A.N.A.L.O.G. ISSUE 32 / JULY 1985 / PAGE 41

Cosmic Defender

32K Cassette or Disk

by Phill Roey

For thousands of years, the evil Lyrean race has ruled the galaxy. As soon as another race reaches technological levels advanced enough to achieve star travel, the Lyreans’ ultimate weapon — the Mesotron Cannon — is trained on them.

Now, mankind’s turn has come. The cannon is inside Pluto’s orbit and approaching rapidly, gathering asteroids to use as fuel as it comes. Things couldn’t look more desperate.

Yet all is not lost. While on a routine maintenance stop on asteroid A37THETA, your ship is swallowed by the cannon. Your duty is clear. You must blast the asteroids which the cannon uses as fuel, and fire through force fields that grow ever closer. You must render this huge weapon inoperative.

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 Defender. The data statements are listed in hexadecimal (base 16], so the program will fit in 16K cassette systems.

Listing 2 is the assembly language source code for the game of Defender, created with the OSS MAC/65 assembler. You don’t 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 Defender.

Cassette instructions.

  1. Type Listing 1 into your computer using the BASIC cartridge and verify your typing with Unicheck (see page 24).
  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, mitil 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 Defender, printing each DATA line number as it goes. When the READY prompt appears, the game is recorded and ready to play. CSAVE the BASIC progi’am onto a separate tape before continuing.
  4. To play, 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 Defender 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 24).
  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 alerl you if it finds any problems. Fix incorrect lines and re-RUN the program, if necessary, until all errors are eliminated.
  3. When all the 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. Defender will load and run automatically.

Playing the game.

Defender is a one-player game that requires a joystick in port 1. Choose the level (1 to 9) you wish to begin on. by pressing the SELECT key.

You start the play by either pressing the START key or the trigger on the joystick. Hitting the SPACE BAR will pause the game; hitting it a second time will resume the game. Defender can be aborted at any time by pressing the OPTION key. Defend your species with all the cuiming at your command. Be careful; I think the Lyreans know you’re coming.


Phil Roey lives in Atlanta and works for UPS. He became a computer enthusiast after seeing a game of Lunar Lander played on an old Selectric terminal. He’s had his Atari 800 since 1982, and this is his first assembly language game.


Listing 1.
BASIC listing.

10 REM *** COSMIC DEFENDER ***
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 3: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,212: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,26,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 D8A085A222A907205CE4A93E8D2F02A9038D1DD0A9228D6F02A9058D0CD0A9648DC402A9268DC502A9388DC602,917
1010 DATA A9D48DC702A9008DC802A9AA8DC002A9368DC102A9008D07D4A000B900E099000899000C990010B900E1990009,550
1020 DATA 99000D99001188D0E5A077B9622B990808B9DA2B99080CB9522C9908108810EBA9088DF40220752120A320205C,824
1030 DATA 21208B21203F2920D12520B62020F727203A21AD1FD0C903D0F6F0DC2065E4A9008590A0078D08D29900D28810,540
1040 DATA FA60AD182B38E911A8A90085D6B931218591AAAD0AD2C9FAB0F9A8AD0AD2293EC928B0F7690120FC20D0E8A691,601
1050 DATA AD0AD2C93090F9C9FFF0F5A8AD0AD2293EC928B0F720FC20D0E66018693085D7B1D6C811D6E6D7E6D711D68811,376
1060 DATA D6D01FC6D7C6D7A90191D6A902C891D6E6D7E6D7A90491D6A9038891D6A93085D7CA60283C46647D46645064AD,784
1070 DATA 00D0F0028581AD08D029FCF0028582AD04D0D007AD0CD029FDF00585808D1ED060A95A85D7A20086D6A0008A91,511
1080 DATA D6C8D0FAC6D7A92FC5D7D0F260A900A8990003990004990005990006990007C8D0EE60A9008585858085818582,60
1090 DATA 85978598858A858B85958593A9308596A9138D052B8583A9548DAF2A8D1ED0A9328599A964859A858460A594D0,808
1100 DATA 278587858B8D01D0A901859420A320209923A9648584A9148D08D2A9C88D06D2A9878D05D28D07D2AD0AD22906,901
1110 DATA 8D12D08D13D0AD0AD28D00D2AD0AD28D02D2AD0AD229DF8D01D28D03D2C684D03220A320A93285998D1ED0A964,457
1120 DATA 859AA90085948580CE052BAD052BC910F017A9008595A93085968D1ED020D92320752120F7274C62E420752120,140
1130 DATA A320A9008580A9018D1ED08583A9198DAD2A8DB32AA92B8DAE2A8DB42AA94E8DB02AA92B8DB12AA9468DAF2AA9,366
1140 DATA FF8D2E028D2002AD2E02D0FB4C7F20A90085D8A583D044854DA582F00620782820DD28A580F0034CBF21ADFC02,489
1150 DATA C921D00BA9FF8DFC02A58549FF8585A585D01B20912520BC2620E222200E2320522320EA2420482820AD2320D9,115
1160 DATA 23A59EF00AA9BD8D0002A9298D01024C62E4AD00D3A69A4AB006E020F002C69A4AB006E0BEF002E69AA6994AB0,655
1170 DATA 06E032F002C6994AB006E064F002E69960A6998E00D0E8E88E05D0A49AA208BD4923990004B9000329F3990003,887
1180 DATA C8CA10EEA49AB90303090C990303B904030904990403B90503090C9905036000C07000730070C000A59BD021AD,525
1190 DATA 10D0D051A901859BA49AA9039904038489A9258D01D2A9328586A59969068588E688E688A5888D04D0E686E686,271
1200 DATA A5868D00D2A9CDC588900AA581F019203824205C24A9008D01D2859B8581A489B9040329FC99040360AD2A0205,960
1210 DATA 93D01FAD182B38E911A8B904248D1C028D2A02A497881008E695D002E696A0038497A6978E04D460A032A596C4,23
1220 DATA 96D009C693D01E204925A93048A214A006A59599922AC86899922A18690248C8C8CA10ED686003030202020202,326
1230 DATA 0101FEF92ABDF92AC91AF00588F00BD0F1A9109DF92A858FD0F2A58FF00C8AF009CAA001A900858FF0D84CB025,520
1240 DATA A58938E91D4A4A29FE186D992A858EA5970A18658838E9274A4A186595858D9002E68E60A58D85D6A58E85D78D,860
1250 DATA 1ED0A000B1D6D00AC8B1D6D005C8B1D6F0E4C901F03CC902D005C6D64CB724C903F006C904D009C6D6C6D7C6D7,465
1260 DATA 4CB724C90AD00BA90D91D6E6D7E6D74CD024C909D0B3A90D91D6C6D7C6D7C6D7C6D74CD024A90091D6E6D7E6D7,469
1270 DATA 91D6C891D6C6D7C6D791D6A203A005D00EA90091D6E6D7E6D791D6A202A0028581200D24A91985904C7828A590,586
1280 DATA F02DAD2C02D028C690A5908D2C02F01FA8B91C258D02D2AD0AD209C08D04D2B9352509408D03D28D05D2A9028D,537
1290 DATA 1E0260F5F4F3F2F2F0F2F5E9E0EFF0F1F2F3F4F5F4F1F5F2F3F4F5F50000010203040505060607070808090909,797
1300 DATA 0A0A0AEE182BAD182BC91AD005A9148D182BA9408D0ED40878205C21A9008595859B20A320A930859620D9238D,985
1310 DATA 1ED020D12520B620A900A20A95B5CA10FB20F727EE052B28A9C08D0ED460AD2E02D019A9048D20028D2E02ADF4,763
1320 DATA 02C910F005186904D002A9088DF40260A000B9F92AD90B2BF0049014B005C8C004D0EFA000B9F92A990B2BC8C0,804
1330 DATA 04D0F560AD182B38E911AABD63268591A000A9308592BD6C2685D6A59285D7A207A90591D6E6D7E6D7A90691D6,800
1340 DATA E6D7E6D7A90791D6E6D7E6D7CAD0E5AD0AD2291FC914B0F7C90590F3C6D60A18659285D7A90891D6C6D7C6D7A9,28
1350 DATA 0991D6C6D7C6D7A98C91D6C8A90091D6C6D7C6D791D688A98B91D6C6D7C6D7A90A91D6C6D7C6D7A90891D6A5D6,711
1360 DATA 659185D6908EE692A592C931F08660FF963C1E1E3C3C5A46FFC8644B323232C864488A48A6D8E6D8B5AA8D03D0,695
1370 DATA 8D02D0B5C08D14D0B5CB8D15D0E00AD00AA9A08D0002A9268D010268AA684048A9F88D16D0A9988D17D0A9268D,160
1380 DATA 19D0A9758D0002A9268D01026840A20086D8B59FF013B5AA38F59FD004959FA9FE95AAE8E00AD0EA60A5930D0A,864
1390 DATA D2D0F3A901AC0AD2C00FB002A902959FAD182BC9169002F69F4CD12600000000000078FC780000000000000000,780
1400 DATA 0000001C3E7F6B7F5D221C000000000000000000007FF87F0000000000000000000000183C7E3C5A667E3C1800,560
1410 DATA 000000000000070F0E1C001C0E0F070000000000000000002C242F3D090F0000000000000000000010387C3810,168
1420 DATA 000000000000000000000000020702000000000000000000070E3C00FC003C0E07000000000000000000000014,613
1430 DATA 00221C00000000000000000003073F3F3F0703000000000000000018244281C3E7FF7E3C18000000000000000F,45
1440 DATA 000000FC0000000F00000000000000F09090D00B09090F00000000000000000010284492442810000000000000,486
1450 DATA 0000000000000200000000000000AD182BC911F049A90A8591A00FA5910A0A0A0A186922AAB977279D0006B9F7,512
1460 DATA 269D0007CA88D0F0C691D0E0A20AA9FE95AAA900959FCA10F5A209A90418695095C0CA10F8A209A98818693095,291
1470 DATA CBCA10F860A58BF02BC68CD027C68BA58B0A0A0A0907AAA9088592A48ABD9528990005CAC8C692D0F4A906858C,25
1480 DATA A58BD0038D01D060A207A9088592A48A206028A589858AA5888D01D0A909858BA901858C600000000000000000,294
1490 DATA 810000000000008181420000000042818942248001244291084A24C00324521D08082CE007341010000808781E,558
1500 DATA 101000000008381C1000000000001818000000A58938E91C4A4A4A4AAAA900959FA9FE95AAF6B5B5B585918692,397
1510 DATA A8A202200D24A692A491C0089006A90095B58591A91785908A0A0A0A0A186931A8A5910A0A0A0A8591090FAABD,562
1520 DATA 7727990006BDF72699000788CAE491D0EE8E1ED0A90085824C9923A9058D3002A92A8D3102207521A9C08D0ED4,424
1530 DATA E69EADBC298D182BAD1FD0C905D017EE182BAD182BC91AD002A9118D182BA91E8D20028D2E02AD182B8D7C2A20,789
1540 DATA 9125AD10D0F007AD1FD0C906D029A9928D3002A92A8D3102A9758D0002A9268D0102A910A00599F82A88D0FA84,691
1550 DATA 83849EAD182B8DBC2960AD2E02D0BDF09D11488A48A20FA59D859CA59C8D0AD48D16D0186902859CCA10F0A20F,30
1560 DATA A59C8D0AD48D16D038E902859CCA10F0AD2C02D00AA9018D2C028D1E02E69DA9A08D0002A9268D010268AA6840,742
1570 DATA 707046DE2A70F047302A473E2A7070464C2A465B2AF0477E2A70C66C2A70707070707046DE2A060641052A0000,672
1580 DATA 0000000000232F332D292300000000000000242526252E242532808080808080808080A2B98080808080808080,766
1590 DATA 80F0E8E9ECEC80F2EFE5F9808000000073656C656374006C6576656C1A00008080E1EEE1ECEFE780E3EFEDF0F5,582
1600 DATA F4E9EEE780807070C6DE2A540000D40000540000D40000540000D40000540000D40000540000D40000540000D4,246
1610 DATA 0000540000D40000540000D40000540000D40000540000D40000540000C6DE2A060641922A8E8E8E8E8E8E8E8E,377
1620 DATA 8E8E8E8E8E8E8E8E8E8E8E8E80F3E3EFF2E59A1010101010006C697665731A13000068691A101010101000006C,638
1630 DATA 6576656C1A11000000000000000000000000000000000000000000000000000000000000000000000000000000,109
1640 DATA 0000000000000000000000000000000000000027212D2500002F362532000000000000010114111A1555004050,766
1650 DATA 506454455159591A15110501006958545450400000FFFFD7D7D7D7FFFFFFFFC3C3C3C3FFFFFFFFEBEBEBEBFFFF,573
1660 DATA 0F03030F0F03030F3FF5F5EAEAF5F53F3FF5F5EAEAF5F53FC33C00C33C00C33C00C33C00C33C00C33FF0F0C0C0,190
1670 DATA F0F03FFF494949494949FF001E212D292D211E00010114111A1555004050506454455159591A15110501006958,108
1680 DATA 545450400000FFFFEBEBEBEBFFFFFFFFD7D7D7D7FFFFFFFFC3C3C3C3FFFF0F03030F0F03030F3FF5F5C0C0F5F5,559
1690 DATA 3F3FF5F5C0C0F5F53F00C33C00C33C00C33C00C33C00C33C003FF0F0C0C0F0F03FFF929292929292FF001E212D,351
1700 DATA 292D211E00010114111A1555004050506454455159591A15110501006958545450400000FFFFC3C3C3C3FFFFFF,37
1710 DATA FFEBEBEBEBFFFFFFFFD7D7D7D7FFFF0F03030F0F03030F3FF5F5D5D5F5F53F3FF5F5D5D5F5F53F3C00C33C00C3,268
1720 DATA 3C00C33C00C33C00C33C3FF0F0C0C0F0F03FFF242424242424FF001E212D292D211E0000000000000000000000,546

