A.N.A.L.O.G. ISSUE 22 / SEPTEMBER 1984 / PAGE 63

Money Hungry

16K Cassette or 24K Disk

by Donald P. Murphy

This month’s assembly language game, Money Hungry, is a game of skill for one player.

Typing it in.

Before typing anything, look at the listings accompanying this article.

Listing 1 is the BASIC data and data checking routine. This listing is used to create both cassette and disk versions of Money Hungry. The data statements are listed in hexadecimal (base 16), so the program will fit in 16K cassette systems. This makes typing more difficult, but it’s a necessary evil.

Listing 2 is the assembly language source code for the game of Money Hungry, created with the OSS MAC/65 assembler. You do not have to type this listing to play the game! It is included for those readers interested in assembly language. Follow the instructions below to make either a cassette or disk version of Money Hungry.

Cassette instructions.

  1. Type Listing 1 into your computer using the BASIC cartridge and verify your typing with C:CHECK (see page 47).
  2. Type RUN and press RETURN. The program will begin and 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 your DATA lines are correct, the computer will beep twice and prompt you to “READY CASSETTE AND PRESS RETURN.” 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 Money Hungry, 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 your computer OFF and remove all cartridges. Press the PLAY button on your recorder and turn ON your computer while holding down the START key. If you have a 600 or 800XL computer, you must hold the START and OPTION keys when you turn on the power. The computer will “beep” once. Hit the RETURN key and Money Hungry will load and run automatically.

Disk instructions.

  1. Type Listing 1 into your computer, using the BASIC cartridge and verify your typing with D:CHECK2 (see page 43).
  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 will 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. Money Hungry will load and run automatically.

Playing the game.

Money Hungry requires one joystick, plugged into port 1. The game is started by pressing START or the joystick button.

In Money Hungry, you play the part of a thief trying to collect as much money as possible, while making every effort to avoid the police. You are placed in a maze, with coins scattered all around. You pick up the coins by moving over them. Once on every board, a money bag appears, containing a 100 coin bonus. Your score, in coins, is shown at the bottom of the screen.

There are three police patrolling the maze, and if they catch you five times, the game is over. The number of tries you have remaining is shown at the lower left of the screen.

You can block the police by placing doors in the maze. To do this, press the joystick button while moving through the maze. A red door will appear, and the police can’t get through it. You have four such doors and can reopen them at any time simply by running over them. Once you pick up a door, you can reuse it by pressing the joystick button again.

When you have picked up all of the coins in the maze, you will move to the next level. In each level, either you or the police will increase in speed. Good

BASIC listing.

10 REM *** MONEY HUNGRY ***
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,68:PUT #1,33:CLOSE #1:END 
160 FOR X=1 TO 107: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,158:PUT #1,32:PUT #1,10:PUT #1,44: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,24,118,32,157,32,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,68,133,10,169,33,133,11,24,96
1000 DATA 7070707070707047B420700670077070707006419E20000000002D2F2E25390028352E27323900000000000000,530
1010 DATA 000000000000E2F9000000000000000000000000646F6E616C6400006D7572706879000000F0F2E5F3F300F3F4,992
1020 DATA E1F2F400F4EF00E2E5E7E9EE70707045003A050505050505050505050741042136147F362A7F1C3E00FA8A8ABA,191
1030 DATA E6E6FFBAFF771C08143E1C1C3E00388888EAEA38EAEA38A7A1ADA5AFB6A5B2A200BDFD279D0038BDFD289D0039,996
1040 DATA BDFE299D003ABDFE2A9D003BCAD0E5A9208D3102A99E8D3002A9228D2F02AD1FD0C906F005AD8402D0F4A9048D,276
1050 DATA 3002A9218D3102A9388DF402A9888DC402A9FC8DC502A9368DC602A9008D6F028D08D2A9038D320220692220BB,838
1060 DATA 22206B23200E238D1ED020712620F72220DA26A200AD0CD0F0034C0D278D0AD4AC0BD4B900188D12D0B900198D,901
1070 DATA 13D0B9001A8D14D0B9001B8D15D0A5CDC96B90D44C9726C6B6F0034C4426A5B785B6A91E85B1A98085B0A91985,499
1080 DATA B3A90085B2AABD05D02904F0138D1ED0B58CD589D0044901958CB5894901958986C1B5B9186901B4BEC8209525,948
1090 DATA A6C1B58C2902F007A588F0074C5122A587D00BB58C9589AD0AD22903958CB589D0034CD525C901D0034CE825C9,323
1100 DATA 02D0034CFB254C1D26A9008DDB3A8DDC3AA90085B0A93A85B1A006B1B0F00EC91EF00AC91FD00A88A90091B0C8,594
1110 DATA A91191B0C8C8C02490E4A5B018692885B0A5B1690085B1A006C93B90D1A5B0C990D0CBA90085CD85BCA905858F,831
1120 DATA 60A91E85B1A90085B0A891B0C8D0FBE6B1A6B1E020D0F3A91885B1A90085B0A891B0C8D0FBE6B1A6B1E01CD0F3,101
1130 DATA A92E8D2F02A9038D1DD0A91C8D07D460A906A223A091205CE4A9408D0FD4A907A221A0F04C5CE4A98085B0A91E,311
1140 DATA 85B1A90085B2A91985B3A017A208BD182191B0BD212191B2C8CA10F2E6B3A5B018698085B0A5B1690085B1C920,71
1150 DATA 90DBA94385B98D01D0A98485BA8D02D0A9B385BB8D03D0A91785BE85BF85C0A9038589858BA901858A60A208A0,74
1160 DATA 37BD2A2199001EBD3321990018C8CA10F0A97C85B88D00D0A93785BDA90B85CB85CC60A9008D01D28D03D2A6B8,363
1170 DATA E8A4BDC8205C2420A624C681F0034C5924A5808581A5CC2903C903F007A584F0074CC723A583D004A5CC85CBAD,972
1180 DATA 7802C90FF00285CCA5CBC90FD0034C5924C90AF008C906F004C90ED020A20AA4BDC018B0034C5924B9001E99FF,994
1190 DATA 1DB9001899FF17C8CAD0F0C6BD4C5924C909F008C905F004C90DD023A5BDC95790034C59246909A8A20AB9FF1D,379
1200 DATA 99001EB9FF1799001888CAD0F0E6BD4C5924C90BD012A6B8E044B0034C5924CA86B88E00D04C5924A6B8E0B390,36
1210 DATA 034C5924E886B88E00D04C5FE486C584C69838E91085C3A90885C4A90085C2203E258583A5C285C62901D004A9,495
1220 DATA 018583A5C538E93085C3A90485C4A90085C2203E258584A5C285C529034901F004A9018584A5C285C560A90085,754
1230 DATA B485CAA5CB2901D00AA5CCC90BD002C6C6E6C6A5C685C7A92885C8205E25E6C5A5C51865C985B4A5CA693A85B5,184
1240 DATA A000B1B4C91ED011A9268D01D2A9148D00D2A900A891B4E68FC91FD017A9268D01D2A9148D00D2A900A891B4C6,713
1250 DATA B491B4E6B4E68FC911F01CC91DD02BA9A68D01D2A9DC8D00D2A26486BCC6B49891B4E6B491B4609891B4E6CDA2,739
1260 DATA 0186BCA95F8D01D2A9B98D00D260A00838E5C40826C206C32A289005E5C44C532565C488D0EDB00365C41826C2,31
1270 DATA 60A90085C9A20846C790031865C86A66C9CAD0F385CA60A005E001B00160B9BF3BC91B9009A91299BF3B8810F1,496
1280 DATA 6018690199BF3BCAD0E06085889838E91085C3A90885C4A90085C2203E258587A5C22901D004A9018587A58838,718
1290 DATA E93085C3A90485C4A90085C2203E258588A5C229034901F004A901858860B4B9C0B390034C4426C89895B99D01,890
1300 DATA D04C4426B4B9C044B0034C4426889895B99D01D04C4426B4BEA20AC018B0034C4426B1B08891B0C8B1B28891B2,379
1310 DATA C8C8CAD0F0A6C1D6BE4C4426A6C1B5BEC95790034C44266909A8A20A88B1B0C891B088B1B2C891B288CAD0F0A6,151
1320 DATA C1F6BE4C4426A5B018698085B0A5B1690085B1E6B3A6C1E8E003B0034C0C22A6BCA90085BC207425AD8402D003,701
1330 DATA 2050274C62E4A903858085B7858185B6A013A90099B83B88D0FAA9578DBA3BA000A91299BF3BC8C006D0F860A5,425
1340 DATA B7C580F008C680D00CA9018580C6B7D004A90185B720C82620D22720692220BB22200E23206B2320F72220DA26,68
1350 DATA 4CC121A906A2E4A05F205CE4A907A2E4A0624C5CE4A9268D2702A9ED8D2602A901A000A2044C5CE4A91C8DDB3A,245
1360 DATA A91D8DDC3AA9278D2702A9048D26024CE426A9008DDB3A8DDC3A6020C826209127AEBA3BCAE052B0034C33278E,950
1370 DATA BA3B20BB22206B23200E2320F7228D1ED04CC121A200BD3C219DBA3BE8E004D0F5A200BD40219DC63BE8E004D0,986
1380 DATA F54C7021C68FD003E68F60A584F017A5C52903D02DA9C08D02D2A9A38D03D2A000A91E91B460A5C62901D016A9,676
1390 DATA C08D02D2A9A38D03D2C6B4A001A91F91B48891B460E68F60A9A88D03D2A9648590A2FFA014A5908D02D2CAD0F8,151
1400 DATA 88D0F5E690E690A014A590C9A0D0E9A9888D03D2A9328D02D2A2FFA0FFCAD0FD88D0FAA9008D02D28D03D260A9,240
1410 DATA A88D01D2A9408591A2FFA014A5918D00D2CAD0F888D0F5C691C691A014A591D0EBA9008D00D28D01D260000000,363
1420 DATA 0000000000555555AA55555555959595AA55555555555555AA9595959595959595959595951515151515151515,466
1430 DATA 959595AA95959595565656AA56565656555555AA56565656565656AA5555555554545454545454545656565656,90
1440 DATA 565656555555555555555595959595555555555656565655555555555555959595959555555556565656560000,333
1450 DATA 008000000000003C666E76663C000018381818187E00003C660C18307E00007E0C180C663C00000C1C3C6C7E0C,345
1460 DATA 00007E607C06663C00003C607C66663C00007E060C18303000003C663C66663C00003C663E060C3800220A2AA0,697
1470 DATA A2A02A0A88A0280A2A0A28A0C0C0C0C0C0C0C0C0000000FF00000000003C666E6E603E0000183C66667E660000,516
1480 DATA 7C667C66667C00003C666060663C0000786C66666C7800007E607C60607E00007E607C60606000003E60606E66,134
1490 DATA 3E000066667E66666600007E181818187E000006060606663C0000666C78786C66000060606060607E00006377,850
1500 DATA 7F6B6363000066767E7E6E6600003C666666663C00007C66667C606000003C6666666C3600007C66667C6C6600,328
1510 DATA 003C603C06063C00007E1818181818000066666666667E0000666666663C18000063636B7F7763000066663C3C,964
1520 DATA 6666000066663C18181800007E0C1830607E00001E181818181E0000406030180C060000781818181878000008,686
1530 DATA 1C3663000000000000000000FF0000000000050301010103010101030101010301010103010101030101010301,167
1540 DATA 0101030101080A0000000000000504001100110011001100110011001100110011001100110011001100110011,456
1550 DATA 0B0A00000000000005040011010600110106001101060011010600110106001101060011010600110B0A000000,692
1560 DATA 00000005040011001100110011001100110011001100110011001100110011001100110B0A0000000000000504,986
1570 DATA 0011010600110106001101060011010600110106001101060011010600110B0A00000000000005040000000000,201
1580 DATA 000000000000000000000000110011001100110011001100110B0A000000000000050400110106001101060011,415
1590 DATA 01060011010600110106001101060011010600110B0A0000000000000504001100110011001100110011001100,684
1600 DATA 1100110011001100110011001100110B0A00000000000005040011010600110106001101060011010600110106,970
1610 DATA 001101060011010600110B0A000000000000050400110011001100110011001100110011001100110011001100,269
1620 DATA 11001100110B0A0000000000000502010101020101010201010102010101020101010201010102010101020101,385
1630 DATA 090A0000000000570000000012121212121A000000000000000000000000000000000000000000000000000000,607
1640 DATA 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,607

