;FRACTAL DRAGON ©1989 BY DANIEL WOLF PH.D.
;ADAPTS TO INTERLACE SCREEN BY DOUBLING WINDOW HEIGHT AND ADDING
;ONE MORE DRAW CYCLE WITH FINER RESOLUTION
;USES REGISTERS AMAP TO CUT DOWN ON MEMORY READS FOR SPEED
;04/21/89

;EXEC LIBRARY OFFSETS

LVO.GETMSG              EQU $FFFFFE8C
LVO.REPLYMSG            EQU $FFFFFE86
LVO.OPENLIBRARY         EQU $FFFFFE68
LVO.CLOSELIBRARY        EQU $FFFFFE62


;DOS LIBRARY OFFSET

LVO.DELAY               EQU $FFFFFF3A


;INTUITION LIBRARY OFFSETS

LVO.OPENWINDOW          EQU $FFFFFF34
LVO.CLOSEWINDOW         EQU $FFFFFFB8
LVO.SIZEWINDOW          EQU $FFFFFEE0
LVO.VIEWPORTADDRESS     EQU $FFFFFED4


;GRAPHIC LIBRARY OFFSETS

LVO.SETDRMD     EQU $FFFFFE9E
LVO.SETAPEN     EQU $FFFFFEAA
LVO.WRITEPIXEL  EQU $FFFFFEBC
LVO.MOVE        EQU $FFFFFF10
LVO.DRAW        EQU $FFFFFF0A
LVO.RECTFILL    EQU $FFFFFECE


;AMIGA CONSTANTS WE NEED

VP.MODES        EQU 32
LACE            EQU 4
JAM1            EQU 0

ACTIVATE        EQU $1000
WINDOWDRAG      EQU 2
WINDOWCLOSE     EQU 8
WINDOWDEPTH     EQU 4
CLOSEWINDOW     EQU $200
SMART_REFRESH   EQU 0
WBENCHSCREEN    EQU 1
IM.CLASS        EQU 20
WW.RPORT        EQU 50
WW.USERPORT     EQU 86
WW.WIDTH        EQU 8
WW.HEIGHT       EQU 10
TICKSPERSECOND  EQU 50

INITX           EQU 91
INITY           EQU 100

MAIN                            ;GET IT TOGETHER FIRST
 MOVE.L $4,A6                   ;GET EXEC LIBRARY POINTER AT MEM LOCATION 4

 MOVE.L #DOSNAME,A1
 JSR LVO.OPENLIBRARY(A6)
 TST.L D0
 BEQ ERROR
 MOVE.L D0,DOSBASE

 MOVE.L #GFXNAME,A1
 JSR LVO.OPENLIBRARY(A6)        ;OPEN GRAPHICS LIBRARY
 TST.L D0
 BEQ ERROR
 MOVE.L D0,GFXBASE

 MOVEA.L #INTNAME,A1
 JSR LVO.OPENLIBRARY(A6)        ;OPEN INTUITION LIBRARY
 TST.L D0
 BEQ ERROR
 MOVE.L D0,INTBASE

 MOVE.L D0,A6                   ;LETS USE INTUITION NOW!

THEWINDOW                       ;MAKE A NEWWINDOW STRUCTURE BY HAND
 MOVE.L #NEWWINDOW,A0
 JSR LVO.OPENWINDOW(A6)
 MOVE.L D0,WINDOW
 BEQ ERROR

 MOVE.L D0,A0
 MOVE.L WW.RPORT(A0),A5         ;STASH THE WINDOW RASTPORT POINTER IN A5
 JSR LVO.VIEWPORTADDRESS(A6)
 TST.L D0
 BEQ ERROR
 MOVE.L D0,A0
 MOVE.W VP.MODES(A0),D0         ;LOOK UP THIS VIEWPORT MODE (INTERLACED?)
 AND.W #LACE,D0
 BEQ.S RESETLEVEL               ;ITS NOT INTERLACED, CARRY ON

 MOVE.W #1,LACED                ;ITS INTERLACED SO KEEP TRACK OF THAT
 MOVEQ #0,D0
 MOVE.L WINDOW,A0
 MOVE.W WW.HEIGHT(A0),D1
 JSR LVO.SIZEWINDOW(A6)         ;AND DOUBLE THE WINDOW HEIGHT

RESETLEVEL
 MOVE.W #1,NB                   ;NB COUNTS HOW MANY TIMES DRAGON IS DRAWN
 LEA SARAY,A2                   ;NEED ARRAY POINTER SEVERAL TIMES SO STASH NOW