Listing 2.
Assembly listing.

*******************
* COSMIC DEFENDER *
*       BY        *
*  PHILLIP  ROEY  *
*******************
;
; OPERATING SYSTEM EQUATES
;
AUDCTL	=	$D208
SKCTL	=	$D20F
AUDF1	=	$D200
AUDC1	=	$D201
AUDF2	=	$D202
AUDC2	=	$D203
AUDF3	=	$D204
AUDC3	=	$D205
AUDF4	=	$D206
AUDC4	=	$D207
ATRACT	=	$4D
VERTI	=	$0200
DMACTL	=	$022F
DLST	=	$0230
GRACTL	=	$D01D
GPRIOR	=	$026F
PMBASE	=	$D407
COLPM0	=	704
COLPM1	=	705
HCOLPM0	=	$D012
HCOLPM1	=	$D013
HCOLPM2	=	$D014
HCOLPM3	=	$D015
COLP0	=	708
COLP1	=	709
COLP2	=	710
COLP3	=	711
COLBK	=	712
HCOLP0	=	$D016
HCOLP1	=	$D017
HCOLP3	=	$D019
CONSOL	=	$D01F
KEY	=	$02FC
HPOSP0	=	$D000
STICK	=	$D300
TRIG0	=	$D010
TIMER3	=	$021C
TIMER4	=	$021E
TIMER5	=	$0220
TIMERF3	=	$022A
TIMERF4	=	$022C
TIMERF5	=	$022E
NMIEN	=	$D40E
SETVBV	=	$E45C
XITVBV	=	$E462
SIOINI	=	$E465
HSCROL	=	$D404
WSYNC	=	$D40A
CHBAS	=	756
SIZEM	=	$D00C
M0PF	=	$D000
M0PL	=	$D008
P0PF	=	$D004
P0PL	=	$D00C
HITCLR	=	$D01E
CHORG	=	$E000
RANDOM	=	$D20A
;
; PAGE ZERO EQUATES
;
	*=	$80