Assembly listing.

         .OPT NO LIST
; MONEY HUNGRY
;
; BY DONALD MURPHY
;
; ANALOG COMPUTING
;
;VARIABLES
;
LEVEL    =   $80     ;LEVEL #
DELAY    =   $81     ;DELAY INDEX
HERE     =   $82
NOX      =   $83     ;HORIZ. MOVE FLAG
NOY      =   $84     ;VERT. MOVE FLAG
TX       =   $85     ;X HOLD AREA
DM       =   $86     ;MISC. VARIABLE
XM       =   $87     ;HORIZ. FLAG
YM       =   $88     ;VERT. FLAG
DIRC     =   $89     ;ENMY CUR DIRECTION
DIRN     =   $8C     ;NEXT ENMY DIRECTION
NDOOR    =   $8F     ;# OF DOORS
TF3      =   $90
TF4      =   $91
POINTL   =   $B0     ;GENERAL POINTER
POINTH   =   $B1
TABPTL   =   $B2     ;TABLE POINTER
TABPTH   =   $B3
VBPNTL   =   $B4     ;VBLANK POINTER
VBPNTH   =   $B5
EDELAY   =   $B6     ;ENEMY DELAY
ELEVEL   =   $B7     ;ENEMY LEVEL
XPOSP0   =   $B8     ;HORIZ. POS. PLR 0
XPOSP1   =   $B9     ;HORIZ. POS. PLR 1
XPOSP2   =   $BA     ;HORIZ. POS. PLR 2
XPOSP3   =   $BB     ;HORIZ. POS. PLR 3
SCOUNT   =   $BC     ;SCORE COUNT TO ADD
YPOSP0   =   $BD     ;VERT. POS. PLR 0
YPOSP1   =   $BE     ;VERT. POS. PLR 1
YPOSP2   =   $BF     ;VERT. POS. PLR 2
YPOSP3   =   $C0     ;VERT. POS. PLR 3
TEMPX    =   $C1     ;VERT. POS. PLR 4
DRES     =   $C2     ;DIVISION RESULT
LDIV     =   $C3     ;LOW DIVIDEND
DIVS     =   $C4     ;DIVISOR
XPOSSC   =   $C5     ;HOR. POS. ON SCRN
YPOSSC   =   $C6     ;VERT POS. ON SCRN
MUPL     =   $C7     ;LO MULTIPLIER
MUCN     =   $C8     ;MULTIPLICAND
RESL     =   $C9     ;RESULT
RESH     =   $CA
STICKC   =   $CB     ;STICK VALUE
STICKN   =   $CC     ;NEXT STICK VALUE
NDOTS    =   $CD     ;#DOTS EATEN
;
;HARDWARE & SHADOW LOCATIONS
;
COLOR0   =   $02C4   ;PLAYFIELD COLORS
COLOR1   =   $02C5
COLOR2   =   $02C6
SDLSTL   =   $0230   ;DISP LIST POINTER
SDLSTH   =   $0231
CHBAS    =   $02F4   ;CHAR BASE ADDR
GRACTL   =   $D01D   ;GRAPHICS CONTROL
SDMCTL   =   $022F   ;DMA CONTROL
COLPM0   =   $D012   ;P/M COLORS
COLPM1   =   $D013
COLPM2   =   $D014
COLPM3   =   $D015
HPOSP0   =   $D000   ;PLAYER HOR. POS.
HPOSP1   =   $D001
HPOSP2   =   $D002
HPOSP3   =   $D003
PMBASE   =   $D407   ;P/M BASE ADDRESS
VCOUNT   =   $D40B   ;VERT. LINE COUNTER
WSYNC    =   $D40A   ;WAIT FOR SYNC
P0PF     =   $D004   ;COLLISION REGISTERS
P0PL     =   $D00C
P1PF     =   $D005
HITCLR   =   $D01E   ;COLLISION CLEAR
RANDOM   =   $D20A   ;RANDOM #
NMIST    =   $D40F   ;NMI STATUS
AUDCTL   =   $D208   ;AUDIO CONTROL
AUDC1    =   $D201   ;AUD. CHANNELS
AUDC2    =   $D203
AUDF1    =   $D200   ;AUD. FREQUENCIES
AUDF2    =   $D202
CONSOL   =   $D01F   ;CONSOLE KEYS
SKCTL    =   $0232   ;SERIAL PORT CTRL
GPRIOR   =   $026F   ;P/M PRIORITY
STICK0   =   $0278   ;STICK 0
STRIG0   =   $0284   ;BUTTON 0
;
;TABLES AND RAM ASSIGNMENTS
;
CTAB0    =   $1800   ;PL.0 COLORS
CTAB1    =   $1900   ;PL.1 COLORS
CTAB2    =   $1A00   ;PL.2 COLORS
CTAB3    =   $1B00   ;PL.3 COLORS
CHSET    =   $3800   ;CHARACTER SET
SCRAM    =   $3A00   ;SCREEN ADDRESS
PMRAM    =   $1C00   ;P/M ADDRESS
;
;PROGRAM START
;
         *=  $209E
