diff --git a/build/misc.tcl b/build/misc.tcl index 512d1d29..b2926770 100644 --- a/build/misc.tcl +++ b/build/misc.tcl @@ -572,6 +572,14 @@ respond "designs" "\r" respond "suns" "\r" expect ":KILL" +# PDP-6/10 Dazzle Dart +respond "*" ":midas games;ts dazdrt_klh; dazdrt\r" +respond "Run under ITS?" "YES\r" +expect ":KILL" +respond "*" ":midas;324 dsk0:.;@ dazdrt_klh; dazdrt\r" +respond "Run under ITS?" "NO\r" +expect ":KILL" + # Dazzle Dart, video game for the Logo group PDP-11/45 respond "*" ":palx bs;_dazzle\r" expect ":KILL" diff --git a/src/klh/dazdrt.122 b/src/klh/dazdrt.122 new file mode 100644 index 00000000..828b7423 --- /dev/null +++ b/src/klh/dazdrt.122 @@ -0,0 +1,1987 @@ + title dazdrt + subttl Accumulator Definitions and Assembly Parameters + .mllit==1 + + f=0 ;flag register + a=1 + b=2 + c=3 + d=4 + e=5 + t=6 ;temps + tt=7 + pwb=10 ;index to player with beam (always !!!!) + plr=11 ;player index (random) + + DP=14 ;DISP BLKO PTR + DL=15 ;DISP LIST PTR + ia=16 ;APR interrupt acc + p=17 ;pdl acc + + nplyrs==4 ;# of players + + +DEFINE SETF TEXT,FLG ;useful set-flag macro! +IFDEF FLG,.STOP +.TAG FOOBAR +PRINTC "TEXT +FLG=" +.TTYMAC FLAG +IFSE FLAG,YES,FLG==1 +IFSE FLAG,NO,FLG==0 +IFSE FLAG,Y,FLG==1 +IFSE FLAG,N,FLG==0 +IFNDEF FLG,FLG==FLAG +TERMIN +IFNDEF FLG,.GO FOOBAR +TERMIN + + SETF [Run under ITS?]$ITS + + subttl Processor state definitions +;---------- bit definitions ------------------- +;produces BIT2.3, BIT35 type defs +radix 10. +define bitdef a,b,c +bit!a!.!b==1_<*9.+> +bit!c==1_<35.-c> +termin +%%3==-1 +repeat 4,[%%1==.rpcnt+1 ? repeat 9.,[%%2==.rpcnt+1 ? %%3==%%3+1 +bitdef \%%1,\%%2,\%%3 +]] +radix 8. + +; ------ PDP-6 APR condition flags +;CONO + A%rpov==bit18 ;reset the PDL OV flag + A%rio== bit19 ;I/O reset + A%rmp== bit22 ;reset the Memory Protection flag + A%rnxm==bit23 ;reset the nonexistent Memory flag + A%ccez==bit24 ;turn the Clock Count Enable flag off + A%cceo==bit25 ;turn the Clock Count Enable flag on + A%clkz==bit26 ;turn the Clock flag off + A%pcez==bit27 ;turn the PC Change Enable flag off + A%pceo==bit28 ;turn the PC Change Enable flag on + A%pcfz==bit29 ;turn the PC Change flag off + A%ovez==bit30 ;turn the OV flag enable off + A%oveo==bit31 ;turn the OV flag enable on + A%ovfz==bit32 ;turn the OV flag off + ;33-35 = assign PI channel to APR flags (listed above) + ;define name to reset/clear all flags and i/o + a%STRT==a%RPOV+a%RIO+a%RMP+a%RNXM+a%CCEZ+a%CLKZ+a%PCEZ+a%PCFZ+a%OVEZ+a%OVFZ +;CONI + A%pov== bit18 ;PDL OV flag set + A%ilop==bit22 ;Illegal Instruction flag set + A%nxm== bit23 ;non-existent Memory flag set + A%cce== bit25 ;Clock Count enable on + A%clk== bit26 ;Clock Count flag set + A%pce== bit28 ;PC Change enable on + A%pcf== bit29 ;PC Change flag set + A%ove== bit31 ;OV enable on + A%ovf== bit32 ;OV flag set + ;33-35 = set to the current PI channel assignment + + +;-------- PDP-6 Priority Interrupt system flags +;CONO + P%clr== bit23 ;clear the PI system + P%act== bit24 ;activate interrupt on channels selected (29-35) + P%cenb==bit25 ;enable channels selected (") + P%cdsb==bit26 ;disable channels selected (") + P%off== bit27 ;turn off the PI system + P%on== bit28 ;turn on the PI system + ;29-35 = channel select: bit 29 selects channel 1, + ; bit 35 selects channel 7, etc. +;CONI + P%piup==bit28 ;PI system is on + ;29-35 = if a bit is 1, corresponding channel is on. + +;---------- 340 display flags +;CONO + D%init==bit1.7 ;initialize display + D%cont==bit1.8 ;resume display after special interrupt + + +;---------- Flag register (F) + + %pfneg==bit1.1 ;for PFDVR,PFMPR etc + %m1inf==bit1.2 ;for intrsc routine + %m2inf==bit1.3 ; " + %zfire==bit1.4 ;set when beam being zapped + %lnchk==bit1.5 + %dexch==bit1.6 ;for drwlin routine + %rstrt==bit1.7 ;indicates restart from lossage, dont reset scores + +;--------------------------------------------- + +aprchn==4 ;processor has highest priority pi channel +dspchn==5 ;special interrupt channel for display +dischn==6 ;normal 'done' channel for display +imxchn==7 ;IMX data channel (pots) +imx==574 +..d574==574 + +aprpic==1_<7-APRCHN> ;channels as represented in PI condition word +dsppic==1_<7-DSPCHN> +dispic==1_<7-DISCHN> + +IFE $ITS,[ +loc aprchn*2+40 + jsr aprbrk ;processor (clock) interrupt vector +loc dspchn*2+40 + jsr dspbrk ;special interrupt on display +loc dischn*2+40 + blko dis,DP ;display output instr for PI system + jsr disbrk ;int vector when BLKO done +] +IFN $ITS,[ +LOC 42 + JSR TSINT +] + +loc 100 + trza f,%rstrt ;set that this is not a restart + tro f,%rstrt ; if started at 10, this is a restart + jrst go + +patch: block 100 + +pdllen==20 +pdl: -pdllen,,pdl + block pdllen + +cpie==3.1415926535 +cpie.5==1.5707963 +cpi1.5==4.7123889 +PIE: 3.1415926535 +PI$2: 6.2831853072 +PI.5: 1.5707963 + + + subttl Macro definitions +maxflo: 377777,,-1 ;maximum floating point value +JOV= ;jump on overflow + +DEFINE PFMPR ac,loc + jov .+1 + fmpr ac,loc + jov [caige ac,0 + troa f,%pfneg + trz f,%pfneg + movm ac,ac + caml ac,[177400,,0] + jrst [setz ac, ? jrst .+1] + move ac,maxflo + trze f,%pfneg + movn ac,ac ? jrst .+1] +TERMIN + +DEFINE PFDVR ac,loc + jov .+1 + skipn loc + jrst [cail ac,0 + skipa ac,maxflo + movn ac,maxflo ? jrst .+3] + fdvr ac,loc + jov [caige ac,0 + troa f,%pfneg + trz f,%pfneg + movm ac,ac + caml ac,[201400,,0] + jrst [setz ac, ? jrst .+1] + move ac,maxflo + trze f,%pfneg + movn ac,ac ? jrst .+1] +TERMIN + +DEFINE PFADR ac,loc + jov .+1 + fadr ac,loc + jov [cail ac,0 + skipa ac,maxflo + movn ac,maxflo + jrst .+1] +TERMIN +;find intersection of lines specified and leave xi,yi in a,b +;xi= (b1-b2)/(m2-m1) +;yi= m1*xi+b1 + +;where b=y-mx + +slplim: 1.0^30 ;criterion for 'infinite'; maxflo is approx 1.E38 + +DEFINE INTRSC DM1,DX1,DY1,DM2,DX2,DY2 + move a,DM1 + movem a,m1 + move a,dx1 + movem a,x1 + move a,dy1 + movem a,y1 + move a,dm2 + movem a,m2 + move a,dx2 + movem a,x2 + move a,dy2 + movem a,y2 + pushj p,intcal +TERMIN + +x1: 0 +y1: 0 +m1: 0 +x2: 0 +y2: 0 +m2: 0 + +intcal: push p,c + push p,d + push p,e + trz f,%m1inf+%m2inf + + movm c,M1 + caml c,slplim + troa f,%m1inf + jrst [movn c,M1 + fmpr c,X1 + fadr c,Y1 ;B1=Y1-M1X1 + jrst .+1] + movm d,M2 + caml d,slplim + troa f,%m2inf + jrst [movn d,M2 + fmpr d,X2 + fadr d,Y2 ;B2=Y2-M2X2 + jrst .+1] + + move b,M1 + move e,b + fsbr b,M2 ;M1-M2 + ;(b)=M1-M2 (c)=B1 (d)=B2 (e)=M1 + trnn f,%m1inf+%m2inf ;either infinite? + jrst intrs2 ;no, normal crunching. + setz a, + trne f,%m1inf + jrst [trne f,%m2inf ;1st infinite, 2nd also? + jrst intrs9 ;yes, no intersection + move a,X1 + move b,M2 + fmpr b,X1 + fadr b,d ;Y=B2+M2*X1 +; move b,d ;X=X1, Y=B2 if M1 infinite + jrst intrs7] + move a,X2 + move b,X2 + fmpr b,M1 + fadr b,c +; move b,c ;X=X2, Y=B1 if M2 infinite + jrst intrs7 + +intrs2: jumpe b,intrs9 ;if M1-M2 then lines parallel + move a,d + fsbr a,c ;(B2-B1) + PFDVR a,b ;(B2-B1)/(M1-M2) = X + move b,a + PFMPR b,e ;X*M1 + fadr b,c ;X*M1+B1 = Y + +intrs7: pop p,e + pop p,d + pop p,c + aos (p) + popj p, +intrs9: pop p,e + pop p,d + pop p,c + popj p, + + + +define conc a,b +a!b!termin + +define ssfix a,b + muli a,400 + tsc a,a + ash a+1,-243+19.!b(a) +termin + +;floating to integer conversion -- works for pos/neg +define ifix a + push p,a+1 + ssfix a,-19. + move a,a+1 + pop p,a+1 +termin + +;floating to fractional integer conversion; integer in LH, fraction in RH +define frifix a + push p,a+1 + ssfix a,-1 + move a,a+1 + pop p,a+1 +termin + + subttl interrupt handlers +IFE $ITS,[ +;processor interrupt handler +aprbrk: 0 + coni apr,ia ;get apr conditions into interrupt acc + trnn ia,A%clk ;clock interrupt? + jrst aprbr2 ;no, don't do clock hackery...go check for bad news + + ;clock interrupt + sosle clkcnt ;count off one tick + jrst aprbr1 ;and don't unset lock if haven't finished countdown + setom clksnk ;ah! unset synchronization lock + move ia,steptm ;get # tics per game step + movem ia,clkcnt ;and reset count. +aprbr1: cono apr,a%cceo+A%clkz+aprchn ;turn off clock flag and make sure enabled + jrst 12,@aprbrk ;and dismiss interrupt + +aprbr2: movem ia,aprcns + jsr death ;for time being, all non-clock ints are no-no's... +] + +aprcns: 0 ;apr conditions if die +steptm: 1 ;duration of a game step in ticks (1 tick= 1/60 sec) +clkcnt: 0 ;tick countdown; when steptm ticks done, setom cklsnk. +clksnk: 0 ;synch lock; each game step must wait until set to -1 + +DDT==34000 ;SA of DDT when present in 6. +death: 0 ;JSR'd here so can tell where came from. + jrst 4,DDT ;stop with PC->DDT so 'continue' gets DDT + +IFN $ITS,[ +TSINT: 0 + 0 + SKIPGE IA,TSINT + .DISMIS TSINT+1 + TLNN IA,200000 + .DISMIS TSINT+1 + SETOM CLKSNK + .SUSET [.SAMASK,,[200000,,0]] + .DISMIS TSINT+1 +] + + +IFE $ITS,[ +DISBRK: 0 +DISBR0: TRNN DL,-1 ;ADDR OF NEXT ITEM IN RH? + MOVE DL,DISLST ;NO, GET PTR TO BEG OF CURRENT DISLIST + MOVE DL,(DL) ;GET ITEM + HLRZ DP,DL ;GET ADDR OF BLKO PTR FOR ITEM + JUMPE DP,DISBR0 ;NOTHING THERE, GET NEXT ITEM + SKIPL DP,(DP) ;GET BLKO PTR + JRST DISBR0 ;AGAIN NOTHING THERE, GET NEXT. + JRST 12,@DISBRK ;RETURN + + +DSPBRK: 0 ;SPECIAL DISPLAY INTERRUPT +; HLRZ DP,DL ;GET ADDR OF BLKO THAT INTERRUPTED +; CAIN DP,BKPT1 ;IF WAS DOING FIRST BACKGROUND, +; MOVE DL,(DL) ;SKIP NEXT (2ND BACKGND) ITEM. +DSPBR1: TRNN DL,-1 + MOVE DL,DISLST + MOVE DL,(DL) + HLRZ DP,DL + JUMPE DP,DSPBR1 + SKIPL DP,(DP) + JRST DSPBR1 + CONO DIS,D%INIT+DSPCHN_3+DISCHN + JRST 12,@DSPBRK ;RETURN + +DEFINE DSTART +MOVE DL,DISLST +MOVE DP,[-1,,[0]-1] +CONO DIS,D%INIT++DISCHN +TERMIN +] + +IFN $ITS,[ +DEFINE DSTART +.DSTART DISLST +.VALUE [ASCIZ /:DISPLAY NOT AVAIL +/] +TERMIN +] + +vbfend: pushj p,disran ;display random stuffs + MOVE B,VDSW + move t,vdlipt ;get addr to end of vlist currently being written + SETZm a,(t) ;terminate vlist + HRRZ T,T + HRRZ A,VDCUR + SUB T,A + CAIGE T, + SETZ T, + MOVN T,T + HRLZ T,T + HRR T,VDCUR + MOVEM T,VDPTR+1(B) + MOVEI A,DSTL+1(B) + MOVEM A,DISLST + SETCAB B,VDSW + MOVE A,VDPTAB+1(B) + MOVEM A,VDCUR + ADDI A,1 + HRRZM A,VDLIPT + POPJ P, + + + subttl main program + ;one time initialization +go: move p,pdl +IFE $ITS,[ + cono apr,a%STRT+aprchn ;clear all APR flags and i/o + cono apr,a%cceo+aprchn ;enable clock ints + cono 420,40 ;enable 36-bit input array + CONO DIS,D%INIT + cono pi,p%clr+p%cenb+p%on+aprpic+dispic+dsppic ;PI reset+assignments +] +IFN $ITS,[ + MOVE A,[600000,,STEPTM] + .REALT A, + JFCL + .SUSET [.SMASK,,[200000,,0]] + .SUSET [.SPICLR,,[-1]] + .OPEN IMXCHN,[.BII,,'IMX] + .VALUE [ASCIZ /: OPEN OF IMX FAILED?  +/] +] + + ;series initialization +series: pushj p,bsetup ;set up board if necessary +IFE $ITS,[ + cono dis,d%init ;reset/initialize display +] + + movsi plr,-nplyrs +ser1: setzm plscor(plr) ;whatever. + move a,splen ;standard player length + movem a,plen(plr) + fmpr a,a + movem a,plensq(plr) + aobjn plr,ser1 + trne f,%rstrt + jrst game ; if this is restart, don't zero the scores + setzm tmscor ;zero scores + setzm tmscor+1 + + ;game initialization +game: setzm f + pushj p,zassgn ;decide which player gets beam (initialize PWB) + move a,ztime + movem a,ztmlft + imuli a,60. + movem a,ztim60 + setzm a,passtm ;make sure pass timer is zero + movsi plr,-nplyrs +game1: move a,pinitx(plr) + movem a,plocx(plr) + move a,pinity(plr) + movem a,plocy(plr) + move a,pinita(plr) + movem a,plang(plr) + setzm input(plr) + pushj p,updat + pushj p,plrdis ;update player (plr) and display him + aobjn plr,game1 + +; movei a,dlstrt-1 ;set up blko ptr +; movem a,disptr +; setzm vdlflg +; setzm vdlloc +; setom vdlapr + + MOVE B,VDSW + HRRZ a,VDPTAB+1(B) + MOVEM A,VDCUR + ADDI A,1 + movem a,vdlipt + MOVE A,DBDPT + MOVEM A,BDPT + MOVEI A,DSTL3 + MOVEM A,DISLST + DSTART +; cono dis,d%init+dischn+dspchn_3 ;start display with PI assigned + + subttl main processing loop + +gamlup: pushj p,vbfend ;switch var. display buffers + aose clksnk ;wait for clock synch +IFE $ITS,[ + jrst .-1 + datai a ;for DDT hacking in the 6 + trze a,1 +break: jfcl +] +IFN $ITS,[ + .HANG + MOVE A,[-2,,[.SPIRQC,,[0] ? .SIMASK,,[200000,,0]]] + .SUSET A +] + + pushj p,inpget ;get inputs for all players + + movsi plr,-nplyrs + pushj p,updat + aobjn plr,.-1 + + setcmm ransw' + move a,ztim60 ;beam-possession time left in 60th's + sub a,steptm + jumpge a,gamlp0 + movsi a,-nplyrs +gaml01: move b,tmon(a) + camn b,tmon(pwb) + aobjn a,gaml01 + skipe ransw + addi a,1 + movei pwb,(a) + setzm passtm;when beam changes hands, pass timer is 0 + move a,ztime + imuli a,60. +gamlp0: movem a,ztim60 + addi a,59. + idivi a,60. + movem a,ztmlft ;time left in seconds + + move a,pwb ;get index to player with beam * 4 + ash a,2 + + skipg b,passtm ;has the passing timer run out yet? + jrst tstpas + sub b,steptm ;subtract the number of 60ths gone by from it + movem b,passtm + jrst tstfir +tstpas: skipl inval+fire(a) ;is he passing beam? + jrst tstfir + move pwb,tmmate(pwb) ;if so, transfer. + move b,paslim ; set pass timer going + movem b,passtm + +tstfir: move a,pwb ;note that pwb may have changed...this is the idea. + ash a,2 + skiple inval+fire(a) ;is PWB firing? + troa f,%zfire ;yes, set global flag and skip + trz f,%zfire ;clear flag otherwise + + movsi plr,-nplyrs +gamlp1: pushj p,plrdis ;display new position etc. + aobjn plr,gamlp1 + + trnn f,%zfire ;now see if beam was fired + jrst gamlup ;nope, just loop back and wait. + +;aha! if skipped over to here, means must compute beam path! +;first must initialize beam variables + + setzm zbounc ;# of bounces + move a,plang(pwb) ;angle of beam + fadr a,pi.5 ;get angle+90 deg + caml a,pi$2 ;normalize + fsbr a,pi$2 + movem a,zangle + move a,plsin(pwb) + movnm a,zcos ;cos (ang+90)= -sin (ang) + move a,plcos(pwb) + movem a,zsin ;sin (ang+90)= cos(ang) + move a,plocx(pwb) + movem a,zstrtx + move a,plocy(pwb) + movem a,zstrty + move a,zsin + PFDVR a,zcos ;find (possibly infinite) slope + movem a,zslope + movem pwb,zfrom ;indicate which player beam coming from + trz f,%lnchk ;clear check-boundary-lines flag. + + ;loops once for each straight line path +zlup: movsi plr,-nplyrs +zlup0: setom zbestd + setom zbestp ;clear locs which save closest termination of this path + + ;loops thru each player seeing if this path hits anyone +zlup1: hrrz a,plr ;get # of player being checked + camn a,zfrom ;same as player beam is coming from? + jrst zlup50 ;yep, don't check this one. + + intrsc zslope,zstrtx,zstrty,plslop(plr),plocx(plr),plocy(plr) + jrst zlup50 ;no skip if no intersection + + trne f,%lnchk + jrst zlup2 ;skip within-ness check if doing boundaries + caml a,blowx ;check if intersection within board limits + camle a,bhighx + jrst zlup50 ;out-of-bounds + caml b,blowy + camle b,bhighy + jrst zlup50 ;out + +zlup2: pushj p,angchk + jrst zlup50 ;not pointing in right direction + + trne f,%lnchk + jrst zlup25 ;skip hit-it check if doing boundaries + move c,plocx(plr) ;see if intersction is close enough to player to hit him + move d,plocy(plr) ;set up to find dist + pushj p,distsq ;leave result in c + camle c,plensq(plr) ;compare with player radius squared + jrst zlup50 ;no skip=nope + +zlup25: move c,zstrtx ;find distance from start of this path to the intersection. + move d,zstrty + pushj p,distsq ;find distance (squared) in c + skipge zbestd ;have any hits already? + jrst zlup3 ;nope, skip the closeness check + caml c,zbestd ;see if it's any closer than closest so far + jrst zlup50 ;nope, forget about it + +zlup3: movem c,zbestd ;ah! closer...store its vars + movem a,zbestx + movem b,zbesty + hrrzm plr,zbestp + +zlup50: aobjn plr,zlup1 ;loop on thru players + skipge plr,zbestp ;found any hits? + jrst [troe f,%lnchk ;nope, go check board boundaries. + jsr death ;couldn't find boundary hit + move plr,[-4,,nplyrs] + jrst zlup0] + trne f,%lnchk + jrst zlup90 ;boundary hit! + ;found a solid hit on a player. now must bounce it off. + move a,zstrtx ;draw line from starting pt + move b,zstrty + move c,zbestx ;to bounce pt + move d,zbesty + pushj p,drwlin ;do it + + aos a,zbounc ;increment bounce cnt + hrrzm plr,zbnclt-1(a) ;record the player bounced off of + cail a,zmaxbc ;skip if not yet reached max # bounces. + jrst [move pwb,zbestp ;ah! beam ownership transfers! + setzm passtm ;zero the pass timer + move a,ztime ;but start a new ownership timout + movem a,ztmlft + imuli a,60. + movem a,ztim60 + jrst gamlup] + movem c,zstrtx ;else do again, relative to new starting place + movem d,zstrty + pushj p,reflct ;find reflected angle of beam + movem a,zangle ;store + push p,a + pushj p,cos ;now get vars related to angle.(sin,cos,tan) + movem a,zcos + pop p,a + pushj p,sin + movem a,zsin + PFDVR a,zcos + movem a,zslope + hrrzm plr,zfrom + jrst zlup ;now do another straight beam path.... + + ;boundary hit! +zlup90: move a,zstrtx + move b,zstrty + move c,zbestx + move d,zbesty + pushj p,drwlin ;draw final leg + + ;now determine if hit a goal... + skipg zbounc ;bounced off someone? + jrst gamlup ;no, back to game. + movei plr,-4(plr) ;adjust index (not pointing into player tables now) + skipn bglflg(plr) ;is line a goal line? + jrst gamlup ;nope. loop back + move a,zbestx ;get x coord of hit + camle a,bglow(plr) ;test low value coordinate of boundary + caml a,bghigh(plr) ;test high " + jrst gamlup ;if no hit + + ;aha! hit goal! whoopee etc... + pushj p,goalht ;go do whatever + jrst game ;back to another game + + subttl calculational subroutines + +distsq: push p,d + fsbr c,a + fsbr d,b + fmpr c,c + fmpr d,d + fadr c,d + pop p,d + popj p, + +angchk: push p,c + push p,d + push p,e + push p,t + move c,a ;x coord of hit + move d,b ;y coord of hit + fsbr c,zstrtx ;get coords relative to start of beam + fsbr d,zstrty + movm e,c + movm t,d + camg e,t + jrst [move c,d ? xor c,zsin ? jumpge c,angchw ? jrst angchl] + xor c,zcos + jumpge c,angchw +angchl: pop p,t + pop p,e + pop p,d + pop p,c + popj p, +angchw: pop p,t + pop p,e + pop p,d + pop p,c + aos (p) + popj p, + +reflct: move a,plang(plr) ;get ang2 + fmpr a,[2.0] ;2*ang2 + fsbr a,zangle ;reflected angle = 2*ang2 - ang1 + jumpl a,[fadr a,pi$2 ? popj p,] + caml a,pi$2 + fsbr a,pi$2 + popj p, + + +;FLOATING POINT SINE AND COSINE. REENTERABLE. + +SIND: FMPR A,[.01745329251994] ;PI/180 + JRST SIN + +COSD: FMPR A,[.01745329251994] +COS: FADR A,SC1 ;PI/2 +SIN: CAMG A,SC9 ;.000211431983 IS SUFFICIENT FOR IDENTITY, 10**-15 IS NECESSARY NOT TO UNDERFLOW + CAMGE A,[-.000211431983] ;ABS X MIGHT CAUSE POLYNOMIAL UNDERFLOW + JRST .+2 + POPJ P, ;AND IS SMALL ENOUGH FOR SIN X _ X + FDVR A,SC1 ;PI/2 + PUSH P,A + PUSH P,B + MULI A,400 + TSC A,A ;CAML A,...SETZB B,-1(P) + ASH B,-243(A) + MOVNS A,B + ANDCMI A,1 + TLC A,232000 + FAD A,A + FADRB A,-1(P) + TRNE B,2 + MOVNS A,-1(P) + FMP A,A + MOVE B,SC9 + FMP B,A + FAD B,SC7 + FMP B,A + FAD B,SC5 + FMP B,A + FAD B,SC3 + FMP A,B + FADR A,SC1 + FMPRM A,-1(P) + POP P,B + POP P,A + POPJ P, + +SC1: 1.5707963267 +SC3: -0.64596371106 +SC5: 0.07968967928 +SC7: -0.00467376557 +SC9: 0.00015148419 + CONSTANTS + VARIABLES + + + subttl data bases and constants + +;data base for players +plrbri: 20112 ;poarameter mode haflwds to set brightness and scale +pwbbri: 20114 ;and go into point mode + +pinitd: 150.0 ;initial dist. from center of board (x and y derived from this) + +pinitx: 300.0 ;initial x value for player positions at start of game + 500.0 + 700.0 + 500.0 +pinity: 500.0 ;initial y + 700.0 + 500.0 + 300.0 +pinita: cpie.5 ;initial angle + 0.0 + cpi1.5 + cpie + +input: block nplyrs ;holds inputs for each player during pass +speed: 3.0 ;points/step to move if moving +angrat: .03 ;radians/step to turn if turning +angspd: 4.0 ;factor to scale pot*angrat by when using pots +fuzzm: .3 ;factor for which pots are considered close enough to be zero +fuzzr: .3 ;same thing except for rotation instead of motion +dconst: 1.0 ;value digital inputs are assumed to be +splen: 40.0 ;standard player length on a side +paslim: 60. ;number of 60th's that must go by between passes +passtm: 0 ;timer for above + + +plocx: block nplyrs ; x coord of player + block 4 ;boundary line x coords (kludge) +plocy: block nplyrs ; y coord + block 4 +plang: block nplyrs ;heading angle in radians + block 4 +plsin: block nplyrs ;sin(plang) + block 4 +plcos: block nplyrs ;cos(plang) + block 4 +plslop: block nplyrs ; tan(plang) i.e. slope + block 4 +plen: block nplyrs ;player length + block 4 +plensq: block nplyrs ;player length squared + block 4 +plscor: block nplyrs + +tmmate: 1 ;index of other teammate(s) (circular list if more than 2) + 0 + 3 ;teams are (0,1) and (2,3) + 2 + +tmon: 0 ;team # player is on + 0 + 1 + 1 + +control: ; says whether to get input from A/D pots or bits +play1: 0?0 ? 0?0 ? 0?0 ? .bp 20,input+1?.bp 100,input+1 +play2: 0?0 ? 0?0 ? 0?0 ? .bp 20,input+1?.bp 100,input+1 +play3: 0?0 ? 0?0 ? 0?0 ? .bp 20,input+3?.bp 100,input+3 +play4: 0?0 ? 0?0 ? 0?0 ? .bp 20,input+3?.bp 100,input+3 + +rotright==0 ;symbols defined to make patching control table easy +rotleft==1 +Xright==2 +Xleft==3 +Yup==4 +Ydown==5 +fire==6 +pass==7 + +ltmscr: 0 ;last team that had beam when goal hit. +lglhit: 0 ;last goal hit (team # of) +tmscor: 0 ;score for team 0 (0 and 1) + 0 ;team 1 (2 and 3) + +ztime: 30. ;# of seconds team can possess beam +ztmlft: 0 ;count of seconds left til beam possession lost +ztim60: 0 ;count in 60ths of sec +;boundary lines + +blowx: 0 ;left +bhighx: 0 ;right +blowy: 0 ;bottom +bhighy: 0 ;top + +pbdgap: 2.0 ;boundary-player gap +plowx: 0 ;limits of trvael for players. +plowy: 0 +phighx: 0 +phighy: 0 + +bglflg: 0 ;nonzero if line has a goal on it + 1 + 0 + 1 + +bglow: block 4 ;lower bound of coordinate for goal on line (if any) +bghigh: block 4 ;upper bound " +bgwide: 100.0 ;width of goal + +bdlenx: 700.0 ;width of board (x coord) +bdleny: 900.0 ;height of board (y coord) +bln.5x: 0 ;half bdlenx +bln.5y: 0 ;half bdleny +bdcenx: 0 ;coord of center axis (x) +bdceny: 0 ;coord of center axis (y) + +bprot: 160.0 ;radius of protective shield around goal +bprosq: 0 ;set to square of above + +frztim: 3 ;# seconds to freeze action on beam hit. + +;---------------- +;beam hit variables used while computing beam path +zstrtx: 0 ;start of beam, x coord +zstrty: 0 ;start of beam, y coord +zangle: 0 ;direction of beam in radians +zsin: 0 ;sin(zangle) +zcos: 0 ;cos(zangle) +zslope: 0 ;slope = tan(zangle) +zslopx: 0 ;non-zero if slope infinite +zfrom: 0 ;index of player beam from (via fire or bounce) + +zbestd: 0 ;holds distance to best hit seen so far (closest) +zbestp: 0 ;holds index of player implicated by zbestd +zbestx: 0 ;x coord of best hit +zbesty: 0 ;y coord of best hit +zbounc: 0 ; # times beam has bounced off something so far +zmaxbc==3 ;max # bounces before beam ownership transfers +zbnclt: block zmaxbc ;stores record of players bounced off +zbri: 20113 ;beam brightness/scale, go into point mode + + subttl board setup + +define dline x1,y1,x2,y2 + move a,x1 + move b,y1 + move c,x2 + move d,y2 + pushj p,drwlin +termin + +bsetup: move a,bprot ;get protective-circle radius + fmpr a,a ;square it + movem a,bprosq ;store for use by player updat + move a,splen ;get player length + fadr a,[2.0] ;add 2 units for safety + movem a,blowx ;and use that as lower limit of board + movem a,blowy ;in both directions. + fadr a,pbdgap + movem a,plowx + movem a,plowy +IRP xory,,[x,y] + move b,[1024.0] ;get absolute limit of coord + move c,bdlen!xory ;and desired width + fadr c,a ;adjust out + fsbr b,c ;and check + camle a,b ;skip if enough room + jsr death ;foo. + movem c,bhigh!xory + fsbr c,pbdgap ;spacing + movem c,phigh!xory + move b,bdlen!xory + fmpr b,[0.5] ;find 1/2 length + movem b,bln.5!xory + fadr b,blow!xory + movem b,bdcen!xory ;center of board line +TERMIN + + movei t,3 ;loop 4 times storing line data +bsetp1: cain t,0 + jrst [move a,blowx ? move b,bdceny ? move c,pi.5 ? move d,bdleny ? jrst bset2] + cain t,1 + jrst [move a,bdcenx ? move b,bhighy ? setz c, ? move d,bdlenx ? jrst bset2] + cain t,2 + jrst [move a,bhighx ? move b,bdceny ? move c,pi.5 ? move d,bdleny ? jrst bset2] + cain t,3 + jrst [move a,bdcenx ? move b,blowy ? setz c, ? move d,bdlenx ? jrst bset2] +bset2: movem a,plocx+nplyrs(t) + movem b,plocy+nplyrs(t) + movem c,plang+nplyrs(t) + movem d,plen+nplyrs(t) + fmpr d,d + movem d,plensq+nplyrs(t) + move a,c ;setup for trig stuff + pushj p,cos + movem a,plcos+nplyrs(t) + move a,c + pushj p,sin + movem a,plsin+nplyrs(t) + PFDVR a,plcos+nplyrs(t) ;find tan + movem a,plslop+nplyrs(t) + sojge t,bsetp1 + + ;initialize player positions + movei c,3 ;loop thru players +bset3: move a,bdcenx + move b,bdceny ;coords of center of board + cain c,0 + fsbr a,pinitd + cain c,1 + fadr b,pinitd + cain c,2 + fadr a,pinitd + cain c,3 + fsbr b,pinitd + movem a,pinitx(c) + movem b,pinity(c) + sojge c,bset3 + + ;find where to start number display + move a,bhighx + fadr a,[80.0] + movem a,dtx + movem a,dtx+1 + movem a,dtx+2 + move b,bdceny + movem b,dty+1 ;timeout cntr + fadr b,[200.0] + movem b,dty ;score, team 0 + fsbr b,[400.0] + movem b,dty+2 ;score, team 1 + + move a,bgwide ;find desired goal width + fmpr a,[0.5] ;divide + move b,bdcenx ;center of board down middle + fsbr b,a + movem b,bglow+1 + movem b,bglow+3 + move b,bdcenx + fadr b,a + movem b,bghigh+1 + movem b,bghigh+3 + + push p,vdlipt ;save deposit ptr + movei a,dlstrt ;start board here + movem a,vdlipt + move a,bdbri ;get board brightness, scale + movem a,@vdlipt + aos vdlipt + + dline blowx,blowy,blowx,bhighy + dline blowx,bhighy,bhighx,bhighy + dline bhighx,bhighy,bhighx,blowy + dline bhighx,blowy,blowx,blowy + + move a,blowy + fsbr a,bgldep ;goal depth + movem a,glowy + move a,bhighy + fadr a,bgldep + movem a,ghighy + + dline bglow+1,bhighy,bglow+1,ghighy + dline bglow+1,ghighy,bghigh+1,ghighy + dline bghigh+1,ghighy,bghigh+1,bhighy + + dline bglow+3,blowy,bglow+3,glowy + dline bglow+3,glowy,bghigh+3,glowy + dline bghigh+3,glowy,bghigh+3,blowy + + ;display protective semi-cricles around goals + move a,bdcenx ;right in the center X + move b,blowy ;and bottom Y line + move c,[0,0] ;from 0.0 radians + move d,[3.14159265358] ;to Pi radians + move e,bprot ;radius of protective circle + pushj p,dcirc ;draw a circle there + + move a,bdcenx ;same but on top now + move b,bhighy + move c,[3.14159265358] + move d,[6.2831853] ;or 0.0 ? + move e,bprot + pushj p,dcirc ;and drw the top circle + + move a,vdlipt + subi a,dlstrt + movem a,bdsiz + pop p,vdlipt + popj p, + + subttl goal scoring, beam assignment, random generator + +bgldep: 25.0 ;goal depth +glowy: 0 ;bottom y coord of bottom goal +ghighy: 0 ;top y coord of top goal +bdbri: 20111 ;board brightness +bdsiz: 0 ;# words needed in board display list + + ; score a goal +goalht: move a,zbesty ;find which goal hit + setz b, ;assume #0 (top) + camge a,bdceny ;above or below center? + movei b,1 ;below, bottom goal (team #1) + movem b,lglhit ;save # of goal hit + movei b,1 ;now set up default score + camge a,bdceny ;test again + jrst [ skipe c,tmon(pwb) ;team hitting bottom goal should be #0 + hrrei b,-2 ;oops! shot self! + jrst golht0] + skipn c,tmon(pwb) ;team hitting top goal should be #1 + hrrei b,-2 ;oops again +golht0: addm b,tmscor(c) ;add to score + movem c,ltmscr ;save # as last team to score (whether hit theirs or own) + pushj p,vbfend ;wrap up current variable buffer and switch it + move b,frztim ;secs to freeze + imuli b,60. ;60ths + idiv b,steptm ;find # of go-aheads to wait +golht1: aose clksnk +IFE $ITS,[ + jrst .-1 +] +IFN $ITS,[ + .HANG + MOVE A,[-2,,[.SPIRQC,,[0] ? .SIMASK,,[200000,,0]]] + .SUSET A +] + sojg b,golht1 + + popj p, + + ;find which player gets beam at start of game +zassgn: move c,lglhit ;get team # of last goal hit +zass1: pushj p,prandm + idivi a,nplyrs + came c,tmon(b) ;see if selected player on that team + jrst zass1 ;no, get another + move pwb,b ;remainder is from 0-nplyrs + popj p, + +prandm: pushj p,random + movm a,a ;return positive random number + popj p, +random: skipn a,ztim60 ;hash it up with random time + move a,ran + fmpb a,ran + tsc a,a + popj p, +ran: 123456,,654321 ;initial seed + + subttl input + +;---- input bits-- +i%fire==bit1.5 ;firing beam +i%pass==bit1.2 ;passing to teammate +i%clkw==bit1.9 ;rotate clockwise (right) +i%ccw== bit1.8 ;rotate counter-clockwise(left) +i%posy==bit1.6 ;move up +i%negy==bit1.7 ;move down +i%posx==bit1.3 ;move right +i%negx==bit1.4 ;move left + +inpget: push p,a + push p,b + skipn inmode + datai a + skipe inmode + datai 420,a + setca a,a ;bits are 1's until 0 imposed. + movsi plr,-4 +inpgt1: lshc a,-9. + lsh b,-27. + movem b,input(plr) + aobjn plr,inpgt1 + + skipe switch + jrst getpot + move a,[inval-1,,inval] ;setup overlapping blt + blt a,inval-1+16. ;if no pots are to be read, zero inval + jrst timout + +getpot: MOVE A,[CHANS,,INPUTS] ;SET UP ARGS TO GET-POT-VAL RTN + BLT A,INPUTS+16.-1 + + ; read pot values +ife $its,[ +wait: CONI IMX,B + JUMPGE B,TIMOUT ;SIGN BIT IS SET IF PROCESSOR CAN ACCESS A/D + + movsi a,-16. ; index + cono IMX,2000 ; rate of 2, non-sequential, non-pack, no intrpt +loop5: skipn b,INPUTS(a) ; get channel # form channel table + jrst next + datao IMX,b ; select channel + CONO IMX,2000 + + moveI b,50. + sojl b,next ; if much more than 40 microseconds, just use last val + conso IMX,BIT32 ; is data here yet? + jrst .-2 + + datai IMX,inputs(a) ; input pot value and place in list + +next: aobjn a,loop5 +] +ifn $its,[ + ;IMX device should already have been opened in block mode + move a,[-16.,,inputs] ; get values + .iot imxchn,a +] + movsi a,-16. +loop6: move b,inputs(a) ; get input value + fsc b,233 ; float the number +ife $its, fadr b,[0.0] ; on 6, must normalize before dividing!! + fdvr b,[1000.0] ; scale to number from 0.0 to 2.0 (almost) + fsbr b,[1.0] ; change to -1.0 to 1.0 + skipn chans(a) ; this is to make sure if we didn't input for that + setz b, ; channel the value is still zero + skipe negpot(a) + movn b,b + movem b,inval(a) ; stick into input value + aobjn a,loop6 + +timout: pop p,b + pop p,a + popj p, + +chans: 73 ? 70 ? 71 ? 0 ;players 1 and 2 each side of New Pot Box + 74 ? 77 ? 76 ? 0 + 10 ? 2 ? 3 ? 0 ;player 2 and 3 , AMF arm console pots + 30 ? 5 ? 6 ? 0 + +negpot: 0 ? 0 ? 0 ? 0 ;if non-0, means negate sense of pot. + 0 ? 0 ? 0 ? 0 + 1 ? 1 ? 1 ? 0 + 1 ? 1 ? 1 ? 0 + +inputs: block 4*4 + 0 ;this wd blt'd to zap invals. +inval: block 4*4 ; place to put input values, should be inited to 0 +rotate==0 +xmove==1 +ymove==2 +fire==3 +inmode: 1 ;0= data switches, 1=extra switch bank +switch: 0 ;1= use A/D or switches depending on control table + ;0= use switches in the old fashion + + subttl player updating +updat: ; update inval variables according to directions + move c,dconst ; digital inputs have the value dconst + movei e,(plr) + ash e,2 ; 4 * player + skipe switches + jrst updati + move b,input(plr) + trne b,i%posx ? movem c,inval+xmove(e) + trne b,i%negx ? movnm c,inval+xmove(e) + trne b,i%posy ? movem c,inval+ymove(e) + trne b,i%negy ? movnm c,inval+ymove(e) + trne b,i%clkw ? movem c,inval+rotate(e) + trne b,i%ccw ? movnm c,inval+rotate(e) + trne b,i%pass ? movnm c,inval+fire(e) + trne b,i%fire ? movem c,inval+fire(e) + jrst updat4 + +updati: movei a,(plr) + ash a,3 ; get # of player * 8 in a + movei e,(plr) + ash e,2 + hrli e,-4 ; -4,,player # * 4 +loop7: skipn b,control(a) ; does control table say to use pots? + jrst nextsw ; use the pot input for this variable + setzm inval(e) ; zap any pot reading there may already be + ldb b,b ; pick up bit using byte pointer in control tab + trne b,1 ; if its on, set corresponding inval to (dconst) + movem c,inval(e) + ldb b,control+1(a) ; pick up bit representing opposite condition + ;e.g. left rotate instead of right rotate.. + trne b,1 ;if its on, set inval to -(dconst) + movnm c,inval(e) +nextsw: addi a,2 ; advance a to next control tabl entry + aobjn e,loop7 ; advance e to next inval + +updat4: movei e,(plr) ; e gets plr*4 + ash e,2 + + ;update X motion of player + setz a, + move a,inval+xmove(e) + movm t,a ; takes abs val + camg t,fuzzm ; is the value small enough to be zero? + setz a, ; then make it exactly zero + fmpr a,speed ; multiply by speed const + jfcl ; for patching more interesting calculations + fadr a,plocx(plr) ; add the x position to new movment + camle a,phighx ; truncate new position if its outside board + move a,phighx + camge a,plowx + move a,plowx + + setz b, ; do same things for Y movement + move b,inval+ymove(e) + movm t,b + camg t,fuzzm + setz b, + fmpr b,speed + jfcl + fadr b,plocy(plr) + camle b,phighy + move b,phighy + camge b,plowy + move b,plowy + + ; check for moving within edge of protective circle: + move c,bdcenx + move d,bhighy ;coords of center of top goal + camge b,bdceny ;use above if player is in upper half + move d,blowy ;else check lower goal + pushj p,distsq ;get dist + caml c,bprosq ;compare w/square of protective circle radius + jrst updat2 ;okay... + skipe inval+xmove(e) ;within circle! moving in x dir? + jrst [camn a,bdcenx ;test for critical point + jrst updat1 + camg a,bdcenx ;see which side of bd he's on + jrst [skipl inval+xmove(e) ;ok to move in neg. dir + move a,plocx(plr) ;but not OK in pos dir(non-neg) + jrst updat1] + skipg inval+xmove(e) ;ok to move in pos dir + move a,plocx(plr) + jrst updat1] + +updat1: skipe inval+ymove(e) ;moving in y dir? + jrst [camg b,bdceny ;see which side + jrst [skipg inval+ymove(e) ;ok to move up + move b,plocy(plr) + jrst updat2] + skipl inval+ymove(e) + move b,plocy(plr) + jrst updat2] +updat2: movem a,plocx(plr) ;store normalized coords + movem b,plocy(plr) + + movei c,(plr) ;get 8 * plr into c + ash c,3 + + skipn a,inval+rotate(e) ; is rotation non-zero? + jrst updat3 + movm b,inval+rotate(e) +; movm t,b ;if absval of rotate is too small + camg b,fuzzr + jrst updat3 + fmpr b,angrat + fmpr b,angspd ;scale-up for pots + jfcl + skipe switches ;if rotate was digital, us angrat + skipe control(c) + move b,angrat + caile a, + movn b,b ;CCW is - in inval, CW is +. + fadrm b,plang(plr) + move a,plang(plr) ;normalize + camle a,pi$2 ;make angle between 0 and pi*2 + fsbr a,pi$2 + caige a, + fadr a,pi$2 + movem a,plang(plr) + +; if analog use value as direct position +; skipn b,inval+rotate(e) ;now check for rotation. +; jrst updat3 ;skip if not +; fadr b,[1.0] ;make range 0.0 to 2.0 +; fmpr b,[1.2] ;don't want having to turn pot all the way +; fmpr b,pie ;now angle is between 0 and 2*pi (well, not really) +; movem b,plang(plr) + + ;derive necessary trigonometric values +updat3: move a,plang(plr) + pushj p,sin + movem a,plsin(plr) + move a,plang(plr) + pushj p,cos + movem a,plcos(plr) + move a,plsin(plr) + PFDVR a,plcos(plr) + movem a,plslop(plr) + + popj p, + + subttl display updating + +plrdis: move a,plrbri ;get standard player bri. + hrrz b,plr + camn b,pwb ;this one is pwb? + move a,pwbbri ;if so, use increased pwb brightness + move t,dlplst(plr) ;get addr to display list + movem a,(t) ;store brightness + + move a,plocx(plr) + move b,plocy(plr) + pushj p,getpt ;get display wd for pt specified + andcmi c,bit2.7+bit2.6+bit2.5 ;flush mode bits + iori c,bit2.7 ;go into vector mode after this hwd + movem c,1(t) ;store + + move b,plsin(plr) + move a,plcos(plr) + fmpr a,plen(plr) + fmpr b,plen(plr) + pushj p,getvec ;get vector for this displacement + hrl c,c ;copy in LH + ior c,[bit2.8,,0] ;make visible vector for first one + xori c,bit2.7+bit1.8 ;reverse sign for invisible vector(to return to strt) + movem c,2(t) ;store + + movn a,a + movn b,b + pushj p,getvec + hrl c,c + ior c,[bit2.8,,bit2.9] ;escape into parameter mode after this one + xori c,bit2.7+bit1.8 + movem c,3(t) ;store second side of player + movei a,20000 ;go into point mode + movem a,4(t) + + move a,plocx(plr) + move b,plocy(plr) + move c,plsin(plr) + move d,plcos(plr) + pushj p,@dpradr(plr) ;do ID stuff (points) + + popj p, + +define pushae pdac,aclist +IRP ac,,[aclist] + push pdac,ac +TERMIN +TERMIN +define popae pdac,aclist +IRP ac,,[aclist] + pop pdac,ac +termin +termin + +;routine to display random numbers and text as indicated in tables + +disran: pushae p,[a,b,c,d,e] + movsi e,-dtmax ;get aobjn thru random-display tables +disrn1: skipe d,dtloc(e) ;skip til something found(get addr of it) + jrst [move c,dtscbr(e) ;get scale/brightness + move b,dty(e) ;y coord to start at + move a,dtx(e) ;x coord + pushj p,dtdisp ;display it + jrst .+1] + aobjn e,disrn1 + popae p,[e,d,c,b,a] + popj p, + +dtmax==3 ;current max slots in random-display tables + +dtx: 900.0 ;x coord of start of text + 900.0 + 900.0 +dty: 950.0 ;y coord + 700.00 + 450.0 +dtscbr: 20173 ; scale/brightness parameter wd + 20175 + 20173 +dtloc: tmscor ;location of integer number (or setz [asciz/string/] ) + ztmlft + tmscor+1 + +;displays text; takes starting x and y in a,b scale/bri param wd in c, and +;addr of number (or addr of text string, with sign bit set as in setz) + +dtdisp: movem c,@vdlipt ;store paramter wd. (later, an idpb c,vdlipt) + aos vdlipt + pushj p,getpt ;convert a,b into point-mode word in c + andcmi c,bit2.5+bit2.2 ;take out point-mode bit and don't intensify + iori c,bit2.6+bit2.5 ;go into text mode after this one + movem c,@vdlipt ;store + aos vdlipt + movei a,440600 ;get LH to turn VDLIPT + hrlm a,vdlipt ;into a 6-bit byte pointer. + movei a,35 ;go into upper case + idpb a,vdlipt +; jumpl d,dtex ;jump if doing ASCIZ text + + ;doing a number. get it + move a,@d ;more general than (d) + pushj p,dnum ;do the chars + jrst dtdsp9 ;done + +dtdsp9: movei a,37 ;esc. to parameter mode + idpb a,vdlipt + setz a, ;now do kludge to ensure core zeroed til next param wd. + movei b,6 + idpb a,vdlipt + sojg b,.-1 ;repeat for a word's length + hrrzs vdlipt ;now clear LH of vdlipt ptr, and all's well. + popj p, + +dnum: jumpl a,[push p,b ? movei b,55 ? idpb b,vdlipt ? pop p,b ;minus sign + movn a,a ;make positive + jrst .+1] +dnum1: idivi a,10. ;base 10. + jumpe a,dnum2 ;ah, finished + push p,b ;save remainder for later typeout + pushj p,dnum1 ;deposit number in a + pop p,b ;restore remainder-digit +dnum2: movei b,"0(b) ;convert to ascii + idpb b,vdlipt ;mapping for #'s is equiv. to ascii + popj p, + + +getpt: push p,a + push p,b + frifix a + frifix b + hlrz c,a + hll c,b + and c,[1777,,1777] + ior c,[220000,,022000] + pop p,b + pop p,a + popj p, + + ;takes floating x,y in a,b as vector increment from present position +drwvec: push p,c + pushj p,getvec + iori c,bit2.8 ;make visible vector + movem c,@vdlipt ;deposit + aos vdlipt + pop p,c + popj p, + +getvec: push p,a + push p,b + frifix a + frifix b + movm c,a + hlrz c,c + andi c,177 + skipge a + tro c,200 ;sign bit for x + movm a,b + hlrz a,a + andi a,177 + skipge b + tro a,200 ;sign bit for y + dpb a,[101000,,c] ;deposit in c + pop p,b + pop p,a + popj p, + +drawl: push p,a + push p,b + push p,c + push p,d + push p,e + push p,c + pushj p,getpt ;get display wd for pt specified + andcmi c,bit2.7+bit2.6+bit2.5 ;flush mode bits + iori c,bit2.7 ;go into vector mode after this hwd + movem c,(t) + aoj t, ;starting point is now set + pop p,c + fsbr c,a ;find relative coords + fsbr d,b + move b,c ;don't mung c yet + PFDVR b,d ;find slope + movm a,b + caml a,[2048.0] ;no sense in more precision for vertical + jrst [skipge b + skipa b,[-2048.0] + move b,[2048.0] + jrst .+1] + frifix b ;y rise per + move a,[1,,0] ;single x step + skipge d + movn a,a ;in whatever direction + push p,a + push p,b + movm a,a + movm b,b + camge a,b ;if x changest fastest, do normal stuff +%dxch==bit2.9 + troa f,%dxch ;if y changes fastest, set flag + trz f,%dxch + pop p,b + pop p,a + trne f,%dxch + jrst [ exch a,b ? exch c,d ? jrst .+1] + movm e,a + move d,[177,,0] + idivi d,e ;find pct of total vecto length + imul b,d ;adjust smaller step accordingly + skipl a + skipa a,[177,,0] + movn a,[177,,0] + frifix c ;find limit of controlling coord + movm d,c ;magn. + idiv d,[177,,0] ;find # loops in it + +drwln5: + + + +drwlin: push p,a + push p,b + push p,c + push p,d + push p,e + push p,tt + push p,c + move c,zbri ;beam brightness/scale + movem c,@vdlipt ;store + aos vdlipt + pushj p,getpt ;set location + andcmi c,bit2.7+bit2.6+bit2.5 ;flush mode + iori c,bit2.7 ;go into vector mode after this + movem c,@vdlipt + aos vdlipt + pop p,c + fsbr c,a ;del_x + fsbr d,b ;del_y + movm e,c ;magn of del_x + movm tt,d ;magn of del_y + camg e,c127. + camle tt,c127. + skipa + jrst [move a,c ? move b,d ? jrst nofig] ;then dont have to figure + trz f,%dexch + camge e,tt ;skip if del_y < del_x + jrst [tro f,%dexch ? exch c,d ? exch e,tt ? jrst .+1] ;if del-y > del-x + + pfdvr d,c ;find m = / +xcont: move a,c127. ;amount of x to be moved + skipg c ;if del_x < 0 + movn a,a ;move -127. + move b,a + fmpr b,d ;get y (m*x increment) + trne f,%dexch + exch a,b ;exchange coords if y is really in a + pushj p,drwvec ;draw this + fsbr e,c127. ;|del_x| = 127 - new del_x + camle e,c127. ;done yet? + jrst xcont + + move a,e + skipg c + movn a,a + move b,a + fmpr b,d + trne f,%dexch + exch a,b +nofig: pushj p,getvec + ior c,[bit2.9+bit2.8] ;escape to param mode + movem c,@vdlipt + aos vdlipt + + pop p,tt + pop p,e + pop p,d + pop p,c + pop p,b + pop p,a + popj p, ;return + +c127.: 127.0 +yinc: 0.0 +xinc: 0.0 + + subttl circle drawer +%ixpos==bit2.9 +%ixneg==bit2.8 +%iypos==bit2.7 +%iyneg==bit2.6 + +dcirc: push p,t + push p,tt + move t,a + move tt,b + move a,[0.5] + fdvr a,e + fsbr d,c + fdvr d,a + ifix d + move b,a + pushj p,sin + movem a,csini + move a,b + pushj p,cos + movem a,ccosi + + move a,c + pushj p,sin + move b,a + move a,c + pushj p,cos + exch a,t + exch b,tt + fmpr t,e + fmpr tt,e + fadr a,t + fadr b,tt + push p,a + move a,bpbri + movem a,@vdlipt + aos vdlipt + pop p,a + push p,c + pushj p,getpt + andcmi c,bit2.7+bit2.6+bit2.5 + iori c,bit2.7+bit2.6 + movem c,@vdlipt + aos vdlipt + pop p,c + + move e,d + move c,t + move d,tt + move a,c + move b,d + pushj p,incrst + +cirlup: move a,c ;x + fmpr a,ccosi ;x cosi + move b,d + fmpr b,csini ;y sini + fsbr a,b ;new x = x*cosi - y*sini + fmpr c,csini ;x sini + fmpr d,ccosi ;y cosi + fadr c,d ;new y = x*sini + y*cosi + move b,c + + move c,a + move d,b + pushj p,drincp + sojg e,cirlup + pushj p,incre + pop p,tt + pop p,t + popj p, + +ccosi: 0 +csini: 0 + +drincp: ifix a + ifix b + sub a,t + sub b,tt + + trz f,%ixneg+%ixpos+%iyneg+%iypos + jumpe a,drin1 + cail a, + troa f,%ixpos + tro f,%ixneg +drin1: jumpe b,drin2 + cail b, + troa f,%iypos + tro f,%iyneg +drin2: trnn f,%ixneg+%ixpos+%iyneg+%iypos + popj p, + add t,a + add tt,b + move a,incwd + move b,inccnt + trne f,%ixneg+%ixpos + jrst [tro a,@ixenb(b) + trne f,%ixneg + tro a,@ixbit(b) + jrst .+1] + trne f,%iyneg+%iypos + jrst [tro a,@iyenb(b) + trne f,%iyneg + tro a,@iybit(b) + jrst .+1] + sojl b,[idpb a,vdlipt + movei a,200000 + movei b,3 + jrst .+1] + movem a,incwd + movem b,inccnt + popj p, + + +incrst: ifix a + ifix b + move t,a + move tt,b + movei a,200000 + movem a,incwd + movei b,3 + movem b,inccnt + movei a,442200 + hrlm a,vdlipt + popj p, + +incre: movei a,400000 + idpb a,vdlipt + setz a, + idpb a,vdlipt + idpb a,vdlipt + hrrzs vdlipt + popj p, + +ixenb: bit1.4 + bit1.8 + bit2.3 + bit2.7 + +ixbit: bit1.3 + bit1.7 + bit2.2 + bit2.6 + +iyenb: bit1.2 + bit1.6 + bit2.1 + bit2.5 + +iybit: bit1.1 + bit1.5 + bit1.9 + bit2.4 + +inccnt: 0 +incwd: 0 +bpbri: 20112 + + subttl utility subroutines and data bases +define player num,list + dlplr!num=%%dp + %%dp=%%dp+5 ;bright/scale wd,point wd,2 vector wds,+back to pt mode +dwplr!num: +relfig num,[list] +termin + +;macro for routine to display pts relative to starting pt and angle. +;1 is along angle, 2 is 45 deg ccw, 3 is 90 deg ccw to angle, etc. +define relfig num,list + push p,a + push p,b + push p,c + push p,d +; push p,e ;if using maskoff--allows wraparound on screen + frifix a ;convert x and + frifix b ;y to fractional integer form + pushj p,csncvt ;convert sin/cos in c/d to various needed values +; move e,[776000,,776000] ;if using maskoff--flush high order bits of coords + move d,[220000,,022000] ;point mode bits IOR'd with coords +irpc pt,,[list] +ifse [pt][1][relpnt rsin,rcos, ? .stop] +ifse [pt][2][relpnt rsn45,rcs45, ? .stop] +ifse [pt][3][relpnt rcos,nrsin, ? .stop] +ifse [pt][4][relpnt rcs45,nrsn45, ? .stop] +ifse [pt][5][relpnt nrsin,nrcos, ? .stop] +ifse [pt][6][relpnt nrsn45,nrcs45, ? .stop] +ifse [pt][7][relpnt nrcos,rsin, ? .stop] +ifse [pt][8][relpnt nrcs45,rsn45, ? .stop] +ifse [pt][S][ push p,a ? push p,b +] +ifse [pt][U][ pop p,b ? pop p,a +] +termin +; pop p,e ;if using maskoff + pop p,d + pop p,c + pop p,b + pop p,a + popj p, +termin + +define relpnt yrel,xrel + add a,xrel + add b,yrel + hllz c,b ;y coord first + hlr c,a +; and c,e ;to mask bits off if necessary + ior c,d + movem c,%%dp +%%dp=%%dp+1 +termin + +csncvt: push p,a + push p,b + move a,c + move b,d + frifix c + movem c,rsin + movnm c,nrsin + move c,a ;get floating sin back + fadr c,b + fmpr c,[.7071] ; (1/sqrt(2))*(sin + cos)=sin(ang+45 deg) + frifix c + movem c,rsn45 + movnm c,nrsn45 + + frifix d + movem d,rcos + movnm d,nrcos + fsbr b,a ;cos-sin + fmpr b,[.7071] + frifix b + movem b,rcs45 + movnm b,nrcs45 + pop p,b + pop p,a + popj p, + +rsin: 0 +nrsin: 0 +rcos: 0 +nrcos: 0 +rsn45: 0 +nrsn45: 0 +rcs45: 0 +nrcs45: 0 + +dpradr: repeat nplyrs,[conc dwplr,\.rpcnt+1 +] ;addr of routine for each player that mungs dlist +dlplst: repeat nplyrs,[conc dlplr,\.rpcnt+1,+dpstrt +] ;addr of first word in display list for player + +;routines to update player ID, given isin/icos/isin45/icos45 and x,y in c,d +;--all using fractional integer format. + + if1 %%dp=0 + if2 %%dp=dpstrt +player 1,[1111144444466666611111] ;single triangle +player 2,[S222222888888U444444666666] ;double triangle +player 3,[111333333555555777777] ;single square +player 4,[333333S111111777777U555555777777] ;double square + +DBDPT: -DLLEN,,DLSTRT-1 + +dlstrt: block 500 ;reserved for board + bit4.9 ;to break out of vector mode just in case +dpstrt: if1 loc .+%%dp ;reserve however many words the board needs + if2 repeat %%dp-., 0 +DLLEN==.-DLSTRT + 3000 ;interrupt display when reach end of "fixed" d-list + +vdllen==500 ;max size of variable-length display list +VDIS1: +vdlst1: block vdllen ;idea is that 340 crunches one while APR creates the other +VDIS2: +vdlst2: block vdllen + + +VDSLEN==VDLLEN +VDBR: 0 +VDCUR: 0 +VDSW: 0 +VDPTAB: -VDSLEN,,VDIS1-1 + -VDSLEN,,VDIS2-1 + + +DSTL: VDPTR,,[BDPT,,0] + VDPTR+1,,[BDPT,,0] + +DSTL3: BDPT,,0 + +DISLST: 0 ;PTR TO CURRENT DISLIST, SET BY DSTART. + +VDPTR: 0 ;HOLDS BLKO FOR VDIS1 + 0 ;FOR VDIS2 +BDPT: 0 + + + +vdlipt: 0 ;holds ptr into a vdlst for APR deposit of halfwords + +vdlapr: 0 ;# of vdl that APR is munging +vdl340: 0 ;# of vdl that 340 is munging +vdl1st: 0 ;status of vdl 1; -1 = 340, 0=free waiting for 340, 1= APR +vdl2st: 0 ;status for vdl 2 + +vbfnum: 0 ;flag for 340 routine, -1 means hacking vlist, 0 mainlist +vdlcnt: 0 ;# times display has shown list since start of use +vdlflg: 0 ;when APR wants to switch vlists, puts addr of new one here. +vdlloc: 0 ;340 routine stores current vlist start addr here. +disptr: 0 ;BLKO ptr wd. + +end go + \ No newline at end of file