;
KILLU	.DS	1	COLLISION
KILLIT	.DS	1	FLAGS
KILLPL	.DS	1	DITTO
OVER	.DS	1	GAMEOVER?
FRAME	.DS	1	COUNTER
PAUSE	.DS	1	PAUSE FLAG
SNDF1	.DS	1	MISSLE SND
SND1	.DS	1	LOCATIONS
OXM0	.DS	1	MISSLE X
OYM0	.DS	1	MISSLE Y
XPY	.DS	1	EXPLOSION Y
XPIMAGE	.DS	1	EXP. IMAGE#
EXPTIME	.DS	1	EXP. TIMER
TEMPLO	.DS	1
TEMPHI	.DS	1
SCRTEMP	.DS	1
EXPLODE	.DS	1	EXP. SOUND CNTR
TEMP	.DS	1
TEMP2	.DS	1
NONEW1	.DS	1	SCROLL FLAG
XPLON	.DS	1	EXP. FLAG
ABX	.DS	1	SCREEN POS. LSB
ABY	.DS	1	SCREEN POS. MSB
FX	.DS	1
FY	.DS	1
OX	.DS	1	PLAYER X
OY	.DS	1	PLAYER Y
MSL0	.DS	1	MISSLE FLG
CSHIFT	.DS	1	DLI COLOR
DSHIFT	.DS	1	SHIFT USE
TITLF	.DS	1	TITLE SCRN FLAG
ROCKSPD	.DS	11
ROCKPOS	.DS	11	NASTY X LOC
RIMAGE	.DS	11
COLOR2	.DS	11	COLORS OF
COLOR3	.DS	11	NASTIES
ADR	.DS	2
DLINE	.DS	1	NASTY COUNTER
;
; MISCELLANEOUS EQUATES
;
;
SCRN	=	$3000	SCREEN MEM.
PLAYER	=	$00	PMG MEMORY
;
	*=	$2000	ORIGIN
;
; INITIALIZATION OF GAME
;
START	CLD
	LDY	# <MAIN	POINT TO
	LDX	# >MAIN	VBI ROUTINE
	LDA	#7
	JSR	SETVBV
	LDA	#$3E	ENABLE PMG
	STA	DMACTL
	LDA	#$03
	STA	GRACTL
	LDA	#34
	STA	GPRIOR
	LDA	#5	SET MISSLE
	STA	SIZEM	SIZE
	LDA	#100
	STA	COLP0	SET
	LDA	#$26	PLAYFIELD
	STA	COLP1	AND P/M
	LDA	#$38	COLORS
	STA	COLP2
	LDA	#$D4
	STA	COLP3
	LDA	#0
	STA	COLBK
	LDA	#170
	STA	COLPM0
	LDA	#$36
	STA	COLPM1
	LDA	# >PLAYER	POINT TO
	STA	PMBASE	P/M AREA
;
; MAKE 3 COPIES OF CHAR SET
;
	LDY	#0
COPY	LDA	CHORG,Y
	STA	PLAYER+$0800,Y
	STA	PLAYER+$0C00,Y
	STA	PLAYER+$1000,Y
	LDA	CHORG+256,Y
	STA	PLAYER+$0900,Y
	STA	PLAYER+$0D00,Y
	STA	PLAYER+$1100,Y
	DEY
	BNE	COPY
;
; INSTALL CUSTOM CHARACTERS
;
	LDY	#119
INST	LDA	CHSET,Y
	STA	PLAYER+$0808,Y
	LDA	CHSET2,Y
	STA	PLAYER+$0C08,Y
	LDA	CHSET3,Y
	STA	PLAYER+$1008,Y
	DEY
	BPL	INST
	LDA	# >PLAYER+$0800	POINT TO
	STA	CHBAS	NEW CHAR. SET
;
; EACH NEW GAME STARTS HERE
;
BEGIN	JSR	PLRINT	CLEAR P/M
	JSR	SNDINT	KILL SOUND
	JSR	CLRSCRN	CLR SCREEN
	JSR	VARINT	INITIALIZE VARIABLES
	JSR	TITLE	DISPLAY TITLES
	JSR	GRID	ADD FFIELDS
	JSR	ROCKS	AND ROCKS
	JSR	ROCKINT	AND NASTIES
;
; MAIN GAME LOOP
;
MLOOP	JSR	COLDET	CHECK FOR COLLISIONS
	LDA	CONSOL	ABORT GAME?
	CMP	#3	(OPTION)
	BNE	MLOOP	NO,LOOP
	BEQ	BEGIN	YES,RESTART
;
; INITIALIZE SOUND CHANNELS
;
SNDINT	JSR	SIOINI
	LDA	#0
	STA	EXPLODE
	LDY	#7
	STA	AUDCTL
SN1	STA	AUDF1,Y
	DEY
	BPL	SN1
	RTS
;
; ADD ROCKS TO SCREEN
;
ROCKS	LDA	LEVEL	GET NUMBER
	SEC		OF ROCKS,
	SBC	#17	AND PUT IN
	TAY		X REG
	LDA	#0
	STA	ADR
	LDA	NUMROCK,Y
	STA	TEMP	AND TEMP
	TAX
R1	LDA	RANDOM	GET A VALID
	CMP	#250	RANDOM
	BCS	R1	LOCATION
	TAY
R2	LDA	RANDOM
	AND	#$3E
	CMP	#40
	BCS	R2
	ADC	#1	CHECK IF IT
	JSR	EMPTY	IS EMPTY
	BNE	R1	NEXT!
	LDX	TEMP	GET # OF ROCKS FOR
R3	LDA	RANDOM	2ND PAGE OF SCRN MEM
	CMP	#48	GET A VALID
	BCC	R3	LOCATION
	CMP	#255
	BEQ	R3
	TAY
R4	LDA	RANDOM
	AND	#$3E
	CMP	#40
	BCS	R4
	JSR	EMPTY	LOOK FOR AN EMPTY SEAT.
	BNE	R3	NEXT!
	RTS
;
EMPTY	CLC		CHECK TO MAKE
	ADC	# >SCRN	SURE THE SPACE
	STA	ADR+1	FOR ALL FOUR
	LDA	(ADR),Y	PARTS IS VACANT
	INY
	ORA	(ADR),Y
	INC	ADR+1
	INC	ADR+1
	ORA	(ADR),Y
	DEY
	ORA	(ADR),Y
	BNE	RX	NO VACANCY! EXIT
	DEC	ADR+1	POKE 4
	DEC	ADR+1	PART ROCK
	LDA	#1	INTO
	STA	(ADR),Y	SCREEN
	LDA	#2	MEMORY
	INY		IN LIVING
	STA	(ADR),Y	COLOR...
	INC	ADR+1
	INC	ADR+1
	LDA	#4
	STA	(ADR),Y
	LDA	#3
	DEY
	STA	(ADR),Y
	LDA	# >SCRN
	STA	ADR+1
	DEX		DEC COUNTER
RX	RTS
;
NUMROCK	.BYTE	40,60,70,100,125,70,100,80,100
;
; CHECK FOR COLLISIONS
;
COLDET	LDA	M0PF	HAS MISSLE HIT?
	BEQ	C1	NO,CONT...
	STA	KILLIT	YES,SET FLG
C1	LDA	M0PL	HIT NASTY?
	AND	#$FC
	BEQ	C2	NO,CONT...
	STA	KILLPL	YES,SET FLG
C2	LDA	P0PF	HIT WALL OR ROCK?
	BNE	DIE	YES,SET FLAG
	LDA	P0PL	DID WE RUN
	AND	#$FD	INTO NASTY?
	BEQ	NODIE	NO. EXIT
DIE	STA	KILLU
	STA	HITCLR
NODIE	RTS
;
; CLEAR OUT SCROLLING PORTION OF SCREEN
;
CLRSCRN	LDA	#42+>SCRN	21 LINES *
	STA	ADR+1	2 PAGES + SCRN ADDR
	LDX	#0
	STX	ADR
	LDY	#0
CL1	TXA		LOOP UNTIL
	STA	(ADR),Y	WE'VE GOT
	INY		LOTS OF
	BNE	CL1	NOTHING
	DEC	ADR+1
	LDA	# >SCRN-1
	CMP	ADR+1
	BNE	CL1
	RTS
;
; ZERO OUT P/M MEMORY
;
PLRINT	LDA	#0
	TAY
PL1	STA	PLAYER+$0300,Y
	STA	PLAYER+$0400,Y
	STA	PLAYER+$0500,Y
	STA	PLAYER+$0600,Y
	STA	PLAYER+$0700,Y
	INY
	BNE	PL1
	RTS
;
; REINITIALIZE GAME VARIABLES
;
VARINT	LDA	#0
	STA	PAUSE
	STA	KILLU
	STA	KILLIT
	STA	KILLPL
	STA	FX
	STA	FY
	STA	XPY
	STA	XPIMAGE
	STA	ABX
	STA	NONEW1
	LDA	# >SCRN
	STA	ABY
	LDA	#19
	STA	LIVES
	STA	OVER
	LDA	#$54	LOAD MEMORY SCAN
	STA	ML2
	STA	HITCLR
	LDA	#50
	STA	OX
	LDA	#100
	STA	OY
	STA	FRAME
	RTS
