A.N.A.L.O.G. ISSUE 34 / SEPTEMBER 1985 / PAGE 73

Elevator Repairman

16K Cassette or 24K Disk

by Fred Caprilli

You are Dan the Elevator Repairman. You’ve been called into the Polychromatic Hotel to fix its elevators, which have been sabotaged and are going haywire. One problem: this hotel wasn’t very well engineered, and the only way to get to the engine room’s entrance is to climb the fire escape, which is found on alternate sides of each floor as you go up.

The object, then, is to make your way across each floor toward the stairs, avoiding the elevators and, eventually, to reach the top right-hand side. (If you think this scenario is far-fetched, I suggest you pull out ANALOG Computing’s issue 10 and read the backgromid for Fill ’Er Up!)

If an elevator hits you (or vice versa), you’re sent back to the start of the same floor. When you reach the other side safely, you will automatically climb to the next floor. Reaching the top brings you to the next level, where a couple of elevators speed up. Subsequent levels bring more of the fast elevators; level 7 has a surprise (don’t look at the source code — that’s cheating).

The top of the screen shows a timer which starts counting down from 250 (about 25 seconds) when you start a floor. Whatever is left when you reach the other side is added to your score, so the faster you get across, the higher your score.

Score, High Score, Level (starting with 0) and Men Left are all shown at the bottom of the screen. I didn’t make allowances for levels higher than 9, so if you’re good enough to get past level 9, I hope you won’t mind funny characters on the status line.

Use a joystick to move Dan left and right. Notice that you can’t really stop in one position — that would be too easy, however, repeated deft flicks of the stick can help you get out of most situations. Note, also, that the spaces between elevators are not all the same width. Use this to your advantage.

You get nine men to start with (you’ll need them!), but no bonus lives are given. If you look carefully, you’ll notice random elevators “stalling” temporarily ever few seconds. This changes the pattern of the elevators constantly, so that an “impossible” pattern won’t last for long.

Some notes on programming.

Elevator Repairman uses lots of display list interrupts (DLIs) to generate the multicolored playfield and to switch between character sets. Virtually all the game runs in the vertical blank interval (VBI), where graphics changes can be executed smoothly before the screen is drawn, and where events can be monitored eighty times per second.

This time is also used to play the music, the theme from “Peter Gunn.” I realize this has precious little to do with repairing elevators, but it’s nice and short, and kind of catchy. Note that the bass notes are implemented in 16-bit sound (so they play more in tune) and an “envelope” is applied to shape their sound (i.e., the volume is changed during the duration of one note).

All the elevators and Dan are player/missile graphics. Dan is multicolored (overlapped players 2 and 3). Elevators 1 and 2 are player 0; elevators 3, 4 and 5 are missiles 0, 1 and 2; and elevators 6 and 7 are player 1. By bit-twiddling the players just like missiles, I got two seemingly independent objects out of each of them. All elevators are quadruple width.

If you look at the title screen carefully, you’ll notice that Repairman is nicely centered below Elevator. This was done by shifting Repairman by half a character with the fine scroll register.

Finally, here are some tips I learned in the process of writing the game (the first I’ve managed to complete), which cost me days of debugging time to discover

When using sound, always include an LDA #3, STA SKCTL as part of initialization. The Atari uses POKEY to make the beeping sound when loading, and this can cause your sound not to be heard (not to mention making a myriad of expletives issue forth from your mouth) when the game first boots up.

Also, when using VBI routines in conjunction with DLIs, do an LDA #$40, STA NMIEN before setting them up. Otherwise, your formerly functioning DLIs won’t work when you implement your VBI routine.

Typing it in.

Listing 1 is the BASIC data and data checking routines. This listing is used to create both cassette and disk versions of Elevator Repairman. The data statements are listed in hexadecimal, so the program will fit in 16K cassette systems.

Listing 2 is the assembly language source code for the game (MAC/65). You don’t have to type this listing to play the game. It’s included for those readers interested in assembly language.

Cassette instructions.

  1. Type Listing 1 into your computer, using the BASIC cartridge, and verify your typing with Unicheck (see page 30).
  2. Type RUN and RETURN. The program wall ask:
    MAKE CASSETTE (0) OR DISK (1)? Type 0 and press RETURN. The program will begin checking the DATA statements, printing the line number of each as it goes. It will alert you if it finds any problems. Fix any incorrect lines and re-RUN the program, if necessary, until all errors are eliminated.
  3. When all of your DATA lines are correct, the computer will beep twice and prompt you to READY CASSETTE AND PRESS RETURN. Now, insert a blank cassette in your recorder, press the RECORD and PLAY buttons simultaneously and hit RETURN. The message WRITING FILE will appear, and the program will create a machine language boot tape version of Elevator Repairman, printing each DATA line number as it goes. When the READY prompt appears, the game is recorded and ready to play. CSAVE the BASIC program onto a separate tape before continuing.
  4. To play the game, rewind the tape created by the BASIC program to the beginning. Turn the computer OFF and remove all cartridges. Press the PLAY button on your recorder and turn ON your computer, while holding down your START key If you have a 600 or 800XL computer, you must hold the START and OPTION keys when you tun on the power. The computer will beep once. Hit the RETURN key, and Elevator Repairman will load and run automatically.

Disk instructions.

  1. Type Listing 1 into your computer, using the BASIC cartridge, and verify your typing with Unicheck (see page 30).
  2. Type RUN and press RETURN. The program will ask:
    MAKE CASSETTE (0) OR DISK (1)? Type 1 and press RETURN. The program will begin checking the DATA lines, printing the line number of each statement as it goes. It will alert you if it finds any problems. Fix incorrect lines and re-RUN the program, if necessary, until all errors are eliminated.
  3. When all DATA lines are correct, you’ll be prompted to INSERT DISK WITH DOS, PRESS RETURN. Put a disk containing DOS 2.0S into drive 1 and press RETURN. The message WRITING FILE will appear, and the program will create an AUTORUN.SYS file on the disk, displaying each DATA line number as it goes. When the READY prompt appears, the game is ready to play. Be sure the BASIC program is SAVEd before continuing.
  4. To play the game, insert the disk containing the AUTORUN.SYS file into drive 1. Turn your computer OFF, remove all cartridges and turn the computer back ON. Elevator Repairman will load and run automatically.

That’s it. I hope you don’t fall down any elevator shafts.


Fred Caprilli is an Information Analyst in Ontario. He has had his Atari 800 for three years and has served as president of the Hamilton-Burlington-Oakville Atari Users Group.


Listing 1.
BASIC listing.

