0100 ; 0110 ; File: D:PLANET3.M65 0120 ; 0130 ; ---------------------- 0140 ; Check satellite status 0150 ; ---------------------- 0160 ; 0170 CHKSAT LDA DEADTM ;satellite ok? 0180 BEQ LIVE ;No. skip next 0190 CHKSX RTS ;return 0200 LIVE LDA LIVES ;lives left? 0210 BMI CHKSX ;No. exit 0220 LDA #1 ;get one 0230 STA SATLIV ;set alive flag 0240 LDA M0PL ;did satellite 0250 ORA M0PL+1 ;hit any bombs? 0260 BEQ CHKSX ;No. exit 0270 LDA #0 ;get zero 0280 STA SATLIV ;kill satellite 0290 STA SCNT ;init orbit 0300 LDX LIVES ;one less life 0310 STA SCOLIN+14,X ;erase life 0320 DEC LIVES ;dec lives count 0330 BPL MORSAT ;any left? Yes. 0340 LDA #255 ;lot of bombs 0350 STA BOMBS ;into bomb count 0360 STA GAMCTL ;end game 0370 JSR SNDOFF ;no sound 1 2 3 0380 MORSAT LDA SATX ;sat X-coord 0390 STA NEWX ;explo X-coord 0400 LDA SATY ;sat Y-coord 0410 STA NEWY ;explo Y-coord 0420 JSR NEWEXP ;set off explo 0430 LDA #80 ;init sat X 0440 STA SATX ;sat X-coord 0450 LDA #21 ;init sat Y 0460 STA SATY ;sat Y-coord 0470 LDX #0 ;don't show the 0480 CLRSAT LDA MISL,X ;satellite pic 0490 AND #$F0 ;mask off sat 0500 STA MISL,X ;restore data 0510 DEX ;dec index 0520 BNE CLRSAT ;done? No. 0530 LDA #$FF ;4.25 seconds 0540 STA DEADTM ;till next life! 0550 RTS ;return 0560 ; 0570 ; ------------------ 0580 ; Check console keys 0590 ; ------------------ 0600 ; 0610 ENDGAM JSR SNDOFF ;no sound 123 0620 ENDGLP LDA STRIG0 ;stick trigger 0630 AND PTRIG0 ;mask w/paddle 0 0640 AND PTRIG1 ;mask w/paddle 1 0650 BEQ ENDGL1 ;any pushed? No. 0660 LDA CONSOL ;chk console 0670 CMP #7 ;any pushed? 0680 BEQ ENDGLP ;No. loop here 0690 ENDGL1 JMP PLANET ;restart game 0700 ; 0710 ; ------------------------- 0720 ; Turn off sound regs 1 2 3 0730 ; ------------------------- 0740 ; 0750 SNDOFF LDA #0 ;zero volume 0760 STA AUDC1 ;to sound #1 0770 STA AUDC1+2 ;sound #2 0780 STA AUDC1+4 ;sound #3 0790 RTS ;return 0800 ; 0810 ; ----------------------- 0820 ; Check for hits on bombs 0830 ; ----------------------- 0840 ; 0850 CHKHIT LDX #3 ;4 bombs 0..3 0860 LDA SAUCER ;saucer enabled? 0870 BEQ CHLOOP ;No. skip next 0880 LDA #0 ;get zero 0890 STA BOMCOL ;collision count 0900 LDA GAMCTL ;game over? 0910 BMI NOSCOR ;Yes. skip next 0920 LDA BOMBX+3 ;saucer X-coord 0930 CMP #39 ;off screen lf? 0940 BCC NOSCOR ;Yes. kill it 0950 CMP #211 ;off screen rt? 0960 BCS NOSCOR ;Yes. kill it 0970 LDA BOMBY+3 ;saucer Y-coord 0980 CMP #19 ;off screen up? 0990 BCC NOSCOR ;Yes. kill it 1000 CMP #231 ;off screen dn? 1010 BCS NOSCOR ;Yes. kill it 1020 CHLOOP LDA #0 ;get zero 1030 STA BOMCOL ;collision count 1040 LDA P0PF,X ;playf collision 1050 AND #$05 ;w/shot+planet 1060 BEQ NOBHIT ;hit either? No. 1070 INC BOMCOL ;Yes. inc count 1080 AND #$04 ;hit shot? 1090 BEQ NOSCOR ;No. skip next 1100 LDA GAMCTL ;game over? 1110 BMI NOSCOR ;Yes. skip next 1120 LDA #2 ;1/30th second 1130 STA BOMBWT ;bomb wait time 1140 CPX #3 ;saucer player? 1150 BNE ADDBS ;No. skip this 1160 LDA SAUCER ;saucer on? 1170 BEQ ADDBS ;No. this this 1180 LDA SAUVAL ;saucer value 1190 STA SCOADD+1 ;point value 1200 JMP ADDIT ;add to score 1210 ; 1220 ; ----------------------- 1230 ; Add bomb value to score 1240 ; ----------------------- 1250 ; 1260 ADDBS LDA BOMVL ;bomb value low 1270 STA SCOADD+2 ;score inc low 1280 LDA BOMVH ;bomb value high 1290 STA SCOADD+1 ;score inc high 1300 ADDIT STX XHOLD ;save X register 1310 JSR ADDSCO ;add to score 1320 LDX XHOLD ;restore X 1330 NOSCOR LDA #0 ;get zero 1340 STA BOMACT,X ;kill bomb 1350 LDY BOMBLR,X ;L/R flag 1360 LDA BOMBX,X ;bomb X-coord 1370 SEC ;set carry 1380 SBC BXOF,Y ;bomb X offset 1390 STA NEWX ;plotter X-coord 1400 LDA BOMBY,X ;bomb Y-coord 1410 SEC ;set carry 1420 SBC #40 ;bomb Y offset 1430 LSR A ;2 line res. 1440 STA NEWY ;plotter Y-coord 1450 LDA SAUCER ;saucer? 1460 BEQ EXPBOM ;No. explode it 1470 CPX #3 ;bomb player? 1480 BNE EXPBOM ;Yes. explode it 1490 LDA #0 ;get zero 1500 STA SAUCER ;kill saucer 1510 JSR CLRPLR ;clear player 1520 LDA GAMCTL ;game over? 1530 BMI NOBHIT ;Yes. skip next 1540 EXPBOM JSR CLRPLR ;clear player 1550 LDA BOMCOL ;collisions? 1560 BEQ NOBHIT ;No. skip this 1570 JSR NEWEXP ;init explosion 1580 NOBHIT DEX ;dec index 1590 BPL CHLOOP ;done? No. 1600 STA HITCLR ;reset collision 1610 RTS ;return 1620 ; 1630 ; ------------------------- 1640 ; Advance bombs/projectiles 1650 ; ------------------------- 1660 ; 1670 ADVIT LDA BXHOLD,X ;bomb X-sum 1680 CLC ;clear carry 1690 ADC BXINC,X ;add X-increment 1700 STA BXHOLD,X ;replace X-sum 1710 LDA #0 ;get zero 1720 ROL A ;carry = 1 1730 STA DELTAX ;X-delta 1740 LDA BYHOLD,X ;bomb Y-sum 1750 ADC BYINC,X ;add Y-increment 1760 STA BYHOLD,X ;replace Y-sum 1770 LDA #0 ;get zero 1780 ROL A ;carry = 1 1790 STA DELTAY ;Y-delta 1800 LDA BOMBLR,X ;bomb L/R flag 1810 BEQ ADVLFT ;go left? Yes. 1820 LDA BOMBX,X ;bomb X-coord 1830 ADC DELTAX ;add X-delta 1840 JMP ADVY ;skip next 1850 ADVLFT LDA BOMBX,X ;bomb X-coord 1860 SEC ;set carry 1870 SBC DELTAX ;sub X-delta 1880 ADVY STA BOMBX,X ;save X-coord 1890 LDA BOMBUD,X ;bomb U/D flag 1900 BEQ ADVDN ;go down? Yes. 1910 LDA BOMBY,X ;bomb Y-coord 1920 SEC ;set carry 1930 SBC DELTAY ;sub Y-delta 1940 JMP ADVEND ;skip next 1950 ADVDN LDA BOMBY,X ;bomb Y-coord 1960 CLC ;clear carry 1970 ADC DELTAY ;add Y-delta 1980 ADVEND STA BOMBY,X ;save Y-coord 1990 RTS ;return 2000 ; 2010 ; -------------------------- 2020 ; Clear out player indicated 2030 ; by the X register! 2040 ; -------------------------- 2050 ; 2060 CLRPLR LDA #0 ;move player... 2070 STA HPOSP0,X ;off screen, 2080 TAY ;init index 2090 TXA ;get X 2100 ORA # >PLR0 ;mask w/address 2110 STA HI ;plr addr high 2120 TYA ;Acc = 0 2130 STA LO ;plr addr low 2140 CLPLP STA (LO),Y ;zero player 2150 DEY ;dec index 2160 BNE CLPLP ;done? No. 2170 RTS ;return 2180 ; 2190 ; ----------------------- 2200 ; Calculate target vector 2210 ; ----------------------- 2220 ; 2230 VECTOR LDA #0 ;get zero 2240 STA LR ;going left 2250 LDA FROMX ;from X-coord 2260 CMP TOX ;w/to X-coord 2270 BCC RIGHT ;to right? Yes. 2280 SBC TOX ;get X-diff 2290 JMP VECY ;skip next 2300 RIGHT INC LR ;going right 2310 LDA TOX ;to X-coord 2320 SEC ;set carry 2330 SBC FROMX ;get X-diff 2340 VECY STA VXINC ;save difference 2350 LDA #1 ;get one 2360 STA UD ;going up flag 2370 LDA FROMY ;from Y-coord 2380 CMP TOY ;w/to Y-coord 2390 BCC DOWN ;down? Yes. 2400 SBC TOY ;get Y-diff 2410 JMP VECSET ;skip next 2420 DOWN DEC UD ;going down flag 2430 LDA TOY ;to Y-coord 2440 SEC ;set carry 2450 SBC FROMY ;get Y-diff 2460 VECSET STA VYINC ;are both 2470 ORA VXINC ;distances 0? 2480 BNE VECLP ;No. skip next 2490 LDA #$80 ;set x increment 2500 STA VXINC ;to default. 2510 VECLP LDA VXINC ;X vector incre 2520 BMI VECEND ;>127? Yes. 2530 LDA VYINC ;Y vector incre 2540 BMI VECEND ;>127? Yes. 2550 ASL VXINC ;times 2 until 2560 ASL VYINC ;one is >127 2570 JMP VECLP ;continue 2580 VECEND RTS ;return 2590 ; 2600 ; ------------ 2610 ; Add to score 2620 ; ------------ 2630 ; 2640 ADDSCO LDY #0 ;init index 2650 SED ;decimal mode 2660 CLC ;clear carry 2670 LDX #2 ;do 3 bytes 2680 ASCLP LDA SCORE,X ;get score 2690 ADC SCOADD,X ;add bomb value 2700 STA SCORE,X ;save score 2710 STY SCOADD,X ;zero value 2720 DEX ;next byte 2730 BPL ASCLP ;done? No. 2740 CLD ;clear decimal 2750 ; 2760 ; ---------- 2770 ; Show score 2780 ; ---------- 2790 ; 2800 SHOSCO LDA #$10 ;put color 0 2810 STA SHCOLR ;in hold area 2820 LDX #1 ;2nd line char 2830 LDY #0 ;digits 1,2 2840 SSCOLP LDA SCORE,Y ;get digits 2850 JSR SHOBCD ;show 'em 2860 INX ;advance score 2870 INX ;line pointer 2880 INY ;next 2 digits 2890 CPY #3 ;done 6? 2900 BNE SSCOLP ;no! 2910 RTS ;all done! 2920 ; 2930 ; ----------------- 2940 ; Show level number 2950 ; ----------------- 2960 ; 2970 SHOLVL LDY #$50 ;use color 2 2980 STY SHCOLR ;save it 2990 LDA LEVEL ;get level # 3000 LDX #11 ;12th char on line 3010 ; 3020 ; ----------------- 3030 ; Show 2 BCD digits 3040 ; ----------------- 3050 ; 3060 SHOBCD STA SHOBYT ;save digits 3070 AND #$0F ;get lower digit 3080 ORA SHCOLR ;add color 3090 STA SCOLIN+1,X ;show it 3100 LDA SHOBYT ;get both again 3110 LSR A ;mask... 3120 LSR A ;off... 3130 LSR A ;upper... 3140 LSR A ;digit 3150 ORA SHCOLR ;add color 3160 STA SCOLIN,X ;show it! 3170 RTS ;and exit. 3180 ; 3190 ; ------------------- 3200 ; KOALA PAD interface 3210 ; ------------------- 3220 ; 3230 ; The following filtering 3240 ; algorithm is used: 3250 ; 3260 ; Given 5 points S1,S2,S3,S4,S5 3270 ; 3280 ; R1=S1+S2+S2+S3 3290 ; R2=S2+S3+S3+S4 3300 ; R3=S3+S4+S4+S5 3310 ; 3320 ; AVG=(R1+R2+R2+R3)/16 3330 ; 3340 ; This reduces to: 3350 ; 3360 ; AVG=(S1+S2*4+S3*6+S4*4+S5)/16 3370 ; 3380 ; --------------------------- 3390 ; Rotate points through queue 3400 ; --------------------------- 3410 ; 3420 KOALA LDX #4 ;do 5 bytes 3430 ROT LDA XQ-1,X ;move X queue 3440 STA XQ,X ;up one byte 3450 LDA YQ-1,X ;move Y queue 3460 STA YQ,X ;up one byte 3470 DEX ;dec count 3480 BNE ROT ;done? No. 3490 ; 3500 ; -------------------- 3510 ; Clear out the cursor 3520 ; -------------------- 3530 ; 3540 LDY CURY ;get Y coord 3550 LDX #5 ;do 6 bytes 3560 CCURS LDA MISL,Y ;get missiles 3570 AND #$F0 ;mask off low 3580 STA MISL,Y ;put back 3590 DEX ;dec count 3600 BPL CCURS ;done? No. 3610 ; 3620 ; --------------------------- 3630 ; Insert new point into queue 3640 ; --------------------------- 3650 ; 3660 LDA #1 ;pen up flag 3670 STA PENFLG ;set pen up 3680 LDA PADDL0 ;X input 3690 STA XQ ;put in queue 3700 CMP #5 ;screen boundary 3710 BCC KOALAX ;on screen? No. 3720 LDA PADDL1 ;Y input 3730 STA YQ ;put in queue 3740 CMP #5 ;screen boundary 3750 BCC KOALAX ;on screen? No. 3760 ; 3770 ; --------------------- 3780 ; Filter the X-Y queues 3790 ; --------------------- 3800 ; 3810 LDA # XQ ;queue addr high 3840 STA PTR+1 ;pointer high 3850 JSR FILTER ;filter X data 3860 BCS KOALAX ;good data? No. 3870 ADC #16 ;X offset 3880 CMP #48 ;far left? 3890 BCS FLF ;No. skip 3900 LDA #48 ;screen left 3910 FLF CMP #208 ;far right? 3920 BCC FRT ;No. skip 3930 LDA #207 ;screen right 3940 FRT STA CURX ;put X coord 3950 LDA # YQ ;queue addr high 3980 STA PTR+1 ;pointer high 3990 JSR FILTER ;filter Y data 4000 BCS KOALAX ;good data? No. 4010 ADC #16 ;Y offset 4020 CMP #32 ;above top? 4030 BCS FUP ;No. skip 4040 LDA #32 ;screen top 4050 FUP CMP #224 ;below bottom? 4060 BCC FDN ;No. skip 4070 LDA #223 ;screen bottom 4080 FDN STA CURY ;put Y coord 4090 ; 4100 ; ---------------------- 4110 ; Paddle trigger handler 4120 ; ---------------------- 4130 ; 4140 LDA PTRIG0 ;paddle trig 0 4150 EOR PTRIG1 ;EOR w/PTRIG1 4160 EOR #1 ;inverse data 4170 STA STRIG0 ;put in STRIG0 4180 LDA #0 ;pen down flag 4190 STA PENFLG ;set pen down 4200 KOALAX RTS ;continue 4210 ; 4220 ; ---------------------------- 4230 ; Filter algorithm, initialize 4240 ; ---------------------------- 4250 ; 4260 FILTER LDA #0 ;get zero 4270 LDX #4 ;do 5 bytes 4280 FILC STA SH,X ;high byte table 4290 DEX ;dec count 4300 BPL FILC ;done? No. 4310 STA AVG ;average low 4320 STA AVG+1 ;average high 4330 TAY ;xero in Y 4340 LDX #1 ;one in X 4350 ; 4360 ; ----------------------- 4370 ; Process the X-Y samples 4380 ; ----------------------- 4390 ; 4400 LDA (PTR),Y ;get S1 4410 STA SL,Y ;save low byte 4420 INY ;inc pointer 4430 JSR MUL4 ;process S2 4440 LDA (PTR),Y ;get S3 4450 ASL A ;times 2 4460 ROL SH,X ;rotate carry 4470 ADC (PTR),Y ;add = times 3 4480 BCC FIL2 ;overflow? No. 4490 INC SH,X ;inc high byte 4500 FIL2 ASL A ;times 6 4510 ROL SH,X ;rotate carry 4520 STA SL,X ;save low byte 4530 INX ;inc pointer 4540 INY ;inc pointer 4550 JSR MUL4 ;process S4 4560 LDA (PTR),Y ;get S5 4570 STA SL,Y ;save low byte 4580 ; 4590 ; ------------- 4600 ; Total samples 4610 ; ------------- 4620 ; 4630 LDX #4 ;add 5 elements 4640 ALOOP LDA SL,X ;get low byte 4650 ADC AVG ;add to average 4660 STA AVG ;save low byte 4670 LDA SH,X ;get high byte 4680 ADC AVG+1 ;add to average 4690 STA AVG+1 ;save high byte 4700 DEX ;dec pointer 4710 BPL ALOOP ;done? No. 4720 ; 4730 ; ------------------ 4740 ; Divide total by 16 4750 ; ------------------ 4760 ; 4770 LDX #4 ;shift 4 bits 4780 LDA AVG ;get lo byte 4790 DIV16 LSR AVG+1 ;rotate high 4800 ROR A ;rotate low 4810 DEX ;dec count 4820 BNE DIV16 ;done? No. 4830 TAX ;save Acc 4840 ; 4850 ; -------------------------- 4860 ; Compare average with DELTA 4870 ; -------------------------- 4880 ; 4890 LDY #4 ;5 byte table 4900 MEAN SEC ;set carry 4910 SBC (PTR),Y ;compare points 4920 BCS POSI ;negative? No. 4930 EOR #$FF ;negate byte and 4940 ADC #1 ;+1 = ABS value 4950 POSI CMP #24 ;within DELTA? 4960 BCS FAIL ;No. abort 4970 TXA ;get Acc again 4980 DEY ;dec pointer 4990 BPL MEAN ;done? No. 5000 FAIL RTS ;exit 5010 ; 5020 ; ---------------- 5030 ; Multply Acc by 4 5040 ; ---------------- 5050 ; 5060 MUL4 LDA (PTR),Y ;get S2 5070 ASL A ;times 2 5080 ROL SH,X ;rotate carry 5090 ASL A ;times 4 5100 ROL SH,X ;rotate carry 5110 STA SL,X ;save low byte 5120 INX ;inc pointer 5130 INY ;inc pointer 5140 RTS ;return 5150 ; 5160 ; ---------- 5170 ; Data areas 5180 ; ---------- 5190 ; 5200 BMAXS .BYTE 0,250 ;bomb limits 5210 BOMPIC .BYTE 0,0,0,0,0,0,$DC,$3E 5220 .BYTE $7E,$3E,$DC,0,0,0,0 5230 .BYTE 0,0,$76,$F8,$FC 5240 .BYTE $F8,$76,0,0,0,0,0,0 5250 BPSTRT .BYTE 27,16 5260 BXOF .BYTE 47,42 5270 CURPIC .BYTE $40,$40,$A0,$A0 5280 .BYTE $40,$40 5290 P3COLR .BYTE $34,$F8 5300 SAUPIC .BYTE 0,0,$18,$7E,0,0 5310 .BYTE $7E,$18,0,0 5320 SAUMID .BYTE $92,$49,$24,$92 5330 STARTX .BYTE 40,$FF,210,$FF 5340 STARTY .BYTE $FF,20,$FF,230 5350 ENDX .BYTE $FF,210,$FF,40 5360 ENDY .BYTE 20,$FF,230,$FF 5370 ; 5380 ; --------------------- 5390 ; Explosion data tables 5400 ; --------------------- 5410 ; 5420 PLOTBL .BYTE $C0,$30,$0C,$03 5430 ERABIT .BYTE $3F,$CF,$F3,$FC 5440 PROMSK .BYTE 0,0,0,0 5450 .BYTE $FF,$FF,$FF,$FF 5460 .BYTE $FF,$FF,$AA,$AA 5470 COORD1 .BYTE 0,1,255,0,255,1 5480 .BYTE 0,2,255,254,0,1 5490 .BYTE 0,254,2,1,1,255 5500 .BYTE 0,2,254,255,3,0 5510 .BYTE 253,254,3,2,255,254 5520 .BYTE 1,255,3,253,1,253,2 5530 COORD2 .BYTE 0,0,1,255,0,1 5540 .BYTE 1,0,255,1,2,255 5550 .BYTE 254,255,1,2,254,2 5560 .BYTE 3,255,0,254,1,253 5570 .BYTE 0,254,255,2,3,2 5580 .BYTE 253,253,0,1,3,255,254 5590 ; 5600 ; ------------------ 5610 ; Initial score line 5620 ; ------------------ 5630 ; 5640 SCOINI .BYTE $00,$00,$00,$00 5650 .BYTE $00,$00,$00,$00 5660 .BYTE $6C,$76,$6C,$00 5670 .BYTE $00,$00,$CA,$CA 5680 .BYTE $CA,$CA,$CA,$00 5690 ; 5700 ; ------------ 5710 ; Level tables 5720 ; ------------ 5730 ; 5740 INIBOM .BYTE 10,15,20,25,20,25 5750 .BYTE 15,20,25,20,25,30 5760 INIBS .BYTE 12,11,10,9,8,7 5770 .BYTE 7,6,5,5,4,3 5780 INISC .BYTE 0,10,50,90,50,80 5790 .BYTE 40,60,100,80,120,125 5800 INIPC .BYTE $20,$30,$40,$50,$60 5810 .BYTE $70,$80,$A0,$B0,$C0 5820 .BYTE $D0,$FF 5830 INIBVH .BYTE 0,0,0,0,0,0 5840 .BYTE 0,0,0,$01,$01,$01 5850 INIBVL .BYTE $10,$20,$30,$40,$50 5860 .BYTE $60,$70,$80,$90,$00 5870 .BYTE $10,$20 5880 INISV .BYTE 0,1,1,1,2,2 5890 .BYTE 3,3,3,4,4,4 5900 ; 5910 ; ---------- 5920 ; Sound data 5930 ; ---------- 5940 ; 5950 PLSHOT .BYTE 244,254,210,220 5960 .BYTE 176,186,142,152,108 5970 .BYTE 118,74,84,40,50 5980 ENSHOT .BYTE 101,96,85,80,69,64 5990 .BYTE 53,48,37,32,21,16,5,0 6000 SAUSND .BYTE 10,11,12,14,16,17 6010 .BYTE 18,17,16,14,12,11 6020 ; 6030 ; ----------------- 6040 ; Program variables 6050 ; ----------------- 6060 ; 6070 XPOS *= *+20 ;all expl. x's 6080 YPOS *= *+20 ;all expl. y's 6090 CNT *= *+20 ;all expl. counts 6100 BOMACT *= *+4 ;bomb active flags 6110 PROACT *= *+8 ;proj. active flags 6120 BOMBX *= *+4 ;bomb x positions 6130 PROJX *= *+8 ;proj. x positions 6140 BOMBY *= *+4 ;bomb y positions 6150 PROJY *= *+8 ;proj. y positions 6160 BXINC *= *+4 ;bomb x vectors 6170 PXINC *= *+8 ;proj. x vectors 6180 BYINC *= *+4 ;bomb y vectors 6190 PYINC *= *+8 ;proj. y vectors 6200 BXHOLD *= *+12 ;b/p hold areas 6210 BYHOLD *= *+12 ;b/p hold areas 6220 BOMBLR *= *+4 ;bomb left/right 6230 PROJLR *= *+8 ;proj. left/right 6240 BOMBUD *= *+4 ;bomb up/down 6250 PROJUD *= *+8 ;proj. up/down 6260 SCOLIN *= *+20 ;score line 6270 ; 6280 ; -------------- 6290 ; End of program 6300 ; -------------- 6310 ; 6320 .END