;
; PLAYER BUYS CEMENT OVERSHOES
;
BITEIT	LDA	XPLON	ALREADY BITING IT?
	BNE	BT1	YES,CONT...
	STA	SND1	KILL SOUND
	STA	XPIMAGE
	STA	HPOSP0+1	EXPLOSION
	LDA	#1	SET DEATH
	STA	XPLON	FLAG
	JSR	SNDINT	KILL REST OF SOUND
	JSR	MISEND	AND MISSLE
	LDA	#100	SET TIMER
	STA	FRAME
	LDA	#20
	STA	AUDCTL	MAKE DEATH
	LDA	#200	TYPE NOISES
	STA	AUDF4
	LDA	#135
	STA	AUDC3
	STA	AUDC4
BT1	LDA	RANDOM	FLASH
	AND	#6	SHIP
	STA	HCOLPM0	IN A NICE
	STA	HCOLPM1	GREY
	LDA	RANDOM	PALLOR.
	STA	AUDF1	MORE NOISE
	LDA	RANDOM
	STA	AUDF2
	LDA	RANDOM
	AND	#$DF
	STA	AUDC1
	STA	AUDC2
	DEC	FRAME	DONE KILLING?
	BNE	DEDEND	NO.
	JSR	SNDINT	KILL NOISE
	LDA	#50	REST SHIP
	STA	OX	LOCATION
	STA	HITCLR
	LDA	#100
	STA	OY
	LDA	#0
	STA	XPLON	CLEAR FLAGS
	STA	KILLU
	DEC	LIVES	ZAP A LIFE
	LDA	LIVES	ANY LEFT?
	CMP	#16
	BEQ	GMOVER	NO? THE BIG SLEEP!
	LDA	#0	YES,RESET
	STA	ABX	TO START
	LDA	# >SCRN	OF SCREEN
	STA	ABY
	STA	HITCLR
	JSR	SCREEN	CLEAN UP
	JSR	PLRINT	SCREEN AND
	JSR	ROCKINT	NASTIES
DEDEND	JMP	XITVBV
;
GMOVER	JSR	PLRINT	CLEAN UP
	JSR	SNDINT	SCREEN +
	LDA	#0	SOUND
	STA	KILLU	AND
	LDA	#1	SET GAME
	STA	HITCLR	OVER
	STA	OVER	FLAG
	LDA	# <BLANK	PUT GAME
	STA	ML1+1	OVER
	STA	ML3+1	INTO THE
	LDA	# >BLANK	MIDDLE OF
	STA	ML1+2	THE SCREEN
	STA	ML3+2
	LDA	# <MESSAGE
	STA	ML2+1
	LDA	# >MESSAGE
	STA	ML2+2
	LDA	#$46
	STA	ML2
	LDA	#255
	STA	TIMERF5	HANG
	STA	TIMER5	AROUND
GM1	LDA	TIMERF5	AWHILE
	BNE	GM1	THEN
	JMP	BEGIN	ALL OVER
;
; VERTICAL BLANK INTERRUPT
; THIS IS WHERE ALL THE ACTION IS!
;
MAIN	LDA	#0
	STA	DLINE	POINT TO
	LDA	OVER	IS GAME ASLEEP?
	BNE	ENDVB	YES,BYE...
	STA	ATRACT	NO ATTRACT MODE
	LDA	KILLPL	HIT NASTY?
	BEQ	MA2	NO,CONT..
	JSR	XPINIT	YES,KILL
	JSR	KILLPLR	IT
MA2	LDA	KILLU	HIT US?
	BEQ	MA1	NO,CONT...
	JMP	BITEIT	YES,SUICIDE
MA1	LDA	KEY	SPACEBAR
	CMP	#$21	PRESSED
	BNE	NOKEY	NO,BYE
	LDA	#255	YES TOGGLE
	STA	KEY	PAUSE
	LDA	PAUSE	FLAG
	EOR	#255
	STA	PAUSE
NOKEY	LDA	PAUSE	FLAG SET?
	BNE	ENDVB	YES,BYE...
	JSR	ANIMATE	ROTATE CHAR SETS
	JSR	ATTACK	MOVE NASTYS
	JSR	RSTICK	READ JOYSTICK
	JSR	MOVE	MOVE SHIP
	JSR	MISL	AND MISSLES
	JSR	SOUND	BOOM
	JSR	XPLODE	FIREWORKS
	JSR	SCROLL	SCROLL SCREEN
	JSR	SCREEN	UPDATE DISP. LIST
ENDVB	LDA	TITLF	TITLES?
	BEQ	EN1	NO,BYE...
	LDA	# <TDLI
	STA	VERTI
	LDA	# >TDLI
	STA	VERTI+1
EN1	JMP	XITVBV
;
; READ JOYSTICK
;
RSTICK	LDA	STICK	GET STICK
	LDX	OY	CHECK STICK FOR
	LSR	A	MOVEMENT IN A
	BCS	RS1	DIRECTION AND
	CPX	#32	CHECK IF WE ARE
	BEQ	RS1	AT OUR LIMITS IN
	DEC	OY	THAT DIRECTION
RS1	LSR	A
	BCS	RS2
	CPX	#190
	BEQ	RS2
	INC	OY
RS2	LDX	OX
	LSR	A
	BCS	RS3
	CPX	#50
	BEQ	RS3
	DEC	OX
RS3	LSR	A
	BCS	RS4
	CPX	#100
	BEQ	RS4
	INC	OX
RS4	RTS
;
; MOVE PLAYER0 AND MISSLE1 (YOUR SHIP)
;
MOVE	LDX	OX
	STX	HPOSP0
	INX
	INX
	STX	HPOSP0+5
	LDY	OY
	LDX	#8
MO0	LDA	SHAPE,X
	STA	PLAYER+$0400,Y
	LDA	PLAYER+$0300,Y
	AND	#$F3
	STA	PLAYER+$0300,Y
	INY
	DEX
	BPL	MO0
	LDY	OY
	LDA	PLAYER+$0303,Y
	ORA	#$0C
	STA	PLAYER+$0303,Y
	LDA	PLAYER+$0304,Y
	ORA	#$04
	STA	PLAYER+$0304,Y
	LDA	PLAYER+$0305,Y
	ORA	#$0C
	STA	PLAYER+$0305,Y
	RTS
;
; SHIP SHAPE (ARGH!)
;
SHAPE	.BYTE	0,$C0,$70,0,$73,0,$70,$C0,0
;
; MOVE MISSLE AND MISSLE SOUND
;
MISL	LDA	MSL0	ACTIVE?
	BNE	MSMOV	YES,MOVE IT
	LDA	TRIG0	TRIGGER PRESSED?
	BNE	MSLEND	NO,BYE...
	LDA	#1	SET FLAG
	STA	MSL0
	LDY	OY	GET Y COORD
	LDA	#3	PUT MISSLE ON SCREEN
	STA	PLAYER+$0304,Y
	STY	OYM0	STORE Y
	LDA	#$25	INITIALIZE
	STA	AUDC1	MISSLE
	LDA	#50	SOUND
	STA	SNDF1
	LDA	OX	CALCULATE
	ADC	#6	INITIAL X
	STA	OXM0	COORD
MSMOV	INC	OXM0	MOVE MISSLE
	INC	OXM0	RIGHT
	LDA	OXM0
	STA	HPOSP0+4
	INC	SNDF1	DECREASE
	INC	SNDF1	FREQUENCY
	LDA	SNDF1
	STA	AUDF1
	LDA	#205	MISSLE AT EDGE?
	CMP	OXM0
	BCC	MISEND	YES,KILL MISSLE
	LDA	KILLIT	DID MISSLE HIT?
	BEQ	MSLEND	NO,BYE...
	JSR	LOCATE	YES,BUT WHAT&WHERE
	JSR	ERASE	ZAP IT
MISEND	LDA	#0	MISSLE DEAD
	STA	AUDC1	SO KILL SOUND
	STA	MSL0	CLEAR FLAG
	STA	KILLIT
	LDY	OYM0	ERASE MISSLE
	LDA	PLAYER+$0304,Y
	AND	#$FC
	STA	PLAYER+$0304,Y
