********************************************************************
*
*       CyberMand       V1.2
*
*       A Mandelbrot realtime animation
*       PowerPC and CyberGFX supported
*       V1.2: Window mode supported
*
*       1996 by Sam Jordan
*
*       Start coding: 16.11.96
*
*       assemble with:
*       phxass CyberMand.s to CyberMand.o smallcode
*
*       link with smalldata and smallcode enabled
*
*       © 1997 HAAGE&PARTNER Computer GmbH
*
********************************************************************

TRUE            =       -1
FALSE           =       0
P_SINGLE        =       0
P_DOUBLE        =       1

_SCREENWIDTH    =       320             ;don't change these three values!
_SCREENHEIGHT   =       256
_SCREENDEPTH    =       4
_NOARGS         =       FALSE
_FULLITERATIONS =       200

_LEFT_POS       equ.d   -1.5            ;initial values for the mandelbrot area
_TOP_POS        equ.d   1
_RIGHT_POS      equ.d   1
_BOTTOM_POS     equ.d   -1
_RADIUS         equ.d   4               ;termination radius
_AREAWIDTH      =       160             ;MUST be a multiple of 32
_AREAHEIGHT     =       128
_ITERATIONS     =       100             ;number of iterations
_ZOOM           =       20              ;zoom (size is decreased by _ZOOM%)
_TRANSLATION    =       1               ;translation value
_PRECISION      =       P_DOUBLE        ;precision (only with PowerPC)
_TURBODRAW      =       TRUE            ;FALSE: Draw with SetAPen/WritePixel
                                        ;TRUE:  Draw with C2P-Conversion
_KEYSPEED       =       20              ;translation speed using keyboard
_KEYSPEEDX      =       50              ;translation speed with SHIFT

;// includes

                include exec_lib.i
                include graphics_lib.i
                include dos_lib.i
                include intuition_lib.i
                include cybergraphics_lib.i

                include exec/memory.i
                include exec/execbase.i
                include graphics/gfx.i
                include graphics/rastport.i
                include intuition/screens.i
                include dos/dos.i
                include cybergraphics.i
                include debug.i
                include powerpc/powerpc.i
;;/
;// XREF / XDEF
                xref    Calculation
                xref    ChunkyToPlanar
                xref    FX
                xref    Calculation_PPC
                xref    ChunkyToPlanar_PPC
                xref    FX_PPC
                xref    _LinkerDB

                xdef    ScrDepth
                xdef    AreaWidth
                xdef    AreaHeight
                xdef    LeftPos
                xdef    TopPos
                xdef    RightPos
                xdef    BottomPos
                xdef    Radius
                xdef    Iterations
                xdef    Precision
                xdef    ChunkyBuffer
                xdef    HiddenBitmap
                xdef    ActualBitmap
                xdef    ZoomIn
                xdef    ZoomOut
                xdef    Zoom
                xdef    MouseDX
                xdef    MouseDY
                xdef    Translation
                xdef    WindowMode
                xdef    TransTable
                xdef    P_SINGLE
                xdef    P_DOUBLE
                xdef    _SCREENDEPTH
                xdef    _SCREENWIDTH
                xdef    _SCREENHEIGHT
;;/

DB_DEBUG        set     DB_OFF

                section "CyberMand_Main",code

                near     a4,-1
                near     code
                mc68020

;// main
                XDEF    _main
_main
                movem.l d0-a6,-(sp)
                lea     _LinkerDB,a4
                move.l  $4.w,_SysBase
                OPENPOWERPC
                DB_OPENDEBUG
                DB_ALLOCDEBUG   DB1,20000
                DB_ALLOCGROUP   DB1,TEMP
                DB_XDEF
                IFEQ    DB_DEBUG-DB_ON
                XDEF    DB1
                XDEF    TEMP
                ENDC
                bsr     OpenLibs                ;open libraries
                tst.l   d0
                bpl.w   .errorhandler
                bsr     CheckFor020             ;check the CPU
                tst.l   d0
                bpl.w   .errorhandler
                bsr     Initializing            ;init some values
                IFEQ    _NOARGS-FALSE
                bsr     GetArgs
                tst.l   d0
                bpl.w   .errorhandler
                ENDC
                tst.b   WindowMode
                beq.b   .nowin
                moveq   #9,d0
                tst.b   V39
                beq.w   .errorhandler
.nowin
                tst.b   WindowMode
                beq.b   .nowin2
                bsr     SetupWindowMode
                tst.l   d0
                bpl.w   .errorhandler
                bsr     SetupTmpRP
                tst.l   d0
                bpl.w   .errorhandler
                bra.b   .action
.nowin2
                tst.b   PAL
                beq.b   .cybergfx
                bsr     SetupBitmaps            ;prepare the two bitmaps
                tst.l   d0
                bpl.w   .errorhandler
                bsr     SetupDisplay            ;open screen and window
                tst.l   d0
                bpl.w   .errorhandler
                bra.b   .action
.cybergfx
                bsr     SetupDisplay_C          ;open screen and window
                tst.l   d0                      ;for cybergfx
                bpl.w   .errorhandler
                bsr     SetupTmpRP
                tst.l   d0
                bpl.w   .errorhandler
.action
                moveq   #0,d0
                moveq   #0,d1
                move    ScrWidth,d0
                move    ScrHeight,d1
                bsr     GetMemory               ;allocate memory
                tst.l   d0
                bpl.w   .errorhandler
                bsr     Action                 ;the main loop
                tst.l   d0
                bpl.w   .errorhandler
.exit
                tst.b   WindowMode
                beq.b   .nowin3
                bsr     ExitWindowMode
                bra.b   .cybergfx2
.nowin3
                tst.b   PAL
                beq.b   .cybergfx2
                bsr     FreeDisplay             ;close screen and window
                bsr     FreeBitmaps             ;free bitmaps
                bra.b   .pal
.cybergfx2
                bsr     FreeDisplay             ;close screen and window
                bsr     FreeTmpRP
.pal
                bsr     FreeMemory
                bsr     CloseLibs               ;closelibraries
                DB_WRITEDEBUG   DB1,<powerasm:debug.txt>,<;//>,<;;/>
                DB_FREEDEBUG    DB1
                DB_CLOSEDEBUG
                CLOSEPOWERPC
                movem.l (sp)+,d0-a6
                moveq   #0,d0
                rts
.errorhandler
                bsr     WriteError              ;write out error message
                bra.w   .exit
.help
                bra.w   .exit
;;/
;// CheckFor020 (checks if we're running under a 68020 or higher)
******************************************************************************
*
*       d0 = CheckFor020
*
*       checks if we're running under a 68020 or higher (FPU required)
*
*       Out:
*       d0 = error code
*
*       error codes:    -1 = success
*                        2 = need 68020 or more
*                        8 = need FPU
******************************************************************************
CheckFor020
                move.l  a0,-(sp)
                move.l  $4.w,a0                 ;get sysbase
                move    AttnFlags(a0),d0        ;read Attnflags
                btst    #AFB_68020,d0           ;if cpu < 68020
                beq.b   .error                  ;then error
                btst    #AFB_68881,d0
                bne.b   .ok
                btst    #AFB_68882,d0
                bne.b   .ok
                btst    #AFB_68040,d0
                beq.b   .error2
                btst    #AFB_FPU40,d0
                beq.b   .error2
.ok
                moveq   #-1,d0
                bra.b   .end
.error2
                moveq   #8,d0
                bra.b   .end
.error
                moveq   #2,d0
.end
                move.l  (sp)+,a0
                rts
