LIST OFF ; *** L A S E R B L A S T *** ; Copyright 1981 Activision, Inc. ; Designer: David Crane ; Analyzed, labeled and commented ; by Dennis Debro ; Last Update: August 9, 2019 ; ; *** 122 BYTES OF RAM USED 6 BYTES FREE ; *** 1 BYTE OF ROM FREE ; ; ============================================================================== ; = THIS REVERSE-ENGINEERING PROJECT IS BEING SUPPLIED TO THE PUBLIC DOMAIN = ; = FOR EDUCATIONAL PURPOSES ONLY. THOUGH THE CODE WILL ASSEMBLE INTO THE = ; = EXACT GAME ROM, THE LABELS AND COMMENTS ARE THE INTERPRETATION OF MY OWN = ; = AND MAY NOT REPRESENT THE ORIGINAL VISION OF THE AUTHOR. = ; = = ; = THE ASSEMBLED CODE IS © 1981, ACTIVISION = ; = = ; ============================================================================== ; ; - 1 ROM byte free but there is room for more code optimizations ; - looks as though a LeadShip laser delay was going to be implemented ; - Added PAL60 switch to make for an easy PAL60 conversion ; - PAL50 version ~17% slower than NTSC processor 6502 include "tia_constants.h" include "vcs.h" include "macro.h" ; ; Make sure we are using vcs.h version 1.05 or greater. ; IF VERSION_VCS < 105 echo "" echo "*** ERROR: vcs.h file *must* be version 1.05 or higher!" echo "*** Updates to this file, DASM, and associated tools are" echo "*** available at https://dasm-assembler.github.io/" echo "" err ENDIF ; ; Make sure we are using macro.h version 1.01 or greater. ; IF VERSION_MACRO < 101 echo "" echo "*** ERROR: macro.h file *must* be version 1.01 or higher!" echo "*** Updates to this file, DASM, and associated tools are" echo "*** available at https://dasm-assembler.github.io/" echo "" err ENDIF LIST ON ;=============================================================================== ; A S S E M B L E R - S W I T C H E S ;=============================================================================== NTSC = 0 PAL50 = 1 PAL60 = 2 TRUE = 1 FALSE = 0 IFNCONST COMPILE_REGION COMPILE_REGION = NTSC ; change to compile for different regions ENDIF IF !(COMPILE_REGION = NTSC || COMPILE_REGION = PAL50 || COMPILE_REGION = PAL60) echo "" echo "*** ERROR: Invalid COMPILE_REGION value" echo "*** Valid values: NTSC = 0, PAL50 = 1, PAL60 = 2" echo "" err ENDIF ;=============================================================================== ; F R A M E - T I M I N G S ;=============================================================================== IF COMPILE_REGION = NTSC || COMPILE_REGION = PAL60 FPS = 60 ; ~60 frames per second VBLANK_TIME = 39 OVERSCAN_TIME = 28 ELSE FPS = 50 ; ~50 frames per second VBLANK_TIME = 80 OVERSCAN_TIME = 46 ENDIF ;=============================================================================== ; C O L O R - C O N S T A N T S ;=============================================================================== BLACK = $00 WHITE = $0E IF COMPILE_REGION = NTSC YELLOW = $10 ORANGE = $40 BLUE = $80 DK_GREEN = $D0 COLOR_LEADSHIP = ORANGE COLOR_TANK_LASER = BLUE ELSE YELLOW = $20 DK_GREEN = $30 RED = $60 BLUE = $B0 COLOR_LEADSHIP = RED COLOR_TANK_LASER = BLUE ENDIF ;=============================================================================== ; U S E R - C O N S T A N T S ;=============================================================================== ROM_BASE = $F000 H_DIGITS = 8 H_EXPLOSION_GRAPHICS = 8 H_LEADSHIP = 8 H_RESERVED_FLEET = 8 H_TANKS = 8 H_TERRAIN_GRAPHICS = 8 H_TURRET = 8 W_MOUNTAIN_TERRAIN = 40 ; number of mountain terrain bits XMIN = 0 XMAX = 160 XMIN_LEADSHIP = XMIN + 15 XMAX_LEADSHIP = XMAX - 27 YMAX = 130 INIT_LEADSHIP_VERT_MIN = 66 INIT_TANK_GROUP_HORIZ = 48 INIT_REMOTE_START_TIMER = 30 LEADSHIP_VERTICAL_INCREMENT = 8 ; value to increase vertical minimum each wave MAX_NUM_LIVES = 6 MAX_TANK_GROUP_TURRET_VALUE = 2 LEADSHIP_LASER_SLOPE = 53 ; 256/53...m = ~4.83...~78 degrees EXPLANATION_POINT_PTR = (ExplanationPoint - NumberFonts) / H_DIGITS ; ; Lead Ship status values ; LEADSHIP_SHOT = %10000000 TANK_DAMAGE_SOUND_VALUE = 30 MAX_LEADSHIP_LASER_TIMER = 0 ; set to implement Lead Ship laser temp ; ; game selection constants ; GAME_SELECT_CADET = 0 GAME_SELECT_LIEUTENANT = 1 GAME_SELECT_CAPTAIN = 2 GAME_SELECT_COMMANDER = 3 CADET_MAX_ATTACK_GROUP = 3 LIEUTENANT_MAX_ATTACK_GROUP = 4 CAPTAIN_MAX_ATTACK_GROUP = 5 COMMANDER_MAX_ATTACK_GROUP = 5 ;=============================================================================== ; Z P - V A R I A B L E S ;=============================================================================== SEG.U variables .org $80 gameSelection ds 1 ; game variation selected selectDelayTimer ds 1 ; set but never changes selectDebounce ds 1 ; debounce rate for SELECT switch actionButtonDebounce ds 1 ; debounce rate for action button joystickValue ds 1 ; active player joystick values zp_Unused_00 ds 1 ; one unused ZP byte colorEOR ds 1 hueMask ds 1 ; color hue mask value objectColors ds 6 ;-------------------------------------- scoreColors = objectColors ;-------------------------------------- player1ScoreColors = scoreColors; only one actually used player2ScoreColors = player1ScoreColors + 1; never referenced terrainColor = player2ScoreColors + 1 skyColor = terrainColor + 1 leadShipColor = skyColor + 1 tankColor = leadShipColor + 1 leadShipVertPos ds 1 ; vertical position for LeadShip leadShipHorizPos ds 1 ; horizontal position for LeadShip tankBitArray ds 1 ; array for active Tanks (only D2 - D0 used) enemyForcesNUSIZValue ds 1 leadShipAnimationIdx ds 1 ; LeadShip animation index (only D2 - D0 used) leadShipLaserSlopeIntegerValue ds 1 tankLaserSlopeIntegerValue ds 1 leadShipLaserSlopFractionValue ds 1 tankLaserSlopeFractionValue ds 1 leadShipLaserHorizDir ds 1 ; horizontal direction of LeadShip laser tankLaserHorizDir ds 1 ; horizontal direction of attacker laser zp_Unused_01 ds 2 mountainTerrainWidth ds 1 ; value never changes mountainTerrainShiftValue ds 1 tankHorizLaserTarget ds 1 enableEnemyForcesLaserValue ds 1 leadShipLaserHorizDelta ds 1 ; LeadShip laser horizontal delta value activateEnemyTurretFrequency ds 1 enemyTankMoveFrequency ds 1 enemyTankLaserFrequency ds 1 remainingLives ds 1 tankGroupHorizPos ds 1 ; horizontal position of Tank group levelTransitionState ds 1 leadShipVertMin ds 1 ; LeadShip minimum vertical position terrainGraphics ds 48 ;-------------------------------------- leftPF0TerrainGraphics = terrainGraphics leftPF1TerrainGraphics = leftPF0TerrainGraphics + H_TERRAIN_GRAPHICS leftPF2TerrainGraphics = leftPF1TerrainGraphics + H_TERRAIN_GRAPHICS rightPF0TerrainGraphics = leftPF2TerrainGraphics + H_TERRAIN_GRAPHICS rightPF1TerrainGraphics = rightPF0TerrainGraphics + H_TERRAIN_GRAPHICS rightPF2TerrainGraphics = rightPF1TerrainGraphics + H_TERRAIN_GRAPHICS scoreGraphicPtrs ds 12 leadShipGraphicPtrs ds 2 explosionGraphicPtrs ds 2 tankGraphicPtrs ds 2 colorCycleMode ds 1 frameCount ds 1 remoteStartTimer ds 1 playerScore ds 3 leadShipTurretHeight ds 1 tankAttackGroup ds 1 objectDamageStatus ds 2 ;-------------------------------------- leadShipDamageStatus = objectDamageStatus tankDamageStatus = leadShipDamageStatus + 1 enableEnemyTurret ds 1 ; D1 used to enable / disable turret objectTimerValues ds 2 ;-------------------------------------- leadShipLaserFrequency = objectTimerValues cycleEnemyTankTimer = leadShipLaserFrequency + 1 extraLifeSoundValue ds 1 objectLaserValues ds 2 ;-------------------------------------- leadShipLaserValue = objectLaserValues tankLaserValue = leadShipLaserValue + 1 activeEnemyForcesTurret ds 1 ; which Enemy turret is active (0 - 2) div16Remainder ds 1 ;-------------------------------------- tmpDigitChar = div16Remainder ;-------------------------------------- tmpShowLeftReservedFleet = tmpDigitChar ;-------------------------------------- tmpTurretTargetDistance = tmpShowLeftReservedFleet ;-------------------------------------- tmpExplosionSoundVolume = tmpTurretTargetDistance tmpLoopCount ds 1 ;-------------------------------------- tmpShowRightReservedFleet = tmpLoopCount tmpTankGroupHorizPos = tmpShowRightReservedFleet leadShipLaserColor ds 1 echo "***",(* - $80 - 3)d, "BYTES OF RAM USED", ($100 - * + 3)d, "BYTES FREE" ;=============================================================================== ; R O M - C O D E (BANK 0) ;=============================================================================== SEG Bank0 .org ROM_BASE Start ; ; Set up everything so the power up state is known. ; sei ; disable interrupts cld ; clear decimal mode ldx #0 RestartGame lda #0 .clearLoop sta VSYNC,x txs inx bne .clearLoop jsr InitializeGame MainLoop ldx #<[tankColor - objectColors] .setObjectColors lda GameColors,x ; read game color table eor colorEOR ; flip color bits based on color cycling and hueMask ; mask color values for COLOR / B&W mode sta objectColors,x cpx #<[leadShipColor - objectColors] bcs .nextObjectColor sta COLUP0,x .nextObjectColor dex bpl .setObjectColors lda #THREE_COPIES sta NUSIZ0 sta NUSIZ1 lda #MSBL_SIZE8 | PF_PRIORITY sta CTRLPF DisplayKernel .waitTime lda INTIM bne .waitTime sta WSYNC ;-------------------------------------- sta VBLANK ; 3 = @03 enable TIA (D1 = 0) sta COLUPF ; 3 = @06 set playfield color to BLACK sta CXCLR ; 3 = @09 clear collisions sta HMCLR ; 3 = @12 clear horizontal motion registers sta leadShipLaserHorizDelta; 3 clear LeadShip laser slope run value lda #H_DIGITS - 1 ; 2 sta tmpLoopCount ; 3 sta VDELP0 ; 3 = @23 VDEL GRP0 (D1 = 1) sta VDELP1 ; 3 = @26 VDEL GRP1 (D1 = 1) .drawDigits ldy tmpLoopCount ; 3 lda (scoreGraphicPtrs + 10),y;5 sta tmpDigitChar ; 3 lda (scoreGraphicPtrs + 8),y;5 tax ; 2 lda (scoreGraphicPtrs),y ; 5 sta WSYNC ;-------------------------------------- SLEEP 2 ; 2 sta GRP0 ; 3 = @05 lda (scoreGraphicPtrs + 2),y;5 sta GRP1 ; 3 = @13 lda (scoreGraphicPtrs + 4),y;5 sta GRP0 ; 3 = @21 lda (scoreGraphicPtrs + 6),y;5 ldy tmpDigitChar ; 3 sta GRP1 ; 3 = @32 stx GRP0 ; 3 = @35 sty GRP1 ; 3 = @38 sta GRP0 ; 3 = @41 dec tmpLoopCount ; 5 bpl .drawDigits ; 2³ IF COMPILE_REGION = PAL50 lda #HMOVE_R8 | THREE_MED_COPIES;2 ELSE lda #HMOVE_R8 ; 2 ENDIF sta HMP1 ; 3 = @53 sta WSYNC ;-------------------------------------- sta HMOVE ; 3 ldy #0 ; 2 sty VDELP0 ; 3 = @08 sty VDELP1 ; 3 = @11 sty GRP0 ; 3 = @14 sty GRP1 ; 3 = @17 IF COMPILE_REGION = PAL50 sta NUSIZ0 ; 3 sta NUSIZ1 ; 3 ENDIF lda leadShipColor ; 3 sta COLUP0 ; 3 = @23 sta COLUP1 ; 3 = @26 IF COMPILE_REGION != PAL50 lda #THREE_MED_COPIES ; 2 sta NUSIZ0 ; 3 sta NUSIZ1 ; 3 ENDIF ldx remainingLives ; 3 get remaining lives bpl .setReservedFleetNUSIZ ; 2³ ldx #0 ; 2 .setReservedFleetNUSIZ lda ReserveFleetNUSIZTable + 1,x;4 sta NUSIZ0 ; 3 sta tmpShowLeftReservedFleet;3 lda ReserveFleetNUSIZTable,x;4 sta NUSIZ1 ; 3 sta tmpShowRightReservedFleet;3 ldy #H_RESERVED_FLEET - 1 ; 2 .drawReservedFleet sta WSYNC ;-------------------------------------- lda Spacecraft_01 - 1,y ; 4 bit tmpShowLeftReservedFleet;3 bmi .checkToShowRightReservedFleet;2³ sta GRP0 ; 3 = @12 .checkToShowRightReservedFleet bit tmpShowRightReservedFleet;3 bmi .nextReservedFleetLine ; 2³ sta GRP1 ; 3 = @20 .nextReservedFleetLine dey ; 2 bne .drawReservedFleet ; 2³ sta WSYNC ;-------------------------------------- sty GRP0 ; 3 = @03 sty GRP1 ; 3 = @06 lda tankLaserValue ; 3 get Tank laser value and hueMask ; 3 sta COLUP1 ; 3 = @15 color Tank laser lda frameCount ; 3 get current frame count bit leadShipDamageStatus ; 3 check if LeadShip hit bmi .colorLeadShip ; 2³ set damaged LeadShip color lda leadShipColor ; 3 .colorLeadShip and hueMask ; 3 sta COLUP0 ; 3 sta WSYNC ;-------------------------------------- sty leadShipLaserSlopeIntegerValue;3 reset LeadShip laser slope integer sty tankLaserSlopeIntegerValue;3 reset Tank laser slope integer sty NUSIZ0 ; 3 = @09 set to ONE_COPY (i.e. y = 0) sty NUSIZ1 ; 3 = @12 set to ONE_COPY (i.e. y = 0) ldy #LOCK_MISSILE | ENABLE_BM;2 sty RESMP0 ; 3 = @17 sty ENABL ; 3 = @20 lda leadShipLaserValue ; 3 and #$0F ; 2 bne .enableOrDisableLeadShipLaser;2³ ldy #DISABLE_BM ; 2 .enableOrDisableLeadShipLaser sty ENAM0 ; 3 ldy #ENABLE_BM ; 2 lda tankLaserValue ; 3 get Tank laser value and #$0F ; 2 bne .enableOrDisableEnemyForcesLaser;2³ ldy #DISABLE_BM ; 2 .enableOrDisableEnemyForcesLaser sty enableEnemyForcesLaserValue;3 lda leadShipLaserValue ; 3 and hueMask ; 3 sta leadShipLaserColor ; 3 lda leadShipHorizPos ; 3 get LeadShip horizontal position ldx #<[HMP0 - HMP0] ; 2 jsr CalculateObjectHorizPosition;6 horizontally position LeadShip ;-------------------------------------- ldx #<[HMM1 - HMP0] ; 2 lda tankHorizLaserTarget ; 3 clc ; 2 adc #4 ; 2 jsr CalculateObjectHorizPosition;6 horizontally position Tank laser ;-------------------------------------- lda tankGroupHorizPos ; 3 get Tank group horizontal position and #1 ; 2 keep D0 value asl ; 2 multiply value by 8 (i.e. H_TANKS) asl ; 2 asl ; 2 adc #> 1 asl adc #GameSpriteData .setGraphicPointerMSBValues sta scoreGraphicPtrs,x dex dex bpl .setGraphicPointerMSBValues ldx #48 .setTerrainGraphicRAMData ldy #H_TERRAIN_GRAPHICS - 1 .internalSetTerrainGraphicRAMData lda TerrainGraphicData,y sta terrainGraphics - 1,x dex dey bpl .internalSetTerrainGraphicRAMData txa bne .setTerrainGraphicRAMData stx mountainTerrainShiftValue ; clear mountain terrain scroll value jmp ContinueInitializeGame ; ; Horizontal reset starts at cycle 8 (i.e. pixel 24). The object's position is ; incremented by 46 to push their pixel positioning to start at cycle 23 (i.e. ; pixel 69) with an fine adjustment of -6 to start objects at pixel 63. ; CalculateObjectHorizPosition clc ; clear carry adc #46 ; increment horizontal position value by 46 tay ; save result for later and #$0F ; keep lower nybbles sta div16Remainder ; keep div16 remainder tya lsr ; divide horizontal position by 16 lsr lsr lsr tay ; division by 16 is course movement value clc adc div16Remainder ; add back division by 16 remainder cmp #15 bcc .determineFineMotionValue sbc #15 iny ; increment course movement value .determineFineMotionValue eor #7 ; get 3-bit 1's complement for fine motion asl asl asl asl sta HMP0,x ; set object's fine motion value sta WSYNC ; wait for next scan line .coarseMoveObject dey bpl .coarseMoveObject sta RESP0,x ; set object's coarse position rts DetermineIfActiveEnemyDestroyed ldx activeEnemyForcesTurret ; get active Enemy Forces turret value lda TankGroupBitMaskingValues,x ; get bit masking values eor #7 ; flip bits D2 - D0 and tankBitArray ; mask with Tank array value rts GameSelectionMaxAttackGroup .byte CADET_MAX_ATTACK_GROUP, LIEUTENANT_MAX_ATTACK_GROUP .byte CAPTAIN_MAX_ATTACK_GROUP, COMMANDER_MAX_ATTACK_GROUP EnemyTankGroupMovementFrequency .byte $0F ; |....XXXX| .byte $07 ; |.....XXX| .byte $03 ; |......XX| .byte $01 ; |.......X| .byte $01 ; |.......X| .byte $01 ; |.......X| EnemyTanksHorizOffsetValues .byte 0, 64, 32, 32, 0, 0, 0, 0 TankGroupBitMaskingValues .byte 3, 5, 6 Copyright_0 .byte $00 ; |........| .byte $AD ; |X.X.XX.X| .byte $A9 ; |X.X.X..X| .byte $E9 ; |XXX.X..X| .byte $A9 ; |X.X.X..X| .byte $ED ; |XXX.XX.X| .byte $41 ; |.X.....X| .byte $0F ; |....XXXX| Copyright_1 .byte $00 ; |........| .byte $50 ; |.X.X....| .byte $58 ; |.X.XX...| .byte $5C ; |.X.XXX..| .byte $56 ; |.X.X.XX.| .byte $53 ; |.X.X..XX| .byte $11 ; |...X...X| .byte $F0 ; |XXXX....| Copyright_2 .byte $00 ; |........| .byte $BA ; |X.XXX.X.| .byte $8A ; |X...X.X.| .byte $BA ; |X.XXX.X.| .byte $A2 ; |X.X...X.| .byte $3A ; |..XXX.X.| .byte $80 ; |X.......| .byte $FE ; |XXXXXXX.| Copyright_3 .byte $00 ; |........| .byte $E9 ; |XXX.X..X| .byte $AB ; |X.X.X.XX| .byte $AF ; |X.X.XXXX| .byte $AD ; |X.X.XX.X| .byte $E9 ; |XXX.X..X| .byte $00 ; |........| .byte $00 ; |........| BOUNDARY 0 GameSpriteData NumberFonts zero .byte $3C ; |..XXXX..| .byte $66 ; |.XX..XX.| .byte $66 ; |.XX..XX.| .byte $66 ; |.XX..XX.| .byte $66 ; |.XX..XX.| .byte $66 ; |.XX..XX.| .byte $66 ; |.XX..XX.| .byte $3C ; |..XXXX..| one .byte $3C ; |..XXXX..| .byte $18 ; |...XX...| .byte $18 ; |...XX...| .byte $18 ; |...XX...| .byte $18 ; |...XX...| .byte $18 ; |...XX...| .byte $38 ; |..XXX...| .byte $18 ; |...XX...| two .byte $7E ; |.XXXXXX.| .byte $60 ; |.XX.....| .byte $60 ; |.XX.....| .byte $3C ; |..XXXX..| .byte $06 ; |.....XX.| .byte $06 ; |.....XX.| .byte $46 ; |.X...XX.| .byte $3C ; |..XXXX..| three .byte $3C ; |..XXXX..| .byte $46 ; |.X...XX.| .byte $06 ; |.....XX.| .byte $0C ; |....XX..| .byte $0C ; |....XX..| .byte $06 ; |.....XX.| .byte $46 ; |.X...XX.| .byte $3C ; |..XXXX..| four .byte $0C ; |....XX..| .byte $0C ; |....XX..| .byte $0C ; |....XX..| .byte $7E ; |.XXXXXX.| .byte $4C ; |.X..XX..| .byte $2C ; |..X.XX..| .byte $1C ; |...XXX..| .byte $0C ; |....XX..| five .byte $7C ; |.XXXXX..| .byte $46 ; |.X...XX.| .byte $06 ; |.....XX.| .byte $06 ; |.....XX.| .byte $7C ; |.XXXXX..| .byte $60 ; |.XX.....| .byte $60 ; |.XX.....| .byte $7E ; |.XXXXXX.| six .byte $3C ; |..XXXX..| .byte $66 ; |.XX..XX.| .byte $66 ; |.XX..XX.| .byte $66 ; |.XX..XX.| .byte $7C ; |.XXXXX..| .byte $60 ; |.XX.....| .byte $62 ; |.XX...X.| .byte $3C ; |..XXXX..| seven .byte $18 ; |...XX...| .byte $18 ; |...XX...| .byte $18 ; |...XX...| .byte $18 ; |...XX...| .byte $0C ; |....XX..| .byte $06 ; |.....XX.| .byte $42 ; |.X....X.| .byte $7E ; |.XXXXXX.| eight .byte $3C ; |..XXXX..| .byte $66 ; |.XX..XX.| .byte $66 ; |.XX..XX.| .byte $3C ; |..XXXX..| .byte $3C ; |..XXXX..| .byte $66 ; |.XX..XX.| .byte $66 ; |.XX..XX.| .byte $3C ; |..XXXX..| nine .byte $3C ; |..XXXX..| .byte $46 ; |.X...XX.| .byte $06 ; |.....XX.| .byte $3E ; |..XXXXX.| .byte $66 ; |.XX..XX.| .byte $66 ; |.XX..XX.| .byte $66 ; |.XX..XX.| .byte $3C ; |..XXXX..| ExplanationPoint .byte $00 ; |........| .byte $18 ; |...XX...| .byte $00 ; |........| .byte $18 ; |...XX...| .byte $18 ; |...XX...| .byte $18 ; |...XX...| .byte $18 ; |...XX...| .byte $18 ; |...XX...| Blank .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| ; ; last three bytes shared with table below ; ExplosionGraphics Explosion_00 .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| .byte $04 ; |.....X..| .byte $20 ; |..X.....| .byte $81 ; |X......X| .byte $44 ; |.X...X..| .byte $00 ; |........| Explosion_01 .byte $00 ; |........| .byte $00 ; |........| .byte $08 ; |....X...| .byte $20 ; |..X.....| .byte $81 ; |X......X| .byte $04 ; |.....X..| .byte $40 ; |.X......| .byte $00 ; |........| Explosion_02 .byte $00 ; |........| .byte $08 ; |....X...| .byte $10 ; |...X....| .byte $42 ; |.X....X.| .byte $08 ; |....X...| .byte $40 ; |.X......| .byte $00 ; |........| .byte $00 ; |........| Explosion_03 .byte $00 ; |........| .byte $18 ; |...XX...| .byte $42 ; |.X....X.| .byte $08 ; |....X...| .byte $20 ; |..X.....| .byte $00 ; |........| .byte $00 ; |........| .byte $00 ; |........| SpacecraftSprites Spacecraft_00 .byte $18 ; |...XX...| .byte $3C ; |..XXXX..| .byte $B6 ; |X.XX.XX.| .byte $B6 ; |X.XX.XX.| .byte $B6 ; |X.XX.XX.| .byte $3C ; |..XXXX..| .byte $18 ; |...XX...| .byte $00 ; |........| Spacecraft_01 .byte $18 ; |...XX...| .byte $3C ; |..XXXX..| .byte $DB ; |XX.XX.XX| .byte $DB ; |XX.XX.XX| .byte $DB ; |XX.XX.XX| .byte $3C ; |..XXXX..| .byte $18 ; |...XX...| .byte $00 ; |........| Spacecraft_02 .byte $18 ; |...XX...| .byte $3C ; |..XXXX..| .byte $6D ; |.XX.XX.X| .byte $6D ; |.XX.XX.X| .byte $6D ; |.XX.XX.X| .byte $3C ; |..XXXX..| .byte $18 ; |...XX...| .byte $00 ; |........| TankSprites TankSprites_00 .byte $00 ; |........| .byte $42 ; |.X....X.| .byte $E7 ; |XXX..XXX| .byte $42 ; |.X....X.| .byte $7E ; |.XXXXXX.| .byte $7E ; |.XXXXXX.| .byte $7E ; |.XXXXXX.| .byte $3C ; |..XXXX..| TankSprites_01 .byte $00 ; |........| .byte $A5 ; |X.X..X.X| .byte $42 ; |.X....X.| .byte $A5 ; |X.X..X.X| .byte $7E ; |.XXXXXX.| .byte $7E ; |.XXXXXX.| .byte $7E ; |.XXXXXX.| .byte $3C ; |..XXXX..| GameColors .byte WHITE - 2 ; player 1 score color .byte WHITE - 2 ; player 2 score color .byte DK_GREEN + 4 ; terrain color .byte BLACK ; sky color .byte YELLOW + 10 ; LeadShip color .byte BLACK + 6 ; Enemy Tank color TerrainGraphicData .byte $FF ; |XXXXXXXX| .byte $FF ; |XXXXXXXX| .byte $DF ; |XX.XXXXX| .byte $8F ; |X...XXXX| .byte $07 ; |.....XXX| .byte $03 ; |......XX| .byte $01 ; |.......X| .byte $00 ; |........| ContinueInitializeGame inx ; x = 1 stx leadShipTurretHeight ; set to not draw LeadShip turret lda #W_MOUNTAIN_TERRAIN sta mountainTerrainWidth lda #