MSLEND	RTS
;
; SCROLL SCREEN
;
SCROLL	LDA	TIMERF3	TIME YET?
	ORA	NONEW1	OR AT END OF LEVEL?
	BNE	M2	THEN DON'T SCROLL
	LDA	LEVEL	GET SCROLL
	SEC		SPEED
	SBC	#17	AND DROP
	TAY		IT IN TIMER
	LDA	SPEED,Y	3 AND RESET
	STA	TIMER3	FLAG
	STA	TIMERF3
	LDY	FX	SCROLLED WHOLE
	DEY		CHARACTER?
	BPL	M15	NO,CONT...
	INC	ABX	YES, UPDATE SCREEN ADD.
	BNE	M14	WHOLE PAGE DONE?
	INC	ABY	YES, BUMP SCREEN PAGE
M14	LDY	#3	RESET
M15	STY	FX	SCROLL CNTR
M2	LDX	FX
	STX	HSCROL
	RTS
;
; UPDATE SCREEN MEMORY IN DL
;
SCREEN	LDY	# >SCRN+$0200	ARE WE AT
	LDA	ABY	THE END OF
	CPY	ABY	2ND PAGE OF SCREEN?
	BNE	S11	NO,CONT..
	DEC	NONEW1	YES,DELAY TILL NEW LEVEL
	BNE	SXIT	BYE...
	JSR	LEVELUP	SET UP NEW LEVEL
	LDA	# >SCRN	RESET TO SCRN START
S11	PHA
	LDX	#20	# OF LINES TO BE SCROLLED
	LDY	#6	OFFSET IN DL
S0	LDA	ABX	GET LSB AND
	STA	DSP,Y	STORE IN DL
	INY
	PLA		GET MSB AND
	STA	DSP,Y	STORE IN DL
	CLC		ADD TWO
	ADC	#2	PAGES
	PHA		AND HIDE IT ON STACK TILL NEXT
	INY		LOOP
	INY		INC DL POINTER
	DEX		DONE?
	BPL	S0	NO,LOOP..
	PLA		YES, CLEAR STACK
SXIT	RTS
;
SPEED	.BYTE	3,3,2,2,2,2,2,1,1
;
; SCORE ROUTINE:ENTRY CONDITION
; XREG: SCORE DIGIT TO CHANGE
; YREG: AMOUNT TO ADD TO DIGIT
;
SCOREIT	INC	SCORE,X	GET DIGIT
	LDA	SCORE,X	AND BUMP IT
	CMP	#26	DIGIT>9?
	BEQ	BIGSCR	YES. FIX IT
SCR	DEY		NO. ARE WE
	BEQ	SCREND	DONE? YES.
	BNE	SCOREIT	NO. LOOP
BIGSCR	LDA	#16	DIGIT=0
	STA	SCORE,X	STORE IT
	STA	SCRTEMP	SCORE CARRY FLAG
	BNE	SCR	LOOP...
;
SCREND	LDA	SCRTEMP	FLAG SET?
	BEQ	SC1	NO.
	TXA		LAST DIGIT?
	BEQ	SC1	YES.
	DEX		SET XREG
	LDY	#1	AND YREG
	LDA	#0	CLEAR FLAG
	STA	SCRTEMP	AND START
	BEQ	SCOREIT	ALL OVER
SC1	JMP	HIGHSC	CHECK FOR HIGH SCORE
;
; FIND OUT WHERE WE HIT
;
LOCATE	LDA	OYM0	GET Y COORD
	SEC		AND CONVERT
	SBC	#29	TO IRG4
	LSR	A	SCREEN
	LSR	A	COORDINATES
	AND	#$FE	ADD THE
	CLC		START OF
	ADC	DSP+7	SCREEN MEM.
	STA	TEMPHI	SHAKE WELL AND VIOLA! THE MSB
	LDA	FX	GET LSB OF
	ASL	A	SCREEN
	CLC		ADD THE MISSLES
	ADC	OXM0	X COORD
	SEC		CONVERT
	SBC	#39	TO IRG4
	LSR	A	COORDINATES
	LSR	A	ADD SCROLL
	CLC
	ADC	ABX	AND WE GET
	STA	TEMPLO	THE LSB
	BCC	LOC1	OVER BORDER THEN
	INC	TEMPHI	BUMP MSB
LOC1	RTS
;
; FIND OUT WHAT WE HIT
;
ERASE	LDA	TEMPLO	GET SCREEN
	STA	ADR	MEMORY AND
	LDA	TEMPHI	SEARCH TILL
	STA	ADR+1	WE FIND A
	STA	HITCLR	NONZERO
	LDY	#0	CHARACTER
	LDA	(ADR),Y	(A VICTIM!)
	BNE	GOTIT
	INY
	LDA	(ADR),Y
	BNE	GOTIT
	INY
	LDA	(ADR),Y
	BEQ	LOC1
GOTIT	CMP	#1	IF CHAR IS
	BEQ	ERASE4	1-4,ITS A
	CMP	#2	ROCK.
	BNE	GOT1	SET TO TOP
	DEC	ADR	RIGHT CHAR
	JMP	ERASE4	OF ROCK,
GOT1	CMP	#3	THEN JUMP
	BEQ	GOT2	TO ERASE4
	CMP	#4
	BNE	GOT4
	DEC	ADR
GOT2	DEC	ADR+1
	DEC	ADR+1
	JMP	ERASE4
GOT4	CMP	#10	GENERATOR?
	BNE	GOT5	NO,CONT..
	LDA	#13	YES,KILL IT
	STA	(ADR),Y	SET TO TOP
	INC	ADR+1	OF FIELD.
	INC	ADR+1
	JMP	ERASE2V	ERASE IT!
GOT5	CMP	#9	LOWER GENERATOR?
	BNE	LOC1	NO,BYE..
	LDA	#13	YES,KILL IT
	STA	(ADR),Y	SET TO TOP
	DEC	ADR+1	OF FORCE
	DEC	ADR+1	FIELD.
	DEC	ADR+1
	DEC	ADR+1
	JMP	ERASE2V	ERASE IT.
;
ERASE4	LDA	#0	ERASE THE
	STA	(ADR),Y	FOUR PART
	INC	ADR+1	ROCK BY
	INC	ADR+1	STORING A
	STA	(ADR),Y	BLANK IN
	INY		EACH OF
	STA	(ADR),Y	THE FOUR
	DEC	ADR+1	FORMER
	DEC	ADR+1	POSITIONS
	STA	(ADR),Y
	LDX	#3	SET SCORE
	LDY	#5	TO 50 PTS.
	BNE	ER2
;
ERASE2V	LDA	#0	STORE A
	STA	(ADR),Y	BLANK CHAR
	INC	ADR+1	IN THE 2
	INC	ADR+1	FORCE FIELD
	STA	(ADR),Y	POSITIONS
	LDX	#2	SET SCORE
	LDY	#2	TO 200 PTS.
ER2	STA	KILLIT	CLR COLLISION FLG
	JSR	SCOREIT
	LDA	#25	SET BOOM
	STA	EXPLODE	COUNTER
	JMP	XPINIT	FIREWORKS
;
; BOOM!
;
SOUND	LDA	EXPLODE	FLAG SET?
	BEQ	SNDEND	NO,BYE...
	LDA	TIMERF4	TIME YET?
	BNE	SNDEND	NO,BYE...
	DEC	EXPLODE	SET TO NEXT
	LDA	EXPLODE	TONE+CONTRL
	STA	TIMERF4	RESET FLAG
	BEQ	SNDEND	ANY LEFT? NO,BYE
	TAY		YES,GET
	LDA	EXPSND,Y	THE NEXT
	STA	AUDF2	TONE + CTL
	LDA	RANDOM	AND PUT'EM
	ORA	#$C0	IN (THE)
	STA	AUDF3	POKEY
	LDA	EXPTONE,Y
	ORA	#$40
	STA	AUDC2
	STA	AUDC3
	LDA	#2
	STA	TIMER4
SNDEND	RTS
;
EXPSND	.BYTE	$F5,$F4,$F3,$F2,$F2
	.BYTE	$F0,$F2,$F5,$E9,$E0
	.BYTE	$EF,$F0,$F1,$F2,$F3
	.BYTE	$F4,$F5,$F4,$F1,$F5
	.BYTE	$F2,$F3,$F4,$F5,$F5