;;/
;// OpenLibs (opens some libraries)
******************************************************************************
*
*       d0 = OpenLibs
*
*       Opens some libraries
*
*       Out:
*       d0 = error code
*
*       error codes:    -1 = success
*                        1 = need V36
*                        7 = asl.library couldn't be opened
******************************************************************************
OpenLibs
                movem.l d1/a0/a1,-(sp)
                lea     dos_name,a1
                moveq   #36,d0
                CALLEXEC        OpenLibrary     ;Open dos.library V36
                tst.l   d0
                beq.w   .error
                move.l  d0,_DOSBase

                lea     graf_name,a1
                moveq   #39,d0
                CALLEXEC        OpenLibrary     ;Open graphics.library V39
                st      V39
                tst.l   d0
                bne.b   .V39
                sf      V39
                lea     graf_name,a1
                moveq   #36,d0
                CALLEXEC        OpenLibrary     ;Open graphics.library V36
                tst.l   d0
                beq.w   .error
.V39
                move.l  d0,_GfxBase

                lea     int_name,a1
                moveq   #36,d0
                CALLEXEC        OpenLibrary     ;Open intuition.library V36
                tst.l   d0
                beq.b   .error
                move.l  d0,_IntuitionBase

                st      PAL
                lea     cybergfx_name,a1
                moveq   #0,d0
                CALLEXEC        OpenLibrary     ;Open cybergraphics.library
                tst.l   d0
                beq.b   .nocybergfx
                move.l  d0,_CyberGfxBase
                sf      PAL
.nocybergfx
                moveq   #-1,d0                  ;error code = success
                bra.b   .end
.error7
                moveq   #7,d0
                bra.b   .end
.error
                moveq   #1,d0
.end
                movem.l (sp)+,d1/a0/a1
                rts
;;/
;// CloseLibs (closes some libraries)
******************************************************************************
*
*       CloseLibs
*
*       Closes some libraries
*
******************************************************************************
CloseLibs
                movem.l d0/a1,-(sp)
                move.l  _DOSBase,d0
                beq.b   .closegfx
                move.l  d0,a1
                CALLEXEC        CloseLibrary    ;close dos.library
.closegfx
                move.l  _GfxBase,d0
                beq.b   .closeintuition
                move.l  d0,a1
                CALLEXEC        CloseLibrary    ;close graphics.library
.closeintuition
                move.l  _IntuitionBase,d0
                beq.b   .closecybergfx
                move.l  d0,a1
                CALLEXEC        CloseLibrary    ;close intuition.library
.closecybergfx
                move.l  _CyberGfxBase,d0
                beq.b   .end
                move.l  d0,a1
                CALLEXEC        CloseLibrary    ;close intuition.library
.end
                movem.l (sp)+,d0/a1
                rts
;;/
;// GetMemory (allocate memory)
******************************************************************************
*
*       d0 = GetMemory (d0,d1)
*
*       Allocates some memory
*
*       In:
*       d0 = screen width
*       d1 = screen height
*
*       Out:
*       d0 = error code
*
*       error codes:    -1 = success
*                        3 = not enough memory
******************************************************************************
GetMemory
                movem.l d1/a0/a1,-(sp)
                mulu.l  d1,d0
                add.l   #32,d0
                move.l  #MEMF_PUBLIC!MEMF_CLEAR,d1
                CALLEXEC        AllocVec
                move.l  d0,ChunkyMem
                subq.l  #1,d0
                and.l   #$ffffffe0,d0
                add.l   #32,d0
                move.l  d0,ChunkyBuffer
                beq.b   .error
                moveq   #-1,d0
                bra.b   .end
.error
                moveq   #3,d0
.end
                movem.l (sp)+,d1/a0/a1
                rts
;;/
;// FreeMemory (free memory)
******************************************************************************
*
*       FreeMemory
*
*       Frees the memory
*
******************************************************************************
FreeMemory
                movem.l d1/a0/a1,-(sp)
                move.l  ChunkyMem,d0
                beq.b   .nofree
                move.l  d0,a1
                CALLEXEC        FreeVec
.nofree
                move.l  NullPointer,d0
                beq.b   .nofree2
                move.l  d0,a1
                CALLEXEC        FreeVec
.nofree2
                movem.l (sp)+,d1/a0/a1
                rts
;;/
;// Initializing (does some initialization)
******************************************************************************
*
*       Initializing
*
*       Does some initializiation
*
******************************************************************************
Initializing
                move.l  _LeftPos,LeftPos        ;copy the initial values
                move.l  _LeftPos+4,LeftPos+4    ;to the 'actual' values
                move.l  _RightPos,RightPos
                move.l  _RightPos+4,RightPos+4
                move.l  _TopPos,TopPos
                move.l  _TopPos+4,TopPos+4
                move.l  _BottomPos,BottomPos
                move.l  _BottomPos+4,BottomPos+4
                move.l  _Rad,Radius
                move.l  _Rad+4,Radius+4
                move    #_ITERATIONS,Iterations
                move    #_FULLITERATIONS,FullIterations
                move.b  #_PRECISION,Precision
                move    #_AREAWIDTH,AreaWidth
                move    #_AREAHEIGHT,AreaHeight
                move.b  #_TURBODRAW,TurboDraw
                move.b  #_ZOOM,Zoom
                move.b  #_TRANSLATION,Translation
                sf      PowerPC
                tst.l   _PowerPCBase
                beq.b   .cont
                st      PowerPC
.cont
                rts
;;/
;// GetArgs (reads the command line arguments)
******************************************************************************
*
*       d0 = GetArgs
*
*       Reads the command line arguments
*
*       d0 = error code
*
*       error codes:    -1 = success
*                        0 = success and help selected
*                        6 = readargs error (no message)
******************************************************************************
GetArgs
                move.l  #template,d1
                move.l  #array,d2
                moveq   #0,d3
                CALLDOS ReadArgs                ;get CLI arguments
                move.l  d0,d5
                beq.w   .error
                lea     array,a0
                tst.l   (a0)                    ;help selected?
                beq.b   .nohelp                 ;no -> jump
                move.l  d5,d1
                CALLDOS FreeArgs
                moveq   #0,d0                   ;exit
                bra.w   .end
.nohelp
                move.l  4(a0),a1                ;get AreaWidth
                tst.l   a1
                beq.b   .nextarg
                move    2(a1),d0
                subq    #1,d0                   ;round up to next 32 Pixel
                and     #$ffe0,d0               ;boundary
                add     #32,d0
                bpl.b   .notneg                 ;if negative
                moveq   #32,d0                  ;then limit value
.notneg
                move    d0,AreaWidth
.nextarg
                move.l  8(a0),a1                ;get AreaHeight
                tst.l   a1
                beq.b   .nextarg2
                move    2(a1),d0
                bpl.b   .notneg2                ;if negative
                moveq   #16,d0                  ;then limit value
.notneg2
                move    d0,AreaHeight
.nextarg2
                move.l  12(a0),a1               ;get number of iterations
                tst.l   a1
                beq.b   .nextarg3
                move    2(a1),d0                ;if negative
                bpl.b   .notneg3
                moveq   #1,d0                   ;then limit value
.notneg3
                move    d0,Iterations
.nextarg3
                move.l  16(a0),a1               ;get number of iterations (FS)
                tst.l   a1
                beq.b   .nextarg3b
                move    2(a1),d0                ;if negative
                bpl.b   .notneg3b
                moveq   #1,d0                   ;then limit value
.notneg3b
                move    d0,FullIterations
.nextarg3b
                move.l  20(a0),a1               ;get zoom speed
                tst.l   a1
                beq.b   .nextarg4
                move.b  3(a1),d0                ;if negative
                bpl.b   .notneg4
                moveq   #1,d0                   ;then limit value
.notneg4
                cmp.b   #90,d0                  ;if too high
                ble.b   .nottoohigh2
                move.b  #90,d0                  ;then limit value
.nottoohigh2
                move.b  d0,Zoom
.nextarg4
                move.l  24(a0),a1               ;get translation speed
                tst.l   a1
                beq.b   .nextarg5
                move.b  3(a1),d0                ;if negative
                bpl.b   .notneg5
                moveq   #1,d0                   ;then limit value
.notneg5
                cmp.b   #5,d0
                ble.b   .nottoohigh2b
                move.b  #5,d0
.nottoohigh2b
                move.b  d0,Translation