LOOP
 MOVE.L #TICKSPERSECOND*2,D1    ;2 SECONDS TO LOOK AT THE DRAGON!
 MOVE.L DOSBASE,A6              ;NEVER A SOFTWARE DELAY LOOP!!!
 JSR LVO.DELAY(A6)              ;ALWAYS AMIGA DELAY FOR MULTITASKING!

 MOVE.L WINDOW,A0
 MOVE.L WW.USERPORT(A0),A0
 MOVE.L $4,A6
 JSR LVO.GETMSG(A6)             ;GET ANY MESSAGE FROM WINDOW IDCMP
 TST.L D0
 BEQ.S ONE                      ;THERE WAS NO MESSAGE SO SKIP REPLY
 MOVE.L D0,A1
 MOVE.L IM.CLASS(A1),D2         ;HANG ONTO MESSAGE CLASS VALUE IN D2
 JSR LVO.REPLYMSG(A6)           ;QUICK! REPLY NOW!

 CMP.L #CLOSEWINDOW,D2          ;NOW CHECK IF THE CLASS VALUE IS CLOSEWINDOW
 BEQ DONE                       ;YUP, SO WE ARE DONE - USER SAID CLOSE IT

ONE
 MOVEQ #0,D2                    ;TO AVOID THE EXT.L
 MOVEQ #0,D3                    ;INSTRUCTIONS PRIOR TO RECTFILL CALLS

 MOVE.L GFXBASE,A6              ;NOW WE NEED GRAPHICS LIBRARY POINTER
 MOVE.W NB,D0                   ;HOW MANY TIMES HAVE WE DONE THIS = NB
 MOVE.W D0,D1
 ADD.W D1,D1                    ;DOUBLE D1
 MOVE.W D1,NC                   ;VARIABLE NC = 2 * NB IS THE ARRAY SUBSCRIPT
 ADDQ.W #1,D1
 MOVE.W D1,ND                   ;VARIABLE ND = NC + 1
 MOVE.W #128,D1                 ;MAX DX AND DY (LINE LENGTH) = 128
 LSR.W D0,D1                    ;DIVIDE BY 2 ^ NB (SHORTER LINES EACH TIME)
 MOVE.W D1,DY
 ADD.W D1,D1
 MOVE.W D1,DX                   ;BUT MAKE DX = 2*DY
 TST.W LACED
 BEQ DRAWDRAGON
 MOVE.W DX,DY                   ;UNLESS INTERLACED THEN DX = DY

DRAWDRAGON
 MOVE.L A5,A1
 MOVEQ #JAM1,D0
 JSR LVO.SETDRMD(A6)

ERASEDRAGON
 MOVE.L A5,A1
 MOVEQ #0,D0                    ;SET DRAWING COLOR TO BACKGROUND FOR FILL
 JSR LVO.SETAPEN(A6)

 MOVE.L WINDOW,A0
 MOVE.W WW.WIDTH(A0),D2         ;GET WINDOW WIDTH
 MOVE.W WW.HEIGHT(A0),D3        ;AND HEIGHT
 SUBI.W #4,D2                   ;AND SUBTRACT SOME FROM EACH
 SUBI.W #2,D3                   ;TO AVOID BOMBING THE WINDOW BORDERS
 MOVEQ #2,D0                    ;STARTING FROM X = 2 AND Y = 12
 MOVEQ #12,D1                   ;NO EXT.L BECAUSE MOVEQ IS A LONGWORD OP
 MOVE.L A5,A1
 JSR LVO.RECTFILL(A6)           ;FILL WINDOW WITH BACKGROUND COLOR REG

 MOVE.L A5,A1
 MOVEQ #1,D0                    ;NOW SET DRAWING COLOR TO COLOR REG #1
 JSR LVO.SETAPEN(A6)

 MOVE.W #INITX,D7               ;STARTING X POSITION
 MOVE.W #INITY,D6               ;STARTING Y POSITION
 TST.W LACED
 BEQ FIRSTPOSITION
 ADD.W D6,D6                    ;MOVE STARTING Y LOWER IF INTERLACED

FIRSTPOSITION
 MOVE.L A5,A1
 MOVE.W D7,D0
 MOVE.W D6,D1
 EXT.L D0                       ;YES, VIRGINIA, THESE ARE NECESSARY
 EXT.L D1                       ;FOR GRAPHICS LIBRARY FUNCTION CALLS
 JSR LVO.WRITEPIXEL(A6)         ;DRAW A PIXEL AT STARTING POINT

 MOVE.L A2,A4                   ;POINTER TO ARRAY OF WORD DATA
 MOVEQ #0,D0
 MOVEQ #15,D1                   ;CLEAR 32 WORD ARRAY (16 LONGWORDS)
ZERORAY
 MOVE.L D0,(A4)+
 DBRA D1,ZERORAY

DRAGONLOOP
 MOVE.L A2,A4                   ;A2 POINTS TO THE ARRAY
 MOVE.L A2,A3                   ;NOW SO DOES A4
 ADDQ.L #2,A3                   ;AND A3 POINTS ONE ITEM INTO THE ARRAY
 MOVEQ #1,D1

MAKED
 CMPM.W (A3)+,(A4)+             ;MAIN RECURSION AND DRAWING ROUTINE
 BNE.S DPLUSONE
 SUBQ.W #2,D0
DPLUSONE
 ADDQ.W #1,D0
 BPL.S CHEKIFATE
 MOVEQ #7,D0
CHEKIFATE
 CMPI.W #8,D0
 BNE.S CPLUSONE
 MOVEQ #0,D0
