;HILBERT CURVE © 1989 BY DANIEL WOLF PH.D.
;ADAPTS TO INTERLACED SCREEN BY DOUBLING WINDOW HEIGHT
;AND EXECUTING ONE MORE DRAWING CYCLE
;WITH EXPLICITLY RECURSIVE DRAWING ROUTINE
;USES REGISTERS AMAP TO CUT DOWN ON MEM READS FOR SPEED
;4/22/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


;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 10
INITY           EQU 12
MAXLEN          EQU 128

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,A2                   ;CHEAT USING INTBASE IN A2 (INSTEAD OF A6)

 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 #0,J                    ;INITIALIZE COUNT OF # TIMES CURVE DRAWN
 SUBA.L A4,A4                   ;CLEAR A4 FOR USE AS DATA STORAGE (P)
 SUBA.L A3,A3                   ;SAME FOR A3 (Z)

LOOP
 MOVE.L #TICKSPERSECOND*2,D1    ;2 SECONDS TO LOOK AT THE DRAGON!
 MOVE.L DOSBASE,A6
 JSR LVO.DELAY(A6)

 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 ONEH                     ;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

ONEH
 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.L A5,A1
 MOVEQ #JAM1,D0
 JSR LVO.SETDRMD(A6)

DONEYET
 ADDQ.W #1,J
 TST.W LACED
 BEQ.S ONLYSEVEN
 CMPI.W #8,J
 BEQ.S RESETLEVEL
 BNE.S ERASEHILBERT
ONLYSEVEN
 CMPI.W #7,J
 BEQ.S RESETLEVEL

ERASEHILBERT
 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)

BEGINHERE
 MOVE.W J,D0
 MOVE.W D0,D7
 MOVE.W #MAXLEN,D1              ;MAX LINE LENGTH
 LSR.W D0,D1                    ;DIVIDED BY 2 ^ J (J = HOW MANY TIMES)
 MOVE.W D1,Q                    ;Q IS LINE LENGTH FOR ONE DRAWING

 MOVEQ #1,D6                    ;INITIALIZE R VALUE

 MOVE.W #INITX,D4               ;STARTING X POSITION
 MOVE.W #INITY,D5               ;STARTING Y POSITION
 TST.W LACED
 BEQ FIRSTPOSITION
 ADDI.W #7,D5                   ;START A LITLE FURTHER DOWN

FIRSTPOSITION
 MOVE.L A5,A1
 MOVE.W D4,D0
 MOVE.W D5,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

 BSR HILFRAC                    ;NOW START THE RECURSIVE FUN AND
 BRA LOOP                       ;WHEN ITS OVER, DO IT AGAIN

HILFRAC
 SUBQ.W #1,D7
 EORI.W #1,D6                   ;D6 = R
 BSR HILARITH
 TST.W D7                       ;D7 = T
 BLE.S M0
 BSR HILFRAC
M0
 BSR DOALINE
 EORI.W #1,D6
 BSR HILARITH
 TST.W D7
 BLE.S M1
 BSR HILFRAC
M1
 BSR DOALINE
 TST.W D7
 BLE.S M2
 BSR HILFRAC
M2
 BSR HILARITH
 EORI.W #1,D6
 BSR DOALINE
 TST.W D7
 BLE.S M3
 BSR HILFRAC
M3
 BSR HILARITH
 EORI.W #1,D6
 ADDQ.W #1,D7
 RTS

HILARITH
 MOVEQ #0,D0
 MOVEA.W Q,A3                   ;A3 = Z
 TST.W D6
 BNE.S PLUSP
MINUSP
 SUB.W A4,D0                    ;A4 = P
 MOVE.W D0,Q
 MOVEA.W A3,A4
 RTS
PLUSP
 MOVE.W A4,Q
 SUB.W A3,D0
 MOVE.W D0,A4
 RTS

DOALINE
 MOVE.W A4,D0                   ;D0 = P
 ADD.W D0,D0                    ;P = P * 2
 ADD.W D4,D0                    ;NEWX = CURRENT X + 2*P
 MOVE.W D0,D2                   ;D2 = NEW X
 MOVE.W D5,D0                   ;TAKE OLD Y
 ADD.W Q,D0                     ;ADD LINE LENGTH
 TST.W LACED
 BEQ.S NOTDOUBLEY
 ADD.W Q,D0                     ;IF INTERLACED ADD LINE LENGTH AGAIN
NOTDOUBLEY
 MOVE.W D0,D3                   ;D3 = NEW Y
 MOVE.W D4,D0                   ;CURRENT X
 MOVE.W D5,D1                   ;CURRENT Y
 EXT.L D0
 EXT.L D1
 MOVE.L A5,A1                   ;THIS IS THE STASHED RASTPORT ADDRESS
 JSR LVO.MOVE(A6)               ;MOVE TO CURRENT X,Y
 MOVE.W D2,D0                   ;NEW X
 MOVE.W D3,D1                   ;NEW Y
 EXT.L D0
 EXT.L D1
 MOVE.L A5,A1
 JSR LVO.DRAW(A6)               ;DRAW TO NEW X,Y
 MOVE.W D2,D4                   ;NEW X = OLD X
 MOVE.W D3,D5                   ;NEW Y = OLD Y
 RTS


DONE
 MOVEQ #0,D7                    ;ALL IS WELL
QUIT
 MOVE.L WINDOW,D0
 BEQ.S 1$
 MOVE.L D0,A0
 MOVE.L A2,A6
 JSR LVO.CLOSEWINDOW(A6)
1$
 MOVE.L $4,A6                   ;GET EXEC LIB POINTER AGAIN
 MOVE.L DOSBASE,D0
 BEQ.S 2$
 MOVE.L D0,A1
 JSR LVO.CLOSELIBRARY(A6)
2$
 MOVE.L GFXBASE,D0
 BEQ.S 3$
 MOVE.L D0,A1
 JSR LVO.CLOSELIBRARY(A6)
3$
 MOVE.L A2,D0
 BEQ.S 4$
 MOVE.L D0,A1
 JSR LVO.CLOSELIBRARY(A6)
4$
 MOVE.L D7,D0                   ;PLACE RETURN VALUE INTO D0
 RTS

ERROR
 MOVEQ #-1,D7                   ;GENERAL NONZERO RETURN VALUE
 BRA QUIT                       ;UPROGRAM THE ERROR MESSAGE STUFF


 DATA

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

J       DC.W 0                  ;NUMBER OF TIMES WE DRAW THE CURVE
Q       DC.W 0                  ;LINE LENGTH EACH TIME WE DRAW
LACED   DC.W 0                  ;INTERLACE FLAG FOR OUR OWN USE

TITLE DC.B 'Hilbert ©1989 AMIGA Plus',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 275
 DC.W 142
 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