;
;TITLE SCREEN DISPLAY LIST
;
TSCRD    .BYTE 112,112,112,112,112
         .BYTE 112,112,$47
         .WORD TSCRW
         .BYTE 112,6,112,7,112,112,112
         .BYTE 112,6,$41
         .WORD TSCRD
;
;TITLE SCREEN DATA
;
TSCRW    .BYTE 0,0,0,0,45,47,46,37
         .BYTE 57,0,40,53,46,39,50,57
         .BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0
         .BYTE 226,249,0,0,0,0,0,0,0,0,0
         .BYTE 0,0,0,100,111,110,97
         .BYTE 108,100,0,0,109,117,114
         .BYTE 112,104,121,0,0,0,240,242
         .BYTE 229,243,243,0,243,244,225
         .BYTE 242,244,0,244,239,0,226
         .BYTE 229,231,233,238
;
;GAME BOARD DISPLAY LIST
;
DLIST    .BYTE 112,112,112,$45
         .WORD SCRAM
         .BYTE 5,5,5,5,5,5,5
         .BYTE 5,5,5,7,65
         .WORD DLIST
;
;PLAYER COLORS & BIT MAPS
;
ENBMAP   .BYTE 54,20,127,54
         .BYTE 42,127,28,62,0
ENCMAP   .BYTE $FA,$8A,$8A,$BA
         .BYTE $E6,$E6,$FF,$BA,$FF
PLBMAP   .BYTE 119,28,8,20,62
         .BYTE 28,28,62,0
PLCMAP   .BYTE $38,$88,$88,$EA
         .BYTE $EA,$38,$EA,$EA,$38
GAME     .BYTE $A7,$A1,$AD,$A5
OVER     .BYTE $AF,$B6,$A5,$B2
;
;GAME EXECUTION STARTS HERE!
;
INIT     LDX #0
INILP    LDA CHDAT,X ;SET UP
         STA CHSET,X ;CHAR SET
         LDA CHDAT+256,X
         STA CHSET+256,X
         LDA SCDAT,X ;AND SCREEN
         STA SCRAM,X
         LDA SCDAT+256,X
         STA SCRAM+256,X
         DEX 
         BNE INILP
         LDA # >TSCRD ;SHOW...
         STA SDLSTH  ;TITLE SCREEN
         LDA # <TSCRD
         STA SDLSTL
         LDA #$22
         STA SDMCTL
PROG     LDA CONSOL ;GET CONSOLE
         CMP #6      ;START PRESSED?
         BEQ GO      ;YES!
         LDA STRIG0  ;TRIGGER PRESSED?
         BNE PROG    ;NO!
GO       LDA #DLIST&255 ;SHOW...
         STA SDLSTL  ;GAME SCREEN
         LDA #DLIST/256
         STA SDLSTH
         LDA #CHSET/256 ;POINT TO
         STA CHBAS   ;CHAR SET
         LDA #$88    ;SET COLORS
         STA COLOR0
         LDA #$FC
         STA COLOR1
         LDA #$36
         STA COLOR2
         LDA #0      ;SET...
         STA GPRIOR  ;PRIORITY
         STA AUDCTL  ;AND AUDIO
         LDA #3      ;RESET SOUNDS
         STA SKCTL
         JSR SETSC   ;SETUP SCREEN
         JSR SETPM   ;SETUP P/M
         JSR SETPL   ;SET YOU
         JSR SETEM   ;SET ENEMIES
         STA HITCLR  ;CLEAR COLLISIONS
         JSR INT     ;MISC. INIT.
         JSR SETVB   ;START VBLANK
         JSR PRIZE   ;INIT MONEY BAG
         LDX #0      ;ZERO X REG
;
;MAINLINE COLOR LOOP
;
COLOR    LDA P0PL  ;HIT ANYTHING?
         BEQ CONT    ;NO, CONTINUE
         JMP DEATH   ;YOU'RE DEAD!
CONT     STA WSYNC  ;WAIT FOR SYNC
         LDY VCOUNT  ;GET VERT LINE#
         LDA CTAB0,Y ;GET COLOR FOR
         STA COLPM0  ;PLAYER 0
         LDA CTAB1,Y ;GET COLOR FOR
         STA COLPM1  ;PLAYER 1
         LDA CTAB2,Y ;GET COLOR FOR
         STA COLPM2  ;PLAYER 2
         LDA CTAB3,Y ;GET COLOR FOR
         STA COLPM3  ;PLAYER 3
         LDA NDOTS   ;# OF DOTS...
         CMP #107    ;=107?
         BCC COLOR   ;NO, GET NEXT COLOR
         JMP NEXTL   ;NEW LEVEL!
;
;DEFERRED VBLANK
;
DVBL     DEC EDELAY ;TIME FOR EN. MOVE?
         BEQ EDO     ;YES!
         JMP END     ;NO, EXIT
EDO      LDA ELEVEL  ;RESET MOVE TIMER
         STA EDELAY
         LDA #PMRAM/256+2 ;POINT TO
         STA POINTH  ;PLAYERS
         LDA #$80
         STA POINTL
         LDA #CTAB1/256 ;GET COLOR...
         STA TABPTH  ;TABLE OFFSET
         LDA #0
         STA TABPTL
         TAX         ;ZERO X