EXPTONE	.BYTE	0,0,1,2,3,4,5,5,6,6
	.BYTE	7,7,8,8,9,9,9,10,10,10
;
; NEXT LEVEL,PLEASE....
;
LEVELUP	INC	LEVEL	BUMP LEVEL
	LDA	LEVEL	LVL>9?
	CMP	#26
	BNE	LV2	NO,CONT...
	LDA	#20	YES,BACK TO
	STA	LEVEL	LEVEL FOUR
LV2	LDA	#$40	DISABLE INTERRUPTS
	STA	NMIEN	AND TELL COMPUTER
	PHP		TO STAY PUT
	SEI		TILL NOTIFIED!
	JSR	CLRSCRN	CLEAR SCRN
	LDA	#0	RESET TO
	STA	ABX	SCRN START
	STA	MSL0	KILL MISSLE
	JSR	SNDINT	AND SOUND
	LDA	# >SCRN	PAGE 1 OF
	STA	ABY	SCREEN
	JSR	SCREEN	UPDATE DL
	STA	HITCLR	CLEAR COLLISIONS
	JSR	GRID	ADD GRIDS
	JSR	ROCKS	AND ROCKS
	LDA	#0	RESET AND
	LDX	#10	ADD NASTIES
LV1	STA	RIMAGE,X
	DEX
	BPL	LV1
	JSR	ROCKINT
	INC	LIVES	ADD AN EXTRA LIFE
	PLP		AND BACK TO
	LDA	#$C0	THE REAL
	STA	NMIEN	WORLD....
	RTS
;
;  ROTATE CHARACTER SETS
;
ANIMATE	LDA	TIMERF5	TIME YET?
	BNE	AN3
	LDA	#4	RESET TIMER
	STA	TIMER5	AND FLAG
	STA	TIMERF5
	LDA	CHBAS
	CMP	# >PLAYER+$1000	3RD SET?
	BEQ	AN2	OOPS..
	CLC		NO,ADD 1K
	ADC	# >1024	TO CHBAS
	BNE	AN1	JMP ALWAYS
AN2	LDA	# >PLAYER+$0800	RESET TO
AN1	STA	CHBAS	1ST CHAR
AN3	RTS		SET AND BYE
;
; HIGH SCORE?!?!?!
;
HIGHSC	LDY	#0	CHECK SCORE
HI1	LDA	SCORE,Y	FROM MS TO
	CMP	HIGH,Y	LS DIGIT
	BEQ	HI3	EQUAL LOOP
	BCC	HSCOREND	LOWER,CONT
	BCS	NEWHIGH	REPLACE HIGH SCORE
HI3	INY
	CPY	#4
	BNE	HI1	LOOP....
NEWHIGH	LDY	#0	COPY
NH1	LDA	SCORE,Y	SCORE INTO
	STA	HIGH,Y	HIGH SCORE
	INY
	CPY	#4
	BNE	NH1	LOOP...
HSCOREND	RTS
;
; ADD FORCE FIELD GRIDS
;
GRID	LDA	LEVEL	GET SPACE
	SEC		BETWEEN
	SBC	#17	GRIDS FOR LEVEL
	TAX
	LDA	GATES,X	AND THROW
	STA	TEMP	IN TEMP
	LDY	#0	THEN GET
	LDA	# >SCRN	OFFSET AND
	STA	TEMP2	ADD IT TO
	LDA	OFFSET,X	START OF
	STA	ADR	SCREEN MEM.
GR1	LDA	TEMP2	POKE THE
	STA	ADR+1	3 GRID
	LDX	#7	CHARACTERS
GR2	LDA	#5	INTO
	STA	(ADR),Y	MEMORY
	INC	ADR+1
	INC	ADR+1
	LDA	#6
	STA	(ADR),Y
	INC	ADR+1
	INC	ADR+1
	LDA	#7
	STA	(ADR),Y
	INC	ADR+1
	INC	ADR+1
	DEX
	BNE	GR2
GR3	LDA	RANDOM	FIND A
	AND	#$1F	VALID GATE
	CMP	#20	LOCATION
	BCS	GR3
	CMP	#5
	BCC	GR3
	DEC	ADR	AND ADD THE
	ASL	A	FORCE FIELD
	CLC		AND
	ADC	TEMP2	GENERATORS
	STA	ADR+1
	LDA	#8
	STA	(ADR),Y
	DEC	ADR+1
	DEC	ADR+1
	LDA	#9
	STA	(ADR),Y
	DEC	ADR+1
	DEC	ADR+1
	LDA	#140	FORCEFIELD
	STA	(ADR),Y
	INY
	LDA	#0
	STA	(ADR),Y
	DEC	ADR+1
	DEC	ADR+1
	STA	(ADR),Y
	DEY
	LDA	#139	FORCEFIELD
	STA	(ADR),Y
	DEC	ADR+1
	DEC	ADR+1
	LDA	#10
	STA	(ADR),Y
	DEC	ADR+1
	DEC	ADR+1
	LDA	#8
	STA	(ADR),Y
	LDA	ADR	ADD SPACE
	ADC	TEMP	AND SCREEN
	STA	ADR	LOCATION
	BCC	GR1	BUMP MSB
	INC	TEMP2	IF
	LDA	TEMP2	NECESSARY
	CMP	# >SCRN+$0100	OUT OF ROOM?
	BEQ	GR1	NO,LOOP..
	RTS
;
GATES	.BYTE	255,150,60,30,30,60,60,90,70
OFFSET	.BYTE	255,200,100,75,50,50,50,200,100
;
; MAIN GAME DLI
;
DLI	PHA		SAVE XREG
	TXA		AND A REG
	PHA
	LDX	DLINE	INC NASTY
	INC	DLINE
	LDA	ROCKPOS,X	GET LOCATION
	STA	HPOSP0+3	AND STORE IN PLR2
	STA	HPOSP0+2	AND PLR3
	LDA	COLOR2,X	PUT COLOR
	STA	HCOLPM2	DIRECTLY
	LDA	COLOR3,X	INTO
	STA	HCOLPM3	HARDWARE REGISTERS
	CPX	#10	ANY LEFT?
	BNE	DL1	YES,LOOP..
	LDA	# <DLI2	NO,POINT
	STA	VERTI	TO NEXT
	LDA	# >DLI2	DLI
	STA	VERTI+1
DL1	PLA		RESTORE A
	TAX		AND X
	PLA
	RTI
;
DLI2	PHA
	LDA	#$F8	POKE SCORE
	STA	HCOLP0	COLORS
	LDA	#$98	DIRECTLY
	STA	HCOLP1	INTO
	LDA	#38	HARDWARE
	STA	HCOLP3	REGISTERS
	LDA	# <DLI	POINT TO
	STA	VERTI	MAIN
	LDA	# >DLI	DLI
	STA	VERTI+1
	PLA
	RTI
;
; ATTACTING NASTIES.....
;
ATTACK	LDX	#0
	STX	DLINE
AT3	LDA	ROCKSPD,X	NASTY ACTIVE?
	BEQ	AT1	NO,GIVE IT LIFE!
	LDA	ROCKPOS,X	YES MOVE
	SEC		IT
	SBC	ROCKSPD,X	LEFT
	BNE	AT2	STILL ON SCREEN?
	STA	ROCKSPD,X	NO, RESET POSITION
	LDA	#254	AND SPEED
AT2	STA	ROCKPOS,X
AT4	INX		MORE
	CPX	#10	NASTIES?
	BNE	AT3	YES,LOOP..
	RTS
AT1	LDA	NONEW1	NOT END OF LEVEL?
	ORA	RANDOM	CAN WE GIVE IT LIFE?
	BNE	AT4	NO,DRATS..
	LDA	#1
	LDY	RANDOM
	CPY	#15	A FAST ONE?
	BCS	AT0
	LDA	#2	YES. FUN!!!
AT0	STA	ROCKSPD,X
	LDA	LEVEL	LVL>6?
	CMP	#22
	BCC	AT10	NO. LOOP
	INC	ROCKSPD,X	SPEED THINGS UP
