;****************************************************************************** ; $Id: tomcat+4.a65,v 1.15 2007/06/28 20:59:48 darron Exp $ ; ; Tomcat C16 (c) 1989 Players Software. ; ; Written by Darron M Broad. ; ; Tomcat +4 (c) 1989 Players Software and Darron M Broad 2007 (version 1), 2009. ; ; This is the +4 only edition! version 2 (2009) ; ;****************************************************************************** ;!source !convtab raw ;****************************************************************************** ; ; memory map ; ; $1000 .. $101f sys dec("1020") ; $1020 .. $33ff code ; $3400 .. $37ff game graphics (bitmaps) ; $3800 .. $3fff game graphics (charsets) ; $4000 .. $41ff previous score + new variables ; $4200 .. $43ff title graphics (CBASE=$4000, GRAPHICS @$4200) ; $4400 .. $53ff level 1 data ; $5400 .. $63ff level 2 data ; $6400 .. $73ff level 3 data ; $7400 .. $73ff level 4 data ; $8400 .. $93ff level 5 data ; $9400 .. $a3ff level 6 data ; $a400 .. $b3ff level 7 data ; $b400 .. $b7ff game over ; $b800 .. $bfff title graphic colors ; $c000 .. $dfff title graphic bitmap ; $e000 .. $fcff music ; ;****************************************************************************** ;****************************************************************************** ; ; variables ; ; $00..$1b are preserved between levels ; $1c..$ff are cleared between levels ; ;****************************************************************************** LEVEL = $0C LEVELLOADED = $0D BOMBCOLOR = $15 CHARCOLOR = $16 SCORE = $17 ; 3 bytes HIGHSCORE = $0E PREVSCORE = $4000 ; $4003..41ff is unused ;****************************************************************************** ; ; keyboard/joy buffer ; ;****************************************************************************** KEYTABLE = $1C ; 8 bytes ;****************************************************************************** ; ; player ; ;****************************************************************************** PLAYERXC = $F6 PLAYERYC = $F7 PLAYERLIVES = $1A PLAYERBLINK = $1B PLAYERBACKGND = $30 ;16 bytes PLAYERALIVE = $8D PLAYERFIRESWAP = $8F PLAYERFIREDIR = $90 PLAYERADDR = $F3 ; 2 bytes PLAYERSTEPX = $F5 ; 1=left, 2-right, 0=none? MDIS = $F8 MPHT = $F9 ;****************************************************************************** ; ; bombs (0..3=player, 4..7=enemy) ; ;****************************************************************************** BOMBADDR = $40 ;16 bytes, 8 addresses BOMBXC = $50 ; 8 bytes BOMBYC = $58 ; 8 bytes BOMBDIR = $60 ; 8 bytes BOMBBACKGND = $68 ; 8 bytes BOMBFLAGS = $70 ; 8 bits ;****************************************************************************** ; ; tanks (2 horizontal, 2 vertical) ; ;****************************************************************************** TANKHORADDR = $71 ; 4 bytes TANKHORXC = $79 ; 2 bytes TANKHORYC = $7D ; 2 bytes TANKHORDIR = $81 ; 2 bytes TANKVERADDR = $75 ; 4 bytes TANKVERXC = $7B ; 2 bytes TANKVERYC = $7F ; 2 bytes TANKVERDIR = $83 ; 2 bytes TANKALIVE = $85 ; 4 bytes TANKTURN = $A4 ; tank to fire next ;****************************************************************************** ; ; aeroplanes (2) ; ;****************************************************************************** PLANEADDR = $99 ; 4 bytes PLANEXC = $9D ; 2 bytes PLANEYC = $9F ; 2 bytes PLDI = $A1 ; 2 bytes PLANEBACKGND = $24 ;12 bytes PLANEDEAD = $AA ; 2 bytes PLANEIX = $A6 ; 2 bytes PLCT = $A8 ; 2 bytes ;****************************************************************************** ; ; turrets (4) ; ;****************************************************************************** TURRETADDR = $C4 ; 8 bytes TURRETYC = $CC ; 4 bytes TURRETXC = $EC ; 4 bytes TURRETTURN = $A3 ; turret to fire next ;****************************************************************************** ; ; sound generation ; ;****************************************************************************** SOUNDFREQ = $8A SOUNDBANG = $8B SOUNDFIRE = $8C ;****************************************************************************** ; ; temporary storage ; ;****************************************************************************** T0 = $91 T1 = $92 T2 = $93 T3 = $94 T4 = $95 T5 = $96 T6 = $97 T7 = $98 T00 = $02 TA = $03 TB = $04 ;****************************************************************************** ; ; other ; ;****************************************************************************** SCROLLOVERFLOW = $A5 LEVELDATAROW = $C1 ; new row counter (irq/4?) LEVELDATAADDR = $C2 ; 2 bytes row index IRQDIVISOR = $F0 SCR = $F1 SCROLLSPEED = $F2 ; new variables (2007) LEVELDATA = $4010 ; level data address hack LEVELEND = $4012 ; level end test hack LEVEL1DATA = $4400 LEVEL2DATA = $5400 LEVEL1TOP = $54 LEVEL2TOP = $64 ;****************************************************************************** ; ; constants ; ;****************************************************************************** ; inverse blit data PLANEINVMAP = $3580 PLAYERINVMAP = $35C0 ; bitmap blit data PLANEBITMAP = $35A0 PLAYERBITMAP = $3620 TURRETBITMAP = $3400 ; destination blit data PLANECHAR1 = $3DA0 ; aeroplane 1 ($3da0..$3dcf) ($b4..$b9) (6 chars) PLANECHAR2 = $3DD0 ; aeroplane 2 ($3dd0..$3dff) ($ba..$bf) (6 chars) PLAYERCHAR = $3E00 ; player image ($3e00..$3ecf) ($c0..$d9) (26 chars) TURRETCHAR1 = $3C20 ; turret 1 (32 bytes) ($3c20..$3c3f) ($84..$87) TURRETCHAR2 = $3C40 ; turret 2 (32 bytes) ($3c40..$3c5f) ($88..$8b) TURRETCHAR3 = $3C60 ; turret 3 (32 bytes) ($3c60..$3c7f) ($8c..$8f) TURRETCHAR4 = $3C80 ; turret 4 (32 bytes) ($3c80..$3c9f) ($90..$93) RADARBITMAP = $3518 TURRETCLOSED = $3540 TURRETOPEN = $3560 ; bitmaps at $3400 ; ; $3400 [00] turret up ; $3420 [04] turret right+up ; $3440 [08] turret right ; $3460 [0c] turret right+down ; $3480 [10] turret down ; $34a0 [14] turret left+down ; $34c0 [18] turret left ; $34e0 [1c] turret left+up ; $3500 [20] blank ; $3508 [21] blank ; $3510 [22] blank ; $3518 [23] centred dot top left ; $3520 [24] centred dot top right ; $3528 [25] centred dot bottom left ; $3530 [26] centred dot bottom right ; $3538 [27] bomb ; $3540 [28] turret closed ; $3560 [2c] turret open ; $3580 [30] aeroplane inverse mask ; $35a0 [34] aeroplane bitmask ; $35c0 [38] player inverse mask left ; $3620 [44] player bitmap left ; $3680 [50] player inverse mask center ; $36e0 [5c] player bitmap center ; $3740 [68] 0 ; $3748 [69] 1 ; $3750 [6a] 2 ; $3748 [6b] 3 ; $3758 [6c] 4 ; $3760 [6d] 5 ; $3768 [6e] 6 ; $3770 [6f] 7 ; $3778 [70] 8 ; $3780 [71] 9 ; $3788 [72] S ; $3790 [73] C ; $3798 [74] O ; $37a0 [75] R ; $37a8 [76] E ; $37b0 [77] L ; $37b8 [78] I ; $37c0 [79] V ; $37c8 [7a] plane? ; $37d0 [7b] T ; $37d8 [7c] M ; $37e0 [7d] A ; $37e8 [7e] ? ; $37f0 [7f] ? ;****************************************************************************** ; ; TED timers ; ;****************************************************************************** TEDTMR1L = $FF00 TEDTMR1H = $FF01 TEDTMR2L = $FF02 TEDTMR2H = $FF03 TEDTMR3L = $FF04 TEDTMR3H = $FF05 ;****************************************************************************** ; ; loader stuff (merged) ; ;****************************************************************************** TITLEBASE = $40 ; loader character set (data @ + $200) CLEARCHAR = $5D ; BLANK LOADBACKGNDCOL = $7E ; color memory colour (loader) GAMEBACKGNDCOL = $49 ; color memory colour (game) ; screen locations for messages SCNADDRERR = 3162 ; $0c5a SCNADDRREWIND = SCNADDRERR SCNADDRLOAD = 3403 ; $0d46 SCNADDRLEVBOX = 3645 ; $0e3d SCNADDRLEVEL = 3889 ; $0f31 ; temporary storage ;****************************************************************************** ; ; SYS DEC("1020") ; ;****************************************************************************** * = $1000 !byte $00,$11,$10,$0a,$00,$9e,$20,$d1 !byte $28,$22,$31,$30,$32,$30,$22,$29 !byte $00,$00,$00,$00,$00,$00,$00,$00 !byte $00,$00,$00,$00,$00,$00,$00,$00 ;****************************************************************************** ; ; initial entry point, entered only once ; ;****************************************************************************** SEI STA $FF3F ; RAM ON/ROM OFF BEGINLOW: JSR TITLEINIT JSR LOADINGMSG LDX #0 STX LEVELLOADED STX HIGHSCORE STX HIGHSCORE+1 STX HIGHSCORE+2 STX PREVSCORE STX PREVSCORE+1 STX PREVSCORE+2 INX STX LEVEL JSR READFILE JMP BEGINAGAIN ;****************************************************************************** ; ; display rewind message (historical) ; ;****************************************************************************** REWIND: LDA #SCNADDRREWIND STA TB LDX #9 LDY #MSGREWIND - MSGADDR JMP DRAWFLASH ;****************************************************************************** ; ; display loading level (historical) ; ;****************************************************************************** LOADLEVELMSG: LDA #SCNADDRLEVBOX STA T2 LDX #6 LDA #$40 JSR DRAWBOX LDX #MSGLEVEL - MSGADDR JSR PRINT LDA #SCNADDRLEVEL STA T2 LDX #2 LDA #$5F JSR DRAWBOX LDY #0 LDA LEVEL ORA #$60 STA (T1),Y LOADINGMSG: LDA #SCNADDRLOAD STA T2 LDX #8 LDA #$40 JSR DRAWBOX LDX #MSGLOADING - MSGADDR JMP PRINT ;****************************************************************************** ; ; pretend to read file and really setup level data ; ;****************************************************************************** READFILE: LDX #0 LDY #0 LDA #8 READFILE1: DEY BNE READFILE1 INC $ff19 DEX BNE READFILE1 SEC SBC #1 BNE READFILE1 LDA LEVEL CMP #1 BEQ SETUPLEVEL1 CMP #2 BEQ SETUPLEVEL2 LDA #1 STA LEVEL SETUPLEVEL1: LDA #LEVEL1TOP STA LEVELEND LDA #LEVEL1DATA STA LEVELDATA+1 RTS SETUPLEVEL2: LDA #LEVEL2TOP STA LEVELEND LDA #LEVEL2DATA STA LEVELDATA+1 RTS ;****************************************************************************** ; ; fake tape control ; ;****************************************************************************** LEVELCTRL: JSR TITLEINIT LDA LEVEL CMP LEVELLOADED BEQ LEVELCTRL4 CMP #3 BCC LEVELCTRL1 LDA #<3526 ; game over, lame success message STA TA LDA #>3526 STA TB LDX #10 LDY #MSGWELLDONE - MSGADDR JSR DRAWFLASH LDA #1 ; back to level 1 STA LEVEL JMP LEVELCTRL LEVELCTRL1: LDA LEVEL CMP LEVELLOADED BCS LEVELCTRL3 JSR REWIND JSR TITLEINIT LEVELCTRL3: JSR LOADLEVELMSG JSR READFILE LDA LEVEL STA LEVELLOADED LDA #0 STA T0 LEVELCTRL4: JSR DRAWTITLESCN JMP RIGHTPANEL ;****************************************************************************** ; ; game start ; ;****************************************************************************** BEGINAGAIN: SEI CLD LDA #0 STA SCORE STA SCORE+1 STA SCORE+2 LDA #4 STA PLAYERLIVES BEGIN: SEI LDX #$FF TXS JSR LEVELCTRL ; load level LDA $800 ; loaded with level data STA CHARCOLOR LDA #$73 ; fixed bomb color STA BOMBCOLOR LDA #IRQ1 STA $FFFF LDX #19 TED1: LDA TEDINIT,X STA $FF06,X DEX BPL TED1 LDX #$1C ; clear memory $1c .. $ff LDA #$00 CLREM: STA $00,X INX BNE CLREM LDA LEVELDATA ; init level data STA LEVELDATAADDR LDA LEVELDATA+1 STA LEVELDATAADDR+1 LDA #3 STA TURRETTURN STA TANKTURN LDA #$FF STA TEDTMR3L STA TEDTMR3H LDY #31 ; init turret char data TURSEX: LDA TURRETCLOSED,Y STA TURRETCHAR1,Y STA TURRETCHAR2,Y STA TURRETCHAR3,Y STA TURRETCHAR4,Y DEY BPL TURSEX JSR PLAYERINIT ; initial player position JSR PLAYERDRAW ; draw player LDX #8 ; init scroll speed to draw first page quickly STX SCROLLSPEED LDA #$60 ; disable keyscan (RTS) STA KEYSCAN CLI ; scroll page with keyboard disabled at high speed LDA #$D0 TURS: CMP LEVELDATAADDR ; wait for a full page draw BNE TURS LDA #1 ; init scroll speed for vertical scrolling STA SCROLLSPEED LDA #169 ; enable keyscan (LDA #) STA KEYSCAN LDA $FF06 ; BLANK=1 (OFF) ORA #$10 STA $FF06 ;****************************************************************************** ; ; game loop ; ;****************************************************************************** MOVE: LDA KEYTABLE CMP #128 BNE PROG ; => Run/Stop not pressed LDX #7 ; inspect keyboard/joy LDA #0 STCHK: ORA KEYTABLE,X DEX BNE STCHK TAX BNE PROG ; => other key pressed (error) LDA #1 ; abort game when only Run/Stop is pressed STA LEVEL JMP BEGINAGAIN PROG: LDA KEYTABLE AND #1 BEQ PROG3 ; => 1 not pressed JSR PAUSE ; pause game when 1 pressed (restart on 2) PROG3: LDA PLAYERALIVE BEQ PLAYERDEAD ; => player died JMP LEVELENDDETECT ; determine if end of level ;****************************************************************************** ; ; player dead ; ;****************************************************************************** PLAYERDEAD: SEI ; player dead STA $FF11 ; VOLUME=0 JSR DEATH ; death scene JSR PLAYERREMOVE ; restore player background graphics JSR BOMBC ; restore bomb background graphics JSR PLANEREMOVE ; restore plane background graphics LDA #0 STA BOMBFLAGS ; disable bombs STA PLANEYC ; disable planes STA PLANEYC+1 STA PLANEDEAD STA PLANEDEAD+1 LDX #3 ; destroy tanks? PLOOP: LDA TANKALIVE,X BEQ QLOOP LDA #1 STA TANKALIVE,X QLOOP: DEX BPL PLOOP JSR TANKDYING JSR PLAYERLIFEDEC BMI GAMEOVER ; => no lives left LDA #1 JSR DELAY JSR PLAYERINIT ; initial player position LDA #2 ; blink player bitmap STA PLAYERBLINK OLOOP: JSR PLAYERDRAW ; draw player LDA #1 JSR DELAY JSR PLAYERREMOVE ; restore player background graphics LDA #1 JSR DELAY DEC PLAYERBLINK BNE OLOOP JSR PLAYERDRAW ; draw player LDA #2 STA $FF09 ; I-RAS=1 CLI FARMOVE: JMP MOVE ; => main game loop ;****************************************************************************** ; ; game over ; ;****************************************************************************** GAMEOVER: LDA #4 ; game over all lives gone JSR DELAY LDA SCORE ; save score as old score STA PREVSCORE LDA SCORE+1 STA PREVSCORE+1 LDA SCORE+2 STA PREVSCORE+2 LDA #1 ; reset level STA LEVEL LDA SCORE ; compare score with high score SEC SBC HIGHSCORE LDA SCORE+1 SBC HIGHSCORE+1 LDA SCORE+2 SBC HIGHSCORE+2 BCC NOTHIGHEST LDA SCORE ; this is a new high score STA HIGHSCORE LDA SCORE+1 STA HIGHSCORE+1 LDA SCORE+2 STA HIGHSCORE+2 NOTHIGHEST: JMP BEGINAGAIN ; => restart ;****************************************************************************** ; ; end of level detection ; ;****************************************************************************** LEVELENDDETECT: LDA LEVELDATAADDR+1 ; end of level detection (victorious) CMP LEVELEND BNE FARMOVE ; => main game loop LDA BOMBFLAGS AND #$F0 ; detect active enemy bombs ORA PLANEYC ; detect active planes ORA PLANEYC+1 LDX #3 LEVELENDDETECT1:ORA TURRETYC,X ; detect active turrets and tanks ORA TANKHORYC,X DEX BPL LEVELENDDETECT1 CMP #0 BNE FARMOVE ; => main game loop LDA #4 JSR DELAY LDA SCORE ; save score as old score STA PREVSCORE LDA SCORE+1 STA PREVSCORE+1 LDA SCORE+2 STA PREVSCORE+2 INC LEVEL ; go to next level SEI JMP BEGIN ; => start next level ;****************************************************************************** ; ; interrupt service routines ; ;****************************************************************************** IRQ1: PHA ; SAVE REGISTERS TXA PHA TYA PHA LDA #2 STA $FF09 ; I-RAS=1 CLD LDA #0 ; not overflowed 8 pixels yet STA SCROLLOVERFLOW JSR KEYSCAN ; scan the keyboard/joy JSR PLAYERREMOVE ; restore player background JSR BOMBC ; restore bomb backgrounds INC IRQDIVISOR ; divide irq /2 = 25hz LDA IRQDIVISOR CMP #2 BEQ IRQ2 ; => secondary service routine ; primary service routine JSR PLANEREMOVE ; restore plane backgrounds JSR TURRETDETECT ; detect new turrets on line 6 JSR TANKCOLLIDE ; ? JSR TANKDYING ; tank dying JSR TANKFIRE ; tank look and fire JSR TURRETFIRE ; turret look and fire JSR PLANEFIRE ; plane fire JSR TANKHORMOVE ; horizontal tank movement? JSR TANKVERMOVE ; vertical tank movement? JSR AEROPLANES ; plane updates JSR RADARBLINK ; radar animation JSR PLAYERFIRE ; player fire JSR PLAYERMOVE ; player movement JSR SCOREDISPLAY ; update score board JMP IRQEXIT2 ; => irq completion ; secondary irq service IRQ2: LDA #0 STA IRQDIVISOR JSR PLAYERPOS ; adjust player position LDA SCR ; update vertical scroll position CLC ADC SCROLLSPEED STA SCROLLOVERFLOW TAX AND #7 STA SCR LDA $FF06 ; store vertical scroll position AND #$F0 ORA SCR STA $FF06 LDA MDIS SEC SBC SCROLLSPEED AND #7 STA MDIS CPX #8 BCS IRQ2SCROLL ; scroll backdrop JMP IRQEXIT1 ; => irq completion IRQ2SCROLL: LDX #$1C ; scroll character screen down one line IRQ2SCROLL1: LDA 3992,X STA 3992+40,X LDA 3952,X STA 3952+40,X LDA 3912,X STA 3912+40,X LDA 3872,X STA 3872+40,X LDA 3832,X STA 3832+40,X LDA 3792,X STA 3792+40,X LDA 3752,X STA 3752+40,X LDA 3712,X STA 3712+40,X LDA 3672,X STA 3672+40,X LDA 3632,X STA 3632+40,X LDA 3592,X STA 3592+40,X LDA 3552,X STA 3552+40,X LDA 3512,X STA 3512+40,X LDA 3472,X STA 3472+40,X LDA 3432,X STA 3432+40,X LDA 3392,X STA 3392+40,X LDA 3352,X STA 3352+40,X LDA 3312,X STA 3312+40,X LDA 3272,X STA 3272+40,X LDA 3232,X STA 3232+40,X LDA 3192,X STA 3192+40,X LDA 3152,X STA 3152+40,X LDA 3112,X STA 3112+40,X LDA 3072,X STA 3072+40,X DEX BEQ IRQ2SCROLL2 JMP IRQ2SCROLL1 IRQ2SCROLL2: JSR ENEMYUPDATE ; update enemy positions LDA LEVELDATAROW ; determine new block row, bottom or top INC LEVELDATAROW LSR BCS IRQ2DRAWTOP JMP IRQ2DRAWBOT IRQ2DRAWTOP: LDY #$00 ; draw new line (top row of 2x2 block) LDX #$01 IRQ2DRAWTOP1: LDA (LEVELDATAADDR),Y PHA ; ; block data is a one byte char indicating the bottom left character of the block ; the other three values are derived from that. ; ; each line is 16 bytes, 14 are line data, the remainder aeroplane initialisaion ; indicators ; ; new tank detection ; ; horizontal: ; tank type 1: $94 $95 ; $96 $97 ; ; tank type 2: $98 $99 ; $9a $9b ; ; vertical: ; tank type 1: $9c $9d ; $9e $9f ; ; tank type 2: $a0 $a1 ; $a2 $a3 ; CMP #$96 ; detect tank horizontal left type 1 BNE IRQ2DRAWTOP2 LDA #$01 STA TANKHORYC STX TANKHORXC STX TANKHORADDR LDA #$0C STA TANKHORADDR+1 LDA #0 STA TANKHORDIR BEQ IRQ2DRAWTOP5 IRQ2DRAWTOP2: CMP #$9A ; detect tank horizontal left type 2 (2=1?) BNE IRQ2DRAWTOP3 LDA #1 STA TANKHORYC+1 STX TANKHORXC+1 STX TANKHORADDR+2 LDA #$C STA TANKHORADDR+3 LDA #$80 STA TANKHORDIR+1 BEQ IRQ2DRAWTOP5 IRQ2DRAWTOP3: CMP #$9E ; detect tank vertical left type 1 BNE IRQ2DRAWTOP4 LDA #1 STA TANKVERYC STX TANKVERXC STX TANKVERADDR LDA #$C STA TANKVERADDR+1 LDA #0 STA TANKVERDIR BEQ IRQ2DRAWTOP5 IRQ2DRAWTOP4: CMP #$A2 ; detect tank vertical left type 2 BNE IRQ2DRAWTOP5 LDA #1 STA TANKVERYC+1 STX TANKVERXC+1 STX TANKVERADDR+2 LDA #$C STA TANKVERADDR+3 LDA #0 STA TANKVERDIR+1 IRQ2DRAWTOP5: PLA ; store new line character SEC SBC #2 STA 3072,X ; store block char - 2 (top left) CLC ADC #1 STA 3073,X ; store block char - 1 (top right) INX INX INY CPY #14 BCC IRQ2DRAWTOP1 LDA LEVELDATAADDR ; move up a line in level (+16) ADC #15 ; C=1 STA LEVELDATAADDR LDA LEVELDATAADDR+1 ADC #0 STA LEVELDATAADDR+1 CMP LEVELEND ; detect end of level screen BNE IRQEXIT1 LDA #0 ; turn off scrolling at end of level STA SCROLLSPEED BEQ IRQEXIT1 IRQ2DRAWBOT: LDY #0 ; draw new line (bottom row of 2x2 block) LDX #0 IRQ2DRAWBOT1: LDA (LEVELDATAADDR),Y STA 3073,X ; store block char (bottom left) CLC ADC #1 STA 3074,X ; store block char (bottom right) INX INX INY CPY #14 BCC IRQ2DRAWBOT1 LDA (LEVELDATAADDR),Y ; detect new planes (bytes 14 and 15 of line) BEQ IRQ2DRAWBOT2 STA PLANEXC STA PLANEADDR LDA #$0C STA PLANEADDR+1 LDA #2 STA PLANEYC LDA #0 STA PLANEIX STA PLDI LDA PTAB STA PLCT IRQ2DRAWBOT2: INY LDA (LEVELDATAADDR),Y BEQ IRQEXIT1 STA PLANEXC+1 STA PLANEADDR+2 LDA #$0C STA PLANEADDR+3 LDA #2 STA PLANEYC+1 LDA #0 STA PLANEIX+1 STA PLDI+1 LDA PTAB STA PLCT+1 IRQEXIT1: JSR SCROLLPANELUP ; reverse right panel characters IRQEXIT2: JSR BOMBS ; update bombs JSR BOMBDRAW ; draw bombs JSR PLAYERDRAW ; draw player JSR PLAYERCOLLIDE ; detect player dead JSR PICKUPWEAPON ; pick up player bonus weapon JSR SOUND ; make some noise PLA TAY PLA TAX PLA RTI ; RESTORE REGISTERS AND RETURN ;****************************************************************************** ; ; draw player ; ;****************************************************************************** PLAYERDRAW: LDX #15 ; save background graphics PLAYERDRAW1: LDA PLAYERINDEX,X TAY LDA (PLAYERADDR),Y STA PLAYERBACKGND,X DEX BPL PLAYERDRAW1 LDX #127 ; copy background bitmap LDY #15 STY T6 PLAYERDRAW2: LDA PLAYERBACKGND,Y JSR CALCADDRESS LDY #7 PLAYERDRAW3: LDA (T1),Y STA PLAYERCHAR,X DEX DEY BPL PLAYERDRAW3 DEC T6 LDY T6 BPL PLAYERDRAW2 LDX MDIS ; shift position? LDY #0 LDA PLAYERSTEPX AND #3 BEQ PLAYERDRAW4 LDY #192 PLAYERDRAW4: LDA #24 STA T1 PLAYERDRAW5: LDA PLAYERINVMAP,Y ; blit player graphic AND PLAYERCHAR,X ORA PLAYERBITMAP,Y STA PLAYERCHAR,X LDA PLAYERINVMAP+24,Y AND PLAYERCHAR+32,X ORA PLAYERBITMAP+24,Y STA PLAYERCHAR+32,X LDA PLAYERINVMAP+48,Y AND PLAYERCHAR+64,X ORA PLAYERBITMAP+48,Y STA PLAYERCHAR+64,X LDA PLAYERINVMAP+72,Y AND PLAYERCHAR+96,X ORA PLAYERBITMAP+72,Y STA PLAYERCHAR+96,X INX INY DEC T1 BNE PLAYERDRAW5 LDX #15 ; store player graphic LDA #$CF STA T1 PLAYERDRAW6: LDA PLAYERINDEX,X TAY LDA T1 STA (PLAYERADDR),Y DEC T1 DEX BPL PLAYERDRAW6 RTS ;****************************************************************************** ; ; scan keyboard/joy ; ; 7 6 5 4 3 2 1 0 (table index) ;----------------------------------------------------------------------------- ; 1 Ins/Del 3 5 7 9 Down Left 1 ; 2 Return w r y i p * Clr/Home ; 4 Pound a d g j l ; Control ; 8 Help/F7 4 6 8 0 Up Right 2 ; 16 F1/F4 z c b m . Escape Space ; 32 F2/F5 s f h k : = C= ; 64 F3/F6 e t u o - + q ;128 @ Shift x v n , / Run/Stop ; ;****************************************************************************** KEYSCAN: LDA #$FE LDX #$07 KEYSCAN1: STA $FD30 STA $FF08 TAY LDA $FF08 EOR #$FF STA KEYTABLE,X TYA SEC ROL DEX BPL KEYSCAN1 RTS ;****************************************************************************** ; ; move player ; ;****************************************************************************** PLAYERMOVE: LDA KEYTABLE+6 AND #16 ; get Z state STA T1 LDA KEYTABLE+5 AND #128 ; get X state ORA T1 CMP #128 BEQ RIGHT ; => only X pressed CMP #16 BEQ LEFT ; => only Z pressed LDA KEYTABLE+5 AND #8 BNE RIGHT ; => joy right LDA KEYTABLE+5 AND #4 BEQ RIG1 ; => not joy left LEFT: LDX PLAYERXC CPX #2 BCC RIG1 DEC PLAYERXC LDX PLAYERADDR BNE RIGH DEC PLAYERADDR+1 RIGH: DEC PLAYERADDR LDX #1 STX PLAYERSTEPX BNE RIG1 RIGHT: LDX PLAYERXC CPX #26 BCS RIG1 INC PLAYERXC LDX #2 STX PLAYERSTEPX RIG1: LDA KEYTABLE+1 AND #4 ; get ; state BNE UP2 LDA KEYTABLE+5 AND #1 ; get joy up BEQ UP1 UP2: LDY PLAYERYC CPY #16 BCC RIGEX JSR SUB4 LDY #1 STY MPHT RTS UP1: LDA KEYTABLE+1 AND #128 ; get / state BNE UP3 LDA KEYTABLE+5 AND #2 ; get joy down BEQ RIGEX UP3: LDY PLAYERYC CPY #20 BCS RIGEX JSR ADD4 LDY #2 STY MPHT RIGEX: RTS ;****************************************************************************** ; ; remove player and restore background ; ;****************************************************************************** PLAYERREMOVE: LDX #15 PLAYERREMOVE1: LDA PLAYERINDEX,X TAY LDA PLAYERBACKGND,X STA (PLAYERADDR),Y DEX BPL PLAYERREMOVE1 RTS ;****************************************************************************** ; ; calculate character address ; ; T1,T2 = $3800 + A * 8 ; ;****************************************************************************** CALCADDRESS: LDY #0 STY T2 ASL ROL T2 ASL ROL T2 ASL ROL T2 STA T1 LDA T2 ADC #$38 ;C=0 ($38=CBASE) STA T2 RTS ;****************************************************************************** ; ; adjust right panel character positions to account for vertical scroll position ; ; when using hardware scrolling the full screen will scroll. in the right ; panel characters are double height and scroll in the inverse direction ; within their bitmaps to counteract that movement to appear non moving. ; ;****************************************************************************** SCROLLPANELUP: LDA #7 SEC SBC SCR STA T1 LDX #0 JSR CLEARD ; clear up to line T1 JSR STORED ; store 8 bytes of data LDA #16 ; clear after last byte to end STA T1 CLEARD: LDA #0 CPX T1 BEQ ADJ3 ADJ2: STA $3E80,X ; 0 STA $3E90,X ; 1 STA $3EA0,X ; 2 STA $3EB0,X ; 3 STA $3EC0,X ; 4 STA $3ED0,X ; 5 STA $3EE0,X ; 6 STA $3EF0,X ; 7 STA $3F00,X ; 8 STA $3F10,X ; 9 STA $3F20,X ; S STA $3F30,X ; C STA $3F40,X ; O STA $3F50,X ; R STA $3F60,X ; E STA $3F70,X ; L STA $3F80,X ; I STA $3F90,X ; V STA $3FA0,X ; mini plane STA $3FB0,X ; T STA $3FC0,X ; M STA $3FD0,X ; A STA $3FE0,X ; ? STA $3FF0,X ; ? INX CPX T1 BCC ADJ2 ADJ3: RTS STORED: LDY #0 STO1: LDA $3740,Y ; 0 source STA $3E80,X ; 0 destination LDA $3748,Y STA $3E90,X LDA $3750,Y STA $3EA0,X LDA $3758,Y STA $3EB0,X LDA $3760,Y STA $3EC0,X LDA $3768,Y STA $3ED0,X LDA $3770,Y STA $3EE0,X LDA $3778,Y STA $3EF0,X LDA $3780,Y STA $3F00,X LDA $3788,Y STA $3F10,X LDA $3790,Y STA $3F20,X LDA $3798,Y STA $3F30,X LDA $37A0,Y STA $3F40,X LDA $37A8,Y STA $3F50,X LDA $37B0,Y STA $3F60,X LDA $37B8,Y STA $3F70,X LDA $37C0,Y STA $3F80,X LDA $37C8,Y STA $3F90,X LDA $37D0,Y STA $3FA0,X LDA $37D8,Y STA $3FB0,X LDA $37E0,Y STA $3FC0,X LDA $37E8,Y STA $3FD0,X LDA $37F0,Y STA $3FE0,X LDA $37F8,Y STA $3FF0,X INX INY CPY #8 BEQ STO2 JMP STO1 STO2: RTS ;****************************************************************************** ; ; update bombs ; ;****************************************************************************** BOMBS: LDX #14 ; index into bomb array addresses LDY #7 ; index into bomb tables BOMBS1: LDA TESTBIT,Y AND BOMBFLAGS BNE BOMB BOMBS2: DEX DEX DEY BPL BOMBS1 RTS BOMB: LDA SCROLLOVERFLOW ; adjust bomb for screen scrolling AND #8 BEQ BOMB1 LDA BOMBADDR,X CLC ADC #40 STA BOMBADDR,X BCC BOMB1 INC BOMBADDR+1,X BOMB1: CPY #4 BCC BOMBUP LDA IRQDIVISOR CMP #1 BNE FARBOMBLIMIT LDA SCR AND #1 BEQ BOMBUP FARBOMBLIMIT: JMP BOMBLIMIT BOMBUP: LDA BOMBDIR,Y AND #1 BEQ BOMBDOWN LDA BOMBYC,Y CMP #3 BCC BOMBCLEAR SBC #1 ;C=1 STA BOMBYC,Y LDA BOMBADDR,X SEC SBC #40 STA BOMBADDR,X BCS BOMBLEFT DEC BOMBADDR+1,X BOMBDOWN: LDA BOMBDIR,Y AND #2 BEQ BOMBLEFT LDA BOMBYC,Y CMP #23 BCS BOMBCLEAR ADC #1 ;C=0 STA BOMBYC,Y LDA BOMBADDR,X CLC ADC #40 STA BOMBADDR,X BCC BOMBLEFT INC BOMBADDR+1,X BOMBLEFT: LDA BOMBDIR,Y AND #4 BEQ BOMBRIGHT LDA BOMBXC,Y CMP #2 BCC BOMBCLEAR SBC #1 ;C=1 STA BOMBXC,Y LDA BOMBADDR,X SEC SBC #1 STA BOMBADDR,X BCS BOMBLIMIT DEC BOMBADDR+1,X BOMBRIGHT: LDA BOMBDIR,Y AND #8 BEQ BOMBLIMIT LDA BOMBXC,Y CMP #28 BCS BOMBCLEAR ADC #1 ;C=0 STA BOMBXC,Y LDA BOMBADDR,X CLC ADC #1 STA BOMBADDR,X BCC BOMBLIMIT INC BOMBADDR+1,X BOMBLIMIT: LDA BOMBADDR+1,X ; bug detect? CMP #$10 BCC FARBOMBS2 BOMBCLEAR: LDA CLEARBIT,Y AND BOMBFLAGS STA BOMBFLAGS FARBOMBS2: JMP BOMBS2 ;****************************************************************************** ; ; restore bomb background ; ;****************************************************************************** BOMBC: LDX #14 LDY #7 BOMBC1: LDA TESTBIT,Y AND BOMBFLAGS BEQ BOMBC2 LDA BOMBBACKGND,Y ; restore bomb backgnd if not... CMP #4 ; bomb type 1 BEQ BOMBC2 ; or CMP #5 ; bomb type 2 BEQ BOMBC2 STA (BOMBADDR,X) LDA BOMBADDR+1,X ; restore bomb backgnd colour PHA EOR #4 STA BOMBADDR+1,X LDA CHARCOLOR STA (BOMBADDR,X) PLA STA BOMBADDR+1,X BOMBC2: DEX DEX DEY BPL BOMBC1 RTS ;****************************************************************************** ; ; update enemies turrets/tanks/planes when screen has scrolled down 1 line. ; ; this adds 40 to be current address of each enemy and 1 to it's Y co-ord ; ;****************************************************************************** ENEMYUPDATE: LDY #3 LDX #6 ; turret update TURRETUPDATE: LDA TURRETYC,Y BEQ TANKUPDATE CLC ADC #1 CMP #22 BCC TURRETUPDATE2 LDA #0 STA TURRETYC,Y STX T1 STY T2 LDA TURDAT,Y ; close turret at screen bottom TAY LDX #0 TURRETUPDATE1: LDA TURRETCLOSED,X STA TURRETCHAR1,Y INY INX CPX #32 BCC TURRETUPDATE1 LDY T2 LDX T1 JMP TANKUPDATE TURRETUPDATE2: STA TURRETYC,Y LDA TURRETADDR,X CLC ADC #40 STA TURRETADDR,X BCC TANKUPDATE INC TURRETADDR+1,X ; tank update TANKUPDATE: LDA TANKHORYC,Y BNE TANKUPDATE1 LDA TANKALIVE,Y BNE TANKUPDATE2 BEQ PLANEUPDATE TANKUPDATE1: CLC ADC #1 STA TANKHORYC,Y CMP #24 BCC TANKUPDATE2 LDA #0 ; disable tank at screen bottom STA TANKHORYC,Y BEQ PLANEUPDATE TANKUPDATE2: LDA TANKHORADDR,X CLC ADC #40 STA TANKHORADDR,X BCC PLANEUPDATE INC TANKHORADDR+1,X ; plane update PLANEUPDATE: CPY #2 BCS ENEMYUPDATE1 ; => skip when >=2 as there are only 2 planes LDA PLANEYC,Y BNE PLANEUPDATE1 ; => plane alive LDA PLANEDEAD,Y BNE PLANEUPDATE3 ; => plane dying BEQ ENEMYUPDATE1 ; => plane dead PLANEUPDATE1: CLC ADC #1 CMP #24 BCC PLANEUPDATE2 LDA #0 ; plane leaving screen bottom STA PLANEYC,Y BEQ ENEMYUPDATE1 PLANEUPDATE2: STA PLANEYC,Y PLANEUPDATE3: LDA PLANEADDR,X CLC ADC #40 STA PLANEADDR,X BCC ENEMYUPDATE1 INC PLANEADDR+1,X ENEMYUPDATE1: DEX DEX DEY BMI ENEMYUPDATE2 JMP TURRETUPDATE ENEMYUPDATE2: RTS ;****************************************************************************** ; ; detect closed turret on lines 6 and 7 of display and activate ; ;****************************************************************************** TURRETDETECT: LDA SCR BNE TURRETDETECT5 LDX #27 TURRETDETECT1: LDA 3312,X ; look on line 6 for turrets CMP #$86 BEQ TURRETDETECT2 ; => turret 1 detected CMP #$8A BEQ TURRETDETECT2 ; => turret 2 detected CMP #$8E BEQ TURRETDETECT2 ; => turret 3 detected CMP #$92 BNE TURRETDETECT4 ; => turret 4 not detected TURRETDETECT2: SEC ; we have a new turret SBC #$86 LSR TAY TXA CLC ADC #<3272 STA TURRETADDR,Y LDA #>3272 ADC #0 STA TURRETADDR+1,Y TYA LSR TAY LDA #6 STA TURRETYC,Y STX TURRETXC,Y STX T7 LDA TURDAT,Y ; activate turret TAY LDX #0 TURRETDETECT3: LDA TURRETOPEN,X STA TURRETCHAR1,Y INY INX CPX #32 BCC TURRETDETECT3 LDX T7 TURRETDETECT4: DEX DEX BPL TURRETDETECT1 TURRETDETECT5: RTS ;****************************************************************************** ; ; turret fire ; ;****************************************************************************** TURRETFIRE: LDY TURRETTURN ; take turns to fire DEC TURRETTURN BPL TURRETFIRE1 LDA #3 STA TURRETTURN TURRETFIRE1: TYA ASL STA T6 LDX TURRETYC,Y BEQ TURRETFIRE2 LDA BOMBFLAGS AND TESTBIT+4,Y BNE TURRETFIRE2 STX BOMBYC+4,Y TXA LDX TURRETXC,Y STX BOMBXC+4,Y JSR PLAYERDIRECTION ; determine direction of player BEQ TURRETFIRE2 ; player above turret STA BOMBDIR+4,Y ; save direction JSR TURRETEYE ; move turret eye in direction of player LDA TEDTMR3H ; psuedo randomly choose when to fire CMP #128 BCC TURRETFIRE2 STY T5 ; init bomb LDY T6 LDX TURRETADDR,Y STX BOMBADDR+8,Y LDX TURRETADDR+1,Y STX BOMBADDR+9,Y LDY T5 ; mark bomb in use LDA BOMBFLAGS ORA TESTBIT+4,Y STA BOMBFLAGS TURRETFIRE2: RTS ;****************************************************************************** ; ; determine player direction from turret ; ; in: X=turret x coord ; A=turret y coord ; ; out: A bitmask 1= 2= 4= 8= ; ; check left/right or level ; ;****************************************************************************** PLAYERDIRECTION:PHA TXA LDX #0 ; no direction SEC SBC PLAYERXC BMI GETRIG CMP #2 BCC GETC LDX #4 !byte $2C ; BIT ABS (skip two bytes) GETRIG: LDX #8 GETC: PLA ; check up/down or level SEC SBC PLAYERYC BMI GETDWN CMP #2 BCS GETUP TXA ; level with turret RTS GETDWN: TXA ORA #2 RTS GETUP: TXA ORA #1 RTS ;****************************************************************************** ; ; move horizontal tanks ; ;****************************************************************************** TANKHORMOVE: LDX #2 LDY #1 TANKHORMOVE1: STY T3 LDA TANKHORYC,Y BNE TANKHORMOVE3 TANKHORMOVE2: DEX DEX LDY T3 DEY BPL TANKHORMOVE1 RTS TANKHORMOVE3: LDA TANKHORADDR,X STA T6 LDA TANKHORADDR+1,X STA T7 LDA TANKHORDIR,Y BMI TANKHORMOVE9 AND #64 BNE TANKHORMOVE6 LDY #2 ; detect tank stop LDA (T6),Y LDY T3 CMP #$4C BCS TANKHORMOVE4 CMP #$48 BCS TANKHORMOVE5 TANKHORMOVE4: LDA TANKHORDIR,Y ORA #64 STA TANKHORDIR,Y JMP TANKHORMOVE13 TANKHORMOVE5: LDA TANKHORDIR,Y ORA #128 STA TANKHORDIR,Y JMP TANKHORMOVE13 TANKHORMOVE6: LDA TANKHORXC,Y ; move tank right CLC ADC #1 STA TANKHORXC,Y INC TANKHORADDR,X BNE TANKHORMOVE7 INC TANKHORADDR+1,X TANKHORMOVE7: LDY #0 !byte $2C ; BIT ABS (skip two bytes) TANKHORMOVE8: LDY #2 LDA #$40 ; store horizontal tracks STA (T6),Y TYA CLC ADC #40 TAY LDA #$42 STA (T6),Y LDY T3 LDA TANKHORDIR,Y AND #128 STA TANKHORDIR,Y JMP TANKHORMOVE13 TANKHORMOVE9: AND #64 BNE TANKHORMOVE8 LDA TANKHORADDR,X SEC SBC #1 STA TANKHORMOVE10+1 LDA TANKHORADDR+1,X SBC #0 STA TANKHORMOVE10+2 TANKHORMOVE10: LDA $FFFF ; self modifying address CMP #$4C ; detect tank stop BCS TANKHORMOVE11 CMP #$48 BCS TANKHORMOVE12 TANKHORMOVE11: LDA TANKHORMOVE10+1 ; move tank left STA TANKHORADDR,X LDA TANKHORMOVE10+2 STA TANKHORADDR+1,X LDA TANKHORXC,Y SEC SBC #1 STA TANKHORXC,Y JMP TANKHORMOVE4 TANKHORMOVE12: LDA #0 STA TANKHORDIR,Y TANKHORMOVE13: LDA TANKHORADDR,X STA T1 LDA TANKHORADDR+1,X STA T2 LDA TANKHORDIR,Y AND #64 BEQ TANKHORMOVE14 LDY #0 ; tank horizonal shifted right 4 LDA #$20 STA (T1),Y INY LDA #$21 STA (T1),Y INY LDA #$22 STA (T1),Y LDY #40 LDA #$23 STA (T1),Y INY LDA #$24 STA (T1),Y INY LDA #$25 STA (T1),Y JMP TANKHORMOVE2 TANKHORMOVE14: LDY #0 ; tank horizontal fixed LDA #$94 STA (T1),Y INY LDA #$95 STA (T1),Y LDY #40 LDA #$96 STA (T1),Y INY LDA #$97 STA (T1),Y JMP TANKHORMOVE2 ;****************************************************************************** ; ; move vertical tanks ; ;****************************************************************************** TANKVERMOVE: LDX #2 LDY #1 TANKVERMOVE1: STY T3 LDA TANKVERYC,Y BNE TANKVERMOVE3 TANKVERMOVE2: DEX DEX LDY T3 DEY BPL TANKVERMOVE1 RTS TANKVERMOVE3: LDA TANKVERADDR,X STA T6 LDA TANKVERADDR+1,X STA T7 LDA TANKVERDIR,Y BMI TANKVERMOVE10 AND #64 BNE TANKVERMOVE6 LDY #80 ; detect tank stop LDA (T6),Y LDY T3 CMP #$4C BCS TANKVERMOVE4 CMP #$48 BCS TANKVERMOVE5 TANKVERMOVE4: LDA TANKVERDIR,Y ORA #64 STA TANKVERDIR,Y JMP TANKVERMOVE14 TANKVERMOVE5: LDA TANKVERDIR,Y ORA #128 STA TANKVERDIR,Y JMP TANKVERMOVE14 TANKVERMOVE6: LDA TANKVERYC,Y CLC ADC #1 CMP #24 BCS TANKVERMOVE9 STA TANKVERYC,Y LDA TANKVERADDR,X CLC ADC #40 STA TANKVERADDR,X BCC TANKVERMOVE7 INC TANKVERADDR+1,X TANKVERMOVE7: LDY #0 !byte $2C ; BIT ABS (skip two bytes) TANKVERMOVE8: LDY #80 LDA #$50 ; store vertical tracks STA (T6),Y INY LDA #$51 STA (T6),Y LDY T3 LDA TANKVERDIR,Y AND #128 STA TANKVERDIR,Y JMP TANKVERMOVE14 TANKVERMOVE9: LDA #0 STA TANKVERYC,Y JMP TANKVERMOVE2 TANKVERMOVE10: AND #64 BNE TANKVERMOVE8 LDA TANKVERADDR,X SEC SBC #40 STA TANKVERMOVE11+1 LDA TANKVERADDR+1,X SBC #0 STA TANKVERMOVE11+2 TANKVERMOVE11: LDA $FFFF ; self modifying address CMP #$4C ; detect tank stop BCS TANKVERMOVE12 CMP #$48 BCS TANKVERMOVE13 TANKVERMOVE12: LDA TANKVERMOVE11+1 ; move tank up STA TANKVERADDR,X LDA TANKVERMOVE11+2 STA TANKVERADDR+1,X LDA TANKVERYC,Y SEC SBC #1 BEQ TANKVERMOVE9 STA TANKVERYC,Y JMP TANKVERMOVE4 TANKVERMOVE13: LDA #0 STA TANKVERDIR,Y TANKVERMOVE14: LDA TANKVERADDR,X STA T1 LDA TANKVERADDR+1,X STA T2 LDA TANKVERDIR,Y AND #64 BEQ TANKVERMOVE15 LDY #0 ; tank vertical shifted down 4 LDA #$26 STA (T1),Y INY LDA #$27 STA (T1),Y LDY #40 LDA #$28 STA (T1),Y INY LDA #$29 STA (T1),Y LDY #80 LDA #$2A STA (T1),Y INY LDA #$2B STA (T1),Y JMP TANKVERMOVE2 TANKVERMOVE15: LDY #0 ; tank vertical fixed LDA #$9C STA (T1),Y INY LDA #$9D STA (T1),Y LDY #40 LDA #$9E STA (T1),Y INY LDA #$9F STA (T1),Y JMP TANKVERMOVE2 ;****************************************************************************** ; ; perform all aeroplane updates ; ;****************************************************************************** AEROPLANES: JSR PLANEDEADTIME JSR PLANEHORIZ JSR PLANEDOWN JSR PLANEDRAW JSR PLANECOLLIDE JSR PLANEBLIT1 JMP PLANEBLIT2 ;****************************************************************************** ; ; remove aeroplane and restore background ; ;****************************************************************************** PLANEREMOVE: LDY #0 LDX #0 JSR PLANEREMOVE1 LDY #1 LDX #2 PLANEREMOVE1: LDA PLANEDEAD,Y BNE PLANEREMOVE2 LDA PLANEYC,Y BEQ PLANEREMOVE4 ; => no plane active CMP #3 BCS PLANEREMOVE2 LDA PLDI,Y BEQ PLANEREMOVE4 ; => no plane active PLANEREMOVE2: LDA PLANEADDR,X STA T3 LDA PLANEADDR+1,X STA T4 LDA PLGD,Y STA T5 LDX #5 PLANEREMOVE3: LDY T5 LDA PLANEBACKGND,Y PHA LDA PLANEINDEX,X TAY PLA STA (T3),Y DEC T5 DEX BPL PLANEREMOVE3 PLANEREMOVE4: RTS ;****************************************************************************** ; ; move aeroplanes down ; ;****************************************************************************** PLANEDOWN: LDY #1 LDX #2 JSR PLANEDOWN1 LDY #0 LDX #0 PLANEDOWN1: LDA PLANEYC,Y BEQ PLANEDOWN3 ; => plane not active LDA PLDI,Y CLC ADC #3 PHA AND #7 STA PLDI,Y PLA AND #8 BEQ PLANEDOWN3 LDA PLANEYC,Y ; increment plane yc CLC ADC #1 CMP #24 BCC PLANEDOWN2 LDA #0 STA PLANEYC,Y BEQ PLANEDOWN3 ; => plane left the screen PLANEDOWN2: STA PLANEYC,Y LDA PLANEADDR,X CLC ADC #40 STA PLANEADDR,X BCC PLANEDOWN3 INC PLANEADDR+1,X PLANEDOWN3: RTS ;****************************************************************************** ; ; draw aeroplanes ; ;****************************************************************************** PLANEDRAW: LDY #1 LDX #2 JSR PLANEDRAW1 LDY #0 LDX #0 PLANEDRAW1: LDA PLANEYC,Y ORA PLANEDEAD,Y BEQ PLANEDRAW4 LDA PLANEADDR,X STA T4 LDA PLANEADDR+1,X STA T5 LDA PLCD,Y STA T3 LDA PLGD,Y STA T6 LDX #5 PLANEDRAW2: TXA LDA PLANEINDEX,X TAY LDA (T4),Y LDY T6 STA PLANEBACKGND,Y DEC T6 DEX BPL PLANEDRAW2 LDX #5 PLANEDRAW3: TXA LDA PLANEINDEX,X TAY LDA T3 STA (T4),Y DEC T3 DEX BPL PLANEDRAW3 PLANEDRAW4: RTS ;****************************************************************************** ; ; aeroplane 1 blit ; ;****************************************************************************** PLANEBLIT1: LDA PLANEYC ORA PLANEDEAD BEQ PLANEBLIT14 ; => plane not active LDX #47 ; copy background bitmap LDY #5 STY T6 PLANEBLIT11: LDA PLANEBACKGND,Y JSR CALCADDRESS LDY #7 PLANEBLIT12: LDA (T1),Y STA PLANECHAR1,X DEX DEY BPL PLANEBLIT12 DEC T6 LDY T6 BPL PLANEBLIT11 LDX PLDI LDY #0 LDA PLANEDEAD BNE PLANEDYING1 PLANEBLIT13: LDA PLANEINVMAP,Y AND PLANECHAR1,X ORA PLANEBITMAP,Y STA PLANECHAR1,X LDA PLANEINVMAP+16,Y AND PLANECHAR1+24,X ORA PLANEBITMAP+16,Y STA PLANECHAR1+24,X INX INY CPY #16 BCC PLANEBLIT13 PLANEBLIT14: RTS PLANEDYING1: LDA PLANEINVMAP,Y AND PLANECHAR1,X STA T1 LDA TEDTMR1L ORA #$AA STA T2 LDA PLANEINVMAP,Y EOR #$FF AND T2 ORA T1 STA PLANECHAR1,X LDA PLANEINVMAP+16,Y AND PLANECHAR1+24,X STA T1 LDA PLANEINVMAP+16,Y EOR #$FF AND T2 ORA T1 STA PLANECHAR1+24,X INX INY CPY #16 BCC PLANEDYING1 RTS ;****************************************************************************** ; ; aeroplane 2 blit ; ;****************************************************************************** PLANEBLIT2: LDA PLANEYC+1 ORA PLANEDEAD+1 BEQ PLANEBLIT24 LDX #47 LDY #5 STY T6 PLANEBLIT21: LDA PLANEBACKGND+6,Y JSR CALCADDRESS LDY #7 PLANEBLIT22: LDA (T1),Y STA PLANECHAR2,X DEX DEY BPL PLANEBLIT22 DEC T6 LDY T6 BPL PLANEBLIT21 LDX PLDI+1 LDY #0 LDA PLANEDEAD+1 BNE PLANEDYING2 PLANEBLIT23: LDA PLANEINVMAP,Y AND PLANECHAR2,X ORA PLANEBITMAP,Y STA PLANECHAR2,X LDA PLANEINVMAP+16,Y AND PLANECHAR2+24,X ORA PLANEBITMAP+16,Y STA PLANECHAR2+24,X INX INY CPY #16 BCC PLANEBLIT23 PLANEBLIT24: RTS PLANEDYING2: LDA PLANEINVMAP,Y AND PLANECHAR2,X STA T1 LDA TEDTMR3L ORA #$AA STA T2 LDA PLANEINVMAP,Y EOR #$FF AND T2 ORA T1 STA PLANECHAR2,X LDA PLANEINVMAP+16,Y AND PLANECHAR2+24,X STA T1 LDA PLANEINVMAP+16,Y EOR #$FF AND T2 ORA T1 STA PLANECHAR2+24,X INX INY CPY #16 BCC PLANEDYING2 RTS ;****************************************************************************** ; ; aeroplane collision detection ; ;****************************************************************************** PLANECOLLIDE: LDX #6 STX T6 LDY #3 STY T7 PLANECOLLIDE1: LDY T7 LDA BOMBFLAGS AND TESTBIT,Y BEQ PLANECOLLIDE3 LDX T6 LDA (BOMBADDR,X) CMP #$B4 BCC PLANECOLLIDE3 CMP #$C0 BCS PLANECOLLIDE3 LDY #0 CMP #$BA BCC PLANECOLLIDE2 INY PLANECOLLIDE2: LDA PLANEDEAD,Y BNE PLANECOLLIDE3 LDA #8 STA PLANEDEAD,Y LDA #0 STA PLANEYC,Y LDY T7 LDA CLEARBIT,Y AND BOMBFLAGS STA BOMBFLAGS LDA #0 SEC JSR SCOREUPDATE LDA #16 STA SOUNDBANG PLANECOLLIDE3: DEC T6 DEC T6 DEC T7 BPL PLANECOLLIDE1 RTS ;****************************************************************************** ; ; aeroplane dead time decrement ; ;****************************************************************************** PLANEDEADTIME: LDY #1 JSR PLANEDEADTIME1 LDY #0 PLANEDEADTIME1: LDA PLANEDEAD,Y BEQ PLANEDEADTIME2 SEC SBC #1 STA PLANEDEAD,Y PLANEDEADTIME2: RTS ;****************************************************************************** ; ; tank fire ; ;****************************************************************************** TANKFIRE: LDY TANKTURN DEC TANKTURN BPL TANKFIRE1 LDA #3 STA TANKTURN TANKFIRE1: TYA ASL STA T6 LDA TEDTMR3H CMP #128 BCS TANKFIRE2 LDX TANKHORYC,Y BEQ TANKFIRE2 LDA BOMBFLAGS AND TESTBIT+4,Y BNE TANKFIRE2 STX BOMBYC+4,Y TXA LDX TANKHORXC,Y STX BOMBXC+4,Y JSR PLAYERDIRECTION AND TBMA,Y BEQ TANKFIRE2 STA BOMBDIR+4,Y STY T5 LDY T6 LDX TANKHORADDR,Y STX BOMBADDR+8,Y LDX TANKHORADDR+1,Y STX BOMBADDR+9,Y LDY T5 LDA BOMBFLAGS ORA TESTBIT+4,Y STA BOMBFLAGS TANKFIRE2: RTS ;****************************************************************************** ; ; tank/turret collision detection ; ;****************************************************************************** TANKCOLLIDE: LDX #3 TANKCOLLIDE1: LDA TESTBIT,X STX T7 AND BOMBFLAGS BNE TANKCOLLIDE3 TANKCOLLIDE2: LDX T7 DEX BPL TANKCOLLIDE1 RTS TANKCOLLIDE3: TXA ASL TAX LDA (BOMBADDR,X) CMP #$20 BCC TANKCOLLIDE2 CMP #$2C BCC TANKCOLLIDE6 CMP #$94 BCC TANKCOLLIDE4 CMP #$A0 BCC TANKCOLLIDE5 TANKCOLLIDE4: JMP TURRETCOLLIDE TANKCOLLIDE5: SEC SBC #$68 TANKCOLLIDE6: SEC SBC #$20 TAY LDA TANKINDEX,Y STA T1 LDY #6 TANKCOLLIDE7: LDA TANKHORADDR,Y CLC ADC T1 STA T2 LDA #0 ADC TANKHORADDR+1,Y CMP BOMBADDR+1,X BNE TANKCOLLIDE8 LDA T2 CMP BOMBADDR,X BEQ TANKCOLLIDE9 TANKCOLLIDE8: DEY DEY BPL TANKCOLLIDE7 JMP TANKCOLLIDE2 TANKCOLLIDE9: TYA LSR TAX LDA TANKHORYC,X BEQ TANKCOLLIDE2 LDA #0 STA TANKHORYC,X TXA CLC ADC #$2C STA T6 LDA #10 STA TANKALIVE,X LDA TANKHORADDR,Y STA T1 LDA TANKHORADDR+1,Y STA T2 LDA TANKHORDIR,X AND #64 BEQ TANKCOLLIDE10 TXA AND #2 TAX LDA TKCLE,X TAY LDA TKCOD,X STA (T1),Y LDA TKCLE+1,X TAY LDA TKCOD+1,X STA (T1),Y TANKCOLLIDE10: LDY #0 LDA T6 STA (T1),Y INY STA (T1),Y LDY #40 STA (T1),Y INY STA (T1),Y CLC LDA #$10 JSR SCOREUPDATE LDA #16 STA SOUNDBANG JMP TURRETCOLLIDE3 FARTANKCOLLIDE2:JMP TANKCOLLIDE2 TURRETCOLLIDE: CMP #$84 BCC FARTANKCOLLIDE2 CMP #$94 BCS FARTANKCOLLIDE2 SEC SBC #$84 AND #$0C LSR TAX LSR TAY LDA TURRETYC,Y BEQ FARTANKCOLLIDE2 STY T3 LDA TURRETADDR,X STA T1 LDA TURRETADDR+1,X STA T2 LDA TEDTMR3L AND #7 CMP #5 BCS TURRETCOLLIDE1 TAY LDA CPICK,Y !byte $2C TURRETCOLLIDE1: LDA #12 LDY #0 STA (T1),Y INY CLC ADC #1 STA (T1),Y LDY #40 ADC #1 STA (T1),Y INY ADC #1 STA (T1),Y LDY T3 LDX #0 STX TURRETYC,Y LDA TURDAT,Y TAY TURRETCOLLIDE2: LDA TURRETCLOSED,X STA TURRETCHAR1,Y INY INX CPX #32 BCC TURRETCOLLIDE2 LDA #$50 CLC JSR SCOREUPDATE LDA #8 STA SOUNDBANG TURRETCOLLIDE3: LDX T7 LDA CLEARBIT,X AND BOMBFLAGS STA BOMBFLAGS LDA #210 STA SOUNDFIRE JMP TANKCOLLIDE2 ;****************************************************************************** ; ; draw bombs ; ;****************************************************************************** BOMBDRAW: LDX #14 LDY #7 BOMBDRAW1: LDA TESTBIT,Y AND BOMBFLAGS BEQ BOMBDRAW3 LDA (BOMBADDR,X) STA BOMBBACKGND,Y LDA #4 CPY #4 BCC BOMBDRAW2 LDA #5 BOMBDRAW2: STA (BOMBADDR,X) LDA BOMBADDR+1,X PHA EOR #4 STA BOMBADDR+1,X LDA BOMBCOLOR STA (BOMBADDR,X) PLA STA BOMBADDR+1,X BOMBDRAW3: DEX DEX DEY BPL BOMBDRAW1 RTS ;****************************************************************************** ; ; update score ; ;****************************************************************************** SCOREUPDATE: SED PHP CLC ADC SCORE STA SCORE PLA AND #1 ADC SCORE+1 STA SCORE+1 LDA #0 ADC SCORE+2 STA SCORE+2 CLD RTS ;****************************************************************************** ; ; display score ; ;****************************************************************************** SCOREDISPLAY: LDA #<3223 ; $97 STA T1 LDA #>3223 ; $0c STA T2 LDY #0 STY T3 LDY #40 STY T4 LDA SCORE+2 JSR BYTEDISPLAY LDA SCORE+1 JSR BYTEDISPLAY LDA SCORE BYTEDISPLAY: PHA LSR LSR LSR LSR JSR NIBBLEDISPLAY PLA AND #15 NIBBLEDISPLAY: ASL CLC ADC #$D0 LDY T3 STA (T1),Y CLC ADC #1 LDY T4 STA (T1),Y INC T3 INC T4 RTS ;****************************************************************************** ; ; tank dying ; ;****************************************************************************** TANKDYING: LDX #3 TANKDYING1: LDA TANKALIVE,X BNE TANKDYING3 ; => tank active TANKDYING2: DEX BPL TANKDYING1 RTS TANKDYING3: CMP #1 BNE TANKDYING4 TXA ASL TAY LDA TANKHORADDR,Y STA T1 LDA TANKHORADDR+1,Y STA T2 TXA AND #2 TAY LDA TKCOD,Y LDY #0 STA (T1),Y INY CLC ADC #1 STA (T1),Y LDY #40 ADC #1 STA (T1),Y INY ADC #1 STA (T1),Y JMP TANKDYING6 TANKDYING4: LDA #$39 STA T2 LDA EXTL,X STA T1 LDY #7 TANKDYING5: LDA TEDTMR3L ORA #$AA AND $3538,Y STA (T1),Y DEY BPL TANKDYING5 TANKDYING6: DEC TANKALIVE,X JMP TANKDYING2 ;****************************************************************************** ; ; move planes horizontally (left or right) ; ;****************************************************************************** PLANEHORIZ: LDY #1 LDX #2 JSR PLANEHORIZ1 LDY #0 LDX #0 PLANEHORIZ1: LDA PLANEYC,Y BEQ PLANEHORIZ6 ; => plane not active LDA PLCT,Y SEC SBC #1 STA PLCT,Y STX T1 LDX PLANEIX,Y LDA PLANEIXTAB,X BEQ PLANEHORIZ4 BMI PLANEHORIZ2 LDX T1 LDA PLANEADDR,X ; right CLC ADC #1 STA PLANEADDR,X BCC PLANEHORIZ3 INC PLANEADDR+1,X JMP PLANEHORIZ3 PLANEHORIZ2: LDX T1 LDA PLANEADDR,X ; left SEC SBC #1 STA PLANEADDR,X BCS PLANEHORIZ3 DEC PLANEADDR+1,X PLANEHORIZ3: LDX PLANEIX,Y LDA PLANEIXTAB,X CLC ADC PLANEXC,Y STA PLANEXC,Y PLANEHORIZ4: LDA PLCT,Y BNE PLANEHORIZ6 INX LDA PTAB,X BNE PLANEHORIZ5 LDX #0 LDA PTAB PLANEHORIZ5: STA PLCT,Y STX PLANEIX,Y PLANEHORIZ6: RTS ;****************************************************************************** ; ; move turret eye ; ;****************************************************************************** TURRETEYE: TAX LDA TURRETEYEIX,X STA TURRETEYE1+1 LDX TURDAT,Y LDA #31 STA T1 TURRETEYE1: LDA TURRETBITMAP STA TURRETCHAR1,X INC TURRETEYE1+1 INX DEC T1 BPL TURRETEYE1 RTS ;****************************************************************************** ; ; blink radar ; ;****************************************************************************** RADARBLINK: LDA SCR CMP #7 BNE RADARBLINK2 LDX #31 RADARBLINK1: LDA RADARBITMAP,X EOR $39E0,X STA $39E0,X LDA $3880,X EOR #$FF STA $3880,X LDA $38A0,X EOR #$FF STA $38A0,X LDA $38C0,X EOR #$FF STA $38C0,X LDA $38E0,X EOR #$FF STA $38E0,X DEX BPL RADARBLINK1 RADARBLINK2: RTS ;****************************************************************************** ; ;****************************************************************************** PLAYERFIRE: LDA KEYTABLE+6 AND #128 ; get shift state BNE PLAYERFIRE1 LDA KEYTABLE+5 AND #64 ; get joy fire BNE PLAYERFIRE1 RTS PLAYERFIRE1: LDA PLAYERFIREDIR AND #1 BEQ PLAYERFIRE2 LDA BOMBFLAGS AND #1 BNE PLAYERFIRE2 LDA #220 STA SOUNDFIRE LDA PLAYERADDR CLC ADC #41 STA BOMBADDR LDA PLAYERADDR+1 ADC #0 STA BOMBADDR+1 LDA PLAYERXC STA BOMBXC INC BOMBXC LDA PLAYERYC STA BOMBYC INC BOMBYC LDA #1 STA BOMBDIR LDA BOMBFLAGS ORA #1 STA BOMBFLAGS PLAYERFIRE2: LDA PLAYERFIREDIR AND #3 CMP #2 BNE PLAYERFIRE3 LDA BOMBFLAGS AND #3 BNE PLAYERFIRE3 LDA #220 STA SOUNDFIRE LDA PLAYERADDR CLC ADC #40 STA BOMBADDR LDA PLAYERADDR+1 ADC #0 STA BOMBADDR+1 LDA PLAYERADDR CLC ADC #42 STA BOMBADDR+2 LDA PLAYERADDR+1 ADC #0 STA BOMBADDR+3 LDA PLAYERXC STA BOMBXC CLC ADC #2 STA BOMBXC+1 LDA PLAYERYC STA BOMBYC INC BOMBYC STA BOMBYC+1 INC BOMBYC+1 LDA #1 STA BOMBDIR STA BOMBDIR+1 LDA BOMBFLAGS ORA #3 STA BOMBFLAGS PLAYERFIRE3: LDA PLAYERFIREDIR AND #3 CMP #3 BNE PLAYERFIRE5 LDA BOMBFLAGS AND #2 BNE PLAYERFIRE5 INC PLAYERFIRESWAP LDA PLAYERFIRESWAP LSR LDA #40 BCS PLAYERFIRE4 LDA #42 PLAYERFIRE4: TAX CLC ADC PLAYERADDR STA BOMBADDR+2 LDA PLAYERADDR+1 ADC #0 STA BOMBADDR+3 TXA SEC SBC #40 TAX CLC ADC PLAYERXC STA BOMBXC+1 LDA PLAYERYC STA BOMBYC+1 INC BOMBYC+1 LDA DIAG,X STA BOMBDIR+1 LDA BOMBFLAGS ORA #2 STA BOMBFLAGS PLAYERFIRE5: LDA PLAYERFIREDIR AND #$0C BEQ PLAYERFIRE7 LDA BOMBFLAGS AND #$0C BNE PLAYERFIRE7 LDA PLAYERFIREDIR AND #$0C LDX #0 CMP #4 BEQ PLAYERFIRE6 LDA PLAYERYC CMP #17 BCS PLAYERFIRE7 LDX #2 PLAYERFIRE6: LDA PLAYERADDR CLC ADC #40 STA BOMBADDR+4 LDA PLAYERADDR+1 ADC #0 STA BOMBADDR+5 LDA PLAYERADDR CLC ADC #42 STA BOMBADDR+6 LDA PLAYERADDR+1 ADC #0 STA BOMBADDR+7 LDA PLAYERXC STA BOMBXC+2 CLC ADC #2 STA BOMBXC+3 LDA PLAYERYC STA BOMBYC+2 INC BOMBYC+2 STA BOMBYC+3 INC BOMBYC+3 LDA EXTRA,X STA BOMBDIR+2 LDA EXTRA+1,X STA BOMBDIR+3 LDA BOMBFLAGS ORA #$0C STA BOMBFLAGS PLAYERFIRE7: RTS ;****************************************************************************** ; ; pick up player bonus weapon (when fire pressed and above) ; ;****************************************************************************** PICKUPWEAPON: LDA KEYTABLE+6 AND #128 ; get shift state BNE PICKUPWEAPON1 LDA KEYTABLE+5 AND #64 ; get joy fire BEQ PICKUPWEAPON2 PICKUPWEAPON1: LDX #2 JSR PICKUPWEAPON3 LDX #6 JSR PICKUPWEAPON3 LDA PLAYERSTEPX AND #3 BEQ PICKUPWEAPON2 LDX #10 JSR PICKUPWEAPON3 PICKUPWEAPON2: RTS PICKUPWEAPON3: LDA PLAYERBACKGND,X CMP #$10 BCC PICKUPWEAPON2 ; => less than first bonus gfx CMP #$20 BCS PICKUPWEAPON2 ; => greater than last bonus gfx TAY AND #3 BNE PICKUPWEAPON2 TYA CLC ADC #1 CMP PLAYERBACKGND+4,X BNE PICKUPWEAPON2 ADC #0 CMP PLAYERBACKGND+1,X BNE PICKUPWEAPON2 ADC #0 CMP PLAYERBACKGND+5,X BNE PICKUPWEAPON2 AND #15 LSR LSR TAY LDA PLAYERFIREDIR AND GUN1,Y ORA GUN2,Y STA PLAYERFIREDIR LDA #12 STA PLAYERBACKGND,X LDA #13 STA PLAYERBACKGND+4,X LDA #14 STA PLAYERBACKGND+1,X LDA #15 STA PLAYERBACKGND+5,X LDA #32 STA SOUNDFREQ PLA PLA RTS ;****************************************************************************** ; ; player collision detection ; ;****************************************************************************** PLAYERCOLLIDE: LDX #4 LDA MDIS CMP #4 BCC PLAYERCOLLIDE1 INX PLAYERCOLLIDE1: STX T1 JSR PLAYERCOLLIDE3 LDA PLAYERSTEPX AND #1 BEQ PLAYERCOLLIDE2 LDA T1 CLC ADC #4 TAX JSR PLAYERCOLLIDE3 PLAYERCOLLIDE2: RTS PLAYERCOLLIDE3: LDY #2 PLAYERCOLLIDE4: LDA PLAYERBACKGND,X CMP #5 BEQ PLAYERCOLLIDE8 CMP #$C0 BCS PLAYERCOLLIDE5 CMP #$B4 BCS PLAYERCOLLIDE6 PLAYERCOLLIDE5: INX DEY BPL PLAYERCOLLIDE4 RTS PLAYERCOLLIDE6: LDY #0 CMP #$BA BCC PLAYERCOLLIDE7 INY PLAYERCOLLIDE7: LDA PLANEDEAD,Y BNE PLAYERCOLLIDE9 PLAYERCOLLIDE8: LDA #0 STA PLAYERALIVE PLA PLA PLAYERCOLLIDE9: RTS ;****************************************************************************** ; ; decrement player life ; ;****************************************************************************** PLAYERLIFEDEC: ; LDA #0 ; RTS LDX PLAYERLIVES LDA PLAYERPANELTAB,X TAY LDA #0 STA 3462,Y ; $0d86 STA 3502,Y ; $0dae DEX STX PLAYERLIVES RTS ;****************************************************************************** ; ; initialise player ; ;****************************************************************************** PLAYERINIT: LDX #1 STX PLAYERALIVE STX PLAYERFIREDIR DEX STX PLAYERFIRESWAP STX PLAYERSTEPX STX MPHT LDA #7 SEC SBC SCR STA MDIS LDX #20 STX PLAYERYC LDX #14 STX PLAYERXC LDX #<3886 STX PLAYERADDR LDX #>3886 STX PLAYERADDR+1 LDA #210 STA SOUNDFIRE LDA #0 STA SOUNDBANG STA SOUNDFREQ RTS ;****************************************************************************** ; ; time delays ; ;****************************************************************************** DELAY: LDX #0 LDY #0 DELAY1: DEY BNE DELAY1 DEX BNE DELAY1 SEC SBC #1 BNE DELAY1 RTS DELAY2: LDX #0 LDY #0 DELAY3: DEY BNE DELAY3 DEX BNE DELAY3 RTS ;****************************************************************************** ; ; pause action ; ;****************************************************************************** PAUSE: SEI PAUSE1: JSR KEYSCAN LDA KEYTABLE AND #8 ; get 2 state BEQ PAUSE1 LDA #2 STA $FF09 ; I-RAS=1 CLI RTS ;****************************************************************************** ; ; plane fire ; ;****************************************************************************** PLANEFIRE: LDY #1 ; plane 1 LDX #2 JSR PLANEFIRE1 LDY #0 ; plane 0 LDX #0 PLANEFIRE1: LDA PLANEYC,Y BEQ PLANEFIRE2 ; => plane not active LDA TESTBIT+4,Y AND BOMBFLAGS BNE PLANEFIRE2 ; => bomb in use LDA PLDI,Y CMP #7 BCC PLANEFIRE2 ; => pseudo random fire? LDA #2 STA BOMBDIR+4,Y ; fire downwards LDA PLANEXC,Y ; init bomb position STA BOMBXC+4,Y LDA PLANEYC,Y STA BOMBYC+4,Y LDA PLANEADDR,X CLC ADC #80 STA BOMBADDR+8,X LDA PLANEADDR+1,X ADC #0 STA BOMBADDR+9,X LDA TESTBIT+4,Y ; mark bomb in use ORA BOMBFLAGS STA BOMBFLAGS PLANEFIRE2: RTS ;****************************************************************************** ; ; ;****************************************************************************** EXTRA: !byte 4,8,6,10 ; player life indicator (right panel) PLAYERPANELTAB: !byte 4,2,6,0,8 DIAG: !byte 5,0,9 GUN1: !byte $C,$C,$3,$3 GUN2: !byte 2, 3, 4, 8 TANKINDEX: !byte 0,1,2,40,41,42 !byte 0,1,40,41,80,81 !byte 0,1,40,41 !byte 0,1,40,41 !byte 0,1,40,41 EXTL: !byte $60,$68,$70,$78 PLANEINDEX: !byte 0,40,80,1,41,81 PLCD: !byte $B9,$BF TURDAT: !byte 0,32,64,96 TEDINIT: !byte $07 ;FF06 !byte $98 ;FF07 MCM MODE !byte $00 ;FF08 KEYBOARD !byte $00 ;FF09 !byte $02 ;FF0A ENABLE I-RAS? !byte $C8 ;FF0B RASTER COUNTER !byte 255,255 ;FF0C/FF0D CURSOR !byte 0,0,0,0 ;FF0E/FF0F/FF10/FF11 SOUND !byte $C8 ;FF12 BMB0=1,R-BANK=0 !byte $38 ;FF13 CBASE=$3800 !byte $08 ;FF14 VM0=1 !byte $00 ;FF15 BKGD0 COLOR (BACKGROUND COLOR: MCM 00) !byte $0E ;FF16 BKGD1 COLOR (MCM: 01) !byte $09 ;FF17 BKGD2 COLOR (MCM: 10) !byte $00 ;FF18 BKGD3 COLOR !byte $00 ;FF19 BKGD4 COLOR (BORDER COLOR) ; player indexes (4x4 = 32x32 bitmap, 24x24 visible) PLAYERINDEX: !byte 0,40,80,120,1,41,81,121 !byte 2,42,82,122,3,43,83,123 PLGD: !byte 5,11 TKCLE: !byte 2,42,80,81 TKCOD: !byte $40,$42,$50,$51 TBMA: !byte $02,$02,$0C,$0C TESTBIT: !byte $01,$02,$04,$08,$10,$20,$40,$80 CLEARBIT: !byte $FE,$FD,$FB,$F7,$EF,$DF,$BF,$7F CPICK: !byte $C,$10,$14,$18,$1C PTAB: !byte 10,8,10,8,0 PLANEIXTAB: !byte 1,0,255,0 ; eye (character) indexes TURRETEYEIX: !byte $00,$00,$80,$00,$C0,$E0,$A0,$00 !byte $40,$20,$60,$00,$00,$00,$00,$00 ;****************************************************************************** ; ; ;****************************************************************************** SOUNDNOISE: LDX #0 STX T0 ASL ROL T0 ASL ROL T0 STA $FF0F LDA T0 STA $FF10 LDA #$48 ORA $FF11 STA $FF11 RTS ;****************************************************************************** ; ; ;****************************************************************************** SOUNDTONE: LDX #0 STX T0 ASL ROL T0 ASL ROL T0 STA $FF0E LDA $FF12 AND #$FC ORA T0 STA $FF12 LDA #$18 ORA $FF11 STA $FF11 RTS ;****************************************************************************** ; ; ;****************************************************************************** SOUND: LDA SOUNDFREQ BEQ SOUND1 JSR SOUNDTONE LDA SOUNDFREQ CLC ADC #16 STA SOUNDFREQ LDA SOUNDFIRE CMP #210 BNE SOUND2 BEQ SOUND4 SOUND1: LDA SOUNDFIRE CMP #210 BEQ SOUND3 JSR SOUNDTONE SOUND2: DEC SOUNDFIRE JMP SOUND4 SOUND3: LDA #$EF AND $FF11 STA $FF11 SOUND4: LDA SOUNDBANG BEQ SOUND5 JSR SOUNDNOISE DEC SOUNDBANG RTS SOUND5: LDA #$BF AND $FF11 STA $FF11 RTS ;****************************************************************************** ; ; position player ; ;****************************************************************************** PLAYERPOS: LDA PLAYERSTEPX BEQ MVEM1 AND #2 BEQ MVEM2 INC PLAYERADDR BNE MVEM2 INC PLAYERADDR+1 MVEM2: LDA #0 STA PLAYERSTEPX MVEM1: LDA MPHT BEQ MVEM9 LDY #0 STY MPHT AND #2 BNE ADD4 ; adjust player position to account for vertical scroll position? SUB4: LDA MDIS SEC SBC #4 TAY AND #7 STA MDIS TYA BPL MVEM9 DEC PLAYERYC LDA PLAYERADDR SEC SBC #40 STA PLAYERADDR BCS MVEM9 DEC PLAYERADDR+1 MVEM9: RTS ADD4: LDA MDIS CLC ADC #4 TAY AND #7 STA MDIS CPY #8 BCC MVEM9 INC PLAYERYC LDA PLAYERADDR CLC ADC #40 STA PLAYERADDR BCC MVEM9 INC PLAYERADDR+1 RTS ;****************************************************************************** ; ; player dead colours and sound ; ;****************************************************************************** DEATH: LDA #0 STA T7 LDA $FF16 PHA LDA $FF17 PHA DEA1: JSR PLAYERDYING LDA T7 STA $FF17 STA $FF16 JSR SOUNDNOISE DEC T7 BNE DEA1 LDA #0 STA $FF11 PLA STA $FF17 PLA STA $FF16 RTS ;****************************************************************************** ; ; player dead random bitmap ; ;****************************************************************************** PLAYERDYING: LDX MDIS LDY #0 LDA PLAYERSTEPX AND #3 BEQ PLAYERDYING1 LDY #192 PLAYERDYING1: LDA #24 STA T1 PLAYERDYING2: LDA PLAYERINVMAP,Y AND PLAYERCHAR,X STA T3 LDA PLAYERINVMAP,Y EOR #$FF AND TEDTMR3L ORA T3 STA PLAYERCHAR,X LDA PLAYERINVMAP+24,Y AND PLAYERCHAR+32,X STA T3 LDA PLAYERINVMAP+24,Y EOR #$FF AND TEDTMR3L ORA T3 STA PLAYERCHAR+32,X LDA PLAYERINVMAP+48,Y AND PLAYERCHAR+64,X STA T3 LDA PLAYERINVMAP+48,Y EOR #$FF AND TEDTMR3L ORA T3 STA PLAYERCHAR+64,X LDA PLAYERINVMAP+72,Y AND PLAYERCHAR+96,X STA T3 LDA PLAYERINVMAP+72,Y EOR #$FF AND TEDTMR3L ORA T3 STA PLAYERCHAR+96,X INX INY DEC T1 BNE PLAYERDYING2 RTS ;****************************************************************************** ; ; draw title screen - wait for space bar to play ; ;****************************************************************************** DRAWTITLESCN: JSR TITLEINIT JSR DRAWTITLE ; prepare text title screen DRAWTITLESCN1: INC T0 ; wait for raster here WAITRAS: LDA $ff0b CMP #230 ; probably in vertical blank, can't remember BCS WAITRAS LDA T0 AND #1 BNE DRAWTITLESCN2 ;text active JSR TEXTFLIP LDA #5 ; delay long JMP WAITSPACE ;graphics active DRAWTITLESCN2: JSR GRAPHICSFLIP LDA #2 ; delay short WAITSPACE: STA T1 LDX #0 LDY #0 WAITSPACE2: LDA #$7F ; wait for space bar press STA $FD30 STA $FF08 LDA $FF08 AND #16 BEQ WAITOVER ; =>space pressed (Z=TRUE) DEX BNE WAITSPACE2 DEY BNE WAITSPACE2 DEC T1 BNE WAITSPACE2 JMP DRAWTITLESCN1 WAITOVER: RTS ;****************************************************************************** ;text (changes): ; FF06=$1b ; FF12=$c8 ; FF14=$08 ; FF15=$06 ; FF16=$36 ; FF19=$06 ;****************************************************************************** TEXTFLIP: LDA #$1b STA $ff06 LDA #$c8 STA $ff12 LDA #$08 STA $ff14 LDA #$06 STA $ff15 LDA #$36 STA $ff16 LDA #$06 STA $ff19 RTS ;****************************************************************************** ;graphic (changes): ; ;2007: ; $7800/$7FE7 colour+luminance ; $8000/$9F3F bitmap ;2009: ; $B800/$BFE7 colour+luminance ; $C000/$DF3F bitmap ; ; FF06=$3B (BMM ON) ; FF12=$20/$30 (BMB2 BMB1 BMB0) ; xx00 0xxx = $0000 ? ; xx00 1xxx = $2000 ; xx01 0xxx = $4000 ; xx01 1xxx = $6000 ; xx10 0xxx = $8000 ; xx10 1xxx = $a000 ; xx11 0xxx = $c000 ; xx11 1xxx = $e000 ; FF14=$78/$B8 (COLOR MAP HIGH BYTE ADDRESS) ; FF15=$80 ; FF16=$E1 ; FF19=$80 ;****************************************************************************** GRAPHICSFLIP: LDA #$3b STA $ff06 LDA #$30 ;$C000 STA $ff12 LDA #$B8 ;$B800 STA $ff14 LDA #$80 STA $ff15 LDA #$e1 STA $ff16 LDA #$80 STA $ff19 RTS ;****************************************************************************** ; ; draw title screen in video ram ; ;****************************************************************************** DRAWTITLE: LDY #0 STY TA DRAWTITLE1: LDA TITLESCREEN,Y STA T1 LDA TITLESCREEN+1,Y STA T2 LDA TITLESCREEN+2,Y TAX LDA #$40 JSR DRAWBOX LDY TA LDA TITLESCREEN+3,Y TAX JSR PRINT LDA TA CLC ADC #4 STA TA TAY CPY #32 BCC DRAWTITLE1 LDA LEVEL ORA #$60 STA 4023 LDA #<3126 STA T1 LDA #>3126 STA T2 LDA PREVSCORE + 2 LDX PREVSCORE + 1 LDY PREVSCORE JSR PRINTBCD LDA #<3137 STA T1 LDA #>3137 STA T2 LDA HIGHSCORE + 2 LDX HIGHSCORE + 1 LDY HIGHSCORE JMP PRINTBCD ;****************************************************************************** ; ; initialise title screen ; ;****************************************************************************** TITLEINIT: LDX #19 TITLEINIT1: LDA TITLETED,X STA $FF06,X DEX BPL TITLEINIT1 LDX #0 TITLEINIT2: LDA #CLEARCHAR STA $C00,X STA $D00,X STA $E00,X STA $F00,X LDA #LOADBACKGNDCOL STA $800,X STA $900,X STA $A00,X STA $B00,X INX BNE TITLEINIT2 RTS ;****************************************************************************** ; ; copy text onto screen ; ;****************************************************************************** PRINT: LDY #0 PRINT1: LDA MSGADDR,X BEQ PRINT2 STA (T1),Y INX INY BNE PRINT1 PRINT2: RTS ;****************************************************************************** ; ; draw a box? ; ; A=box character ; X=box width ; Y=box address offset ; T1,T2=box address ; ;****************************************************************************** DRAWBOX: LDY #0 STY T3 STA T4 ;draw top and bottom DRAWBOX1: STA (T1),Y TYA CLC ADC #80 TAY LDA T4 STA (T1),Y INC T3 LDY T3 DEX BPL DRAWBOX1 ; draw right TYA CLC ADC #39 TAY LDA T4 STA (T1),Y ; draw left LDY #40 STA (T1),Y ; prepare text address LDA T1 CLC ADC #41 STA T1 LDA T2 ADC #0 STA T2 RTS ;****************************************************************************** ; ; draw flashing box with flashing text ; ; X=box width ; Y=text message offset for print ; TA,TB=screen address ; ;****************************************************************************** DRAWFLASH: STX T5 STY T6 LDA #8 STA T7 DRAWFLASH1: LDA TA STA T1 LDA TB STA T2 LDX T5 LDA #$5B JSR DRAWBOX LDX T6 JSR PRINT JSR DELAY2 LDA TA STA T1 LDA TB STA T2 LDX T5 LDA #$40 JSR DRAWBOX JSR DELAY2 DEC T7 BNE DRAWFLASH1 RTS ;****************************************************************************** ; ; write 24 bit BCD on screen ; ;****************************************************************************** PRINTBCD: STY T7 LDY #0 JSR PRINTBCD1 TXA JSR PRINTBCD1 LDA T7 PRINTBCD1: PHA LSR LSR LSR LSR ORA #$60 STA (T1),Y INY PLA AND #15 ORA #$60 STA (T1),Y INY RTS ;****************************************************************************** ; ; draw game right panel ; ;****************************************************************************** RIGHTPANEL: LDA #$B ; blank screen STA $FF06 LDX #0 RIGHTPANEL1: LDA #0 STA $C00,X ; screen memory STA $D00,X STA $E00,X STA $F00,X LDA #GAMEBACKGNDCOL STA $800,X ; color memory STA $900,X STA $A00,X STA $B00,X INX BNE RIGHTPANEL1 LDA #<$846 STA T1 STA T3 LDA #>$846 STA T2 EOR #4 STA T4 LDA #PANELDATA STA T6 LDA #0 STA T0 LDX #11 RIGHTPANEL2: LDA #$37 LDY #9 BORD1: STA (T1),Y DEY BPL BORD1 LDY #49 BORD2: STA (T1),Y DEY CPY #40 BCS BORD2 LDA #0 STA T7 ZEROIZ: LDY T0 LDA (T5),Y INC T0 CMP #1 BEQ ZESKIP LDY T7 STA (T3),Y INC T7 PHA TYA CLC ADC #40 TAY PLA ORA #1 STA (T3),Y LDY T7 CPY #10 BCC ZEROIZ ZESKIP: LDA T1 CLC ADC #80 STA T1 STA T3 LDA T2 ADC #0 STA T2 EOR #4 STA T4 DEX BPL RIGHTPANEL2 LDA LEVEL ASL CLC ADC #$D0 STA 3706 ADC #1 STA 3746 LDY PLAYERLIVES CPY #5 BCC PUTLIVES LDY #4 STY PLAYERLIVES PUTLIVES: LDA LIFETABLE,Y TAX LDA #$F4 STA 3462,X LDA #$F5 STA 3502,X DEY BPL PUTLIVES RTS ;****************************************************************************** ; ; game right panel data ; ;****************************************************************************** PANELDATA: !byte 0,0,$E4,$E6,$E8,$EA,$EC,1 !byte 0,$D0,$D0,$D0,$D0,$D0,$D0,$D0,1 !byte 1 !byte 0,0,$EE,$F0,$F2,$EC,$E4,1 !byte 1 !byte 1 !byte 0,0,$EE,$EC,$F2,$EC,$EE,1 !byte 1 !byte 1 !byte 1 !byte 0,$F6,$E8,$F8,$E6,$FA,$F6,1 !byte 1 LIFETABLE: !byte 4,2,6,0,8 ;****************************************************************************** ; ; title screen data ; ;****************************************************************************** TITLESCREEN: !word 3408 !byte 7, MSGTOMCAT - MSGADDR !word 3480 !byte 23, MSGCOPY - MSGADDR !word 3593 !byte 37, MSGDMB - MSGADDR !word 3079 !byte 6, MSGSCORE - MSGADDR !word 3093 !byte 3, MSGHI - MSGADDR !word 3085 !byte 8, MSGLINE - MSGADDR !word 3096 !byte 8, MSGLINE - MSGADDR !word 3959 !byte 25, MSGPRESSSPACE - MSGADDR TITLETED: !byte $1b ;FF06 !byte $18 ;FF07 MCM MODE !byte $00 ;FF08 KEYBOARD !byte $00 ;FF09 !byte $02 ;FF0A ENABLE I-RAS? !byte $C8 ;FF0B RASTER COUNTER !byte 255,255 ;FF0C/FF0D CURSOR !byte 0,0,0,0 ;FF0E/FF0F/FF10/FF11 SOUND !byte $C8 ;FF12 BMB0=1,R-BANK=0 !byte TITLEBASE ;FF13 CBASE !byte $08 ;FF14 VM0=1 !byte $06 ;FF15 BKGD0 COLOR (BACKGROUND COLOR: MCM 00) !byte $36 ;FF16 BKGD1 COLOR (MCM: 01) !byte $16 ;FF17 BKGD2 COLOR (MCM: 10) !byte $00 ;FF18 BKGD3 COLOR !byte $06 ;FF19 BKGD4 COLOR (BORDER COLOR) MSGADDR: MSGLOADING: !raw "LOADING",$00 MSGLEVEL: !raw "LEVEL",$40,$00 MSGERROR: !raw "ERROR",$40,"IN",0 MSGREWIND: !raw $40,"REWIND",$40,0 MSGTOMCAT: !raw "TOMCAT",0 MSGCOPY: !raw "COPYRIGHT",$40,"PLAYERS",$40,$61,$69,$68,$69,0 MSGDMB: !raw "THIS",$40,"VERSION",$40,"CODED",$40,"BY",$40,"DARRON",$40 !raw "M",$40,"BROAD",0 MSGSCORE: !raw "SCORE",0 MSGHI: !raw "HI",0 MSGLINE: !word $6060,$6060,$6060 !byte $60,0 MSGPRESSSPACE: !raw "PRESS",$40,"SPACE",$40,"FOR",$40,$40,"LEVEL",$40,0 MSGWELLDONE: !raw "WELL",$40,"DONE",0 ;****************************************************************************** ; ; graphics and level data ; ;****************************************************************************** ; * = $3400 !bin "graphicsh.bin",,2 ;$4200 * = TITLEBASE * 256 + $200 !bin "graphicsl.bin",,2 ; * = $4400 !bin "level1.bin",,2 * = $5400 !bin "level2.bin",,2 * = $6400 ; !bin "level3.bin",,2 * = $7400 ; !bin "level4.bin",,2 * = $8400 ; !bin "level5.bin",,2 * = $9400 ; !bin "level6.bin",,2 * = $a400 ; !bin "level7.bin",,2 ; ; TITLE GRAPHICS * = $b800 !bin "titlecol.bin" * = $c000 !bin "titlebmp.bin"