MAIN     LDA P1PF,X ;HIT ANYTHING?
         AND #4      ;GET COLL. BITS
         BEQ NHDR    ;NO COLLISIONS
         STA HITCLR  ;RESET COLLISIONS
         LDA DIRN,X  ;NEXT DIRECTION
         CMP DIRC,X  ;= CURRENT DIR?
         BNE EOR1    ;NO, CHANGE IT.
         EOR #1      ;REVERSE IT,
         STA DIRN,X  ;STORE IT.
EOR1     LDA DIRC,X ;GET CURRENT
         EOR #1      ;REVERSE IT,
         STA DIRC,X  ;AND STORE.
NHDR     STX TEMPX  ;SAVE X
         LDA XPOSP1,X ;GET PLAYER X'S
         CLC         ;HORIZ. POS,
         ADC #1      ;ADD 1,
         LDY YPOSP1,X ;GET VERT POS,
         INY         ;ADD 1
         JSR PMOVE   ;MOVE PLAYER
         LDX TEMPX   ;GET X AGAIN
         LDA DIRN,X  ;GET NEXT DIRECTION
         AND #2      ;GET 1ST 2 BITS
         BEQ TXM     ;TRY HORIZ. MOVE
         LDA YM      ;OK TO MOVE VERT?
         BEQ CCHD    ;YES, CHANGE DIR
         JMP KCD     ;NO, KEEP CURRENT
TXM      LDA XM      ;HORIZ MOVE OK?
         BNE KCD     ;NO, KEEP CURRENT
CCHD     LDA DIRN,X ;CHANGE DIRECTION
         STA DIRC,X  ;STORE NEXT DIR
         LDA RANDOM  ;GET RANDOM #
         AND #3      ;MASK TO 0-3
         STA DIRN,X  ;SAVE FOR NEXT
KCD      LDA DIRC,X  ;GET CURRENT DIR
         BNE TA1     ;NOT RIGHT
         JMP MPXR    ;MOVE RIGHT!
TA1      CMP #1      ;IS IT LEFT?
         BNE TA2     ;NO!
         JMP MPXL    ;MOVE LEFT!
TA2      CMP #2      ;IS IT UP?
         BNE TA3     ;NO!
         JMP MPXU    ;MOVE UP!
TA3      JMP MPXD    ;MOVE DOWN!
;
;SET UP SCREEN
;
SETSC    LDA #0      ;ERASE MONEY BAG
         STA SCRAM+219
         STA SCRAM+220
         LDA #SCRAM&255 ;POINT...
         STA POINTL  ;TO SCREEN
         LDA #SCRAM/256
         STA POINTH
         LDY #6      ;SCRN BORDER OFFSET
L1       LDA (POINTL),Y ;GET SCRN BYTE
         BEQ NFL     ;EMPTY-PLOT DOT!
         CMP #30     ;IS IT DOT?
         BEQ NFL     ;YES, PLOT AGAIN!
         CMP #31     ;WALL?
         BNE PL1     ;YES, DON'T PLOT
         DEY         ;PREVIOUS POS.
         LDA #0      ;ZERO IT!
         STA (POINTL),Y
         INY         ;BACK TO THIS POS.
NFL      LDA #17     ;PLOT A DOT.
         STA (POINTL),Y
PL1      INY         ;NEXT POSITION
         INY 
         CPY #36     ;END OF LINE?
         BCC L1      ;NO!
         LDA POINTL  ;INCREMENT...
         CLC         ;POINTER...
         ADC #40     ;TO NEXT LINE
         STA POINTL
         LDA POINTH
         ADC #0
         STA POINTH
         LDY #6      ;LAST LINE?
         CMP #SCRAM/256+1
         BCC L1      ;NO!
         LDA POINTL  ;LAST LINE?
         CMP #144
         BNE L1      ;NO!
         LDA #0      ;RESET...
         STA NDOTS   ;# OF DOTS
         STA SCOUNT  ;AND SCORE COUNT
         LDA #5      ;RESET # DOORS
         STA NDOOR
         RTS         ;ALL DONE!
;
;INIT PLAYER-MISSILE GRAPHICS
;
SETPM    LDA #PMRAM/256+2 ;POINT...
         STA POINTH  ;TO...
         LDA #0      ;PLAYER MEMORY
         STA POINTL
         TAY         ;ZERO Y REG.
L3       STA (POINTL),Y ;ZERO P/M AREA
         INY 
         BNE L3
         INC POINTH
         LDX POINTH  ;DONE CLEARING?
         CPX #PMRAM/256+4
         BNE L3      ;NO!
         LDA #CTAB0/256 ;POINT...
         STA POINTH  ;TO...
         LDA #0      ;COLOR TABLES
         STA POINTL
         TAY         ;ZERO Y REG.
Q1       STA (POINTL),Y ;ZERO COLOR TABLES
         INY 
         BNE Q1
         INC POINTH
         LDX POINTH  ;DONE CLEARING?
         CPX #CTAB3/256+1
         BNE Q1      ;NO!
         LDA #46     ;TURN ON P/M
         STA SDMCTL
         LDA #3
         STA GRACTL
         LDA #PMRAM/256 ;POINT TO...
         STA PMBASE  ;P/M AREA
         RTS         ;ALL DONE!
;
;RUN VBLANK ROUTINES
;
SETVB    LDA #6      ;SET IMMEDIATE!
         LDX #VBLANK/256
         LDY #VBLANK&255
         JSR $E45C
         LDA #64     ;TURN ON
         STA NMIST
         LDA #7      ;SET DEFERRED!
         LDX #DVBL/256
         LDY #DVBL&255
         JMP $E45C   ;ALL DONE!
;
;DRAW ENEMIES ON SCREEN
;
SETEM    LDA #$80    ;POINT TO P/M
         STA POINTL
         LDA #PMRAM/256+2
         STA POINTH
         LDA #0      ;POINT TO COLORS
         STA TABPTL
         LDA #CTAB1/256
         STA TABPTH
L4       LDY #23     ;P/M VERT OFFSET
         LDX #8      ;P/M HEIGHT
L5       LDA ENBMAP,X ;DRAW ONE!
         STA (POINTL),Y
         LDA ENCMAP,X
         STA (TABPTL),Y
         INY 
         DEX 
         BPL L5
         INC TABPTH  ;NEXT COLOR TABLE
         LDA POINTL  ;NEXT PLAYER
         CLC 
         ADC #$80
         STA POINTL
         LDA POINTH
         ADC #0
         STA POINTH
         CMP #PMRAM/256+4 ;LAST PLAYER?
         BCC L4      ;NO!
         LDA #$43    ;PL 1 HORIZONTAL
         STA XPOSP1
         STA HPOSP1
         LDA #$84    ;PL 2 HORIZONTAL
         STA XPOSP2
         STA HPOSP2
         LDA #$B3    ;PL 3 HORIZONTAL
         STA XPOSP3
         STA HPOSP3
         LDA #23     ;ALL VERTICAL
         STA YPOSP1
         STA YPOSP2
         STA YPOSP3
         LDA #3      ;P1&3 GOING DOWN
         STA DIRC
         STA DIRC+2
         LDA #1      ;P2 GOING LEFT
         STA DIRC+1
         RTS         ;ALL DONE!
;
;SET UP YOUR PLAYER
;
SETPL    LDX #8      ;8 BYTES TALL
         LDY #55     ;GET VERT OFFSET
L6       LDA PLBMAP,X ;DRAW HIM!
         STA PMRAM+512,Y
         LDA PLCMAP,X
         STA CTAB0,Y
         INY 
         DEX 
         BPL L6
         LDA #124    ;SET HORIZ POS
         STA XPOSP0
         STA HPOSP0
         LDA #55     ;AND VERT POS
         STA YPOSP0
         LDA #11     ;GOING LEFT!
         STA STICKC
         STA STICKN
         RTS         ;BYE!