AT10	JMP	AT4	LOOP....
;
IMAGE2	.BYTE	0,0,0,0,0,0,$78,$FC
	.BYTE	$78,0,0,0,0,0,0,0
	.BYTE	0,0,0,0,$1C,$3E,$7F,$6B
	.BYTE	$7F,$5D,$22,$1C,0,0,0,0
	.BYTE	0,0,0,0,0,0,$7F,$F8
	.BYTE	$7F,0,0,0,0,0,0,0
	.BYTE	0,0,0,0,$18,$3C,$7E,$3C
	.BYTE	$5A,$66,$7E,$3C,$18,0,0,0
	.BYTE	0,0,0,0,7,$0F,$0E,$1C
	.BYTE	0,$1C,$0E,$0F,7,0,0,0
	.BYTE	0,0,0,0,0,0,$2C,$24
	.BYTE	$2F,$3D,9,$0F,0,0,0,0
	.BYTE	0,0,0,0,0,0,$10,$38
	.BYTE	$7C,$38,$10,0,0,0,0,0
	.BYTE	0,0,0,0,0,0,0,2
	.BYTE	7,2,0,0,0,0,0,0
IMAGE1	.BYTE	0,0,0,7,$0E,$3C,0,$FC
	.BYTE	0,$3C,$0E,7,0,0,0,0
	.BYTE	0,0,0,0,0,0,0,$14
	.BYTE	0,$22,$1C,0,0,0,0,0
	.BYTE	0,0,0,0,3,7,$3F,$3F
	.BYTE	$3F,7,3,0,0,0,0,0
	.BYTE	0,0,0,$18,$24,$42,$81,$C3
	.BYTE	$E7,$FF,$7E,$3C,$18,0,0,0
	.BYTE	0,0,0,0,$0F,0,0,0
	.BYTE	$FC,0,0,0,$0F,0,0,0
	.BYTE	0,0,0,0,$F0,$90,$90,$D0
	.BYTE	$0B,$09,$09,$0F,0,0,0,0
	.BYTE	0,0,0,0,0,$10,$28,$44
	.BYTE	$92,$44,$28,$10,0,0,0,0
	.BYTE	0,0,0,0,0,0,0,0
	.BYTE	2,0,0,0,0,0,0,0
;
; INITIALIZE NASTIES...
;
ROCKINT	LDA	LEVEL	ARE WE
	CMP	#17	PAST THE 1ST LEVEL?
	BEQ	RK7	NO,BYE..
	LDA	#10	READ THE
	STA	TEMP	IMAGES OF
RK1	LDY	#15	THE NASTIES
	LDA	TEMP	(PLAYERS
	ASL	A	2 AND 3)
	ASL	A	INTO PMG
	ASL	A	MEMORY
	ASL	A	WHERE THE
	CLC		DLI WILL
	ADC	#34	FIND'EM.
	TAX
RK2	LDA	IMAGE1,Y
	STA	PLAYER+$0600,X
	LDA	IMAGE2,Y
	STA	PLAYER+$0700,X
	DEX
	DEY
	BNE	RK2
	DEC	TEMP
	BNE	RK1
	LDX	#10	SET INITIAL POSITION
RK4	LDA	#254	OFF SCREEN AND
	STA	ROCKPOS,X	ZERO SPEED
	LDA	#0	SO THEY
	STA	ROCKSPD,X	STAY
	DEX		PUT UNTIL
	BPL	RK4	WE ACTIVATE
	LDX	#9	THEM
	LDA	#4
RK5	CLC
	ADC	#$50	GIVE EACH
	STA	COLOR2,X	ONE TWO
	DEX		DIFFERENT
	BPL	RK5	COLORS
	LDX	#9
	LDA	#$88
RK6	CLC
	ADC	#$30
	STA	COLOR3,X
	DEX
	BPL	RK6
RK7	RTS
;
; EXPLOSION (FIREWORKS)
;
XPLODE	LDA	XPIMAGE	GET IMAGE NUMBER.
	BEQ	EXPEND	ANY LEFT? NO,BYE...
	DEC	EXPTIME	TIME YET?
	BNE	EXPEND	NO,BYE...
	DEC	XPIMAGE	NEXT IMAGE
	LDA	XPIMAGE
	ASL	A	OFFSET IN
	ASL	A	IMAGE DATA
	ASL	A
	ORA	#$07
	TAX
	LDA	#8
	STA	TEMP2
	LDY	XPY
XPLOOP	LDA	XPLOD,X	STORE IMAGE
	STA	PLAYER+$0500,Y	IN PLAYER1
	DEX
	INY		NEXT BYTE
	DEC	TEMP2	ANY LEFT?
	BNE	XPLOOP	YES,LOOP
	LDA	#6	NO SET
	STA	EXPTIME	TIMER
	LDA	XPIMAGE
	BNE	EXPEND
	STA	HPOSP0+1
EXPEND	RTS
XPINIT	LDX	#7	INITIALIZE
	LDA	#8	EXPLOSION
	STA	TEMP2
	LDY	XPY	GET IT'S
	JSR	XPLOOP	LOCATION
	LDA	OYM0	AND PUT IT
	STA	XPY	ON THE
	LDA	OXM0	SCREEN THEN
	STA	HPOSP0+1
	LDA	#9	SET IMAGE
	STA	XPIMAGE	POINTER
	LDA	#1	AND TIMER
	STA	EXPTIME
	RTS
;
; EXPLOSION SHAPE DATA
;
XPLOD	.BYTE	0,0,0,0,0,0,0,0
	.BYTE	$81,0,0,0,0,0,0,$81
	.BYTE	$81,$42,0,0,0,0,$42,$81
	.BYTE	$89,$42,$24,$80,$01,$24,$42,$91
	.BYTE	8,$4A,$24,$C0,3,$24,$52,$1D
	.BYTE	8,8,$2C,$E0,7,$34,$10,$10
	.BYTE	0,8,8,$78,$1E,$10,$10,0
	.BYTE	0,0,8,$38,$1C,$10,0,0
	.BYTE	0,0,0,$18,$18,0,0,0
;
; KILL ATTACKING NASTIES!
;
KILLPLR	LDA	OYM0	GET Y COORD
	SEC		AND CONVERT
	SBC	#28	TO GET #
	LSR	A	OF NASTY
	LSR	A	WE HIT
	LSR	A
	LSR	A
	TAX
	LDA	#0	RESET SPEED AND POSITION
	STA	ROCKSPD,X
	LDA	#254
	STA	ROCKPOS,X
	INC	RIMAGE,X	SET TO
	LDA	RIMAGE,X	NEXT NASTY
	STA	TEMP	IMAGE
	STX	TEMP2	SCORE= 100
	TAY		TIMES IMAGE
	LDX	#2	NUMBER+1
	JSR	SCOREIT
	LDX	TEMP2
	LDY	TEMP	ANY IMAGES
	CPY	#8	LEFT?
	BCC	KL1	YES,NEXT
	LDA	#0	NO,RESET
	STA	RIMAGE,X	TO IMAGE #0
	STA	TEMP
KL1	LDA	#23
	STA	EXPLODE
	TXA
	ASL	A	READ NEW
	ASL	A	NASTY
	ASL	A	INTO PMG
	ASL	A	MEMORY
	CLC
	ADC	#49
	TAY
	LDA	TEMP
	ASL	A
	ASL	A
	ASL	A
	ASL	A
	STA	TEMP
	ORA	#$0F
	TAX
KL2	LDA	IMAGE1,X
	STA	PLAYER+$0600,Y
	LDA	IMAGE2,X
	STA	PLAYER+$0700,Y
	DEY
	DEX
	CPX	TEMP	DONE?
	BNE	KL2	NO,LOOP...
	STX	HITCLR	YES,CLEAR
	LDA	#0	COLL. FLAG
	STA	KILLPL
	JMP	MISEND	KILL MISSLE
;
; TITLE SCREEN
;
TITLE	LDA	# <TITLEPG	PUT
	STA	DLST	TITLE
	LDA	# >TITLEPG	PAGE ON
	STA	DLST+1	SCREEN
	JSR	PLRINT	GET RID OF PMG
	LDA	#$C0	ENABLE DLI'S FOR
	STA	NMIEN	RAINBOW EFFECT
	INC	TITLF	SET FLAG
	LDA	STLEVEL	UPDATE
	STA	LEVEL	LEVEL
LOOP	LDA	CONSOL	IS SELECT
	CMP	#5	PRESSED?
	BNE	LOOP2	NO,CONT..
	INC	LEVEL	YES,INC
	LDA	LEVEL	LEVEL
	CMP	#26	LVL>9?
	BNE	LP2	NO,CONT..
	LDA	#17	LVL=1
