
* This file: gui v1.00

* (c) 1990 by H. Helminen

* linkage information:
* blink gui.o brot.o pipe.o to mandel lib amiga.lib

* And now for something completely different:
* A graphical user interface for MandelBrot.

* of course by The DM (Hannu Helminen, dm@stekt.oulu.fi)

* BUGS: many, including
* - coordinates in screen title may trash window title bar
* - if not enough memory, 56 bytes will disappear.

            NOLIST
            INCLUDE  "macros.i"
            INCLUDE  "mbrot.i"
            INCLUDE  "iff.i"
            INCLUDE  "exec/lists.i"
            INCLUDE  "exec/memory.i"
            INCLUDE  "exec/ports.i"
            INCLUDE  "exec/alerts.i"
            INCLUDE  "devices/timer.i"
            INCLUDE  "libraries/dos.i"
            INCLUDE  "libraries/dosextens.i"
            INCLUDE  "intuition/screens.i"
            INCLUDE  "intuition/intuition.i"
            INCLUDE  "workbench/workbench.i"
            INCLUDE  "workbench/startup.i"

            XREF     _LVOAlert

* Misc defines

DEPTH       EQU   5     ; # of bitplanes (use at least 3 (2 is minimum))
SCREEN      EQU   0

* SCREEN: Select one of the following:

*        non-lace lace
* lores     0       2
* hires     1       3

* SCREEN determines VIEWMODE, screen size and mb_dx/mb_dy scaling.
* NOTE: if SCREEN > 0, max. magnification will be 28

         ifeq  SCREEN-0
VIEWMODE    EQU   0
XSIZE       EQU   320      ; Size of screen
YSIZE       EQU   256
         endc
         ifeq  SCREEN-1
VIEWMODE    EQU   V_HIRES
XSIZE       EQU   640
YSIZE       EQU   256
         endc
         ifeq  SCREEN-2
VIEWMODE    EQU   V_LACE
XSIZE       EQU   320
YSIZE       EQU   512
         endc
         ifeq  SCREEN-3
VIEWMODE    EQU   V_HIRES|V_LACE
XSIZE       EQU   640
YSIZE       EQU   512
         endc

WINX        EQU   20      ; Place & size of info window
WINY        EQU   20
WINW        EQU   148
WINH        EQU   80

RASSIZE     EQU   ((XSIZE+15)/16*2)*YSIZE
MAXVECT     EQU   6553  ; Cant get bigger than this. (Sigh.)

NORMAL_X    EQU   0
NORMAL_Y    EQU   0
NORMAL_JX   EQU   0
NORMAL_JY   EQU   0
NORMAL_I    EQU   100
NORMAL_ZOOM EQU   $010000
NORMAL_M    EQU   $060000
MIN_M       EQU   $050000

         ifeq  SCREEN
MAX_M       EQU   $1d0000
         endc
         ifgt  SCREEN
MAX_M       EQU   $1c0000
         endc

FLAGS1      EQU   ACTIVATE|BACKDROP|BORDERLESS|REPORTMOUSE|RMBTRAP|NOCAREREFRESH
FLAGS2      EQU   WINDOWCLOSE|WINDOWDRAG|RMBTRAP|NOCAREREFRESH

IDCMP1      EQU   MOUSEMOVE|MOUSEBUTTONS|RAWKEY
IDCMP2      EQU   GADGETUP|GADGETDOWN|CLOSEWINDOW|RAWKEY

FAKECLASS   EQU   3  ; This pretends to be one of IDCMP classes

ZOOM        EQU   0  ; these internal tokens represent method of zooming
REDRAW      EQU   1
RESET       EQU   2

TRUE        EQU   1
FALSE       EQU   0

* Import brot entry point
            XREF  MandelBrot

* A simple macro that converts letters to upper case
toupper  macro
         cmp.b #'a',\1
         blo.s no\@
         sub.b #'a'-'A',\1
no\@:    ds.w  0           ; needed for assembler's sake.
         endm


            LIST


            SECTION  main,CODE

* This is where the actual code begins.
         push     d1-d7/a0-a6

         move.l   a0,a3
         move.w   d0,d3

* We need to find out whether we have been invoked from CLI or WorkBench
         sub.l    a1,a1
         Base     Exec
         Call     FindTask
         move.l   d0,a0          ; This is a process, right?
         move.l   pr_CLI(a0),d0
         beq.s    from_WB

         clr.b    -1(a3,d3.w)
         clr.l    WBmessage      ; from CLI
         move.l   d0,a0
         add.l    a0,a0          ; BPTR conversion
         add.l    a0,a0
         move.l   cli_CommandName(a0),a0  ; BSTR
         add.l    a0,a0          ; BPTR conversion
         add.l    a0,a0          ; now here we'll find a BCPL string...
         move.b   (a0)+,d0       ; get len and goto first character
         move.l   a0,MyName      ; save name
         ext.w    d0
         move.w   d0,MyNameLen   ; and length

         bra.s    common_code
from_WB:
         lea      pr_MsgPort(a0),a3
         move.l   a3,a0
         Call     WaitPort
         move.l   a3,a0
         Call     GetMsg
         move.l   d0,WBmessage   ; Do not reply until ready to exit.

         move.l   d0,a0
         move.l   sm_ArgList(a0),d0 ; Argument list
         beq.s    common_code
         move.l   d0,a0
         move.l   wa_Lock(a0),d2    ; lock to current directory
         move.l   wa_Name(a0),a0
         move.l   a0,MyName         ; save name
         moveq    #-1,d1
1$
         addq.w   #1,d1
         tst.b    (a0)+
         bne.s    1$
         move.w   d1,MyNameLen      ; and length

common_code:

* Open some libraries
         lea      _DosLib,a1
         moveq    #0,d0
         Call     OpenLibrary
         move.l   d0,_DosBase
         bne.s    dos_ok
         ALERT    AG_OpenLib|AO_DOSLib
         bra      nodos
dos_ok:
         tst.l    WBmessage
         beq.s    1$
         move.l   d2,d1
         Base     Dos
         Call     CurrentDir
         Base     Exec
1$
         lea      _IntuitionLib,a1
         moveq    #0,d0
         Call     OpenLibrary
         move.l   d0,_IntuitionBase
         bne.s    intui_ok
         ALERT    AG_OpenLib|AO_Intuition
         bra      nointui
intui_ok:
         lea      _GfxLib,a1
         moveq    #0,d0
         Call     OpenLibrary
         move.l   d0,_GfxBase
         bne.s    gfx_ok
         ALERT    AG_OpenLib|AO_GraphicsLib
         bra      nogfx
gfx_ok:

* Open timer.device
         lea      _TimerDev,a0
         moveq    #UNIT_VBLANK,d0
         lea      IOreq,a1
         moveq    #0,d1
         Call     OpenDevice
         tst.b    d0
         beq.s    timer_ok
         ALERT    AG_OpenDev|AO_TimerDev
         bra      timererr
timer_ok:
* initialize msgport
         lea      MsgPort,a2
         move.b   #NT_MSGPORT,LN_TYPE(a2)
         clr.b    LN_PRI(a2)
         clr.l    LN_NAME(a2)
         move.b   #PA_SIGNAL,MP_FLAGS(a2)    ; signal me when done

         moveq    #-1,d0
         move.b   #ERROR_nosignal,error
         Call     AllocSignal          ; get a signal bit
         tst.b    d0
         bmi      nosignal
         move.b   d0,MP_SIGBIT(a2)

         sub.l    a1,a1
         Call     FindTask
         move.l   d0,MP_SIGTASK(a2)
                                       ; task to be signalled
         lea      MP_MSGLIST(a2),a0
         NEWLIST  a0                   ; init link fields
         lea      IOreq,a0
         move.l   a2,MN_REPLYPORT(a0)
         clr.l    UseReq               ; mark it as not being in use

         move.l   a3,a0

         lea      MyMandelBrot,a4

         move.w   #0,mb_x1(a4)
         move.w   #0,mb_y1(a4)
         move.w   #XSIZE-1,mb_x2(a4)
         move.w   #YSIZE-1,mb_y2(a4)

* Defaults
         move.b   #ERROR_none,error
         move.w   #NORMAL_I,mb_i(a4)
         move.b   #MBF_AUTOPREC|MBF_AUTOCRAWL,mb_flags(a4)
         move.b   #TRUE,inter
         move.b   #ZOOM,method
         clr.b    isdrawn
         clr.w    Counter
         clr.b    saveit

         move.l   #NORMAL_ZOOM,Zoom    ; 2^(-1) = 50%
         move.l   #NORMAL_M,Magnify    ; 2^(-6) = 1/64
         move.l   #NORMAL_X,CurrentX
         move.l   #NORMAL_Y,CurrentY
         move.l   #NORMAL_JX,mb_jx(a4)
         move.l   #NORMAL_JY,mb_jy(a4)

         lea      CtrlC,a1
         move.l   a1,mb_break(a4)   ; Call-back procedure

         move.w   #(1<<DEPTH)-2,mb_colors(a4)

* This is again WB/CLI specific code, option processing
         tst.l    WBmessage
         beq      CLI_1

* WB option stuff
         Base     Exec
         lea      _IconLib,a1
         moveq    #0,d0
         Call     OpenLibrary
         tst.l    d0
         bne.s    iconlib_ok
* Currently this error is not reported...
         move.b   #ERROR_iconlib,error
         bra      options_done
iconlib_ok
         move.l   d0,a6
         move.l   MyName,a0
         Call     GetDiskObject
         tst.l    d0
         bne.s    diskobject_ok
         move.b   #ERROR_noicon,error
         bra.s    close_icon_lib
diskobject_ok
         move.l   d0,a5          ; disk object
         lea      WBjumptable,a2
         lea      WBoptions,a3
browse_tools
         tst.b    (a3)              ; The last in line?
         beq.s    icons_done
         move.l   do_ToolTypes(a5),a0
         move.l   a3,a1
         Call     FindToolType
         move.l   (a2)+,a1          ; The actual address to jump to
         tst.l    d0
         beq.s    tool_notfound
         move.l   d0,a0
         jsr      (a1)
         beq.s    wrong_option
tool_notfound
         tst.b    (a3)+
         bne.s    tool_notfound     ; Find next tool type
         bra.s    browse_tools
wrong_option
         move.b   #ERROR_tooltype,error
icons_done
         move.l   a5,a0
         Call     FreeDiskObject
close_icon_lib
         move.l   a6,a1
         Base     Exec
         Call     CloseLibrary
         tst.b    error
         bne      nosignal
         bra.s    options_done

CLI_1
         lea      LongUsage,a3
         move.l   #LongLen,d3
         tst.b    (a0)
         beq.s    options_done
         cmp.b    #'?',(a0)
         beq.s    usage

         move.b   #ERROR_cmdline,error
         lea      ShortUsage,a3
         move.l   #ShortLen,d3
getnext:
         move.b   (a0)+,d0
         beq.s    options_done
         cmp.b    #' ',d0
         beq.s    getnext
         cmp.b    #8,d0
         beq.s    getnext
         cmp.b    #'-',d0
         bne.s    usage

         move.b   (a0)+,d0
         lea      options,a1
         lea      jumptable,a2

         toupper  d0
getopt:
         move.l   (a2)+,a5
         cmp.b    (a1)+,d0
         bne.s    next
         jsr      (a5)
         beq.s    usage          ; a result of zero means wrong option
         bra.s    getnext
next:
         tst.b    (a1)
         bne.s    getopt
usage:
         Base     Dos
         Call     Output
         move.l   d0,d1
         move.l   a3,d2
         Call     Write
         bra      noscreen       ; draw nothing
options_done:

* Screen to display the new map.
         lea      MyNewScreen,a0
         Base     Intuition
         Call     OpenScreen
         move.b   #ERROR_noscreen,error
         move.l   d0,MyScreen
         beq      noscreen
         move.l   d0,a2

         move.l   a2,InsertScreen1
         move.l   a2,InsertScreen2

         lea      sc_ViewPort(a2),a3

* First window that takes over entire screen
         lea      MyNewWindow1,a0
         Call     OpenWindow
         move.b   #ERROR_nowindow,error
         move.l   d0,MyWindow1
         beq      nowindow

* This version fetches windows rastport.
         move.l   d0,a0
         move.l   wd_RPort(a0),a2
         move.l   a2,mb_RastPort(a4)

         move.l   a3,a0
         lea      Colors,a1
         moveq    #(1<<DEPTH),d0
         Base     Gfx
         Call     LoadRGB4

* Now get a TmpRas to screen
         move.l   #RASSIZE,d0
         moveq    #MEMF_CHIP,d1
         move.l   d1,d2
         Base     Exec
         Call     AllocMem
         move.b   #ERROR_nomem,error
         move.l   d0,Mem1
         beq      nomem1
         lea      MyTmpRas,a3
         move.l   d0,a1
         move.l   a3,a0
         move.l   d2,d0
         Base     Gfx
         Call     InitTmpRas
         move.l   a3,rp_TmpRas(a2)

         move.l   #MAXVECT*5,d0
         moveq    #0,d1
         Base     Exec
         Call     AllocMem
         move.l   d0,Mem2
         beq      nomem2
         lea      MyAreaInfo,a3
         move.l   a3,a0
         move.l   d0,a1
         move.l   #MAXVECT,d0
         Base     Gfx
         Call     InitArea
         move.l   a3,rp_AreaInfo(a2)

         move.b   #ERROR_none,error
* main loop if 'interactive'
loop:
         move.l   Magnify,d0
         move.l   #MAX_M,d1
         cmp.l    d1,d0
         bls.s    1$
         move.l   d1,d0
1$:
         move.l   #MIN_M,d1
         cmp.l    d1,d0
         bhs.s    2$
         move.l   d1,d0
2$:
         move.l   d0,Magnify
         bsr      Transform
         move.l   Magnify,OldMagnify

* This is why we did all the above... and will be doing all the below...
* Draw mandelbrot!
         move.l   a4,a0
         jsr      MandelBrot

         tst.b    inter
         beq      exit        ; user didnt want us to be interactive.

* A friend of mine once pointed out that the doings of my
* programs are often commented to be done by "we". Don't know why.

* Perhaps I think my program is a person, and we are doing the
* thing together, I by designing the program, and the program
* in turn by running it.

* One of these days, I may actually begin to talk to my programs.
* Is that all right to you, my tiny little proggie?

         bsr      calculate
reopen:
* Open another window
         lea      MyNewWindow2,a0
         Base     Intuition
         Call     OpenWindow
         move.l   d0,MyWindow2
         beq      exit_dont_save      ; could not get memory
* Thenafter, refresh allll gadgets.

* This gives refresh_m and refresh_z a hassle-free operation
         move.b   method,d7
         move.b   #RESET,method

         move.l   CurrentX,d0
         bsr      refresh_x
         move.l   CurrentY,d0
         bsr      refresh_y
         move.l   Magnify,d0
         bsr      refresh_m
         move.w   mb_i(a4),d0
         bsr      refresh_i
         move.l   Zoom,d0
         bsr      refresh_z

         move.b   d7,method

         bsr      refresh_set
         bsr      refresh_zoom   ; this does also DrawGrid