;
;IMMEDIATE VBLANK
;
VBLANK   LDA #0      ;TURN OFF...
         STA AUDC1   ;SOUND 1
         STA AUDC2   ;SOUND 2
         LDX XPOSP0  ;GET PLAYER X
         INX         ;OFFSET FOR SCRN
         LDY YPOSP0  ;GET PLAYER Y
         INY         ;OFFSET IT TOO
         JSR PMTGR   ;CONVERT TO SCRN LOC
         JSR XYTOME  ;THEN TO ADDRESS
         DEC DELAY   ;OK TO MOVE?
         BEQ DO      ;YUP!
         JMP ENDVB   ;NO, EXIT.
DO       LDA LEVEL   ;RESET TIMER
         STA DELAY
         LDA STICKN  ;GET NEXT DIRECTION
         AND #3      ;MASK IT,
         CMP #3      ;HORIZ MOVEMENT?
         BEQ TNM     ;YES!
         LDA NOY     ;CHECK IF VERT CLEAR
         BEQ CHD     ;IT'S CLEAR!
         JMP CD      ;KEEP CURRENT DIR
TNM      LDA NOX     ;HORIZ CLEAR?
         BNE CD      ;NO! KEEP CURRENT
CHD      LDA STICKN  ;GET NEXT MOVE
         STA STICKC  ;SAVE IN CURRENT
CD       LDA STICK0  ;GET STICK
         CMP #15     ;MOVED?
         BEQ NC      ;NO!
         STA STICKN  ;SAVE NEW MOVE
NC       LDA STICKC  ;GET CURRENT
         CMP #15     ;MOVED?
         BNE N15     ;YES!
         JMP ENDVB   ;NO, EXIT.
N15      CMP #10     ;UP?
         BEQ MU      ;YES!
         CMP #6      ;UP?
         BEQ MU      ;YES!
         CMP #14     ;UP?
         BNE VBP1    ;NO!
MU       LDX #$0A    ;10 BYTES TO MOVE
         LDY YPOSP0  ;GET VERT OFFSET
         CPY #24     ;AT TOP?
         BCS VBL1    ;NO, MOVE IT!
         JMP ENDVB   ;BYE!
VBL1     LDA PMRAM+512,Y ;MOVE PLAYER
         STA PMRAM+511,Y
         LDA CTAB0,Y
         STA CTAB0-1,Y
         INY 
         DEX 
         BNE VBL1
         DEC YPOSP0  ;DEC VERT POS.
MUE      JMP ENDVB   ;BYE!
VBP1     CMP #9      ;DOWN?
         BEQ MD      ;YES!
         CMP #5      ;DOWN?
         BEQ MD      ;YES!
         CMP #13     ;DOWN?
         BNE VBP2    ;NO!
MD       LDA YPOSP0  ;AT BOTTOM?
         CMP #87
         BCC OKMD    ;NO, MOVE IT!
         JMP ENDVB   ;;BYE!
OKMD     ADC #9      ;GET LAST PLAYER BYTE
         TAY         ;PUT IN Y
         LDX #$0A    ;10 BYTES TO MOVE
VBL2     LDA PMRAM+511,Y ;MOVE PLAYER
         STA PMRAM+512,Y
         LDA CTAB0-1,Y
         STA CTAB0,Y
         DEY 
         DEX 
         BNE VBL2
         INC YPOSP0  ;INC VERT POS.
MDE      JMP ENDVB   ;BYE!
VBP2     CMP #11     ;LEFT?
         BNE VBP3    ;NO!
         LDX XPOSP0  ;TOO FAR LEFT?
         CPX #68
         BCS OKML    ;NO!
         JMP ENDVB   ;BYE!
OKML     DEX         ;DEC HORIZ POS
         STX XPOSP0
         STX HPOSP0
MLE      JMP ENDVB   ;BYE!
VBP3     LDX XPOSP0  ;TOO FAR RIGHT?
         CPX #179
         BCC OKMR    ;NO!
         JMP ENDVB   ;BYE!
OKMR     INX         ;INC HORIZ POS
         STX XPOSP0
         STX HPOSP0
ENDVB    JMP $E45F   ;LEAVE VBLANK!
;
;P/M TO SCREEN COORDS SUBROUTINE
;
PMTGR    STX XPOSSC  ;SAVE HORIZ
         STY YPOSSC  ;SAVE VERT
         TYA         ;GET VERT IN A
         SEC         ;SUB SCREEN OFFSET
         SBC #16
         STA LDIV    ;SAVE IN DIVIDER
         LDA #8      ;DIV. BY 8
         STA DIVS
         LDA #0      ;ZERO RESULT
         STA DRES
         JSR DIVIDE  ;DIVIDE IT!
         STA NOX     ;STORE REMAINDER
         LDA DRES    ;GET RESULT
         STA YPOSSC  ;SAVE SCREEN Y
         AND #1      ;EVEN OR ODD?
         BNE OD1     ;ODD!
         LDA #1      ;PROHIBIT ANY
         STA NOX     ;HORIZONTAL MOVE
OD1      LDA XPOSSC  ;GET HORIZ.
         SEC         ;SUB SCREEN OFFSET
         SBC #48
         STA LDIV    ;PUT IN DIVIDER
         LDA #4      ;DIVIDE BY 4
         STA DIVS
         LDA #0      ;ZERO RESULT
         STA DRES
         JSR DIVIDE  ;DIVIDE IT!
         STA NOY     ;SAVE REMAINDER
         LDA DRES    ;GET RESULT
         STA XPOSSC  ;SAVE SCREEN X
         AND #3      ;IS VERT MOVE OK?
         EOR #1
         BEQ OD2     ;YES!
         LDA #1      ;PROHIBIT ALL
         STA NOY     ;VERTICAL MOVES
OD2      LDA DRES    ;GET RESULT
         STA XPOSSC  ;SAVE SCREEN X
         RTS         ;ALL DONE!
;
;X&Y COORDS TO MEMORY ADDRESS
;
XYTOME   LDA #0      ;ZERO...
         STA VBPNTL  ;VBLANK POINTER
         STA RESH    ;AND RESULT
         LDA STICKC  ;GET CURRENT DIR.
         AND #1      ;LEFT?
         BNE NI      ;NO!
         LDA STICKN  ;GET NEXT DIR
         CMP #11     ;LEFT?
         BNE INCY    ;NO!
         DEC YPOSSC  ;CANCEL NEXT INC
INCY     INC YPOSSC  ;INC VERT POS
NI       LDA YPOSSC  ;GET VERT
         STA MUPL    ;SAVE MULTIPLIER
         LDA #40     ;TIMES 40
         STA MUCN
         JSR MULT    ;MULTIPLY IT!
         INC XPOSSC  ;INC HORIZ POS
         LDA XPOSSC  ;GET IT,
         CLC         ;ADD RESULT
         ADC RESL
         STA VBPNTL  ;SAVE IN POINTER
         LDA RESH
         ADC #SCRAM/256 ;ADD SCRN BASE
         STA VBPNTH
         LDY #0      ;ZERO Y
         LDA (VBPNTL),Y ;GET BYTE
         CMP #30     ;IS IT DOOR?
         BNE DCHD    ;NO!
         LDA #38     ;MAKE DOOR SOUND
         STA AUDC1
         LDA #20
         STA AUDF1
         LDA #0
         TAY 
         STA (VBPNTL),Y ;ERASE DOOR
         INC NDOOR   ;1 MORE DOOR