10 REM *** ELEVATOR REPAIRMAN ***
20 TRAP 20:? "MAKE CASSETTE (0), OR DISK (1)";:INPUT DSK:IF DSK>1 THEN 20
30 TRAP 40000:DATA 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,11,12,13,14,15
40 DIM DAT$(91),HEX(22):FOR X=0 TO 22:READ N:HEX(X)=N:NEXT X:LINE=990:RESTORE 1000:TRAP 120:? "CHECKING DATA"
50 LINE=LINE+10:? "LINE:";LINE:READ DAT$:IF LEN(DAT$)<>90 THEN 220
60 DATLIN=PEEK(183)+PEEK(184)*256:IF DATLIN<>LINE THEN ? "LINE ";LINE;" MISSING!":END 
70 FOR X=1 TO 89 STEP 2:D1=ASC(DAT$(X,X))-48:D2=ASC(DAT$(X+1,X+1))-48:BYTE=HEX(D1)*16+HEX(D2)
80 IF PASS=2 THEN PUT #1,BYTE:NEXT X:READ CHKSUM:GOTO 50
90 TOTAL=TOTAL+BYTE:IF TOTAL>999 THEN TOTAL=TOTAL-1000
100 NEXT X:READ CHKSUM:IF TOTAL=CHKSUM THEN 50
110 GOTO 220
120 IF PEEK(195)<>6 THEN 220
130 IF PASS=0 THEN 170
140 IF  NOT DSK THEN 160
150 PUT #1,224:PUT #1,2:PUT #1,225:PUT #1,2:PUT #1,0:PUT #1,32:CLOSE #1:END 
160 FOR X=1 TO 21:PUT #1,0:NEXT X:CLOSE #1:END 
170 IF  NOT DSK THEN 200
180 ? "INSERT DISK WITH DOS, PRESS RETURN";:DIM IN$(1):INPUT IN$:OPEN #1,8,0,"D:AUTORUN.SYS"
190 PUT #1,255:PUT #1,255:PUT #1,0:PUT #1,32:PUT #1,66:PUT #1,40:GOTO 210
200 ? "READY CASSETTE AND PRESS RETURN";:OPEN #1,8,128,"C:":RESTORE 230:FOR X=1 TO 40:READ N:PUT #1,N:NEXT X
210 ? :? "WRITING FILE":PASS=2:LINE=990:RESTORE 1000:TRAP 120:GOTO 50
220 ? "BAD DATA: LINE ";LINE:END 
230 DATA 0,17,216,31,255,31,169,0,141,47,2,169,60,141,2,211,169,0,141,231,2,133,14,169,56,141,232,2
240 DATA 133,15,169,0,133,10,169,32,133,11,24,96
1000 DATA A93C8D02D3A9008D4402A9018509A919850CA920850D20EF20D820242520C12020072420512020EB23A5A1F01A,956
1010 DATA A9088D1FD0AD1FD04906D0F985A1A907A062A2E4205CE44C1920A59DF0DE2007244C2920A2008E2F02A9408D0E,813
1020 DATA D4A92D8D3002A9278D3102A9688D0002A9218D0102A0C9A221A907205CE4A93D8D2F02A9C08D0ED4A90A8DC402,342
1030 DATA A9008DC5028DC80285BCA9CC8DC602A9508D08D2A9038D0FD2A9AA8D03D28D05D28D07D2A9FF85BF85BEA90E85,169
1040 DATA BDA237BDE4279D0006CA10F760A900A2109591CA10FBA90285B3A990A2059DAE26CA10FA8DC926A9FF85B2A999,102
1050 DATA 8DB926A96B8D3027A9268D312760A205A9909DBE26CA10FA60A9388D07D4A9038D1DD0A900A899003B99003C99,981
1060 DATA 003D99003E99003F88D0EEA007B9BC259900D08810F7A94085B0201423A97A8DC002A9F88DC102A9488DC202A9,147
1070 DATA 908DC302A93F8D08D08D09D08D0CD0A9008D0AD08D0BD0A9218D6F02A93E858C85848588A93F858E8586858A60,460
1080 DATA 488A48A206A9C28D0AD48E09D4454F254E8D0AD48D1AD0A9218D0102A98D8D000268AA6840488A48A9008D0AD4,55
1090 DATA 8D1AD0A691BDC425454F254E8D0AD48D1AD0E691A591C90BD016A9E08D09D4A90085918D16D0A9688D0002A921,482
1100 DATA 8D010268AA6840A5A1F0034CDC22A59CD06DA206B5A2C9201008C9441004A901D00AC99F3008C9C13004A90095,230
1110 DATA A9CA10E3A206E4B5D00CA5B6F008C6B6A5B62903F032BDD6258581B5A28580BDCF2549FF8582B5A9F00FB592F0,799
1120 DATA 04F6A2E680F6A2E6804C3422B592F004D6A2C680D6A2C68020F222CA10BBA514D00320E222A59BF00620C2234C,776
1130 DATA D622A59CF006208D244CDC22A49AB9E825C5B0D010C00A3006201A254CD62220B3234CD622200125F006A97885,482
1140 DATA 9CD05DE6B4A5B4C5B33055A90085B4A6B220A023E4B2F003206124A5B23041A49AB9DD25C5B0F01818B9202669,308
1150 DATA 0FA8A5142907C9043004A918D002A92499003EA5B26A900BA5B0C940F015C6B04CCE22A5B0C9B8F00AE6B0A5B0,688
1160 DATA 8D02D08D03D02024232075258D1ED04C62E4AD0AD22907C907F0F785B5A98085B660A00F20062388B18025821D,504
1170 DATA CF25918088C001D0F2B1802582918088B1802582918060A206AD0AD2293F0A692895A2CA10F360A59BD042A5BA,155
1180 DATA D006A5B9290FF038F838A5BBE91185BBA5BAE90085BAA5B9E90085B9D8A5BA290F09908D7326A5BA4A4A4A4A09,827
1190 DATA 908D7226A5B9290F85B909908D7126A90085B860A203F818CAB59E75B8959E8AD0F6D885B885B985BA85BBA202,847
1200 DATA A005B59E48290F099099AE26684A4A4A4A09908899AE2688CA10E760AD00D32908F009AD00D32904D004A90185,358
1210 DATA B260206B23A910859BA49AB9202685B160A000A5B185838585C6B1A5B185878589B1839187B1859189C8C01030,181
1220 DATA F3A90091879189C69BD002E69AA90085B8A90285B9A95085BAA9928D7126A9958D7226A9908D732660A499C007,82
1230 DATA 3004A90185B3C0043002A004980AA8B91626858FC8B916268590A006B18F9992008810F820FA20A900859A2048,658
1240 DATA 2420EB23A59909908DC926A900859D60A49AB9DD258D02D08D03D085B0206124A900854DA9FF85B260A49AB920,85
1250 DATA 26858B858DA00FA5B26AB00EB94B26918BB95B26918D8810F360B92B26918BB93B26918D8810F360A9008D00D2,285
1260 DATA 8D02D28D04D2C69CA59CF02AC93C1006A9008D06D2602903D054A5B2F00B206124A90085B2A920D009206124A9,182
1270 DATA 0185B2A9408D06D260204824CEB926ADB926290FD02BA9CA8D3027A9268D3127A90185A1A200BDAE26DDBE2630,11
1280 DATA 13D006E8E00630F160A205BDAE269DBE26CA10F760AD0ED00D0FD02903D00BAD08D00D09D00D0AD0290C8D1ED0,781
1290 DATA 60206B23E699A901859D60A9008D2F028DC402A95B8D3002A9278D3102A93D8D2F02A90E8DC502A9048D04D4AD,185
1300 DATA 0BD4D0FBA8A6B78D0AD48D1AD0E88A29F00908C8C0F0D0EFE6B7A9088D1FD0AD1FD04906F0088D0AD48D1AD0D0,524
1310 DATA D160A5BD1006A90E85BDE6BCA5BC2907A8B9DA268D00D2B9E2268D02D2A6BDBDEA268D03D2C6BDA5BF1013E6BE,659
1320 DATA A4BEC01A3006A9FF85BED00FB9132785BFA4BEB9F9268D04D2C6BF6048A040406C7C8C008222B2421252723262,990
1330 DATA E406C00C030C30C00C3C3C3B3B3B3D3D40B840B840B840B840B840B840B840B840B840B840B800000000000000,842
1340 DATA 00010000010000010100010001000001010101000101010101010101F325FA25012608260F26C0B0A090807060,573
1350 DATA 50403020000F3F1C347D7D6F06021E3F3F3F1E0C000F3F030B020210180E1E3D39391E0000787E1C165F5F7B30,627
1360 DATA 203C7E7E7E3C1800787E60682020040C383C5E4E4E3C0000000000000090909000000000000000014600460000,706
1370 DATA 410041004100460046050346004600004100410041004600460201460046000041004100410046004604332300,92
1380 DATA 909090909090002D252E009000282900909090909090002C2536009000000027212D25002F362532000000006B,901
1390 DATA 6B966BEA6B036435352F352C35282AA2A6AAA8A8A8A8A8A8A8A7A5A3A0A04451004428390051443C3900390039,277
1400 DATA 00393C44515B516C600000722259721313630E0E0E1300120012001213131313130E0E7F507070C66B26C77B26,779
1410 DATA C78B26C79B26C78B26C79B26C78B26C79B26C78B26C79B26C78B26C79B261046AB2606412D2770707070707047,812
1420 DATA 7C277017707046A027707046B0277006707056D0277070415B2700000000252C253621342F3200000000000000,560
1430 DATA 00003225302129322D212E000000000000223900263225240023213032292C2C29000000000823090011191815,670
1440 DATA 00000000212E212C2F2700232F2D303534292E2700000000707265737300737461727400000000000000000000,433
1450 DATA 0000008080808080808080010101010101010180FF80FF80FF80FF01FF01FF01FF01FF3C7E7EE7E7FFFFFF0808,576
1460 DATA 080808080808000000000000000000000000000000000000000000000000000000000000000000000000000000,624