msgloop:
         bsr      GetMessage
         bne      exitloop        ; nonzero if user issued break
gotmessage:
         Base     Intuition
         cmp.l    #CLOSEWINDOW,d2
         bne.s    no_close


* Info window is about to be closed. Hide also title bar.
         move.l   MyWindow2,a0

* This copies both LeftEdge and TopEdge to NewWindow structure
* This way when the window is opened again, it will be in same place.
         move.l   wd_LeftEdge(a0),MyNewWindow2
         Call     CloseWindow
         clr.l    MyWindow2   ; This window is closed
         move.l   MyScreen,a0
         moveq    #FALSE,d0
         Call     ShowTitle
         bsr      RemoveGrid

* Resume when either button pressed
get_it:  bsr      GetMessage
         bne      exit        ; break, no need to close window
         cmp.l    #MOUSEBUTTONS,d2
         bne.s    get_it      ; wait for it to happen

* Restore all
         bsr      DrawGrid
         move.l   MyScreen,a0
         moveq    #TRUE,d0
         Base     Intuition
         Call     ShowTitle
         bra      reopen      ; resume window


no_close:
         cmp.l    #MOUSEMOVE,d2
         bne.s    no_move
         bsr      dispCoords  ; All we do here is to display current
         bra.s    msgloop     ; coordinates


no_move:
         cmp.l    #MOUSEBUTTONS,d2
         bne.s    no_buttons
         cmp.w    #SELECTDOWN,d3
         bne.s    no_left_button
         bsr      LeftButton     ; 3 things might get returned:
         beq      msgloop     ; finished
         bmi      exitloop    ; ^C
         bra      zoom_draw   ; There has been a double-click -> Draw!
no_left_button:
         cmp.w    #MENUDOWN,d3
         bne.s    no_buttons
         bsr      RightButton
         bne      exitloop
         bra      msgloop
no_buttons:

         cmp.w    #GADGETDOWN,d2
         bne.s    no_gadg_down
         move.w   gg_GadgetID(a5),d1   ; Gadget's ID.
         move.w   d1,d0
         and.w    #STRING,d0
         beq.s    not_string_gadget

         bsr      StringGadgetDown  ; we also get one message here.
         bne      exitloop          ; sigh. (l)user wants to get rid of us
         bra      gotmessage        ; yeah, we've already got one.
not_string_gadget:
         bsr      OtherGadgetDown   ; Three things might return from this:
         bmi.s    zoom_draw         ; negative if zoom
         bne      exitloop          ; positive if exit

no_gadg_down:
         cmp.l    #RAWKEY,d2
         bne.s    no_rawkey
         cmp.w    #$21,d3           ; RAW key code for 'S'
         bne.s    no_rawkey
         btst     #IEQUALIFIERB_CONTROL,d4
         beq.s    no_rawkey
         move.l   MyWindow2,a0
         move.l   wd_LeftEdge(a0),MyNewWindow2  ; See previous CloseWindow
         Call     CloseWindow
         clr.l    MyWindow2      ; This window is closed
         move.l   MyScreen,a0
         moveq    #FALSE,d0
         Call     ShowTitle
         bsr      RemoveGrid

         bsr      SavePicture

         bsr      DrawGrid
         move.l   MyScreen,a0
         moveq    #TRUE,d0
         Base     Intuition
         Call     ShowTitle
         bra      reopen      ; open window again

no_rawkey:
         bra      msgloop           ; and zero if nothing

zoom_draw:
         move.l   MyWindow2,a0
         Base     Intuition
         move.l   wd_LeftEdge(a0),MyNewWindow2  ; See previous CloseWindow
         Call     CloseWindow
         bsr      RemoveGrid
         cmp.b    #ZOOM,method
         beq.s    1$
         cmp.b    #REDRAW,method
         beq.s    2$
         move.l   #NORMAL_M,Magnify
         move.l   #NORMAL_X,CurrentX
         move.l   #NORMAL_Y,CurrentY
         bra      loop
1$:
         move.l   Zoom,d0
         add.l    d0,Magnify
2$:
         bra      loop




exitloop:
* Close window
         move.l   MyWindow2,a0
         Base     Intuition
         Call     CloseWindow
         bsr      RemoveGrid

* Leave ship
exit:
* If non-interactive and user explicitely set -s option, save picture.
         tst.b    inter
         bne.s    exit_dont_save
         tst.b    saveit
         beq.s    exit_dont_save
         bsr      SavePicture
exit_dont_save
         move.l   MyScreen,a0
         moveq    #FALSE,d0
         Base     Intuition
         Call     ShowTitle

         move.l   Mem2,a1
         move.l   #5*MAXVECT,d0
         Base     Exec
         Call     FreeMem
nomem2:
         move.l   Mem1,a1
         move.l   #RASSIZE,d0
         Base     Exec
         Call     FreeMem
nomem1:
         Base     Intuition
         move.l   MyWindow1,a0
         Call     CloseWindow
nowindow:
         move.l   MyScreen,a0
         Call     CloseScreen
noscreen:
         lea      MsgPort,a0
         move.b   MP_SIGBIT(a0),d0
         Base     Exec
         Call     FreeSignal
nosignal:
         lea      IOreq,a1
         Call     CloseDevice
timererr:
         move.l   _GfxBase,a1
         Call     CloseLibrary
nogfx:
         move.l   _IntuitionBase,a1
         Call     CloseLibrary
nointui:
         tst.b    error
         beq.s    close_dos   ; no error

         Base     Dos
         tst.l    WBmessage
         beq.s    CLI_2
         lea      stdout_name,a0
         move.l   a0,d1
         move.l   #MODE_NEWFILE,d2
         Call     Open
         tst.l    d0
         beq.s    close_dos
         bra.s    common_code2
CLI_2
         Call     Output
common_code2
         move.l   d0,d4       ; save file handle for further use

* First, output our name.
         move.l   d4,d1
         move.l   MyName,d2
         move.w   MyNameLen,d3
         ext.l    d3
         Call     Write

* Then, the error message.
         move.l   d4,d1
         move.b   error,d0
         ext.w    d0
         lsl.w    #2,d0
         lea      errors,a0
         move.l   0(a0,d0.w),a0
         move.l   a0,d2
         moveq    #-1,d3
1$
         addq.l   #1,d3
         tst.b    (a0)+
         bne.s    1$
         Call     Write

         tst.l    WBmessage
         beq.s    close_dos
         move.l   #2*TICKS_PER_SECOND,d1
* REM ALLOW TIME FOR USER TO RELEASE BUTTON FROM LAST PUSH
         Call     Delay
         move.l   d4,d1
         Call     Close       ; close stdout window
close_dos
         Base     Exec
         move.l   _DosBase,a1
         Call     CloseLibrary
         move.l   WBmessage,d0
         beq.s    nodos
         Call     Forbid
         move.l   d0,a1
         Call     ReplyMsg       ; Now WB knows we are safe to get rid of
nodos:
         moveq    #0,d0
         move.b   error,d0
         beq.s    2$
         moveq    #RETURN_FAIL,d0
2$:
         pull     d1-d7/a0-a6
         rts

RemoveGrid:
         tst.b    isdrawn
         beq      nothing_to_remove

         push     d0-d2/a0-a2/a6

         Base     Intuition
         move.l   MyWindow1,a0
         move.l   wd_RPort(a0),a2

* DrawGrid has conveniently set up some values for me. How nice of him!
         move.w   centerx,d0
         move.w   centery,d1
         move.l   pic_c,a1
         bsr.s    remove_1

         move.w   lowx,d0
         move.w   lowy,d1
         move.l   pic_tl,a1
         bsr.s    remove_1

         move.w   lowx,d0
         move.w   highy,d1
         move.l   pic_bl,a1
         bsr.s    remove_1

         move.w   highx,d0
         move.w   lowy,d1
         move.l   pic_tr,a1
         bsr.s    remove_1

         move.w   highx,d0
         move.w   highy,d1
         move.l   pic_br,a1
         bsr.s    remove_1

         clr.b    isdrawn
         pull     d0-d2/a0-a2/a6
nothing_to_remove:
         rts

remove_1:
         move.l   a2,a0
         move.l   a1,d2
         beq.s    1$
         Call     DrawBorder
1$:      rts


DrawGrid:
         bsr      RemoveGrid
         cmp.b    #ZOOM,method
         beq.s    draw_yes
         cmp.b    #RESET,method
         beq      draw_over
         move.l   Magnify,d0
         cmp.l    OldMagnify,d0
         bne      draw_over
draw_yes:
         push     a0-a2/a6/d0-d7
         move.l   prex,d0
         move.l   prey,d1
         move.b   #TRUE,isdrawn

         move.l   d0,prex
         move.l   d1,prey
         move.l   #$8000,d2      ; round
         add.l    d2,d0
         add.l    d2,d1

         move.l   d0,d4
         move.l   d1,d5

         swap     d0
         swap     d1

         moveq    #0,d2          ; record # of crossings
         Base     Intuition
         lea      Cross,a1
         move.l   MyWindow1,a0
         move.l   wd_RPort(a0),a2

         cmp.w    mb_x1(a4),d0
         bge.s    1$
         move.w   mb_x1(a4),d0
         lea      LeftLeft,a1
         addq.w   #1,d2
1$:
         cmp.w    mb_x2(a4),d0
         ble.s    2$
         move.w   mb_x2(a4),d0
         lea      RightRight,a1
         addq.w   #1,d2
2$:
         cmp.w    mb_y1(a4),d1
         bge.s    3$
         move.w   mb_y1(a4),d1
         lea      UpUp,a1
         addq.w   #1,d2
3$:
         cmp.w    mb_y2(a4),d1
         ble.s    4$
         move.w   mb_y2(a4),d1
         lea      DownDown,a1
         addq.w   #1,d2
4$:
         cmp.w    #1,d2       ; only 1 crossing allowed
         bls.s    ok_to_disp
         clr.l    pic_c
         bra.s    cross_over
ok_to_disp:
         move.w   d0,centerx
         move.w   d1,centery

         move.l   a2,a0
         move.l   a1,pic_c
         Call     DrawBorder
cross_over:
         move.w   mb_x2(a4),d0
         sub.w    mb_x1(a4),d0
         move.l   Zoom,d3

         cmp.b    #REDRAW,method ; if redraw, grid has size of screen
         bne.s    revolution
         moveq    #0,d3
revolution:
         add.l    #$10000,d3
         bmi      pig_big

         moveq    #0,d1
         moveq    #0,d2
         bsr      Power2
* Hey! What are you doing?
* We will find how long the side of the grid should be.
* If Zoom < -$10000, it wont fit on the screen same time as
* crosshairs. And adding $10000 means halving the distance,
* and as it happens, that is just what we want!
         move.l   d0,d6

         move.w   mb_y2(a4),d0
         sub.w    mb_y1(a4),d0
         bsr      Power2         ; d1-d3 remain!
         move.l   d0,d7

         move.l   d4,d2
         move.l   d5,d3
         sub.l    d6,d2          ; note! d7 has a remainder similar to
         sub.l    d7,d3          ; that of d4
         add.l    d6,d4
         add.l    d7,d5
         swap     d2
         swap     d3
         swap     d4
         swap     d5

         moveq    #0,d6
         move.w   mb_x1(a4),d0
         move.w   mb_x2(a4),d1
         cmp.w    d0,d2
         bge.s    1$
         move.w   d0,d2
         bset     #0,d6
1$:
         cmp.w    d1,d2
         bgt      pig_big
         cmp.w    d1,d4
         ble.s    2$
         move.w   d1,d4
         bset     #1,d6
2$:
         cmp.w    d0,d4
         blt      pig_big
         move.w   mb_y1(a4),d0
         move.w   mb_y2(a4),d1
         cmp.w    d0,d3
         bge.s    3$
         move.w   d0,d3
         bset     #2,d6
3$:
         cmp.w    d1,d3
         bgt      pig_big
         cmp.w    d1,d5
         ble.s    4$
         move.w   d1,d5
         bset     #3,d6
4$:
         cmp.w    d0,d5
         blt      pig_big

         move.w   d2,lowx
         move.w   d3,lowy
         move.w   d4,highx
         move.w   d5,highy

* process the corners.
         push     a3-a5    ; NEED some workspace
         lea      TopLeft,a1
         lea      BottomLeft,a3
         lea      TopRight,a4
         lea      BottomRight,a5
         btst.b   #0,d6
         beq      no_left
         lea      LeftLeft,a1
         move.l   a1,a3
no_left:
         btst.b   #1,d6
         beq.s    no_right
         lea      RightRight,a4
         move.l   a4,a5
no_right:
         btst.b   #2,d6
         beq.s    no_up
         lea      UpUp,a1
         move.l   a1,a4
no_up:
         btst.b   #3,d6
         beq.s    no_down
         lea      DownDown,a3
         move.l   a3,a5
no_down:
         not.b    d6
         move.b   d6,d0
         and.b    #%0101,d0
         bne.s    skip_tl
         sub.l    a1,a1
skip_tl:
         move.b   d6,d0
         and.b    #%1001,d0
         bne.s    skip_bl
         sub.l    a3,a3
skip_bl:
         move.b   d6,d0
         and.b    #%0110,d0
         bne.s    skip_tr
         sub.l    a4,a4
skip_tr:
         and.b    #%1010,d6
         bne.s    skip_br
         sub.l    a5,a5
skip_br:
         move.l   a2,a0
         move.l   a1,pic_tl
         beq.s    no_tl
         move.w   d2,d0
         move.w   d3,d1
         Call     DrawBorder
no_tl:
         move.l   a3,a1
         move.l   a2,a0
         move.l   a1,pic_bl
         beq.s    no_bl
         move.w   d2,d0
         move.w   d5,d1
         Call     DrawBorder
no_bl:
         move.l   a4,a1
         move.l   a2,a0
         move.l   a1,pic_tr
         beq.s    no_tr
         move.w   d4,d0
         move.w   d3,d1
         Call     DrawBorder
no_tr:
         move.l   a5,a1
         move.l   a2,a0
         move.l   a1,pic_br
         beq.s    no_br
         move.w   d4,d0
         move.w   d5,d1
         Call     DrawBorder
no_br:
         pull     a3-a5
         bra.s    draw_pulling
pig_big:
         clr.l    pic_tl
         clr.l    pic_bl
         clr.l    pic_tr
         clr.l    pic_br
draw_pulling:
         pull     a0-a2/a6/d0-d7
draw_over:
         rts

calculate:
* Calculate centerpoint coordinates.
* Only needed when string gadget updated.
* The formula we use is (CurrentX - mb_x(a4)) / mb_dx(a4) (for x)
* and because I would have to use 32-bit division which my processor
* does unfortunately not have any instructions for, we use 16-bit
* division, which is much more tricky!

* Another problem occurs when user enters a number that is NOT
* in the visible area. Because our number system can only represent
* numbers from -4 to 4, we have no reliable way of telling whether
* user wants to see grid to be (arrows!) to the LEFT, for instance,
* or to the RIGHT.

* Currently any such numbers map to RIGHT and DOWN. One could try
* to fix it by choosing numbers that are as close to previous prex
* and prey as possible.
* I wont try to code that, however, my hair is grey enough now.

         push     d0-d4
         move.l   mb_dx(a4),d2
         move.l   CurrentX,d4
         sub.l    mb_x0(a4),d4