.nextarg5
                tst.l   28(a0)                  ;check if slow draw selected
                beq.b   .nextarg6
                sf      TurboDraw               ;switch off turbodraw
.nextarg6
                move.l  32(a0),a1               ;get color number
                tst.l   a1
                beq.b   .nextarg7
                move.b  3(a1),d0
                subq.b  #1,d0
                bpl.b   .noneg6
                moveq   #0,d0
.noneg6
                cmp.b   #4,d0
                ble.b   .nottoohigh3
                moveq   #4,d0
.nottoohigh3
                move.b  d0,ColorNum
.nextarg7
                tst.l   36(a0)                  ;check if single precision
                beq.b   .nextarg8
                move.b  #P_SINGLE,Precision ;single precision
.nextarg8
                tst.l   40(a0)                  ;display forced to PAL?
                beq.b   .cybergfx               ;no -> jump
                st      PAL
.cybergfx
                tst.l   44(a0)                  ;display in full size?
                beq.b   .notfull                ;no -> jump
                st      Full
.notfull
                tst.l   48(a0)                  ;display in window?
                beq.b   .nowin                  ;no -> jump
                st      WindowMode
                st      Full                    ;always fullscreen
.nowin
                tst.l   52(a0)                  ;disable mouse control?
                beq.b   .mouse                  ;no -> jump
                st      NoMouse
.mouse
                move.l  d5,d1
                CALLDOS FreeArgs
                moveq   #-1,d0
.end
                rts
.error
                CALLDOS IoErr           ;get error code
                move.l  d0,d1
                moveq   #0,d2
                CALLDOS PrintFault      ;write error message
                moveq   #6,d0
                bra.b   .end

;;/
;// WriteError (writes an error message to stdout)
******************************************************************************
*
*       WriteError (d0)
*
*       writes an error message to stdout
*
*       In: d0 [UWORD] = error code
*
******************************************************************************
WriteError
                movem.l d0-d5/a0/a1,-(sp)
                tst.l   _DOSBase
                beq.b   .end
                move    d0,d4                   ;save error code
                CALLDOS Output                  ;get output handle
                move.l  d0,d5                   ;save output handle
                lea     ErrorStruct,a0          ;a0 -> ErrorStruct
                lea     Err_Unknown,a1          ;a1 -> text: unknown error code
                cmp     (a0)+,d4                ;error code too high?
                bhs.b   .unknown                ;yes -> its an unknown error
                move.l  0(a0,d4.w*4),a1         ;get ptr to error text
.unknown
                move.l  d5,d1                   ;d1 = outhandle
                move.l  a1,d2                   ;d2 -> error text
                CALLDOS FPuts                   ;write to stdout
.end
                movem.l (sp)+,d0-d5/a0/a1
                rts
;;/
;// SetupBitmaps (prepares two bitmaps for double buffering)
******************************************************************************
*
*       d0 = SetupBitmaps
*
*       prepares two bitmaps for double buffering (size and depth are defined
*       as constants at the top of the source)
*
*       Out:
*       d0 = error code
*
*       error codes:    -1 = success
*                        3 = not enough memory
******************************************************************************
SetupBitmaps
                movem.l d1/d5-a2,-(sp)
                moveq   #2-1,d7
                lea     bitmap1,a0
                move.l  a0,ActualBitmap
.loop
                move.l  a0,a2
                lea     bm_Planes(a2),a2        ;a2 -> planeptrs
                move.l  #_SCREENDEPTH,d0
                move.l  #_SCREENWIDTH,d1
                move.l  #_SCREENHEIGHT,d2
                CALLGRAF        InitBitMap      ;init bitmap structures
                moveq   #_SCREENDEPTH-1,d6
.loop2
                move.l  #_SCREENWIDTH,d0
                move.l  #_SCREENHEIGHT,d1
                CALLGRAF        AllocRaster     ;allocate bitmap memory
                move.l  d0,(a2)+                ;and insert into bitmap struct
                beq.b   .error
                move.l  d0,a0
                move    #(_SCREENHEIGHT*(_SCREENWIDTH/8))/4-1,d5
.clear
                clr.l   (a0)+                   ;clear one plane
                dbra    d5,.clear
                dbra    d6,.loop2
                lea     bitmap2,a0              ;once again for bitmap 2
                move.l  a0,HiddenBitmap
                dbra    d7,.loop
                moveq   #-1,d0
                bra.b   .end
.error
                moveq   #3,d0
.end
                movem.l (sp)+,d1/d5-a2
                rts
;;/
;// FreeBitmaps (frees all the memory allocated by 'AllocRaster')
******************************************************************************
*
*       FreeBitmaps
*
*       frees all the memory allocated by 'AllocRaster'
*
******************************************************************************
FreeBitmaps
                movem.l d0/d1/d6-a2,-(sp)
                moveq   #2-1,d7
                lea     bitmap1,a0
.loop
                move.l  a0,a2
                lea     bm_Planes(a2),a2
                moveq   #_SCREENDEPTH-1,d6
.loop2
                move.l  (a2)+,d0                ;read planeptr
                beq.b   .next
                move.l  d0,a0
                move.l  #_SCREENWIDTH,d0
                move.l  #_SCREENHEIGHT,d1
                CALLGRAF        FreeRaster      ;free the bitmap memory
.next
                dbra    d6,.loop2
                lea     bitmap2,a0              ;once again for bitmap2
                dbra    d7,.loop
                movem.l (sp)+,d0/d1/d6-a2
                rts
;;/
;// SetupDisplay (open screen and window)
******************************************************************************
*
*       d0 = SetupDisplay
*
*       open a screen and a window
*
*       Out:
*       d0 = error code
*
*       error codes:    -1 = success
*                        4 = Couldn't open screen
*                        5 = Couldn't open window
******************************************************************************
SetupDisplay
                movem.l d1/a0/a1,-(sp)
                cmp     #320,AreaWidth          ;check for size overflow
                ble.b   .nottoowide
                move    #320,AreaWidth
.nottoowide
                cmp     #256,AreaHeight
                ble.b   .nottoohigh
                move    #256,AreaHeight
.nottoohigh
                tst.b   Full                    ;full size?
                beq.b   .notfull                ;no -> jump
                move    #320,AreaWidth
                move    #256,AreaHeight
.notfull
                sub.l   a0,a0
                lea     ScreenTags,a1
                CALLINT OpenScreenTagList       ;open screen
                moveq   #4,d1
                move.l  d0,_Screen
                beq.w   .error
                move.l  d0,a0
                move.l  d0,ScreenAddress        ;insert into windowtaglist
                move    sc_Width(a0),ScrWidth
                move    sc_Height(a0),ScrHeight
                move    #_SCREENDEPTH,ScrDepth
                lea     sc_ViewPort(a0),a0      ;a0 -> screen viewport
                move.l  a0,_VPort               ;save viewport
                bsr     InitColorTable
                lea     ColorTable,a1           ;a1 -> color table
                moveq   #32,d0                  ;32 colors
                CALLGRAF        LoadRGB4        ;set screen colors
                sub.l   a0,a0
                lea     WindowTags,a1
                CALLINT OpenWindowTagList       ;open window
                moveq   #5,d1
                move.l  d0,_Window
                beq.b   .error
                move.l  d0,a0
                move.l  wd_RPort(a0),_RPort
                move.l  #16,d0
                move.l  #MEMF_CHIP!MEMF_CLEAR,d1
                CALLEXEC        AllocVec        ;get chip RAM for pointer
                move.l  d0,NullPointer
                move.l  d0,a1
                move.l  _Window,a0
                moveq   #1,d0
                moveq   #1,d1
                moveq   #0,d2
                moveq   #0,d3
                CALLINT SetPointer              ;clear pointer
                moveq   #-1,d0
                bra.b   .end
.error
                move.l  d1,d0
.end
                movem.l (sp)+,d1/a0/a1
                rts
;;/
;// FreeDisplay (close screen and window)
******************************************************************************
*
*       FreeDisplay
*
*       closes the screen and the window
*
******************************************************************************
FreeDisplay
                movem.l d1/a0/a1,-(sp)
                move.l  _Window,d0
                beq.b   .nowindow
                move.l  d0,a0
                CALLINT CloseWindow