Listing 2.
Assembly listing.

; +----------------------+
; |                      |
; |  ELEVATOR REPAIRMAN  |
; |                      |   /\
; |   by Fred Caprilli   |  /UP\
; |                      |  |--|
; |       (c) 1985       |  \DN/
; |                      |   \/
; |   Analog Computing   |
; |                      |
; +----------------------+
;
; System equates
;
VDSLST	=	$0200
SDLSTL	=	$0230
SDMCTL	=	$022F
GRACTL	=	$D01D
NMIEN	=	$D40E
WSYNC	=	$D40A
COLBAK	=	$D01A
CHBASE	=	$D409
PMBASE	=	$D407
HSCROL	=	$D404
VCOUNT	=	$D40B
HPOSP0	=	$D000
HPOSP2	=	$D002
HPOSP3	=	$D003
COLRP0	=	$02C0
COLRP1	=	$02C1
COLRP2	=	$02C2
COLRP3	=	$02C3
SIZEP0	=	$D008
SIZEP1	=	$D009
SIZEP2	=	$D00A
SIZEP3	=	$D00B
SIZEM	=	$D00C
RANDOM	=	$D20A
SETVBV	=	$E45C
XITVBV	=	$E462
CONSOL	=	$D01F
STICK	=	$D300
P2PL	=	$D00E
P3PL	=	$D00F
M0PL	=	$D008
M1PL	=	$D009
M2PL	=	$D00A
COLPF0	=	$D016
HITCLR	=	$D01E
JIFFY	=	$14
GPRIOR	=	$026F
COLOR0	=	$02C4
COLOR1	=	$02C5
COLOR2	=	$02C6
SCOLBK	=	$02C8
BOOT	=	$09
COLDST	=	$0244
DOSINI	=	$0C
ATRACT	=	$4D
DRKMSK	=	$4E
COLRSH	=	$4F
CHSET	=	$0600
;
AUDF0	=	$D200
AUDF1	=	$D202
AUDC1	=	$D203
AUDF2	=	$D204
AUDC2	=	$D205
AUDF3	=	$D206
AUDC3	=	$D207
AUDCTL	=	$D208
SKCTL	=	$D20F
PACTL	=	$D302
;
; Player / Missile Area
;
	*=	$3800
;
PMAREA	.DS	$0300
MAREA	.DS	$0100
P0AREA	.DS	$0100
P1AREA	.DS	$0100
P2AREA	.DS	$0100
P3AREA	.DS	$0100
;
; Page Zero Variables
;
	*=	$80
;
EHT	.DS	2	;P/M ht for elev
EMSK	.DS	1	;msk to clr bits
D1S	.DS	2	;climb fr height
D2S	.DS	2	;same (P3)
D1D	.DS	2	;climb to height
D2D	.DS	2	;same (P3)
DAN1	.DS	2	;P/M pg. Dan (P2)
DAN2	.DS	2	;P/M pg. Dan (P3)
ESP	.DS	2	;speed tbl pntr
COFSET	.DS	1	;DLI tbl offset
ESPEED	.DS	7	;elevator speeds
LEVEL	.DS	1	;level no.
FLOOR	.DS	1	;current floor
CLIMBF	.DS	1	;Dan climbing flg
DIEFLAG	.DS	1	;indicates dying
NEWLVL	.DS	1	;flags new level
SCORE	.DS	3	;score in BCD
OVERFLG	.DS	1	;game over status
HITES	.DS	7	;elevator heights
DIR	.DS	7	;elevator dirs
DANHOR	.DS	1	;Dan's hor pos
CLIMBHT	.DS	1	;climb height
DANDIR	.DS	1	;Dan's direction
DANSPD	.DS	1	;Dan's speed
SPDCNT	.DS	1	;speed counter
ELDLAY	.DS	1	;elev # to stall
DLYCNT	.DS	1	;death delay
COLCNT	.DS	1	;color counter
TIME	.DS	4	;time in BCD
BASCNT	.DS	1	;Bass note cntr
BASTIM	.DS	1	;Bass timer
TRBCNT	.DS	1	;Treble counter
TRBTIM	.DS	1	;Treble timer
;
; Game starts here
;
	*=	$2000