LP2	STA	LEVEL
	LDA	#30	DELAY 1/2
	STA	TIMER5	SECOND
	STA	TIMERF5
LOOP2	LDA	LEVEL	PUT NEW
	STA	TITLE4+16	LEVEL
	JSR	ANIMATE	ON SCREEN
	LDA	TRIG0	IF TRIGGER
	BEQ	LP7	OR START
	LDA	CONSOL	IS PRESSED
	CMP	#6	CONTINUE, IF NOT
	BNE	LP3	LOOP...
LP7	LDA	# <DSP	POINT TO
	STA	DLST	MAIN GAME
	LDA	# >DSP	SCREEN
	STA	DLST+1
	LDA	# <DLI
	STA	VERTI
	LDA	# >DLI
	STA	VERTI+1
	LDA	#'0-32
	LDY	#5
LP5	STA	SCORE-1,Y
	DEY
	BNE	LP5
	STY	OVER	CLR FLAG
	STY	TITLF
	LDA	LEVEL	SET LEVEL
	STA	STLEVEL
	RTS
LP3	LDA	TIMERF5	DELAY LOOP
	BNE	LOOP2
	BEQ	LOOP
;
STLEVEL	.BYTE	17
;
; TITLE SCREEN DLI
;
TDLI	PHA		SAVE X AND
	TXA		A REGISTERS
	PHA
	LDX	#15
	LDA	DSHIFT	GET COLOR
	STA	CSHIFT
TDLI1	LDA	CSHIFT
	STA	WSYNC	WAIT FOR NEW SCAN LINE
	STA	HCOLP0	STORE IT IN HARDWARE
	CLC		ADD TWO
	ADC	#2
	STA	CSHIFT
	DEX		ANY MORE LINES?
	BPL	TDLI1	YES,LOOP
	LDX	#15	RESET COUNT
TDLI2	LDA	CSHIFT	GET COLOR
	STA	WSYNC	WAIT FOR NEW LINE
	STA	HCOLP0	STORE IT
	SEC		SUBTRACT 2
	SBC	#2	TO GET THE
	STA	CSHIFT	MIRROR EFFECT
	DEX		ANY MORE?
	BPL	TDLI2	YES,LOOP
	LDA	TIMERF4	TIME YET?
	BNE	TDLIX	NO,CONT..
	LDA	#1	YES,RESET
	STA	TIMERF4	TIMER AND
	STA	TIMER4	FLAG AND
	INC	DSHIFT	INC THE START COLOR
TDLIX	LDA	# <DLI2	POINT TO
	STA	VERTI	NEXT DLI
	LDA	# >DLI2
	STA	VERTI+1
	PLA		RESTORE
	TAX		REGISTERS
	PLA
	RTI
;
; TITLE PAGE DISPLAY LIST
;
TITLEPG	.BYTE	$70,$70,$46
	.WORD	SCORELN
	.BYTE	$70,$F0,$47
	.WORD	TITLE1
	.BYTE	$47
	.WORD	TITLE6
	.BYTE	$70,$70,$46
	.WORD	TITLE2
	.BYTE	$46
	.WORD	TITLE3
	.BYTE	$F0,$47
	.WORD	TITLE5
	.BYTE	$70,$C6
	.WORD	TITLE4
	.BYTE	$70,$70,$70
	.BYTE	$70,$70,$70,$46
	.WORD	SCORELN
	.BYTE	6,6,$41
	.WORD	TITLEPG
;
TITLE1	.SBYTE	"       COSMIC "
TITLE6	.SBYTE	"      DEFENDER"
TITLE2	.SBYTE	+$80,"         BY    "
TITLE3	.SBYTE	+$80,"     phill roey  "
TITLE4	.SBYTE	"   select level:  "
TITLE5	.SBYTE	+$80,"  analog computing  "
;
;       DISPLAY LIST
;
DSP	.BYTE	$70,$70,$C6
	.WORD	SCORELN
	.BYTE	$54
	.WORD	0
	.BYTE	$D4
	.WORD	0
	.BYTE	$54
	.WORD	0
	.BYTE	$D4
	.WORD	0
	.BYTE	$54
	.WORD	0
	.BYTE	$D4
	.WORD	0
	.BYTE	$54
	.WORD	0
ML1	.BYTE	$D4
	.WORD	0
ML2	.BYTE	$54
	.WORD	0
ML3	.BYTE	$D4
	.WORD	0
	.BYTE	$54
	.WORD	0
	.BYTE	$D4
	.WORD	0
	.BYTE	$54
	.WORD	0
	.BYTE	$D4
	.WORD	0
	.BYTE	$54
	.WORD	0
	.BYTE	$D4
	.WORD	0
	.BYTE	$54
	.WORD	0
	.BYTE	$D4
	.WORD	0
	.BYTE	$54
	.WORD	0
	.BYTE	$D4
	.WORD	0
	.BYTE	$54
	.WORD	0
	.BYTE	$C6
	.WORD	SCORELN
	.BYTE	6,6,$41
	.WORD	DSP
;
SCORELN	.SBYTE	+$80,"...................."
	.SBYTE	+$80," score:"
SCORE	.SBYTE	"00000"
	.SBYTE	" lives:"
LIVES	.SBYTE	"3"
	.SBYTE	"  hi:"
HIGH	.SBYTE	"00000"
	.SBYTE	"  level:"
LEVEL	.SBYTE	"1"
BLANK	.SBYTE	"                                                     "
MESSAGE	.SBYTE	"     GAME  OVER     "
;
; CHARACTER SET #1
;
CHSET	.BYTE	0,1,1,20,17,26,21,85
	.BYTE	0,64,80,80,100,84,69,81
	.BYTE	89,89,26,21,17,5,1,0
	.BYTE	105,88,84,84,80,64,0,0
	.BYTE	255,255,215,215,215,215,255,255
	.BYTE	255,255,195,195,195,195,255,255
	.BYTE	255,255,235,235,235,235,255,255
	.BYTE	15,3,3,15,15,3,3,15
	.BYTE	63,245,245,234,234,245,245,63
	.BYTE	63,245,245,234,234,245,245,63
	.BYTE	195,60,0,195,60,0,195,60
	.BYTE	0,195,60,0,195,60,0,195
	.BYTE	63,240,240,192,192,240,240,63
	.BYTE	$FF,$49,$49,$49,$49,$49,$49,$FF
	.BYTE	0,$1E,$21,$2D,$29,$2D,$21,$1E
;
; CHARACTER SET #2
;
CHSET2	.BYTE	0,1,1,20,17,26,21,85
	.BYTE	0,64,80,80,100,84,69,81
	.BYTE	89,89,26,21,17,5,1,0
	.BYTE	105,88,84,84,80,64,0,0
	.BYTE	255,255,235,235,235,235,255,255
	.BYTE	255,255,215,215,215,215,255,255
	.BYTE	255,255,195,195,195,195,255,255
	.BYTE	15,3,3,15,15,3,3,15
	.BYTE	63,245,245,192,192,245,245,63
	.BYTE	63,245,245,192,192,245,245,63
	.BYTE	0,195,60,0,195,60,0,195
	.BYTE	60,0,195,60,0,195,60,0
	.BYTE	63,240,240,192,192,240,240,63
	.BYTE	$FF,$92,$92,$92,$92,$92,$92,$FF
	.BYTE	0,$1E,$21,$2D,$29,$2D,$21,$1E
;
; CHARACTER SET #3
;
CHSET3	.BYTE	0,1,1,20,17,26,21,85
	.BYTE	0,64,80,80,100,84,69,81
	.BYTE	89,89,26,21,17,5,1,0
	.BYTE	105,88,84,84,80,64,0,0
	.BYTE	255,255,195,195,195,195,255,255
	.BYTE	255,255,235,235,235,235,255,255
	.BYTE	255,255,215,215,215,215,255,255
	.BYTE	15,3,3,15,15,3,3,15
	.BYTE	63,245,245,213,213,245,245,63
	.BYTE	63,245,245,213,213,245,245,63
	.BYTE	60,0,195,60,0,195,60,0
	.BYTE	195,60,0,195,60,0,195,60
	.BYTE	63,240,240,192,192,240,240,63
	.BYTE	$FF,$24,$24,$24,$24,$24,$24,$FF
	.BYTE	0,$1E,$21,$2D,$29,$2D,$21,$1E
;
	*=	$02E0	RUN PROGRAM
	.WORD	START
	.END