.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 #,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),# ;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 #,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,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,-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