fix_div_x:
         cmp.l    #$10000,d2
         blo.s    fixed_x
         lsr.l    #1,d2
         lsr.l    #1,d4
         bra.s    fix_div_x
fixed_x:
         divu     d2,d4
         move.l   d4,d0    ; renormalize remainder
         clr.w    d0
         divu     d2,d0
         swap     d0
         move.w   d4,d0

         move.l   mb_dy(a4),d2
         move.l   mb_y0(a4),d4
         sub.l    CurrentY,d4
fix_div_y:
         cmp.l    #$10000,d2
         blo.s    fixed_y
         lsr.l    #1,d2
         lsr.l    #1,d4
         bra.s    fix_div_y
fixed_y:
         divu     d2,d4
         move.l   d4,d1
         clr.w    d1
         divu     d2,d1
         swap     d1
         move.w   d4,d1

         swap     d0
         swap     d1

         move.l   d0,prex
         move.l   d1,prey
         pull     d0-d4
         rts

StringGadgetDown:
* GadgetID in d1
         and.w    #IDMASK,d1

* We will wait for another message, thenafter we know the user has
* finished playing with the string gadget. This message could be the
* GADGETUP of same gadget, but then again, it could be something
* else.
* We must preserve the message (so that main loop may handle it).
         move.l   a5,a1       ; save gadget
         bsr      GetMessage

         move.l   gg_SpecialInfo(a1),a0
         move.l   si_Buffer(a0),a0        ; addr of the actual string

         cmp.w    #GAD_X,d1
         beq.s    gadget_x
         cmp.w    #GAD_Y,d1
         beq.s    gadget_y
         cmp.w    #GAD_M,d1
         beq      gadget_m
         cmp.w    #GAD_Z,d1
         beq.s    gadget_z
* now it must be IGadget
         bsr      GetNum
         beq.s    2$
         tst.b    (a0)
         beq.s    1$
2$:
         move.w   mb_i(a4),d0
1$:      move.w   d0,mb_i(a4)
         bsr      refresh_i
         bra.s    gadget_done

gadget_x:
         bsr      GetFixed
         beq.s    2$
         tst.b    (a0)     ; if user entered some ugly stuff after numbers
         beq.s    1$
2$:
         move.l   CurrentX,d0 ; invalid -> get previous
1$:      move.l   d0,CurrentX
         bsr      calculate
         bsr      refresh_x
         bsr      DrawGrid
         bra.s    gadget_done

gadget_y:
         bsr      GetFixed
         beq.s    2$
         tst.b    (a0)
         beq.s    1$
2$:
         move.l   CurrentY,d0
1$:      move.l   d0,CurrentY
         bsr      calculate
         bsr      refresh_y
         bsr      DrawGrid
         bra.s    gadget_done

gadget_z:
         bsr      GetSMagnify
         beq.s    2$
         tst.b    (a0)
         beq.s    1$
2$:
         move.l   Zoom,d0
1$:      move.l   d0,Zoom
         bsr      refresh_z
         bra.s    gadget_done
gadget_m:
         bsr      GetMagnify
         beq.s    2$
         tst.b    (a0)
         beq.s    1$
2$:
         move.l   Magnify,d0
1$:      move.l   d0,Magnify
         bsr      refresh_m

gadget_done:
         moveq    #0,d0

get_rid_of_us:
         rts


OtherGadgetDown:
* GadgetID in d1
         move.w   d1,d0
         and.w    #ZOOMTYPE,d0
         beq      not_zoom_gadget
         and.w    #IDMASK,d1

         move.b   #ZOOM,d0
         cmp.w    #GAD_ZOOM,d1
         beq.s    1$

         move.b   #REDRAW,d0
         cmp.w    #GAD_DRAW,d1
         beq.s    1$

         move.b   #RESET,d0
1$:
         move.b   d0,method
         bsr      refresh_zoom
* Double-click to start drawing
         move.l   OldSecs,d0
         move.l   OldMicros,d1
         move.l   a2,d2
         move.l   a3,d3
         move.l   a2,OldSecs
         move.l   a3,OldMicros
         Call     DoubleClick
         tst.w    d0
         beq.s    not_yet
         moveq    #-1,d0         ; result is negative
not_yet:
         rts

not_zoom_gadget:
         move.w   d1,d0
         and.w    #SETTYPE,d0
         beq.s    not_set_gadget
         and.w    #IDMASK,d1

         bclr.b   #MBB_JULIA,mb_flags(a4)
         cmp.w    #GAD_MANDEL,d1
         beq.s    1$
         bset.b   #MBB_JULIA,mb_flags(a4)
1$:
         bsr      refresh_set

         moveq    #FALSE,d0
         rts

not_set_gadget:
         cmp.w    #GAD_QUIT,d1
         bne.s    not_quit_gadget
* Double-click to exit
         move.l   OldSecs,d0
         move.l   OldMicros,d1
         move.l   a2,d2
         move.l   a3,d3
         move.l   a2,OldSecs
         move.l   a3,OldMicros
         Call     DoubleClick
         tst.w    d0
         beq.s    first_click
         moveq    #TRUE,d0          ; +1 -> quitting
first_click:
         rts

not_quit_gadget:
         and.w    #IDMASK,d1
         moveq    #0,d7
         move.w   d1,d7
it_was_timer:
         bsr      plus_minus
         lea      IOreq,a1

* Shortage of registers -- we must use upper half of d7
         swap     d7
         move.l   #400000,d0  ; .4 seconds initial delay
         tst.w    d7
         beq.s    huu_haa_joo_jaa
         move.l   #100000,d0  ; .1 seconds next 9
         cmp.w    #9,d7
         blo.s    huu_haa_joo_jaa
         move.l   #020000,d0  ; 1/25 seconds
         move.w   #-2,d7      ; neverending!
huu_haa_joo_jaa:
         addq.w   #1,d7
         swap     d7

         move.w   #TR_ADDREQUEST,IO_COMMAND(a1)
         move.l   #0,IOTV_TIME+TV_SECS(a1)
         move.l   d0,IOTV_TIME+TV_MICRO(a1)
         move.l   a1,UseReq
         Base     Exec
         Call     SendIO
         bsr      GetMessage
         bne.s    1$             ; that old ^C
         cmp.w    #FAKECLASS,d2
         beq.s    it_was_timer
         moveq    #FALSE,d7
         bra.s    2$
1$:
         moveq    #TRUE,d7
2$:
         move.l   UseReq,a1
         Call     AbortIO
         move.l   UseReq,a1
         Call     WaitIO
         clr.l    UseReq
         tst.w    d7
         rts

         moveq    #0,d0
         rts

plus_minus:
* GadgetID in d2
         push     d0-d1
         move.w   d7,d0
         moveq    #1,d1
         and.w    #$7fff,d0
         cmp.w    #GAD_X,d0
         bne.s    skip_x

         move.l   mb_dx(a4),d0
         swap     d1
         tst.w    d7
         bpl.s    1$
         neg.l    d0
         neg.l    d1
1$:
         add.l    d0,CurrentX
         add.l    d1,prex
         move.l   CurrentX,d0
         bsr      refresh_x
         bsr      DrawGrid
         bra      plus_minus_done
skip_x:
         cmp.w    #GAD_Y,d0
         bne.s    skip_y

         move.l   mb_dy(a4),d0
         swap     d1
         tst.w    d7
         bpl.s    1$
         neg.l    d0
         neg.l    d1
1$:
         add.l    d0,CurrentY
         sub.l    d1,prey
         move.l   CurrentY,d0
         bsr      refresh_y
         bsr      DrawGrid
         bra.s    plus_minus_done
skip_y:
         cmp.w    #GAD_M,d0
         bne.s    skip_m

         move.l   #$1999,d0
         tst.w    d7
         bpl.s    1$
         neg.l    d0
1$:
         add.l    d0,Magnify
         move.l   Magnify,d0
         bsr      refresh_m
         bra.s    plus_minus_done
skip_m:
         cmp.w    #GAD_Z,d0
         bne.s    skip_z

         move.l   #$1999,d0
         tst.w    d7
         bpl.s    1$
         neg.l    d0
1$:
         add.l    d0,Zoom
         move.l   Zoom,d0
         bsr      refresh_z
         bra.s    plus_minus_done
skip_z:
         cmp.w    #GAD_I,d0
         bne.s    plus_minus_done

         tst.w    d7
         bpl.s    1$
         neg.l    d1
1$:
         add.w    d1,mb_i(a4)
         move.w   mb_i(a4),d0
         bsr      refresh_i
plus_minus_done:
         pull     d0-d1
         rts



* This group of routines updates whatever visual clues the user might
* have about the current situation.

* NOTE: a DrawGrid is needed after every refresh_x or refresh_y.
* (To avoid drawing it twice if both coords updated)

* d0 is the fresh number.
* Preserves all registers.
refresh_x:
         push     d0-d2/d7/a0-a3/a6
         move.l   MyWindow2,a2   ; save thing from being overwritten
         lea      XGadget,a3
* If in MANDEL mode, alter c = jx + jy settings.
* So user may set jx,jy, enter JULIA mode and still
* select another point.
         btst.b   #MBB_JULIA,mb_flags(a4)
         bne.s    1$
         move.l   d0,mb_jx(a4)
1$:
         move.l   d0,d2

         move.l   a2,a0          ; window
         move.l   a3,a1          ; gadget
         Base     Intuition
         Call     RemoveGadget   ; remove, modify, add back.
* Later we will insert this gadget back to its original place.
* That is why d2 gets position. toDec needs number in d0.
         exg.l    d0,d2

         move.l   gg_SpecialInfo(a3),a0
         move.l   si_Buffer(a0),a0

         move.l   mb_dx(a4),d7   ; delta (see toDec why)
         bsr      toDec
         clr.b    (a0)

         bsr      refresh_add_gadget
         pull     d0-d2/d7/a0-a3/a6
         rts
refresh_y:
         push     d0-d2/d7/a0-a3/a6
         move.l   MyWindow2,a2   ; save things from being overwritten
         lea      YGadget,a3

         btst.b   #MBB_JULIA,mb_flags(a4)
         bne.s    1$
         move.l   d0,mb_jy(a4)
1$:
         move.l   d0,d2

         move.l   a2,a0          ; window
         move.l   a3,a1          ; gadget
         Base     Intuition
         Call     RemoveGadget   ; remove, modify, add back.

         exg.l    d0,d2

         move.l   gg_SpecialInfo(a3),a0
         move.l   si_Buffer(a0),a0

         move.l   mb_dy(a4),d7   ; delta (see toDec why)
         bsr      toDec
         clr.b    (a0)

         bsr      refresh_add_gadget
         pull     d0-d2/d7/a0-a3/a6
         rts
refresh_z:
         push     d0-d2/a0-a3/a6
         move.l   MyWindow2,a2   ; save thing from being overwritten
         lea      ZGadget,a3
         move.l   d0,d2

         move.l   a2,a0          ; window
         move.l   a3,a1          ; gadget
         Base     Intuition
         Call     RemoveGadget   ; remove, modify, add back.
* Later we will insert this gadget back to its original place.
* That is why d2 gets position. toDec needs number in d0.
         exg.l    d0,d2

         move.l   gg_SpecialInfo(a3),a0
         move.l   si_Buffer(a0),a0

         move.b   #'+',d1
         tst.l    d0
         bpl.s    1$
         neg.l    d0
         move.b   #'-',d1
1$:
         move.b   d1,(a0)+

         bsr      toMag
         clr.b    (a0)

         bsr      refresh_add_gadget

         cmp.b    #REDRAW,method
         bne.s    2$
         move.l   OldMagnify,d0
         move.l   d0,Magnify
         bsr      refresh_m         ; to show magnify is again normal
         move.b   #ZOOM,method      ; NOTE: this must be AFTER refresh_m
         bsr      refresh_zoom      ; does also DrawGrid
         bra.s    3$                ; so dont waste time doing it again
2$:
         bsr      DrawGrid
3$:
         pull     d0-d2/a0-a3/a6
         rts
refresh_i:
         push     d0-d2/a0-a3/a6
         move.l   MyWindow2,a2   ; save thing from being overwritten
         lea      IGadget,a3
         move.l   d0,d2

         move.l   a2,a0          ; window
         move.l   a3,a1          ; gadget
         Base     Intuition
         Call     RemoveGadget   ; remove, modify, add back.
* Later we will insert this gadget back to its original place.
* That is why d2 gets position. toDec needs number in d0.
         exg.l    d0,d2

         move.l   gg_SpecialInfo(a3),a0
         move.l   si_Buffer(a0),a0

         bsr      toInt
         clr.b    (a0)

         bsr.s    refresh_add_gadget
         pull     d0-d2/a0-a3/a6
         rts
refresh_m:
         push     d0-d2/a0-a3/a6
         move.l   MyWindow2,a2   ; save thing from being overwritten
         lea      MGadget,a3
         move.l   d0,d2

         move.l   a2,a0          ; window
         move.l   a3,a1          ; gadget
         Base     Intuition
         Call     RemoveGadget   ; remove, modify, add back.
* Later we will insert this gadget back to its original place.
* That is why d2 gets position. toDec needs number in d0.
         exg.l    d0,d2

         move.l   gg_SpecialInfo(a3),a0
         move.l   si_Buffer(a0),a0

         bsr      toMag
         clr.b    (a0)

         bsr.s    refresh_add_gadget

         cmp.b    #ZOOM,method
         bne.s    1$
         move.b   #REDRAW,method
         bsr      refresh_zoom   ; does also DrawGrid,
         bra.s    2$             ; so dont repeat it.
1$:
         bsr      DrawGrid
2$:
         pull     d0-d2/a0-a3/a6
         rts

* This is common to all above.
refresh_add_gadget:
         move.l   gg_SpecialInfo(a3),a0
         clr.w    si_BufferPos(a0)
         clr.w    si_DispPos(a0)
         move.l   a2,a0          ; window
         move.l   a3,a1          ; gadget
         move.l   d2,d0          ; the very same position
         Call     AddGadget
         move.l   a3,a0          ; gadget
         move.l   a2,a1          ; window
         sub.l    a2,a2          ; "requester / no requester"
         moveq    #1,d0
         Call     RefreshGList   ; actually just one
         rts

* Hah haa! Still more refreshing routines:

refresh_set:
         push     d0-d2/a0-a3/a5/a6
         Base     Intuition
         move.l   MyWindow2,a0
         move.l   a0,a5
         lea      MANDELGadget,a1
         move.l   a1,a3
         moveq    #2,d0
         Call     RemoveGList

         lea      JULIAGadget,a1
         btst.b   #MBB_JULIA,mb_flags(a4)
         beq.s    it_is_mandel

         or.w     #SELECTED,gg_Flags(a1)
         and.w    #~SELECTED,gg_Flags(a3)
         bra.s    put_them_back
it_is_mandel:
         and.w    #~SELECTED,gg_Flags(a1)
         or.w     #SELECTED,gg_Flags(a3)