;
INIT	LDA	#$3C	;cassette off
	STA	PACTL	;if necessary
	LDA	#0
	STA	COLDST	;Warm start
	LDA	#1
	STA	BOOT	;Disk boot OK
	LDA	# <RST
	STA	DOSINI
	LDA	# >RST
	STA	DOSINI+1	;Trap S/RESET
	JSR	CLRHI	;clear hiscore
RST	CLD		;just in case
	JSR	TITLE	;Title screen
	JSR	ZERO	;init. variables
	JSR	SLEVEL
	JSR	SETUP	;main display
	JSR	INITIM	;reset timer
;
; Mainline (non-VBI) code
;
MAIN	LDA	OVERFLG	;Game over?
	BEQ	MN1	;No.
	LDA	#8	;Yes, so clear
	STA	CONSOL	;CONSOL and
MN0	LDA	CONSOL	;poll START key
	EOR	#6	;Is it pressed?
	BNE	MN0	;No.
	STA	OVERFLG	;Yes, zero flag
	LDA	#7	;back to   
	LDY	# <XITVBV	;standard VB
	LDX	# >XITVBV	;routine
	JSR	SETVBV
	JMP	RST	;and start at top
MN1	LDA	NEWLVL	;Check new level
	BEQ	MAIN	;Not yet, loop
	JSR	SLEVEL	;Yes, new level
	JMP	MAIN	;and loop back
;
; End of Mainline code
;
SETUP	LDX	#0
	STX	SDMCTL	;Disable DMA
	LDA	#$40
	STA	NMIEN	;Disable DLI
	LDA	# <DLIST
	STA	SDLSTL	;Point to
	LDA	# >DLIST	;the game
	STA	SDLSTL+1	;display list
	LDA	# <DLI1	;DLI vector
	STA	VDSLST
	LDA	# >DLI1
	STA	VDSLST+1
	LDY	# <VBI	;Set up VBI
	LDX	# >VBI
	LDA	#7	;Deferred
	JSR	SETVBV
	LDA	#$3D	;P/M enable, and
	STA	SDMCTL	;narrow playfield
	LDA	#$C0
	STA	NMIEN	;enable DLI's
	LDA	#$0A	;white
	STA	COLOR0	;for stairs
	LDA	#$00	;black 
	STA	COLOR1	;for shafts
	STA	SCOLBK	;and screen top.
	STA	BASCNT	;bass notes index
	LDA	#$CC	;green
	STA	COLOR2	;for digits
;
	LDA	#$50	;16-bit ch. 0/1
	STA	AUDCTL	;8-bit ch. 2,3
	LDA	#3
	STA	SKCTL	;reset POKEY
	LDA	#$AA	;vol.10, dist.10
	STA	AUDC1
	STA	AUDC2
	STA	AUDC3
	LDA	#$FF
	STA	TRBTIM	;timer for treble
	STA	TRBCNT	;treble note cntr
	LDA	#14
	STA	BASTIM	;timer for bass
;
; Download charset to page 6
;
	LDX	#55	;# of bytes
CDL	LDA	CSETB,X
	STA	CHSET,X
	DEX
	BPL	CDL
	RTS
;
ZERO	LDA	#0	;zero variables
	LDX	#OVERFLG-COFSET
Z1	STA	COFSET,X
	DEX
	BPL	Z1
	LDA	#2	;Dan moves...
	STA	DANSPD	;every other VBI
	LDA	#$90	;ATASCII inv "0"
	LDX	#5
L1	STA	SSCORE,X	;0 score
	DEX
	BPL	L1
	STA	LEVBYTE	;level 0
	LDA	#$FF
	STA	DANDIR	;no initial dir.
	LDA	#$99	;digit 9 on 
	STA	MENBYT	;screen - 9 men
	LDA	# <TLINE
	STA	MSG
	LDA	# >TLINE
	STA	MSG+1	;Top shows timer
	RTS
;
CLRHI	LDX	#5	;hi to 000000
	LDA	#$90
CR1	STA	HISCORE,X
	DEX
	BPL	CR1
	RTS
;
PMSETUP	LDA	# >PMAREA
	STA	PMBASE	;to P/M area
	LDA	#3
	STA	GRACTL	;enable P/M DMA
	LDA	#0	;clear P/M area
	TAY
CLN	STA	MAREA,Y
	STA	P0AREA,Y
	STA	P1AREA,Y
	STA	P2AREA,Y
	STA	P3AREA,Y
	DEY
	BNE	CLN
;
	LDY	#7	;8 P/M locs
INITPM	LDA	ELEPOS,Y	;init P/M
	STA	HPOSP0,Y	;horizontal pos
	DEY		;next P/M
	BPL	INITPM	;done? No.
	LDA	#64
	STA	DANHOR
;
	JSR	SETHTS	;elev heights
;
	LDA	#$7A	;Set P/M colors
	STA	COLRP0
	LDA	#$F8
	STA	COLRP1
	LDA	#$48
	STA	COLRP2
	LDA	#$90
	STA	COLRP3
;
	LDA	#$3F	;P/M widths
	STA	SIZEP0	;quadruple for
	STA	SIZEP1	;elevators (P0,
	STA	SIZEM	;P1,M0-M2)
	LDA	#0	;single for
	STA	SIZEP2	;Dan
	STA	SIZEP3	;(P2,P3)
	LDA	#$21
	STA	GPRIOR	;Multicolor PL
	LDA	# >P2AREA	;Set up zero
	STA	DAN1+1	;page pointers
	STA	D1S+1
	STA	D1D+1
	LDA	# >P3AREA
	STA	DAN2+1
	STA	D2S+1
	STA	D2D+1
	RTS
;
; The Display list interrupt routines
;
DLI1	PHA		;Save registers
	TXA
	PHA
	LDX	# >CHSET	;new charset
	LDA	#$C2
	STA	WSYNC
	STX	CHBASE
	EOR	COLRSH	;mask attract
	AND	DRKMSK
	STA	WSYNC
	STA	COLBAK	;change color
	LDA	# >DLI2
	STA	VDSLST+1
	LDA	# <DLI2
	STA	VDSLST	;next DLI
	PLA
	TAX
	PLA		;Restore regs
	RTI