DCHD     CMP #31     ;IS IT DOOR?
         BNE CVDA    ;NO!
         LDA #38     ;MAKE DOOR SOUND
         STA AUDC1
         LDA #20
         STA AUDF1
         LDA #0
         TAY 
         STA (VBPNTL),Y ;ERASE DOOR
         DEC VBPNTL  ;(2 BYTES)
         STA (VBPNTL),Y
         INC VBPNTL
         INC NDOOR   ;1 MORE DOOR
CVDA     CMP #17     ;IS IT A DOT?
         BEQ CC      ;YES!
         CMP #29     ;MONEY BAG?
         BNE R       ;NO!
         LDA #166    ;MAKE SOUND
         STA AUDC1
         LDA #220
         STA AUDF1
         LDX #100    ;ADD 100 TO SCORE
         STX SCOUNT
         DEC VBPNTL  ;ERASE MONEY BAG
         TYA 
         STA (VBPNTL),Y
         INC VBPNTL
         STA (VBPNTL),Y
         RTS         ;AND EXIT!
CC       TYA         ;ERASE DOT
         STA (VBPNTL),Y
         INC NDOTS   ;1 MORE DOT TAKEN
         LDX #1      ;ADD 1 POINT
         STX SCOUNT
         LDA #95     ;MAKE SOUND
         STA AUDC1
         LDA #185
         STA AUDF1
R        RTS         ;AND EXIT!
;
;GENERAL-PURPOSE DIVIDE ROUTINE
;
DIVIDE   LDY #8      ;GET # OF BITS
         SEC         ;SUBTRACT DIVISOR
         SBC DIVS
DILO     PHP         ;SAVE PROC. STATUS
         ROL DRES    ;ROTATE RESULT
         ASL LDIV    ;SHIFT DIVIDER
         ROL A       ;ROTATE DIVIDER
         PLP         ;GET STATUS BACK
         BCC ADD     ;BRANCH IF CLEAR
         SBC DIVS    ;SUBTRACT DIVISOR
         JMP NEXT    ;CONTINUE
ADD      ADC DIVS    ;ADD DIVISOR
NEXT     DEY         ;LAST BIT?
         BNE DILO    ;NO!
         BCS LAST    ;BRANCH IF LAST
         ADC DIVS    ;ADD DIVISOR
         CLC         ;CLEAR CARRY
LAST     ROL DRES    ;ROTATE RESULT
         RTS         ;AND EXIT.
;
;MULTIPLY SUBROUTINE
;
MULT     LDA #0      ;ZERO RESULT
         STA RESL
         LDX #8      ;8 BITS
MLOP     LSR MUPL    ;SHIFT MULTIPLIER
         BCC NOADD   ;HI BIT EMPTY
         CLC         ;ADD MULTIPLICAND
         ADC MUCN
NOADD    ROR A       ;ROTATE RESULT
         ROR RESL    ;AND LOW RESULT
         DEX         ;1 MORE BIT
         BNE MLOP    ;MORE TO COME!
         STA RESH    ;SAVE RESULT HI
         RTS         ;AND EXIT
;
;SCOREKEEPING SUBROUTINE
;
SCORE    LDY #5      ;6TH SCORE DIGIT
         CPX #1      ;ANY INCREASE?
         BCS GET     ;YES!
         RTS         ;NO, RETURN
GET      LDA SCRAM+447,Y ;GET SCORE
         CMP #27     ;>=9?
         BCC NOB     ;NO
         LDA #18     ;WRAP TO ZERO
         STA SCRAM+447,Y
         DEY         ;NEXT CHARACTER
         BPL GET
         RTS         ;ALL DONE!
NOB      CLC         ;INCREMENT THE
         ADC #1      ;SCORE
         STA SCRAM+447,Y
         DEX         ;NEXT ADD
         BNE SCORE   ;GO ADD IT!
         RTS         ;ALL DONE!
;
;PLAYER MOVEMENT
;
PMOVE    STA YM      ;SAVE ACCUM
         TYA         ;MOVE VERT TO A
         SEC         ;SCREEN OFFSET
         SBC #16
         STA LDIV    ;PUT IN DIVIDER
         LDA #8      ;DIV BY 8
         STA DIVS
         LDA #0      ;CLEAR RESULT
         STA DRES
         JSR DIVIDE  ;DIVIDE IT!
         STA XM      ;SAVE REMAINDER
         LDA DRES    ;GET RESULT
         AND #1      ;ODD?
         BNE OD1M    ;YES!
         LDA #1      ;DON'T PERMIT
         STA XM      ;HORIZ. MOVE
OD1M     LDA YM      ;GET VERT
         SEC         ;SUB SCREEN OFFSET
         SBC #48
         STA LDIV    ;STORE IN DIVIDER
         LDA #4      ;DIV BY 4
         STA DIVS
         LDA #0      ;CLEAR RESULT
         STA DRES
         JSR DIVIDE  ;DIVIDE IT!
         STA YM      ;SAVE REMAINDER
         LDA DRES    ;GET RESULT
         AND #3      ;VERT MOVE OK?
         EOR #1
         BEQ OD2M    ;YES!
         LDA #1      ;DON'T ALLOW
         STA YM      ;VERT MOVEMENT
OD2M     RTS         ;EXIT!
MPXR     LDY XPOSP1,X ;CAN PLAYER
         CPY #179    ;MOVE RIGHT?
         BCC CMR     ;YES!
         JMP END     ;NO!
CMR      INY         ;INCREMENT HORIZ
         TYA         ;PUT IN ACCUM
         STA XPOSP1,X ;SET THE POS
         STA HPOSP1,X
         JMP END     ;ALL DONE!
MPXL     LDY XPOSP1,X ;CAN PLAYER
         CPY #68     ;MOVE LEFT?
         BCS CML     ;YES!
         JMP END     ;NO!
CML      DEY         ;DEC HORIZ
         TYA         ;PUT IN ACCUM
         STA XPOSP1,X ;CHANGE POS
         STA HPOSP1,X
         JMP END     ;ALL DONE
MPXU     LDY YPOSP1,X ;GET VERT
         LDX #$0A    ;10 BYTES TO MOVE
         CPY #24     ;AT TOP?
         BCS CMU     ;NO, CAN MOVE
         JMP END     ;CAN'T GO UP!
CMU      LDA (POINTL),Y ;MOVE UP!
         DEY 
         STA (POINTL),Y
         INY 
         LDA (TABPTL),Y ;MOVE COLORS
         DEY 
         STA (TABPTL),Y
         INY 
         INY 
         DEX 
         BNE CMU
         LDX TEMPX   ;RESTORE X
         DEC YPOSP1,X ;DEC VERT POS
         JMP END     ;ALL DONE
MPXD     LDX TEMPX   ;GET PLAYER #
         LDA YPOSP1,X ;CAN HE...
         CMP #87     ;GO DOWN?
         BCC CMD     ;YES!
         JMP END     ;NO!
CMD      ADC #9      ;GET OFFSET...
         TAY         ;TO PLAYER END
         LDX #$0A    ;10 BYTES
L        DEY 
         LDA (POINTL),Y ;MOVE HIM!
         INY 
         STA (POINTL),Y
         DEY 
         LDA (TABPTL),Y ;MOVE COLOR
         INY 
         STA (TABPTL),Y
         DEY 
         DEX 
         BNE L
         LDX TEMPX   ;RESTORE X
         INC YPOSP1,X ;INC VERT POS
         JMP END     ;ALL DONE
