LdX; +----------------------+iX; | |nX; | ELEVATOR REPAIRMAN |s#X; | | /\x$X; | by Fred Caprilli | /UP\}$X; | | |--|$X; | (c) 1985 | \DN/#X; | | \/X; | Analog Computing |X; | |X; +----------------------+X;X; System equatesX;VDSLSTSDLSTL0SDMCTL/GRACTLо NMIEN WSYNC COLBAKCHBASE PMBASEHSCROLVCOUNT HPOSP0HPOSP2HPOSP3COLRP0COLRP1COLRP2COLRP3SIZEP0 SIZEP1 SIZEP2 SIZEP3  SIZEM RANDOM "SETVBV\'XITVBVb,CONSOL1 STICK6 P2PL; P3PL@ M0PLE M1PL J M2PL OCOLPF0THITCLRY JIFFY^GPRIORocCOLOR0hCOLOR1mCOLOR2rSCOLBKw BOOT |COLDSTD DOSINI  ATRACTM DRKMSKN COLRSHO CHSETX; AUDF0Ҥ AUDF1ҩ AUDC1Ү AUDF2ҳ AUDC2Ҹ AUDF3ҽ AUDC3AUDCTL SKCTL PACTLX;X; Player / Missile AreaX;8X;PMAREA MAREAP0AREAP1AREAP2AREAP3AREAX; X; Page Zero VariablesX;X;!EHT;;P/M ht for elev&EMSK;;msk to clr bits+D1S;;climb fr height0D2S;;same (P3)5D1D;;climb to height:D2D;;same (P3)?DAN1;;P/M pg. Dan (P2)DDAN2;;P/M pg. Dan (P3)IESP;;speed tbl pntrNCOFSET;;DLI tbl offsetSESPEED;;elevator speedsXLEVEL;;level no.]FLOOR;;current floorbCLIMBF;;Dan climbing flggDIEFLAG;;indicates dyinglNEWLVL;;flags new levelqSCORE;;score in BCDv OVERFLG;;game over status{HITES;;elevator heightsDIR;;elevator dirsDANHOR;;Dan's hor posCLIMBHT;;climb heightDANDIR;;Dan's directionDANSPD;;Dan's speedSPDCNT;;speed counterELDLAY;;elev # to stallDLYCNT;;death delayCOLCNT;;color counterTIME;;time in BCDBASCNT;;Bass note cntrBASTIM;;Bass timerTRBCNT;;Treble counterTRBTIM;;Treble timerX;X; Game starts hereX; X;INITQ><;;cassette offPPACTL;;if necessaryQ>PCOLDST;;Warm startQ>PBOOT;;Disk boot OK Q>4RST PDOSINI Q>5RST PDOSINI;;Trap S/RESET CLRHI;;clear hiscoreRST-;;just in case TITLE;;Title screen  ZERO;;init. variables% SLEVEL* SETUP;;main display/ INITIM;;reset timer4X;9X; Mainline (non-VBI) code>X;CMAINQOVERFLG;;Game over?H FMN1;;No.MQ>;;Yes, so clearRPCONSOL;;CONSOL andWMN0QCONSOL;;poll START key\N>;;Is it pressed?a HMN0;;No.fPOVERFLG;;Yes, zero flagkQ>;;back to p%>4XITVBV;;standard VBu$>5XITVBV;;routinez SETVBV!RST;;and start at top MN1QNEWLVL;;Check new levelFMAIN;;Not yet, loop SLEVEL;;Yes, new level!MAIN;;and loop backX;X; End of Mainline codeX; SETUP$>&SDMCTL;;Disable DMAQ>@PNMIEN;;Disable DLI Q>4DLISTPSDLSTL;;Point toQ>5DLIST;;the gamePSDLSTL;;display listQ>4DLI1;;DLI vector PVDSLST Q>5DLI1PVDSLST%>4VBI;;Set up VBI $>5VBIQ>;;Deferred SETVBVQ>=;;P/M enable, andPSDMCTL;;narrow playfieldQ>PNMIEN;;enable DLI's Q> ;;whitePCOLOR0;;for stairsQ>;;black PCOLOR1;;for shaftsPSCOLBK;;and screen top.$PBASCNT;;bass notes index)Q>;;green.PCOLOR2;;for digits3X;8Q>P;;16-bit ch. 0/1=PAUDCTL;;8-bit ch. 2,3BQ>GPSKCTL;;reset POKEYLQ>;;vol.10, dist.10Q PAUDC1V PAUDC2[ PAUDC3`Q>ePTRBTIM;;timer for treblejPTRBCNT;;treble note cntroQ>tPBASTIM;;timer for bassyX;~ X; Download charset to page 6X;$>7;;# of bytesCDLQCSETB9 PCHSET90ICDL:X;ZEROQ>;;zero variables$>OVERFLGCOFSETZ1PCOFSET90IZ1Q>;;Dan moves...PDANSPD;;every other VBIQ>;;ATASCII inv "0"$>L1PSSCORE9;;0 score0IL1PLEVBYTE;;level 0Q>PDANDIR;;no initial dir.Q>;;digit 9 on PMENBYT;;screen - 9 men Q>4TLINEPMSG  Q>5TLINEPMSG;;Top shows timer:X;CLRHI$>;;hi to 000000#Q>(CR1PHISCORE9-02ICR17:<X;APMSETUPQ>5PMAREAFPPMBASE;;to P/M areaKQ>PPGRACTL;;enable P/M DMAUQ>;;clear P/M areaZ?_CLNPMAREA8d PP0AREA8i PP1AREA8n PP2AREA8s PP3AREA8x1}HCLNX;%>;;8 P/M locsINITPMQELEPOS8;;init P/MPHPOSP08;;horizontal pos1;;next P/MIINITPM;;done? No.Q>@ PDANHORX; SETHTS;;elev heightsX;Q>z;;Set P/M colors PCOLRP0Q> PCOLRP1Q>H PCOLRP2Q> PCOLRP3X;Q>?;;P/M widthsPSIZEP0;;quadruple forPSIZEP1;;elevators (P0,PSIZEM;;P1,M0-M2)Q>;;single forPSIZEP2;;DanPSIZEP3;;(P2,P3) Q>!PGPRIOR;;Multicolor PLQ>5P2AREA;;Set up zeroPDAN1;;page pointers PD1S" PD1D' Q>5P3AREA, PDAN21 PD2S6 PD2D;:@X;E)X; The Display list interrupt routinesJX;ODLI15;;Save registersTAY5^$>5CHSET;;new charsetcQ>h PWSYNCm &CHBASErNCOLRSH;;mask attractw MDRKMSK| PWSYNCPCOLBAK;;change color Q>5DLI2PVDSLST Q>4DLI2PVDSLST;;next DLI7>7;;Restore regs9X;DLI25;;Save registersA5Q> PWSYNCPCOLBAK;;Black ceiling $COFSETQCOLORS9;;get colorNCOLRSH;;mask attract MDRKMSK PWSYNC PCOLBAK#COFSET;;inc indexQCOFSET;;table indexR> ;;last DLI? HEX;;no.Q>;;Yes, so restorePCHBASE;;default cset. Q>PCOFSET;;and zero indexPCOLPF0;;and color 0.Q>4DLI1;;Point back to!PVDSLST;;first DLI.& Q>5DLI1+PVDSLST0EX75>:7;;Restore registers.?9DX;I X; The Vertical Blank routineNX;SVBIQOVERFLG;;Skip VBI ifXFV0;;game over.]!XVBbV0QDIEFLAG;;Dan dying?gHDAN;;Yes, skip elevslX;q(X; Check screen heights for elevatorsv(X; and reverse direction if necessary{X;C3$>;;do 7 elevatorC0QHITES9R> ;;At top?IC1;;No. skipR>D;;IntermediateIC1Q>;;Going down!HC2AX;C1R>;;intermediateGC2R>;;At bottom?GC2;;No. no changeQ>;;Yes, going up! C2APDIR9C20;;next elevatorIC0;;done? No.X;*X; Now set up for movement of elevatorsX;$>;;do 7 elevatorsM1(ELDLAY;;slow it down? HM2;;No.QDLYCNT;;Yes.FM2;;Delay over yet?"DLYCNT;;No.QDLYCNT;;count down oneM>;;and skip a turn FM5;;every 1/15 sec.M2QELOCS9;;P/M page PEHTQHITES9;;byte loc in page PEHT%QEMASKS9;;Get mask*N>;;save its inverse/ PEMSK4QDIR9;;0=up, 1=down9FUP>X;CX; Set up for down movementHX;MQESPEED9;;elevator speedRFD1W #HITES9\#EHT;;double speedaD1#HITES9f#EHT;;normal speedk!M4pX;uX; Set up for up movementzX;UPQESPEED9FU1 "HITES9"EHT;;double speedU1"HITES9"EHT;;normal speedX;X; Execute the movementX;M4 MV;;move the bytesM50;;next elevatorIM1;;done? No.X;QJIFFY;;Stall elevator?HDAN;;(when JIFFY=0) ELNEWX;%X; Elevators done. Now, we process"X; Dan the Elevator Repair Man.X;DANQCLIMBF;;climbing? FVB1;;No. CLIMB1;;Yes, move him up!DANEND;;and exit."VB1QDIEFLAG;;Presently dying?FVB2;;No. skip  DEATH;;Yes. keep dying !XVB;;and exit. VB2%FLOOR QSTAIRS8;;Has he reached RDANHOR;;the stairs? HVB4;;No. )> ;;Top floor?$ GVB3;;No, climb stairs)  ENDLEV;;Yes, so end it. !DANEND;;and exit.3 VB3 SCLIMB;;init climbing8 !DANEND;;and exit.= VB4 HITCHK;;Chk collisionB FVB5;;Dan hit? No.G Q>x;;Yes, start 120L PDIEFLAG;;jiffy death...Q HDANEND;;and exitV X;[ )X; If we make it to here, it means our` 'X; hero is either starting or in thee 'X; midst of his perilous trek acrossj X; the screen.o X;t VB5#SPDCNT;;Speed countery QSPDCNT~ RDANSPD;;Time to move? GDANEND;;No, so exit. Q> PSPDCNT;;Zero the counter $DANDIR;;Save old dir  JOY;;dir change? (DANDIR FMOVEDAN;;No, skip  DRAWDAN;;Yes, redraw him MOVEDANQDANDIR GDANEND;;Wait on joystick %FLOOR QSTARTS8;;Is Dan at start RDANHOR;;of floor? FF3;;Yes, skip next ,;;animate feet QDANHT8 O>;;Bottom of Dan ?;;for feet. QJIFFY M>;;Mod 8 counter R>;;at 4 jiffies? GF2 Q>;;"feet in" byte HF3A F2Q>$;;"feet out" byte F3APP2AREA8 F3QDANDIR W?;;Right or left? DMVRT;;Right (DANDIR=0) QDANHOR;;trying to pass R>@;;left edge? FDANEND;;Yes, stop him# "DANHOR;;Dec horizontal( !MVLF- MVRTQDANHOR;;Trying to pass2 R>;;right edge?7 FDANEND;;Yes, stop him< #DANHOR;;No, so move itA !MVLFQDANHOR;;position shadowF PHPOSP2;;and do theK PHPOSP3;;horizontal moveP X;U DANEND TIMER;;Do the timerZ  MUSIC;;Do the music_ XVBPHITCLR;;clr collisionsd !XITVBV;;and finish VBI!i X;n X; Subroutiness X; -----------x X;} %X; Pick an elevator to stall [0-6] X; ELNEWQRANDOM M>;;0-7 R> FELNEW;;0-6 PELDLAY Q> PDLYCNT : X; 'X; Animate the elevators - on entry, 'X; (EHT) pointS to the pertinent P/M )X; area, and EMSK contains inverse bit &X; mask, to zero out bits (tops and 'X; bottoms of elevators). Elevators )X; are 12 solid lines plus 2 blanks on X; top and 2 on bottom. X; MV%>;;16 bytes  V2;;15-14 (bottom) 1 V1Q@EHT7;;lines 13 to 2 MEMSK;;Clr current bits LEMASKS9;;set new ones P@EHT7 1 )> HV1 V2Q@EHT7;;line 1 MEMSK;;Zero out bits P@EHT7;;with mask 1" Q@EHT7;;line 0 (top)' MEMSK, P@EHT71 :6 X;; (X; Generate elevator starting heights@ X;E SETHTS$>;;7 elevatorsJ SH1QRANDOMO M>?;;0-63T T?;;0-126 evenY O>(;;40-166 even^ PHITES9c 0h ISH1m :r X;w !X; This subroutine updates the| %X; countdown timer, and puts it to X; the screen X; TIMERQCLIMBF;;Don't time HTI1;;if climbing QTIME HTI0 QTIME M> FTI1;;If 0 don't dec TI0<;;Decimal math ; QTIME;;Fractional byte S>;;approx. 0.1 sec PTIME;;(rolls over QTIME;;every 6 jiffies) S> PTIME QTIME S> PTIME - X; QTIME;;Take 3-byte (6 M>;;decimal digit), L>;;take the low 3 PTLINE;;digits and put QTIME;;to the screen. V?;;move high nybble V?;;for 2nd decimal V?;;digit down to V?;;low nybble L>;;make it ATASCII! PTLINE;;put to screen& QTIME;;we only want low+ M>;;nybble here0 PTIME;;(3 digits total)5 L>;;make it ATASCII: PTLINE;;put to screen? Q>D PTIME;;not usedI TI1:N X;S )X; This subroutine updates the scoringX "X; when Dan reaches a new floor] X;b !SCORING$>;;3-byte (6-digit)g <;;decimal addl ,q SC10v QSCORE9{ OTIME9 PSCORE9 A HSC1 - PTIME;;Zero out timer PTIME PTIME PTIME $> %> SC2QSCORE9 5;;Save it M>;;low nybble L>;;make it ATASCII PSSCORE8;;put on screen 7;;use same byte V?;;high nybble V?;;we move it V?;;down to V?;;low nybble L>;;make it ATASCII 1 PSSCORE8;;put to screen 1 0 ISC2 : X; )X; This subroutine reads the joystick. X; JOYQSTICK;;Read joystick M>;;Right? FJLR;;Yes.% QSTICK* M>;;No. left?/ HJE;;No, dir same4 Q>;;1 = left9 JLRPDANDIR> JE:C X;H 'X; This subroutine updates the scoreM X; and sets up the climb.R X;W !SCLIMB SCORING;;Update score\ Q>;;16 scan linesa PCLIMBF;;to climb.f %FLOOR;;index to screen.k QDANHT8;;height tablep PCLIMBHT;;start climb hereu :z X; 'X; This subroutine makes Dan climb 1 'X; scan line per VBI (if CLIMBF<>0). "X; It continues into the INITIM X; subroutine. X; CLIMB1%> QCLIMBHT;;Set up zero page PD1S;;pointers PD2S "CLIMBHT;;destination is QCLIMBHT;;one scan line up PD1D PD2D CL1Q@D1S7;;Move P2 up one. P@D1D7 Q@D2S7;;Move P3 up one. P@D2D7 3 )>;;All bytes moved? GCL1;;No. Q>;;Erase last line P@D1D7 P@D2D7 "CLIMBF HINITIM;;Is climb over? #FLOOR;;Yes, new floor.X;'X; This subroutine sets timer to 250 X;INITIMQ>;;250 decimal PTIMEQ> PTIME$Q>P) PTIME. Q>;;"2"3 PTLINE8 Q>;;"5"= PTLINEB Q>;;"0"G PTLINEL:QX;V*X; This subroutine sets up a new level,[)X; speeds of elevators and Dan, timer,`(X; Dan on bottom, increased level no.eX;jSLEVEL%LEVELo)>;;Level 7 or more?t GSL0;;No.yQ>;;Yes, so we have~PDANSPD;;superfast Dan.SL0)>;;Level 4 or more? GSL1;;No.%>;;Yes, lev.4 speedSL1CT??;;Lev *2 indexQLEVSPD8;;elev speed tblPESP;;init 0 page pntr3 QLEVSPD8 PESP%>;;Download elevSL2Q@ESP7;;speeds to PESPEED8;;zero page tbl1ISL2 PMSETUP;;reset P/M grQ>PFLOOR;;floor 0 SFLOOR INITIM QLEVELL>;;make it ATASCIIPLEVBYTE;;put to screen.Q>PNEWLVL;;Turn off flag.: X;"SFLOOR%FLOOR;;find hor. start QSTARTS8PHPOSP2;;put Dan there. PHPOSP3# PDANHOR( DRAWDAN;;Draw him-Q>2PATRACT;;defeat attract7Q><PDANDIR;;no initial dir.A:FX;K#DRAWDAN%FLOOR;;index to heightPQDANHT8;;tbl correspondsUPDAN1;;to P/M memoryZPDAN2;;'height'_%>;;draw 16 bytesd QDANDIRiW?;;Right or left?nES2sX;xX; Draw Dan facing right}X;S1QDANRT18;;P2 data P@DAN17QDANRT28;;P3 data P@DAN271IS1:X;X; Draw Dan facing leftX;S2QDANLF18;;P2 data P@DAN17QDANLF28;;P3 data P@DAN271IS2:X;&X; Death subroutine - flip-flop Dan%X; for 1 second, then freeze for 1$X; second. If no lives are left,X; it ends the game.X; DEATHQ> PAUDF0 PAUDF1PAUDF2;;Silence music "DIEFLAG;;lower counterQDIEFLAG;;Done yet?FDE2;;Yes.R><;;time for freeze? IDE8;;No."Q>;;Yes...'PAUDF3;;silence,:;;skip flip-flop.1DE8M>;;No, flip Dan6HDE3;;every 4 jiffies; QDANDIR@FDE1E DRAWDAN;;flip leftJQ>;;and set up forOPDANDIR;;right flipTQ> ;;high noteYHDE0^DE1 DRAWDAN;;flip rightcQ>;;and set up forhPDANDIR;;left flipmQ>@;;low noterDE0PAUDF3w:|X;X; Death overX;DE2 SFLOOR;;put Dan back"MENBYT;;One less man...QMENBYT;;Any men left?M>HDE3;;Yes, continue.Q>4OVERLN;;No, changePMSG;;top line LMSQ>5OVERLN;;LMS to showPMSG;;"GAME OVER"Q>;;set flag POVERFLG$>;;Compare score toDE4QSSCORE9;;high scoreRHISCORE9;;digit by digitGDE3;;lt?, no changeHDE5;;gt?, update hi2;;next digit(>GDE4: DE5$>DE6QSSCORE9;;Move scorePHISCORE9;;to high score0IDE6DE3: X;$X; This subroutine does collisionX; detection.X;!HITCHKQP2PL;;Did P2&LP3PL;;or P3 hit+M>;;elev 0,1,5,6?0HENDCHK;;Yes, Dan's dead.5QM0PL;;Did M0 (elev 2):LM1PL;;or M1 (elev 3)?LM2PL;;or M2 (elev 4)?DM> I#ENDCHKPHITCLR;;Clear collisionN:SX;X!ENDLEV SCORING;;update score]#LEVEL;;on to next levelbQ>;;Flag so mainlinegPNEWLVL;;code can set upl:;;a new levelqX;v(X; This subroutine produces the title{"X; screen, and waits for START.X; TITLEQ>PSDMCTL;;disable DMAPCOLOR0;;black lettersQ>4TDLIST;;Point toPSDLSTL;;Display listQ>5TDLIST;;for titlePSDLSTL;;screenQ>=;;narrow playfield PSDMCTLQ>;;white letters PCOLOR1Q>;;center titles PHSCROL X1QVCOUNT;;rainbow backgrndHX1;;wait for line 0?;;and keep track$COLCNT;;colour counterX2PWSYNC;;sync to TV linePCOLBAK;;store in reg2;;inc color #AM>;;but make itL>;;luminance 83)>;;screen bottom? HX2;;No.X; *X; Now increase the starting colour for'X; next TV frame, produces scrollingX; rainbow effectX;  #COLCNT%Q>;;We have some*PCONSOL;;time left to/QCONSOL;;check for START4N>;;Pushed?9FX3;;Yes, so exit>PWSYNC;;keep stuffingC PCOLBAKHHX1;;Infinite loopMX3:;;unless sent hereRX;W&X; This subroutine plays the music.\X;a!MUSICQBASTIM;;New note time?f IBN0;;No.kQ>;;all notespPBASTIM;;are 15 jiffies.u #BASCNTzBN0QBASCNT;;Get the note.M>;;mod 8 counter?QBASSLO8;;Bass is 16-bitPAUDF0;;sound, so stuffQBASSHI8;;lo and hi bytesPAUDF1;;in channels 0,1 $BASTIM QBASENV9PAUDC1;;Apply envelope"BASTIM;;dec. durationX;X; Melody (Treble)X;QTRBTIM;;Note timer done? ITN1;;No.#TRBCNT;;Yes - inc cntr%TRBCNT;;Are we at...)>;;end of tune? GTN0;;No.Q>;;Yes, resetPTRBCNT;;counterHTN2TN0QTRBDUR8;;load thePTRBTIM;;durationTN1%TRBCNTQTREBLE8;;Play the note.. PAUDF2"TRBTIM;;and dec timer. TN2:X;X; Various Data TablesX;ELEPOS H==@=@$ l=|==)COLORS ="==B==R. r=2=b==3EMASKS = == 8 0== =ELOCS 5P0AREA=5P0AREAB 5MAREA=5MAREAG 5MAREA=5P1AREAL 5P1AREAQSTARTS @==@==@V =@==@==@[STAIRS =@==@=` @==@==@=eESPED1 ======jESPED2 ======oESPED3 ======tESPED4 ======yESPED5 ======~X;"LEVSPD ESPED1=ESPED2=ESPED3 ESPED4=ESPED5X;'X; Vertical height of tops of floorsX;DANHT === =p=`=P @=0= X;DANLF1 ==?= 4=}=}=o ===? ?=?== DANLF2 ==?=  === ==== 9=9==DANRT1 =x=~= =_=_={ 0= =<=~ ~=~=<=DANRT2 =x=~=` h= = =  =8=<=^ N=N=<=X;TLINE A A  =A000A A A#TOPLINE =F==F===A= A==A==F==F=!LLINE =F==F===A=# A==A==F==F=(!RLINE =F==F===A=- A==A==F==F=2INFOLN ASC A7SSCORE =A000000A< A MEN AAMENBYT =A0AF A HI AKHISCORE =A000000AP A LEV AULEVBYTE =A0AZOVERLN A GAME OVER A_X;dX; Music DataiX;nBASSLO k=k==ks =k==dxBASSHI 5=5=/=5} ,=5=(=*BASENV === === === =="TREBLE D=Q==D=(=9==Q D=<=9==9==9= 9=<=D=Q=[=Q=l `==TRBDUR r="=Y=r===c ======= ======= ==PX;X; The Game Display ListX;DLIST p=p=MSG TLINE  TOPLINE  LLINE  RLINE  LLINE  RLINE   LLINE  RLINE " LLINE' , RLINE1 6 LLINE; @ RLINEE =FJ INFOLNO =AT DLISTYX;^X; Title Screen Display ListcX;hTDLIST p=p=p=pm p=p=Gr GAMEw p==p=p=F| AUTHOR p=p=F COPYR p==p=p=V INSTR p=p=A TDLISTX;GAME A ELEVATOR A A REPAIRMAN AAUTHOR ABY FRED CAPRILLIACOPYR A (C) 1985 A AANALOG COMPUTINGAINSTR A pressA A start AX;X;MODIFIED CHARACTER SETX;CSETB === === === === === === === === === === <=~=~=  === === ===X;!&X;+ INIT0