;
DLI2	PHA		;Save registers
	TXA
	PHA
	LDA	#0
	STA	WSYNC
	STA	COLBAK	;Black ceiling
	LDX	COFSET
	LDA	COLORS,X	;get color
	EOR	COLRSH	;mask attract
	AND	DRKMSK
	STA	WSYNC
	STA	COLBAK
	INC	COFSET	;inc index
	LDA	COFSET	;table index
	CMP	#11	;last DLI?
	BNE	EX	;no.
	LDA	#$E0	;Yes, so restore
	STA	CHBASE	;default cset.
	LDA	#0
	STA	COFSET	;and zero index
	STA	COLPF0	;and color 0.
	LDA	# <DLI1	;Point back to
	STA	VDSLST	;first DLI.
	LDA	# >DLI1
	STA	VDSLST+1
EX	PLA
	TAX
	PLA		;Restore registers.
	RTI
;
; The Vertical Blank routine
;
VBI	LDA	OVERFLG	;Skip VBI if
	BEQ	V0	;game over.
	JMP	XVB
V0	LDA	DIEFLAG	;Dan dying?
	BNE	DAN	;Yes, skip elevs
;
; Check screen heights for elevators
; and reverse direction if necessary
;
C3	LDX	#6	;do 7 elevator
C0	LDA	HITES,X
	CMP	#32	;At top?
	BPL	C1	;No. skip
	CMP	#68	;Intermediate
	BPL	C1
	LDA	#1	;Going down!
	BNE	C2A
;
C1	CMP	#159	;intermediate
	BMI	C2
	CMP	#193	;At bottom?
	BMI	C2	;No. no change
	LDA	#0	;Yes, going up!
C2A	STA	DIR,X
C2	DEX		;next elevator
	BPL	C0	;done? No.
;
; Now set up for movement of elevators
;
	LDX	#6	;do 7 elevators
M1	CPX	ELDLAY	;slow it down?
	BNE	M2	;No.
	LDA	DLYCNT	;Yes.
	BEQ	M2	;Delay over yet?
	DEC	DLYCNT	;No.
	LDA	DLYCNT	;count down one
	AND	#3	;and skip a turn
	BEQ	M5	;every 1/15 sec.
M2	LDA	ELOCS,X	;P/M page
	STA	EHT+1
	LDA	HITES,X	;byte loc in page
	STA	EHT
	LDA	EMASKS,X	;Get mask
	EOR	#$FF	;save its inverse
	STA	EMSK
	LDA	DIR,X	;0=up, 1=down
	BEQ	UP
;
; Set up for down movement
;
	LDA	ESPEED,X	;elevator speed
	BEQ	D1
	INC	HITES,X
	INC	EHT	;double speed
D1	INC	HITES,X
	INC	EHT	;normal speed
	JMP	M4
;
; Set up for up movement
;
UP	LDA	ESPEED,X
	BEQ	U1
	DEC	HITES,X
	DEC	EHT	;double speed
U1	DEC	HITES,X
	DEC	EHT	;normal speed
;
; Execute the movement
;
M4	JSR	MV	;move the bytes
M5	DEX		;next elevator
	BPL	M1	;done? No.
;
	LDA	JIFFY	;Stall elevator?
	BNE	DAN	;(when JIFFY=0)
	JSR	ELNEW
;
; Elevators done. Now, we process
; Dan the Elevator Repair Man.
;
DAN	LDA	CLIMBF	;climbing?
	BEQ	VB1	;No.
	JSR	CLIMB1	;Yes, move him up
	JMP	DANEND	;and exit.
VB1	LDA	DIEFLAG	;Presently dying?
	BEQ	VB2	;No. skip
	JSR	DEATH	;Yes. keep dying
	JMP	XVB	;and exit.
VB2	LDY	FLOOR
	LDA	STAIRS,Y	;Has he reached
	CMP	DANHOR	;the stairs?
	BNE	VB4	;No.
	CPY	#10	;Top floor?
	BMI	VB3	;No, climb stairs
	JSR	ENDLEV	;Yes, so end it
	JMP	DANEND	;and exit.
VB3	JSR	SCLIMB	;init climbing
	JMP	DANEND	;and exit.
VB4	JSR	HITCHK	;Chk collision
	BEQ	VB5	;Dan hit? No.
	LDA	#120	;Yes, start 120
	STA	DIEFLAG	;jiffy death...
	BNE	DANEND	;and exit
;
; If we make it to here, it means our
; hero is either starting or in the
; midst of his perilous trek across
; the screen.
;
VB5	INC	SPDCNT	;Speed counter
	LDA	SPDCNT
	CMP	DANSPD	;Time to move?
	BMI	DANEND	;No, so exit.
	LDA	#0
	STA	SPDCNT	;Zero the counter
	LDX	DANDIR	;Save old dir
	JSR	JOY	;dir change?
	CPX	DANDIR
	BEQ	MOVEDAN	;No, skip
	JSR	DRAWDAN	;Yes, redraw him
MOVEDAN	LDA	DANDIR
	BMI	DANEND	;Wait on joystick
	LDY	FLOOR
	LDA	STARTS,Y	;Is Dan at start
	CMP	DANHOR	;of floor?
	BEQ	F3	;Yes, skip next
	CLC		;animate feet
	LDA	DANHT,Y
	ADC	#15	;Bottom of Dan
	TAY		;for feet.
	LDA	JIFFY
	AND	#7	;Mod 8 counter
	CMP	#4	;at 4 jiffies?
	BMI	F2
	LDA	#$18	;"feet in" byte
	BNE	F3A
F2	LDA	#$24	;"feet out" byte
F3A	STA	P2AREA,Y
F3	LDA	DANDIR
	ROR	A	;Right or left?
	BCC	MVRT	;Right (DANDIR=0)
	LDA	DANHOR	;trying to pass
	CMP	#$40	;left edge?
	BEQ	DANEND	;Yes, stop him
	DEC	DANHOR	;Dec horizontal
	JMP	MVLF
MVRT	LDA	DANHOR	;Trying to pass
	CMP	#$B8	;right edge?
	BEQ	DANEND	;Yes, stop him
	INC	DANHOR	;No, so move it
MVLF	LDA	DANHOR	;position shadow
	STA	HPOSP2	;and do the
	STA	HPOSP3	;horizontal move
;
DANEND	JSR	TIMER	;Do the timer
	JSR	MUSIC	;Do the music
XVB	STA	HITCLR	;clr collisions
	JMP	XITVBV	;and finish VBI!
;
; Subroutines
; -----------
;
; Pick an elevator to stall [0-6]
;
ELNEW	LDA	RANDOM
	AND	#7	;0-7
	CMP	#7
	BEQ	ELNEW	;0-6
	STA	ELDLAY
	LDA	#$80
	STA	DLYCNT
	RTS