.nowindow
                move.l  _Screen,d0
                beq.b   .noscreen
                move.l  d0,a0
                CALLINT CloseScreen             ;close screen
.noscreen
                movem.l (sp)+,d1/a0/a1
                rts
;;/
;// SetupDisplay_C (open screen and window for cybergfx)
******************************************************************************
*
*       d0 = SetupDisplay_C
*
*       open a screen and a window for cybergfx
*
*       Out:
*       d0 = error code
*
*       error codes:    -1 = success
*                        4 = Couldn't open screen
*                        5 = Couldn't open window
*                        7 = no screen mode requester
******************************************************************************
SetupDisplay_C
                movem.l d1/d2/a0/a1,-(sp)
                bsr     InitColorTable256       ;create color table
                sub.l   a0,a0
                lea     CyberModeTags,a1
                CALLCYBERGFX    CModeRequestTagList     ;get screen mode
                moveq   #7,d1
                tst.l   d0
                beq.w   .error
                moveq   #6,d1
                cmp.l   #-1,d0
                beq.w   .error
                move.l  d0,DispID
                sub.l   a0,a0
                lea     ScreenTags_C,a1
                CALLINT OpenScreenTagList       ;open screen
                moveq   #4,d1
                move.l  d0,_Screen
                beq.w   .error
                move.l  d0,a0
                clr.l   WinWidth
                clr.l   WinHeight
                move    sc_Width(a0),WinWidth+2
                move    sc_Height(a0),WinHeight+2
                move    sc_Width(a0),ScrWidth
                move    sc_Height(a0),ScrHeight
                move    #8,ScrDepth
                move.l  d0,ScreenAddress        ;insert into windowtaglist
                lea     sc_ViewPort(a0),a0      ;a0 -> screen viewport
                move.l  a0,_VPort               ;save viewport
                lea     ColorTable256,a1        ;a1 -> color table
                CALLGRAF        LoadRGB32       ;set screen colors
                sub.l   a0,a0
                lea     WindowTags,a1
                CALLINT OpenWindowTagList       ;open window
                moveq   #5,d1
                move.l  d0,_Window
                beq.w   .error
                move.l  d0,a0
                move.l  wd_RPort(a0),_RPort
                move.l  #16,d0
                move.l  #MEMF_CHIP!MEMF_CLEAR,d1
                CALLEXEC        AllocVec        ;get chip RAM for pointer
                move.l  d0,NullPointer
                move.l  d0,a1
                move.l  _Window,a0
                moveq   #1,d0
                moveq   #1,d1
                moveq   #0,d2
                moveq   #0,d3
                CALLINT SetPointer              ;clear pointer
                move    ScrHeight,d0            ;check for size overflow
                cmp     AreaHeight,d0
                bge.b   .nottoohigh
                move    ScrHeight,AreaHeight
.nottoohigh
                move    ScrWidth,d0
                cmp     AreaWidth,d0
                bge.b   .nottoowide
                move    ScrWidth,AreaWidth
.nottoowide
                tst.b   Full                    ;full size?
                beq.b   .notfull                ;no -> jump
                move    ScrWidth,AreaWidth
                move    ScrHeight,AreaHeight
.notfull
                moveq   #-1,d0
                bra.b   .end
.error
                move.l  d1,d0
.end
                movem.l (sp)+,d1/d2/a0/a1
                rts
;;/
;// SetupWindowMode (open window on public screen)
******************************************************************************
*
*       d0 = SetupWindowMode
*
*       open window on public screen
*
*       Out: d0 = error code
*
*       error codes:    -1 = success
*                        5 = Couldn't open window
******************************************************************************
SetupWindowMode
                movem.l d1-d5/a0-a3,-(sp)
                bsr     InitColorTable256       ;create color table
                sub.l   a0,a0
                lea     WindowTags2,a1
                CALLINT OpenWindowTagList       ;open window
                moveq   #5,d1
                move.l  d0,_Window
                beq.w   .error
                move.l  d0,a0
                move.l  wd_RPort(a0),_RPort
                move    wd_GZZWidth(a0),OldGZZWidth
                move    wd_GZZHeight(a0),OldGZZHeight
                st      WindowModeOn
                move    #8,ScrDepth
                bsr     ReCalcDimensions
                move.l  _Window,a0
                move.l  wd_WScreen(a0),a0
                move.l  sc_ViewPort+vp_ColorMap(a0),d4
                move.l  d4,_ColorMap
                lea     TransTable,a2
                lea     ColorTable,a3
                addq.l  #4,a3
                move    #256-1,d5
.loop
                move.l  d4,a0
                move.l  (a3)+,d1
                move.l  (a3)+,d2
                move.l  (a3)+,d3
                lea     EmptyTags,a1
                CALLGRAF        ObtainBestPenA
                move.l  d0,(a2)+
                dbra    d5,.loop
                moveq   #-1,d0
                move.b  #-1,Resizing
                bra.b   .end
.error
                move.l  d1,d0
.end
                movem.l (sp)+,d1-d5/a0-a3
                rts
;;/
;// ReCalcDimensions (recalculate dimensions in window mode)
******************************************************************************
*
*       ReCalcDimensions
*
*       recalculate dimensions in window mode
*
******************************************************************************
ReCalcDimensions
                movem.l d0/d1/a0/a1,-(sp)
                move.l  _Window,a0
                move    wd_LeftEdge(a0),d0
                moveq   #0,d1
                move.b  wd_BorderLeft(a0),d1
                add     d1,d0
                and.l   #$3,d0
                moveq   #4,d1
                sub.l   d0,d1
                and.l   #$3,d1
                move    d1,HorOffset
                move    wd_GZZWidth(a0),d0
                subq.l  #3,d0
                and.l   #$fffffff0,d0
                move    d0,ScrWidth
                move    d0,AreaWidth
                move    wd_GZZHeight(a0),ScrHeight
                move    ScrHeight,AreaHeight
                movem.l (sp)+,d0/d1/a0/a1
                rts
;;/
;// ExitWindowMode (cleanup in window mode)
******************************************************************************
*
*       ExitWindowMode
*
*       cleanup in window mode
*
******************************************************************************
ExitWindowMode
                movem.l d2/a2,-(sp)
                tst.b   WindowModeOn
                beq.b   .end
                lea     TransTable,a2
                move    #256-1,d2
.loop
                move.l  (a2)+,d0
                move.l  _ColorMap,a0
                CALLGRAF        ReleasePen
                dbra    d2,.loop
.end
                movem.l (sp)+,d2/a2
                rts
;;/
;// SetupTmpRP (setup a temporary rastport for WritePixelArray8)
******************************************************************************
*
*       d0 = SetupTmpRP
*
*       setup a temporary rastport for WritePixelArray8 (cybergfx only)
*
*       Out:
*       d0 = error code
*
*       error codes:    -1 = success
*                        3 = not enough memory
******************************************************************************
SetupTmpRP
                movem.l d1-d4/a0-a2,-(sp)
                lea     tmpRP,a1                ;a1 -> temp rastport
                CALLGRAF        InitRastPort    ;init temporary rastport
                tst.b   V39                     ;if V39 available
                beq.w   .noV39
                moveq   #0,d0                   ;then create bitmap with
                move    ScrWidth,d0             ;AllocBitMap
                moveq   #1,d1
                moveq   #8,d2
                move.l  #BMF_MINPLANES,d3
                move.l  _RPort,a0
                move.l  rp_BitMap(a0),a0
                CALLGRAF        AllocBitMap
                lea     tmpRP,a0
                move.l  d0,rp_BitMap(a0)
                moveq   #-1,d0
                bra.w   .end