put_them_back:
         move.l   a5,a0       ; window
         move.l   a3,a1       ; gadget
         sub.l    a2,a2       ; requester
         ; d0 is all right (RemoveGList...)
         moveq    #2,d1
         Call     AddGList

         move.l   a3,a0       ; gadget
         move.l   a5,a1       ; window
         ; a2 is still 0. (Dunno if it should be 0 anyway?)
         moveq    #2,d0
         Call     RefreshGList

         pull     d0-d2/a0-a3/a5/a6
         rts

refresh_zoom:
         push     d0-d2/a0-a3/a5/a6
         Base     Intuition
         move.l   MyWindow2,a0
         move.l   a0,a5
         lea      ZOOMGadget,a1
         move.l   a1,a3
         moveq    #3,d0
         Call     RemoveGList

         lea      DRAWGadget,a2
         lea      RESETGadget,a1

         move.b   method,d1
         cmp.b    #REDRAW,d1
         beq.s    it_is_draw
         cmp.b    #RESET,d1
         beq.s    it_is_reset

         or.w     #SELECTED,gg_Flags(a3)  ; zoom
         and.w    #~SELECTED,gg_Flags(a2)
         and.w    #~SELECTED,gg_Flags(a1)
         bra.s    complex_and_unique_label
it_is_draw:
         and.w    #~SELECTED,gg_Flags(a3)
         or.w     #SELECTED,gg_Flags(a2)  ; draw
         and.w    #~SELECTED,gg_Flags(a1)
         bra.s    complex_and_unique_label
it_is_reset:
         and.w    #~SELECTED,gg_Flags(a3)
         and.w    #~SELECTED,gg_Flags(a2)
         or.w     #SELECTED,gg_Flags(a1)  ; reset
complex_and_unique_label:
         move.l   a5,a0       ; window
         move.l   a3,a1       ; gadget
         sub.l    a2,a2       ; requester
         ; d0 is all right (RemoveGList...)
         moveq    #3,d1
         Call     AddGList

         move.l   a3,a0       ; gadget
         move.l   a5,a1       ; window
         ; a2 is still 0. (Dunno if it should be 0 anyway?)
         moveq    #3,d0
         Call     RefreshGList

         pull     d0-d2/a0-a3/a5/a6
         bsr      DrawGrid          ; if something changed, show it.
         rts


GetSMagnify:
         move.b   (a0)+,d0
         cmp.b    #'+',d0
         beq.s    1$
         cmp.b    #'-',d0
         beq.s    2$
         subq.l   #1,a0
1$:
         bsr      GetMagnify
         rts
2$:
         bsr      GetMagnify
         beq.s    3$
         neg.l    d0
3$:
         rts

RightButton:
         clr.b    method         ; == move.b #ZOOM,method
                                 ; so RMB is a shorthand for ZOOM
         bsr      refresh_zoom
         move.w   d5,d0
         move.w   d6,d1

         push     d5/d6
         swap     d5
         swap     d6
         clr.w    d5
         clr.w    d6
         bsr      refresh_pos
         pull     d5/d6

* a few words of explanation:
* Because we cannot process MOUSEMOVE events fast enough, we do
* the following: Loop CheckMessage, saving d5/d6 each turn,
* until it returns event that isn't of class MOUSEMOVE.
* Then process saved d5/d6 (they represent the position mouse was
* in BEFORE this message arrived).
* If message is of class NULL (no messages), start it all again.

rightloop:
         move.w   d5,tmpx
         move.w   d6,tmpy
         push     d0-d1
         bsr      CheckMessage
         pull     d0-d1
         bne      do_the_wrong_thing

we_have_already_got_one:
         cmp.l    #MOUSEMOVE,d2
         beq.s    rightloop

         push     d0-d2/d5/d6    ; so as not to trash current message

* Uh oh... When I thought it would be nice if user could use
* magnification instead of deltas, I knew I would have to
* code 2^(-mag) in mach lang. But it never occured to me that
* I would have to code log2 somewhere....
* There is only one word to describe this: disqusting
         push     d0/d1          ; again!
         sub.w    tmpx,d0
         bpl.s    notneg1
         neg.w    d0
notneg1:
         sub.w    tmpy,d1
         bpl.s    notneg2
         neg.w    d1
notneg2:
         bne.s    r_isnonzero
         tst.w    d0
         beq.s    r_iszero
r_isnonzero:
         move.w   mb_x2(a4),d2
         sub.w    mb_x1(a4),d2
         swap     d0
         clr.w    d0
         divu     d2,d0
         bvc.s    no_overf_1
         moveq    #-1,d0
no_overf_1:
         move.w   mb_y2(a4),d2
         sub.w    mb_y1(a4),d2
         swap     d1
         clr.w    d1
         divu     d2,d1
         bvc.s    no_overf_2
         moveq    #-1,d1
no_overf_2:
         cmp.w    d1,d0
         bhi.s    d0_is_higher
         move.w   d1,d0
d0_is_higher:
         bsr      log2        ; I will code it later, ok?
         move.l   d0,Zoom
r_iszero:
         pull     d0/d1
         move.w   tmpx,d5
         move.w   tmpy,d6
         add.w    d0,d5
         add.w    d1,d6
         swap     d5
         swap     d6
         clr.w    d5
         clr.w    d6

         move.l   mb_dx(a4),d1
         move.l   mb_dy(a4),d2
         lsr.l    #1,d1
         lsr.l    #1,d2

         lsr.l    #1,d5
         tst.w    d5
         bmi.s    1$
         moveq    #0,d1
1$:
         lsr.l    #1,d6
         tst.w    d6
         bmi.s    2$
         moveq    #0,d2
2$:
         move.l   d5,prex
         move.l   d6,prey
         swap     d5
         swap     d6
         bsr      Position
         add.l    d1,d5
         sub.l    d2,d6
         move.l   d5,CurrentX
         move.l   d6,CurrentY
         move.l   d5,d0
         bsr      refresh_x
         move.l   d6,d0
         bsr      refresh_y
         move.l   Zoom,d0
         bsr      refresh_z   ; This will do DrawGrid also.
         pull     d0-d2/d5/d6
         tst.l    d2
         bne.s    exit_right_button    ; probably MENUUP

* How cute!!! LOVELY!!! Even here, this proggie refuses to busywait!!!!
         bsr      GetMessage     ; (ya see, no CheckMessage!)
         bne.s    do_the_wrong_thing
         cmp.l    #MOUSEMOVE,d2
         bne.s    exit_right_button
         move.w   d5,tmpx
         move.w   d6,tmpy
         bra      we_have_already_got_one

exit_right_button:
         moveq    #0,d0
do_the_wrong_thing:
         rts

refresh_pos:
         push     d0
         move.l   d5,prex
         move.l   d6,prey
         swap     d5
         swap     d6
         bsr      Position
         move.l   d5,CurrentX
         move.l   d6,CurrentY
         move.l   d5,d0
         bsr      refresh_x
         move.l   d6,d0
         bsr      refresh_y
         bsr      DrawGrid
         pull     d0
         rts

LeftButton:
         move.l   OldSecs,d0
         move.l   OldMicros,d1
         move.l   a2,d2
         move.l   a3,d3
         move.l   a2,OldSecs
         move.l   a3,OldMicros
         Call     DoubleClick
         tst.w    d0
         bne.s    left_double

* We use a loop similar to RightButton's.
leftloop
         move.w   d5,tmpx
         move.w   d6,tmpy
         bsr      CheckMessage
         bne      left_aborted   ; ^C
left_gotmessage
         cmp.l    #MOUSEMOVE,d2
         beq.s    leftloop

         push     d5/d6
         swap     d5
         swap     d6
         clr.w    d5
         clr.w    d6
         bsr      refresh_pos
         pull     d5/d6

         tst.l    d2
         bne.s    left_exit      ; probably SELECTUP

         bsr      GetMessage
         bne.s    left_aborted
         cmp.l    #MOUSEMOVE,d2
         bne.s    left_exit
         move.w   d5,tmpx
         move.w   d6,tmpy
         bra      left_gotmessage
left_exit
         moveq    #FALSE,d0   ; return zero
         bra.s    left_return
left_double
         swap     d5
         swap     d6
         clr.w    d5
         clr.w    d6
         bsr      refresh_pos
         moveq    #TRUE,d0    ; return positive nonzero
         bra.s    left_return
left_aborted
         moveq    #-TRUE,d0   ; return negative nonzero
left_return
         rts


* Converts an integer from d0.w to a string (a0)+.
* Grr.. Why don't we have most significant digit last?
toInt:
         push     d0-d2
         move.w   #10000,d1
         moveq    #FALSE,d2
1$:
         and.l    #$ffff,d0
         divu     d1,d0
         bne.s    4$
         tst.w    d2    ; discard leading zeros
         beq.s    2$
4$:
         add.b    #'0',d0
         move.b   d0,(a0)+
         moveq    #TRUE,d2
2$:
         swap     d0
         ext.l    d1
         divu     #10,d1
         bne.s    1$

         tst.w    d2
         bne.s    3$
         move.b   #'0',(a0)+  ; if d0=0, display at least a 0.
3$:
         pull     d0-d2
         rts