;
;VBLANK FINISH
;
END      LDA POINTL  ;ADD 128 TO
         CLC         ;P/M POINTER
         ADC #$80    ;TO INDICATE
         STA POINTL  ;NEXT PLAYER
         LDA POINTH
         ADC #0
         STA POINTH
         INC TABPTH
         LDX TEMPX   ;GET PLAYER #
         INX         ;INCREMENT IT
         CPX #3      ;ALL DONE?
         BCS ENDDVB  ;YES!
         JMP MAIN    ;NO, LOOP BACK!
ENDDVB   LDX SCOUNT  ;GET SCORE ADD
         LDA #0      ;ZERO IT
         STA SCOUNT
         JSR SCORE   ;ADD TO SCORE
         LDA STRIG0  ;BUTTON PRESSED?
         BNE PQW     ;NO!
         JSR DOOR    ;PLACE A DOOR
PQW      JMP $E462   ;VBLANK DONE!
;
;INITIALIZATION SEQUENCE
;
INT      LDA #3      ;SET UP...
         STA LEVEL   ;INITIAL SPEEDS
         STA ELEVEL
         STA DELAY
         STA EDELAY
         LDY #19     ;CLEAR SCORE LINE
         LDA #0
CG       STA SCRAM+440,Y
         DEY 
         BNE CG
         LDA #$57    ;RESET # MEN
         STA SCRAM+442
         LDY #0      ;ZERO SCORE
         LDA #18
L2       STA SCRAM+447,Y
         INY 
         CPY #6
         BNE L2
         RTS         ;ALL DONE!
;
;CHANGE LEVELS
;
NEXTL    LDA ELEVEL  ;GET ENEMY SPEED
         CMP LEVEL   ;SAME AS PLAYER?
         BEQ NDS     ;YES!
         DEC LEVEL   ;SPEED UP PLAYER
         BNE NOC     ;BUT DON'T ALLOW
         LDA #1      ;LEVEL < 1
         STA LEVEL
NDS      DEC ELEVEL  ;SPEED UP ENEMY
         BNE NOC     ;BUT DON'T ALLOW
         LDA #1      ;ELEVEL < 1
         STA ELEVEL
NOC      JSR CLRVB   ;CLEAR VBLANK
         JSR SOUND2  ;MAKE A SOUND
         JSR SETSC   ;SET UP SCREEN
         JSR SETPM   ;SET UP P/M
         JSR SETEM   ;SET ENEMIES
         JSR SETPL   ;SET UP PLAYER
         JSR SETVB   ;SET VBLANK
         JSR PRIZE   ;SET UP MONEYBAG
         JMP COLOR   ;DISPLAY COLORS
;
;CLEAR VBLANK VECTORS
;
CLRVB    LDA #6      ;IMMEDIATE OFF
         LDX #$E4
         LDY #$5F
         JSR $E45C
         LDA #7      ;DEFERRED OFF
         LDX #$E4
         LDY #$62
         JMP $E45C   ;AND EXIT
;
;MONEY BAG HANDLER
;
PRIZE    LDA #MONEY/256 ;SET UP...
         STA $0227   ;TIMER 1 VECTOR...
         LDA #MONEY&255 ;TO POINT TO...
         STA $0226   ;BAG PRINTER
SETT1    LDA #1      ;SET UP TIMER!
         LDY #0
         LDX #4
         JMP $E45C   ;ALL DONE!
;
;MONEY BAG DISPLAY ROUTINE
;
MONEY    LDA #28     ;PUT BAG CHAR 1
         STA SCRAM+219 ;ON SCREEN
         LDA #29     ;PUT BAG CHAR 2
         STA SCRAM+220 ;ON SCREEN
         LDA #MGONE/256 ;REPOINT TIMER
         STA $0227   ;TO BAG ERASE
         LDA #MGONE&255 ;ROUTINE
         STA $0226
         JMP SETT1   ;GO SET IT
MGONE    LDA #0      ;ERASE BAG
         STA SCRAM+219
         STA SCRAM+220
         RTS         ;AND EXIT
DEATH    JSR CLRVB   ;TURN OFF VBLANK
         JSR SOUND1  ;DO DEATH SOUND
         LDX SCRAM+442 ;1 LESS LIFE
         DEX 
         CPX #$52    ;MORE LIVES?
         BCS STILL   ;YES!
         JMP GOVER   ;GAME OVER!
STILL    STX SCRAM+442 ;ZERO LIVES
         JSR SETPM   ;SET UP P/M
         JSR SETPL   ;AND PLAYER
         JSR SETEM   ;AND ENEMIES
         JSR SETVB   ;AND VBLANK
         STA HITCLR  ;CLEAR COLLISIONS
         JMP COLOR   ;AND RESTART!
;
;GAME OVER ROUTINE
;
GOVER    LDX #0      ;SHOW MESSAGE:
PR1      LDA GAME,X  ;'GAME'
         STA SCRAM+442,X
         INX 
         CPX #4
         BNE PR1
         LDX #0
PR2      LDA OVER,X  ;'OVER'
         STA SCRAM+454,X
         INX 
         CPX #4
         BNE PR2
         JMP PROG    ;AND RESTART!
;
;OPEN DOOR
;
DOOR     DEC NDOOR   ;1 LESS DOOR
         BNE RED     ;DOORS LEFT
         INC NDOOR   ;NO DOORS!
         RTS         ;EXIT
RED      LDA NOY     ;VERTIVAL DOOR?
         BEQ VD      ;YES!
         LDA XPOSSC  ;OK FOR HOR. DOOR?
         AND #3
         BNE ENDD    ;NO!
         LDA #$C0    ;MAKE DOOR SOUND
         STA AUDF2
         LDA #$A3
         STA AUDC2
         LDY #0      ;DRAW DOOR
         LDA #30
         STA (VBPNTL),Y
         RTS         ;AND EXIT
VD       LDA YPOSSC  ;VERT DOOR OK?
         AND #1
         BNE ENDD    ;NO!
         LDA #$C0    ;MAKE DOOR SOUND
         STA AUDF2
         LDA #$A3
         STA AUDC2
         DEC VBPNTL  ;BACK 1 CHAR
         LDY #1      ;DRAW DOOR
         LDA #31
         STA (VBPNTL),Y
         DEY 
         STA (VBPNTL),Y
         RTS         ;AND EXIT
ENDD     INC NDOOR   ;NO DOOR DISPLAYED,
         RTS         ;RESET & RETURN
;
;SOUND SUBROUTINES
;
SOUND1   LDA #168    ;INIT SOUND
         STA AUDC2
         LDA #100    ;INIT FREQ
         STA TF3
         LDX #$FF    ;LOW DELAY COUNT
         LDY #20     ;HI DELAY COUNT
SL1      LDA TF3     ;GET FREQ
         STA AUDF2   ;STORE IT
         DEX         ;DELAY 1
         BNE SL1     ;LOOP IF NOT READY
         DEY         ;DELAY 2
         BNE SL1     ;LOOP AGAIN
         INC TF3     ;INC FREQUENCY
         INC TF3
         LDY #20     ;RESET HI DELAY
         LDA TF3     ;GET FREQ
         CMP #$A0    ;LAST FREQ?
         BNE SL1     ;NO!
         LDA #136    ;END OF SOUND
         STA AUDC2
         LDA #50
         STA AUDF2
         LDX #255    ;LO DELAY COUNT
         LDY #255    ;HI DELAY COUNT
SL2      DEX         ;DELAY LOOP
         BNE SL2
         DEY 
         BNE SL2
         LDA #0      ;SOUND OFF
         STA AUDF2
         STA AUDC2
         RTS         ;BYE!
SOUND2   LDA #168    ;INITIAL SOUND
         STA AUDC1
         LDA #$40    ;INITIAL FREQ
         STA TF4
         LDX #$FF    ;LO DELAY COUNT
         LDY #20