.noV39
                lea     bitmap1,a0
                lea     tmpRP,a1                ;a1 -> temp rastport
                move.l  a0,rp_BitMap(a1)
                moveq   #8,d0                   ;depth = 8
                moveq   #0,d1
                move    ScrWidth,d1             ;width = screen width
                move.l  d1,d3
                moveq   #1,d2                   ;height = 1
                CALLGRAF        InitBitMap      ;initialize bitmap
                lea     bitmap1,a2
                moveq   #8-1,d7
                moveq   #0,d4
.loop
                move.l  d3,d0                   ;width = screen width
                moveq   #1,d1                   ;height = 1
                CALLGRAF        AllocRaster     ;get bitplane memory
                moveq   #3,d1
                tst.l   d0
                beq.w   .error
                move.l  d0,bm_Planes(a2,d4.w)   ;insert plane ptr
                addq    #4,d4
                dbra    d7,.loop
                moveq   #-1,d1
.error
                move.l  d1,d0
.end
                movem.l (sp)+,d1-d4/a0-a2
                rts
;;/
;// FreeTmpRP (frees the temporary rastport)
******************************************************************************
*
*       FreeTmpRP
*
*       frees the temporary rastport (cybergfx only)
*
******************************************************************************
FreeTmpRP
                movem.l d0-d3/a0-a2,-(sp)
                tst.b   V39
                beq.b   .noV39
                lea     tmpRP,a0
                move.l  rp_BitMap(a0),d0
                beq.w   .end
                clr.l   rp_BitMap(a0)
                move.l  d0,a0
                CALLGRAF        FreeBitMap
                bra.b   .end
.noV39
                lea     bitmap1,a2
                moveq   #8-1,d3
                moveq   #0,d2
.loop
                move.l  bm_Planes(a2,d2.w),d0   ;get plane ptr
                beq.w   .next                   ;0 -> jump
                clr.l   bm_Planes(a2,d2.w),d0
                move.l  d0,a0
                moveq   #0,d0
                move    ScrWidth,d0             ;width = screen width
                moveq   #1,d1                   ;height = 1
                CALLGRAF        FreeRaster      ;free bitplane memory
.next
                addq    #4,d2
                dbra    d3,.loop
.end
                movem.l (sp)+,d0-d3/a0-a2
                rts
;;/
;// InitColorTable (fills the colortable with the desired colors)
******************************************************************************
*
*       InitColorTable
*
*       fills the colortable with the desired colors
*
******************************************************************************
InitColorTable
                movem.l d0/d1/a0/a1,-(sp)
                lea     ColorTable,a0
                lea     ColorOffsets,a1
                moveq   #0,d0
                move.b  ColorNum,d0
                move    0(a1,d0.w*2),d0
                moveq   #0,d1
                moveq   #(1<<_SCREENDEPTH)-1,d7
.fill
                move    d1,(a0)+
                add     d0,d1
                dbra    d7,.fill
                movem.l (sp)+,d0/d1/a0/a1
                rts
;;/
;// InitColorTable256 (fills the colortable with the desired colors)
******************************************************************************
*
*       InitColorTable256
*
*       fills the colortable with the desired colors (for cybergfx)
*
******************************************************************************
InitColorTable256
                movem.l d0-a1,-(sp)
                lea     ColorTable256,a0
                lea     ColorOffsets256,a1
                moveq   #0,d0
                move.b  ColorNum,d0
                mulu    #12,d0
                lea     0(a1,d0.w),a1
                move.l  (a1)+,d2
                move.l  (a1)+,d3
                move.l  (a1)+,d4
                moveq   #0,d1
                move    #256,(a0)+
                clr     (a0)+
                move    #256-1,d7
                moveq   #0,d0
                moveq   #0,d5
                moveq   #0,d6
.fill
                move.l  d0,(a0)+
                move.l  d5,(a0)+
                move.l  d6,(a0)+
                add.l   d2,d0
                add.l   d3,d5
                add.l   d4,d6
                dbra    d7,.fill
                clr.l   (a0)+
                movem.l (sp)+,d0-a1
                rts
;;/
;// Action (main loop: calculate and draw the graphics and check messages)
******************************************************************************
*
*       d0 = Action
*
*       main loop: calculation of the graphics, displaying of the graphics
*       and check for messages
*
*       Out:
*       d0 = error code
*
*       error codes:    -1 = success
*                        3 = not enough memory
******************************************************************************
Action
                movem.l d1-a6,-(sp)
.loop
                tst.b   ForbidAnim              ;if animation is forbidden
                bne.w   .waitformsg             ;then wait for msg
.do
                move    #_KEYSPEED,d0
                tst.b   Shift
                beq.b   .noshift
                move    #_KEYSPEEDX,d0
.noshift
                move    d0,d1
                neg     d1
                tst.b   Key_Up
                beq.b   .no_up
                move    d1,MouseDY
.no_up
                tst.b   Key_Down
                beq.b   .no_down
                move    d0,MouseDY
.no_down
                tst.b   Key_Left
                beq.b   .no_left
                move    d1,MouseDX
.no_left
                tst.b   Key_Right
                beq.b   .no_right
                move    d0,MouseDX
.no_right
                tst.b   PowerPC
                bne.b   .ppc
                bsr     FX
                bra.b   .68K
.ppc
                RUNPOWERPC      FX_PPC          ;calc zoom and movements
.68K
                clr     MouseDX
                clr     MouseDY
                tst.b   PowerPC
                bne.w   .ppc2
                bsr     Calculation
;                DB_CALL         DB1,Calculation
                bra.w   .68K2
.ppc2
                RUNPOWERPC      Calculation_PPC
;                DB_CALL         DB1,RUNPOWERPC,Calculation_PPC,,0
.68K2
                tst.b   WindowMode
                bne.b   .windowmode
                tst.b   PAL
                bne.b   .pal
.windowmode
                bsr     DrawGraphics_C          ;draw the picture
                bra.b   .cybergfx
.pal
                bsr     DrawGraphics            ;draw the picture
.cybergfx
;                btst    #6,$bfe001
;                bne.b   .cybergfx
;                bra.w   .exit

                tst.b   ClearDisplay
                beq.b   .getmsg
                subq.b  #1,ClearDisplay
                bra.b   .getmsg
.waitformsg
                move.l  _Window,a0
                move.l  wd_UserPort(a0),a0
                CALLEXEC        WaitPort
.getmsg
                move.l  _Window,a0
                move.l  wd_UserPort(a0),a0
                CALLEXEC        GetMsg          ;get message
                tst.l   d0                      ;no message?
                beq.w   .loop                   ;then jump back
                move.l  d0,d4                   ;save message ptr
                move.l  d0,a0
                move.l  im_Class(a0),d0         ;get message class
                move    im_Code(a0),d1          ;get message code
                move    im_MouseX(a0),d2
                move    im_MouseY(a0),d3
                cmp.l   #MOUSEBUTTONS,d0        ;mouse buttons pressed?
                beq.w   .checkmouse             ;yes -> jump
                cmp.l   #RAWKEY,d0              ;key pressed?
                beq.w   .checkrawkey            ;yes -> jump
                cmp.l   #MOUSEMOVE,d0
                beq.w   .checkdeltamove
                cmp.l   #ACTIVEWINDOW,d0
                beq.w   .activewindow
                cmp.l   #INACTIVEWINDOW,d0
                beq.w   .inactivewindow
                cmp.l   #CHANGEWINDOW,d0
                beq.b   .changewindow
                cmp.l   #CLOSEWINDOW,d0
                bne.w   .reply
                st      GameOver
                bra.w   .reply
.changewindow
                move.l  _Window,a0
                move    wd_GZZWidth(a0),d0
                cmp     OldGZZWidth,d0
                bne.b   .resize
                move    wd_GZZHeight(a0),d0
                cmp     OldGZZHeight,d0
                bne.b   .resize
                bsr     ReCalcDimensions
                st      Resizing
                bra.w   .reply
.resize
                bsr     FreeTmpRP
                bsr     ReCalcDimensions
                move.l  ChunkyMem,a1
                CALLEXEC        FreeVec
                clr.l   ChunkyMem
                moveq   #0,d0
                moveq   #0,d1
                move    ScrWidth,d0
                move    ScrHeight,d1
                bsr     GetMemory
                tst.l   d0
                bpl.w   .error
                bsr     SetupTmpRP
                st      Resizing
                bra.w   .reply