;
; Animate the elevators - on entry,
; (EHT) pointS to the pertinent P/M
; area, and EMSK contains inverse bit
; mask, to zero out bits (tops and
; bottoms of elevators).  Elevators
; are 12 solid lines plus 2 blanks on
; top and 2 on bottom.
;
MV	LDY	#15	;16 bytes
	JSR	V2	;15-14 (bottom)
	DEY
V1	LDA	(EHT),Y	;lines 13 to 2
	AND	EMSK	;Clr current bits
	ORA	EMASKS,X	;set new ones
	STA	(EHT),Y
	DEY
	CPY	#1
	BNE	V1
V2	LDA	(EHT),Y	;line 1
	AND	EMSK	;Zero out bits
	STA	(EHT),Y	;with mask
	DEY
	LDA	(EHT),Y	;line 0 (top)
	AND	EMSK
	STA	(EHT),Y
	RTS
;
; Generate elevator starting heights
;
SETHTS	LDX	#6	;7 elevators
SH1	LDA	RANDOM
	AND	#$3F	;0-63
	ASL	A	;0-126 even
	ADC	#40	;40-166 even
	STA	HITES,X
	DEX
	BPL	SH1
	RTS
;
; This subroutine updates the
; countdown timer, and puts it to
; the screen
;
TIMER	LDA	CLIMBF	;Don't time
	BNE	TI1	;if climbing
	LDA	TIME+2
	BNE	TI0
	LDA	TIME+1
	AND	#$0F
	BEQ	TI1	;If 0 don't dec
TI0	SED		;Decimal math
	SEC
	LDA	TIME+3	;Fractional byte
	SBC	#17	;approx. 0.1 sec
	STA	TIME+3	;(rolls over
	LDA	TIME+2	;every 6 jiffies)
	SBC	#0
	STA	TIME+2
	LDA	TIME+1
	SBC	#0
	STA	TIME+1
	CLD