SL3      LDA TF4     ;GET FREQ
         STA AUDF1   ;STORE IT
         DEX         ;DELAY 1
         BNE SL3
         DEY         ;DELAY 2
         BNE SL3
         DEC TF4     ;NEXT FREQ
         DEC TF4
         LDY #20     ;RESET DELAY
         LDA TF4     ;LAST FREQ?
         BNE SL3     ;NO!
         LDA #0      ;TURN OFF SOUND
         STA AUDF1
         STA AUDC1
         RTS         ;AND EXIT
;
;CHARACTER SET DATA
;
CHDAT
         .BYTE 0,0,0,0,0,0,0,0,85,85
         .BYTE 85,170,85,85,85,85,149,149,149,170
         .BYTE 85,85,85,85,85,85,85,170,149,149
         .BYTE 149,149,149,149,149,149,149,149,149,149
         .BYTE 21,21,21,21,21,21,21,21,149,149
         .BYTE 149,170,149,149,149,149,86,86,86,170
         .BYTE 86,86,86,86,85,85,85,170,86,86
         .BYTE 86,86,86,86,86,170,85,85,85,85
         .BYTE 84,84,84,84,84,84,84,84,86,86
         .BYTE 86,86,86,86,86,86,85,85,85,85
         .BYTE 85,85,85,85,149,149,149,149,85,85
         .BYTE 85,85,86,86,86,86,85,85,85,85
         .BYTE 85,85,85,149,149,149,149,149,85,85
         .BYTE 85,86,86,86,86,86,0,0,0,128
         .BYTE 0,0,0,0,0,60,102,110,118,102
         .BYTE 60,0,0,24,56,24,24,24,126,0
         .BYTE 0,60,102,12,24,48,126,0,0,126
         .BYTE 12,24,12,102,60,0,0,12,28,60
         .BYTE 108,126,12,0,0,126,96,124,6,102
         .BYTE 60,0,0,60,96,124,102,102,60,0
         .BYTE 0,126,6,12,24,48,48,0,0,60
         .BYTE 102,60,102,102,60,0,0,60,102,62
         .BYTE 6,12,56,0,34,10,42,160,162,160
         .BYTE 42,10,136,160,40,10,42,10,40,160
         .BYTE 192,192,192,192,192,192,192,192,0,0
         .BYTE 0,255,0,0,0,0,0,60,102,110
         .BYTE 110,96,62,0,0,24,60,102,102,126
         .BYTE 102,0,0,124,102,124,102,102,124,0
         .BYTE 0,60,102,96,96,102,60,0,0,120
         .BYTE 108,102,102,108,120,0,0,126,96,124
         .BYTE 96,96,126,0,0,126,96,124,96,96
         .BYTE 96,0,0,62,96,96,110,102,62,0
         .BYTE 0,102,102,126,102,102,102,0,0,126
         .BYTE 24,24,24,24,126,0,0,6,6,6
         .BYTE 6,102,60,0,0,102,108,120,120,108
         .BYTE 102,0,0,96,96,96,96,96,126,0
         .BYTE 0,99,119,127,107,99,99,0,0,102
         .BYTE 118,126,126,110,102,0,0,60,102,102
         .BYTE 102,102,60,0,0,124,102,102,124,96
         .BYTE 96,0,0,60,102,102,102,108,54,0
         .BYTE 0,124,102,102,124,108,102,0,0,60
         .BYTE 96,60,6,6,60,0,0,126,24,24
         .BYTE 24,24,24,0,0,102,102,102,102,102
         .BYTE 126,0,0,102,102,102,102,60,24,0
         .BYTE 0,99,99,107,127,119,99,0,0,102
         .BYTE 102,60,60,102,102,0,0,102,102,60
         .BYTE 24,24,24,0,0,126,12,24,48,96
         .BYTE 126,0,0,30,24,24,24,24,30,0
         .BYTE 0,64,96,48,24,12,6,0,0,120
         .BYTE 24,24,24,24,120,0,0,8,28,54
         .BYTE 99,0,0,0,0,0,0,0,0,0
         .BYTE 255,0,0
;
;SCREEN DATA
;
SCDAT
         .BYTE 0,0,0,5,3,1,1,1,3,1
         .BYTE 1,1,3,1,1,1,3,1,1,1
         .BYTE 3,1,1,1,3,1,1,1,3,1
         .BYTE 1,1,3,1,1,8,10,0,0,0
         .BYTE 0,0,0,5,4,0,17,0,17,0
         .BYTE 17,0,17,0,17,0,17,0,17,0
         .BYTE 17,0,17,0,17,0,17,0,17,0
         .BYTE 17,0,17,0,17,11,10,0,0,0
         .BYTE 0,0,0,5,4,0,17,1,6,0
         .BYTE 17,1,6,0,17,1,6,0,17,1
         .BYTE 6,0,17,1,6,0,17,1,6,0
         .BYTE 17,1,6,0,17,11,10,0,0,0
         .BYTE 0,0,0,5,4,0,17,0,17,0
         .BYTE 17,0,17,0,17,0,17,0,17,0
         .BYTE 17,0,17,0,17,0,17,0,17,0
         .BYTE 17,0,17,0,17,11,10,0,0,0
         .BYTE 0,0,0,5,4,0,17,1,6,0
         .BYTE 17,1,6,0,17,1,6,0,17,1
         .BYTE 6,0,17,1,6,0,17,1,6,0
         .BYTE 17,1,6,0,17,11,10,0,0,0
         .BYTE 0,0,0,5,4,0,0,0,0,0
         .BYTE 0,0,0,0,0,0,0,0,0,0
         .BYTE 0,0,17,0,17,0,17,0,17,0
         .BYTE 17,0,17,0,17,11,10,0,0,0
         .BYTE 0,0,0,5,4,0,17,1,6,0
         .BYTE 17,1,6,0,17,1,6,0,17,1
         .BYTE 6,0,17,1,6,0,17,1,6,0
         .BYTE 17,1,6,0,17,11,10,0,0,0
         .BYTE 0,0,0,5,4,0,17,0,17,0
         .BYTE 17,0,17,0,17,0,17,0,17,0
         .BYTE 17,0,17,0,17,0,17,0,17,0
         .BYTE 17,0,17,0,17,11,10,0,0,0
         .BYTE 0,0,0,5,4,0,17,1,6,0
         .BYTE 17,1,6,0,17,1,6,0,17,1
         .BYTE 6,0,17,1,6,0,17,1,6,0
         .BYTE 17,1,6,0,17,11,10,0,0,0
         .BYTE 0,0,0,5,4,0,17,0,17,0
         .BYTE 17,0,17,0,17,0,17,0,17,0
         .BYTE 17,0,17,0,17,0,17,0,17,0
         .BYTE 17,0,17,0,17,11,10,0,0,0
         .BYTE 0,0,0,5,2,1,1,1,2,1
         .BYTE 1,1,2,1,1,1,2,1,1,1
         .BYTE 2,1,1,1,2,1,1,1,2,1
         .BYTE 1,1,2,1,1,9,10,0,0,0
         .BYTE 0,0,87,0,0,0,0,18,18,18
         .BYTE 18,18,26,0,0,0,0,0,0,0
         .BYTE 0,0,0,0,0,0,0,0,0,0
         .BYTE 0,0,0,0,0,0,0,0,0,0
         .BYTE 0,0,0,0,0,0,0,0,0,0
         .BYTE 0,0,0,0,0,0,0,0,0,0
         .BYTE 0,0,0,0,0,0,0,0,0,0
         .BYTE 0,0,0
;
;RUN ADDRESS
;
         *=  $02E0
         .WORD INIT
         .END