.checkmouse
                tst.b   NoMouse
                bne.w   .reply
                cmp     #IECODE_LBUTTON,d1      ;left mouse button down
                beq.b   .zoomin
                cmp     #IECODE_LBUTTON+IECODE_UP_PREFIX,d1 ;LMB up
                beq.b   .stopzoomin
                cmp     #IECODE_RBUTTON,d1      ;right mouse button down
                beq.b   .zoomout
                cmp     #IECODE_RBUTTON+IECODE_UP_PREFIX,d1 ;RMB up
                beq.b   .stopzoomout
                bra.w   .reply
.activewindow
                sf      WindowInActive
                bra.w   .reply
.inactivewindow
                st      WindowInActive
                bra.w   .reply
.zoomin
                st      ZoomIn                  ;enable zoom in
                bra.w   .reply
.stopzoomin
                sf      ZoomIn                  ;disable zoom in
                bra.w   .reply
.zoomout
                st      ZoomOut                 ;enable zoom out
                bra.w   .reply
.stopzoomout
                sf      ZoomOut                 ;disable zoom out
                bra.w   .reply
.checkdeltamove
                tst.b   NoMouse
                bne.w   .reply
                move    d2,MouseDX              ;save delta coordinates
                move    d3,MouseDY
                bra.w   .reply
.checkrawkey
                cmp     #$40,d1                 ;SPACE pressed?
                beq.w   .freeze
                cmp.b   #$44,d1                 ;RETURN pressed?
                beq.w   .continue
                cmp.b   #$50,d1                 ;F1 pressed?
                beq.w   .switchCPU              ;yes -> change CPU
                cmp.b   #$45,d1                 ;ESC pressed?
                beq.w   .gameover
                btst    #IECODEB_UP_PREFIX,d1
                bne.w   .keyup
                cmp.b   #$4c,d1
                beq.w   .up_start
                cmp.b   #$4d,d1
                beq.w   .down_start
                cmp.b   #$4f,d1
                beq.w   .left_start
                cmp.b   #$4e,d1
                beq.w   .right_start
                cmp.b   #$61,d1
                beq.w   .shiftdown
                cmp.b   #$60,d1
                beq.w   .zoomin
                cmp.b   #$64,d1
                beq.w   .zoomout
                bra.w   .reply
.keyup
                bclr    #IECODEB_UP_PREFIX,d1
                cmp.b   #$4c,d1
                beq.w   .up_end
                cmp.b   #$4d,d1
                beq.w   .down_end
                cmp.b   #$4f,d1
                beq.w   .left_end
                cmp.b   #$4e,d1
                beq.w   .right_end
                cmp.b   #$61,d1
                beq.w   .shiftup
                cmp.b   #$60,d1
                beq.w   .stopzoomin
                cmp.b   #$64,d1
                beq.w   .stopzoomout
                bra.w   .reply
.shiftdown
                st      Shift
                bra.w   .reply
.shiftup
                sf      Shift
                bra.w   .reply
.up_start
                st      Key_Up
                bra.w   .reply
.up_end
                sf      Key_Up
                bra.w   .reply
.down_start
                st      Key_Down
                bra.w   .reply
.down_end
                sf      Key_Down
                bra.w   .reply
.left_start
                st      Key_Left
                bra.w   .reply
.left_end
                sf      Key_Left
                bra.w   .reply
.right_start
                st      Key_Right
                bra.w   .reply
.right_end
                sf      Key_Right
                bra.w   .reply
.gameover
                st      GameOver
                bra.w   .reply
.switchCPU
                tst.l   _PowerPCBase
                beq.w   .reply
                eori.b  #-1,PowerPC
                bra.w   .reply
.freeze
                tst.b   ForbidAnim              ;if anim already forbidden
                bne.w   .reply                  ;then jump
                tst.b   ClearDisplay
                bne.w   .reply
                st      ForbidAnim
                move    AreaWidth,OldAreaWidth  ;save width and height
                move    AreaHeight,OldAreaHeight
                move    Iterations,OldIterations
                move    ScrWidth,AreaWidth      ;set width and height to full
                move    ScrHeight,AreaHeight    ;screen
                move    FullIterations,Iterations
                move.l  d4,a1                   ;restore message ptr
                CALLEXEC        ReplyMsg        ;reply msg
                bra.w   .do                     ;calc one frame
.continue
                tst.b   ForbidAnim
                beq.b   .reply
                sf      ForbidAnim              ;enable animation
                move    OldAreaWidth,AreaWidth  ;restore width and height
                move    OldAreaHeight,AreaHeight
                move    OldIterations,Iterations
                move.b  #2,ClearDisplay
                bra.b   .reply
.reply
                move.l  d4,a1                   ;restore message ptr
                CALLEXEC        ReplyMsg        ;reply msg
                tst.b   GameOver                ;if gameover set then leave
                bne.b   .exit
                tst.b   ForbidAnim
                bne.w   .waitformsg
                tst.b   WindowInActive
                bne.w   .waitformsg
                bra.w   .getmsg
.error
                move.l  d0,-(sp)
                move.l  d4,a1                   ;restore message ptr
                CALLEXEC        ReplyMsg        ;reply msg
                move.l  (sp)+,d0
                bra.b   .end2
.exit
                moveq   #-1,d0
.end2
                movem.l (sp)+,d1-a6
                rts
;;/
;// DrawGraphics (draws the mandelbrot area into the hidden bitmap)
******************************************************************************
*
*       DrawGraphics
*
*       draws the mandelbrot area into the hidden bitmap
*
******************************************************************************
DrawGraphics
                movem.l d0-a2,-(sp)
                move.l  _RPort,a0
                move.l  HiddenBitmap,a1
                move.l  a1,rp_BitMap(a0)        ;insert into actual rastport
                move.l  _VPort,a0
                move.l  vp_RasInfo(a0),a0
                move.l  a1,ri_BitMap(a0)        ;insert into viewport.rasinfo

                move.l  _RPort,d4               ;save rastport
                cmp.b   #1,ClearDisplay         ;right frame now to clear?
                bne.b   .noclear                ;no -> jump
                moveq   #0,d0
                move.l  d4,a1
                CALLGRAF        SetAPen         ;change color to 0
                move.l  d4,a1
                moveq   #0,d0
                moveq   #0,d1
                move    #_SCREENWIDTH-1,d2
                move    #_SCREENHEIGHT-1,d3
                CALLGRAF        RectFill        ;clear screen
                CALLGRAF        WaitBlit
.noclear
                cmp.b   #TRUE,TurboDraw         ;turbodraw enabled?
                bne.w   .slowdraw               ;no -> slow draw
                tst.b   PowerPC
                bne.w   .ppc
;                DB_CALL         DB1,ChunkyToPlanar
                bsr     ChunkyToPlanar
                bra.w   .end
.ppc
;                DB_CALL         DB1,RUNPOWERPC,ChunkyToPlanar_PPC,,0
                RUNPOWERPC      ChunkyToPlanar_PPC
                bra.w   .end
.slowdraw
                move.l  ChunkyBuffer,a2         ;a2 -> Chunkybuffer
                move    AreaWidth,d6            ;d6 = width
                move    AreaHeight,d7           ;d7 = height
                move    #_SCREENWIDTH,d2
                sub     d6,d2
                lsr     #1,d2                   ;calc start x
                move    d2,d5                   ;and save it
                move    #_SCREENHEIGHT,d3
                sub     d7,d3
                lsr     #1,d3                   ;calc start y
                subq    #1,d7
.loop
                move    AreaWidth,d6
                subq    #1,d6
