A.N.A.L.O.G. ISSUE 17 / MARCH 1984 / PAGE 83
Think you can defend a planet from enemy space-bombs? This issue’s assembly-language game will let you find out. Planetary Defense is a one-player game that can be played with either a joystick or Koala Technologies Corporation’s “KoalaPad.”
If you’re familiar with ANALOG’s previous assembly-language games, you’ll notice something new about this one: There’s only one BASIC listing! Our early efforts included modification listings for cassette and disk versions. This new approach allows you to make either version using just one program, and reduces the possibility of typing errors.
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 Planetary Defense. 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 Planetary Defense, 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 Planetary Defense.
MAKE CASSETTE (0), OR DISK (1)?MAKE CASSETTE (0), OR DISK (1)?Once started, Planetary Defense will display the title screen and controller options. To use a joystick, plug it into controller jack #1 and press either START or the joystick button to begin the game.
To use the KoalaPad, plug it into controller jack #1 and press either SELECT or one of the KoalaPad buttons to begin the game.
You are in charge of protecting your planet from alien attackers. Your only defense is an orbiting satellite armed with a charged-particle gun. To aim the gun, you simply move the targeting crosshairs to the desired point with the controller. Press your controller button to fire at the target. Once fired, you have no control over the charged-particle projectile. Up to six projectiles may be active at a time. Be careful about where you shoot — if you’re not careful, you can hit your own planet and destroy part of it!
Your usual target will be the red space-bombs being dropped by the aliens. These bombs head toward the center of your planet. If they hit the planet they will explode, destroying a chunk of it. If any explosion ever reaches the core of the planet, the game is over. If you destroy a space-bomb before it hits your planet, you are awarded from 10-120 points, depending on the level.
Another threat that is much more dangerous than the space-bombs is a flying saucer that cruises along, firing its own charged-particle weapons at your planet! If not stopped quickly, this alien menace will do an incredible amount of damage. The saucer appears more often at higher levels, so be on the lookout! Saucers are worth from 100-400 points each, depending on the level.
If your satellite ever collides with an incoming space-bomb, the satellite will be destroyed. If the collision is a direct hit, the bomb will also explode, giving you the appropriate amount of points. This is a costly way to gain points, as you have only five satellites. Once all five are destroyed, the game is over, and your planet will be overrun by enemy bombs.
Your score is shown at the upper left of the screen. The number of the level you are on is shown at the upper center of the screen. The number of satellites you have is shown at the upper right by the “*” characters. The space bar pauses the game. Good luck!
10 REM *** PLANETARY DEFENSE *** 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:RESTOR E 1000:TRAP 120:? "CHECKING DATA" 50 LINE=LINE+10:? "LINE:";LINE:READ DA T$:IF LEN(DAT$)<>90 THEN 220 60 DATLIN=PEEK(183)+PEEK(184)*256:IF D ATLIN<>LINE THEN ? "LINE ";LINE;" MISS ING!":END 70 FOR X=1 TO 89 STEP 2:D1=ASC(DAT$(X, X))-48:D2=ASC(DAT$(X+1,X+1))-48:BYTE=H EX(D1)*16+HEX(D2) 80 IF PASS=2 THEN PUT #1,BYTE:NEXT X:R EAD 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,18:PUT #1,33:CLOSE #1:END 160 FOR X=1 TO 34:PUT #1,0:NEXT X:CLOS E #1:END 170 IF NOT DSK THEN 200 180 ? "INSERT DISK WITH DOS, PRESS RET URN";: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,181:PUT #1,45: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=99 0:RESTORE 1000:TRAP 120:GOTO 50 220 ? "BAD DATA: LINE ";LINE :END 230 DATA 0,28,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,18,133,10,169,33,1 33,11,24,96 1000 DATA 707070707070707070461C207007 700610067070062006400641002000212E212C 2F2700232F2D303534292E27,480 1010 DATA 07330040706C616E657461727940 40646566656E73654080A2B980A3A8A1B2ACA5 B380A2A1A3A8A1AEA480C0C0,82 1020 DATA C0E1EEE4C0F4EFEDC0E8F5E4F3EF EEC0C0C0406B6F616C6140706164404D407365 6C65637440C0EAEFF9F3F4E9,570 1030 DATA E3EBC0CDCDCDC0F3F4E1F2F4C000 002F3200303225333300343229272725320000 707046452E4D00308D8D8D8D,161 1040 DATA 8D8D8D8D8D8D8D8D8D8D8D8D8D8D 8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D 8D8D8D8D8D8D8D8D8D8D8D8D,506 1050 DATA 8D8D8D8D8D8D8D8D8D8D8D8D8D8D 8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D 8D8D8D8D8D8D8D8D8D8D8D8D,851 1060 DATA 8D41A820D8A9008D0ED4A27F9580 CAD0FBE6BBA9FF859C85A985B985BA20EA298D 07D2A9C48DC402A9848DC502,315 1070 DATA A90A8DC602A9988DC702A9508D00 02A9238D0102A9C08D0ED4A9328D00D48D2F02 A9008D1DD08D08D2A2049D0D,970 1080 DATA D0CA10FA2065E4A9008D3002A920 8D3102A223A076A907205CE4A93C858CA58CD0 FCAD7C024D7D02D010AD8402,64 1090 DATA F00BAD1FD02903C903F0EA290185 B0A90A858CA58CD0FCAD1FD0C907D0F1A93085 81A9008580A20FA89180C8D0,21 1100 DATA FBE681CA10F6A2009D00039D0004 9D00059D00069D0007CAD0EEA9A88D3002A920 8D3102A9008D07D4A93E8D2F,584 1110 DATA 028D00D4A9038D1DD0A9118D6F02 A90085BBA98F85828584A93785838585A200A0 00BD5F22D0034C9522300991,324 1120 DATA 829184C8E84C11220A85870A0AA9 55B002A90048BD5F22290F85866891829184C8 C686D0F7E8A58710CB38A582,647 1130 DATA E9288582B002C68318A584692885 8490B5E6854C0F22EAEAEAEAEA15A854C115A8 54C105A850C105A850C101A8,397 1140 DATA 40C181E88115A654C18105A650C1 8101A640C182E68205A450C183E484E200A240 A00018A9607D0F2399401F9D,638 1150 DATA 801FA9507DCE229D001E99401E38 A950FDCE229D801E99C01EA960FD0F239D001F 99C01FC8CA10CE4C34250001,255 1160 DATA 02020304050506070809090A0B0C 0C0D0E0E0F1010111212131414151516171718 1819191A1A1B1B1B1C1C1D1D,15 1170 DATA 1D1E1E1E1E1F1F1F1F1F20202020 20202020363636363636363635353534343433 3332323131302F2F2E2D2C2C,943 1180 DATA 2B2A292827262625242321201F1E 1D1C1B1A18171615141211100F0D0C0B090807 0504030100488A48E6AAA5AA,834 1190 DATA 2907AABD6E2305B18D0AD48D16D0 A98C8D17D068AA68400002040608060402D8A6 ABBD8F2C8DC302A90585AAA9,370 1200 DATA C08D0ED4ADFC02C921D00BA5B249 FF85B2A9FF8DFC02A5B2F00DA900A2079D00D2 CA10FA4C62E4A5BBD009ADC6,721 1210 DATA 021869108DC602A5B8F00C4A4A8D 07D2A9288D06D2C6B8A5A910034C3324A491A2 05A90F39FD0299FD02C8CA10,578 1220 DATA F4AD7802A690A4914AB00288884A B002C8C84AB001CA4AB001E8E0309006E0D0B0 028690C0209006C0E0B00284,258 1230 DATA 91A5B0F003207B2BA5BCD01CA205 A491BD892C19FD0299FD02C8CA10F3A690CA8E 07D0E8E88E06D0A5AEF002C6,437 1240 DATA AEA58CF002C68CA58DF002C68DA5 8EF002C68EA5A910034C62E4A5A5F03AE689A4 8918B9001E8596692F8D05D0,351 1250 DATA 69028D04D0B9001F4A85972A6924 AAE68FA58F2908A8A9088588BD000329F01924 259D0003CAC8C688D0EFA5AB,332 1260 DATA F030ACF42D8888A209C020900AC0 DFB006BD912C99000788CA10EEADE82D8D03D0 E6ACA5AC4A2903AABD9B2C8D,987 1270 DATA 952C8D962CA6BA1007A9008D01D2 F00DA9A68D01D2BD752D8D00D2C6BAA6B91007 A9008D03D2F00DA9A68D03D2,276 1280 DATA BD832D8D02D2C6B9A5ABF00BADF4 2DC9249004C9E79007A9008D05D2F017E6B7A6 B7E00C3004A20086B7A9A88D,189 1290 DATA 05D2BD912D8D04D24C62E4000000 0A040A0000000000040A040000A900859D859E 859F858C85B285BD85AB859B,122 1300 DATA A20B9DD92DCA10FAA213BD0D2D9D 452ECA10F7A901859A85A5A904859CA90C8DC6 02A9348DC0028DC1028DC202,315 1310 DATA A97F8590A9818591A90185A92048 2BA9548D9337A9158D94378D1ED0205E2BA69B BD212D85C6BD2D2D85C7BD39,537 1320 DATA 2D85ADBD452DC9FFD005AD0AD229 F085B1BD5D2D85A6BD512D85A7BD692D85A8E0 0BF002E69BF8A59A18690185,417 1330 DATA 9AD8A5B2D0FCA900854DA5A91007 A5BDD0034CD229AD93372903C903F009AD9437 29C0C9C0D00FA90085C685A5,113 1340 DATA A9FF859C85A920EA29AD1FD0C907 F0034C1221204327A5A5F010AD8402C599F009 8599C900D00320652820AE28,172 1350 DATA A58DD01720802920F62920762620 1B29A5ABF003202328A901858DA5C6D089A5A9 3085ADD92D0DDA2D0DDB2D0D,871 1360 DATA DC2DF0034CCF254C8F25A94085B8 E6BDA4BDA5BE999D2DA5BF99B12DA90099C52D 60A90085C1E6C1A5BDC5C130,88 1370 DATA F3A6C1A90085C0BDC52DC925302E E6C038E925C92530258AA8E8E4BDF0021015BD 9D2D999D2DBDB12D99B12DBD,973 1380 DATA C52D99C52DC8D0E4C6BDC6C14C7A 26FEC52DA8BD9D2D1879C32C85C2C9A0B0ACBD B12D79E82C85C3C960B0A020,536 1390 DATA F326A5C0D00ABDAF2C118A918A4C 7A26BDB32C318A4CE626A5C30A858AA900858B 068A268B068AA58A85C5268B,774 1400 DATA A58B85C4068A268B068A268BA58A 1865C5858AA58B65C4858BA90018658A858AA9 30658B858BA5C22903AAA5C2,182 1410 DATA 4A4A18658A858A9002E68BA00060 A5AED004A5C6D00160A203BDD92DF004CA10F8 60A9019DD92DC6C6A9009D15,608 1420 DATA 2E9D212EA5A93053E003D04FAD0A D2C5ADB048A90185ABAD0AD22903A8B99F2CC9 FFD005201928692385929DE5,918 1430 DATA 2DB9A32CC9FFD005201928693785 939DF12DB9A72CC9FFD005A9E638E5938594B9 AB2CC9FFD002A59285954C01,917 1440 DATA 28AD0AD23019AD0AD22901A8B967 2C9DF12DAD0AD2C9FAB0F99DE52D4CF127AD0A D22901A8B9672C9DE52DAD0A,406 1450 DATA D2C9FAB0F99DF12DBDE52D8592BD F12D8593A9808594859520EE2AA5CA9D2D2EA5 CB9D392EA5C89DFD2DA5C99D,190 1460 DATA 092E60AD0AD2297FC964B0F760AD 0AD2C906B00DA207BDDD2DF007CABDDD2DF001 60A9308595A9508594ADE82D,855 1470 DATA 38E92C85929DE92DC9A0B0E8ADF4 2DE9254A85939DF52DC95FB0D9A90D85B94C91 28A205BDDD2DF004CA10F860,82 1480 DATA A90D85BAA59685929DE92DA59785 939DF52DA59038E9308594A59138E9204A8595 20EE2AA5C89D012EA5C99D0D,986 1490 DATA 2EA5CA9D312EA5CB9D3D2EA9019D DD2D60A58ED0FBA59C1004A901D002A5C7858E A203BDD92DF052208F2AA59C,574 1500 DATA 1009208F2A208F2A208F2ABDF12D 1869028582A900858A8A0904858B8684E003D0 04A5ABD027BC2D2EA9118587,3 1510 DATA BE852CA482C0209009C0DFB005BD 692C918A88CAC687D0EDA684BDE52D9D00D0CA 10A660A20BBDD92DF058BDE5,350 1520 DATA 2D85C2BDF12D85C3869820F326B1 8A3DB32C918AA698208F2ABDE52DC9A0B02285 C2BDF12DC960B01985C320F3,478 1530 DATA 26BDAF2C318AF015A698A5C285BE A5C385BF205E26A9009DD92D4C7A29BDAF2CA6 983DB72C118A918ACAE003D0,136 1540 DATA 9E60A58CF00160A59C30FBA90185 A5AD08D00D09D0F0EFA90085A58589A69C9D53 2EC69C1009A9FF85C685A920,31 1550 DATA EA29A59685BEA59785BF205E26A9 508596A9158597A200BD000329F09D0003CAD0 F5A9FF858C6020EA29AD8402,611 1560 DATA 2D7C022D7D02F007AD1FD0C907F0 EE4C1221A9008D01D28D03D28D05D260A203A5 ABF01EA90085AFA5A9304DAD,633 1570 DATA E82DC9279046C9D3B042ADF42DC9 13903BC9E7B037A90085AFBD04D02905F063E6 AF2904F026A5A93022A90285,277 1580 DATA AEE003D00BA5ABF007A5A885A14C 4A2AA5A685A2A5A785A1869820362BA698A900 9DD92DBC2D2EBDE52D38F987,54 1590 DATA 2C85BEBDF12D38E9284A85BFA5AB F00FE003D00BA90085AB20DA2AA5A9300A20DA 2AA5AFF003205E26CA108F8D,358 1600 DATA 1ED060BD152E187DFD2D9D152EA9 002A85CCBD212E7D092E9D212EA9002A85CDBD 2D2EF008BDE52D65CC4CBF2A,5 1610 DATA BDE52D38E5CC9DE52DBD392EF009 BDF12D38E5CD4CD62ABDF12D1865CD9DF12D60 A9009D00D0A88A0904858B98,847 1620 DATA 858A918A88D0FB60A90085CAA592 C5949005E5944C042BE6CAA59438E59285C8A9 0185CBA593C5959005E5954C,177 1630 DATA 1C2BC6CBA59538E59385C905C8D0 04A98085C8A5C8300BA5C9300706C806C94C26 2B60A000F818A202B59D75A0,498 1640 DATA 959D94A0CA10F5D8A91085A4A201 A000B99D0020662BE8E8C8C003D0F360A05084 A4A59AA20B85A3290F05A49D,227 1650 DATA 462EA5A34A4A4A4A05A49D452E60 A204B5CD95CEB5D295D3CAD0F5A491A205B900 0329F0990003CA10F5A90185,684 1660 DATA BCAD700285CEC9059052AD710285 D3C9059049A9CE85B5A90085B620F72BB03C69 10C930B002A930C9D09002A9,205 1670 DATA CF8590A9D385B5A90085B620F72B B01F6910C920B002A920C9E09002A9DF8591AD 7C024D7D0249018D8402A900,391 1680 DATA 85BC60A900A20495DDCA10FB85B3 85B4A8A201B1B599D800C8205A2CB1B50A36DD 71B59002F6DD0A36DD95D8E8,463 1690 DATA C8205A2CB1B599D800A204B5D865 B385B3B5DD65B485B4CA10F1A204A5B346B46A CAD0FAAAA00438F1B5B00449,757 1700 DATA FF6901C918B0048A8810EF60B1B5 0A36DD0A36DD95D8E8C86000FA000000000000 DC3E7E3EDC00000000000076,27 1710 DATA F8FCF8760000000000001B102F2A 4040A0A0404034F80000187E00007E18000092 49249228FFD2FFFF14FFE6FF,377 1720 DATA D2FF2814FFE6FFC0300C033FCFF3 FC00000000FFFFFFFFFFFFAAAA0001FF00FF01 0002FFFE000100FE020101FF,69 1730 DATA 0002FEFF0300FDFE0302FFFE01FF 03FD01FD02000001FF00010100FF0102FFFEFF 0102FE0203FF00FE01FD00FE,931 1740 DATA FF020302FDFD000103FFFE000000 00000000006C766C000000CACACACACA000A0F 141914190F141914191E0C0B,829 1750 DATA 0A090807070605050403000A325A 3250283C6450787D20304050607080A0B0C0D0 FF0000000000000000000101,251 1760 DATA 0110203040506070809000102000 0101010202030303040404F4FED2DCB0BA8E98 6C764A542832656055504540,601 1770 DATA 35302520151005000A0B0C0E1011 1211100E0C0B00000000000000000000000000 000000000000000000000000,981
;
; File: PLANET1.M65
;
.OPT NO LIST
; ------------------
; ANALOG Computing's
; PLANETARY DEFENSE
; ------------------
;
; by Charles Bachand
; and Tom Hudson
;
; Written with OSS MAC/65
;
; ------------------
; Hardware Registers
; ------------------
;
HPOSP0 = $D000 ;P0 horizontal
HPOSM0 = $D004 ;M0 horizontal
P0PF = $D004 ;P0-PField coll.
M0PL = $D008 ;M0-PLayer coll.
GRAFP0 = $D00D ;PM graphics
COLPF0 = $D016 ;PF color 0
GRACTL = $D01D ;graphic control
HITCLR = $D01E ;clear hit reg
CONSOL = $D01F ;console buttons
AUDF1 = $D200 ;frequency 1
AUDC1 = $D201 ;volume 1
AUDCTL = $D208 ;audio control
RANDOM = $D20A ;random numbers
DMACTL = $D400 ;DMA control
PMBASE = $D407 ;PM base address
WSYNC = $D40A ;wait hor. sync
NMIEN = $D40E ;interrupt reg.
ATRACT = $4D ;attract flag
;
; ------------------------
; Operating System Vectors
; ------------------------
;
SETVBV = $E45C ;set v.blank
XITVBV = $E462 ;exit v.blank
SIOINV = $E465 ;serial I/O init
;
; ----------------
; Shadow Registers
; ----------------
;
VDSLST = $0200 ;DLI vector
SDMCTL = $022F ;DMA control
SDLSTL = $0230 ;DList pointer
GPRIOR = $026F ;gr. priority
PADDL0 = $0270 ;paddle 0
PADDL1 = $0271 ;paddle 1
STICK0 = $0278 ;joystick 0
PTRIG0 = $027C ;paddle trig 0
PTRIG1 = $027D ;paddle trig 1
STRIG0 = $0284 ;stick trig 0
PCOLR0 = $02C0 ;player colors
COLOR0 = $02C4 ;playfield "
CH = $02FC ;keyboard char
;
; -------------------
; Page Zero Registers
; -------------------
;
*= $80 ;top of page 0
;
INDEX *= *+2 ;temp index
INDX1 *= *+2 ;temp index
INDX2 *= *+2 ;temp index
COUNT *= *+1 ;temp register
TEMP *= *+1 ;temp register
SATEMP *= *+1 ;temp register
SCNT *= *+1 ;orbit index
LO *= *+1 ;plot low byte
HI *= *+1 ;plot high byte
DEADTM *= *+1 ;death timer
EXPTIM *= *+1 ;explosion timer
BOMTIM *= *+1 ;bomb timer
SATPIX *= *+1 ;sat. pic cntr
CURX *= *+1 ;cursor x
CURY *= *+1 ;cursor y
FROMX *= *+1 ;vector from X
FROMY *= *+1 ;vector from Y
TOX *= *+1 ;vector to X
TOY *= *+1 ;vector to Y
SATX *= *+1 ;satellite x
SATY *= *+1 ;satellite y
XHOLD *= *+1 ;x reg hold area
LASTRG *= *+1 ;last trigger
LEVEL *= *+1 ;level number
BLEVEL *= *+1 ;binary level #
LIVES *= *+1 ;lives left
SCORE *= *+3 ;score digits
SCOADD *= *+3 ;score inc.
SHOBYT *= *+1 ;digit hold
SHCOLR *= *+1 ;digit color
SATLIV *= *+1 ;satellite flag
BOMVL *= *+1 ;bomb value low
BOMVH *= *+1 ;bomb value high
SAUVAL *= *+1 ;saucer value
GAMCTL *= *+1 ;game ctrl flag
DLICNT *= *+1 ;DLI counter
SAUCER *= *+1 ;saucer flag
SAUTIM *= *+1 ;image timer
SAUCHN *= *+1 ;saucer chance
BOMBWT *= *+1 ;bomb wait time
BOMCOL *= *+1 ;bomb collis flg
DEVICE *= *+1 ;koala pad sw
PLNCOL *= *+1 ;planet color
PAUSED *= *+1 ;pause flag
AVG *= *+2 ;average
PTR *= *+2 ;queue pointer
SSSCNT *= *+1 ;saucer snd cnt
EXSCNT *= *+1 ;expl. snd count
ESSCNT *= *+1 ;enemy shot snd
PSSCNT *= *+1 ;player shot snd
TITLE *= *+1 ;title scrn flag
PENFLG *= *+1 ;pen up/dwn flg
EXPCNT *= *+1 ;explosion counter
NEWX *= *+1 ;explosion x
NEWY *= *+1 ;explosion y
PLOTCLR *= *+1 ;plot/erase flag
COUNTR *= *+1 ;explosion index
PLOTX *= *+1 ;plot x coord
PLOTY *= *+1 ;plot y coord
HIHLD *= *+1 ;plot work area
LOHLD *= *+1 ;plot work area
BOMBS *= *+1 ;bombs to come
BOMTI *= *+1 ;bomb speeds
VXINC *= *+1 ;vector x hold
VYINC *= *+1 ;vector y hold
LR *= *+1 ;vector left/right hold
UD *= *+1 ;vector up/down hold
DELTAX *= *+1 ;vector work area
DELTAY *= *+1 ;vector work area
XQ *= *+5 ;x queue
YQ *= *+5 ;y queue
SL *= *+5 ;samples lo
SH *= *+5 ;samples hi
;
; ----------------------------
; Screen + Player/Missile Area
; ----------------------------
;
SCRN = $3000 ;screen area
PPOS = SCRN+1935 ;planet pos
;
PM = $00
MISL = PM+$0300 ;missiles
PLR0 = MISL+$0100 ;player 0
PLR1 = PLR0+$0100 ;player 1
PLR2 = PLR1+$0100 ;player 2
PLR3 = PLR2+$0100 ;player 3
;
ORBX = $1E00 ;orbit X
ORBY = $1F00 ;orbit Y
;
; -------------
; Start of game
; -------------
;
*= $2000
;
; ------------------
; Intro Display List
; ------------------
;
TLDL .BYTE $70,$70,$70,$70
.BYTE $70,$70,$70,$70
.BYTE $70,$46
.WORD MAGMSG
.BYTE $70,7,$70,6
.BYTE $10,6,$70,$70
.BYTE 6,$20,6,$40
.BYTE 6,$41
.WORD TLDL
;
; ------------------
; Intro Message Text
; ------------------
;
MAGMSG .SBYTE " ANALOG CO"
.SBYTE "MPUTING'S "
.SBYTE +$40," PLANETARY"
.SBYTE +$40," DEFENSE "
.SBYTE +$80," BY CHARLE"
.SBYTE +$80,"S BACHAND "
.SBYTE +$C0," AND TOM"
.SBYTE +$C0," HUDSON "
.SBYTE +$40," KOALA PAD"
.SBYTE +$40," - SELECT "
.SBYTE +$C0," JOYSTICK "
.SBYTE +$C0,"--- START "
.SBYTE " OR PRESS"
.SBYTE " TRIGGER "
;
; -----------------
; Game Display List
; -----------------
;
GLIST .BYTE $70,$70,$46
.WORD SCOLIN
.BYTE $4D
.WORD SCRN
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$8D
.BYTE $8D,$8D,$8D,$41
.WORD GLIST
;
; ------------------------
; Display the Intro Screen
; ------------------------
;
PLANET CLD ;clear decimal
LDA #$00 ;get zero
STA NMIEN ;display off
LDX #$7F ;set index
CLPG0 STA $80,X ;clr top page 0
DEX ;dec pointer
BNE CLPG0 ;done? No.
INC TITLE ;title on flag
LDA #$FF ;get $FF
STA LIVES ;set dead
STA GAMCTL ;game control
STA ESSCNT ;no enemy shots
STA PSSCNT ;no player shots
JSR SNDOFF ;no sound on 123
STA AUDC1+6 ;turn off snd 4
LDA #$C4 ;medium green
STA COLOR0 ;score color
LDA #$84 ;medium blue
STA COLOR0+1 ;text color
LDA #$0A ;bright white
STA COLOR0+2 ;shot color
LDA #$98 ;light blue
STA COLOR0+3 ;text color
LDA # <DLI ;set DLI vector
STA VDSLST ;low byte
LDA # >DLI ;set DLI vector
STA VDSLST+1 ;high byte
LDA #$C0 ;enable Display
STA NMIEN ;List Interrupts
LDA #$32 ;PM DMA off
STA DMACTL ;DMA control
STA SDMCTL ;and shadow reg
LDA #0 ;get zero
STA GRACTL ;graphics ctrl
STA AUDCTL ;reset audio
LDX #4 ;5 PM registers
NOPM STA GRAFP0,X ;clr register
DEX ;dec index
BPL NOPM ;done? No.
JSR SIOINV ;init sound
LDA # <TLDL ;DL addr low
STA SDLSTL ;DL pntr low
LDA # >TLDL ;DL addr high
STA SDLSTL+1 ;DL pntr high
LDX # >VBLANK ;vblank high
LDY # <VBLANK ;vblank low
LDA #7 ;deferred
JSR SETVBV ;set vblank
LDA #60 ;one second
STA DEADTM ;dead time
;
; --------------------------
; Check console and triggers
; --------------------------
;
START LDA DEADTM ;look dead time
BNE START ;alive? No.
CCHK LDA PTRIG0 ;paddle trig 0
EOR PTRIG1 ;mask w/PTRIG1
BNE PDEV ;pushed? Yes.
LDA STRIG0 ;stick trig
BEQ PDEV ;pushed? Yes.
LDA CONSOL ;get console
AND #3 ;do START/SELECT
CMP #3 ;test buttons
BEQ CCHK ;any pushed? No.
AND #1 ;mask off START
PDEV STA DEVICE ;device switch
RELWT LDA #10 ;1/6 second
STA DEADTM ;dead time
RELWT2 LDA DEADTM ;debounce!
BNE RELWT2 ;time up? No.
LDA CONSOL ;get console
CMP #7 ;keys released?
BNE RELWT ;No. loop until
;
; ---------------------------
; Clear PM Area and Playfield
; ---------------------------
;
LDA # >SCRN ;scrn addr high
STA INDEX+1 ;pointer high
LDA #0 ;get zero
STA INDEX ;pointer low
LDX #15 ;16 pages 0..15
TAY ;use as index
CL0 STA (INDEX),Y ;clear ram
INY ;next byte
BNE CL0 ;page done? No.
INC INDEX+1 ;next page
DEX ;page counter
BPL CL0 ;scrn done? No.
LDX #0 ;now clear P/m
CLPM STA MISL,X ;clear missiles
STA PLR0,X ;clear plyr 0
STA PLR1,X ;clear plyr 1
STA PLR2,X ;clear plyr 2
STA PLR3,X ;clear plyr 3
DEX ;done 256 bytes?
BNE CLPM ;no, loop back!
LDA # <GLIST ;Point to the
STA SDLSTL ;game display
LDA # >GLIST ;list to show
STA SDLSTL+1 ;the playfield.
LDA # >PM ;PM address high
STA PMBASE ;into hardware
LDA #$3E ;enable single
STA SDMCTL ;line resolution
STA DMACTL ;DMA control
LDA #3 ;enable player
STA GRACTL ;and missile DMA
LDA #$11 ;set up
STA GPRIOR ;P/M priority
LDA #0 ;get zero
STA TITLE ;title off
;
; ---------------
; Draw The Planet
; ---------------
;
LDA # <PPOS ;planet pos high
STA INDX1 ;pointer #1 low
STA INDX2 ;pointer #2 low
LDA # >PPOS ;planet pos high
STA INDX1+1 ;pointer #1 high
STA INDX2+1 ;pointer #2 high
LDX #0 ;table pointer
DP0 LDY #0 ;index pointer
DP1 LDA DPTBL,X ;table value
BNE DP2 ;done? No.
JMP SETUP ;continue
DP2 BMI DPRPT ;repeat? Yes.
STA (INDX1),Y ;put values
STA (INDX2),Y ;onto screen
INY ;inc index pntr
INX ;inc table pntr
JMP DP1 ;continue
;
; -------------------
; Repeat Byte Handler
; -------------------
;
DPRPT ASL A ;shift byte
STA TEMP ;new line flag
ASL A ;NL bit -> carry
ASL A ;color -> carry
LDA #$55 ;color 1 bits
BCS FILL1 ;color 1? Yes.
LDA #0 ;get background
FILL1 PHA ;save color byte
LDA DPTBL,X ;table value
AND #$0F ;mask 4 bits
STA COUNT ;save as count
PLA ;restore color
FILL2 STA (INDX1),Y ;put bytes
STA (INDX2),Y ;onto screen
INY ;inc index
DEC COUNT ;dec byte count
BNE FILL2 ;done? No.
INX ;inc table index
LDA TEMP ;get flag
BPL DP1 ;new line? No.
SEC ;set carry
LDA INDX1 ;Yes. get low
SBC #40 ;subtract 40
STA INDX1 ;new low
BCS DPN1 ;overflow? No.
DEC INDX1+1 ;decrement high
DPN1 CLC ;clear carry
LDA INDX2 ;get low
ADC #40 ;add 40
STA INDX2 ;new low
BCC DP0 ;overflow? No.
INC INDX2+1 ;increment high
JMP DP0 ;continue
;
; ----------------
; Planet Draw Data
; ----------------
;
DPTBL .BYTE $EA,$EA,$EA,$EA
.BYTE $EA,$15,$A8,$54
.BYTE $C1,$15,$A8,$54
.BYTE $C1,$05,$A8,$50
.BYTE $C1,$05,$A8,$50
.BYTE $C1,$01,$A8,$40
.BYTE $C1,$81,$E8,$81
.BYTE $15,$A6,$54,$C1
.BYTE $81,$05,$A6,$50
.BYTE $C1,$81,$01,$A6
.BYTE $40,$C1,$82,$E6
.BYTE $82,$05,$A4,$50
.BYTE $C1,$83,$E4,$84
.BYTE $E2,0
;
; -------------------------
; Setup Orbiter Coordinates
; -------------------------
;
SETUP LDX #64 ;do 65 bytes
LDY #0 ;quad 2/4 offset
SU1 CLC ;clear carry
LDA #96 ;center Y
ADC OYTBL,X ;add offset Y
STA ORBY+$40,Y ;quad-2 Y
STA ORBY+$80,X ;quad-3 Y
LDA #80 ;center X
ADC OXTBL,X ;add offset X
STA ORBX,X ;quad-1 X
STA ORBX+$40,Y ;quad-2 X
SEC ;set carry
LDA #80 ;center X
SBC OXTBL,X ;sub offset X
STA ORBX+$80,X ;quad-3 X
STA ORBX+$C0,Y ;quad-4 X
LDA #96 ;center Y
SBC OYTBL,X ;sub offset Y
STA ORBY,X ;quad-1 Y
STA ORBY+$C0,Y ;quad-4 Y
INY ;quad 2/4 offset
DEX ;quad 1/3 offset
BPL SU1 ;done? No.
JMP INIT ;continue
;
; ---------------------------
; Orbiter X,Y Coordinate Data
; ---------------------------
;
OXTBL .BYTE 0,1,2,2,3
.BYTE 4,5,5,6,7
.BYTE 8,9,9,10,11
.BYTE 12,12,13,14,14
.BYTE 15,16,16,17,18
.BYTE 18,19,20,20,21
.BYTE 21,22,23,23,24
.BYTE 24,25,25,26,26
.BYTE 27,27,27,28,28
.BYTE 29,29,29,30,30
.BYTE 30,30,31,31,31
.BYTE 31,31,32,32,32
.BYTE 32,32,32,32,32
;
OYTBL .BYTE 54,54,54,54,54
.BYTE 54,54,54,53,53
.BYTE 53,52,52,52,51
.BYTE 51,50,50,49,49
.BYTE 48,47,47,46,45
.BYTE 44,44,43,42,41
.BYTE 40,39,38,38,37
.BYTE 36,35,33,32,31
.BYTE 30,29,28,27,26
.BYTE 24,23,22,21,20
.BYTE 18,17,16,15,13
.BYTE 12,11,9,8,7
.BYTE 5,4,3,1,0
;
; ----------------------
; Display list interrupt
; ----------------------
;
DLI PHA ;save Acc
TXA ;X --> Acc
PHA ;save X register
INC DLICNT ;inc counter
LDA DLICNT ;get counter
AND #$07 ;only 3 bits
TAX ;use as index
LDA DLIBRT,X ;planet bright
ORA PLNCOL ;planet color
STA WSYNC ;start of scan
STA COLPF0 ;color planet
LDA #$8C ;bright blue
STA COLPF0+1 ;shot color
PLA ;restore X
TAX ;Acc --> X
PLA ;restore Acc
RTI ;return
;
DLIBRT .BYTE 0,2,4,6 ;planet
.BYTE 8,6,4,2 ;brightness
;
; ----------------------
; Vertical blank routine
; ----------------------
;
VBLANK CLD ;clear decimal
LDX SAUCER ;saucer flag as
LDA P3COLR,X ;index 0 or 1
STA PCOLR0+3 ;saucer color
LDA #5 ;get 5
STA DLICNT ;reset DLI count
LDA #$C0 ;enable
STA NMIEN ;DLI's
LDA CH ;keyboard char
CMP #$21 ;space bar?
BNE PCHK ;No. skip it
LDA PAUSED ;pause flag
EOR #$FF ;invert it
STA PAUSED ;save pause flag
LDA #$FF ;get $FF
STA CH ;reset keyboard
PCHK LDA PAUSED ;pause flag
BEQ NOPAU ;paused? No.
LDA #0 ;get zero
LDX #7 ;do 8 bytes
NOSND STA AUDF1,X ;zero sound
DEX ;dec index
BPL NOSND ;done? No.
JMP XITVBV ;exit VBLANK
NOPAU LDA TITLE ;title flag
BNE NOCYC ;title? Yes.
LDA COLOR0+2 ;No. get color
CLC ;clear carry
ADC #$10 ;next color
STA COLOR0+2 ;explosion col.
NOCYC LDA EXSCNT ;explosion cnt
BEQ NOPAU2 ;any? No.
LSR A ;count/2
LSR A ;count/4
STA AUDC1+6 ;explo volume
LDA #40 ;explosion
STA AUDF1+6 ;explo frequency
DEC EXSCNT ;dec count
NOPAU2 LDA GAMCTL ;game control
BPL CURSOR ;cursor? Yes.
JMP TIMERS ;No. skip
;
; --------------
; Cursor handler
; --------------
;
CURSOR LDY CURY ;get y pos
LDX #5 ;clear 6 bytes
ERACUR LDA #$0F ;now clear out
AND MISL-3,Y ;old cursor
STA MISL-3,Y ;graphics,
INY ;next Y position
DEX ;dec count
BPL ERACUR ;loop until done
LDA STICK0 ;read joystick
LDX CURX ;get X value
LDY CURY ;get Y value
LSR A ;shift right
BCS NOTN ;North? No.
DEY ;move cursor up
DEY ;two scan lines
NOTN LSR A ;shift right
BCS NOTS ;South? No.
INY ;cursor down
INY ;two scan lines
NOTS LSR A ;shift right
BCS NOTW ;West? No.
DEX ;cursor left
NOTW LSR A ;shift right
BCS NOTE ;East? No.
INX ;cursor right
NOTE CPX #48 ;too far left?
BCC BADX ;Yes. skip next
CPX #208 ;too far right?
BCS BADX ;Yes. skip next
STX CURX ;No. it's ok!
BADX CPY #32 ;too far up?
BCC BADY ;Yes. skip next
CPY #224 ;too far down?
BCS BADY ;Yes. skip next
STY CURY ;No. it's ok!
BADY LDA DEVICE ;KOALA switch
BEQ NKOALA ;KOALA PAD?
JSR KOALA ;Yes. do it
NKOALA LDA PENFLG ;koala pen flg
BNE TIMERS ;pen up? Yes.
LDX #5 ;6 bytes...
LDY CURY ;get cursor Y
SHOCUR LDA CURPIC,X ;cursor pic
ORA MISL-3,Y ;mask missiles
STA MISL-3,Y ;store missiles
INY ;next scan line
DEX ;dec count
BPL SHOCUR ;done? No.
LDX CURX ;get x position,
DEX ;1 less for...
STX HPOSM0+3 ;missile 3
INX ;2 more for...
INX ;missile 2
STX HPOSM0+2 ;save position
;
; -----------------------
; Handle timers and orbit
; -----------------------
;
TIMERS LDA BOMBWT ;bomb wait cnt
BEQ NOBWT ;wait over? Yes.
DEC BOMBWT ;dec count
NOBWT LDA DEADTM ;death timer
BEQ NOTIM0 ;zero? yes.
DEC DEADTM ;decrement it!
NOTIM0 LDA EXPTIM ;exp timer
BEQ NOTIM1 ;zero? Yes.
DEC EXPTIM ;decrement it!
NOTIM1 LDA BOMTIM ;get bomb time
BEQ NOTIM2 ;zero? Yes.
DEC BOMTIM ;dec bomb time
NOTIM2 LDA GAMCTL ;game control
BPL NOTOVR ;game over? No.
JMP XITVBV ;exit VBLANK
NOTOVR LDA SATLIV ;get satellite
BEQ NOSAT ;alive? No.
INC SCNT ;inc count
LDY SCNT ;orbit index
CLC ;clear carry
LDA ORBX,Y ;get X coord
STA SATX ;save Pfield x
ADC #47 ;X offset
STA HPOSM0+1 ;horizontal pos
ADC #2 ;+2 offset for
STA HPOSM0 ;right side
LDA ORBY,Y ;get Y coord
LSR A ;divide by 2
STA SATY ;for playfield
ROL A ;restore for PM
ADC #36 ;screen offset
TAX ;use as index
INC SATPIX ;next sat. image
LDA SATPIX ;get number
AND #$08 ;use bit 3
TAY ;use as index
LDA #8 ;do 8 bytes
STA SATEMP ;save count
SSAT LDA MISL,X ;missile graphic
AND #$F0 ;mask off 1,2
ORA SATSH,Y ;add sat shape
STA MISL,X ;put player #1
DEX ;dec position
INY ;dec index
DEC SATEMP ;dec count
BNE SSAT ;done? No.
NOSAT LDA SAUCER ;saucer flag
BEQ SOUNDS ;saucer? No.
LDY BOMBY+3 ;saucer Y pos
DEY ;-1
DEY ;-2
LDX #9 ;10 scan lines
SSAULP CPY #32 ;above top?
BCC NXTSP ;Yes. skip it
CPY #223 ;below bottom?
BCS NXTSP ;Yes. skip it
LDA SAUPIC,X ;saucer image
STA PLR3,Y ;store player 3
NXTSP DEY ;next scan line
DEX ;dec index
BPL SSAULP ;done? No.
LDA BOMBX+3 ;saucer X pos
STA HPOSP0+3 ;move it
INC SAUTIM ;saucer time
LDA SAUTIM ;get counter
LSR A ;/2
AND #$03 ;use only 0..3
TAX ;as X index
LDA SAUMID,X ;saucer middle
STA SAUPIC+4 ;put in
STA SAUPIC+5 ;saucer image
SOUNDS LDX PSSCNT ;shot sound
BPL DOS1 ;shot? Yes.
LDA #0 ;No. get zero
STA AUDC1 ;volume for shot
BEQ TRYS2 ;skip next
DOS1 LDA #$A6 ;shot sound vol
STA AUDC1 ;set hardware
LDA PLSHOT,X ;shot sound
STA AUDF1 ;frequency
DEC PSSCNT ;dec shot snd
TRYS2 LDX ESSCNT ;enemy shots
BPL DOS2 ;shots? Yes.
LDA #0 ;No. get zero
STA AUDC1+2 ;into volume
BEQ TRYS3 ;skip rest
DOS2 LDA #$A6 ;shot sound vol
STA AUDC1+2 ;set hardware
LDA ENSHOT,X ;shot sound
STA AUDF1+2 ;frequency
DEC ESSCNT ;dec shot snd
TRYS3 LDA SAUCER ;saucer flag
BEQ NOS3 ;saucer? No.
LDA BOMBY+3 ;saucer Y pos
CMP #36 ;above top?
BCC NOS3 ;Yes. skip
CMP #231 ;below bottom?
BCC DOS3 ;No. make sound
NOS3 LDA #0 ;get zero
STA AUDC1+4 ;no saucer snd
BEQ VBDONE ;skip next
DOS3 INC SSSCNT ;inc saucer cnt
LDX SSSCNT ;saucer count
CPX #12 ;at limit?
BMI SETS3 ;No. skip next
LDX #0 ;get zero
STX SSSCNT ;zero saucer cnt
SETS3 LDA #$A8 ;saucer volume
STA AUDC1+4 ;set hardware
LDA SAUSND,X ;saucer sound
STA AUDF1+4 ;set hardware
VBDONE JMP XITVBV ;continue
;
; ---------------------
; Satellite shape table
; ---------------------
;
SATSH .BYTE 0,0,0,$0A
.BYTE $04,$0A,0,0
.BYTE 0,0,0,$04
.BYTE $0A,$04,0,0
;
;
; File: D:PLANET2.M65
;
; ----------------
; Initialize Misc.
; ----------------
;
INIT LDA #0 ;zero out..
STA SCORE ;score byte 0
STA SCORE+1 ;score byte 1
STA SCORE+2 ;score byte 2
STA DEADTM ;dead timer
STA PAUSED ;pause flag
STA EXPCNT ;expl. counter
STA SAUCER ;no saucer
STA BLEVEL ;bomb level
LDX #11 ;no bombs!
CLRACT STA BOMACT,X ;deactivate
DEX ;next bomb
BPL CLRACT ;done? No.
LDX #19 ;zero score line
INISLN LDA SCOINI,X ;get byte
STA SCOLIN,X ;put score line
DEX ;next byte
BPL INISLN ;done? No.
LDA #$01 ;get one
STA LEVEL ;game level
STA SATLIV ;live satellite
LDA #4 ;get 4
STA LIVES ;number of lives
LDA #$0C ;set explosion
STA COLOR0+2 ;brightness
LDA #$34 ;medium red
STA PCOLR0 ;bomb 0 color
STA PCOLR0+1 ;bomb 1 color
STA PCOLR0+2 ;bomb 2 color
LDA #127 ;center screen X
STA CURX ;cursor X pos
LDA #129 ;center screen Y
STA CURY ;cursor Y pos
LDA #1 ;get one
STA GAMCTL ;game control
JSR SHOSCO ;display score
LDA #$54 ;graphic-LF of
STA SCRN+1939 ;planet center
LDA #$15 ;graphic-RT of
STA SCRN+1940 ;planet center
STA HITCLR ;reset collision
;
; ----------------------
; Set up level variables
; ----------------------
;
SETLVL JSR SHOLVL ;show level
LDX BLEVEL ;bomb level
LDA INIBOM,X ;bombs / level
STA BOMBS ;bomb count
LDA INIBS,X ;bomb speed
STA BOMTI ;bomb timer
LDA INISC,X ;% chance of
STA SAUCHN ;saucer in level
LDA INIPC,X ;planet color
CMP #$FF ;level >14?
BNE SAVEPC ;No. skip next
LDA RANDOM ;random color
AND #$F0 ;mask off lum.
SAVEPC STA PLNCOL ;planet color
LDA INIBVL,X ;bomb value low
STA BOMVL ;save it
LDA INIBVH,X ;bomb value hi
STA BOMVH ;save it
LDA INISV,X ;saucer value
STA SAUVAL ;save that too
CPX #11 ;at level 11?
BEQ SAMLVL ;Yes. skip next
INC BLEVEL ;inc bomb level
SAMLVL SED ;decimal mode
LDA LEVEL ;game level #
CLC ;clear carry
ADC #1 ;add one
STA LEVEL ;save game level
CLD ;clear decimal
;
; -----------------
; Main program loop
; -----------------
;
LOOP LDA PAUSED ;game paused?
BNE LOOP ;Yes. loop here
LDA #0 ;get zero
STA ATRACT ;attract mode
LDA GAMCTL ;game done?
BPL CKCORE ;No. check core
LDA EXPCNT ;Yes. expl count
BNE CKCORE ;count done? No.
JMP ENDGAM ;The End!
;
; --------------------------
; Check planet core for hit!
; --------------------------
;
CKCORE LDA SCRN+1939 ;center LF
AND #$03 ;RT color clock
CMP #$03 ;explosion colr?
BEQ PLDEAD ;Yes. go dead
LDA SCRN+1940 ;center RT
AND #$C0 ;LF color clock
CMP #$C0 ;explosion colr?
BNE PLANOK ;No. skip next
;
; ---------------
; Planet is Dead!
; ---------------
;
PLDEAD LDA #0 ;get zero
STA BOMBS ;zero bombs
STA SATLIV ;satelite dead
LDA #$FF ;get #$FF
STA LIVES ;no lives left
STA GAMCTL ;game control
JSR SNDOFF ;no sound
;
; -------------
; Check console
; -------------
;
PLANOK LDA CONSOL ;get console
CMP #7 ;any pressed?
BEQ NORST ;No. skip next
JMP PLANET ;restart game!
;
; -----------------
; Projectile firing
; -----------------
;
NORST JSR BOMINI ;try new bomb
LDA SATLIV ;satellite stat
BEQ NOTRIG ;alive? No.
LDA STRIG0 ;get trigger
CMP LASTRG ;same as last VB
BEQ NOTRIG ;Yes. skip next
STA LASTRG ;No. save trig
CMP #0 ;pressed?
BNE NOTRIG ;No. skip next
JSR PROINI ;strt projectile
NOTRIG JSR BOMADV ;advance bombs
LDA EXPTIM ;do explosion?
BNE NOEXP ;no!
JSR CHKSAT ;satellite ok?
JSR CHKHIT ;any hits?
JSR EXPHAN ;handle expl.
JSR PROADV ;advance shots
LDA SAUCER ;saucer flag
BEQ RESTIM ;saucer? No.
JSR SSHOOT ;Yes. let shoot
RESTIM LDA #1 ;get one
STA EXPTIM ;reset timer
NOEXP LDA BOMBS ;# bombs to go
BNE LOOP ;any left? Yes.
LDA GAMCTL ;game control
BMI LOOP ;dead? Yes.
LDA BOMACT ;bomb 0 status
ORA BOMACT+1 ;bomb 1 status
ORA BOMACT+2 ;bomb 2 status
ORA BOMACT+3 ;bomb 3 status
BEQ JSL ;any bombs? No.
JMP LOOP ;Yes. continue
JSL JMP SETLVL ;setup new level
;
; ------------------------
; Initiate a new explosion
; ------------------------
;
NEWEXP LDA #64 ;1.07 seconds
STA EXSCNT ;expl sound cnt
INC EXPCNT ;one more expl
LDY EXPCNT ;use as index
LDA NEWX ;put X coord
STA XPOS,Y ;into X table
LDA NEWY ;put Y coord
STA YPOS,Y ;into Y table
LDA #0 ;init to zero
STA CNT,Y ;explosion image
RT1 RTS ;return
;
; ------------------------------
; Main explosion handler routine
; ------------------------------
;
EXPHAN LDA #0 ;init to zero
STA COUNTR ;zero counter
RUNLP INC COUNTR ;nxt explosion
LDA EXPCNT ;get explosion #
CMP COUNTR ;any more expl?
BMI RT1 ;No. return
LDX COUNTR ;get index
LDA #0 ;init plotclr
STA PLOTCLR ;0 = plot block
LDA CNT,X ;expl counter
CMP #37 ;all drawn?
BMI DOPLOT ;No. do it
INC PLOTCLR ;1 = erase block
SEC ;set carry
SBC #37 ;erase cycle
CMP #37 ;erase done?
BMI DOPLOT ;No. erase block
TXA ;move index
TAY ;to Y register
;
; ---------------------------
; Repack explosion table, get
; rid of finished explosions
; ---------------------------
;
REPACK INX ;next explosion
CPX EXPCNT ;done?
BEQ RPK2 ;No. repack more
BPL RPKEND ;Yes. exit
RPK2 LDA XPOS,X ;get X position
STA XPOS,Y ;move back X
LDA YPOS,X ;get Y position
STA YPOS,Y ;move back Y
LDA CNT,X ;get count
STA CNT,Y ;move back count
INY ;inc index
BNE REPACK ;next repack
RPKEND DEC EXPCNT ;dec pointers
DEC COUNTR ;due to repack
JMP RUNLP ;continue
DOPLOT INC CNT,X ;inc pointer
TAY ;exp phase in Y
LDA XPOS,X ;get X-coord
CLC ;clear carry
ADC COORD1,Y ;add X offset
STA PLOTX ;save it
CMP #160 ;off screen?
BCS RUNLP ;Yes. don't plot
LDA YPOS,X ;get Y-coord
ADC COORD2,Y ;add Y offset
STA PLOTY ;save it
CMP #96 ;off screen?
BCS RUNLP ;Yes. don't plot
JSR PLOT ;get plot addr
LDA PLOTCLR ;erase it?
BNE CLEARIT ;Yes. clear it
LDA PLOTBL,X ;get plot bits
ORA (LO),Y ;alter display
PUTIT STA (LO),Y ;and replot it!
JMP RUNLP ;exit
CLEARIT LDA ERABIT,X ;erase bits
AND (LO),Y ;turn off pixel
JMP PUTIT ;put it back
;
; ------------------------
; Dedicated multiply by 40
; with result in LO and HI
; ------------------------
;
PLOT LDA PLOTY ;get Y-coord
ASL A ;shift it left
STA LO ;save low *2
LDA #0 ;get zero
STA HI ;init high byte
ASL LO ;shift low byte
ROL HI ;rotate high *4
ASL LO ;shift low byte
LDA LO ;get low byte
STA LOHLD ;save low *8
ROL HI ;rotate high *8
LDA HI ;get high byte
STA HIHLD ;save high *8
ASL LO ;shift low byte
ROL HI ;rotate high *16
ASL LO ;shift low byte
ROL HI ;rotate high *32
LDA LO ;get low *32
CLC ;clear carry
ADC LOHLD ;add low *8
STA LO ;save low *40
LDA HI ;get high *32
ADC HIHLD ;add high *8
STA HI ;save high *40
;
; -----------------------------
; Get offset into screen memory
; -----------------------------
;
LDA # <SCRN ;screen addr lo
CLC ;clear carry
ADC LO ;add low offset
STA LO ;save addr low
LDA # >SCRN ;screen addr hi
ADC HI ;add high offset
STA HI ;save addr hi
LDA PLOTX ;mask PLOTX for
AND #3 ;the plot bits,
TAX ;place in X..
LDA PLOTX ;get PLOTX and
LSR A ;divide
LSR A ;by 4
CLC ;and add to
ADC LO ;plot address
STA LO ;for final plot
BCC PLOT1 ;address.
INC HI ;overflow? Yes.
PLOT1 LDY #0 ;zero Y register
RTS ;return
;
; ----------------
; Bomb initializer
; ----------------
;
BOMINI LDA BOMBWT ;bomb wait time
BNE NOBINI ;done? No.
LDA BOMBS ;more bombs?
BNE CKLIVE ;Yes. skip RTS
NOBINI RTS ;No. return
CKLIVE LDX #3 ;find..
CKLVLP LDA BOMACT,X ;an available..
BEQ GOTBOM ;bomb? Yes.
DEX ;No. dec index
BPL CKLVLP ;done? No.
RTS ;return
GOTBOM LDA #1 ;this one is..
STA BOMACT,X ;active now
DEC BOMBS ;one less bomb
LDA #0 ;zero out all..
STA BXHOLD,X ;vector X hold
STA BYHOLD,X ;vector Y hold
LDA GAMCTL ;game control
BMI NOSAUC ;saucer possible?
;
; --------------
; Saucer handler
; --------------
;
CPX #3 ;Yes. bomb #3?
BNE NOSAUC ;No. skip next
LDA RANDOM ;random number
CMP SAUCHN ;compare chances
BCS NOSAUC ;put saucer? No.
LDA #1 ;Yes. get one
STA SAUCER ;enable saucer
LDA RANDOM ;random number
AND #$03 ;range: 0..3
TAY ;use as index
LDA STARTX,Y ;saucer start X
CMP #$FF ;random flag?
BNE SAVESX ;No. use as X
JSR SAURND ;random X-coord
ADC #35 ;add X offset
SAVESX STA FROMX ;from X vector
STA BOMBX,X ;init X-coord
LDA STARTY,Y ;saucer start Y
CMP #$FF ;random flag?
BNE SAVESY ;No. use as Y
JSR SAURND ;random Y-coord
ADC #55 ;add Y offset
SAVESY STA FROMY ;from Y vector
STA BOMBY,X ;init Y-coord
LDA ENDX,Y ;saucer end X
CMP #$FF ;random flag?
BNE SAVEEX ;No. use as X
LDA #230 ;screen right
SEC ;offset so not
SBC FROMY ;to hit planet
SAVEEX STA TOX ;to X vector
LDA ENDY,Y ;saucer end Y
CMP #$FF ;random flag?
BNE SAVEEY ;No. use as Y
LDA FROMX ;use X for Y
SAVEEY STA TOY ;to Y vector
JMP GETBV ;skip next
;
; ------------
; Bomb handler
; ------------
;
NOSAUC LDA RANDOM ;random number
BMI BXMAX ;coin flip
LDA RANDOM ;random number
AND #1 ;make 0..1
TAY ;use as index
LDA BMAXS,Y ;top/bottom tbl
STA BOMBY,X ;bomb Y-coord
SETRBX LDA RANDOM ;random number
CMP #250 ;compare w/250
BCS SETRBX ;less than? No.
STA BOMBX,X ;bomb X-coord
JMP BOMVEC ;skip next
BXMAX LDA RANDOM ;random number
AND #1 ;make 0..1
TAY ;use as index
LDA BMAXS,Y ;0 or 250
STA BOMBX,X ;bomb X-coord
SETRBY LDA RANDOM ;random number
CMP #250 ;compare w/250
BCS SETRBY ;less than? No.
STA BOMBY,X ;bomb Y-coord
BOMVEC LDA BOMBX,X ;bomb X-coord
STA FROMX ;shot from X
LDA BOMBY,X ;bomb Y-coord
STA FROMY ;shot from Y
LDA #128 ;planet center
STA TOX ;shot to X-coord
STA TOY ;shot to Y-coord
GETBV JSR VECTOR ;calc shot vect
;
; ---------------------
; Store vector in table
; ---------------------
;
LDA LR ;bomb L/R flag
STA BOMBLR,X ;bomb L/R table
LDA UD ;bomb U/D flag
STA BOMBUD,X ;bomb U/D table
LDA VXINC ;velocity X inc
STA BXINC,X ;Vel X table
LDA VYINC ;velocity Y inc
STA BYINC,X ;Vel Y table
RTS ;return
;
; -----------------------------
; Saucer random generator 0..99
; -----------------------------
;
SAURND LDA RANDOM ;random number
AND #$7F ;0..127
CMP #100 ;compare w/100
BCS SAURND ;less than? No.
RTS ;return
;
; --------------------
; Saucer shoot routine
; --------------------
;
SSHOOT LDA RANDOM ;random number
CMP #6 ;2.3% chance?
BCS NOSS ;less than? No.
LDX #7 ;7 = index
LDA PROACT,X ;projectile #7
BEQ GOTSS ;active? No.
DEX ;6 = index
LDA PROACT,X ;projectile #6
BEQ GOTSS ;active? No.
NOSS RTS ;return, no shot
;
; --------------------
; Enable a saucer shot
; --------------------
;
GOTSS LDA #48 ;PF center, Y
STA TOY ;shot to Y-coord
LDA #80 ;PF center X
STA TOX ;shot to X-coord
LDA BOMBX+3 ;saucer x-coord
SEC ;set carry
SBC #44 ;PF offset
STA FROMX ;shot from X
STA PROJX,X ;X-coord table
CMP #160 ;screen X limit
BCS NOSS ;on screen? No.
LDA BOMBY+3 ;saucer Y-coord
SBC #37 ;PF offset
LSR A ;2 scan lines
STA FROMY ;shot from Y
STA PROJY,X ;Y-coord table
CMP #95 ;screen Y limit
BCS NOSS ;on screen? No.
LDA #13 ;shot snd time
STA ESSCNT ;emeny snd count
JMP PROVEC ;continue
;
; ----------------------
; Projectile initializer
; ----------------------
;
PROINI LDX #5 ;6 projectiles
PSCAN LDA PROACT,X ;get status
BEQ GOTPRO ;active? No.
DEX ;Yes. try again
BPL PSCAN ;done? No.
RTS ;return
;
; -----------------
; Got a projectile!
; -----------------
;
GOTPRO LDA #13 ;shot snd time
STA PSSCNT ;player sht snd
LDA SATX ;satellite X
STA FROMX ;shot from X
STA PROJX,X ;proj X table
LDA SATY ;satellite Y
STA FROMY ;shot from Y
STA PROJY,X ;proj Y table
LDA CURX ;cursor X-coord
SEC ;set carry
SBC #48 ;playfld offset
STA TOX ;shot to X-coord
LDA CURY ;cursor Y-coord
SEC ;set carry
SBC #32 ;playfld offset
LSR A ;2 line res
STA TOY ;shot to Y-coord
PROVEC JSR VECTOR ;compute vect
LDA VXINC ;X increment
STA PXINC,X ;X inc table
LDA VYINC ;Y increment
STA PYINC,X ;Y inc table
LDA LR ;L/R flag
STA PROJLR,X ;L/R flag table
LDA UD ;U/D flag
STA PROJUD,X ;U/D flag table
LDA #1 ;active
STA PROACT,X ;proj status
RT2 RTS ;return
;
; --------------------
; Bomb advance handler
; --------------------
;
BOMADV LDA BOMTIM ;bomb timer
BNE RT2 ;time up? No.
LDA LIVES ;any lives?
BPL REGBT ;Yes. skip next
LDA #1 ;speed up bombs
BNE SETBTM ;skip next
REGBT LDA BOMTI ;get bomb speed
SETBTM STA BOMTIM ;reset timer
LDX #3 ;check 4 bombs
ADVBLP LDA BOMACT,X ;bomb on?
BEQ NXTBOM ;No. try next
JSR ADVIT ;advance bomb
LDA LIVES ;any lives left?
BPL SHOBOM ;Yes. skip next
JSR ADVIT ;No. move bombs
JSR ADVIT ;4 times faster
JSR ADVIT ;than normal
;
; --------------------------
; We've now got updated bomb
; coordinates for plotting!
; --------------------------
;
SHOBOM LDA BOMBY,X ;bomb Y-coord
CLC ;clear carry
ADC #2 ;bomb center off
STA INDX1 ;save it
LDA #0 ;get zero
STA LO ;init low byte
TXA ;index to Acc
ORA # >PLR0 ;mask w/address
STA HI ;init high byte
STX INDX2 ;X temp hold
CPX #3 ;saucer slot?
BNE NOTSAU ;No. skip next
LDA SAUCER ;saucer in slot?
BNE NXTBOM ;Yes. skip bomb
NOTSAU LDY BOMBLR,X ;L/R flag
LDA #17 ;do 17 bytes
STA TEMP ;set counter
LDX BPSTRT,Y ;start position
LDY INDX1 ;bomb Y pos
BDRAW CPY #32 ;off screen top?
BCC NOBDRW ;Yes. skip next
CPY #223 ;screen bottom?
BCS NOBDRW ;Yes. skip next
LDA BOMPIC,X ;bomb picture
STA (LO),Y ;put in PM area
NOBDRW DEY ;PM index
DEX ;picture index
DEC TEMP ;dec count
BNE BDRAW ;done? No.
LDX INDX2 ;restore X
LDA BOMBX,X ;bomb X-coord
STA HPOSP0,X ;player pos
NXTBOM DEX ;more bombs?
BPL ADVBLP ;yes!
RTS ;all done!
;
; --------------------------
; Projectile advance handler
; --------------------------
;
PROADV LDX #11 ;do 8: 11..4
PADVLP LDA BOMACT,X ;active?
BEQ NXTPRO ;No. skip next
LDA BOMBX,X ;bomb X-coord
STA PLOTX ;plotter X
LDA BOMBY,X ;bomb Y-coord
STA PLOTY ;plotter Y
STX XHOLD ;X-reg temporary
JSR PLOT ;calc plot addr
LDA (LO),Y ;get plot byte
AND ERABIT,X ;erase bit
STA (LO),Y ;replace byte
LDX XHOLD ;restore X
JSR ADVIT ;advance proj
LDA BOMBX,X ;bomb X-coord
CMP #160 ;off screen?
BCS KILPRO ;Yes. kill it
STA PLOTX ;plotter X
LDA BOMBY,X ;bomb Y-coord
CMP #96 ;off screen?
BCS KILPRO ;Yes. kill it
STA PLOTY ;plotter Y
JSR PLOT ;calc plot addr
LDA PLOTBL,X ;get plot mask
AND (LO),Y ;chk collision
BEQ PROJOK ;No. plot it
LDX XHOLD ;restore X
LDA PLOTX ;proj X-coord
STA NEWX ;explo X-coord
LDA PLOTY ;proj Y-coord
STA NEWY ;explo Y-coord
JSR NEWEXP ;set off explo
KILPRO LDA #0 ;get zero
STA BOMACT,X ;kill proj
JMP NXTPRO ;skip next
PROJOK LDA PLOTBL,X ;plot mask
LDX XHOLD ;restore X
AND PROMSK,X ;mask color
ORA (LO),Y ;add playfield
STA (LO),Y ;replace byte
NXTPRO DEX ;next projectile
CPX #3 ;proj #3 yet?
BNE PADVLP ;No. continue
RTS ;return
;
;
; File: D:PLANET3.M65
;
; ----------------------
; Check satellite status
; ----------------------
;
CHKSAT LDA DEADTM ;satellite ok?
BEQ LIVE ;No. skip next
CHKSX RTS ;return
LIVE LDA LIVES ;lives left?
BMI CHKSX ;No. exit
LDA #1 ;get one
STA SATLIV ;set alive flag
LDA M0PL ;did satellite
ORA M0PL+1 ;hit any bombs?
BEQ CHKSX ;No. exit
LDA #0 ;get zero
STA SATLIV ;kill satellite
STA SCNT ;init orbit
LDX LIVES ;one less life
STA SCOLIN+14,X ;erase life
DEC LIVES ;dec lives count
BPL MORSAT ;any left? Yes.
LDA #255 ;lot of bombs
STA BOMBS ;into bomb count
STA GAMCTL ;end game
JSR SNDOFF ;no sound 1 2 3
MORSAT LDA SATX ;sat X-coord
STA NEWX ;explo X-coord
LDA SATY ;sat Y-coord
STA NEWY ;explo Y-coord
JSR NEWEXP ;set off explo
LDA #80 ;init sat X
STA SATX ;sat X-coord
LDA #21 ;init sat Y
STA SATY ;sat Y-coord
LDX #0 ;don't show the
CLRSAT LDA MISL,X ;satellite pic
AND #$F0 ;mask off sat
STA MISL,X ;restore data
DEX ;dec index
BNE CLRSAT ;done? No.
LDA #$FF ;4.25 seconds
STA DEADTM ;till next life!
RTS ;return
;
; ------------------
; Check console keys
; ------------------
;
ENDGAM JSR SNDOFF ;no sound 123
ENDGLP LDA STRIG0 ;stick trigger
AND PTRIG0 ;mask w/paddle 0
AND PTRIG1 ;mask w/paddle 1
BEQ ENDGL1 ;any pushed? No.
LDA CONSOL ;chk console
CMP #7 ;any pushed?
BEQ ENDGLP ;No. loop here
ENDGL1 JMP PLANET ;restart game
;
; -------------------------
; Turn off sound regs 1 2 3
; -------------------------
;
SNDOFF LDA #0 ;zero volume
STA AUDC1 ;to sound #1
STA AUDC1+2 ;sound #2
STA AUDC1+4 ;sound #3
RTS ;return
;
; -----------------------
; Check for hits on bombs
; -----------------------
;
CHKHIT LDX #3 ;4 bombs 0..3
LDA SAUCER ;saucer enabled?
BEQ CHLOOP ;No. skip next
LDA #0 ;get zero
STA BOMCOL ;collision count
LDA GAMCTL ;game over?
BMI NOSCOR ;Yes. skip next
LDA BOMBX+3 ;saucer X-coord
CMP #39 ;off screen lf?
BCC NOSCOR ;Yes. kill it
CMP #211 ;off screen rt?
BCS NOSCOR ;Yes. kill it
LDA BOMBY+3 ;saucer Y-coord
CMP #19 ;off screen up?
BCC NOSCOR ;Yes. kill it
CMP #231 ;off screen dn?
BCS NOSCOR ;Yes. kill it
CHLOOP LDA #0 ;get zero
STA BOMCOL ;collision count
LDA P0PF,X ;playf collision
AND #$05 ;w/shot+planet
BEQ NOBHIT ;hit either? No.
INC BOMCOL ;Yes. inc count
AND #$04 ;hit shot?
BEQ NOSCOR ;No. skip next
LDA GAMCTL ;game over?
BMI NOSCOR ;Yes. skip next
LDA #2 ;1/30th second
STA BOMBWT ;bomb wait time
CPX #3 ;saucer player?
BNE ADDBS ;No. skip this
LDA SAUCER ;saucer on?
BEQ ADDBS ;No. this this
LDA SAUVAL ;saucer value
STA SCOADD+1 ;point value
JMP ADDIT ;add to score
;
; -----------------------
; Add bomb value to score
; -----------------------
;
ADDBS LDA BOMVL ;bomb value low
STA SCOADD+2 ;score inc low
LDA BOMVH ;bomb value high
STA SCOADD+1 ;score inc high
ADDIT STX XHOLD ;save X register
JSR ADDSCO ;add to score
LDX XHOLD ;restore X
NOSCOR LDA #0 ;get zero
STA BOMACT,X ;kill bomb
LDY BOMBLR,X ;L/R flag
LDA BOMBX,X ;bomb X-coord
SEC ;set carry
SBC BXOF,Y ;bomb X offset
STA NEWX ;plotter X-coord
LDA BOMBY,X ;bomb Y-coord
SEC ;set carry
SBC #40 ;bomb Y offset
LSR A ;2 line res.
STA NEWY ;plotter Y-coord
LDA SAUCER ;saucer?
BEQ EXPBOM ;No. explode it
CPX #3 ;bomb player?
BNE EXPBOM ;Yes. explode it
LDA #0 ;get zero
STA SAUCER ;kill saucer
JSR CLRPLR ;clear player
LDA GAMCTL ;game over?
BMI NOBHIT ;Yes. skip next
EXPBOM JSR CLRPLR ;clear player
LDA BOMCOL ;collisions?
BEQ NOBHIT ;No. skip this
JSR NEWEXP ;init explosion
NOBHIT DEX ;dec index
BPL CHLOOP ;done? No.
STA HITCLR ;reset collision
RTS ;return
;
; -------------------------
; Advance bombs/projectiles
; -------------------------
;
ADVIT LDA BXHOLD,X ;bomb X-sum
CLC ;clear carry
ADC BXINC,X ;add X-increment
STA BXHOLD,X ;replace X-sum
LDA #0 ;get zero
ROL A ;carry = 1
STA DELTAX ;X-delta
LDA BYHOLD,X ;bomb Y-sum
ADC BYINC,X ;add Y-increment
STA BYHOLD,X ;replace Y-sum
LDA #0 ;get zero
ROL A ;carry = 1
STA DELTAY ;Y-delta
LDA BOMBLR,X ;bomb L/R flag
BEQ ADVLFT ;go left? Yes.
LDA BOMBX,X ;bomb X-coord
ADC DELTAX ;add X-delta
JMP ADVY ;skip next
ADVLFT LDA BOMBX,X ;bomb X-coord
SEC ;set carry
SBC DELTAX ;sub X-delta
ADVY STA BOMBX,X ;save X-coord
LDA BOMBUD,X ;bomb U/D flag
BEQ ADVDN ;go down? Yes.
LDA BOMBY,X ;bomb Y-coord
SEC ;set carry
SBC DELTAY ;sub Y-delta
JMP ADVEND ;skip next
ADVDN LDA BOMBY,X ;bomb Y-coord
CLC ;clear carry
ADC DELTAY ;add Y-delta
ADVEND STA BOMBY,X ;save Y-coord
RTS ;return
;
; --------------------------
; Clear out player indicated
; by the X register!
; --------------------------
;
CLRPLR LDA #0 ;move player...
STA HPOSP0,X ;off screen,
TAY ;init index
TXA ;get X
ORA # >PLR0 ;mask w/address
STA HI ;plr addr high
TYA ;Acc = 0
STA LO ;plr addr low
CLPLP STA (LO),Y ;zero player
DEY ;dec index
BNE CLPLP ;done? No.
RTS ;return
;
; -----------------------
; Calculate target vector
; -----------------------
;
VECTOR LDA #0 ;get zero
STA LR ;going left
LDA FROMX ;from X-coord
CMP TOX ;w/to X-coord
BCC RIGHT ;to right? Yes.
SBC TOX ;get X-diff
JMP VECY ;skip next
RIGHT INC LR ;going right
LDA TOX ;to X-coord
SEC ;set carry
SBC FROMX ;get X-diff
VECY STA VXINC ;save difference
LDA #1 ;get one
STA UD ;going up flag
LDA FROMY ;from Y-coord
CMP TOY ;w/to Y-coord
BCC DOWN ;down? Yes.
SBC TOY ;get Y-diff
JMP VECSET ;skip next
DOWN DEC UD ;going down flag
LDA TOY ;to Y-coord
SEC ;set carry
SBC FROMY ;get Y-diff
VECSET STA VYINC ;are both
ORA VXINC ;distances 0?
BNE VECLP ;No. skip next
LDA #$80 ;set x increment
STA VXINC ;to default.
VECLP LDA VXINC ;X vector incre
BMI VECEND ;>127? Yes.
LDA VYINC ;Y vector incre
BMI VECEND ;>127? Yes.
ASL VXINC ;times 2 until
ASL VYINC ;one is >127
JMP VECLP ;continue
VECEND RTS ;return
;
; ------------
; Add to score
; ------------
;
ADDSCO LDY #0 ;init index
SED ;decimal mode
CLC ;clear carry
LDX #2 ;do 3 bytes
ASCLP LDA SCORE,X ;get score
ADC SCOADD,X ;add bomb value
STA SCORE,X ;save score
STY SCOADD,X ;zero value
DEX ;next byte
BPL ASCLP ;done? No.
CLD ;clear decimal
;
; ----------
; Show score
; ----------
;
SHOSCO LDA #$10 ;put color 0
STA SHCOLR ;in hold area
LDX #1 ;2nd line char
LDY #0 ;digits 1,2
SSCOLP LDA SCORE,Y ;get digits
JSR SHOBCD ;show 'em
INX ;advance score
INX ;line pointer
INY ;next 2 digits
CPY #3 ;done 6?
BNE SSCOLP ;no!
RTS ;all done!
;
; -----------------
; Show level number
; -----------------
;
SHOLVL LDY #$50 ;use color 2
STY SHCOLR ;save it
LDA LEVEL ;get level #
LDX #11 ;12th char on line
;
; -----------------
; Show 2 BCD digits
; -----------------
;
SHOBCD STA SHOBYT ;save digits
AND #$0F ;get lower digit
ORA SHCOLR ;add color
STA SCOLIN+1,X ;show it
LDA SHOBYT ;get both again
LSR A ;mask...
LSR A ;off...
LSR A ;upper...
LSR A ;digit
ORA SHCOLR ;add color
STA SCOLIN,X ;show it!
RTS ;and exit.
;
; -------------------
; KOALA PAD interface
; -------------------
;
; The following filtering
; algorithm is used:
;
; Given 5 points S1,S2,S3,S4,S5
;
; R1=S1+S2+S2+S3
; R2=S2+S3+S3+S4
; R3=S3+S4+S4+S5
;
; AVG=(R1+R2+R2+R3)/16
;
; This reduces to:
;
; AVG=(S1+S2*4+S3*6+S4*4+S5)/16
;
; ---------------------------
; Rotate points through queue
; ---------------------------
;
KOALA LDX #4 ;do 5 bytes
ROT LDA XQ-1,X ;move X queue
STA XQ,X ;up one byte
LDA YQ-1,X ;move Y queue
STA YQ,X ;up one byte
DEX ;dec count
BNE ROT ;done? No.
;
; --------------------
; Clear out the cursor
; --------------------
;
LDY CURY ;get Y coord
LDX #5 ;do 6 bytes
CCURS LDA MISL,Y ;get missiles
AND #$F0 ;mask off low
STA MISL,Y ;put back
DEX ;dec count
BPL CCURS ;done? No.
;
; ---------------------------
; Insert new point into queue
; ---------------------------
;
LDA #1 ;pen up flag
STA PENFLG ;set pen up
LDA PADDL0 ;X input
STA XQ ;put in queue
CMP #5 ;screen boundary
BCC KOALAX ;on screen? No.
LDA PADDL1 ;Y input
STA YQ ;put in queue
CMP #5 ;screen boundary
BCC KOALAX ;on screen? No.
;
; ---------------------
; Filter the X-Y queues
; ---------------------
;
LDA # <XQ ;queue addr low
STA PTR ;pointer low
LDA # >XQ ;queue addr high
STA PTR+1 ;pointer high
JSR FILTER ;filter X data
BCS KOALAX ;good data? No.
ADC #16 ;X offset
CMP #48 ;far left?
BCS FLF ;No. skip
LDA #48 ;screen left
FLF CMP #208 ;far right?
BCC FRT ;No. skip
LDA #207 ;screen right
FRT STA CURX ;put X coord
LDA # <YQ ;queue addr low
STA PTR ;pointer low
LDA # >YQ ;queue addr high
STA PTR+1 ;pointer high
JSR FILTER ;filter Y data
BCS KOALAX ;good data? No.
ADC #16 ;Y offset
CMP #32 ;above top?
BCS FUP ;No. skip
LDA #32 ;screen top
FUP CMP #224 ;below bottom?
BCC FDN ;No. skip
LDA #223 ;screen bottom
FDN STA CURY ;put Y coord
;
; ----------------------
; Paddle trigger handler
; ----------------------
;
LDA PTRIG0 ;paddle trig 0
EOR PTRIG1 ;EOR w/PTRIG1
EOR #1 ;inverse data
STA STRIG0 ;put in STRIG0
LDA #0 ;pen down flag
STA PENFLG ;set pen down
KOALAX RTS ;continue
;
; ----------------------------
; Filter algorithm, initialize
; ----------------------------
;
FILTER LDA #0 ;get zero
LDX #4 ;do 5 bytes
FILC STA SH,X ;high byte table
DEX ;dec count
BPL FILC ;done? No.
STA AVG ;average low
STA AVG+1 ;average high
TAY ;xero in Y
LDX #1 ;one in X
;
; -----------------------
; Process the X-Y samples
; -----------------------
;
LDA (PTR),Y ;get S1
STA SL,Y ;save low byte
INY ;inc pointer
JSR MUL4 ;process S2
LDA (PTR),Y ;get S3
ASL A ;times 2
ROL SH,X ;rotate carry
ADC (PTR),Y ;add = times 3
BCC FIL2 ;overflow? No.
INC SH,X ;inc high byte
FIL2 ASL A ;times 6
ROL SH,X ;rotate carry
STA SL,X ;save low byte
INX ;inc pointer
INY ;inc pointer
JSR MUL4 ;process S4
LDA (PTR),Y ;get S5
STA SL,Y ;save low byte
;
; -------------
; Total samples
; -------------
;
LDX #4 ;add 5 elements
ALOOP LDA SL,X ;get low byte
ADC AVG ;add to average
STA AVG ;save low byte
LDA SH,X ;get high byte
ADC AVG+1 ;add to average
STA AVG+1 ;save high byte
DEX ;dec pointer
BPL ALOOP ;done? No.
;
; ------------------
; Divide total by 16
; ------------------
;
LDX #4 ;shift 4 bits
LDA AVG ;get lo byte
DIV16 LSR AVG+1 ;rotate high
ROR A ;rotate low
DEX ;dec count
BNE DIV16 ;done? No.
TAX ;save Acc
;
; --------------------------
; Compare average with DELTA
; --------------------------
;
LDY #4 ;5 byte table
MEAN SEC ;set carry
SBC (PTR),Y ;compare points
BCS POSI ;negative? No.
EOR #$FF ;negate byte and
ADC #1 ;+1 = ABS value
POSI CMP #24 ;within DELTA?
BCS FAIL ;No. abort
TXA ;get Acc again
DEY ;dec pointer
BPL MEAN ;done? No.
FAIL RTS ;exit
;
; ----------------
; Multply Acc by 4
; ----------------
;
MUL4 LDA (PTR),Y ;get S2
ASL A ;times 2
ROL SH,X ;rotate carry
ASL A ;times 4
ROL SH,X ;rotate carry
STA SL,X ;save low byte
INX ;inc pointer
INY ;inc pointer
RTS ;return
;
; ----------
; Data areas
; ----------
;
BMAXS .BYTE 0,250 ;bomb limits
BOMPIC .BYTE 0,0,0,0,0,0,$DC,$3E
.BYTE $7E,$3E,$DC,0,0,0,0
.BYTE 0,0,$76,$F8,$FC
.BYTE $F8,$76,0,0,0,0,0,0
BPSTRT .BYTE 27,16
BXOF .BYTE 47,42
CURPIC .BYTE $40,$40,$A0,$A0
.BYTE $40,$40
P3COLR .BYTE $34,$F8
SAUPIC .BYTE 0,0,$18,$7E,0,0
.BYTE $7E,$18,0,0
SAUMID .BYTE $92,$49,$24,$92
STARTX .BYTE 40,$FF,210,$FF
STARTY .BYTE $FF,20,$FF,230
ENDX .BYTE $FF,210,$FF,40
ENDY .BYTE 20,$FF,230,$FF
;
; ---------------------
; Explosion data tables
; ---------------------
;
PLOTBL .BYTE $C0,$30,$0C,$03
ERABIT .BYTE $3F,$CF,$F3,$FC
PROMSK .BYTE 0,0,0,0
.BYTE $FF,$FF,$FF,$FF
.BYTE $FF,$FF,$AA,$AA
COORD1 .BYTE 0,1,255,0,255,1
.BYTE 0,2,255,254,0,1
.BYTE 0,254,2,1,1,255
.BYTE 0,2,254,255,3,0
.BYTE 253,254,3,2,255,254
.BYTE 1,255,3,253,1,253,2
COORD2 .BYTE 0,0,1,255,0,1
.BYTE 1,0,255,1,2,255
.BYTE 254,255,1,2,254,2
.BYTE 3,255,0,254,1,253
.BYTE 0,254,255,2,3,2
.BYTE 253,253,0,1,3,255,254
;
; ------------------
; Initial score line
; ------------------
;
SCOINI .BYTE $00,$00,$00,$00
.BYTE $00,$00,$00,$00
.BYTE $6C,$76,$6C,$00
.BYTE $00,$00,$CA,$CA
.BYTE $CA,$CA,$CA,$00
;
; ------------
; Level tables
; ------------
;
INIBOM .BYTE 10,15,20,25,20,25
.BYTE 15,20,25,20,25,30
INIBS .BYTE 12,11,10,9,8,7
.BYTE 7,6,5,5,4,3
INISC .BYTE 0,10,50,90,50,80
.BYTE 40,60,100,80,120,125
INIPC .BYTE $20,$30,$40,$50,$60
.BYTE $70,$80,$A0,$B0,$C0
.BYTE $D0,$FF
INIBVH .BYTE 0,0,0,0,0,0
.BYTE 0,0,0,$01,$01,$01
INIBVL .BYTE $10,$20,$30,$40,$50
.BYTE $60,$70,$80,$90,$00
.BYTE $10,$20
INISV .BYTE 0,1,1,1,2,2
.BYTE 3,3,3,4,4,4
;
; ----------
; Sound data
; ----------
;
PLSHOT .BYTE 244,254,210,220
.BYTE 176,186,142,152,108
.BYTE 118,74,84,40,50
ENSHOT .BYTE 101,96,85,80,69,64
.BYTE 53,48,37,32,21,16,5,0
SAUSND .BYTE 10,11,12,14,16,17
.BYTE 18,17,16,14,12,11
;
; -----------------
; Program variables
; -----------------
;
XPOS *= *+20 ;all expl. x's
YPOS *= *+20 ;all expl. y's
CNT *= *+20 ;all expl. counts
BOMACT *= *+4 ;bomb active flags
PROACT *= *+8 ;proj. active flags
BOMBX *= *+4 ;bomb x positions
PROJX *= *+8 ;proj. x positions
BOMBY *= *+4 ;bomb y positions
PROJY *= *+8 ;proj. y positions
BXINC *= *+4 ;bomb x vectors
PXINC *= *+8 ;proj. x vectors
BYINC *= *+4 ;bomb y vectors
PYINC *= *+8 ;proj. y vectors
BXHOLD *= *+12 ;b/p hold areas
BYHOLD *= *+12 ;b/p hold areas
BOMBLR *= *+4 ;bomb left/right
PROJLR *= *+8 ;proj. left/right
BOMBUD *= *+4 ;bomb up/down
PROJUD *= *+8 ;proj. up/down
SCOLIN *= *+20 ;score line
;
; --------------
; End of program
; --------------
;
.END