simh-testsetgenerator/PDP11/dazzledart/dazzle.68

2329 lines
No EOL
39 KiB
Text
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

.TITLE DAZZLE DART
.STITL MACROS
;CONVERT ADDRESS TO DISPLAY PUSHJ
; ARGUMENT IS AC
.MACR MAKEPJ F
.XLIST
SUB #DISREL,F
ASR F
BIS #DPUSHJ,F
.LIST
.ENDM
;CONVERT DISPLAY CONTROLLER ADDRESSES TO REAL WORLD ADDRESSES
; ARG IS AC
.MACR MAKEAD F
.XLIST
ASL F
ADD #DISREL,F
.LIST
.ENDM
.MACR SPUSH AA
.XLIST
MOV AA,-(P)
.LIST
.ENDM
.MACR SPOP AA
.XLIST
MOV (P)+,AA
.LIST
.ENDM
.MACR FPUSH FF
.XLIST
STF FF,-(P)
.LIST
.ENDM
.MACR FPOP FF
.XLIST
LDD (P)+,FF
.LIST
.ENDM
.MACR REPT1 A,B
.XLIST
.REPT A
B
.ENDR
.LIST
.ENDM
.MACR REPT2 A,B,C
.XLIST
.REPT A
B
C
.ENDR
.LIST
.ENDM
.STITL SYSTEM PARAMETERS
CIRC==1
A=%0
B=%1
C=%2
D=%3
E=%4
F=%5
U=%5
M=%5
P=%6
SP=%6
PC=%7
FA==%0
FB==%1
FC==%2
FD==%3
FE==%4
FF==%5
NDISP==0
MNUSRS==2
;PROGRAMMABLE CLOCK
;BREAK LEVEL 6
PCBRV=104 ;PROGRAMMABLE CLOCK BREAK VECTOR
PCS=172540 ;PROGRAMMABLE CLOCK STATUS
PCSTBF=172542 ;PROGRAMMABLE CLOCK SET BUFFER
PCCNT=172544 ;PROGRAMMABLE CLOCK COUNTER
;TK DISPLAY
NGCSR=164040 ;DISPLAY CONTROL AND STATUS REGISTER
NGREL=164042 ;DISPLAY RELOCATION REGISTER
;CONSOLE SWITCHES
SWB=177570
;SWITCH BOX STUFF
DEVADD=160104 ;PLACE NUMBER OF BOX HERE TO SELECT
DEVICE=160106 ;ACTUAL IN/OUT BUFFER
PENUF==1
ADDX=150000
ADDY=144000
ADDXY=ADDX!ADDY
DPUSHJ=100000
DPOP=140200
DPOPJ=140100
DSTOP=140400
DRSTXY=143000 ;RESET X AND Y TO 0
DINC=40000
TLEN==100 ;LENGTH OF TURTLE DISPLAY LIST (IN BYTES)
TURSIZE==6 ;(DO NOT MAKE BIGGER THAN 8)
TKRUN==4000
TKGO==10000
TKSTOP==20000
DPDLL==20.
.=PCBRV
CLKBRK ;PROGRAMMABLE CLOCK
300 ;IS ON BR6
.=400
.=.+200
SPDLP: . ;PDL
.=1000
;DISPLAY DIRECTION CODES
DREC: .BYTE 10
.BYTE 0
.BYTE 20
.BYTE 30
.BYTE 60
.BYTE 70
.BYTE 50
.BYTE 40
.EVEN
TIME: 0
TIMER: 0 ;COUNTS IN SECONDS
;DISPLAY SYSTEM VARIABLES
DFLAGS: .WORD 0
;VARIABLES AND CONSTANTS FOR DISPLAY SYSTEM
;THESE MUST BE IN THIS ORDER
DORBEG==.
CURX: .WORD 0,0 ;CURX = CURRENT X POSITION
; THE FIREST WORD IS THE INTEGER PART
; THE SECOND WORD IS THE FRACTION PART
CURY: .WORD 0,0 ;CURY = CURRENT Y POSITION
CURA: 0 ;CURA = THE CURRENT ANGLE
DOREND==. ;MARKS END OF THESE VARIABLES
;END OF ORDER
STB: 0 ;STATIC AREA BOTTOM
STT: 0 ;STATIC AREA TOP.POINTS TO TOP OF STATIC DISPLAY AREA
DYB: 0 ;DYNAMIC BOTTOM. POINTS TO BOT OF DY AREA
DYR: 0 ;ROVING POINTER USED BY DISPLAY STORAGE ALLOCATIN ROUTINES
DYT: 0 ;POINTER TO DYNAMIC AREA TOP
MIRT: 0 ;POINTER TO TEMP TOP OF MIRROR
TEM1: 0 ;USED BY THE TURTLE DRAWER
TEM2: 0
TEM3: 0
DIREC: 0
PI: 40511
7732
121041
64303
;VARIABLES AND CONSTANTS FOR DAZZLE DART
DAZSTR==.
MAXMRS==10.
MAXBMS==10.
LARGE==77000 ;A LARGE FLOATING POINT NUMBER
RTURNF==1 ;BIT CODE FOR MRBOX
LTURNF==2
RSLIDF==4
LSLIDF==10
BKTRF==20
FDTRF==40
PASSF==100
FIREF==200
R360: .WORD 36066,5542 ;1/360.
;VARIABLES -- ONE COPY
WALLB: .WORD 0,0
WALLT: .WORD 0,0
TEN: .WORD 0,0
TURNSP: .WORD 40440,0
SPEED: .WORD 40440,0
FFBDR: .WORD 0,0 ;RAD OF FBDN ZONE
FFBDR2: .WORD 0,0 ;SQUARE OF ABOVE
FFBDH: .WORD 0,0 ;HT OF FBDN ZONE IN FLOATING POINT
FFBDW: .WORD 0,0 ;WDTH
FFBDB: .WORD 0,0 ;BOUNDARY OF FBDN ZONE
REFSIZ: .WORD 41400,0 ;32.
TARD: .WORD 0,0
SX: .WORD 0,0
SY: .WORD 0,0
BMX: .WORD 0,0
BMY: .WORD 0,0
CNT: .WORD 0,0
TARX: .WORD 0,0
TARY: .WORD 0,0
NUMMRS: 12.
NUMBMS: 3
GOLTIM: 5. ;WAIT THIS MANY SECONDS AFTER HITTING GOAL
DIGIT: <<DIG.0-DISREL>/2>!DPUSHJ ;DISPLAY SUBROUTINES TO DRAW DIGITS
<<DIG.1-DISREL>/2>!DPUSHJ
<<DIG.2-DISREL>/2>!DPUSHJ
<<DIG.3-DISREL>/2>!DPUSHJ
<<DIG.4-DISREL>/2>!DPUSHJ
<<DIG.5-DISREL>/2>!DPUSHJ
<<DIG.6-DISREL>/2>!DPUSHJ
<<DIG.7-DISREL>/2>!DPUSHJ
<<DIG.8-DISREL>/2>!DPUSHJ
<<DIG.9-DISREL>/2>!DPUSHJ
;MIRROR VARIABLES
VARBEG==.
CX: REPT2 MAXMRS+8,0,0
CY: REPT2 MAXMRS+8,0,0
TX: REPT2 MAXMRS+8,0,0
TY: REPT2 MAXMRS+8,0,0
BX: REPT2 MAXMRS+8,0,0
BY: REPT2 MAXMRS+8,0,0
ANGM: REPT2 MAXMRS+8,0,0
COSM: REPT2 MAXMRS+8,0,0
SINM: REPT2 MAXMRS+8,0,0
DBOT: REPT2 MAXMRS,0,0
DIRE: REPT2 MAXMRS,0,0
CONTRO: REPT2 MAXMRS,0,0
BN: 0
BMLOST: 0
SMN: 0
TARN: 0
MRFIRE: 0
VAREND==.
BMR: 0 ;WHO'S GOT THE BEAM?
WALMAX: 200. ;WALLS AT PLUS OR MINUS THIS NUMBER
GOLSIZ: 25. ;GOALS AT PLUS AND MINUS THIS
GOLHT: 10. ;HEIGHT OF GOALS
FBDR: 90. ;RAD OF FBDN ZONE
FBDH: 30. ;HEIGHT OF FORBIDDEN ZONE
FBDW: 100. ;HALF THE WIDTH OF FBDN ZONE
TMOUT: 30. ;MUST SHOOT WITHIN THIS MANY SECONDS
MXPAS: 10. ;MAX NUM OF ALLOWED PASSES
;INITIAL VALUES FOR MIRRORS AS INTEGERS
ICX: 50.
-50.
REPT1 MAXMRS+6,0
ICY: 0
0
100.
-100.
REPT1 MAXMRS+4,0
IANGM: 180.
0.
90.
270.
REPT1 MAXMRS+4,0
HIT: 0 ;A FLAG USED BY FIRE ROUTINES
CPAS: 0
SC1: 0
SC2: 0
PSC1: 0
PSC2: 0
PCPAS: 0
PTIM: 0 ;POINTERS TO DISPLAY LIST
NBDR: 0 ;COUNTER FOR BEAM DRAWER
BMCRP: 0 ;POINTER INTO NEXT AREA
BMCRS: REPT1 4*<MAXBMS+1>,0 ;SAVE BEAM CORS HERE
.STITL CLOCKBREAK
CLKBRK: DEC TIME
BGT CLK1
MOV #60.,TIME
DEC TIMER
BGE CLK1 ;DONT ALLOW IT TO BECOME NEGATIVE
CLR TIMER
CLK1: RTT
.STITLE DAZZLE
START: RESET
MOV SPDLP,P
MOV DISREL,NGREL
CLR BMR
RSTRT: MOV #60.,TIME
MOV TMOUT,TIMER
MOV #115,PCS
CLR SC1
CLR SC2
;DAZZLE DART
DAZZLE: MOV #60.,TIME
MOV TMOUT,TIMER
MOV MXPAS,CPAS
JSR PC,STARTD
LDFPS #0 ;INTEGER,FLOATING
JSR PC,DZCLR ;CLEAR OUT MIRROR VARIABLES
JSR PC,MRALOC ;ALLOCATE BUFFERS
JSR PC,DZINIT ;INITIALIZE VARIABLES
JSR PC,WLINIT ;INITIALIZE WALL VARIABLES
JSR PC,DRWALL ;DRAW THE WALLS
JSR PC,SCINIT ;AREA FOR DRAWING SCORE
JSR PC,MRST ;INITIALZE STATIC (IE BEAM) AREA
;THE MAIN LOOP
DZMAIN: BIT #20000,SWB
BEQ DZM0
BPT
DZM0: TST TIMER ;DID HE FIRE IN TIME?
BGT DZM01
MOV TMOUT,TIMER
MOV #60.,TIME
MOV MXPAS,CPAS
ADD #4,BMR ;GIVE BEAM AWAY
BIC #177763,BMR
INC BMLOST
DZM01: JSR PC,MOVEAL ;MOVE ALL MIRRORS
CLR HIT ;BEAM COMPUTATION
CLR NBDR
TST MRFIRE
BEQ DZM1
JSR PC,FBEAM
BR DZM1
;DELETE PREVIOUS INSTRUCTION TO ALLOW FIRING TO RESET TIME
MOV TMOUT,TIMER
MOV #60.,TIME
DZM1: JSR PC,DWAIT
;YES. SO NOW IT IS OKAY TO MUNGE DISPLAY LISTS.
JSR PC,DRAWAL ;DRAW ALL NEW THINGS
JSR PC,DR.BM
MOV PTIM,D ;PRINT TIME
MOV TIMER,B
JSR PC,NPRNT
MOV PCPAS,D ;PRINT PASSES LEFT
MOV CPAS,B
JSR PC,NPRNT
TST HIT
BEQ DZM2 ;DIDN'T HIT GOAL
JMP GOLWAT ;GO TO WAIT AND RESTART
DZM2: JSR PC,DIGO ;START THE DISPLAY BACK UP
BR DZMAIN
;HAS THE DISPLAY FINISHED YET?
DWAIT: SPUSH A
SPUSH B
MOV #NDISP,A
DWAIT1: MOV A,B
SWAB B
DWAIT2: MOV B,NGCSR
BIT #TKRUN,NGCSR
BNE DWAIT2
DEC A
BGE DWAIT1
SPOP B
SPOP A
RTS PC
;WAIT WHILE RUNNING DISPLAY AND THEN RESTART
GOLWAT: JSR PC,SCCOMP
JSR PC,DWAIT
MOV #60.,TIME
MOV GOLTIM,TIMER
JSR PC,PRSCR ;PRINT THE SCORE
GOLW1: JSR PC,DWAIT
JSR PC,DIGO
TST TIMER
BGT GOLW1
GOLWR: JSR PC,DISTOP
ADD #4,BMR
BIC #177763,BMR
JMP DAZZLE
DIGO: SPUSH C
MOV #TKGO,C
JSR PC,DIMUNG
SPOP C
RTS PC
DISTOP: SPUSH C
MOV #TKSTOP,C
JSR PC,DIMUNG
SPOP C
RTS PC
DIMUNG: SPUSH A
SPUSH B
MOV #NDISP,A
DMUNG1: MOV A,B
SWAB B
BIS C,B
MOV B,NGCSR
DEC A
BGE DMUNG1
SPOP B
SPOP A
RTS PC
SCCOMP: MOV NUMMRS,A
ADD #20.,A
CMP A,HIT ;WAS TOP GOAL HIT?
BNE SCGBOT
SCGTOP: INC SC2
BIT #4,BMR
BNE SCRET
INC SC2 ;TOP GOAL HIT BY DEFENSE?
BR SCRET
SCGBOT: INC SC1
BIT #4,BMR
BEQ SCRET
INC SC1 ;BOTTOM GOAL HIT BY DEFENSE?
SCRET: RTS PC
;PRINT THE SCORE
PRSCR: MOV PSC1,D
MOV SC1,B
JSR PC,NPRNT
MOV PSC2,D
MOV SC2,B
JSR PC,NPRNT
RTS PC
NPRNT: CLR -(D) ;CLEAR OUT OLD NUMBER
CLR -(D)
CLR -(D)
ADD #6,D
CLR A
CMP B,#999.
BLE NPRNT1
BPT
NPRNT1: DIV #10.,A
ASL B
MOV DIGIT(B),-(D)
TST A
BEQ NPRNT2
MOV A,B
CLR A
BR NPRNT1
NPRNT2: RTS PC
;MOVE ALL MIRRORS
MOVEAL: MOV NUMMRS,M
MOVELP: JSR PC,MOVE ;MOVE ONE MIRROR
SUB #4,M
BGE MOVELP
RTS PC
;MOVE ONE MIRROR.
; CALL WITH INDEX IN M
MOVE: JSR PC,MRBOX ;A _ CONTROL BOX
; BITS ARE CODED AS <FIRE, BK, FD, LT, RT>
SPUSH A
MOV A,CONTRO(M)
BIT #<RTURNF!LTURNF>,A
BEQ MVNOTU
BIT #RTURNF,A
BEQ MVLTU ;ITS A LEFT TURN
MVRTU: CLR A ;A FLAG FOR MVTURN
MVLTU: JSR PC,MVTURN ;TURN THIS MIRROR
MVNOTU: MOV (P),A
BIT #<FDTRF!BKTRF>,A
BEQ MVNOTR
BIT #FDTRF,A
BEQ MVBKTR ;BACKWARDS TRANSLATION
MVFDTR: CLR A
MVBKTR: JSR PC,MVTRAN ;TRANSLATE THIS MIRROR
MVNOTR: MOV (P),A ;NOW CHECK FOR SLIDING
BIT #<RSLIDF!LSLIDF>,A
BEQ MVNOTS
BIT #LSLIDF,A
BEQ MLSLD
CLR A
MLSLD: JSR PC,MVSLID
MVNOTS: TST (P)+
RTS PC
;READ THE BOX
MRBOX: MOV M,A
ASH #8,A
MOV A,DEVADD
CLR DEVICE
MRB1: TST DEVICE ;INPUT IS COMPLETE WHEN M.S.B.= 1
BPL MRB1
MOV DEVICE,A
COM A ;DEVICE BITS ARE INVERTED
MRB9: RTS PC
;DRAW ALL THE MIRROS THAT NEED TO BE DRAWN
;
DRAWAL: MOV NUMMRS,M
DRAWLP: JSR PC,DRAW ;DRAW ONE MIRROR
SUB #4,M
BGE DRAWLP
CLR BMLOST
RTS PC
;DRAW ONE MIRROR.
; CALL WITH INDEX IN M
DRAW: SPUSH CONTRO(M) ;CONTROL BOX WORD
BIT #PASSF,(P) ;PASS THE BEAM?
BEQ DRAW0
CMP M,BMR
BNE DRAW0
TST CPAS ;PASSES USED UP?
BEQ DRAW0
DEC CPAS
ADD #8.,BMR
BIC #177763,BMR
INC BMLOST
BIC #PASSF,CONTRO(M) ;TURN OF FLAG SO WE DON'T LOOP
CMP (P)+,(P)+ ;WHEN WE GO TO REDRAW ALL MIRRORS
BR DRAWAL ;WHAT A KLUDGE!
DRAW0: TST BMLOST
BNE DRAW1 ;IF BEAMER CHANGES REDRAW MIRRORS ANYWAY
; BITS ARE CODED AS <FIRE, BK, FD, LT, RT>
BIT #<RTURNF!LTURNF>,(P)
BEQ DRNOTU
DRAW1: JSR PC,DR.MIR ;REDRAW THE MIRROR
DRNOTU: BIT #<FDTRF!BKTRF!LSLIDF!RSLIDF>,(P)
BEQ DRNOTR
JSR PC,DRTRAN ;TRANSLATE THIS MIRROR
DRNOTR: CMP M,BMR ;DOES THIS GUY HAVE THE BEAM?
BNE NOTFIR
CLR MRFIRE
BIT #FIREF,(P) ;IS MIRROR 0 FIRING
BEQ NOTFIR
INC MRFIRE ;YES. SET FLAG
NOTFIR: TST (P)+
RTS PC
;TURN THIS MIRROR.
; CALL WITH A = 0 IFF RIGHT TURN
;UPDATE VARIABLES ONLY
MVTURN: LDF ANGM(M),FA
TST A
BEQ MTURT ;RIGHT TURN
SUBF TURNSP,FA ;LEFT TURN
BR .+6
MTURT: ADDF TURNSP,FA
JSR PC,MOD360 ;MAKE ANGM MOD 360
STF FA,ANGM(M)
MRTUR1: JSR PC,MRANG ;GET SIN, COS, AND DIREC
JSR PC,MRTUUP ;UPDATE REST OF TURNED VARIABLES
RTS PC
;DO ANGLE CRAP
MRANG: STF FA,FE
JSR PC,SINDEG ;FA _ SIN FA
STF FA,SINM(M)
LDF FE,FA
JSR PC,COSDEG
STF FA,COSM(M)
ASH #2,C ;TRIG LEAVES QUADRANT INFO IN C
MOV C,DIRE(M)
RTS PC
;INCREMENATL MOD360 ROUTINE. CLOBBERS FC
MOD360: LDCIF #360.,FC
TSTF FA ;IS ANGLE NEGATIVE?
CFCC
BLT MODNEG ;YES
CMPF FA,FC ;IS ANGLE > 360.
CFCC
BLT MODRTS ;NO. ANGLE IS OKAY
SUBF FC,FA ;ELSE ANGLE = ANGLE - 360
MODRTS: RTS PC
;ANGLE IS NEGATIVE, SO
MODNEG: ADDF FC,FA ;ANGLE = ANGLE + 360
RTS PC
;UPDATE VARIABLES THAT HAVE BEEN TURNED
MRTUUP: LDF COSM(M),FA
MULF REFSIZ,FA
STF FA,FF ;DY
LDF SINM(M),FA
MULF REFSIZ,FA
STF FA,FE ;DX
ADDF CX(M),FA
STF FA,TX(M)
LDF FF,FA ;DY
ADDF CY(M),FA
STF FA,TY(M)
LDF CX(M),FA
SUBF FE,FA
STF FA,BX(M)
LDF CY(M),FA
SUBF FF,FA
STF FA,BY(M)
RTS PC
;SLIDE THIS MIRROR
;A=0 IF SLIDE TO RIGHT
MVSLID: LDCIF #-1,FA ;FOR TURTLE CONTROLS USE---LDF SINM(M),FA
CLRF FB ;FOR TURTLE--LDF COSM(M),FB
NOP ;SPACE FOR TURTLE PATCH
BR MVTRS
;TRANSLATE THIS MIRROR
; A = 0 IFF THE DIRECTION IS FORWARD
MVTRAN: LDCIF #-1,FB ;FOR TURTLE---LDF SINM(M),FB
NEGF FB ;= COS (ANGM+90)
CLRF FA ;FOR TURTLE---LDF COSM(M),FA
NOP
MVTRS: MULF SPEED,FA ;DX
MULF SPEED,FB ;DY
TST A ;FD OR BK ?
BEQ FDMOVE
NEGF FA ;BACKWARD, SO NEGATE DX AND DY
NEGF FB
FDMOVE: STF FA,FE
STF FB,FF
ADDF CX(M),FA ;NEW X
ADDF CY(M),FB
LDF FA,FD
JSR PC,CHKBND ;IN BOUNDS?
BNE NOTBND ;OUT OF BOUNDS. DO NOTHING
YBND: LDF FB,FD
JSR PC,CHKBND ;IN BOUNDS?
BNE NOTBND ;OUT OF BOUNDS. DO NOTHING
JSR PC,FBDCH ;CHECK TO SEE IF IN FORBIDDEN ZONE
BNE NOTBND
MRTR1: JSR PC,MRTRUP ;UPDATE VARIABLES
NOTBND: RTS PC
;CHECK TO SEE IF ENTERING FORBIDDEN ZONE
.IFZ CIRC
FBDCH: FPUSH FA
FPUSH FB
ABSF FA
CMPF FFBDW,FA
CFCC
BLT FBOK
ABSF FB
CMPF FFBDB,FB
CFCC
BGT FBOK
FPOP FB ;INSIDE FORBIDDEN ZONE
FPOP FA
CLZ
RTS PC
FBOK: FPOP FB
FPOP FA
SEZ
RTS PC
.ENDC
.IFZ CIRC-1
FBDCH: FPUSH FA
FPUSH FB
FPUSH FC
STF FB,FC
MULF FA,FA
ADDF WALLT,FC
MULF FC,FC
ADDF FA,FC
CMPF FFBDR2,FC
CFCC
BGT FBNO
SUBF WALLT,FB
MULF FB,FB
ADDF FA,FB
CMPF FFBDR2,FB
CFCC
BGT FBNO
FPOP FC ;OK
FPOP FB
FPOP FA
SEZ
RTS PC
FBNO: FPOP FC
FPOP FB
FPOP FA
CLZ
RTS PC
.ENDC
;UPDATE VARIABLES DUE TO TRANSLATION
MRTRUP: STF FA,CX(M)
STF FB,CY(M)
LDF FE,FC ;DX
ADDF TX(M),FC
STF FC,TX(M)
LDF FF,FC
ADDF TY(M),FC
STF FC,TY(M)
LDF FE,FC
ADDF BX(M),FC
STF FC,BX(M)
LDF FF,FC
ADDF BY(M),FC
STF FC,BY(M)
RTS PC
;MUNGE DISPLAY LIST TO TRANSLATE THIS MIRROR
DRTRAN: LDF CX(M),FA
LDF CY(M),FB
JSR PC,ROUND
STCFI FA,D
STCFI FB,E
MOV DBOT(M),A
JSR PC,MTO.R1 ;ACTUALLY PUT IN THE ADDX AND ADDY COMMANDS
RTS PC
;DRAW A MIRROR
DR.MIR: MOV DBOT(M),A
MOV A,MIRT ;MIRT WILL BE POINTER TO TOP OF TURTLE DLIST SO FAR
CMP -(A),-(A)
MOV #DRSTXY!DPOPJ,-(A)
SPUSH A
MOV DIRE(M),DIREC
LDCIF #TURSIZ,FB
LDF SINM(M),FA
MULF FB,FA ;DX OF 1ST TURTLE SIDE
MULF COSM(M),FB ;DY OF 1ST SIDE
JSR PC,ROUND
STCFI FA,D
STCFI FB,E
MOV M,A
ASR A
JSR PC,@DR.TU(A)
JSR PC,DR.REF ;THE REFLECTOR
MOV #DRSTXY,@(P)+ ;RESTORE THIS WORD
RTS PC
;DISPATCH TABLE FOR POINTERS
;THESE ROUTINES SHOULD BE CALLED WITH D,E AND DIREC SET
;AND LEAVE MIRT POINTING TO WHERE REFLECTOR CODE SHOULD START
DR.TU: DR.TUR
DR.TSQ
DR2TR
DR2SQ
REPT1 MAXMRS-4,DR.TUR
DR.TUL: DR.TUR ;DISPATCH TABLE FOR THE "2 FIGURE "ROUTINES
DR.TS1
;DRAW A TRIANGULAR POINTER
DR.TUR: SPUSH M
SPUSH DIREC
SPUSH D
SPUSH D
SUB E,2(SP) ;NOW SIZE * (SIN - COS) ON STACK
ADD E,(SP) ;NOW SIZE * (SIN + COS) ON STACK
;SIDE 1--WILL BE AN ADDXY
MOV MIRT,A
MOV A,TEM3
CMP (A)+,(A)+
MOV A,MIRT
JSR PC,MTO.R1
;SIDE 2
ADD #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
ADD #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 MIRT,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,
SPOP DIREC
SPOP M
MOV TEM3,B ;COPY THE SAME ADDXY
MOV (B)+,(A)+
MOV (B)+,(A)+
MOV #DPOPJ,(A)
MOV A,MIRT
RTS PC
; DRAW ONE SIDE OF THE TURTLE
; DIREC CONTAINS THE DIRECTION
; MIRT 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.STUP
ADD MIRT,D ;D = NEW TOP OF TURTLE
MOV D,MIRT
JSR PC,DR.ASC ;ACTUALLY CREAT THE DISPLAY LIST
RTS PC
;THE 2 FIGURE ROUTINES USE C AS A FLAG TO DECIDE
;BETWEEN TRIANGLE AND SQUARE
DR2TR: CLR C
JSR PC,DR.TU1
RTS PC
DR2SQ: MOV #2,C
ASR D ;SQUARE IS HALF AS BIG AS TRI
ASR E
JSR PC,DR.TU1
RTS PC
;DRAW POINTER AS TWO TRIANGLES
;DLIST IS ADDXY,PUSHJ TO TRIANGLE,ADDXY,PUSHJ,ADDXY,
;PUSHJ TO REFLECTOR,POPJ,TIRANGLE CODE,REFLECTOR CODE
DR.TU1: SPUSH D
SPUSH E
MOV MIRT,A ;POINTER TO START OF CODE
ADD #4,A
MOV A,TEM1 ;FIRST PUSHJ WILL GO HERE
JSR PC,MTO.R1 ;PUT IN ADDXY. D,E ALREADY SET
MOV TEM1,A
ADD #6,A
MOV A,TEM2 ;POINTER TO 2ND PUSHJ
MOV (P),E
MOV 2(P),D
ASL D
ASL E
NEG D
NEG E ;SET UP FOR 2ND ADDXY
JSR PC,MTO.R1
MOV TEM2,A
ADD #10.,A ;LEAVE ROOM FOR ADDXY,PUSH TO REF AND POPJ
MOV A,MIRT ;TRIANGLE CODE WILL START HERE
MOV A,B
MAKEPJ B
MOV B,@TEM1
MOV B,@TEM2 ;PUT IN PUSHJ'S TO TURTLE CODE
MOV #DPOPJ,-(A) ;THE FINAL POPJ
TST -(A)
MOV A,TEM1 ;POINTER TO PUSHJ TO REFLECTOR
MOV (P),E
MOV 2(P),D
JSR PC,MTO.R1 ;THE FINAL ADDXY
SPOP E
SPOP D
JSR PC,@DR.TUL(C) ;DECIDE BETWEEN SQUARE AND TRIANGLE
ADD #2,MIRT ;REFLECTOR CODE WILL START HERE
MOV MIRT,A
MAKEPJ A
MOV A,@TEM1
RTS PC
;DRAW POINTER AS A SQUARE
;MADE UP OF ADDXY (DX,DY)
;SIDES ARE (-2DY,2DX),(-2DX,-2DY),(2DY,-2DX)
;ADDXY (DX,DY)
DR.TSQ: ASR D ;SQUARE IS HALF AS BIG AS TRIANGLE
ASR E
DR.TS1: SPUSH DIREC ;ENTRY FOR "2-SQUARE" WHICH ALREADY ASR'ED D AND E
SPUSH DYB ;THIS WILL FAKE OUT THE
;ERROR CONDITION ON THE LINE DRAWER
MOV #DISEND,DYB
SPUSH STT ;FOR LINE DRAWER WE WILL MUNG STT
SPUSH M
SPUSH D
SPUSH E
MOV MIRT,A ;FIRST WORD OF CODE WILL GO HERE
CMP (A)+,(A)+
MOV A,MIRT
JSR PC,MTO.R1 ;FIRST ADDXY
MOV MIRT,STT ;FOR LINE DRAWER
MOV (P),D ;SET UP DX AND DY FOR SIDE 2
MOV 2(P),E
ASL D
ASL E
NEG E
JSR PC,XYDIR
JSR PC,DR.LIN ;SIDE 2
MOV (P),E
ASL E
NEG E
MOV 2(P),D
ASL D
NEG D
JSR PC,XYDIR
JSR PC,DR.LIN ;SIDE 3
MOV (P),D
MOV 2(P),E
ASL D
ASL E
NEG D
JSR PC,XYDIR
JSR PC,DR.LIN ;SIDE 4
SPOP E
SPOP D
MOV STT,A
CMP (A)+,(A)+
MOV A,MIRT
MOV #DPOPJ,(A) ;LAST WORD OF CODE
JSR PC,MTO.R1 ;FINAL SIDE
SPOP M
SPOP STT
SPOP DYB
SPOP DIREC
RTS PC
;THE REFLECTOR PART OF THE MIRROR
DR.REF: SPUSH M
LDF TX(M),FA ;GET DX,DY TO TOP OF MIRROR
LDF CX(M),FB
JSR PC,ROUND
SUBF FB,FA ;DX
STCFI FA,D
LDF TY(M),FA
LDF CY(M),FB
JSR PC,ROUND
SUBF FB,FA ;DY
STCFI FA,E
MOV MIRT,A ;HACK THE DISPLAY LIST
CMP (A)+,(A)+
MOV #DPOPJ,(A)
MOV A,MIRT
JSR PC,MTO.R1 ;ACTUALLY PUTS IN THE ADDX, ADDY
;GET DX,DY FROM TOP TO BOTTOM OF MIRROR
LDF BX(M),FA
LDF TX(M),FB
JSR PC,ROUND
SUBF FB,FA ;DX
STF FA,FC
STCFI FA,D
LDF BY(M),FA
LDF TY(M),FB
JSR PC,ROUND
SUBF FB,FA ;DY
STCFI FA,E
SPUSH D
SPUSH E
ADD #40,DIREC
BIC #177707,DIREC
JSR PC,DR.STUP ;SET UP TO DRAW LINE
ADD MIRT,D ;POINTER TO NEW TOP
MOV D,MIRT
MOV #DPOPJ,(D)
JSR PC,DR.ASC ;ACTUALLY ASSEMBLE DISPLAY CODE
MOV 4(P),M
CMP M,BMR ;SPECIAL REFLECTOR FOR BEAMER
BNE DR.RER
DIVF TEN,FA
DIVF TEN,FC
STCFI FA,D
STCFI FC,E
NEG D
MOV MIRT,A
CMP (A)+,(A)+
MOV #DPOPJ,(A)
MOV A,MIRT
JSR PC,MTO.R1
SPOP E
SPOP D
NEG E
NEG D
JSR PC,XYDIR
SPUSH STT ;FAKE OUT ERROR CONDINTION IN DR.LIN
SPUSH DYB
MOV #DISEND,DYB
MOV MIRT,STT
JSR PC,DR.LIN
MOV #DPOPJ,@STT
SPOP DYB
SPOP STT
BR DR.RE1
DR.RER: SPOP E
SPOP D
DR.RE1: SPOP M
RTS PC
;ALLOCATE DISPLAY BUFFERS FOR EACH MIRROR
; A = MAX LENGTH OF DISPLAY CODE PLUS DPOPJ
MRALOC:
;CALCULATE SIZE OF EACH MIRROR DISPLAY BUFFER
LDF REFSIZ,FA ;= 1/2 SIZE OF MIRROR
STCFI FA,B
CLR A
DIV #4,A ;=((1/2 SIZE)/8)*2
;= # OF WORDS OF DISPLAY CODE FOR WHOLE MIRROR
TST B ;IF THERE IS A REMAINDER
BEQ DAZ1 ;
INC A ;ROUND UP
DAZ1: ASL A ;TURN INTO BYTE COUNT
ADD #<TLEN+6>,A ;LEAVE ROOM FOR TURTLE, ETC
MOV NUMMRS,M
MOV DYT,B
MRAL1: SUB A,B ;B -> FIRST USABLE WORD
MOV B,DBOT(M)
MOV #ADDX,-(B)
MOV #ADDY,-(B)
MOV #DRSTXY,-(B)
SUB #4,M
BGE MRAL1 ;LOOP ON
MOV B,DYB ;BOTTOM OF MIRROR BUFFERS
RTS PC
;INITIALIZE STATIC AND LIGHT BEAM AREAS.
;PUT IN A PUSHJ TO EACH MIRROR
MRST: MOV STT,A
MOV NUMMRS,M
MOV M,B
ASR B
ADD B,A
CMP (A)+,(A)+
MOV A,STT
MOV A,STB ;THIS IS ALSO BOTTOM OF BEAM AREA
MOV #DSTOP,(A)
MOV #DRSTXY,-(A)
MRST1: MOV DBOT(M),E
SUB #6,E ;E -> THE DRSTXY AT THE BEGINNING
MAKEPJ E
MOV E,-(A)
SUB #4,M
BGE MRST1
RTS PC
;INITIALIZE
DZINIT: MOV NUMMRS,M
MOV M,A
ASR A
DZILP: LDCIF IANGM(A),FA
LDCIF ICX(A),FB
LDCIF ICY(A),FC
STF FA,ANGM(M)
STF FB,CX(M)
STF FC,CY(M)
SPUSH A
JSR PC,MRTUR1 ;GETS SINM, COSM, ETC. AND DRAWS MIRROR
JSR PC,DR.MIR
JSR PC,DRTRAN
SPOP A
SUB #4,M
SUB #2,A
BGE DZILP
RTS PC
DZCLR: MOV #VARBEG,A
DZCLR0: CLR (A)+
CMP A,#VAREND
BLO DZCLR0
LDCIF #20.,FA
STF FA,TEN
CLR BMLOST
RTS PC
;INITIAL WALL VARIABLES
WLINIT: MOV NUMMRS,M
LDCIF WALMAX,FA
STF FA,WALLT
STF FA,FB ;WALL1--(200,200) TO (-200,200)
STF FA,FC
STF FA,FD
NEGF FC
STF FC,WALLB
FPUSH FA
LDCIF #90.,FA ;ANGLE=90 DEGREES
STF FA,FE
FPOP FA
JSR PC,WLINI1
NEGF FB ;WALL2--(200,-200) TO (200,200)
NEGF FC
CLRF FE ;ANGLE=0
JSR PC,WLINI1
NEGF FA ;WALL3--(-200,-200) TO (200,-200)
NEGF FD
FPUSH FA
LDCIF #90.,FA ;ANGLE=90 DEGREES
STF FA,FE
FPOP FA
JSR PC,WLINI1
NEGF FB ;WALL4--(-200,200) TO (-200,-200)
NEGF FC
CLRF FE ;ANG=0
JSR PC,WLINI1
LDCIF GOLSIZ,FA ;GOAL1 (-25,200) TO (25,200)
STF FA,FC
NEGF FA
NEGF FD
FPUSH FA
LDCIF #90.,FA ;ANGLE=90 DEGREES
STF FA,FE
FPOP FA
JSR PC,WLINI1
ADD #4.,M ;SKIP GOALS 2
NEGF FB ;GOAL3 (-25,-200) TO (25,-200)
NEGF FD
JSR PC,WLINI1
LDCIF FBDW,FA ;SET UP FBDN ZONE VARIABLES IN FLOATING POINT
STF FA,FFBDW
LDCIF FBDH,FA
STF FA,FFBDH
LDCIF FBDR,FA
STF FA,FFBDR
MULF FA,FA ;RADIUS AND SQUARE OF FBDN ZONE
STF FA,FFBDR2
LDF WALLT,FB
SUBF FA,FB
STF FB,FFBDB
RTS PC
WLINI1: FPUSH FA
FPUSH FB
FPUSH FC
FPUSH FD
ADD #4,M
STF FA,BX(M)
STF FB,BY(M)
STF FC,TX(M)
STF FD,TY(M)
LDF FE,FA
STF FA,ANGM(M)
JSR PC,MRANG
FPOP FD
FPOP FC
FPOP FB
FPOP FA
RTS PC
;DRAW THE WALLS
DRWALL: LDF WALLB,FA
LDF WALLT,FB
STCFI FA,D
SPUSH D ;WALLB
STCFI FB,-(P) ;WALLT
MOV D,E
JSR PC,MTO.AD ;PUT IN SETXY TO BOTTOM LEFT
SPOP E ;WALLT
SUB (P),E ;WALLB-WALLT = WALLSIZE
MOV E,(P)
CLR D ;DX = 0
CLR DIREC ;VERTICAL LINE
JSR PC,DR.LIN
MOV (P),D ;DX = WALLSIZE
CLR E ;DY = 0
MOV #20,DIREC
JSR PC,DR.LIN
MOV (P),E ;DY = WALLSIZE
CLR D ;DX = 0
MOV #40,DIREC
JSR PC,DR.LIN
SPOP D ;DX = WALLSIZE
CLR E ;DY = 0
MOV #60,DIREC
JSR PC,DR.LIN
JSR PC,DR.GLS ;DRAW THE GOALS
JSR PC,DR.FB ;DRAW FORBIDDEN ZONE
RTS PC
;DRAW THE GOALS
DR.GLS: JSR PC,DR.RST ;PUT IN A RESET
MOV WALMAX,E
MOV GOLSIZ,D
NEG D
JSR PC,MTO.AD ;SETXY AT FIRST GOAL
JSR PC,DR.G1 ;DRAW FIRST GOAL
MOV WALMAX,E
ASL E
ADD GOLHT,E
NEG E
CLR D
JSR PC,MTO.AD ;SETXY AT 2ND GOAL
JSR PC,DR.G1 ;DRAW 2ND GOAL
RTS PC
DR.G1: MOV GOLHT,E ;DRAW A GOAL
MOV GOLSIZ,D
ASL D
JSR PC,DR.SQ
RTS PC
DR.RST: MOV STT,A ;PUT IN A RESET
MOV #DRSTXY,(A)+
MOV #DSTOP,(A)
MOV A,STT
RTS PC
.IFZ CIRC
DR.FB: JSR PC,DR.RST
MOV FBDW,D
NEG D
MOV WALMAX,E
NEG E
JSR PC,MTO.AD
MOV FBDW,D
ASL D
MOV FBDH,E
JSR PC,DR.SQ ;DRAW BOTTOM FBDN ZONE
MOV WALMAX,E ;POSITION FOR TOP ZONE
ASL E
SUB FBDH,E
CLR D
JSR PC,MTO.AD
MOV FBDW,D
MOV FBDH,E
ASL D
JSR PC,DR.SQ
RTS PC
.ENDC
.IFZ CIRC-1
DR.FB: CLR A ;FLAG TO DRAW TOP
JSR PC,DR.FB0
MOV #-1,A
JSR PC,DR.FB0
RTS PC
DR.FB0: SPUSH A
JSR PC,DR.RST ;PUT IN A RESET
CLRF CURX
CLRF CURY
BIS #PENUF,DFLAGS
LDF WALLT,FB
TST (P)
BEQ DR.F0T ;NEGATE YCOR FOR BOTTOM
NEGF FB
DR.F0T: CLRF FA
SUBF FFBDR,FA
JSR PC,MOVETO
BIC #PENUF,DFLAGS ;PENDOWN
SPOP A ;TOP--BOTTOM FLAG
LDCIF #180.,FA
STF FA,FE
JSR PC,DR.FBS
RTS PC
DR.FBS: SPUSH A
DR.FB2: LDF FE,FA
LDCIF #3,FB
SUBF FB,FA
STF FA,FE
JSR PC,SINDEG
MULF FFBDR,FA
FPUSH FA ;SAVE Y-COORDINATE
LDF FE,FA
JSR PC,COSDEG
MULF FFBDR,FA ;X--COORDINATE
FPOP FB
SUBF WALLT,FB
TST (P)
BNE D.FBSB
NEGF FB ;NEGATE IT WHEN DRAWING TOP
D.FBSB: JSR PC,MOVETO
TSTF FE
CFCC
BGT DR.FB2
SPOP A
RTS PC
.ENDC
;LEAVE ROOM IN DISPLAY LIST FOR SCORE AND TIME
SCINIT: JSR PC,DR.RST
MOV #-150.,D
MOV WALMAX,E
ADD #20.,E
CMP (A)+,(A)+
MOV A,STT
JSR PC,MTO.R1 ;ADDXY TO UPPER LEFT
MOV STT,A
CLR (A)+
CLR (A)+
CLR (A)+ ;3 DIGITS. 0 IS DISPLAY NOP
MOV A,PSC1 ;POINTER BEYOND LAST WORDOF SCORE 1
JSR PC,SCIN0
MOV A,PCPAS
JSR PC,SCIN0 ;ROOM FOR NUM PASSES LEFT
MOV A,PTIM
JSR PC,SCIN0
MOV A,PSC2
MOV A,STT
MOV #DSTOP,(A)
RTS PC
SCIN0: CMP (A)+,(A)+ ;LEAVE ROOM FOR A 3-DIGIT NUMBER
MOV A,PSC2
CLR E
MOV #50.,D
JSR PC,MTO.R1
MOV PSC2,A
CLR (A)+
CLR (A)+
CLR (A)+
RTS PC
;DRAW A SQUARE
;D IS WIDTH AND E IS HEIGHT
DR.SQ: SPUSH D
SPUSH E
CLR D
CLR DIREC
JSR PC,DR.LIN
CLR E
MOV 2(P),D
MOV #20,DIREC
JSR PC,DR.LIN
CLR D
MOV (P),E
MOV #40,DIREC
JSR PC,DR.LIN
CLR E
MOV 2(P),D
MOV #60,DIREC
JSR PC,DR.LIN
SPOP E
SPOP D
RTS PC
;SAVE BEAM COORDS FOR DRAW ROUTINE
; CALL BMSTRT FOR FIRST BEAM.
; CALL BMCONT FOR SUBSEQUENT ONES
STRTBM: MOV #BMCRS,A
STF FA,(A)+
STF FB,(A)+
MOV A,BMCRP
CONTBM: INC NBDR
MOV BMCRP,A
STF FC,(A)+
STF FD,(A)+
MOV A,BMCRP
RTS PC
;DRAW THE BEAM!
DR.BM: JSR PC,BMCS
TST NBDR
BLE DR.BMR ;NO BEAMS
MOV #BMCRS,A
LDF (A)+,FA
LDF (A)+,FB
LDF (A)+,FC
LDF (A)+,FD
SPUSH A
JSR PC,STRTB1
SPOP A
DR.BM1: DEC NBDR
BLE DR.BMR
LDF (A)+,FC
LDF (A)+,FD
SPUSH A
JSR PC,CONTB1
SPOP A
BR DR.BM1
DR.BMR: RTS PC
;FA = X OF FIRST POINT
;FB = Y OF FIRST POINT
STRTB1: BIS #PENUF,DFLAGS
CLRF CURX
CLRF CURY
FPUSH FC
FPUSH FD
JSR PC,MOVETO
FPOP FD
FPOP FC
BIC #PENUF,DFLAGS
;FC = X OF NEW POINT.
;FD = Y OF NEW POINT
CONTB1: SPUSH M
STF FC,FA ;X
STF FD,FB ;Y
JSR PC,MOVETO
SPOP M
RTS PC
;CLEAR BEAM SCREEN
BMCS: MOV STB,STT
MOV #DSTOP,@STT
RTS PC
;FIRST BEAM
FBEAM: CLR BN ;BEAM NUMBER
MOV BMR,SMN ;SOURCE OF BEAM
LDD #LARGE,FA
STF FA,TARD ;TARGET DISTANCE
MOV BMR,M ;MIRROR INDEX
LDD CX(M),FA ;SET UP SOURCE
STF FA,SX
LDD CY(M),FB
STF FB,SY
LDD COSM(M),FC
STF FC,BMX ;BEAM VECTOR COORDS
LDD SINM(M),FD
NEGD FD ;BM PRRP TO MIRROR
STF FD,BMY
MULD FB,FC ;BMX*SY
MULD FA,FD ;BMY*SX
SUBD FD,FC
STF FC,CNT ;L(X)=BM(PERP).(X-S)=BMY*X-BMX*Y+(BMX*SY-BMY*SX)
CLR M
CHKMRS: CMP M,SMN ;STARTING MIRROR?
BEQ ENDMRS
LDD BMY,FA ;BEAM THRU MIRROR?
MULD TX(M),FA
LDD BMX,FB
MULD TY(M),FB
SUBD FB,FA ;L(T) IN FA
ADDD CNT,FA
LDD BMY,FB
MULD BX(M),FB
LDD BMX,FC
MULD BY(M),FC
SUBD FC,FB
ADDD CNT,FB ;L(B) IN FB
LDD FA,FC ;L(T) IN FC
MULD FB,FA
CFCC ;L(T)*L(B)<0?
BGE ENDMRS
LDD FB,FA ;COMPUTE INTERSECTION, I=B+D*(T-B)
SUBD FC,FB ;D=L(B)/(L(B)-L(T)) IN FA
DIVD FB,FA
LDD TX(M),FC
SUBD BX(M),FC
MULD FA,FC
ADDD BX(M),FC ;TTARX IN FC
LDD TY(M),FD
SUBD BY(M),FD
MULD FA,FD
ADDD BY(M),FD ;TTARY IN FD
LDD FC,FA ;COMPUTE TARGET DISTANCE
SUBD SX,FA ;TTARD=BM.(TTAR-S)
MULD BMX,FA
LDD FD,FB
SUBD SY,FB
MULD BMY,FB
ADDD FB,FA ;TTARD IN FA
CFCC ;MIRROR IN DIRECTION OF BEAM?
BLE ENDMRS
CMP M,NUMMRS ;IS THIS A WALL?
BLE CHKMR1
JMP WALLS
CHKMR1: CMPD TARD,FA ;CLOSEST MIRROR SO FAR?
CFCC
BLE ENDMRS
MOV M,TARN ;TTAR BECOMES TAR
STF FA,TARD
STF FC,TARX
STF FD,TARY
ENDMRS: CMP M,NUMMRS ;CHECKED ALL MIRRORS?
BEQ .ENDMR
MOV NUMMRS,A ;CHECKED ALL WALLS?
ADD #16.,A
CMP M,A
BLT .RTRN
BMERR: RTS PC
.RTRN: ADD #4,M ;CHECK REST
JMP CHKMRS
.ENDMR: LDD #LARGE,FA ;HIT A MIRROR?
CMPD TARD,FA
CFCC
BEQ .RTRN ;NO, DO WALLS
LDD SX,FA ;DRAW BEAM
LDD SY,FB
LDD TARX,FC
LDD TARY,FD
TST BN ;IS THIS FIRST BEAM?
BEQ .FBM
JSR PC,CONTBM
BR ENDBM
.FBM: JSR PC,STRTBM
ENDBM: INC BN ;ALL BEAMS?
CMP BN,NUMBMS
BNE NEWBM
CLR HIT
CMP TARN,NUMMRS ;HIT A MIRROR ON FINAL BOUNCE?
BGT FBM.R
MOV TARN,B ;DID BEAM CHANGE TEAMS?
MOV BMR,C
MOV #177773,D
BIC D,B
BIC D,C
CMP B,C
BEQ ENDBM1 ;NO--SAME TEAM
MOV TMOUT,TIMER ;YES--RESET CLOCK
MOV #60.,TIME ;RESET CLOCK
MOV MXPAS,CPAS ;RESET NUM PASSES
ENDBM1: MOV TARN,BMR ;LAST GUY HIT GETS BEAM
MOV #1,BMLOST
FBM.R: RTS PC
NEWBM: MOV TARN,M ;INDEX TO TARGET
LDD TARX,FA ;TAR BECOMES SOURCE
STF FA,SX
LDD TARY,FA
STF FA,SY
MOV TARN,SMN
LDD #LARGE,FA
STF FA,TARD
LDD ANGM(M),FA ;REFLECT
MULD #40400,FA
STF FA,FE ;2*ANGLE IN FE
JSR PC,SINDEG
STF FA,FD
LDD FE,FA
STF FD,FE ;SIN 2*ANG IN FE
JSR PC,COSDEG ;COS 2*ANG IN FA
LDD BMX,FC ;BMX IN FC
LDD BMY,FB ;BMY IN FB
MULD FE,FB
MULD FA,FC
SUBD FC,FB ;NEW BMX IN FB, YSIN -XCOS
LDD FE,FD
MULD BMX,FD
MULD BMY,FA ;NEW BMY IN FA,XSIN +YCOS
ADDD FD,FA
STF FB,BMX
STF FA,BMY
MULD SY,FB ;COMPUTE NEW CNT
MULD SX,FA
SUBD FA,FB
STF FB,CNT
CLR M ;RESET MIRROR NUMBER
JMP CHKMRS
WALLS: MOV M,TARN ;WALL BECOMES TARGET
STF FD,TARY
STF FC,TARX
LDD SX,FA
LDD SY,FB
TST BN ;FIRST BEAM?
BEQ .FWBM
JSR PC,CONTBM ;DRAW BEAM
BR .GLCHK ;GO TO CHECK GOALS
.FWBM: JSR PC,STRTBM
.GLCHK: ADD #16.,M ;CHECK GOAL
LDD TX(M),FA
SUBD TARX,FA
LDD TARX,FB
SUBD BX(M),FB
MULD FB,FA
CFCC
BGT GOAL ;(T-X)*(X-B)>0 IMPLIES GOAL
CLR HIT
RTS PC
GOAL: MOV M,HIT
TST BN
BNE GOAL1
CLR HIT
GOAL1: RTS PC
;STARTDISPLAY
STARTD: MOV #NDISP,A
ASL A
STARD1: MOV #DSTOP,DISREL(A)
MOV #DPDLL,D
MUL A,D
ADD #<DPDL-DISREL>,D
ASR D
MOV D,DISPDL(A)
SUB #2,A
BGE STARD1
MOV #DORBEG,F ;ZERO VARIOUS USER DISPLAY VARS
MOV #DOREND,D ;LAST WORD
SDLOOP: CLR (F)+ ;ZERO WORD
CMP F,D
BLE SDLOOP
;SET FIRST 2 WORDS OF DLIST
;AND SET THE BUFFER VARIABLES
MOV #DLIST,D
MOV #<DRSTXY!DPOP>,(D)+
MOV #DSTOP,(D)
MOV D,STB ;STATIC AREA BOTTOM
MOV D,STT ;STATIC AREA TOP
MOV #DISEND,B
CLR -(B) ;SET UP DUMMY FREE AREA
MOV B,DYT ;DYNAMIC AREA TOP
CLR -(B)
MOV B,DYB ;DYNAMIC AREA BOTTOM
MOV B,DYR ;DYNAMIC AREA ROVING POINTER
;NOW MAKE A PUSHJ TO THE DISPLAY LIST
;AND STUFF IT INTO THE HARDWARE FIRST LOCATION FOR THIS DISPLAY
MOV #DLIST,D
MAKEPJ D
CLR A
SDLP1: MOV D,DISREL(A)
ADD #2,A
CMP A,#2*NDISP
BLE SDLP1
;AND LAST BUT NOT LEAST
MOV #DISREL,NGREL
RTS PC
;MOVE FROM CURX,CURY TO POINT IN FA,FB
MOVETO: JSR PC,ROUND
STF FA,FC ;SAVE NEW POINT FOR A MOMENT
STF FB,FD
SUBF CURX,FA ;DX
SUBF CURY,FB ;DY
STF FC,CURX ;UPDATE CURX, CURY TO NEW POINT
STF FD,CURY
STCFI FA,D ;PUT DX IN D
STCFI FB,E ;PUT DY IN E
BNE MTO.1 ;CHECK FOR DX=DY=0
TST D
BEQ MTO.R ;JUST RETURN
MTO.1: BIT #PENUF,DFLAGS ;IS PEN UP?
BNE MTO.PU ;YES
;THE PEN IS DOWN
JSR PC,XYDIR ;CALCULATE DIREC
JSR PC,DR.LIN ;AND DRAW LINE!!
MTO.R: RTS PC
;THE PEN IS UP
;PUT ADDX AND ADDY COMMANDS INTO DISPLAY LIST
;HAVE TO EXPAND STATIC AREA AND PUT IN ADD COMMANDS
MTO.PU: MTO.AD: MOV #STT,A
JSR PC,STXPND ;STATIC AREA EXPAND
MTO.RM: MOV A,STT ;A WAS SET IN STXPND
MOV #DSTOP,(A) ;DISPLAY JUMP TO TURTLE
MTO.R1: 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
RTS PC
;ROUNDS FA AND FB
ROUND: ADDF #40000,FA ;FA <- FA + 1/2
STCFI FA,-(P) ;INTEGERIZE FA
LDCIF (P)+,FA ;FA <- INTEGER (FA)
CFCC ;IS FA > 0?
BGE .+6 ;YES
SUBF #40200,FA ;FA <- FA - 1 (TO ROUND AWAY FROM 0)
ADDF #40000,FB ;REPEAT SAME PROCESS FOR FB
STCFI FB,-(P)
LDCIF (P)+,FB
CFCC
BGE .+6
SUBF #40200,FB
RTS PC
;CHECK THE NUMBER IN FD.
; SEZ IF IN BOUNDS. CLZ IF OUT OF BOUNDS
CHKBND: ABSF FD
CMPF WALLT,FD
CFCC
BLT ERROOB ;YES, ERROR
CBRND: SEZ
RTS PC
ERROOB: CLZ
RTS PC
;STATIC AREA EXPAND.
; IS THERE ROOM IN STATIC AREA FOR 2 DISPLAY WORDS?
; RETURN POINTER TO NEW STATIC TOP IN A
STXPND: MOV (A),A ;ROUTINE IS CALLED WITH ADDRESS OF VARIABLE
CMP (A)+,(A)+ ;A _ A+4
CMP A,DYB ;COMPARE A WITH DYNAMIC BOTTOM
BLO STXPN8 ;THERE'S ROOM!
BPT
STXPN8: RTS PC
;SIN AND COSINE FUNCTIONS
SINDEG: MOV #-1,A
BR TRIG
COSDEG: MOV #1,A
TRIG: MOV #1,B
TSTF FA
CFCC
BGE TRIG1
NEGF FA
MUL A,B
TRIG1: DIVF #41464,FA ;DIVIDE BY 45
MODD #40200,FA ;SEPERATE FRACTION AND INTEGER
MODD #37400,FB
MULF #41000,FB ;MOD 8
STCFI FB,C
ASL C
ADD C,PC
BR .TRIG0
BR .TRIG1
BR .TRIG2
BR .TRIG3
BR .TRIG4
BR .TRIG5
BR .TRIG6
MUL A,B
BR .TRIG7
.TRIG6: MUL A,B
NEG A
BR .TRIG0
.TRIG4: NEG B
BR .TRIG0
.TRIG3: NEG B
MUL A,B
BR .TRIG7
.TRIG2: NEG A
MUL A,B
BR .TRIG0
.TRIG5: NEG B
.TRIG1: NEG A
.TRIG7: SUBF #40200,FA ;WE WANT 45 - ANGLE
NEGF FA
.TRIG0: MULF PI,FA
MULF #37600,FA ;CONVERT FROM DEGREES TO RADIANS
LDD FA,FD
MULF FD,FD
NEGF FD ;-ANGLE SQUARED INTO FD
LDCFD #40200,FB ;COUNTING CONSTANT "1"
STF FB,FF
TST A
BLT .TRIG9 ;WE WANT SIN
LDD FB,FA
CLRF FB
.TRIG9: LDD FA,FC
TSTF FD
CFCC
BEQ TRIG11
TRIG10: ADDF FF,FB
DIVF FB,FC
ADDF FF,FB
DIVF FB,FC
MULF FD,FC
ADDF FC,FA
CMPF #41100,FB
CFCC
BGE TRIG10
TRIG11: TST B
BGE .+4
NEGF FA
RTS PC
;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
;HERE START THE LINE 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: JSR PC,DR.STUP ;SET A=CON, B=AC.
ADD STT,D ;D = HOW MANY MORE WORDS IN DLIST
CMP D,DYB ;COMPARE TO DY BOTTOM
BLO DR.L1 ;THERE'S ROOM
BPT
;OKAY, THERE WAS ROOM FOR THE LINE
DR.L1: MOV D,STT ;SET STT TO NEW STATIC TOP
MOV #DSTOP,(D) ;PUT PUSHJ TURTLE AT TOP
JSR PC,DR.ASC ;ASSEMBLE THE DISPLAY CODE
RTS PC ;RETURN
;SET UP CON AND AC
; CALL WITH D,E = + OR - DX OR DY
; PASSES ON A=FRACTION: MIN (DX/DY,DY/DX)
; B=ACCUMULATED FRACTION PART SIDEWAYS OF MAIN DIRECT.
; STARTS AT 1/2
DR.STUP: 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:
CLR B ;CLEAR LOW WORD OF WHICHEVER NUMBER
CMP D,E
BGT DR.DBG ;D IS BIGGER
BEQ DR.EQ ;THEY ARE THE SAME SIZE
;OTHERWISE, E IS BIGGER
ASL E ;SO EAE WON'T OVERFLOW WITH A 16 BIT QUOTIENT
MOV D,A ;DIVIDE D,,0 BY E
DIV E,A
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: ASL D
MOV E,A ;DIVIDE E,,0 BY D
DIV D,A
MOV D,F ;NUMBER OF INCS
;NOW PICK UP THE QUOTIENT
DR.SC4:
ASL A ;MAKE QUOTIENT 16 BITS
ASR F ;SINCE WE DOUBLED IT ABOVE
;NOW SET AC = .1000 = 1/2 IN THIS REPRESENTATION
DR.SC5: MOV #100000,B
;FALLS IN!
;CALCULATE THE NEW END POINT OF THE DLIST
; RETURNS A AND B AS ABOVE
; C = BIT-POSITION OF LAST BIT OF NEW CODE
; (GENERATED BACKWARDS--STORE FROM HERE BACK)
; D = NUMBER OF MORE WORDS IN DLIST
; (WILL BECOME ADDR OF LAST NEW WORD + 2)
; E = TOP BYTE OF INCR INSTRUCTION, SWAPPED
; F = # NEW INCREMENTS
DR.NEP: CLR C ;CLEAR BIT-POSITION
MOV F,E ;GET # OF INCREMENTS
MOV E,D
ASH #-3,D ;DIVIDE BY 8
ASL D
BIC #177770,E ;REMAINDER IS # BITS IN LAST WORD
BEQ DR.NE2 ;IF 0 THEN = 8 IN PREVIOUS WORD
TST (D)+ ;ADD ONE-WORD FUDGE FACTOR IN THIS CASE
SPUSH E
SEC
DR.NE1: RORB C ;SHIFT FIRST-BIT IN OR RIGHT ONE BIT
DEC E ;SHIFT IT RIGHT (REMAINDER) PLACES
BNE DR.NE1
SPOP E
BR DR.NE3
;REMAINDER WAS 0: LAST WORD GETS FILLED UP
DR.NE2: INC C ;LAST BIT IS LAST IN WORD
DR.NE3: ADD #DINC_-8,E ;PUT IN "INCREMENT" CODE
ADD DIREC,E ;ADD IN THE DIRECTION
RTS PC
;ACTUALLY ASSEMBLE THE NEW DISPLAY LIST
; CALL WITH A=SIDEWAYS/FORWARD, B=1/2 (ACCUM SIDEWAYS),
; C=FIRST BIT POS., D=POINTER TO FIRST WORD TO STORE 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
CLC
ROLB C ;SHIFT BYCNT
BCC DR.AS0 ;CONTINUE WITH THIS WORD
;THIS WORD DONE
JSR PC,DR.SH
MOV E,-(D) ;STORE IN DLIST
BIC #3777,E ;0 THE COUNT AND BOTTOM BYTE
MOV #1,C ;RESET BYCNT
BR DR.AS0
;ALL THAT'S LEFT TO DO IS STORE THE BOTTOM WORD OF NEW DLIST
DR.ALW: MOV -(D),B ;GET WORD TO HOOK
CLR A ;SET UP BIT TO HOOK FROM
SEC ; "
DR.LW1: ROL A ; " OR NEXT BIT TO HOOK FROM
CLC
ROLB C ;NEXT BIT TO HOOK INTO
BCS DR.LW2 ;DONE HOOKING
BIT A,B ;GET BIT
BEQ DR.LWX
ADD C,E ;STORE IT
DR.LWX: CLC ;SET UP FOR ROL A
BR DR.LW1
DR.LW2: JSR PC,DR.SH ;SHOVE TO RIGHT END OF WORD
MOV E,(D) ;STORE LAST WORD
RTS PC
;SHIFT CODE RIGHT 8 MINUS COUNT TIMES
DR.SH: SPUSH E
SWAB E ;GET COUNT OF USED BITS
DR.SH1: BIC #177770,E ;ISOLATE COUNT
BEQ DR.SH2 ;DONE
INC E ;COUNT UP; DONE AT 8 (OR 0)
CLC
RORB (SP) ;MAKE ANOTHER FREE BIT AT LEFT
BR DR.SH1
DR.SH2: SPOP E
RTS PC
.STITL DISPLAY BUFFERS
DISREL: REPT1 8,DSTOP ;FIRST WORD OF EACH DISPLAY
DISPDL: .BLKW 8 ;PDL POINTERS
DPDL: .BLKW <2*DPDLL>*<NDISP+1> ;PDL AREA FOR OUR DISPLAYS
;DISPLAY LISTS FOR DIGITS
DIG.0: 145775
150017
55400
70400
55000
70400
54400
71000
54400
71000
64401
72004
40400
71000
40400
70400
41000
70400
40000
42400
44400
40400
45406
40400
47400
54400
44400
51003
54400
44400
54000
55000
150013
144003
DPOPJ
DIG.1: 150001
144010
45407
54000
54000
57000
72000
44000
44400
150013
144013
DPOPJ
DIG.2: 150000
144004
41400
44400
40400
44400
40400
44400
40400
45400
40400
44400
54400
45400
54400
44400
54400
44400
54400
44400
57000
64377
66437
44000
46400
150011
144014
DPOPJ
DIG.3: 150004
145775
55400
44400
54400
44400
54400
44400
54400
45400
54400
44400
40400
45400
40400
44400
40400
44400
40400
44400
41400
72425
46425
42400
70400
40400
70400
40400
73400
5440
70400
64401
54400
70400
55000
70400
150025
145772
DPOPJ
DIG.4: 150014
144014
54000
54000
40000
42000
47000
70000
70000
71000
40255
41001
150030
145766
DPOPJ
DIG.5: 144013
44000
45400
70000
71400
54000
55400
40400
44100
54400
44400
54400
44400
54400
44400
57000
70400
55000
71000
54400
71000
54400
71400
40400
71000
40400
70400
40400
70400
41000
150027
144005
DPOPJ
DIG.6: 150014
144007
41000
70401
40400
70400
40400
73020
64401
70400
54400
70400
54400
64401
54000
56400
44400
55000
44400
54400
45000
54400
46000
40400
45000
40400
44400
41000
44400
42000
70401
40400
70400
40400
73020
64401
70400
54400
70400
54400
64401
55000
150023
144004
DPOPJ
DIG.7: 150000
144011
41400
44000
44000
60125
60112
63052
150027
144013
DPOPJ
DIG.8: 144001
150005
45000
40400
45000
41000
44400
42000
70400
41000
71000
40400
72000
54400
71000
55000
70400
56000
44400
55000
45000
54400
46000
54400
45400
56000
44400
54400
70400
55400
70400
54400
71000
54400
72000
40400
71000
40400
70400
40000
45400
40400
45000
150012
144000
DPOPJ
DIG.9: 144006
150011
41400
70400
40400
70400
40400
70400
40400
73000
55000
71000
54400
70400
56400
44400
55000
45000
54400
44400
54400
46000
40400
45000
40400
44400
40400
44400
41400
60104
60210
61002
150017
144016
DPOPJ
DLIST: DSTOP ;THE START OF THE DISPLAY LIST
.=.+6000
DISEND:
PATCH:
PAT:
.END START