.loop2
                move.b  (a2)+,d0                ;read chunky pixel
                move.l  d4,a1
                CALLGRAF        SetAPen         ;change color
                move.l  d4,a1
                move    d2,d0                   ;get x coord
                move    d3,d1                   ;get y coord
                CALLGRAF        WritePixel      ;write pixel
                addq    #1,d2                   ;increase x position
                dbra    d6,.loop2
                move    d5,d2                   ;restore start x
                addq    #1,d3                   ;increase y position
                dbra    d7,.loop
.end
                move.l  _Screen,a0
                CALLINT MakeScreen              ;make the invisible picture
                CALLINT RethinkDisplay          ;visible
                move.l  ActualBitmap,d0         ;now change both bitmap ptrs
                move.l  HiddenBitmap,ActualBitmap
                move.l  d0,HiddenBitmap
                movem.l (sp)+,d0-a2
                rts
;;/
;// DrawGraphics_C (draws the mandelbrot area into the hidden bitmap)
******************************************************************************
*
*       DrawGraphics_C
*
*       draws the mandelbrot area into the hidden bitmap (for cybergfx)
*
******************************************************************************
DrawGraphics_C
                movem.l d0-a2,-(sp)
                cmp.b   #2,ClearDisplay
                bne.b   .noclear

                move.l  _RPort,d4               ;save rastport
                moveq   #0,d0
                move.l  d4,a1
                CALLGRAF        SetAPen         ;change color to 0
                move.l  d4,a1
                moveq   #0,d0
                moveq   #0,d1
                move    ScrWidth,d2
                subq    #1,d2
                move    ScrHeight,d3
                subq    #1,d3
                add     HorOffset,d0
                add     HorOffset,d1
                add     HorOffset,d2
                add     HorOffset,d3
                CALLGRAF        RectFill        ;clear screen
.noclear
                move.l  _RPort,a0
                move    ScrWidth,d0
                move    AreaWidth,d2
                sub     d2,d0
                lsr     #1,d0
                move    ScrHeight,d1
                move    AreaHeight,d3
                sub     d3,d1
                lsr     #1,d1
                add     d0,d2
                add     d1,d3
                subq    #1,d2
                subq    #1,d3
                move.l  ChunkyBuffer,a2
                lea     tmpRP,a1
                add     HorOffset,d0
                add     HorOffset,d2
                CALLGRAF        WritePixelArray8
                tst.b   Resizing
                beq.b   .end
                sf      Resizing
                move.l  _RPort,a1
                lea     TransTable,a0
                move.l  (a0),d0
                CALLGRAF        SetAPen
                move.l  _RPort,a1
                moveq   #0,d0
                moveq   #0,d1
                move.l  _Window,a0
                move    HorOffset,d2
                beq.b   .nodraw
                subq    #1,d2
                move    wd_GZZHeight(a0),d3
                subq    #1,d3
                CALLGRAF        RectFill
.nodraw
                move.l  _RPort,a1
                move    AreaWidth,d0
                add     HorOffset,d0
                moveq   #0,d1
                move.l  _Window,a0
                move    wd_GZZWidth(a0),d2
                subq    #1,d2
                cmp     d2,d0
                bgt.b   .end
                move    wd_GZZHeight(a0),d3
                subq    #1,d3
                CALLGRAF        RectFill
.end
                movem.l (sp)+,d0-a2
                rts
;;/

                section "CyberMand_Data",data
                POWERDATA
dos_name        DOSNAME
graf_name       GRAFNAME
int_name        INTNAME
cybergfx_name   CYBERGFXNAME
                even
template        dc.b    "?=HELP/S,W=WIDTH/K/N,H=HEIGHT/K/N,I=ITERATIONS/K/N,"
                dc.b    "F=FULLSCREEN/K/N,Z=ZOOMSPEED/K/N,M=MOVESPEED/K/N,S=SLOWDRAW/S,"
                dc.b    "C=COLOR/K/N,SP=SINGLE/S,P=PAL/S,X=MAXSIZE/S,WI=WINDOW/S,"
                dc.b    "NM=NOMOUSE/S",0

version         dc.b    "$VER: CyberMand 1.2 (13.10.97)",0
cybermand_title dc.b    "Select Screen Mode",0
                even

array           dcb.l   15,0

ErrorStruct
                dc.w    (.end-.start)/4         ;number of error entries
.start
                dc.l    HelpText
                dc.l    Err_V36
                dc.l    Err_020
                dc.l    Err_Mem
                dc.l    Err_Screen
                dc.l    Err_Window
                dc.l    Err_Empty
                dc.l    Err_Mode
                dc.l    Err_FPU
                dc.l    Err_NoWin
.end

Err_V36         dc.b    "Couldn't open libraries: need OS V36\n",0
Err_020         dc.b    "This program requires at least 68020\n",0
Err_Mem         dc.b    "Not enough memory\n",0
Err_Screen      dc.b    "Couldn't open the screen\n",0
Err_Window      dc.b    "Couldn't open the window\n",0
Err_Empty       dc.b    0
Err_Mode        dc.b    "Failed to open the screen mode requester\n",0
Err_FPU         dc.b    "This program requires a FPU\n",0
Err_NoWin       dc.b    "Window mode only available with V39\n",0

Err_Unknown     dc.b    "Unknown error code\n",0


HelpText        dc.b    "\n"
                dc.b    "CyberMand V1.2  1997 by Sam Jordan\n"
                dc.b    "PowerPC and 68K/FPU supported\n"
                dc.b    "----------------------------------\n"
                dc.b    "\n"
                dc.b    "CLI-Parameters:\n"
                dc.b    "?=HELP                  - displays this help text\n"
                dc.b    "WI=WINDOW               - runs the demo in a window\n"
                dc.b    "W=WIDTH                 - width of the visible display\n"
                dc.b    "H=HEIGHT                - height of the visible display\n"
                dc.b    "X=MAXSIZE               - display in full size\n"
                dc.b    "I=ITERATIONS            - number of iterations (Default=100)\n"
                dc.b    "F=FULLSCREEN            - iterations in full screen mode\n"
                dc.b    "Z=ZOOMSPEED  [1..90]    - zoom speed\n"
                dc.b    "M=MOVESPEED  [1..5]     - translation speed\n"
                dc.b    "S=SLOWDRAW              - Drawing with SetAPen()/WritePixel()\n"
                dc.b    "                          instead of ChunkyToPlanar-Conversion\n"
                dc.b    "C=COLOR      [1..5]     - white, red, green, blue, yellow\n"
                dc.b    "SP=SINGLE               - use single precision operations (PPC)\n"
                dc.b    "P=PAL                   - force display to PAL screen\n"
                dc.b    "NM=NOMOUSE              - disables mouse control\n"
                dc.b    "\n"
                dc.b    "Move area with the mouse, zoom in with left mouse button\n"
                dc.b    "and zoom out with right mouse button.\n"
                dc.b    "\n"
                dc.b    "Key functions:\n"
                dc.b    "ESC         - quit\n"
                dc.b    "SPC         - show display in full screen\n"
                dc.b    "RETURN      - go back to animation mode\n"
                dc.b    "F1          - switch CPU's (68K <-> PPC)\n"
                dc.b    "Cursor keys - move area\n"
                dc.b    "Right Shift - accelerate moving\n"
                dc.b    "Left Shift  - zoom in\n"
                dc.b    "Left Alt    - zoom out\n"
                dc.b    "\n"
                dc.b    0
                even

ScreenTags      dc.l    SA_Left                 ;tags for OpenScreenTagList
                dc.l    0
                dc.l    SA_Top
                dc.l    0
                dc.l    SA_Width
                dc.l    _SCREENWIDTH
                dc.l    SA_Height
                dc.l    _SCREENHEIGHT
                dc.l    SA_Depth
                dc.l    _SCREENDEPTH
                dc.l    SA_BitMap
                dc.l    bitmap1
                dc.l    SA_Quiet
                dc.l    TRUE
                dc.l    SA_Type
                dc.l    CUSTOMSCREEN
                dc.l    TAG_DONE

ScreenTags_C                                    ;tags for OpenScreenTagList
                dc.l    SA_Quiet
                dc.l    TRUE
                dc.l    SA_DisplayID