CPLUSONE
 ADDQ.W #1,D1
 CMP.W ND,D1
 BNE.S MAKED

 MOVE.W D7,D2
 MOVE.W D6,D3
 TST.W D0
 BEQ.S RIGHT
 CMPI.W #2,D0
 BEQ.S UP
 CMPI.W #4,D0
 BEQ.S LEFT
DOWN
 SUB.W DY,D3
 BRA.S TWO
UP
 ADD.W DY,D3
 BRA.S TWO
LEFT
 SUB.W DX,D2
 BRA.S TWO
RIGHT
 ADD.W DX,D2

TWO
 MOVE.L A5,A1
 MOVE.W D7,D0
 MOVE.W D6,D1
 EXT.L D0
 EXT.L D1
 JSR LVO.MOVE(A6)               ;MOVE TO NEW X,Y
 MOVE.L A5,A1
 MOVE.W D2,D0
 MOVE.W D3,D1
 EXT.L D0
 EXT.L D1
 JSR LVO.DRAW(A6)               ;DRAW FROM OLD X,Y TO NEW X,Y

 MOVE.W D2,D7                   ;OLD X POSITION IS NOW NEW X POSITION
 MOVE.W D3,D6                   ;OLD Y POSITION IS NOW NEW Y POSITION

 MOVE.W NC,D0                   ;NC IS ARRAY SUBSCRIPT
 ADD.W D0,D0                    ;D0 POINTS TO A WORD! IN THE ARRAY
 MOVEQ #0,D1
 ADDI.W #1,0(A2,D0.W)
ARAYLOOP
 CMPI.W #2,0(A2,D0.W)
 BNE.S THREE
 MOVE.W D1,0(A2,D0.W)
 SUBQ.W #2,D0                   ;BACK OFF TO PREVIOUS WORD IN ARRAY
 ADDI.W #1,0(A2,D0.W)
 TST.W D0
 BNE.S ARAYLOOP

THREE
 MOVE.W SARAY,D0                ;IS ARRAY(0) = 0 (IS DRAGON UNFINISHED?)
 BEQ DRAGONLOOP                 ;YUP, SO REPEAT DRAGONLOOP
 ADDI.W #1,NB                   ;INCREMENT NB
 TST.W LACED
 BNE CMPWITH8
 CMPI.W #7,NB                   ;DO IT ONLY 7 TIMES IF NOT INTERLACED
 BNE LOOP
 BRA RESETLEVEL

CMPWITH8
 CMPI.W #8,NB                   ;DO IT      8 TIMES IF INTERLACED
 BNE LOOP

 BRA RESETLEVEL                 ;START THE WHOLE THING OVER AGAIN

DONE
 MOVEQ #0,D7                    ;ALL IS WELL, SET RETURN VALUE OF 0

QUIT
 MOVE.L WINDOW,D0
 BEQ.S 1$

 MOVE.L INTBASE,A6
 MOVE.L D0,A0
 JSR LVO.CLOSEWINDOW(A6)
1$
 MOVE.L $4,A6
 MOVE.L DOSBASE,D0
 BEQ 2$
 MOVE.L D0,A1
 JSR LVO.CLOSELIBRARY(A6)
2$
 MOVE.L GFXBASE,D0
 BEQ 3$
 MOVE.L D0,A1
 JSR LVO.CLOSELIBRARY(A6)
3$
 MOVE.L INTBASE,D0
 BEQ 4$
 MOVE.L D0,A1
 JSR LVO.CLOSELIBRARY(A6)
4$
 MOVE.L D7,D0                   ;PUT RETURN VALUE INTO D0
 RTS

ERROR
 MOVEQ #-1,D7                   ;GENERAL ERROR RETURN VALUE
 BRA QUIT

 DATA                           ;THE DATA SECTION CAN BE SCATTER
                                ;LOADED ANYWHERE
 EVEN

DOSBASE DC.L 0
GFXBASE DC.L 0
INTBASE DC.L 0
WINDOW  DC.L 0

DX      DC.W 0
DY      DC.W 0
NB      DC.W 0
NC      DC.W 0
ND      DC.W 0
LACED   DC.W 0

TITLE DC.B ' DragonCurve ©1989 AMIGA Plus by D. Wolf ',0
 EVEN
DOSNAME DC.B 'dos.library',0
 EVEN
GFXNAME DC.B 'graphics.library',0
 EVEN
INTNAME DC.B 'intuition.library',0
 EVEN

NEWWINDOW
 DC.W 40
 DC.W 16
 DC.W 428
 DC.W 150
 DC.B -1
 DC.B -1
 DC.L CLOSEWINDOW
 DC.L ACTIVATE!WINDOWDRAG!WINDOWDEPTH!WINDOWCLOSE!SMART_REFRESH
 DC.L 0
 DC.L 0
 DC.L TITLE
 DC.L 0
 DC.L 0
 DC.W 40
 DC.W 40
 DC.W 640
 DC.W 400
 DC.W WBENCHSCREEN

 EVEN

 BSS                            ;A BLOCK STORAGE SECTION LETS THE LOADER
                                ;SCATTER LOAD THIS PART ANYWHERE ALSO
SARAY DS.W 32
