1457 lines
No EOL
36 KiB
Text
1457 lines
No EOL
36 KiB
Text
.STITL DISPLAY AND TURTLE
|
||
VERN==VERN+%FNAM2
|
||
|
||
;A BRIEF DESCRIPTION OF WHAT IS LEFT TO BE DONE TO THIS PROGRAM.
|
||
|
||
|
||
;2) GARBAGE COLLECTION. COLLAPSING ADDS AND NOPS IN THE STATIC AREA.
|
||
;3) ERROR RECOVERY.
|
||
;4) DECIDING WHAT SNAP AND WIPE REALLY ARE GOING TO DO.
|
||
;AT THIS TIME, SNAP OUTPUTS THE ENTIRE SCREEN
|
||
;AND WIPE ERASES ONLY TOP LEVEL OCCURRENCES OF THE SNAP
|
||
;6) RUNNING THE DISPLAY ON INTERRUPT LEVEL.
|
||
|
||
|
||
|
||
|
||
|
||
|
||
;CHOOSE BETWEEN DISPLAY AND REAL TURTLE
|
||
; THE ARGUMENT IS WHERE TO JUMP IF DISPLAY.
|
||
.MACR WHICHTUR DADD
|
||
BITB #TURTF,DFLAGS
|
||
BNE .+6
|
||
JMP DADD
|
||
.ENDM
|
||
|
||
;MOVE THE REAL TURTLE
|
||
; THE ARG IS THE CHARACTER CODE TO CAUSE 1-STEP OF MOTION
|
||
.MACR MOVTUR CHAR
|
||
MOV #" 'CHAR,-(P)
|
||
JMP TURMOV
|
||
.ENDM
|
||
|
||
;SEND OUT SOME CONTROL COMMAND TO REAL TURTLE
|
||
; ARGUMENT IS THE CHARACTER FOR THE COMMAND
|
||
.MACR CONTUR CHAR
|
||
MOV #" 'CHAR,A
|
||
JMP TURCON
|
||
.ENDM
|
||
|
||
;CONVERT ADDRESS TO DISPLAY PUSHJ
|
||
; ARGUMENT IS AC
|
||
.MACR MAKEPJ F
|
||
SUB #DISREL,F
|
||
ASR F
|
||
BIS #DPUSHJ,F
|
||
.ENDM
|
||
|
||
;CONVERT DISPLAY CONTROLLER ADDRESSES TO REAL WORLD ADDRESSES
|
||
; ARG IS AC
|
||
.MACR MAKEAD F
|
||
ASL F
|
||
ADD #DISREL,F
|
||
.ENDM
|
||
|
||
;START UP DISPLAY--FOR SIMULATOR ONLY
|
||
.MACR DISGO
|
||
BISB DISBIT,NGCSR
|
||
.ENDM
|
||
;DISPLAY AND TURTLE COMMANDS THAT HAVE TO CHOOSE BETWEEN
|
||
;THE TWO GO THROUGH HERE
|
||
|
||
FORWAR: JSR PC,G1NARG
|
||
WHICHTUR DFD
|
||
MOVTUR C
|
||
BACK: JSR PC,G1NARG
|
||
WHICHTUR DBK
|
||
MOVTUR @
|
||
RIGHT: JSR PC,G1NARG
|
||
WHICHTUR DRT
|
||
MOVTUR B
|
||
LEFT: JSR PC,G1NARG
|
||
WHICHTUR DLT
|
||
MOVTUR A
|
||
PENUP: WHICHTUR DPU
|
||
CONTUR 8
|
||
PENDOW: WHICHTUR DPD
|
||
CONTUR 0
|
||
|
||
|
||
;REST OF REAL TURTLE COMMANDS
|
||
LAMPON: BITB #TURTF,DFLAGS
|
||
BNE LMPON1
|
||
ERROR+YNT ;YOU DON'T HAVE THE TURTLE
|
||
LMPON1: CONTUR "
|
||
LAMPOFF: BITB #TURTF,DFLAGS
|
||
BNE LMPOF1
|
||
ERROR+YNT ;YOU DON'T HAVE THE TURTLE
|
||
LMPOF1: CONTUR !
|
||
|
||
TOOT: BITB #TURTF,DFLAGS
|
||
BNE TOOT.0
|
||
ERROR+YNT ;YOU DON'T HAVE THE TURTLE
|
||
TOOT.0: JSR PC,G1NARG ;GET NUMERIC ARG
|
||
MOV #" (,A
|
||
BR TOOT.9
|
||
|
||
TOOT.1: MOV #1,E
|
||
JSR PC,TUROUT ;A IS OUTPUT CHARACTER, E IS COUNT
|
||
SWAB A ;PUT SPACE AS BOTTOM CHARACTER OF A.
|
||
MOV #5,E
|
||
JSR PC,TUROUT ;THERE NEED TO BE 5 SPACES BETWEEN TOOTS.
|
||
TOOT.9: DEC B ;NUMBER OF TOOTS
|
||
BGE TOOT.1
|
||
JMP NORT ;RETURN
|
||
|
||
;TURTLE MOVER
|
||
; OUTUT THE APPROPRIATE CHARACTERS TO CAUSE THE REAL TURTLE
|
||
; TO MOVE.
|
||
; CALL WITH NUMBER OF STEPS IN B
|
||
; CALL WITH CHARACTER FOR 1-STEP ON STACK
|
||
;
|
||
; IT IS NECESSARY TO ACCELERATE AND DECELERATE THE TURTLE
|
||
; MUCH OF THE ROUTINE BELOW IS TO DO THIS.
|
||
TURMOV: JSR PC,TURON ;TURN ON THE TURTLE
|
||
MOV (P),A ;THE CHARACTER FOR ONE STEP
|
||
MOV #10,F ;AN OFT USED CONSTANT
|
||
CMP B,4 ;COMPARE # OF STEPS TO 4
|
||
BLT TM.8 ;THERE IS NO CHANCE FOR MORE THAN 1-STEPS
|
||
CMP B,12.
|
||
BLT TM.3 ;NO CHANCE FOR MORE THAN 2-STEPS
|
||
|
||
MOV #MQ,C ;START TO DIVIDE.
|
||
MOV B,(C) ;THE DIVIDEND
|
||
CLR -(C) ;CLEAR THE TOP PART OF DIVIDEND.
|
||
MOV #4,-(C) ;THE DIVISOR.
|
||
TST (C)+
|
||
MOV (C)+,D ;THE REMAINDER.
|
||
MOV (C),C ;THE QUOTIENT.
|
||
CLR B
|
||
ASR D ;DIVIDE BY 2
|
||
ROL B ;PUT REMAINDER IN B
|
||
TST (D)+ ;ADD 2 TO D
|
||
TST (B)+ ;ADD 2 TO B
|
||
;NOW A=#OF 1-STEPS TO DECELERATE, B=# OF 2-STEPS TO DECELERATE
|
||
;AND D= # OF 4-STEPS ALTOGETHER
|
||
MOV #2,E
|
||
JSR PC,TUROUT ;OUTPUT TO TURTLE. A=THE CHAR. E=COUNT
|
||
ADD F,A ;TURN A INTO CHAR FOR 2-STEP
|
||
MOV #2,E
|
||
JSR PC,TUROUT
|
||
ADD F,A ;TURN A INTO CHARACTER FOR 4-STEP
|
||
MOV D,E ;NUMBER OF 4-STEPS
|
||
JSR PC,TUROUT
|
||
SUB F,A ;TURN A INTO CHARACTER FOR 2-STEP
|
||
BR TM.5
|
||
|
||
;THERE ARE LESS THAN 12. STEPS.
|
||
; SO THERE IS NO CHANCE FOR ANY 4-STEPS
|
||
TM.3: SUB #4,B ;YOU LOSE AT LEAST 4 STEPS IN ACCELERATION AND DECEL.
|
||
MOV B,D
|
||
CLR B
|
||
ASR D ;DIVIDE BY 2
|
||
ROL B ;PUT REMAINDER IN B
|
||
TST (B)+ ;ADD 2 TO B
|
||
MOV #2,E
|
||
JSR PC,TUROUT ;ACCELERATE
|
||
ADD F,A ;TURN A INTO CHAR FOR 2-STEP
|
||
;OUTPUT THE NUMBER OF 2-STEPS
|
||
TM.5: MOV D,E ;NUMBER OF STEPS
|
||
JSR PC,TUROUT
|
||
SUB F,A ;TURN A INTO CHAR FOR 1-STEP
|
||
;OUTPUT THE 1-STEPS
|
||
TM.8: MOV B,E ;NUMBER OF 1-STEPS
|
||
JSR PC,TUROUT
|
||
JSR PC,TUROFF ;TURN OFF THE TURTLE
|
||
JMP NORT
|
||
|
||
|
||
;TURTLE OUTPUT
|
||
; CALL WITH A=CHARACTER TO OUTPUT
|
||
; E=NUMBER OF TIMES TO OUTPUT IT
|
||
; NOTE: JSR TO TUROUT NOT TO TO.1
|
||
TO.1: JSR PC,.IOT ;NOT THE ENTRY POINT!!
|
||
;ENTER HERE
|
||
TUROUT: DEC E
|
||
BGE TO.1 ;THERE'S MORE TO OUTPUT
|
||
RTS PC
|
||
|
||
;.IOT
|
||
; OUTPUT CAHRACTER IN A TO TELETYPE
|
||
.IOT: BIT #200,TPS ;TEST READY
|
||
BEQ .IOT
|
||
MOV A,TPB ;OUTPUT THE CHARACTER
|
||
RTS PC
|
||
|
||
|
||
|
||
;TURN THE TURTLE ON
|
||
; OUTPUT CHARACTERS TO TURN OFF THE PRINTER AND TURN ON THE TURTLE
|
||
TURON: MOV #143,A
|
||
JSR PC,.IOT
|
||
MOV #151,A
|
||
JSR PC,.IOT
|
||
RTS PC
|
||
|
||
;TURN OFF THE TURTLE
|
||
; AND TURN THE PRINTER BACK ON
|
||
TUROFF: MOV #150,A
|
||
JSR PC,.IOT
|
||
MOV #142,A
|
||
JSR PC,.IOT
|
||
RTS PC
|
||
|
||
|
||
;OUTPUT A CONTROLLING CHARACTER TTO TURTLE
|
||
; CALL WITH B=CHARACTER
|
||
TURCON: JSR PC,TURON
|
||
MOV #1,E
|
||
MOV B,A
|
||
JSR PC,TUROUT ;A HAS CHAR, E HAS COUNT
|
||
JSR PC,TUROFF
|
||
JMP NORT ;RETURN.
|
||
;HERE IS WHERE THE DISPLAY PRIMITIVES START.
|
||
|
||
;STARTDISPLAY
|
||
; INITIALIZE EVERYTHING
|
||
; ALLOCATE DISPLAY BUFFERS
|
||
STARTDISPLAY:
|
||
MOVB DISBIT,A ;HAS A BIT SET IF USER ALREADY HAS A DISPLAY
|
||
BEQ STRTD1 ;USER DOESN'T HAVE A DISPLAY YET
|
||
JSR PC,KILLD2 ;KILL HIS PREVIOUS DISPLAY FIRST
|
||
|
||
STRTD1: MOV USER,MQ ;FIND USER'S DISPLAY CONSOLE NUMBER
|
||
MOV #L,DIVIDE ;LENGTH OF USER BLOCK
|
||
MOV MQ,A ;USER NUMBER
|
||
MOVB DCONS(A),A
|
||
BGE .+4
|
||
ERROR+NDU ;NOT A DISPLAY USER
|
||
|
||
MOV #DORBEG,C ;ZERO VARIOUS USER DISPLAY VARS
|
||
MOV #DOREND,B ;LAST WORD
|
||
SDLOOP: CLR (C)+ ;ZERO WORD
|
||
CMP C,B
|
||
BLE SDLOOP
|
||
|
||
MOVB SDISBT(A),B ;DISBIT
|
||
MOVB B,DISBIT
|
||
|
||
ASL A ;MAKE INTO WORD INDEX
|
||
MOV STLIST(A),C ;THIS USERS TURTLE DISPLAY AREA
|
||
MOV C,TUB ;TURTLE BOTTOM
|
||
MAKEPJ C
|
||
MOV C,PUSHJT ;PUSHJ TO TURTLE
|
||
|
||
MOV DISREL(A),D ;PUSHJ TO START OF DLIST
|
||
MAKEAD D
|
||
MOV #DRSTXY!DPOP,(D)+ ;FIRST WORD OF DLIST
|
||
MOV C,(D) ;PUSHJT IN 2ND WORD
|
||
|
||
;SET UP BUFFER VARIABLES
|
||
MOV D,STB ;STATIC AREA BOTTOM
|
||
MOV D,STT ;STATIC AREA TOP
|
||
TST -(D) ;POINT D BACK TO FIRST WORD
|
||
ADD #DLEN,D
|
||
CLR -(D) ;SET UP DUMMY FREE AREA
|
||
MOV D,DYT ;(DYNAMIC AREA TOP)
|
||
CLR -(D) ;AT THE TOP OF DYNAMIC AREA
|
||
MOV D,DYB ;DYNAMIC AREA BOTTOM
|
||
MOV D,DYR ;DYNAMIC AREA ROVING POINTER
|
||
|
||
MOV SDPDLP(A),DPDLP(A) ;SET DISPLAY PDL POINTER
|
||
|
||
JSR PC,ANGCRP ;GET DIREC, SINA, COSA
|
||
JSR PC,DR.TUR ;DRAW THE TURTLE
|
||
JSR PC,NEWSN2 ;SET UP FOR NEW SNAP
|
||
|
||
MOV #DISREL,NGREL ;SET THE RELOCATION, JUST IN CASE
|
||
BISB DISBIT,NGCSR ;AND START UP THIS GUYS DISPLAY
|
||
JMP NORT ;RETURN
|
||
|
||
;KILLDISPLAY
|
||
; USER WANTS TO GIVE UP HIS DISPLAY
|
||
KILLDISPLAY:
|
||
MOV #NORT,-(SP) ;ENTER HERE FROM EVAL
|
||
KILLD1: MOVB DISBIT,A ;HAS A BIT SET IF USER HAS DISPLAY
|
||
BEQ KILLDR ;USER DOESN'T HAVE DISPLAY
|
||
KILLD2: BIC A,NGCSR ;STOP HIS DISPLAY (ENTER HERE FROM STARTDISPLAY)
|
||
CLR SNLIST ;CLEAR SNAPS
|
||
CLRB DISBIT
|
||
JSR PC,.GCOLL
|
||
|
||
KILLDR: RTS PC
|
||
|
||
DBK: NEG B
|
||
|
||
;DISPLAY FORWARD AND BACK
|
||
DFD: MOV DIREC,-(SP) ;SAVE DIREC SINCE DRAW
|
||
; WANTS TO USE IT FOR ITS OWN DEVIOUS PURPOSES
|
||
MOV B,A
|
||
BPL DFD.0 ;FIGURE THIS ONE OUT FOR HOMEWORK
|
||
SUB #40,DIREC
|
||
BIC #177707,DIREC
|
||
DFD.0: JSR PC,MULSIN ;PUTS DX IN B,,C
|
||
MOV B,-(SP)
|
||
MOV C,-(SP)
|
||
ADD CURX,B ;INTEGER PARTS
|
||
ADD CURX+2,C ;FRACTION PARTS
|
||
ADC B ;IF FRACTIONS > 1, ADD 1 TO INT
|
||
DFD.1: MOV B,NEWX
|
||
MOV C,NEWX+2
|
||
JSR PC,FIX ;B HAS THE INTEGER PART OF B,,C
|
||
JSR PC,CHKBND ;ERROR IF B IS OFF SCREEN
|
||
|
||
;DO DELTA Y NOW
|
||
JSR PC,MULCOS ;DY IS IN B,,C
|
||
MOV B,-(SP)
|
||
MOV C,-(SP)
|
||
ADD CURY,B ;THE INTEGER PARTS.
|
||
ADD CURY+2,C ;THE FRACTION PARTS
|
||
ADC B ;IF FRACTIONS > 1, ADD 1 TO INT
|
||
DFD.2: MOV B,NEWY
|
||
MOV C,NEWY+2
|
||
JSR PC,FIX ;B HAS THE INTEGER PART OF B,,C
|
||
JSR PC,CHKBND ;ERROR IF B IS OFF SCREEN.
|
||
|
||
;FALLS THROUGH
|
||
|
||
;FALLS IN
|
||
|
||
|
||
;WHEN WE ACTUALLY DRAW THE LINE, DX AND DY ARE OF INTEREST.
|
||
;THE STUFF IN REGISTERS NOW IS CURX+DX, ETC.
|
||
MOV (SP)+,C ;FRACTION PART OF DY
|
||
MOV (SP)+,B ;THE INTEGER PART OF DY
|
||
JSR PC,FIX
|
||
MOV B,E ;THIS IS DY.
|
||
|
||
MOV (SP)+,C ;THE FRACTION PART OF DX
|
||
MOV (SP)+,B ;THE INTEGER PART OF DX.
|
||
JSR PC,FIX
|
||
MOV B,D ;THIS IS DX.
|
||
|
||
MOV #<MTO.P2-MTO.P1>,B ;A SORT OF FLAG FOR MOVETO
|
||
JSR PC,MOVETO ;DRAW A LINE OR PUT ADDXY INTO DLIST
|
||
MOV (SP)+,DIREC ;RESTORE DIREC
|
||
|
||
DISGO
|
||
JMP NORT
|
||
|
||
|
||
;SETX
|
||
; IF THE PEN IS UP, SIMPLY SET THE CURRENT X TO THE ARG.
|
||
; IF THE PEN IS DOWN, DRAW A LINE.
|
||
SETX: MOV #CURX,A
|
||
MOV #NEWX,F
|
||
JSR PC,SET.A ;RETURNS DX IN B AND SET CURX
|
||
MOV (A)+,(F)+ ;SET NEWY TO CURY
|
||
MOV (A),(F) ;SET FRACTION OF NEWY TO FRACTION OF CURY
|
||
MOV B,D ;DX
|
||
CLR E ;DY
|
||
BR SETMOV
|
||
|
||
|
||
;SETY
|
||
; SIMILAR TO SETX
|
||
SETY: MOV #CURX,A
|
||
MOV #NEWX,F
|
||
MOV (A)+,(F)+ ;SET NEWX TO CURX
|
||
MOV (A)+,(F)+ ;SET FRACTION OF NEWY TO FRACTION OF CURY
|
||
JSR PC,SET.A ;RETURNS DY IN B.
|
||
CLR D ;DX
|
||
MOV B,E ;DY
|
||
BR SETMOV
|
||
|
||
|
||
;SETXY
|
||
; CALLED WITH TWO ARGS. AND DOES THE OBVIOUS THING.
|
||
SETXY: JSR PC,G2NARG ;B=X, A=Y
|
||
MOV A,E
|
||
MOV B,D
|
||
JSR PC,SXY.S ;GETS DX AND DY
|
||
SETMOV: MOV DIREC,-(SP)
|
||
CLR B ;A FLAG THAT CAUSES DIREC TO BE CALCULATED IN MOVETO
|
||
JSR PC,MOVETO ;DRAW LINE OR DO ADDXY
|
||
MOV (SP)+,DIREC ;BUT RESTORE GLOBAL DIREC
|
||
|
||
DISGO
|
||
JMP NORT
|
||
|
||
|
||
;SETTURTLE
|
||
; ARGUMENT IS A LIST OF 3 NUMBERS
|
||
; SETXY TO FIRST TWO SNUMS, AND SETHEADING TO THE THIRD
|
||
SETTURTLE:
|
||
MOV @S,C ;ARGUMENT
|
||
JSR PC,LD3NUM ;GET 3 NUMBERS IN D,E,F
|
||
MOV F,-(SP) ;SAVE ANGLE FOR SETHEADING LATER
|
||
JSR PC,SPOPT ;AND POP S
|
||
JSR PC,SXY.S ;GETS DX AND DY
|
||
CLR B ;A FLAG THAT CAUSES DIREC TO BE CALCULATED IN MOVETO
|
||
JSR PC,MOVETO ;DRAW LINE OR DO ADDXY
|
||
MOV (SP)+,B ;PUT THE ANGLE INTO B
|
||
|
||
JMP DRT.HD ;AND JUMP TO SETHEADING PROGRAM
|
||
|
||
;THIS PAGE IS VARIOUS SUBROUTINES USED BY THE SET COMMANDS.
|
||
|
||
;SET.A
|
||
; CALL WITH A POINTING TO EITHER CURX OR CURY
|
||
; CALL WITH F POINTING TO EITHER NEWX OR NEWY
|
||
; TAKES AN ARGUMENT OFF OF THE S PDL. PUTS THE ARG IN NEW
|
||
; PUTS ARG - CURRENT IN B
|
||
SET.A: JSR PC,G1NARG ;NUMERIC ARGUMENT IN B.
|
||
|
||
;ENTER HERE IF ARGUMENT IS ALREADY IN B
|
||
SET.A1: JSR PC,CHKBND ;IS NUMBER IN BOUNDS?
|
||
MOV B,(F)+ ;PUT IN NEW
|
||
CLR (F)+ ;CLEAR THE FRACTION PART OF NEW.
|
||
JSR PC,SUBXY ;RETURNS INTEGER OF B-CURRENT IN B.
|
||
RTS PC
|
||
|
||
|
||
;SXY.S
|
||
; CALL WITH D = NEW X
|
||
; CALL WITH E = NEW Y
|
||
; GET DX AND DY
|
||
SXY.S: MOV #CURX,A
|
||
MOV #NEWX,F
|
||
MOV D,B ;X
|
||
JSR PC,SET.A1 ;RETURN DX IN B
|
||
MOV B,D
|
||
MOV E,B ;Y
|
||
JSR PC,SET.A1 ;RETURN DY IN B
|
||
MOV B,E
|
||
RTS PC
|
||
|
||
|
||
;MOVE TO
|
||
|
||
|
||
;ENTER HERE WITH D = DX, AND E = DY
|
||
;IF THE PEN IS DOWN, DRAW A LINE
|
||
;IF THE PEN IS UP, INSERT ADDX AND ADDY COMMANDS
|
||
|
||
MOVETO: TST D ;IS DX=0
|
||
BNE MTO.1 ;NO
|
||
TST E ;IS DY=0, TOO
|
||
BEQ MTO.R ;RETURN
|
||
|
||
MTO.1: BITB #PENUF,DFLAGS ;IS THE PEN UP?
|
||
BNE MTO.PU ;YES
|
||
;THE PEN IS DOWN. DRAW A LINE
|
||
MTO.PD: ADD B,PC ;B WAS SET SUCH THAT
|
||
; IF MOVETO CALLED FROM SETXY, ETC. , THERE IS NO SKIP
|
||
; BUT IF MOVETO CALLED FROM FORWARD THERE IS A SKIP
|
||
MTO.P1: JSR PC,XYDIR
|
||
MTO.P2: JSR PC,DR.LIN ;DRAW THE LINE
|
||
|
||
;AT THIS POINT, WE HAVE SUCCESSFULLY DONE THE COMMAND.
|
||
;THEREFORE SET CURX AND CURY TO THEIR NEW VALUES, AND EXIT
|
||
MTO.XY: MOV #CURX,A ;POINT A TO CURX
|
||
MOV #NEWX,F ;POINT F TO NEWX
|
||
MOV (F)+,(A)+ ;MOVE NEWX TO CURX
|
||
MOV (F)+,(A)+ ;MOVE FRACTION OF NEWX TO F. OF CURX
|
||
MOV (F)+,(A)+ ;MOVE NEWY TO CURY
|
||
MOV (F),(A) ;MOVE FRACTION OF NEWY TO F. OF CURY
|
||
MTO.R: RTS PC
|
||
|
||
|
||
|
||
;THE PEN IS UP
|
||
;PUT ADDX AND ADDY COMMANDS INTO DISPLAY LIST
|
||
MTO.PU: SPUSH #MTO.XY ;SO THAT THE RTS BELOW WILL WORK
|
||
MOV STT,A ;TOP OF STATIC DISPLAY AREA.
|
||
MTO.: ADD #4,A ;WHERE NEW TOP WILL BE
|
||
CMP A,DYB ;PROVIDING THERE'S ROOM.
|
||
BLT MTO.RM ;THERE'S ROOM
|
||
ERROR+TML ;TOO MANY LINES
|
||
|
||
MTO.RM: MOV A,STT
|
||
MOV PUSHJT,(A) ;DISPLAY JUMP TO TURTLE
|
||
BIC #176000,D ;IN CASE EITHER DX OR DY WERE NEGATIVE
|
||
BIC #176000,E ;CLEAR THE TOP 6 BITS
|
||
BIS #ADDY,E ;TURN E INTO ADDY COMMAND
|
||
MOV E,-(A) ;STORE IN DLIST
|
||
BIS #ADDX,D ;TURN D INTO ADDX COMMAND
|
||
MOV D,-(A) ;STORE IN DLIST
|
||
BICB #HOOKF,DFLAGS ;FOR LINE DRAWER
|
||
RTS PC
|
||
|
||
DLT: NEG B
|
||
|
||
;DISPLAY RIGHT AND LEFT
|
||
|
||
DRT: ADD CURA,B
|
||
DRT.HD: JSR PC,MOD360 ;SET B=B MOD 360
|
||
MOV B,CURA
|
||
JSR PC,ANGCRP ;DO ALL THE ANGLE CRAP.
|
||
; CALCULATE DIREC, SIN, AND COS.
|
||
BITB #HIDETF,DFLAGS ;IS THE TURTLE BEING HIDDEN ?
|
||
BNE DRTRET ;YES. SO RETURN
|
||
|
||
;THE TURTLE IS BEING SHOWN. SO DRAW THE TURTLE
|
||
JSR PC,DR.TUR
|
||
|
||
DRTRET: DISGO
|
||
JMP NORT
|
||
|
||
|
||
;SETHEAD
|
||
; LIKE RIGHT, EXCEPT SET CURA TO ARGUMENT
|
||
SETHEAD: JSR PC,G1NARG ;NUMERIC ARGUMENT IN B
|
||
BR DRT.HD ;JUMP INTO RIGHT
|
||
|
||
|
||
;HERE
|
||
; OUTPUT A SENTENCE OF CURX,CURY,CURA
|
||
HERE: MOV #CURX,D
|
||
JSR PC,PSHINT ;PUSH INTEGER OF CURX ONTO S-PDL
|
||
JSR PC,PSHINT ;PUSH INTEGER OF CURY
|
||
MOV (D),B ;CURRENT ANGLE
|
||
HERE.1: JSR PC,PSHNUM ;PUSH CURRENT ANGLE
|
||
HERE.2: SPUSH #3 ;PUSH 3 ONTO P-PDL
|
||
JMP SENTENCE
|
||
|
||
;HOME
|
||
; OUTPUT A SENTENCE OF 0 0 0
|
||
HOME: CLR B
|
||
JSR PC,PSHNUM
|
||
SPUSHS B ;AND PUSH IT AGAIN
|
||
SPUSHS B ;AND AGAIN
|
||
BR HERE.2
|
||
|
||
|
||
;XCOR
|
||
; OUTPUT THE X COORDINATE
|
||
XCOR: MOV #CURX,D
|
||
BR .+6
|
||
;YCOR
|
||
; OUTPUT THE Y COORDINATE
|
||
YCOR: MOV #CURY,D
|
||
JMP R1INT ;RETURN INTEGER
|
||
|
||
|
||
;HEADING
|
||
; RETURN THE CURRENT ANGLE
|
||
HEADING: MOV CURA,B
|
||
JMP R1NARG
|
||
|
||
|
||
; HIDETURTLE
|
||
HIDETURTLE:
|
||
BISB #HIDETF,DFLAGS ;SET THE HIDETURTLE FLAG
|
||
MOV #DPOP!DSTOP,@TUB ;DISPLAY POP AND STOP
|
||
DISGO
|
||
JMP NORT
|
||
|
||
|
||
; SHOWTURTLE
|
||
SHOWTURTLE:
|
||
BITB #HIDETF,DFLAGS ;IS TURTLE HIDDEN NOW ?
|
||
BEQ SHOWT9 ;NO, IT'S ALREADY BEING SHOWN
|
||
;HAVE TO DRAW THE TURTLE
|
||
BICB #HIDETF,DFLAGS ;CLEAR THE FLAG FIRST
|
||
JSR PC,DR.TUR
|
||
SHOWT9: DISGO
|
||
JMP NORT
|
||
|
||
|
||
; DISPLAY PENUP
|
||
DPU: BISB #PENUF,DFLAGS
|
||
JMP NORT
|
||
|
||
|
||
; DISPLAY PENDOWN
|
||
DPD: BICB #PENUF,DFLAGS
|
||
JMP NORT
|
||
|
||
|
||
;SNAP
|
||
; OUTPUTS STUFF ON THE SCREEN
|
||
; TRANSFER D. CODE STARTING AT STB+2 AND GOING ALL THE WAY TO STT
|
||
; INTO THE DYNAMIC AREA.
|
||
; RETURNS A LIST OF CURX, CURY AND POINTER TO SNAP
|
||
SNAP: MOV SNABOT,D ;BOTTOM OF STUFF TO BE SNAPPED
|
||
JSR PC,DYXFR ;TRANSFER THE DCODE.
|
||
; SET D = POINTER TO DCODE
|
||
TST D ;IF 0
|
||
BEQ SNAP.3 ;NO CODE MOVED
|
||
|
||
;NOW PUT THIS SNAP ON THE SNAP LIST
|
||
SNAP.1: MOV SNLIST,C ;POINTER TO SNAP LIST
|
||
BNE SNAP.2
|
||
MOV #SNUM,A ;FIRST SNAP
|
||
CLR B ;CREATE SNAP LIST. FIRST NODE IS A DUMMY
|
||
JSR PC,GRBAD
|
||
MOV C,SNLIST
|
||
SNAP.2: JSR PC,.LDP1 ;POINTER TO REST OF SNAP LIST
|
||
MOV D,B ;PUT PTR TO SNAP IN B
|
||
JSR PC,GRBAD1 ;:KILINK NODE IN A,B TO NODE IN (C)
|
||
|
||
;CHECK THAT THIS SNAP WON'T CAUSE DISPLAY PDL OVERFLOW
|
||
TST -(D) ;POINTER TO SNAP
|
||
CMP -(D),#<DPDLL/2> ;DEPTH COUNTER
|
||
BLE .+4
|
||
ERROR+STD ;SNAP TOO DEEP
|
||
;NOW SET UP THE 3 NODE SNAP STRUCTURE ITSELF
|
||
JSR PC,PSHNUM ;PUSH THE POINTER ONTO S-PDL
|
||
MOV #CURX,D
|
||
JSR PC,GETINT ;INTEGER OF CURX IN B
|
||
SUB OLDX,B ;TO GET DELTA X
|
||
JSR PC,PSHNUM ;PUSH ON S-PDL
|
||
JSR PC,GETINT ;INTEGER OF CURY
|
||
SUB OLDY,B ;TO GET DELTA-Y
|
||
JSR PC,PSHNUM
|
||
MOV #SNP,-(SP) ;TYPE OF LIST SENTENCE WILL CREATE
|
||
MOV #3,D ;NUMBER OF ARGS TO SENTENCE
|
||
JMP SNPSEN ;JUMP INTO SENTENCE
|
||
|
||
;SINCE NO DISPLAY CODE WAS MOVED, RETURN EMPTY SNAP
|
||
SNAP.3: MOV #SNP,A
|
||
JMP ORTA
|
||
|
||
|
||
|
||
;NEWSNAP
|
||
;SET UP FOR NEXT SNAP TO START HERE
|
||
NEWSNAP: MOV #NORT,-(SP) ;ENTER HERE FROM LOGO
|
||
NEWSN1: MOV #CURX,D ;ENTER HERE AS SUBROUTINE
|
||
JSR PC,GETINT ;GET INTEGER OF CURX IN B
|
||
MOV B,OLDX
|
||
JSR PC,GETINT ;GET INTEGER OF CURY IN B
|
||
MOV B,OLDY
|
||
NEWSN2: MOV STT,SNABOT ;RESET SNAP BOTTOM TO TOP OF DISPLAY
|
||
BICB #HOOKF,DFLAGS ;TELL LINE DRAWER THAT LAST WORD OF DLIST ISN'T INCREMENTS
|
||
RTS PC ;EITHER RETURN FROM SUBROUTINE , OR JMP NORT
|
||
|
||
;DISPLAY A SINGLE SNAP
|
||
|
||
DISPLAY:
|
||
JSR PC,G1SNAP ;LOAD D,E,F WITH PTR TO SNAP,CURX,CURY
|
||
BR D.RET ;RETURNS HERE IF ARG IS EMPTY
|
||
MOV E,B
|
||
ADD CURX,B
|
||
JSR PC,CHKBND ;IS NEW X COR IN BOUNDS?
|
||
MOV F,B
|
||
ADD CURY,B
|
||
JSR PC,CHKBND ;IS NEW Y COR IN BOUNDS?
|
||
|
||
;NOW SEE IF THERE'S ENOUGH ROOM IN THE DISPLAY AREA
|
||
MOV STT,A ;TOP OF THE STATIC AREA
|
||
ADD #4,A ;RAISE IT 4 BYTES
|
||
CMP A,DYB ;COMPARE TO BOTTOM OF DYNAMIC AREA
|
||
BLT DISRM
|
||
ERROR+TML ;TOO MANY LINES
|
||
|
||
;FINALLY, WE CAN PLACE THE PUSHJ TO THE SNAP INTO THE DISPLAY LIST
|
||
DISRM: INC -2(D) ;INCREMENT THE REF COUNTER OF THE SNAP
|
||
MOV A,STT ;SET STATIC TOP TO HERE IN DLIST
|
||
MOV PUSHJT,(A) ;PUT PUSHJ TO TURTLE AT TOP OF DLIST
|
||
MAKEPJ D
|
||
MOV D,-(A) ;PUT IN THE PUSHJ
|
||
CLR -(A) ;PRECEDE BY A NOP
|
||
|
||
;NOW, SET CURX AND CURY
|
||
ADD E,CURX ;E HAD DX OF THE SNAP
|
||
ADD F,CURY ;F HAS DY OF THE SNAP
|
||
|
||
BICB #HOOKF,DFLAGS ;TELL LINE DRAWER THAT LAST DWORD NOT INCREMENTS
|
||
D.RET: DISGO
|
||
JSR PC,SPOPT ;POP S
|
||
JMP NORT ;RETURN
|
||
|
||
;WIPE A SNAP
|
||
|
||
WIPE: JSR PC,G1SNAP ;LOAD D,E,F WITH PTR TO SNAP, X, Y
|
||
|
||
BR D.RET ;RETURNS HERE IF ARG IS EMPTY
|
||
BIC #176000,E ;CLEAR TOP 6 BITS
|
||
BIS #ADDX,E ;AND TURN INTO ADDX COMMAND
|
||
BIC #176000,F ;CLEAR TOP 6 BITS
|
||
BIS #ADDY,F ;TURN INTO ADDY
|
||
|
||
MOV D,B
|
||
TST -(D) ;POINT D TO SNAP'S REF COUNTER
|
||
MAKEPJ B ;MAKE B INTO DPUSHJ TO SNAP
|
||
MOV STT,A ;POINTER TO TOP OF DISPLAY LIST
|
||
MOV STB,C ;POINTER TO BOTTOM OF DLIST
|
||
|
||
WIPE.L: CMP A,C ;ARE WE AT THE BOTTOM YET?
|
||
BLT D.RET ;YES, SO WE ARE DONE
|
||
CMP B,-(A) ;IS THE NEXT WORD A PUSHJ?
|
||
BNE WIPE.L ;NO. LOOP BACK AND TRY ANOTHER
|
||
;YES! IT IS A PUSHJ
|
||
;PUT ADDX AND ADDY COMMANDS INTO DLIST
|
||
MOV F,(A)
|
||
MOV E,-(A)
|
||
|
||
DEC (D) ;DECREMENT REF COUNTER
|
||
BR WIPE.L ;AND THEN LOOP BACK TO SEE IF THERE'S ANOTHER
|
||
; PUSHJ TO THIS SNAP
|
||
|
||
|
||
;WIPE THE ENTIRE DISPLAY
|
||
|
||
WIPECLEAN:
|
||
MOV STB,A ;POINTER TO BOTTOM OF DISPLAY LIST
|
||
MOV STT,B ;POINTER TO TOP OF DLIST
|
||
|
||
MOV #100000,E ;SMALLEST DPUSHJ
|
||
MOV #140000,F ;SMALLEST COMMAND BIGGER THAN PUSHJ
|
||
|
||
WC.LP: CMP B,A ;ARE WE AT BOTTOM YET?
|
||
BLT WC.DUN ;YES, WE ARE DONE
|
||
CMP -(B),E ;IS NEXT WORD DOWN A PUSHJ?
|
||
BLO WC.LP ;NO, IT'S TOO SMALL
|
||
CMP (B),F
|
||
BHIS WC.LP ;NO, IT'S TOO BIG
|
||
;THIS WORD IS A PUSHJ
|
||
MOV (B),D ;MOVE THE PUSHJ COMMAND INTO D
|
||
MAKEAD D ;TURN INTO PDP-11 ADDRESS
|
||
DEC -(D) ;DECREMENT SNAP'S REF COUNTER
|
||
BR WC.LP ;LOOP BACK TO LOOK FOR MORE PUSHJ'S
|
||
|
||
;NOW PLACE ADDX AND ADDY COMMANDS IN THE DISPLAY LIST
|
||
;SO THAT THE TURTLE WILL STAY AT THE SAME PLACE IT WAS BEFORE THE WIPE
|
||
WC.DUN: MOV #CURX,D
|
||
JSR PC,GETINT ;GET INTEGER OF CURX IN B
|
||
SPUSH B ;SAVE DX
|
||
JSR PC,GETINT ;GET INTEGER OF CURY IN B
|
||
MOV B,E ;PUT DY IN E
|
||
SPOP D ;PUT DX IN B
|
||
JSR PC,MTO. ;PUTS THE ADD COMMANDS INTO THE DLIST, STARTING AT A
|
||
JSR PC,NEWSN1 ;SO THAT SNAPS WILL START HERE
|
||
|
||
DISGO
|
||
JMP NORT ;RETURN
|
||
.STITL DISPLAY UTILITY ROUTINES
|
||
|
||
|
||
;SUBXY
|
||
; CALL WITH AN INTEGER IN B
|
||
; CALL WITH A POINTER TO CURX OR CURY IN A
|
||
; RETURNS THE INTEGER OF B-CURRENT X OR Y IN B
|
||
; ALSO LEAVES A POINTING TO WORD AFTER THE FRACTION PART
|
||
SUBXY: SUB (A)+,B ;B-CUR
|
||
TST (A)+ ;TEST THE FRACTION PART
|
||
BGE SUBXY9 ;BRANCH IF THE HIGH BIT IS OFF
|
||
DEC B ;ROUND THE ANSWER DOWN
|
||
SUBXY9: RTS PC
|
||
|
||
|
||
;CHKBND
|
||
; CHECK BOUNDS. ERROR IF B IS OFF SCREEN
|
||
CHKBND: CMP B,#100.
|
||
BGT ERROOB
|
||
CMP B,#-100.
|
||
BLT ERROOB
|
||
RTS PC
|
||
;THE NUMBER IS OUT OF BOUNDS
|
||
ERROOB: MOV #PUSHJT,@STT ;A VERY SIMPLE ERROR RECOVERY
|
||
ERROR+OOB
|
||
|
||
|
||
; CALL WITH D POINTING TO CURX OR CURY.
|
||
; RETURN THE INTEGER OF CURX OR CURY IN B
|
||
GETINT: MOV (D)+,B
|
||
MOV (D)+,C
|
||
;FIX
|
||
; CALL WITH INTEGER IN B AND FRACTION IN C
|
||
; RETURNS INTEGER ROUNDED CORRECTLY IN B
|
||
FIX: ROL C ;PUT TOP BIT OF C INTO CARRY
|
||
ADC B ;SO THAT B IS ROUNDED UP IFF TOP BIT OF C SET
|
||
RTS PC
|
||
|
||
|
||
;MOD360
|
||
; OUTPUT B MOD 360 IN B.
|
||
; ALWAYS OUTPUTS A POSITIVE NUMBER
|
||
MOD360: MOV #360.,C
|
||
MOV #AC,A
|
||
MOV B,2(A) ;MOVE NUMBER TO LOW PART OF DIVIDEND
|
||
BGE M360A
|
||
M360A: MOV C,-(A) ;360 TO DIVISOR
|
||
MOV 2(A),B ;REMAINDER
|
||
BGE M360R
|
||
ADD C,B ;IF REMAINDER WAS NEGATIVE, ADD 360 TO IT
|
||
|
||
M360R: RTS PC
|
||
|
||
|
||
|
||
;MULCOS
|
||
; RETURN A*COSINE OF CURA IN B,,C
|
||
MULCOS: MOV COSA,B
|
||
BR MULCS2
|
||
;MULSIN
|
||
; RETURN A*SINE OF CURA IN B,,C
|
||
MULSIN: MOV SINA,B
|
||
MULCS2: MOV D,-(SP) ;GUESS WHY
|
||
CLR D ;USE D AS FLAG
|
||
TST B
|
||
BPL MULCS3
|
||
DEC D ;TO MARK THAT B WAS NEGATIVE
|
||
BIC #100000,B ;WHEN TRIG THINGS ARE SUPPOSED TO BE NEG.
|
||
; THEY ARE INSTEAD STORED POSITIVE, BUT WITH TOP BIT SET
|
||
MULCS3: MOV #MQ,F
|
||
MOV B,(F)+ ;MULTIPLICAND
|
||
MOV A,(F) ;MULTIPLIER
|
||
MOV -(F),C ;LOW ORDER PRODUCT = FRACTION
|
||
MOV -(F),B ;HIGH ORDER PRODUCT = INTEGER
|
||
ASL C ;MULTIPLY FRACTION AND
|
||
ROL B ;INTEGER BY 2.
|
||
TST D ;WAS THE TRIG THING NEGATIVE?
|
||
BGE MULCS9
|
||
NEG C ;SINCE THE TRIG FUNCTION WAS NEGATIVE, NEGATE FRACTION
|
||
ADC B ;INCREMENT INTEGER UNLESS, FRACTION WAS 0
|
||
NEG B ;AND NEGATE THE INTEGER.
|
||
MULCS9: MOV (SP)+,D ;RESTORE D
|
||
RTS PC
|
||
|
||
|
||
;ANGCRP
|
||
; CALCULATE ANGLE CRAP.
|
||
; CALCULATE DIREC, SINA, COSA
|
||
ANGCRP: MOV CURA,A ;THE CURRENT ANGLE
|
||
MOV #90.,E
|
||
MOV #MQ,F
|
||
MOV A,(F) ;THE DIVIDEND
|
||
CLR -(F)
|
||
MOV E,-(F) ;THE DIVISOR = 90.
|
||
TST (F)+
|
||
MOV (F)+,A ;THE REMAINDER
|
||
MOV (F),F ;THE QUOTIENT
|
||
MOV A,C ;SAVE THE REMAINDER
|
||
SUB A,E ;NOW E = 90.- REMAINDER
|
||
JSR PC,SINGET ;D_SIN (A)
|
||
MOV D,B
|
||
MOV E,A
|
||
JSR PC,SINGET
|
||
MOV #100000,E ;BIS THIS GUY WHEN TRIG THINGS ARE SUPPOSED TO BE NEGATIVE
|
||
ASL F ;F = 0,1,2,3
|
||
ADD F,PC ;JUMP THROUGH THIS DISPATCH TABLE
|
||
BR ACR.D
|
||
BR ACRII ;QUADRANT II
|
||
BR ACRIII ;QUADRANT III
|
||
;FOURTH QUADRANT
|
||
MOV B,A ;SIN (A)
|
||
MOV D,B ;SIN (90-A)
|
||
BIS E,B ;SINA=-SIN(90-A) IN 4TH QUADRANT
|
||
MOV A,D ;AND COSA=SIN(A) IN 4TH QUADRANT
|
||
BR ACR.D
|
||
|
||
;THE THIRD QUADRANT
|
||
ACRIII: BIS E,B ;SINA = -SIN (A) IN 3RD QUADRANT
|
||
BIS E,D ;COSA = - SIN (90-A) IN 3RD QUADRANT
|
||
BR ACR.D
|
||
|
||
;SECOND QUADRANT
|
||
ACRII: MOV B,A ;SIN (A)
|
||
MOV D,B ;SINA = SIN (90-A) IN 2ND QUADRANT
|
||
MOV A,D
|
||
BIS E,D ;COSA = -SIN (A) IN 2ND QUADRANT
|
||
|
||
;IN THE FIRST QUADRANT
|
||
;SINA = SIN (A) AND
|
||
;COSA = SIN (90-A)
|
||
ACR.D: MOV B,SINA
|
||
MOV D,COSA
|
||
|
||
|
||
;NOW GET DIREC. DIREC IS THE DIRECTION CODE FOR THE DISPLAY CODE
|
||
CMP #45.,C ;IS THE REMAINDER MORE THAN 45?
|
||
ADC F ;CARRY WAS SET IF C<45
|
||
ASL F
|
||
ASL F
|
||
ASL F
|
||
MOV F,DIREC
|
||
|
||
RTS PC
|
||
|
||
;GET SIN (A) INTO D.
|
||
;THE SINE TABLE HAS ONLY EVEN ANGLES. INTERPOLATE ODD ANGLES.
|
||
SINGET: BIT #1,A ;ODD OR EVEN
|
||
BEQ AEVEN
|
||
ADD #<SIN+1>,A ;POINT TO ANGLE AFTER IT
|
||
MOV (A),D ;SIN (A+1)
|
||
ADD -(A),D ;PLUS SIN (A-1)
|
||
ASR D ;DIVIDED BY 2
|
||
RTS PC
|
||
AEVEN: MOV SIN(A),D
|
||
RTS PC
|
||
|
||
|
||
;BEAUTIFUL SINE TABLE IN WHOOPIE FORMAT
|
||
|
||
|
||
SIN:
|
||
|
||
0 ;0 DEGREES
|
||
2167 ;2 DEGREES
|
||
4355 ;4 DEGREES
|
||
6541 ;6 DEGREES
|
||
10720 ;8 DEGREES
|
||
13072 ;10 DEGREES
|
||
15234 ;12 DEGREES
|
||
17367 ;14 DEGREES
|
||
21510 ;16 DEGREES
|
||
23615 ;18 DEGREES
|
||
25707 ;20 DEGREES
|
||
27763 ;22 DEGREES
|
||
32017 ;24 DEGREES
|
||
34034 ;26 DEGREES
|
||
36027 ;28 DEGREES
|
||
40000 ;30 DEGREES
|
||
41724 ;32 DEGREES
|
||
43623 ;34 DEGREES
|
||
45474 ;36 DEGREES
|
||
47315 ;38 DEGREES
|
||
51106 ;40 DEGREES
|
||
52646 ;42 DEGREES
|
||
54352 ;44 DEGREES
|
||
56023 ;46 DEGREES
|
||
57437 ;48 DEGREES
|
||
61015 ;50 DEGREES
|
||
62335 ;52 DEGREES
|
||
63615 ;54 DEGREES
|
||
65035 ;56 DEGREES
|
||
66214 ;58 DEGREES
|
||
67331 ;60 DEGREES
|
||
70404 ;62 DEGREES
|
||
71413 ;64 DEGREES
|
||
72357 ;66 DEGREES
|
||
73255 ;68 DEGREES
|
||
74107 ;70 DEGREES
|
||
74674 ;72 DEGREES
|
||
75412 ;74 DEGREES
|
||
76062 ;76 DEGREES
|
||
76463 ;78 DEGREES
|
||
77016 ;80 DEGREES
|
||
77301 ;82 DEGREES
|
||
77514 ;84 DEGREES
|
||
77660 ;86 DEGREES
|
||
77754 ;88 DEGREES
|
||
77777 ;90 DEGREES
|
||
|
||
;XYDIR
|
||
; CALL WITH D=DX, E=DY
|
||
; CALCULATE DIREC BASED ON DX AND DY
|
||
XYDIR: CLR A ;BUILD INDEX IN A
|
||
TST D ;IS DX POSITIVE
|
||
BGE XYDIR1
|
||
NEG D ;ABSOLUTE VALUE OF DX
|
||
TST (A)+ ;PUT 2 INTO A
|
||
XYDIR1: TST E ;IS DY POSITIVE
|
||
BGE XYDIR2
|
||
NEG E ;ABSOLUTE VALUE OF DY
|
||
INC A ;INCREMENT INDEX
|
||
XYDIR2: CMP D,E ;WILL GENERATE CARRY IF D<E
|
||
ROL A ;PUT CARRY INTO BOTTOM BIT OF INDEX. AND MULTIPLY REST BY 2
|
||
MOVB DREC(A),DIREC ;NOW MOVE THE RIGHT THING INTO DIREC
|
||
RTS PC
|
||
DREC: .BYTE 10
|
||
.BYTE 0
|
||
.BYTE 20
|
||
.BYTE 30
|
||
.BYTE 60
|
||
.BYTE 70
|
||
.BYTE 50
|
||
.BYTE 40
|
||
.EVEN
|
||
|
||
|
||
;DYXFR
|
||
; TRANSFER FROM STATIC AREA TO DYNAMIC AREA
|
||
; THE CODE BEING TRANSFERRED STARTS AT D AND GOES UP TO STT
|
||
; ON RETURN, D POINTS TO THE TRANSFERRED DCODE
|
||
; IF NO CODE WAS TRANSFERRED, THEN D = 0.
|
||
DYXFR: MOV STT,E
|
||
SUB D,E ;LENGTH OF DCODE TO BE MOVED
|
||
BLE DYRET ;NOTHING TO BE MOVED
|
||
;ALLOCATE STORAGE
|
||
;LENGTH OF BLOCK TO BE ALLOCATED IS IN E
|
||
DYAL: ADD #6,E ;INCREASE LENGTH TO ALLOW FOR REF CNTR, DEPTH CNTR, AND POPJ
|
||
MOV DYR,B ;INITIALIZE POINTER
|
||
MOV #1,C ;INITIALIZE FLAG
|
||
DYAL1: MOV 2(B),A ;POINTER TO NEXT FREE BLOCK
|
||
BNE DYAL2
|
||
DEC C ;NO NEXT FREE BLOCK--TEST AND SET FLAG
|
||
BNE DYAL7 ;NO MORE ROOM--GO TO EXPAND DY AREA
|
||
MOV DYB,B ;START AGAIN AT BOTTOM OF LIST
|
||
BR DYAL1
|
||
DYAL2: MOV (A),F ;FREE BLOCK FOUND--CHECK LENGTH
|
||
SUB E,F
|
||
BPL DYAL4
|
||
DYAL3: MOV A,B ;BLOCK TOO SHORT--MOVE TO NEXT BLOCK
|
||
BR DYAL1
|
||
DYAL4: BNE DYAL5 ;BLOCK LONG ENOUGH--IF FILLED EXACTLY
|
||
MOV 2(A),2(B) ;REMOVE BLOCK FROM LIST BY CHANGING POINTERS
|
||
DYAL5: CMP F,2 ;DONT LEAVE A BLOCK OF LENGTH 2 BYTES
|
||
BEQ DYAL3
|
||
MOV F,(A) ;NEW LENGTH OF FREE BLOCK
|
||
MOV 2(B),C ;RESET ROVING POINTER
|
||
BNE DYAL6 ;DONT SET IT TO O
|
||
MOV DYB,C
|
||
DYAL6: MOV C,DYR
|
||
ADD F,A ;START STORING AT THIS ADDRESS
|
||
BR DYAL9
|
||
DYAL7: MOV DYB,A ;ADD NEW BLOCK TO BOTTOM OF LIST
|
||
MOV 2(A),F ;POINTER TO 2ND FREE BLOCK
|
||
SUB E,A
|
||
CMP A,STT
|
||
BGT DYAL8 ;THERE IS ENOUGH ROOM IN THE DY AREA
|
||
ERROR+TML
|
||
DYAL8: MOV A,DYB ;NEW BOTTOM OF DY
|
||
MOV A,DYR ;FIX ROVING POINTER
|
||
MOV DYB,C ;SET UP NEW LIST BOTTOM
|
||
CLR (A)+
|
||
MOV F,(A)+
|
||
DYAL9: SUB #6,E ;RESTORE LENGTH
|
||
|
||
|
||
;NOW A CONTAINS ADDRESS OF FREE BLOCK
|
||
;E CONTAINS NUMBER OF BYTES TO BE TRANSFERRED
|
||
;NOW FINALLY YOU GET TO DO THE TRANSFER
|
||
;WHILE YOU DO IT, INCREMENT THE REF COUNTER OF ANY PUSHJ'S
|
||
DYXFR1: MOV #100000,C ;THE CODE FOR DISPLAY PUSHJ
|
||
MOV #140000,B ;NEXT HIGHER DISPLAY COMMAND
|
||
SPUSH A ;SAVE POINTER TO DEPTH COUNTER
|
||
CLR (A)+ ;DEPTH_0
|
||
CLR (A)+ ;SET REFERENCE COUNTER TO ZERO
|
||
ASR E ;E/2 = NUMBER OF WORDS TO BE TRANSFERRED
|
||
;PICK UP A WORD. SEE IF ITS A PUSHJ. AND TRANSFER IT
|
||
DYXFR2: DEC E ;NUMBER OF WORDS TO BE XFRED
|
||
BLT DYXFR3
|
||
MOV (D)+,F ;WORD OF DCODE IN F
|
||
MOV F,(A)+ ;PUT THIS WORD IN ITS NEW PLACE
|
||
CMP F,C
|
||
BLO DYXFR2 ;NOT A PUSHJ
|
||
CMP F,B
|
||
BHIS DYXFR2 ;NOT A PUSHJ
|
||
;IT IS A PUSHJ
|
||
MAKEAD F
|
||
INC -(F) ;INCREMENT THE REF COUNTER
|
||
CMP -(F),@(SP) ;DEPTH _ MAX (DEPTH OF SUB SNAPS)
|
||
BLE DYXFR2
|
||
MOV (F),@(SP) ;DEPTH OF SUB SNAP BIGGEST YET
|
||
BR DYXFR2 ;LOOP BACK
|
||
|
||
;ALL TRANSFERRING DONE. END THE BLOCK WITH A POPJ
|
||
DYXFR3: MOV #DPOPJ,(A)
|
||
SPOP D ;POINTER TO DEPTH COUNTER
|
||
INC (D)+
|
||
TST (D)+ ;POINTER TO FIRST D.WORD OF SNAP
|
||
RTS PC ;AND RETURN
|
||
|
||
;THERE WAS NOTHING TO BE MOVED
|
||
DYRET: CLR D ;TO SIGNAL THIS FACT
|
||
RTS PC
|
||
|
||
;DYFREE
|
||
; CALLED DURING GARBAGE COLLECTIONS
|
||
; CALL WITH D POINTING TO REF COUNTER (WORD BEFORE SNAP)
|
||
; FREES THE BLOCK!!
|
||
DYFREE: PUSH A ;SAVE REGISTERS
|
||
SPUSH B
|
||
SPUSH C
|
||
SPUSH D
|
||
SPUSH E
|
||
SPUSH F
|
||
|
||
MOV #100000,A
|
||
MOV #140000,B
|
||
MOV #DPOPJ,C
|
||
JSR PC,DYF1 ;DOES THE FREEING
|
||
JMP RETF ;RESTORE AC'S AND RETURN TO OUT OF DYFREE
|
||
|
||
;REAL WORK OF FREEING STARTS HERE.
|
||
DYF1: MOV D,-(SP) ;SAVE PTR TO 2ND WORD OF BLOCK
|
||
TST (D)+ ;POINT D TO FIRST WORD
|
||
|
||
;PICK UP EACH WORD OF BLOCK. IF IT IS A PUSHJ, FREE THAT BLOCK
|
||
;CONTINUE UNTIL A POPJ IS REACHED
|
||
DYF11: MOV (D)+,F ;NEXT WORD
|
||
CMP F,A
|
||
BLO DYF11 ;NOT PUSHJ OR POPJ
|
||
CMP F,B
|
||
BHIS DYF2 ;NOT PUSHJ, BUT MAY BE POPJ
|
||
|
||
; ITS A PUSHJ
|
||
MAKEAD F
|
||
DEC -(F) ;REF COUNTER
|
||
BNE DYF11 ;SNAP BEING DISPLAYED, OR EXISTS IN LOGO
|
||
SPUSH D ;SAVE WHERE YOU ARE IN THIS BLOCK
|
||
MOV F,D ;POINTER TO NEW BLOCK TO BE FREED
|
||
JSR PC,DYF1 ;RECURSE (GOD DAMN IT AGAIN)
|
||
SPOP D ;RESTORE PLACE IN THIS BLOCK
|
||
BR DYF11 ;LOOK AT NEXT WORD
|
||
|
||
;IS THE WORD A POPJ
|
||
DYF2: CMP F,C ;C CONTAINS A POPJ
|
||
BNE DYF11 ;NOT A POPJ. LOOK AT NEXT WORD
|
||
SPOP C ;POINTER TO 2ND WORD OF BLOCK
|
||
TST -(C) ;NOW IT POINTS TO BOTTOM WORD
|
||
SUB C,D ;LENGTH OF BLOCK
|
||
MOV D,F
|
||
|
||
|
||
;NOW LINK BLOCK BACK TO FREE CORE
|
||
;C/ADDRESS OF BLOCK TO BE LIBERATED
|
||
;F CONTAINS LENGTH OF BLOCK
|
||
|
||
DYLIB: MOV DYB,B ;INITIALIZE POINTER TO BOTTOM OF LIST
|
||
DYLIB1: MOV 2(B),A ;NEXT FREE BLOCK
|
||
BEQ DYLIB3 ;AT END OF LIST
|
||
CMP A,C
|
||
BGT DYLIB2 ;PASSED BLOCK TO BE FREED
|
||
MOV A,B ;TRY NEXT FREE BLOCK
|
||
BR DYLIB1
|
||
DYLIB2: MOV F,D ;CHECK UPPER BOUND
|
||
ADD C,D ;DO WE COLLAPSE NEW BLOCK WITH NEXT ONE?
|
||
CMP D,A
|
||
BNE DYLIB3 ;NO
|
||
ADD (A),F ;YES--NEW LENGTH
|
||
MOV 2(A),2(C) ;NEW POINTER
|
||
CMP A,DYR ;DID WE JUST SCREW ROVING POINTER?
|
||
BNE DYLIB4
|
||
MOV DYB,DYR ;YES--RESET IT
|
||
DYLIB3: MOV A,2(C) ;POINTER TO NEXT FREE BLOCK--NO COLLAPSE ON TOP
|
||
DYLIB4: MOV (B),D ;CHECK LOWER BOUND
|
||
ADD B,D
|
||
CMP D,C ;DO WE COLLAPSE WITH BLOCK ON BOTTOM?
|
||
BNE DYLIB5 ;NO
|
||
ADD F,(B) ;NEW LENGTH OF PREVIOUS BLOCK
|
||
MOV 2(C),2(B) ;NEW POINTER
|
||
BR DYLIB6
|
||
DYLIB5: MOV C,2(B) ;POINTER IN PREVIOUS BLOCK--NO COLLAPSE
|
||
MOV F,(C) ;LENGTH OF BLOCK JUST FREED
|
||
DYLIB6: MOV C,A ;DID WE JUST FREE BOTTOM BLOCK IN DY?
|
||
SUB #4,A
|
||
CMP A,DYB ;NOTE THAT IF CURRENT BLOCK = DYB+4
|
||
;THEN PREVIOUS BLOCK (ADDR IN B) MUST BE DYB
|
||
BNE DYLIB7 ;NO
|
||
ADD (C),B ;YES--COLLAPSE DY AREA
|
||
CLR (B)
|
||
MOV 2(C),2(B) ;NEW BOTTOM BLOCK
|
||
MOV B,DYB
|
||
MOV B,DYR ;FIX POINTERS
|
||
DYLIB7: RTS PC
|
||
|
||
|
||
;DSGCF
|
||
; CALLED BY LOGO GARBAGE COLLECTOR WHEN ITS ALL DONE
|
||
; SEE IF EACH SNAP ON THE SNAP LIST WAS MARKED.
|
||
; AND DYFREE THE SNAP IF NOT MARKED AND IT'S REFERENCE COUNTER IS 0
|
||
|
||
DSGCF: CLR F
|
||
BR DSGC1
|
||
|
||
DSGC4: TST F ;0 IF FIRST TIME THROUGH
|
||
BEQ .+4
|
||
DSGC9: RTS PC
|
||
MOV #<DSGC6-DSGCF1>,F ;NOW CLEAR MARKED BITS
|
||
DSGC1: MOV SNLIST,C ;POINTER TO SNAP LIST
|
||
BEQ DSGC9 ;OBVIOUSLY DOESN'T HAVE SNAPS
|
||
|
||
JSR PC,.LOADC ;FIRST NODE OF LIST IS DUMMY
|
||
DSGC2: MOV C,E ;SAVE POINTER TO NODE
|
||
DSGC3: BIT #7777,A ;LEAVE ADDRESS ONLY
|
||
BEQ DSGC4 ;END OF LIST
|
||
MOV A,C ;POINTER TO NEXT NODE
|
||
JSR PC,.LOADC
|
||
ADD F,PC ;CHOOSE BETWEEN FREEING AND CLEARING
|
||
|
||
;TRY TO FREE THE SNAP
|
||
DSGCF1: TST -(B) ;WAS SNAP MARKED? (B POINTS TO REF COUNT)
|
||
BNE DSGC2 ;EITHER DISPLAYED OR MARKED
|
||
|
||
;NOT MARKED, AND NOT DISPLAYED ANYWHERE!!
|
||
;FREE THIS SNAP
|
||
JSR PC,.FREE ;CLEAN UP SNLIST
|
||
MOV E,C ;POINTER TO PREVIOUS NODE OF SNLIST
|
||
JSR PC,.STP1 ;STORE A AS TOP WORD OF PREVIOUS NODE
|
||
MOV B,D ;POINTER TO SNAP DCODE
|
||
JSR PC,DYFREE
|
||
BR DSGC3
|
||
|
||
DSGC6: BIC #100000,-(B) ;CLEAR MARKED BIT
|
||
BR DSGC3
|
||
|
||
|
||
;MKDC
|
||
; CALLED BY LOGO GARBAGE COLLECTOR DURING MARKING PHASE
|
||
; CALLED WITH B POINTING TO SNAP NODE
|
||
MKDC: TST SNLIST ;CALLED TO KILL THE DISPLAY?
|
||
BEQ MKDC.K ;YES
|
||
BIT #7777,B
|
||
BEQ DSGC9 ;EMPTY SNAP
|
||
;MARK THE SNAP
|
||
PUSH A
|
||
SPUSH B
|
||
JSR PC,.LOAD
|
||
MOV #SNUM,A
|
||
JSR PC,CONVERT ;GET SNAP ADDRESS INTO B
|
||
BR MKDC.R ;IF DOESN'T SKIP, THEN BAD NODE!!!!!!!!!!!!!!!
|
||
BIS #100000,-(B) ;MARK THE REF COUNTER
|
||
MKDC.R: JMP RETB ;RESTORE A AND B
|
||
|
||
;CALLED BY KILLDISPLAY
|
||
;TURN SNAP INTO EMPTY SNAP
|
||
MKDC.K: MOV #SNP,B ;EMPTY SNAP
|
||
JSR PC,.STP2
|
||
RTS PC
|
||
|
||
|
||
|
||
;HERE START THE LINE AND TURTLE DRAWING PROGRAMS
|
||
|
||
;DR.LIN
|
||
; DRAW A LINE. D=DX, E=DY, OR VICE VERSA.
|
||
; THE DIRECTION CODE FOR THE LINE IS IN DIREC
|
||
DR.LIN: BICB #TEMF,DFLAGS ;GOING TO USE TEMF SO CLEAR IT
|
||
MOV BYCNT,C
|
||
MOVB OLDIR,-(SP) ;IN CASE OF ERROR BOMB OUT
|
||
|
||
CMPB DIREC,(SP) ;OLDIR IS THE DIREC LAST TIME DR.LIN CALLED
|
||
BEQ DR.LAN ;THEY ARE THE SAME
|
||
MOV #1,C ;NOT SAME.
|
||
MOVB DIREC,(SP) ;SET OLDIR
|
||
|
||
DR.LAN: BITB #HOOKF,DFLAGS ;CAN NEW D.LIST BE HOOKED TO PREVIOUS ONE?
|
||
BNE DR.LBN ;YES.
|
||
MOV #1,C ;NO.
|
||
DR.LBN: JSR PC,DR.SC ;SET A=CON, B=AC.
|
||
JSR PC,DR.NEP ;CALCULATE NEW END POINT OF DLIST
|
||
MOV C,-(SP) ;SAVE THE NEW BYCNT
|
||
ADD STT,D ;D = HOW MANY MORE WORDS IN DLIST
|
||
CMP D,DYB ;COMPARE TO DY BOTTOM
|
||
BLT DR.L1 ;THERE'S ROOM
|
||
ERROR+TML ;TOO MANY LINES
|
||
|
||
;OKAY, THERE WAS ROOM FOR THE LINE
|
||
DR.L1: MOV D,STT ;SET STT TO NEW STATIC TOP
|
||
MOV PUSHJT,(D) ;PUT PUSHJ TURTLE AT TOP
|
||
JSR PC,DR.ASC ;ASSEMBLE THE DISPLAY CODE
|
||
MOV (SP)+,BYCNT ;THE NEW BYCNT
|
||
MOVB (SP)+,OLDIR ;NEW OLDIR
|
||
BISB #HOOKF,DFLAGS ;FOR NEXT TIME
|
||
RTS PC ;RETURN
|
||
|
||
|
||
;DRAW THE TURTLE
|
||
DR.TUR: MOV DIREC,-(SP) ;USED LOCALLY BY DR.TUR
|
||
MOV #TURSIZ,A ;TURTLE SIZE
|
||
JSR PC,MULSIN ;B,,C = SIZE * SINA
|
||
JSR PC,FIX
|
||
MOV B,E ;NOW E HAS INTEGER OF SIZE * SINA
|
||
JSR PC,MULCOS ;B,,C = SIZE * COSA
|
||
JSR PC,FIX
|
||
MOV B,D ;NOW D HAS INTEGER OF SIZE * COSA
|
||
|
||
MOV B,-(SP)
|
||
SUB E,(SP) ;NOW SIZE * (COSA - SINA) IS ON STACK
|
||
ADD E,B
|
||
MOV B,-(SP) ;SIZE * (COSA + SINA) IS NOW ON STACK
|
||
|
||
MOV TUB,TUT ;TUT WILL BE POINTER TO TOP OF TURTLE DLIST SO FAR
|
||
|
||
;SIDE 1
|
||
ADD #20,DIREC ;SIDE 1 IS 2*45 DEGREES LEFT OF CURRENT DIRECTION
|
||
JSR PC,DR.TSD ;DRAW THE SIDE
|
||
|
||
;SIDE 2
|
||
SUB #30,DIREC ;SIDE 2 IS 3*45 DEGREES RIGHT OF SIDE 1
|
||
MOV (SP)+,D ;DX IS SIZE * (COSA + SINA)
|
||
MOV (SP)+,E ;DY IS SIZE * (COSA - SINA)
|
||
JSR PC,DR.TSD ;DRAW THE SIDE
|
||
|
||
;SIDE 3 HAS THE SAME INCREMENTS AS SIDE 2.
|
||
;JUST THE DIRECTION IS DIFFERENT
|
||
MOV DIREC,B
|
||
SUB #20,B ;SIDE 3 IS 2*45 DEGREES RIGHT
|
||
BIC #177707,B ;LEAVE ONLY THE 3 BITS
|
||
SWAB B ;PUT THE DIREC BITS IN TOP BYTE
|
||
MOV TUT,C ;POINTS TO WORD ABOVE LAST ONE OF TURTLE DLIST
|
||
MOV C,A
|
||
SUB D,C ;SINCE D POINTS TO BOTTOM WORD OF SIDE 2
|
||
;C-D IS NUMBER OF BYTES IN SIDE 2'S DLIST
|
||
ASR C ;C/2 = NUMBER OF WORDS
|
||
DR.TS3: MOV (D)+,E ;NEXT WORD OF SIDE 2'S DLIST
|
||
BIC #34000,E ;CLEAR THE DIRECTION BITS THEREIN
|
||
BIS B,E ;AND SET THEM FROM THE NEW DIREC IN B
|
||
MOV E,(A)+ ;STORE IN DLIST
|
||
DEC C ;NUMBER OF WORDS IN SIDE 2'S DLIST
|
||
BGT DR.TS3 ;THERE ARE MORE WORDS
|
||
|
||
;SIDE 4 IS IDENTICAL TO SIDE 1
|
||
;FURTHERMORE, SIDE 1 IS MADE UP OF ONLY ONE WORD
|
||
MOV @TUB,(A)+ ;PUT THE FIRST WORD OF TURTLE INTO TOP WORD
|
||
MOV #DPOP!DSTOP,(A) ;DISPLAY POP AND STOP.
|
||
|
||
;RESTORE DIREC, THEN RETURN
|
||
MOV (SP)+,DIREC
|
||
RTS PC
|
||
|
||
|
||
;DRAW TURTLE SIDE
|
||
; DRAW ONE SIDE OF THE TURTLE
|
||
; DIREC CONTAINS THE DIRECTION
|
||
; TUT POINTS TO TOP OF TURTLE DISPLAY LIST SO FAR
|
||
; C,D = + OR - DX OR DY
|
||
DR.TSD: BIC #177707,DIREC ;BITS MAY HAVE BEEN SET BY THE SUBTRACTING
|
||
JSR PC,DR.SC
|
||
MOV #1,C ;BYCNT
|
||
JSR PC,DR.NE1
|
||
ADD TUT,D ;D = NEW TOP OF TURTLE
|
||
MOV D,TUT
|
||
JMP DR.ASC ;ACTUALLY CREAT THE DISPLAY LIST
|
||
|
||
|
||
;SET UP CON AND AC
|
||
; CALL WITH D,E = + OR - DX OR DY
|
||
; RETURNS A=CON, B = AC
|
||
DR.SC: TST D
|
||
BGE DR.TE ;TEST E
|
||
NEG D ;MAKE D POSITIVE
|
||
;MAKE SURE E IS POSITIVE
|
||
DR.TE: TST E
|
||
BGE DR.BIG ;NEXT WE'LL SEE WHICH IS BIGGER
|
||
NEG E ;MAKE D POSITIVE
|
||
|
||
;WHICH IS BIGGER
|
||
DR.BIG: MOV #MQ,A
|
||
CLR (A) ;START TO SET UP DIVISION
|
||
CMP D,E
|
||
BGT DR.DBG ;D IS BIGGER
|
||
BEQ DR.EQ ;THEY ARE THE SAME SIZE
|
||
|
||
;OTHERWISE, E IS BIGGER
|
||
MOV D,-(A) ;HIGH ORDER DIVIDEND
|
||
MOV E,-(A) ;AND E IS THE DIVISOR
|
||
MOV E,F ;WHICHEVER IS BIGGER IS THE NUMBER OF INCS
|
||
BR DR.SC4
|
||
|
||
;THEY ARE THE SAME SIZE
|
||
DR.EQ: MOV #-1,A ;SET CON = .777...
|
||
MOV E,F ;NUMBER OF INCS
|
||
BR DR.SC5
|
||
|
||
;D IS BIGGER
|
||
DR.DBG: MOV E,-(A) ;HIGH ORDER DIVIDEND
|
||
MOV D,-(A) ;AND D IS THE DIVISOR
|
||
MOV D,F ;NUMBER OF INCS
|
||
|
||
;NOW PICK UP THE QUOTIENT
|
||
DR.SC4: ADD #4,A ;POINT A TO QUOTIENT
|
||
MOV (A),A ;SET CON TO THE QUOTIENT
|
||
|
||
;NOW SET AC = .1000 = 1/2 IN THIS REPRESENTATION
|
||
DR.SC5: MOV #100000,B
|
||
RTS PC
|
||
|
||
|
||
;CALCULATE THE NEW END POINT OF THE DLIST
|
||
; CALL WITH F = THE NUMBER OF INCS
|
||
; RETURNS D = NUMBER OF MORE WORDS IN DLIST
|
||
; C = PLACE WHERE FIRST INCREMENT CAN GO IN LAST DWORD
|
||
DR.NEP: CMP C,#1
|
||
BNE DR.NE2
|
||
|
||
DR.NE1: BISB #TEMF,DFLAGS ;TEMF IS SET WHEN YOU CAN'T HOOK
|
||
DR.NE2: MOV A,-(SP) ;SAVE A REGISTER
|
||
MOV #MQ,D
|
||
MOV F,(D) ;DIVIDEND=NUMBER OF INCS
|
||
CLR -(D)
|
||
MOV #8.,-(D) ;DIVISOR.
|
||
TST (D)+
|
||
MOV (D)+,A ;PUT REMAINDER IN A
|
||
MOV (D),D ;PUT QUOTIENT INTO D
|
||
DR.N1: DEC A ;THE REMAINDER
|
||
BLT DR.N25 ;FINISHED SHIFTING, BUT BYCNT DIDNT FALL OFF
|
||
ASR C ;SHIFT BYCNT RIGHT
|
||
BCC DR.N1
|
||
|
||
;SINCE CARRY SET, BYCNT FELL OFF RIGHT END OF REGISTER
|
||
RORB C ;STICK A ONE IN THE HIGH BIT OF C
|
||
INC D ;INCREMENT THE QUOTIENT
|
||
MOV #100,E ;INCREMENT MODE MARKER
|
||
DR.N2: INC E ;COUNTER IN LAST DWORD
|
||
DEC A ;THE REMAINDER
|
||
BLT DR.N3
|
||
ASR C ;SHIFT BYCNT RIGHT
|
||
BR DR.N2
|
||
|
||
;C IS SET CORRECTLY, BUT HAVE TO GET COUNT IN E
|
||
DR.N25: MOV C,-(SP) ;SAVE FOR A WHILE
|
||
MOV #111,E ;INCREMENT-MODE MARKER + 9
|
||
DR.N26: DEC E ;DEC THE COUNT
|
||
ASR C ;SHIFT BYCNT
|
||
BCC DR.N26 ;DIDN'T FALL OFF. DEC COUNT AGAIN
|
||
MOV (SP)+,C ;E IS SET NOW. RESTORE C.
|
||
|
||
DR.N3: BIC #10,E ;STRAY BIT THAT MIGHT BE ON
|
||
BIS DIREC,E ;OR IN THE DIRECTION
|
||
ASL D ;NUMBER OF WORDS IS 2*QUOTIENT
|
||
MOV (SP)+,A ;RESTORE A
|
||
RTS PC
|
||
|
||
|
||
;ACTUALLY ASSEMBLE THE NEW DISPLAY LIST
|
||
; CALL WITH A=CON, B=AC, C=BYCNT, D=POINTER TO FIRST WORD OF DLIST
|
||
; E=TOP HALF OF THE INC MODE INSTRUCTION, F=NUMBER OF INCS
|
||
DR.ASC: SWAB E ;STUFF IN E WAS IN WRONG HALF
|
||
DR.AS0: ADD A,B ;CON+AC
|
||
BCC DR.AS1
|
||
ADD C,E ;CARRY, SO PUT A 1 INTO DCODE
|
||
DR.AS1: DEC F ;NUMBER OF INCS
|
||
BLE DR.ALW ;THIS WAS THE LAST WORD
|
||
ASLB C ;SHIFT BYCNT
|
||
BCC DR.AS0 ;CONTINUE WITH THIS WORD
|
||
|
||
;THIS WORD DONE
|
||
MOV E,-(D) ;STORE IN DLIST
|
||
BIC #3777,E ;0 THE COUNT AND BOTTOM BYTE
|
||
INC C ;SET C TO 1
|
||
BR DR.AS0
|
||
|
||
;ALL THAT'S LEFT TO DO IS STORE THE BOTTOM WORD OF NEW DLIST
|
||
DR.ALW: BITB #TEMF,DFLAGS ;IS BOTTOM WORD OF NEW SAME AS TOP WORD OF OLD?
|
||
BNE DR.AS9 ;NO.
|
||
BISB -2(D),E ;SET THE BITS IN BOTTOM WORD THAT WERE ALREADY SET IN DLIST
|
||
DR.AS9: MOV E,-(D) ;STORE BOTTOM WORD
|
||
|
||
RTS PC
|
||
|
||
.STITL DISPLAY BUFFERS
|
||
|
||
.IF2
|
||
PAD ^\START OF BUFFERS\,\.
|
||
.ENDC
|
||
|
||
DISREL=. ;DISPLAY RELOCATION
|
||
|
||
;FIRST WORD OF EACH DISPLAY IS HERE
|
||
REPT1 3,<DLIST+<.RPCNT*DLEN>-DISREL>/2!DPUSHJ
|
||
REPT1 5,DSTOP
|
||
|
||
;THE DISPLAY PDL POINTERS FOLLOW
|
||
DPDLP=.
|
||
REPT1 10,-1
|
||
|
||
;THE DISPLAY PDL'S GO HERE
|
||
DPDL=.
|
||
.=.+SDPDLL ;SAVE A BLOCK OF CORE FOR PDL'S
|
||
|
||
;THE BODY OF THE DISPLAY LISTS GO HERE
|
||
DLIST=.
|
||
.=.+SDLEN ;SAVE A BLOCK OF CORE FOR DISPLAY LISTS
|
||
|
||
;THE TURTLE DISPLAY LISTS GO HERE
|
||
TLIST=.
|
||
.=.+STLEN ;SAVE A BLOCK OF CORE FOR THE TURTLES
|
||
|
||
;AND THAT IS THE END OF THE DISPLAY LIST BUFFERS
|
||
DLTOP=.-1
|
||
|