DispID
                dc.l    0
                dc.l    SA_Depth
                dc.l    8
                dc.l    TAG_DONE

WindowTags      dc.l    WA_Left                 ;tags for OpenWindowTagList
                dc.l    0
                dc.l    WA_Top
                dc.l    0
                dc.l    WA_Width
WinWidth
                dc.l    _SCREENWIDTH
                dc.l    WA_Height
WinHeight
                dc.l    _SCREENHEIGHT
                dc.l    WA_Activate
                dc.l    TRUE
                dc.l    WA_Borderless
                dc.l    TRUE
                dc.l    WA_RMBTrap
                dc.l    TRUE
                dc.l    WA_ReportMouse
                dc.l    TRUE
                dc.l    WA_IDCMP
                dc.l    IDCMP_MOUSEBUTTONS!IDCMP_RAWKEY!IDCMP_MOUSEMOVE!IDCMP_DELTAMOVE!IDCMP_ACTIVEWINDOW!IDCMP_INACTIVEWINDOW
                dc.l    WA_CustomScreen
ScreenAddress
                dc.l    0
                dc.l    TAG_DONE

WindowTags2     dc.l    WA_Left                 ;tags for OpenWindowTagList
                dc.l    0
                dc.l    WA_Top
                dc.l    0
                dc.l    WA_InnerWidth
                dc.l    320+3
                dc.l    WA_InnerHeight
                dc.l    256
                dc.l    WA_MinWidth
                dc.l    96+3
                dc.l    WA_MinHeight
                dc.l    64
                dc.l    WA_MaxWidth
                dc.l    1600
                dc.l    WA_MaxHeight
                dc.l    1200
                dc.l    WA_Title
                dc.l    WinTitle
                dc.l    WA_Activate
                dc.l    TRUE
                dc.l    WA_RMBTrap
                dc.l    TRUE
                dc.l    WA_ReportMouse
                dc.l    TRUE
                dc.l    WA_GimmeZeroZero
                dc.l    TRUE
                dc.l    WA_DragBar
                dc.l    TRUE
                dc.l    WA_CloseGadget
                dc.l    TRUE
                dc.l    WA_DepthGadget
                dc.l    TRUE
                dc.l    WA_SizeGadget
                dc.l    TRUE
                dc.l    WA_IDCMP
                dc.l    IDCMP_MOUSEBUTTONS!IDCMP_RAWKEY!IDCMP_MOUSEMOVE!IDCMP_DELTAMOVE!IDCMP_CHANGEWINDOW!IDCMP_CLOSEWINDOW!IDCMP_ACTIVEWINDOW!IDCMP_INACTIVEWINDOW
                dc.l    TAG_DONE
WinTitle        dc.b    "Cybermand 1.2",0
                cnop    0,4

EmptyTags       dc.l    TAG_DONE

CyberModeTags   dc.l    CYBRMREQ_CModelArray
                dc.l    ColorModel
                dc.l    TAG_DONE
ColorModel
                dc.w    PIXFMT_LUT8
                dc.w    -1

ColorOffsets    dc.w    $111
                dc.w    $100
                dc.w    $010
                dc.w    $001
                dc.w    $110
ColorOffsets256
                dc.l    $01000000,$01000000,$01000000
                dc.l    $01000000,0,0
                dc.l    0,$01000000,0
                dc.l    0,0,$01000000
                dc.l    $01000000,$01000000,0

ColorTable      dcb.w   32,0                    ;colortable for LoadRGB4
ColorTable256   dcb.l   256*3+2                 ;colortable for LoadRGB32

_LeftPos        dc.d    _LEFT_POS
_TopPos         dc.d    _TOP_POS
_RightPos       dc.d    _RIGHT_POS
_BottomPos      dc.d    _BOTTOM_POS
_Rad            dc.d    _RADIUS

                section "CyberMand_Bss",bss

                ds.b    32
bitmap1         ds.b    bm_SIZEOF               ;first bitmap structure
bitmap2         ds.b    bm_SIZEOF               ;second bitmap structure
tmpRP           ds.b    rp_SIZEOF               ;temporary rastport
TransTable      ds.l    256                     ;color translation table
_SysBase        ds.l    1                       ;base of exec.library
_DOSBase        ds.l    1                       ;base of dos.library
_GfxBase        ds.l    1                       ;base of graphics.library
_IntuitionBase  ds.l    1                       ;base of intuition.library
_CyberGfxBase   ds.l    1                       ;base of cybergraphics.library
_Screen         ds.l    1                       ;address of screen structure
_Window         ds.l    1                       ;address of window structure
_VPort          ds.l    1                       ;address of screen's ViewPort
_RPort          ds.l    1                       ;address of screen's RastPort
_ColorMap       ds.l    1                       ;viewport's colormap
ChunkyMem       ds.l    1                       ;Pointer to Chunky Memory
ChunkyBuffer    ds.l    1                       ;Pointer to the Chunkybuffer
ActualBitmap    ds.l    1                       ;bitmap currently displayed
HiddenBitmap    ds.l    1                       ;bitmap currently modified
request         ds.l    1                       ;return value of AllocASLRequest
NullPointer     ds.l    1                       ;pointer to empty pointer (CHIP)
ScrWidth        ds.w    1                       ;screenwidth
ScrHeight       ds.w    1                       ;screenheight
ScrDepth        ds.w    1                       ;screendepth
AreaWidth       ds.w    1                       ;width of graphics area
AreaHeight      ds.w    1                       ;height of graphics area
OldAreaWidth    ds.w    1                       ;place to save AreaWidth
OldAreaHeight   ds.w    1                       ;place to save AreaHeight
OldGZZWidth     ds.w    1                       ;used for resizing
OldGZZHeight    ds.w    1                       ;used for resizing
HorOffset       ds.w    1                       ;draw offset in window mode
                ds.b    32                      ;because of PPC cache flush
                cnop    0,4
LeftPos         ds.d    1                       ;left border of mandelbrot area
TopPos          ds.d    1                       ;top border of mandelbrot area
RightPos        ds.d    1                       ;right border of mandelbrot area
BottomPos       ds.d    1                       ;bottom border of mandelbrot area
                ds.b    32                      ;because of PPC cache flush
Radius          ds.d    1                       ;termination condition
Iterations      ds.w    1                       ;number of iterations
OldIterations   ds.w    1                       ;place to save Iterations
FullIterations  ds.w    1                       ;iterations in full screen mode
MouseDX         ds.w    1                       ;deltaX mouse coordinates
MouseDY         ds.w    1                       ;deltaY mouse coordinates
Precision       ds.b    1                       ;single or double precision
TurboDraw       ds.b    1                       ;if TRUE then C2P-Conversion
GameOver        ds.b    1                       ;termination flag
ZoomIn          ds.b    1                       ;switch to enable/disable zooming
ZoomOut         ds.b    1                       ;switch to enbale/disable zooming
Zoom            ds.b    1                       ;zoom value
Translation     ds.b    1                       ;translation value
Help            ds.b    1                       ;flag for help display
ForbidAnim      ds.b    1                       ;flag to forbid animation
ClearDisplay    ds.b    1                       ;clear the full screen display
WindowInActive  ds.b    1                       ;set when window is inactive
ColorNum        ds.b    1                       ;color number
PAL             ds.b    1                       ;display on PAL screen
Full            ds.b    1                       ;full size
V39             ds.b    1                       ;graphics.library V39 available
PowerPC         ds.b    1                       ;which CPU active
WindowMode      ds.b    1                       ;window mode
WindowModeOn    ds.b    1                       ;window mode enabled
Resizing        ds.b    1                       ;window is resized
Key_Up          ds.b    1                       ;move upwards
Key_Down        ds.b    1                       ;move downwards
Key_Left        ds.b    1                       ;move to the left
Key_Right       ds.b    1                       ;move to the right
NoMouse         ds.b    1                       ;disable mouse control
Shift           ds.b    1                       ;accelerate moving
                ds.b    32