* Still one more conversion routine. (for Magnify's internal format)
toMag:
         push     d0-d2
         move.l   d0,d1
         swap     d0
         bsr.s    toInt
         move.b   #'.',(a0)+

         moveq    #3,d2
1$:
         mulu     #10,d1
         swap     d1
         add.b    #'0',d1
         move.b   d1,(a0)+
         swap     d1
         dbf      d2,1$

         tst.w    d1
         bpl.s    2$       ; if < $8000, no rounding needed
         bsr      Round
2$:
         pull     d0-d2
         rts


dispCoords:
* This routine displays the coordinates of current mouse position
* in screen title bar.
         bsr.s    Position
         lea      CoordText,a0
         move.l   d5,d0
         move.l   mb_dx(a4),d7
         bsr.s    toDec
         move.b   #' ',(a0)+
         move.l   d6,d0
         move.l   mb_dy(a4),d7
         bsr.s    toDec
         clr.b    (a0)+
* There was a time when I used SetWindowTitles here.
* But the flashing... and the speed (or rather lack of)...

         move.l   MyScreen,a0
         lea      sc_RastPort(a0),a0
         lea      Coords,a1
         moveq    #80,d0
         moveq    #0,d1
         Call     PrintIText

         rts

* Fetch absolute position in complex plane when d5/d6 has
* mouse position. Return result also in d5/d6.
Position:
         push     d0
         move.w   d5,d0
         mulu     mb_dx(a4),d5
         swap     d5
         clr.w    d5
         mulu     2+mb_dx(a4),d0
         add.l    d0,d5
         add.l    mb_x0(a4),d5

         move.w   d6,d0
         mulu     mb_dy(a4),d6
         swap     d6
         clr.w    d6
         mulu     2+mb_dy(a4),d0
         add.l    d0,d6
         neg.l    d6
         add.l    mb_y0(a4),d6
         pull     d0

         rts

* toDec is the reverse of GetFixed. I will use a couple look-up tables
* here, too.
* INPUTS fixed point in d0, buffer in a0, delta in d7.
* RETURN next a0 in a0.

toDec:
         push     a1-a3/d0-d6
         move.b   #'+',d2
         tst.l    d0
         bpl.s    1$

         move.b   #'-',d2
         neg.l    d0
1$:      move.b   d2,(a0)+

         move.b   #'0',d2
3$:      cmp.l    #$20000000,d0
         blo.s    2$
         sub.l    #$20000000,d0
         addq.b   #1,d2
         bra.s    3$
2$:
         move.b   d2,(a0)+
         move.b   #'.',(a0)+

         lea      4+NumberHi,a1
         lea      4+NumberLo,a2
         move.l   #-1,a3         ; for precision determining.
         moveq    #0,d1          ; use 64 bits of precision (SHIT! why?)
outerloop:
         move.b   #'0',d2
         move.l   (a1)+,d3
         move.l   (a2)+,d4
innerloop:
         move.l   d0,d5
         move.l   d1,d6
         sub.l    d4,d6
         subx.l   d3,d5
         bmi.s    below0
         move.l   d5,d0
         move.l   d6,d1
         addq.b   #1,d2
         bra.s    innerloop
below0:
         cmp.l    a3,d7
         move.l   -4(a1),a3
         bhi.s    it_is_over  ; it sayz: being too accurate
         move.b   d2,(a0)+
         bra.s    outerloop
it_is_over:

* Now we round the number. This was added because it was frustrating
* when user entered, say, 0.7 and got back 0.69.
* This is an ascii round.
         cmp.b    #'5',d2
         blo.s    no_round
         bsr.s    Round

no_round:
         pull     a1-a3/d0-d6
         rts

* This is an ASCII round.
Round:   push     a0/d0
1$:      move.b   -(a0),d0
         cmp.b    #'.',d0
         beq.s    1$
         cmp.b    #'9',d0
         bne.s    2$
         move.b   #'0',(a0)
         bra.s    1$
2$:
         addq.b   #1,(a0)
         pull     a0/d0
         rts

* Wait() for an IDCMP message from either of the windows,
* or timer I/O to complete.
* Handle ^C explicitely.

GetMessage:
         push     d0-d1/a0-a1

test_messages:
         bsr      CheckMessage
         bne.s    found_one      ; of class ^C
         tst.l    d2             ; which class? (0 = none found)
         bne.s    set_Z_exit

* No messages. Wait for them.
         bset     #SIGBREAKB_CTRL_C,d0
         Base     Exec
         Call     Wait
         btst     #SIGBREAKB_CTRL_C,d0
         bne.s    found_one      ; ^C (return with Z clear)

         bra.s    test_messages  ; Now there's a message for us. Fetch it.
set_Z_exit:
         moveq    #0,d0
found_one:
         pull     d0-d1/a0-a1
         rts

* This routine just gets a message if it IS here, but does not
* Wait() for it. However, returns with signal mask in d0 if
* caller wishes to wait.

CheckMessage:
* Test if any messages arrived
         Base     Exec
         moveq    #0,d2             ; Signal mask

* First window
         move.l   MyWindow1,a0      ; This is always open
         move.l   wd_UserPort(a0),a0
         move.b   MP_SIGBIT(a0),d0
         bset     d0,d2
         Call     GetMsg
         tst.l    d0
         bne.s    foundmsg

* Second window
         move.l   MyWindow2,a0
         move.l   a0,d0
         beq.s    1$                ; check if open
         move.l   wd_UserPort(a0),a0
         move.b   MP_SIGBIT(a0),d0
         bset     d0,d2
         Call     GetMsg
         tst.l    d0
         bne.s    foundmsg
1$:
* Timer I/O
         move.l   UseReq,a1
         move.l   a1,d0
         beq.s    2$          ; no request pending
         move.l   MN_REPLYPORT(a1),a0
         move.b   MP_SIGBIT(a0),d0
         bset     d0,d2
         Call     CheckIO
         tst.l    d0
         bne.s    foundio
2$:
* No messages! Return with 0 in d2, signal set in d0.
         exg.l    d0,d2
         rts

foundmsg:
         move.l   d0,a1
         move.l   im_Class(a1),d2
         move.w   im_Code(a1),d3
         move.w   im_Qualifier(a1),d4
         move.l   im_IAddress(a1),a5
         move.w   im_MouseX(a1),d5
         move.w   im_MouseY(a1),d6
         move.l   im_Seconds(a1),a2
         move.l   im_Micros(a1),a3
         Call     ReplyMsg
         cmp.l    #RAWKEY,d2
         bne.s    nobreak
         cmp.w    #$33,d3      ; RAW keycode for 'c'
         bne.s    nobreak
         btst     #IEQUALIFIERB_CONTROL,d4
         beq.s    nobreak
break:
         moveq    #TRUE,d0
         rts
foundio:
         move.l   UseReq,a1
         Call     WaitIO
         clr.l    UseReq
         moveq    #FAKECLASS,d2
nobreak:
         moveq    #FALSE,d0
         rts

Transform:
* Firsty: Magnify is useless to brot. Need to calculate
* 2 ^ (-Magnify). That, again, is very very inconvenient.

* Lets do it in a subroutine. Someone else might need it.
         move.w   #$2000,d0
         moveq    #$0000,d1   ; d0/d1 form 1 (fixed),
         moveq    #$0000,d2   ; d2 is just extension
         move.l   Magnify,d3
         bsr.s    Power2

         ifeq     SCREEN-0
         move.l   d0,mb_dx(a4)
         move.l   d0,mb_dy(a4)
         endc
         ifeq     SCREEN-1
         asr.l    #1,d0
         move.l   d0,mb_dx(a4)
         asl.l    #1,d0
         move.l   d0,mb_dy(a4)
         endc
         ifeq     SCREEN-2
         asr.l    #1,d0
         move.l   d0,mb_dy(a4)
         asl.l    #1,d0
         move.l   d0,mb_dx(a4)
         endc
         ifeq     SCREEN-3
         asr.l    #1,d0
         move.l   d0,mb_dx(a4)
         move.l   d0,mb_dy(a4)
         endc

* 'brot' expects to see z = x0 + y0 i to be upper lefthand corner
* whereas this program has until now assumed it is centerpoint.
* I wont use mulX instructions here because we are not in such a
* hurry. And secondly, on low magnification levels this is more
* accurate. (OK, that sounded nice. The real reason was that
* I am too lazy to find out what was wrong with that mulu!)

         move.w   mb_x1(a4),d0
         add.w    mb_x2(a4),d0
         move.l   CurrentX,d1
         move.l   mb_dx(a4),d2
         lsr.w    #1,d0
         bcc.s    1$

         move.l   d2,d3
         asr.l    #1,d3
         sub.l    d3,d1
1$:
         tst.w    d0
         beq.s    2$
         sub.l    d2,d1
         subq.w   #1,d0
         bra.s    1$
2$:      move.l   d1,mb_x0(a4)

         move.w   mb_y1(a4),d0
         add.w    mb_y2(a4),d0
         move.l   CurrentY,d1
         move.l   mb_dy(a4),d2
         lsr.w    #1,d0
         bcc.s    3$

         move.l   d2,d3
         asr.l    #1,d3
         add.l    d3,d1
3$:
         tst.w    d0
         beq.s    4$
         add.l    d2,d1
         subq.w   #1,d0
         bra.s    3$
4$:      move.l   d1,mb_y0(a4)

         rts

Power2:
* I must be a masochist...
* Right now I have no idea how to code this routine. Hm. let's see.

* This routine should be called with Magnify (or Zoom) in d3.
* d0/d1/d2 should be set to value to be multiplied by 2^(-d3).
* Returns d0.

         push     d1-d4/a0

* I seem to break the calculation into smaller ones, like
* 2¯¹ x 2¯¹ x ... x 2¯¹ x 2^(-1/2) x 2^(-1/4) x ...
* Each bit corresponds to one multiplication.

         swap     d3
         tst.w    d3
minusone:
         beq.s    skip_power
         lsr.w    #1,d0    ; This is  x 2¯¹
         roxr.w   #1,d1
         roxr.w   #1,d2
         subq.w   #1,d3
         bra.s    minusone
skip_power:

         swap     d3
         lea      NumberP,a0
minusfrac:
         move.w   (a0)+,d4
         asl.w    #1,d3
         bcc.s    dont_multi

         mulu     d4,d0
         mulu     d4,d1
         mulu     d4,d2
         swap     d2
         add.w    d1,d2
         swap     d1
         addx.w   d0,d1
         swap     d0
         moveq    #0,d4
         addx.w   d4,d0
dont_multi:
         tst.w    d3
         bne    minusfrac

* Ha! It was easy!
         swap     d0
         move.w   d1,d0

         pull     d1-d4/a0
         rts

* Oooooh how I wish I had a C-compiler!
* Inverse of Power2, that is,
* log  ( d2 )  in zoom/magnify fixed point format.
*    2
log2:
         push     d1-d4/a0
         moveq    #0,d1       ; this gets the answer
log_int:
         tst.w    d0
         bmi.s    log_frac
         addq.w   #1,d1
         lsl.w    #1,d0
         bra.s    log_int
log_frac:
         swap     d1
         lea      NumberL,a0
         moveq    #15,d2
log_loop:
         lsl.w    #1,d1       ; go through 16 bits
         move.w   (a0)+,d3
         moveq    #0,d4
         move.w   d0,d4
         swap     d4
         mulu     d0,d3
         add.l    d3,d4
         bcs.s    log_overflow
* That multiplication was "valid" -> record intermediate result
* in d0. Bit in d1 collects final result.
         or.b     #1,d1
         swap     d4
         bpl.s    1$
         add.w    #1,d4
1$:
         move.w   d4,d0
log_overflow:
         dbf      d2,log_loop
         move.l   d1,d0
         pull     d1-d4/a0

* AMAZING! UNBELIEVABLE! I think I got it right THE VERY FIRST TIME
* I CODED IT! This must have been the 1st routine that didnt
* need to be debugged! And I thought this would be hard...

         rts


CtrlC:
         push     a0-a1/d0-d1/a6
         Base     Exec
         move.l   MyWindow1,a0
         move.l   wd_UserPort(a0),a0
         Call     GetMsg
         tst.l    d0
         beq.s    no_c
         move.l   d0,a1
         cmp.l    #RAWKEY,im_Class(a1)
         bne.s    reply_c
         cmp.w    #$33,im_Code(a1)
         bne.s    reply_c
         move.w   im_Qualifier(a1),d0
         btst     #IEQUALIFIERB_CONTROL,d0
         beq.s    reply_c
         Call     ReplyMsg
         moveq    #-1,d0
         bra.s    exit_c
reply_c:
         Call     ReplyMsg
no_c:
         moveq    #0,d0
         moveq    #0,d1
         Call     SetSignal
         btst     #SIGBREAKB_CTRL_C,d0
exit_c:
         pull     a0-a1/d0-d1/a6
         rts



* This routine gets decimal number ( -4.0 .. 4.0 ) from (a0)+ to d0.
* Format is fixed point.

* If Z bit is set (indicating zero result) no number was found.

* This may be one of the stupidest routines I've written. But
* it doesnot matter. This way I will always be accurate enough.
* (For those meatheads that do not understand what I mean:
* I use internally 64 bits of precision, the final result
* will have only 32...)

GetFixed:
         push     a1-a3/d1-d5
         move.l   a0,a3
         moveq    #0,d1
         moveq    #0,d3
         move.l   #$80000000,d2
         lea      NumberHi,a1
         lea      NumberLo,a2
1$:
         move.b   (a0)+,d0
         cmp.b    #'+',d0
         beq.s    1$
         cmp.b    #'-',d0
         bne.s    2$
         bset     #15,d3   ; Now this is negative
         bra.s    1$
2$:
         cmp.b    #'.',d0
         bne.s    3$
         bset     #7,d3    ; Remember: now we have gone past
         bra.s    1$
3$:
         cmp.b    #'0',d0
         blo.s    4$
         cmp.b    #'9',d0
         bhi.s    4$

         bset     #0,d3
         cmp.l    (a1)+,(a2)+ ; go to next number position
         tst.b    d3
         bmi.s    5$
         lea      NumberHi,a1 ; We will patiently stuck with these until
         lea      NumberLo,a2 ; decimal point found
5$:
         sub.b    #'0'+1,d0
         bmi.s    1$
         ext.w    d0
         move.l   (a1),d4
         move.l   (a2),d5
6$:
         add.l    d5,d2
         addx.l   d4,d1
         dbf      d0,6$
         bra.s    1$

4$:
         subq.l   #1,a0
         bsr.s    SkipBlk
         tst.w    d3
         bpl.s    7$
         neg.l    d1
7$:
         move.l   d1,d0
         btst     #0,d3
         bne.s    8$
         move.l   a3,a0 ; if error, go to where we started from
8$:
         pull     a1-a3/d1-d5
         rts

* This routine gets number from (a0)+ to d0.w

GetNum:
         push     d1/d2/a1
         move.l   a0,a1
         moveq    #FALSE,d2      ; no valid number yet
         moveq    #0,d0
2$:
         move.b   (a0)+,d1
         cmp.b    #'0',d1
         blo.s    1$
         cmp.b    #'9',d1
         bhi.s    1$

         sub.b    #'0',d1
         ext.w    d1
         mulu     #10,d0
         add.w    d1,d0
         moveq    #TRUE,d2       ; valid number
         bra.s    2$

1$:
         subq.l   #1,a0
         bsr.s    SkipBlk

         tst.w    d2          ; invalid?
         bne.s    3$
         move.l   a1,a0       ; if error, get back where to we started from
3$:
         pull     d1/d2/a1
         rts

* This will skip all spaces and tabs.

SkipBlk:
         push     d0
1$:
         move.b   (a0)+,d0
         cmp.b    #' ',d0
         beq.s    1$
         subq.l   #1,a0
         pull     d0
         rts

* A subroutine for each of the options
opt_x:   bsr      GetFixed
         beq.s    opt_xx
         move.l   d0,CurrentX
         moveq    #TRUE,d0
         rts
opt_xx
* This is just -x meaning exit when drawn.
         clr.b    inter
         moveq    #TRUE,d0
         rts

opt_y:   bsr      GetFixed
         beq.s    1$
         move.l   d0,CurrentY
         moveq    #TRUE,d0
1$:      rts

* This option is a very special one (internally) because it uses
* still one different number format (scaled by 2^16).
* This is converted to actual mb_dx and mb_dy values later...
opt_m:   bsr.s    GetMagnify
         beq.s    opt_mm
         move.l   d0,Magnify
         moveq    #TRUE,d0
         rts
opt_mm
* This is only -m meaning mandelbrot sets
         bclr.b   #MBB_JULIA,mb_flags(a4)
         moveq    #TRUE,d0
         rts

GetMagnify:
         push     a1-a2/d1-d2
         move.l   a1,a2
         bsr      GetNum
         swap     d0             ; integer part go to high 16 bits
         cmp.b    #'.',(a0)+
         bne.s    m_space        ; number had ONLY integer part
         moveq    #0,d1          ; collect number here
         moveq    #0,d2          ; clear extra bits
         clr.w    d0
m_find_end:
         move.b   (a0)+,d2
         addq.w   #1,d0          ; low word has a temporary role as counter
         cmp.b    #'0',d2
         blo.s    m_end_found
         cmp.b    #'9',d2
         bls.s    m_find_end
m_end_found:
         lea      -1(a0),a1
m_loop:
         subq.w   #1,d0
         beq.s    m_got_it
         move.b   -(a1),d2
         sub.b    #'0',d2
         swap     d1
         move.w   d2,d1
         swap     d1
         divu     #10,d1
         bra.s    m_loop
m_got_it:
         move.w   d1,d0

m_space:
         subq.l   #1,a0
         bsr      SkipBlk
         cmp.l    #$001d0000,d0  ; greater than 2^29?
         bhi.s    m_error
         moveq    #TRUE,d1
         bra.s    m_exit
m_error:
         moveq    #FALSE,d0
         move.l   a2,a1
m_exit:  pull     a1-a2/d1-d2
         rts


opt_i:   bsr      GetNum
         beq.s    1$
         move.w   d0,mb_i(a4)
         moveq    #TRUE,d0
1$:      rts


opt_l:   bclr.b   #MBB_AUTOPREC,mb_flags(a4)
         bclr.b   #MBB_HIGH,mb_flags(a4)
         moveq    #TRUE,d0
         rts

opt_h:   bclr.b   #MBB_AUTOPREC,mb_flags(a4)
         bset.b   #MBB_HIGH,mb_flags(a4)
         moveq    #TRUE,d0
         rts

opt_a:   bset.b   #MBB_AUTOPREC,mb_flags(a4)
         moveq    #TRUE,d0
         rts


opt_c:   bclr.b   #MBB_AUTOCRAWL,mb_flags(a4)
         bset.b   #MBB_CRAWL,mb_flags(a4)
         moveq    #TRUE,d0
         rts

opt_w:   bclr.b   #MBB_AUTOCRAWL,mb_flags(a4)
         bclr.b   #MBB_CRAWL,mb_flags(a4)
         moveq    #TRUE,d0
         rts

opt_p:   bset.b   #MBB_AUTOCRAWL,mb_flags(a4)
         moveq    #TRUE,d0
         rts

opt_g:   move.b   #TRUE,inter
         rts


opt_j:   move.b   (a0)+,d0
         toupper  d0

         cmp.b    #'X',d0
         bne.s    j_no_x
opt_jx      ; WB options enter this routine here
         bsr      GetFixed
         beq.s    1$
         move.l   d0,mb_jx(a4)
         moveq    #TRUE,d0
1$:      rts

j_no_x:  cmp.b    #'Y',d0
         bne.s    j_no_y
opt_jy      ; WB entry point
         bsr      GetFixed
         beq.s    1$
         move.l   d0,mb_jy(a4)
         moveq    #TRUE,d0
1$:      rts


j_no_y
* This is just -j meaning julia sets
         subq.l   #1,a0
opt_jj      ; WB entry
         bset.b   #MBB_JULIA,mb_flags(a4)
         moveq    #TRUE,d0
         rts

opt_s
         lea      NameBuffer,a1
s_endstr
         move.b   (a0)+,d0
         beq.s    s_over
         cmp.b    #' ',d0
         beq.s    s_over
         move.b   d0,(a1)+
         bra.s    s_endstr
s_over
         subq.l   #1,a0
         clr.b    (a1)
         move.l   a1,NameEnd
         bsr      SkipBlk
         move.b   #TRUE,d0
         move.b   d0,saveit
         rts


* For WB use, e.g. FLAGS=xc\0
opt_flags
         move.b   (a0)+,d0
         beq.s    no_more_flags
         toupper  d0

* This will return use in this routine.
         pea      opt_flags
         cmp.b    #'L',d0
         beq      opt_l
         cmp.b    #'H',d0
         beq      opt_h
         cmp.b    #'A',d0
         beq      opt_a
         cmp.b    #'C',d0
         beq      opt_c
         cmp.b    #'W',d0
         beq      opt_w
         cmp.b    #'P',d0
         beq      opt_p
         cmp.b    #'G',d0
         beq      opt_g
         cmp.b    #'J',d0
         beq      opt_jj      ; not opt_j
         cmp.b    #'M',d0
         beq      opt_mm      ; not opt_m
         cmp.b    #'X',d0
         beq      opt_xx      ; not opt_x
* Wrong option!
         addq.l   #4,a7
         moveq    #FALSE,d0
         rts
no_more_flags
         moveq    #TRUE,d0
         rts

SavePicture:
         lea      NameBuffer,a0
         move.l   a0,d2

         move.l   NameEnd,a0
         move.w   Counter,d0
         beq.s    first_time
* When 2nd etc. file saved, use a running number as an identifier
         bsr      toInt
         clr.b    (a0)        ; 0 terminates string
first_time:
         addq.w   #1,Counter

         lea      _IffLib,a1
         moveq    #0,d0
         Base     Exec
         Call     OpenLibrary
         tst.l    d0
         beq.s    noifflib
         move.l   d0,a6

         move.l   MyScreen,a0
         move.l   sc_ViewPort+vp_ColorMap(a0),a2
         move.l   cm_ColorTable(a2),a2          ; colortable
         move.l   sc_RastPort+rp_BitMap(a0),a1  ; bitmap
         move.l   d2,a0                         ; filename

         move.w   mb_x1(a4),d1
         move.w   mb_y1(a4),d2
         move.w   mb_x2(a4),d3
         move.w   mb_y2(a4),d4

         lsr.w    #3,d1       ; no of BYTES
         add.w    #7,d3
         lsr.w    #3,d3

         sub.w    d1,d3
         sub.w    d2,d4
         addq.w   #1,d3       ; width and heigth
         addq.w   #1,d4

         moveq    #1,d0       ; run-length compression

         jsr      SaveClip(a6)
         move.l   d0,d2

         move.l   a6,a1
         Base     Exec
         Call     CloseLibrary

         tst.l    d2
         bne.s    exit_save
         move.b   #ERROR_ifflib,error
         bra.s    exit_save
noifflib:
         move.b   #ERROR_noifflib,error
exit_save:
         rts

   SECTION  data,DATA
* First elements form $20000000 00000000 (represents 1)
* then 1/10, 1/100 etc.
NumberHi:
         dc.l  $20000000,$03333333,$0051EB85,$00083126
         dc.l  $0000D1B7,$000014F8,$00000218,$00000035
         dc.l  $00000005,$00000000,$00000000,$00000000
         dc.l  $00000000,$00000000,$00000000,$00000000
NumberLo:
         dc.l  $00000000,$33333333,$1EB851EB,$E978D4FD
         dc.l  $1758E219,$B588E368,$DEF416BD,$AFE53579
         dc.l  $5E63B88C,$89705F41,$0DBE6FEC,$015FD7FE
         dc.l  $00232F33,$000384B8,$00005A12,$00000901

* Still one table. This time: 2^(-1/2) , 2^(-1/4) ... times $10000.
NumberP:
         dc.w  $b505,$d745,$eac1,$f525,$fa84,$fd3e,$fe9e,$ff4f
         dc.w  $ffa7,$ffd4,$ffea,$fff5,$fffa,$fffd,$ffff,$ffff
* Inverse of former: 2^(1/2), 2^(1/4) etc.
* Implied highest "1" has been deleted.
* (Example: 2^(1/2) = sqrt(2) = 1.4142 x $10000 = $16a0a -> $6a0a)
NumberL:
         dc.w  $6A0A,$3070,$172C,$0B56,$059B,$02CA,$0164,$00B2
         dc.w  $0059,$002C,$0016,$000B,$0006,$0003,$0001,$0001


Colors:
         ifeq  DEPTH-5
            dc.w  $888,$000
            dc.w  $f00,$f30,$f60,$f90,$fc0,$ff0,$cf0,$9f0,$6f0,$3f0
            dc.w  $0f0,$0f3,$0f6,$0f9,$0fc,$0ff,$0cf,$09f,$06f,$03f
            dc.w  $00f,$30f,$60f,$90f,$c0f,$f0f,$f0c,$f09,$f06,$f03
         endc
         ifeq  DEPTH-4
            dc.w  $888,$000
            dc.w  $f00,$f80,$ff0,$8f0
            dc.w  $0f0,$0f6,$0fc,$0cf,$06f
            dc.w  $00f,$60f,$c0f,$f0c,$f06
         endc
         ifeq  DEPTH-3
            dc.w  $888,$000,$f00,$ff0,$0f0,$0ff,$00f,$f0f
         endc
         ifeq  DEPTH-2
            dc.w  $888,$000,$f00,$00f
         endc
MyNewScreen:
         dc.w  0,0            ; offsets
         dc.w  XSIZE,YSIZE    ; size x * y
         dc.w  DEPTH          ; planes
         dc.b  1,2            ; default pens
         dc.w  VIEWMODE
         dc.w  CUSTOMSCREEN
         dc.l  0,ScreenTitle,0          ; font,title,gadgets

MyNewWindow1:
         dc.w  0,0
         dc.w  XSIZE,YSIZE       ; width, heigth
         dc.b  1,2               ; pens
         dc.l  IDCMP1            ; IDCMP
         dc.l  FLAGS1
         dc.l  0,0,0             ; gadgets, checkmark, title
InsertScreen1:
         ds.l  1                 ; screen (to be inserted later)
         dc.l  0                 ; bitmap
         dc.w  -1,-1,-1,-1       ; min/max size
         dc.w  CUSTOMSCREEN      ; screen type

MyNewWindow2:
         dc.w  WINX,WINY         ; place (to be modified later)
         dc.w  WINW,WINH         ; width, heigth
         dc.b  1,2               ; pens
         dc.l  IDCMP2            ; IDCMP
         dc.l  FLAGS2
         dc.l  XGadget           ; ... gadgets ... (lots of them!)
         dc.l  0,0               ; checkmark, title
InsertScreen2:
         ds.l  1                 ; screen (to be inserted later)
         dc.l  0                 ; bitmap
         dc.w  -1,-1,-1,-1       ; min/max size
         dc.w  CUSTOMSCREEN      ; screen type

uniqueID SET   0
MakeID   macro
\1       EQU   uniqueID
uniqueID SET   uniqueID+1
         endm

         MakeID   GAD_X
         MakeID   GAD_Y
         MakeID   GAD_M
         MakeID   GAD_Z
         MakeID   GAD_I
         MakeID   GAD_ZOOM
         MakeID   GAD_DRAW
         MakeID   GAD_RESET
         MakeID   GAD_MANDEL
         MakeID   GAD_JULIA
         MakeID   GAD_QUIT
MINUS    EQU      $8000
STRING   EQU      $4000
ZOOMTYPE EQU      $2000
SETTYPE  EQU      $1000
IDMASK   EQU      $8fff    ; so as not to mask sign

XGadget:
         dc.l  YGadget     ; link to next
         dc.w  39,13,104,8 ; place & size
         dc.w  GADGHCOMP
         dc.w  RELVERIFY|GADGIMMEDIATE
         dc.w  STRGADGET
         dc.l  XYBorder    ; image for gadget
         dc.l  0
         dc.l  XText
         dc.l  0           ; MutualExclude
         dc.l  XString     ; specialinfo
         dc.w  STRING|GAD_X ; ID
         dc.l  0
XString:
         dc.l  XBuffer
         dc.l  0
         dc.w  0
         dc.w  13
         dc.w  0
         dc.w  0,0,0,0,0
         dc.l  0
         dc.l  0,0
XText:
         dc.b  1,2      ; pens
         dc.b  RP_JAM1,0   ; drawmodes
         dc.w  -10,0     ; offsets
         dc.l  0        ; default font
         dc.l  XLetter  ; (yeah, just one letter)
         dc.l  0        ; no more text
YGadget:
         dc.l  YPLUSGadget     ; the next one
         dc.w  39,26,104,8 ; place & size
         dc.w  GADGHCOMP
         dc.w  RELVERIFY|GADGIMMEDIATE
         dc.w  STRGADGET
         dc.l  XYBorder
         dc.l  0
         dc.l  YText
         dc.l  0
         dc.l  YString     ; specialinfo
         dc.w  STRING|GAD_Y ; ID
         dc.l  0
YString:
         dc.l  YBuffer
         dc.l  0
         dc.w  0
         dc.w  13
         dc.w  0
         dc.w  0,0,0,0,0
         dc.l  0
         dc.l  0,0
YText:
         dc.b  1,2      ; pens
         dc.b  RP_JAM1,0   ; drawmodes
         dc.w  -10,0    ; offsets
         dc.l  0        ; default font
         dc.l  YLetter  ; (yeah, just one letter)
         dc.l  0        ; no more text
XYBorder:
         dc.w  -2,-2 ; place
         dc.b  1,0   ; pens
         dc.b  RP_JAM1
         dc.b  5     ; # of pairs
         dc.l  XYPairs  ; the actual data
         dc.l  0
XYPairs:
         dc.w  0,0
         dc.w  107,0
         dc.w  107,11
         dc.w  0,11
         dc.w  0,0
YPLUSGadget:
         dc.l  YMINUSGadget ; and the next one.
         dc.w  10,11,11,6  ; place & size
         dc.w  GADGHCOMP|GADGIMAGE
         dc.w  RELVERIFY|GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  UPimage
         dc.l  0,0,0
         dc.l  0           ; specialinfo
         dc.w  GAD_Y       ; ID
         dc.l  0
YMINUSGadget:
         dc.l  XMINUSGadget ; and the next one.
         dc.w  10,30,11,6  ; place & size
         dc.w  GADGHCOMP|GADGIMAGE
         dc.w  RELVERIFY|GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  DOWNimage
         dc.l  0,0,0
         dc.l  0           ; specialinfo
         dc.w  GAD_Y|MINUS ; ID
         dc.l  0
XMINUSGadget:
         dc.l  XPLUSGadget ; and the next one.
         dc.w  3,18,6,11   ; place & size
         dc.w  GADGHCOMP|GADGIMAGE
         dc.w  RELVERIFY|GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  LEFTimage
         dc.l  0,0,0
         dc.l  0           ; specialinfo
         dc.w  GAD_X|MINUS ; ID
         dc.l  0
XPLUSGadget:
         dc.l  MGadget     ; and the next one.
         dc.w  22,18,6,11  ; place & size
         dc.w  GADGHCOMP|GADGIMAGE
         dc.w  RELVERIFY|GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  RIGHTimage
         dc.l  0,0,0
         dc.l  0           ; specialinfo
         dc.w  GAD_X       ; ID
         dc.l  0
MGadget:
         dc.l  MPLUSGadget ; more to come...
         dc.w  23,42,40,8 ; place & size
         dc.w  GADGHCOMP
         dc.w  RELVERIFY|GADGIMMEDIATE
         dc.w  STRGADGET
         dc.l  MBorder
         dc.l  0
         dc.l  MText
         dc.l  0
         dc.l  MString     ; specialinfo
         dc.w  STRING|GAD_M ; ID
         dc.l  0
MString:
         dc.l  MBuffer
         dc.l  0
         dc.w  0
         dc.w  9
         dc.w  0
         dc.w  0,0,0,0,0
         dc.l  0
         dc.l  0,0
MText:
         dc.b  1,2      ; pens
         dc.b  RP_JAM1,0   ; drawmodes
         dc.w  -18,0    ; offsets
         dc.l  0        ; default font
         dc.l  MLetter  ; (yeah, just one letter)
         dc.l  0        ; no more text
MBorder:
         dc.w  -2,-2 ; place
         dc.b  1,0   ; pens
         dc.b  RP_JAM1
         dc.b  5     ; # of pairs
         dc.l  MPairs   ; the actual data
         dc.l  0
MPairs:
         dc.w  0,0
         dc.w  43,0
         dc.w  43,11
         dc.w  0,11
         dc.w  0,0
MPLUSGadget:
         dc.l  MMINUSGadget ; and the next one.
         dc.w  14,40,6,11   ; place & size
         dc.w  GADGHCOMP|GADGIMAGE
         dc.w  RELVERIFY|GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  LEFTimage
         dc.l  0,0,0
         dc.l  0           ; specialinfo
         dc.w  GAD_M       ; ID
         dc.l  0
MMINUSGadget:
         dc.l  ZGadget     ; and the next one.
         dc.w  66,40,6,11  ; place & size
         dc.w  GADGHCOMP|GADGIMAGE
         dc.w  RELVERIFY|GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  RIGHTimage
         dc.l  0,0,0
         dc.l  0           ; specialinfo
         dc.w  GAD_M|MINUS ; ID
         dc.l  0
ZGadget:
         dc.l  ZPLUSGadget ; more to come...
         dc.w  23,55,40,8  ; place & size
         dc.w  GADGHCOMP
         dc.w  RELVERIFY|GADGIMMEDIATE|STRINGRIGHT
         dc.w  STRGADGET
         dc.l  ZBorder
         dc.l  0
         dc.l  ZText
         dc.l  0
         dc.l  ZString     ; specialinfo
         dc.w  STRING|GAD_Z ; ID
         dc.l  0
ZString:
         dc.l  ZBuffer
         dc.l  0
         dc.w  0
         dc.w  9
         dc.w  0
         dc.w  0,0,0,0,0
         dc.l  0
         dc.l  0,0
ZText:
         dc.b  1,2      ; pens
         dc.b  RP_JAM1,0   ; drawmodes
         dc.w  -18,0    ; offsets
         dc.l  0        ; default font
         dc.l  ZLetter  ; (yeah, just one letter)
         dc.l  0        ; no more text
* These are same as ZBorder. One could optimize. Why should one?
ZBorder:
         dc.w  -2,-2 ; place
         dc.b  1,0   ; pens
         dc.b  RP_JAM1
         dc.b  5     ; # of pairs
         dc.l  ZPairs   ; the actual data
         dc.l  0
ZPairs:
         dc.w  0,0
         dc.w  43,0
         dc.w  43,11
         dc.w  0,11
         dc.w  0,0
ZPLUSGadget:
         dc.l  ZMINUSGadget ; and the next one.
         dc.w  14,53,6,11  ; place & size
         dc.w  GADGHCOMP|GADGIMAGE
         dc.w  RELVERIFY|GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  LEFTimage
         dc.l  0,0,0
         dc.l  0           ; specialinfo
         dc.w  GAD_Z       ; ID
         dc.l  0
ZMINUSGadget:
         dc.l  IGadget     ; still these to go
         dc.w  66,53,6,11  ; place & size
         dc.w  GADGHCOMP|GADGIMAGE
         dc.w  RELVERIFY|GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  RIGHTimage
         dc.l  0,0,0
         dc.l  0           ; specialinfo
         dc.w  GAD_Z|MINUS ; ID
         dc.l  0
IGadget:
         dc.l  IMINUSGadget ; more to come...
         dc.w  27,68,32,8 ; place & size
         dc.w  GADGHCOMP
         dc.w  RELVERIFY|GADGIMMEDIATE|STRINGRIGHT
         dc.w  STRGADGET
         dc.l  IBorder
         dc.l  0
         dc.l  IText
         dc.l  0
         dc.l  IString     ; specialinfo
         dc.w  STRING|GAD_I ; ID
         dc.l  0
IString:
         dc.l  IBuffer
         dc.l  0
         dc.w  0
         dc.w  6
         dc.w  0
         dc.w  0,0,0,0,0
         dc.l  0
         dc.l  0,0
IText:
         dc.b  1,2      ; pens
         dc.b  RP_JAM1,0   ; drawmodes
         dc.w  -22,0    ; offsets
         dc.l  0        ; default font
         dc.l  ILetter  ; (yeah, just one letter)
         dc.l  0        ; no more text
* This is actually same as ZBorder & ZPairs, but who cares?
IBorder:
         dc.w  -2,-2    ; place
         dc.b  1,0      ; pens
         dc.b  RP_JAM1
         dc.b  5        ; # of pairs
         dc.l  IPairs   ; the actual data
         dc.l  0
IPairs:
         dc.w  0,0
         dc.w  35,0
         dc.w  35,11
         dc.w  0,11
         dc.w  0,0
IMINUSGadget:
         dc.l  IPLUSGadget ; and the next one.
         dc.w  18,66,6,11  ; place & size
         dc.w  GADGHCOMP|GADGIMAGE
         dc.w  RELVERIFY|GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  LEFTimage
         dc.l  0,0,0
         dc.l  0           ; specialinfo
         dc.w  GAD_I|MINUS ; ID
         dc.l  0
IPLUSGadget:
         dc.l  ZOOMGadget  ; and still more.
         dc.w  62,66,6,11  ; place & size
         dc.w  GADGHCOMP|GADGIMAGE
         dc.w  RELVERIFY|GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  RIGHTimage
         dc.l  0,0,0
         dc.l  0              ; specialinfo
         dc.w  GAD_I          ; ID
         dc.l  0
ZOOMGadget:
         dc.l  DRAWGadget     ; and still more.
         dc.w  73,40,32,12    ; place & size
         dc.w  GADGHIMAGE|GADGIMAGE
         dc.w  GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  ZOOMimage0
         dc.l  ZOOMimage1
         dc.l  0,0
         dc.l  0              ; specialinfo
         dc.w  GAD_ZOOM|ZOOMTYPE ; ID
         dc.l  0
DRAWGadget:
         dc.l  RESETGadget    ; and still more.
         dc.w  73,53,32,12    ; place & size
         dc.w  GADGHIMAGE|GADGIMAGE
         dc.w  GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  DRAWimage0
         dc.l  DRAWimage1
         dc.l  0,0
         dc.l  0              ; specialinfo
         dc.w  GAD_DRAW|ZOOMTYPE ; ID
         dc.l  0
RESETGadget:
         dc.l  MANDELGadget   ; and still more.
         dc.w  73,66,32,12    ; place & size
         dc.w  GADGHIMAGE|GADGIMAGE
         dc.w  GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  RESETimage0
         dc.l  RESETimage1
         dc.l  0,0
         dc.l  0              ; specialinfo
         dc.w  GAD_RESET|ZOOMTYPE ; ID
         dc.l  0
MANDELGadget:
         dc.l  JULIAGadget    ; and still more.
         dc.w  106,40,19,25   ; place & size
         dc.w  GADGHIMAGE|GADGIMAGE
         dc.w  GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  MANDELimage0   ; gadgetrender
         dc.l  MANDELimage1   ; selectrender
         dc.l  0,0
         dc.l  0              ; specialinfo
         dc.w  GAD_MANDEL|SETTYPE ; ID
         dc.l  0
JULIAGadget:
         dc.l  QUITGadget     ; and still more.
         dc.w  126,40,19,25   ; place & size
         dc.w  GADGHIMAGE|GADGIMAGE
         dc.w  GADGIMMEDIATE
         dc.w  BOOLGADGET
         dc.l  JULIAimage0    ; gadgetrender
         dc.l  JULIAimage1    ; selectrender
         dc.l  0,0
         dc.l  0              ; specialinfo
         dc.w  GAD_JULIA|SETTYPE ; ID
         dc.l  0
QUITGadget:
         dc.l  0              ; This was the end (Thank Goddess) (see below)
         dc.w  106,66,39,12   ; place & size
         dc.w  GADGHIMAGE|GADGIMAGE
         dc.w  GADGIMMEDIATE|RELVERIFY
         dc.w  BOOLGADGET
         dc.l  QUITimage0
         dc.l  QUITimage1
         dc.l  0,0
         dc.l  0              ; specialinfo
         dc.w  GAD_QUIT       ; ID
         dc.l  0

* That was God awful!!! Gadget after gadget, structure after structure...
* Uhh... It must've been a real pain to code a program like preferences
* with thousands of gadgets.

UPimage:
         dc.w  0,0         ; offsets
         dc.w  11,6        ; w, h
         dc.w  DEPTH       ; depth
         dc.l  UParrow     ; actual image
         dc.b  %00011      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
* The nextimage field seems to be important. Forget it and you
* will have to debug your program for weeks.
DOWNimage:
         dc.w  0,0         ; offsets
         dc.w  11,6        ; w, h
         dc.w  DEPTH       ; depth
         dc.l  DOWNarrow   ; actual image
         dc.b  %00011      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
LEFTimage:
         dc.w  0,0         ; offsets
         dc.w  6,11        ; w, h
         dc.w  DEPTH       ; depth
         dc.l  LEFTarrow   ; actual image
         dc.b  %00011      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
RIGHTimage:
         dc.w  0,0         ; offsets
         dc.w  6,11        ; w, h
         dc.w  DEPTH       ; depth
         dc.l  RIGHTarrow  ; actual image
         dc.b  %00011      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
ZOOMimage0:
         dc.w  0,0         ; offsets
         dc.w  32,12       ; w, h
         dc.w  DEPTH       ; depth
         dc.l  ZOOMpict    ; actual image
         dc.b  %00001      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
ZOOMimage1:
         dc.w  0,0         ; offsets
         dc.w  32,12       ; w, h
         dc.w  DEPTH       ; depth
         dc.l  ZOOMpict    ; actual image
         dc.b  %00011      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
DRAWimage0:
         dc.w  0,0         ; offsets
         dc.w  32,12       ; w, h
         dc.w  DEPTH       ; depth
         dc.l  DRAWpict    ; actual image
         dc.b  %00001      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
DRAWimage1:
         dc.w  0,0         ; offsets
         dc.w  32,12       ; w, h
         dc.w  DEPTH       ; depth
         dc.l  DRAWpict    ; actual image
         dc.b  %00011      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
RESETimage0:
         dc.w  0,0         ; offsets
         dc.w  32,12       ; w, h
         dc.w  DEPTH       ; depth
         dc.l  RESETpict   ; actual image
         dc.b  %00001      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
RESETimage1:
         dc.w  0,0         ; offsets
         dc.w  32,12       ; w, h
         dc.w  DEPTH       ; depth
         dc.l  RESETpict   ; actual image
         dc.b  %00011      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
JULIAimage0:
         dc.w  0,0         ; offsets
         dc.w  19,25       ; w, h
         dc.w  DEPTH       ; depth
         dc.l  JULIApict   ; actual image
         dc.b  %00001      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
JULIAimage1:
         dc.w  0,0         ; offsets
         dc.w  19,25       ; w, h
         dc.w  DEPTH       ; depth
         dc.l  JULIApict   ; actual image
         dc.b  %00011      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
MANDELimage0:
         dc.w  0,0         ; offsets
         dc.w  19,25       ; w, h
         dc.w  DEPTH       ; depth
         dc.l  MANDELpict  ; actual image
         dc.b  %00001      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
MANDELimage1:
         dc.w  0,0         ; offsets
         dc.w  19,25       ; w, h
         dc.w  DEPTH       ; depth
         dc.l  MANDELpict  ; actual image
         dc.b  %00011      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
QUITimage0:
         dc.w  0,0         ; offsets
         dc.w  39,12       ; w, h
         dc.w  DEPTH       ; depth
         dc.l  QUITpict    ; actual image
         dc.b  %00001      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage
QUITimage1:
         dc.w  0,0         ; offsets
         dc.w  39,12       ; w, h
         dc.w  DEPTH       ; depth
         dc.l  QUITpict    ; actual image
         dc.b  %00011      ; planepick
         dc.b  %00000      ; planeonoff
         dc.l  0           ; nextimage

Cross:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  2           ; # of pairs
         dc.l  CrossVPairs ; the actual data
         dc.l  CrossH      ; next
CrossVPairs:
         dc.w  -10,0
         dc.w  10,0
CrossH:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  2           ; # of pairs
         dc.l  CrossHPairs ; the actual data
         dc.l  0           ; next
CrossHPairs:
         dc.w  0,-10
         dc.w  0,10

TopLeft:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  3           ; # of pairs
         dc.l  TopLeftPairs ; the actual data
         dc.l  0
TopLeftPairs:
         dc.w  0,10
         dc.w  0,0
         dc.w  10,0
TopRight:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  3           ; # of pairs
         dc.l  TopRightPairs ; the actual data
         dc.l  0
TopRightPairs:
         dc.w  0,10
         dc.w  0,0
         dc.w  -10,0
BottomLeft:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  3           ; # of pairs
         dc.l  BottomLeftPairs ; the actual data
         dc.l  0
BottomLeftPairs:
         dc.w  0,-10
         dc.w  0,0
         dc.w  10,0
BottomRight:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  3           ; # of pairs
         dc.l  BottomRightPairs ; the actual data
         dc.l  0
BottomRightPairs:
         dc.w  0,-10
         dc.w  0,0
         dc.w  -10,0
LeftLeft:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  3           ; # of pairs
         dc.l  LeftLeftPairs ; the actual data
         dc.l  LeftVLine
LeftLeftPairs:
         dc.w  5,5
         dc.w  0,0
         dc.w  5,-5
LeftVLine:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  2           ; # of pairs
         dc.l  LeftVPairs  ; the actual data
         dc.l  0
LeftVPairs:
         dc.w  1,0
         dc.w  10,0
RightRight:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  3           ; # of pairs
         dc.l  RightRightPairs ; the actual data
         dc.l  RightVLine
RightRightPairs:
         dc.w  -5,5
         dc.w  0,0
         dc.w  -5,-5
RightVLine:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  2           ; # of pairs
         dc.l  RightVPairs  ; the actual data
         dc.l  0
RightVPairs:
         dc.w  -1,0
         dc.w  -10,0
UpUp:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  3           ; # of pairs
         dc.l  UpUpPairs   ; the actual data
         dc.l  UpHLine
UpUpPairs:
         dc.w  -5,5
         dc.w  0,0
         dc.w  5,5
UpHLine:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  2           ; # of pairs
         dc.l  UpHPairs    ; the actual data
         dc.l  0
UpHPairs:
         dc.w  0,1
         dc.w  0,10
DownDown:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  3           ; # of pairs
         dc.l  DownDownPairs ; the actual data
         dc.l  DownHLine
DownDownPairs:
         dc.w  -5,-5
         dc.w  0,0
         dc.w  5,-5
DownHLine:
         dc.w  0,0         ; place
         dc.b  31,0        ; pens
         dc.b  RP_COMPLEMENT
         dc.b  2           ; # of pairs
         dc.l  DownHPairs    ; the actual data
         dc.l  0
DownHPairs:
         dc.w  0,-1
         dc.w  0,-10
Coords:
         dc.b  1,2         ; pens
         dc.b  RP_JAM2,0      ; drawmode, (wordalign)
         dc.w  1,1         ; offsets
         dc.l  0           ; font (use default)
         dc.l  CoordText   ; the actual text
         dc.l  0           ; no more text

* These options are for CLI usage.
* Note: There are currently three synonyms in these options, namely
* -j# -j  -x# -x  -m# -m
* The presence of a number determines how they are interpreted.
* It is entirely safe to add new options here.

jumptable:
         dc.l  opt_x,opt_y,opt_m,opt_i
         dc.l  opt_l,opt_h,opt_a
         dc.l  opt_c,opt_w,opt_p
         dc.l  opt_g
         dc.l  opt_j
         dc.l  opt_s

options: dc.b  'XYMILHACWPGJS',0  ; These in UPPER CASE...
         ds.w  0

* And now for WB usage. The synonyms do no longer exists, so
* entry points are now slightly different.
* Also, flags lhacwpgx are entered from WB with a sinle FLAGS=
* tooltype.
* I try to organize my program in such a way that you may
* insert new entries here if you like.
WBjumptable
         dc.l  opt_x,opt_y,opt_m,opt_i,opt_jx,opt_jy
         dc.l  opt_flags,opt_s
WBoptions
         dc.b  'X',0
         dc.b  'Y',0
         dc.b  'M',0
         dc.b  'I',0
         dc.b  'JX',0
         dc.b  'JY',0
         dc.b  'FLAGS',0   ; LHA, CWP, XG, JM
         dc.b  'SAVE',0
         dc.b  0           ; This means end
         ds.w  0

ERROR_none     EQU   0
ERROR_nosignal EQU   1
ERROR_cmdline  EQU   2
ERROR_noscreen EQU   3
ERROR_nowindow EQU   4
ERROR_nomem    EQU   5
ERROR_noifflib EQU   6
ERROR_ifflib   EQU   7
ERROR_iconlib  EQU   8
ERROR_noicon   EQU   9
ERROR_tooltype EQU   10

errors:
         dc.l  msg_none,msg_nosignal,msg_cmdline,msg_noscreen,msg_nowindow
         dc.l  msg_nomem,msg_noifflib,msg_ifflib,msg_iconlib,msg_noicon
         dc.l  msg_tooltype

msg_none:      dc.b  0
msg_nosignal:  dc.b  ': Could not allocate signal bit',10,0
msg_cmdline:   dc.b  ': Error in command line options',10,0
msg_noscreen:  dc.b  ': Could not open screen',10,0
msg_nowindow:  dc.b  ': Could not open window',10,0
msg_nomem:     dc.b  ': Could not allocate memory',10,0
msg_noifflib:  dc.b  ': You need iff.library in your libs: directory'
               dc.b  ' to save pictures',10,0
msg_ifflib:    dc.b  ': iff.library returned error on save command',10,0
msg_iconlib    dc.b  ': Could not open icon.library',10,0
msg_noicon     dc.b  ': Could not check icon (for tool types)',10,0
msg_tooltype   dc.b  ': Error in tooltype options',10,0


XBuffer: dc.b  '+0.000000000',0
YBuffer: dc.b  '+0.000000000',0
MBuffer: dc.b  '00.00000',0
ZBuffer: dc.b  '+0.00000',0
IBuffer: dc.b  '00000',0
XLetter: dc.b  'x',0
YLetter: dc.b  'y',0
MLetter: dc.b  'M',0
ZLetter: dc.b  'Z',0
ILetter: dc.b  'i',0

ScreenTitle:
         dc.b  'MandelBrot',0

CoordText:
         dc.b  '+0.000000000 +0.000000000',0


_GfxLib        dc.b  'graphics.library',0
_IntuitionLib  dc.b  'intuition.library',0
_DosLib        dc.b  'dos.library',0
_IconLib       dc.b  'icon.library',0
_IffLib        dc.b  'iff.library',0
_TimerDev      dc.b  'timer.device',0

LongUsage:
   dc.b  10
   dc.b  'This program draws the Mandelbrot and Julia sets'
   dc.b                                       ' (z -> z² + c)',10
   dc.b  'using a smart contour-crawling method'
   dc.b                   ' and fast 32-bit fixed point math.',10
   dc.b  'Author: Hannu "the DM" Helminen',10
   dc.b  10
   dc.b  'Freely distributable version 1.00',10
   dc.b  10
   dc.b  ' z =  x +  y i is the centerpoint of the set',10
   dc.b  ' c = jx + jy i is a constant only for Julia sets',10
   dc.b  ' m is magnification, 5 - 29 (log scale)',10
   dc.b  ' i is the maximum number of iterations, i <= 65535',10
   dc.b  'Save pictures to filename by CTRL-S',10
   dc.b  10
   dc.b  'Flags: -l low    -h high  -a auto precision',10
   dc.b  '       -c crawl  -w walk  -p crawl if possible',10
   dc.b  '       -x exit   -g use GUI',10
   dc.b  '       -j julia  -m mandelbrot',10
ShortUsage:
   dc.b  10
   dc.b  'Usage: mandel  or  mandel ?',10
   dc.b  '   or  mandel '
   dc.b  '{-x',$1b,'[4mx',$1b,'[0m'
   dc.b  ' -y',$1b,'[4my',$1b,'[0m'
   dc.b  ' -m',$1b,'[4mm',$1b,'[0m'
   dc.b  ' -i',$1b,'[4mi',$1b,'[0m'
   dc.b  ' -l-h-a -c-w-p -x-g -j-m'
   dc.b  10,'              '
   dc.b  ' -jx',$1b,'[4mjx',$1b,'[0m'
   dc.b  ' -jy',$1b,'[4mjy',$1b,'[0m'
   dc.b  ' -s',$1b,'[4m<filename>',$1b,'[0m'
   dc.b  '}'

   dc.b  10
LongLen     EQU   *-LongUsage
ShortLen    EQU   *-ShortUsage

stdout_name
   dc.b  'con:0/50/640/100/ mandel  by DM  1990 ',0

NameBuffer  dc.b  'mandel.picture'
Null        dc.b  0
            ds.b  256      ; enough for any filename to be stored here.

NameEnd     dc.l  Null     ; pointer to end of string



   SECTION  images,DATA,CHIP
UParrow:
         dc.w  %0000010000000000
         dc.w  %0000101000000000
         dc.w  %0001000100000000
         dc.w  %0010000010000000
         dc.w  %0100000001000000
         dc.w  %1111111111100000

         dc.w  %0000000000000000
         dc.w  %0000010000000000
         dc.w  %0000111000000000
         dc.w  %0001111100000000
         dc.w  %0011111110000000
         dc.w  %0000000000000000
DOWNarrow:
         dc.w  %1111111111100000
         dc.w  %0100101001000000
         dc.w  %0010000010000000
         dc.w  %0001000100000000
         dc.w  %0000101000000000
         dc.w  %0000010000000000

         dc.w  %0000000000000000
         dc.w  %0011111110000000
         dc.w  %0001111100000000
         dc.w  %0000111000000000
         dc.w  %0000010000000000
         dc.w  %0000000000000000
LEFTarrow:
         dc.w  %0000010000000000
         dc.w  %0000110000000000
         dc.w  %0001010000000000
         dc.w  %0010010000000000
         dc.w  %0100010000000000
         dc.w  %1000010000000000
         dc.w  %0100010000000000
         dc.w  %0010010000000000
         dc.w  %0001010000000000
         dc.w  %0000110000000000
         dc.w  %0000010000000000

         dc.w  %0000000000000000
         dc.w  %0000000000000000
         dc.w  %0000100000000000
         dc.w  %0001100000000000
         dc.w  %0011100000000000
         dc.w  %0111100000000000
         dc.w  %0011100000000000
         dc.w  %0001100000000000
         dc.w  %0000100000000000
         dc.w  %0000000000000000
         dc.w  %0000000000000000
RIGHTarrow:
         dc.w  %1000000000000000
         dc.w  %1100000000000000
         dc.w  %1010000000000000
         dc.w  %1001000000000000
         dc.w  %1000100000000000
         dc.w  %1000010000000000
         dc.w  %1000100000000000
         dc.w  %1001000000000000
         dc.w  %1010000000000000
         dc.w  %1100000000000000
         dc.w  %1000000000000000

         dc.w  %0000000000000000
         dc.w  %0000000000000000
         dc.w  %0100000000000000
         dc.w  %0110000000000000
         dc.w  %0111000000000000
         dc.w  %0111100000000000
         dc.w  %0111000000000000
         dc.w  %0110000000000000
         dc.w  %0100000000000000
         dc.w  %0000000000000000
         dc.w  %0000000000000000

ZOOMpict:
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000001111111100
         dc.w  %0111001000100101,%0000001000000100
         dc.w  %0001010101010111,%0000001001100100
         dc.w  %0010010101010101,%0000011110010100
         dc.w  %0100010101010101,%0000011110010100
         dc.w  %0111001000100101,%0000001001100100
         dc.w  %0000000000000000,%0000001000000100
         dc.w  %0000000000000000,%0000001111111100
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000

         dc.w  %1111111111111111,%1111111111111111
         dc.w  %1111111111111111,%1111111111111111
         dc.w  %1111111111111111,%1111110000000011
         dc.w  %1000110111011010,%1111110000000011
         dc.w  %1110101010101000,%1111110000000011
         dc.w  %1101101010101010,%1111100000000011
         dc.w  %1011101010101010,%1111100000000011
         dc.w  %1000110111011010,%1111110000000011
         dc.w  %1111111111111111,%1111110000000011
         dc.w  %1111111111111111,%1111110000000011
         dc.w  %1111111111111111,%1111111111111111
         dc.w  %1111111111111111,%1111111111111111

DRAWpict:
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000011111111100
         dc.w  %0000000000000000,%0000010000000100
         dc.w  %0110011001110101,%0111111010000100
         dc.w  %0101010101010101,%0100010000000100
         dc.w  %0101011001110101,%0100010010000100
         dc.w  %0101010101010111,%0100010000000100
         dc.w  %0110010101010101,%0100010010000100
         dc.w  %0000000000000000,%0100011111111100
         dc.w  %0000000000000000,%0100000010000000
         dc.w  %0000000000000000,%0111111110000000
         dc.w  %0000000000000000,%0000000000000000

         dc.w  %1111111111111111,%1111111111111111
         dc.w  %1111111111111111,%1111100000000011
         dc.w  %1111111111111111,%1111100000000011
         dc.w  %1001100110001010,%1000000000000011
         dc.w  %1010101010101010,%1000000000000011
         dc.w  %1010100110001010,%1000000000000011
         dc.w  %1010101010101000,%1000000000000011
         dc.w  %1001101010101010,%1000000000000011
         dc.w  %1111111111111111,%1000000000000011
         dc.w  %1111111111111111,%1000000001111111
         dc.w  %1111111111111111,%1000000001111111
         dc.w  %1111111111111111,%1111111111111111
RESETpict:
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000001110011100
         dc.w  %0110011100110111,%0111001100001100
         dc.w  %0101010001000100,%0010001010010100
         dc.w  %0110011000100110,%0010000000000000
         dc.w  %0101010000010100,%0010000000000000
         dc.w  %0101011101100111,%0010001010010100
         dc.w  %0000000000000000,%0000001100001100
         dc.w  %0000000000000000,%0000001110011100
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000

         dc.w  %1111111111111111,%1111111111111111
         dc.w  %1111111111111111,%1111111111111111
         dc.w  %1111111111111111,%1111110001100011
         dc.w  %1001100011001000,%1000110011110011
         dc.w  %1010101110111011,%1101110101101011
         dc.w  %1001100111011001,%1101111111111111
         dc.w  %1010101111101011,%1101111111111111
         dc.w  %1010100010011000,%1101110101101011
         dc.w  %1111111111111111,%1111110011110011
         dc.w  %1111111111111111,%1111110001100011
         dc.w  %1111111111111111,%1111111111111111
         dc.w  %1111111111111111,%1111111111111111

MANDELpict:
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0010101110110011,%0000000000000000
         dc.w  %0011101010101010,%1000000000000000
         dc.w  %0010101110101010,%1000000000000000
         dc.w  %0010101010101010,%1000000000000000
         dc.w  %0010101010101011,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000010000,%0000000000000000
         dc.w  %0000000001101100,%0000000000000000
         dc.w  %0000000010000010,%0000000000000000
         dc.w  %0000011010000010,%0000000000000000
         dc.w  %0000100100000010,%0000000000000000
         dc.w  %0011100000000100,%0000000000000000
         dc.w  %0000100100000010,%0000000000000000
         dc.w  %0000011010000010,%0000000000000000
         dc.w  %0000000010000010,%0000000000000000
         dc.w  %0000000001101100,%0000000000000000
         dc.w  %0000000000010000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000

         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1101010001001100,%1110000000000000
         dc.w  %1100010101010101,%0110000000000000
         dc.w  %1101010001010101,%0110000000000000
         dc.w  %1101010101010101,%0110000000000000
         dc.w  %1101010101010100,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111101111,%1110000000000000
         dc.w  %1111111110010011,%1110000000000000
         dc.w  %1111111101111101,%1110000000000000
         dc.w  %1111100101111101,%1110000000000000
         dc.w  %1111011011111101,%1110000000000000
         dc.w  %1100011111111011,%1110000000000000
         dc.w  %1111011011111101,%1110000000000000
         dc.w  %1111100101111101,%1110000000000000
         dc.w  %1111111101111101,%1110000000000000
         dc.w  %1111111110010011,%1110000000000000
         dc.w  %1111111111101111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000

JULIApict:
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0001010101000101,%1100000000000000
         dc.w  %0001010101000101,%0100000000000000
         dc.w  %0001010101000101,%1100000000000000
         dc.w  %0101010101000101,%0100000000000000
         dc.w  %0111011101110101,%0100000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000011110000000,%0000000000000000
         dc.w  %0000100001000000,%0000000000000000
         dc.w  %0001100000100000,%0000000000000000
         dc.w  %0000010000100000,%0000000000000000
         dc.w  %0000010000010000,%0000000000000000
         dc.w  %0000001000010000,%0000000000000000
         dc.w  %0000001000001000,%0000000000000000
         dc.w  %0000000100000110,%0000000000000000
         dc.w  %0000000010000100,%0000000000000000
         dc.w  %0000000001111000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000

         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1110101010111010,%0010000000000000
         dc.w  %1110101010111010,%1010000000000000
         dc.w  %1110101010111010,%0010000000000000
         dc.w  %1010101010111010,%1010000000000000
         dc.w  %1000100010001010,%1010000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111100001111111,%1110000000000000
         dc.w  %1111011110111111,%1110000000000000
         dc.w  %1110011111011111,%1110000000000000
         dc.w  %1111101111011111,%1110000000000000
         dc.w  %1111101111101111,%1110000000000000
         dc.w  %1111110111101111,%1110000000000000
         dc.w  %1111110111110111,%1110000000000000
         dc.w  %1111111011111001,%1110000000000000
         dc.w  %1111111101111011,%1110000000000000
         dc.w  %1111111110000111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
         dc.w  %1111111111111111,%1110000000000000
QUITpict:
         dc.w  %0000000000000000,%0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000001111,%1111000000000000
         dc.w  %0011101010101110,%0000000000001000,%0001000000000000
         dc.w  %0010101010100100,%0000000000001010,%0101000000000000
         dc.w  %0010101010100100,%0000000000001001,%1001000000000000
         dc.w  %0010101010100100,%0000000000001001,%1001000000000000
         dc.w  %0011101110100100,%0000000000001010,%0101000000000000
         dc.w  %0000100000000000,%0000000000001000,%0001000000000000
         dc.w  %0000000000000000,%0000000000001111,%1111000000000000
         dc.w  %0000000000000000,%0000000000000000,%0000000000000000
         dc.w  %0000000000000000,%0000000000000000,%0000000000000000

         dc.w  %1111111111111111,%1111111111111111,%1111111000000000
         dc.w  %1111111111111111,%1111111111111111,%1111111000000000
         dc.w  %1111111111111111,%1111111111110000,%0000111000000000
         dc.w  %1100010101010001,%1111111111110000,%0000111000000000
         dc.w  %1101010101011011,%1111111111110000,%0000111000000000
         dc.w  %1101010101011011,%1111111111110000,%0000111000000000
         dc.w  %1101010101011011,%1111111111110000,%0000111000000000
         dc.w  %1100010001011011,%1111111111110000,%0000111000000000
         dc.w  %1111011111111111,%1111111111110000,%0000111000000000
         dc.w  %1111111111111111,%1111111111110000,%0000111000000000
         dc.w  %1111111111111111,%1111111111111111,%1111111000000000
         dc.w  %1111111111111111,%1111111111111111,%1111111000000000

   SECTION  pointers,BSS

* Nimi:                  Ja se on:

_GfxBase       ds.l  1
_IntuitionBase ds.l  1
_DosBase       ds.l  1
_ExecBase      EQU   $4
_TimerBase     ds.l  1

MyScreen:   ds.l  1  ; screen structure
MyWindow1:  ds.l  1  ; window
MyWindow2:  ds.l  1  ; another window, non-zero if valid
UseReq:     ds.l  1  ; timer iOreq, non-zero if request pending
Mem1:       ds.l  1  ; TmpRas bitmap pointer
Mem2:       ds.l  1  ; mem for AreaInfo table
WBmessage:  ds.l  1  ; Workbench startup message (null if from CLI)
MyName:     ds.l  1  ; self-explanatory

OldSecs:    ds.l  1  ; to test double-click
OldMicros:  ds.l  1  ; -"-
Magnify:    ds.l  1  ; temp storages for: magnification
OldMagnify: ds.l  1  ;
CurrentX:   ds.l  1  ; x-coordinate
CurrentY:   ds.l  1  ; y-coordinate
Zoom:       ds.l  1  ; zooming
Counter:    ds.w  1  ; identify each save-file with a number
MyNameLen:  ds.w  1  ; works with MyName above


* Some stuff to make RemoveGrid easier
centerx     ds.w  1
centery     ds.w  1
lowx        ds.w  1
lowy        ds.w  1
highx       ds.w  1
highy       ds.w  1
pic_c       ds.l  1
pic_tl      ds.l  1
pic_tr      ds.l  1
pic_bl      ds.l  1
pic_br      ds.l  1

prex        ds.l  1
prey        ds.l  1

* We seem to need MANY temporary buffers for x/y coordinates.
* This one for RightButton.
tmpx        ds.w  1
tmpy        ds.w  1

* Huh! My very own structure.
MyMandelBrot:
            ds.b  mb_SIZEOF
MyTmpRas:   ds.b  tr_SIZEOF
MyAreaInfo: ds.b  ai_SIZEOF
IOreq:      ds.b  IOTV_SIZE
MsgPort:    ds.b  MP_SIZE

inter:      ds.b  1     ; Boolean: are we interactive
error:      ds.b  1     ; general error code
method:     ds.b  1     ; method of zooming (ZOOM, REDRAW or RESET)
isdrawn:    dc.b  1     ; Boolean: is grid drawn?
saveit:     dc.b  1     ; Boolean: do we have to save picture?
         end