;
	LDA	TIME+2	;Take 3-byte (6
	AND	#$0F	;decimal digit),
	ORA	#$90	;take the low 3
	STA	TLINE+8	;digits and put
	LDA	TIME+2	;to the screen.
	LSR	A	;move high nybble
	LSR	A	;for 2nd decimal
	LSR	A	;digit down to
	LSR	A	;low nybble
	ORA	#$90	;make it ATASCII
	STA	TLINE+7	;put to screen
	LDA	TIME+1	;we only want low
	AND	#$0F	;nybble here
	STA	TIME+1	;(3 digits total)
	ORA	#$90	;make it ATASCII
	STA	TLINE+6	;put to screen
	LDA	#0
	STA	TIME	;not used
TI1	RTS
;
; This subroutine updates the scoring
; when Dan reaches a new floor
;
SCORING	LDX	#3	;3-byte (6-digit)
	SED		;decimal add
	CLC
SC1	DEX
	LDA	SCORE,X
	ADC	TIME,X
	STA	SCORE,X
	TXA
	BNE	SC1
	CLD
	STA	TIME	;Zero out timer
	STA	TIME+1
	STA	TIME+2
	STA	TIME+3
	LDX	#2
	LDY	#5
SC2	LDA	SCORE,X
	PHA		;Save it
	AND	#$0F	;low nybble
	ORA	#$90	;make it ATASCII
	STA	SSCORE,Y	;put on screen
	PLA		;use same byte
	LSR	A	;high nybble
	LSR	A	;we move it
	LSR	A	;down to
	LSR	A	;low nybble
	ORA	#$90	;make it ATASCII
	DEY
	STA	SSCORE,Y	;put to screen
	DEY
	DEX
	BPL	SC2
	RTS
;
; This subroutine reads the joystick.
;
JOY	LDA	STICK	;Read joystick
	AND	#8	;Right?
	BEQ	JLR	;Yes.
	LDA	STICK
	AND	#4	;No. left?
	BNE	JE	;No, dir same
	LDA	#1	;1 = left
JLR	STA	DANDIR
JE	RTS
;
; This subroutine updates the score
; and sets up the climb.
;
SCLIMB	JSR	SCORING	;Update score
	LDA	#16	;16 scan lines
	STA	CLIMBF	;to climb.
	LDY	FLOOR	;index to screen.
	LDA	DANHT,Y	;height table
	STA	CLIMBHT	;start climb here
	RTS
;
; This subroutine makes Dan climb 1
; scan line per VBI (if CLIMBF<>0).
; It continues into the INITIM
; subroutine.
;
CLIMB1	LDY	#0
	LDA	CLIMBHT	;Set up zero page
	STA	D1S	;pointers
	STA	D2S
	DEC	CLIMBHT	;destination is
	LDA	CLIMBHT	;one scan line up
	STA	D1D
	STA	D2D
CL1	LDA	(D1S),Y	;Move P2 up one.
	STA	(D1D),Y
	LDA	(D2S),Y	;Move P3 up one.
	STA	(D2D),Y
	INY
	CPY	#16	;All bytes moved?
	BMI	CL1	;No.
	LDA	#0	;Erase last line
	STA	(D1D),Y
	STA	(D2D),Y
	DEC	CLIMBF
	BNE	INITIM	;Is climb over?
	INC	FLOOR	;Yes, new floor.
;
; This subroutine sets timer to 250
;
INITIM	LDA	#0	;250 decimal
	STA	TIME
	LDA	#2
	STA	TIME+1
	LDA	#$50
	STA	TIME+2
	LDA	#$92	;"2"
	STA	TLINE+6
	LDA	#$95	;"5"
	STA	TLINE+7
	LDA	#$90	;"0"
	STA	TLINE+8
	RTS
;
; This subroutine sets up a new level,
; speeds of elevators and Dan, timer,
; Dan on bottom, increased level no.
;
SLEVEL	LDY	LEVEL
	CPY	#7	;Level 7 or more?
	BMI	SL0	;No.
	LDA	#1	;Yes, so we have
	STA	DANSPD	;superfast Dan.
SL0	CPY	#4	;Level 4 or more?
	BMI	SL1	;No.
	LDY	#4	;Yes, lev.4 speed
SL1	TYA
	ASL	A
	TAY		;Lev *2 index
	LDA	LEVSPD,Y	;elev speed tbl
	STA	ESP	;init 0 page pntr
	INY
	LDA	LEVSPD,Y
	STA	ESP+1
	LDY	#6	;Download elev
SL2	LDA	(ESP),Y	;speeds to 
	STA	ESPEED,Y	;zero page tbl
	DEY
	BPL	SL2
	JSR	PMSETUP	;reset P/M gr
	LDA	#0
	STA	FLOOR	;floor 0
	JSR	SFLOOR
	JSR	INITIM
	LDA	LEVEL
	ORA	#$90	;make it ATASCII
	STA	LEVBYTE	;put to screen.
	LDA	#0
	STA	NEWLVL	;Turn off flag.
	RTS
;
SFLOOR	LDY	FLOOR	;find hor. start
	LDA	STARTS,Y
	STA	HPOSP2	;put Dan there.
	STA	HPOSP3
	STA	DANHOR
	JSR	DRAWDAN	;Draw him
	LDA	#0
	STA	ATRACT	;defeat attract
	LDA	#$FF
	STA	DANDIR	;no initial dir.
	RTS
;
DRAWDAN	LDY	FLOOR	;index to height
	LDA	DANHT,Y	;tbl corresponds
	STA	DAN1	;to P/M memory
	STA	DAN2	;'height'
	LDY	#15	;draw 16 bytes
	LDA	DANDIR
	ROR	A	;Right or left?
	BCS	S2
;
; Draw Dan facing right
;
S1	LDA	DANRT1,Y	;P2 data
	STA	(DAN1),Y
	LDA	DANRT2,Y	;P3 data
	STA	(DAN2),Y
	DEY
	BPL	S1
	RTS
;
; Draw Dan facing left
;
S2	LDA	DANLF1,Y	;P2 data
	STA	(DAN1),Y
	LDA	DANLF2,Y	;P3 data
	STA	(DAN2),Y
	DEY
	BPL	S2
	RTS
;
; Death subroutine - flip-flop Dan
; for 1 second, then freeze for 1
; second.  If no lives are left,
; it ends the game.
;
DEATH	LDA	#0
	STA	AUDF0
	STA	AUDF1
	STA	AUDF2	;Silence music
	DEC	DIEFLAG	;lower counter
	LDA	DIEFLAG	;Done yet?
	BEQ	DE2	;Yes.
	CMP	#60	;time for freeze?
	BPL	DE8	;No.
	LDA	#0	;Yes...
	STA	AUDF3	;silence
	RTS		;skip flip-flop.
DE8	AND	#3	;No, flip Dan
	BNE	DE3	;every 4 jiffies
	LDA	DANDIR
	BEQ	DE1
	JSR	DRAWDAN	;flip left
	LDA	#0	;and set up for
	STA	DANDIR	;right flip
	LDA	#$20	;high note
	BNE	DE0
DE1	JSR	DRAWDAN	;flip right
	LDA	#1	;and set up for
	STA	DANDIR	;left flip
	LDA	#$40	;low note
DE0	STA	AUDF3
	RTS
;
; Death over
;
DE2	JSR	SFLOOR	;put Dan back
	DEC	MENBYT	;One less man...
	LDA	MENBYT	;Any men left?
	AND	#$0F
	BNE	DE3	;Yes, continue.
	LDA	# <OVERLN	;No, change
	STA	MSG	;top line LMS
	LDA	# >OVERLN	;LMS to show
	STA	MSG+1	;"GAME OVER"
	LDA	#1	;set flag
	STA	OVERFLG
	LDX	#0	;Compare score to
DE4	LDA	SSCORE,X	;high score
	CMP	HISCORE,X	;digit by digit
	BMI	DE3	;lt?, no change
	BNE	DE5	;gt?, update hi
	INX		;next digit
	CPX	#6
	BMI	DE4
	RTS
DE5	LDX	#5
DE6	LDA	SSCORE,X	;Move score
	STA	HISCORE,X	;to high score
	DEX
	BPL	DE6
DE3	RTS
;
; This subroutine does collision
; detection.
;
HITCHK	LDA	P2PL	;Did P2
	ORA	P3PL	;or P3 hit
	AND	#3	;elev 0,1,5,6?
	BNE	ENDCHK	;Yes, Dan's dead.
	LDA	M0PL	;Did M0 (elev 2)
	ORA	M1PL	;or M1 (elev 3)
	ORA	M2PL	;or M2 (elev 4)?
	AND	#$0C
ENDCHK	STA	HITCLR	;Clear collision
	RTS
;
ENDLEV	JSR	SCORING	;update score
	INC	LEVEL	;on to next level
	LDA	#1	;Flag so mainline
	STA	NEWLVL	;code can set up
	RTS		;a new level
;
; This subroutine produces the title
; screen, and waits for START.
;
TITLE	LDA	#0
	STA	SDMCTL	;disable DMA
	STA	COLOR0	;black letters
	LDA	# <TDLIST	;Point to
	STA	SDLSTL	;Display list
	LDA	# >TDLIST	;for title
	STA	SDLSTL+1	;screen
	LDA	#$3D	;narrow playfield
	STA	SDMCTL
	LDA	#$0E	;white letters
	STA	COLOR1
	LDA	#4	;center titles
	STA	HSCROL
X1	LDA	VCOUNT	;rainbow backgrnd
	BNE	X1	;wait for line 0
	TAY		;and keep track
	LDX	COLCNT	;colour counter
X2	STA	WSYNC	;sync to TV line
	STA	COLBAK	;store in reg
	INX		;inc color #
	TXA
	AND	#$F0	;but make it
	ORA	#$08	;luminance 8
	INY
	CPY	#$F0	;screen bottom?
	BNE	X2	;No.
;
; Now increase the starting colour for
; next TV frame, produces scrolling
; rainbow effect
;
	INC	COLCNT
	LDA	#8	;We have some
	STA	CONSOL	;time left to
	LDA	CONSOL	;check for START
	EOR	#6	;Pushed?
	BEQ	X3	;Yes, so exit
	STA	WSYNC	;keep stuffing
	STA	COLBAK
	BNE	X1	;Infinite loop
X3	RTS		;unless sent here
;
; This subroutine plays the music.
;
MUSIC	LDA	BASTIM	;New note time?
	BPL	BN0	;No.
	LDA	#14	;all notes
	STA	BASTIM	;are 15 jiffies.
	INC	BASCNT
BN0	LDA	BASCNT	;Get the note.
	AND	#7	;mod 8 counter
	TAY
	LDA	BASSLO,Y	;Bass is 16-bit
	STA	AUDF0	;sound, so stuff
	LDA	BASSHI,Y	;lo and hi bytes
	STA	AUDF1	;in channels 0,1
	LDX	BASTIM
	LDA	BASENV,X
	STA	AUDC1	;Apply envelope
	DEC	BASTIM	;dec. duration
;
; Melody (Treble)
;
	LDA	TRBTIM	;Note timer done?
	BPL	TN1	;No.
	INC	TRBCNT	;Yes - inc cntr
	LDY	TRBCNT	;Are we at...
	CPY	#26	;end of tune?
	BMI	TN0	;No.
	LDA	#$FF	;Yes, reset
	STA	TRBCNT	;counter
	BNE	TN2
TN0	LDA	TRBDUR,Y	;load the
	STA	TRBTIM	;duration
TN1	LDY	TRBCNT
	LDA	TREBLE,Y	;Play the note..
	STA	AUDF2
	DEC	TRBTIM	;and dec timer.
TN2	RTS
;
; Various Data Tables
;
ELEPOS	.BYTE	72,160,64,64
	.BYTE	108,124,140,0
COLORS	.BYTE	$82,$22,$B2,$42,$12,$52
	.BYTE	$72,$32,$62,$E4,$06
EMASKS	.BYTE	$C0,$0C,$03,$0C
	.BYTE	$30,$C0,$0C
ELOCS	.BYTE	>P0AREA,>P0AREA
	.BYTE	>MAREA,>MAREA
	.BYTE	>MAREA,>P1AREA
	.BYTE	>P1AREA
STARTS	.BYTE	$40,$B8,$40,$B8,$40
	.BYTE	$B8,$40,$B8,$40,$B8,$40
STAIRS	.BYTE	$B8,$40,$B8,$40,$B8
	.BYTE	$40,$B8,$40,$B8,$40,$B8
ESPED1	.BYTE	0,0,0,0,0,0,0
ESPED2	.BYTE	0,1,0,0,1,0,0
ESPED3	.BYTE	1,1,0,1,0,1,0
ESPED4	.BYTE	0,1,1,1,1,0,1
ESPED5	.BYTE	1,1,1,1,1,1,1
;
LEVSPD	.WORD	ESPED1,ESPED2,ESPED3
	.WORD	ESPED4,ESPED5
;
; Vertical height of tops of floors
;
DANHT	.BYTE	$C0,$B0,$A0,$90
	.BYTE	$80,$70,$60,$50
	.BYTE	$40,$30,$20
;
DANLF1	.BYTE	$00,$0F,$3F,$1C
	.BYTE	$34,$7D,$7D,$6F
	.BYTE	$06,$02,$1E,$3F
	.BYTE	$3F,$3F,$1E,$0C
DANLF2	.BYTE	$00,$0F,$3F,$03
	.BYTE	$0B,$02,$02,$10
	.BYTE	$18,$0E,$1E,$3D
	.BYTE	$39,$39,$1E,$00
DANRT1	.BYTE	$00,$78,$7E,$1C
	.BYTE	$16,$5F,$5F,$7B
	.BYTE	$30,$20,$3C,$7E
	.BYTE	$7E,$7E,$3C,$18
DANRT2	.BYTE	$00,$78,$7E,$60
	.BYTE	$68,$20,$20,$04
	.BYTE	$0C,$38,$3C,$5E
	.BYTE	$4E,$4E,$3C,$00
;
TLINE	.SBYTE	"      "
	.SBYTE	+$80,"000"
	.SBYTE	"       "
TOPLINE	.BYTE	1,$46,0,$46,0,0,$41,0
	.BYTE	$41,0,$41,0,$46,0,$46,5
LLINE	.BYTE	3,$46,0,$46,0,0,$41,0
	.BYTE	$41,0,$41,0,$46,0,$46,2
RLINE	.BYTE	1,$46,0,$46,0,0,$41,0
	.BYTE	$41,0,$41,0,$46,0,$46,4
INFOLN	.SBYTE	"SC "
SSCORE	.SBYTE	+$80,"000000"
	.SBYTE	" MEN "
MENBYT	.SBYTE	+$80,"0"
	.SBYTE	" HI "
HISCORE	.SBYTE	+$80,"000000"
	.SBYTE	" LEV "
LEVBYTE	.SBYTE	+$80,"0"
OVERLN	.SBYTE	"   GAME OVER    "
;
; Music Data
;
BASSLO	.BYTE	$6B,$6B,$96,$6B
	.BYTE	$EA,$6B,$03,$64
BASSHI	.BYTE	$35,$35,$2F,$35
	.BYTE	$2C,$35,$28,$2A
BASENV	.BYTE	$A2,$A6,$AA,$A8
	.BYTE	$A8,$A8,$A8,$A8
	.BYTE	$A8,$A8,$A7,$A5
	.BYTE	$A3,$A0,$A0
TREBLE	.BYTE	68,81,0,68,40,57,0,81
	.BYTE	68,60,57,0,57,0,57,0
	.BYTE	57,60,68,81,91,81,108
	.BYTE	96,0,0
TRBDUR	.BYTE	114,34,89,114,19,19,99
	.BYTE	14,14,14,19,0,18,0,18
	.BYTE	0,18,19,19,19,19,19,14
	.BYTE	14,127,80
;
; The Game Display List
;
DLIST	.BYTE	$70,$70,$C6
MSG	.WORD	TLINE
	.BYTE	$C7
	.WORD	TOPLINE
	.BYTE	$C7
	.WORD	LLINE
	.BYTE	$C7
	.WORD	RLINE
	.BYTE	$C7
	.WORD	LLINE
	.BYTE	$C7
	.WORD	RLINE
	.BYTE	$C7
	.WORD	LLINE
	.BYTE	$C7
	.WORD	RLINE
	.BYTE	$C7
	.WORD	LLINE
	.BYTE	$C7
	.WORD	RLINE
	.BYTE	$C7
	.WORD	LLINE
	.BYTE	$C7
	.WORD	RLINE
	.BYTE	$10,$46
	.WORD	INFOLN
	.BYTE	$06,$41
	.WORD	DLIST
;
; Title Screen Display List
;
TDLIST	.BYTE	$70,$70,$70,$70
	.BYTE	$70,$70,$47
	.WORD	GAME
	.BYTE	$70,$17,$70,$70,$46
	.WORD	AUTHOR
	.BYTE	$70,$70,$46
	.WORD	COPYR
	.BYTE	$70,$06,$70,$70,$56
	.WORD	INSTR
	.BYTE	$70,$70,$41
	.WORD	TDLIST
;
GAME	.SBYTE	"    ELEVATOR    "
	.SBYTE	"     REPAIRMAN      "
AUTHOR	.SBYTE	"BY FRED CAPRILLI"
COPYR	.SBYTE	"    (C) 1985    "
	.SBYTE	"ANALOG COMPUTING"
INSTR	.SBYTE	"    press"
	.SBYTE	" start     "
;
;MODIFIED CHARACTER SET
;
CSETB	.BYTE	$00,$00,$00,$00
	.BYTE	$00,$00,$00,$00
	.BYTE	$80,$80,$80,$80
	.BYTE	$80,$80,$80,$80
	.BYTE	$01,$01,$01,$01
	.BYTE	$01,$01,$01,$01
	.BYTE	$80,$FF,$80,$FF
	.BYTE	$80,$FF,$80,$FF
	.BYTE	$01,$FF,$01,$FF
	.BYTE	$01,$FF,$01,$FF
	.BYTE	$3C,$7E,$7E,$E7
	.BYTE	$E7,$FF,$FF,$FF
	.BYTE	$08,$08,$08,$08
	.BYTE	$08,$08,$08,$08
;
	*=	$02E0
;
	.WORD	INIT
	.END