********************************************************************************
* Asteroids (rev 4) *
* Copyright 1979 Atari, Inc. *
* *
* By Lyle Rains and Ed Logg. *
********************************************************************************
* Disassembly by Nick Mikstas (https://www.nicholasmikstas.com/asteroids- *
* fimrware) and Lonnie Howell / Mark McDougall *
* (http://computerarcheology.com/Arcade/Asteroids/). *
* *
* The binary used is a concatenation of the four ROMs that are addressable by *
* the 6502. The DVG ROM was placed at the end. *
********************************************************************************
* Project created by Andy McFadden, using 6502bench SourceGen v1.8. This is a *
* fairly straight conversion from the listings on nicholasmikstas.com, which *
* in turn drew heavily on the material at computerarcheology.com. I have done *
* some reformatting and correction of typographical errors. *
* *
* Last updated 2021/11/04 *
********************************************************************************
* General memory map: *
* *
* $0000-03ff: RAM (1KB) *
* $2000-3fff: various I/O *
* $4000-47ff: vector RAM *
* $5000-57ff: vector ROM *
* $6800-7fff: game ROM *
* *
* The memory from $0200-02ff and $0300-03ff hold state for player 1 and player *
* 2. The hardware allows the two to be swapped, so the current player's state *
* can always be found at $0200. *
* *
* I/O port definitions: *
* *
* IN0/IN1 bits are mapped to the high bit of a unique address. Some things *
* aren't as simple. *
* *
* DSW1 ($2800-2803): *
* $2800: coinage: 0=free play, 1=1 coin 2 credits, 2=1/1, 3=2/1 *
* $2801: right coin mult: 0=1x, 1=4x, 2=5x, 3=6x *
* $2802: center coin mult & lives (%00=1x/4, %01=1x/3, %10=2x/4, %11=2x/3) *
* $2803: language: 0=en, 1=de, 2=fr, 3=es *
* *
* OUTLATCH ($3200): UURCLP12 *
* UU=unused *
* R=right coin counter enable *
* C=center coin counter enable *
* L=left coin counter enable *
* P=active player; swaps RAM at $200-2ff with $300-3ff *
* 1=player 1 button LED *
* 2=player 2 button LED *
* *
* For a "cocktail" cabinet, the "active player" bit also rotates the screen *
* 180 degrees when player 2 is active. *
********************************************************************************
PlyrText .eq $01 {const} ;PLAYER
YrScrText .eq $02 {const} ;YOUR SCORE IS ONE OF THE TEN BEST
InitText .eq $03 {const} ;PLEASE ENTER YOUR INITIALS
PlyrLamps .eq $03 {const} ;Illuminate both player button lamps.
LargeAst .eq $04 {const} ;Large asteroid.
MpuRamPages .eq $04 {const} ;four pages = 1k MPU RAM.
PshRtText .eq $04 {const} ;PUSH ROTATE TO SELECT LETTER
RamSwap .eq $04 {const} ;Swap RAM banks 2 and 3.
PshHypText .eq $05 {const} ;PUSH HYPERSPACE WHEN LETTER IS CORRECT
PshStrtText .eq $06 {const} ;PUSH START
CoinCtrLeft .eq $08 {const} ;Enable left coin counter.
OneTwoText .eq $08 {const} ;1 COIN 2 PLAYS
CoinCtrCntr .eq $10 {const} ;Enable center coin counter.
GoodRamFreq .eq $14 {const} ;Thump frequency setting for good RAM.
MaxAsteroids .eq $1a {const} ;Max number of asteroids(26+1 = 27).
ShipIndex .eq $1b {const} ;Index to ship status.
ScrIndex .eq $1c {const} ;Index to saucer status.
BadRamFreq .eq $1d {const} ;Thump frequency setting for bad RAM.
CoinCtrRght .eq $20 {const} ;Enable right coin counter.
LargeScrPnts .eq $20 {const} ;200 points for a large saucer hit.
SelfTestWait .eq $24 {const} ;36 3Khz clock wait (.144 seconds).
LValidCoin .eq $74 {const} ;Indicate left coin mechanism valid coin.
CValidCoin .eq $75 {const} ;Indicate center coin mechanism valid coin.
RValidCoin .eq $76 {const} ;Indicate right coin mechanism valid coin.
EnableBit .eq $80 {const} ;The MSB is used to check/set hardware enables.
SmallScrPnts .eq $99 {const} ;990 points for a small saucer hit.
LabsOpcode .eq $a0 {const} ;LABS vector state machine opcode.
HaltOpcode .eq $b0 {const} ;HALT vector state machine opcode.
JsrlOpcode .eq $c0 {const} ;JSRL vector state machine opcode.
RtslOpcode .eq $d0 {const} ;RTSL vector state machine opcode.
JmplOpcode .eq $e0 {const} ;JMPL vector state machine opcode.
SvecOpcode .eq $f0 {const} ;SVEC vector state machine opcode.
ZeroPageRam .eq $00 {addr/256} ;Through $00FF.
VecRamPtr .eq $02 {addr/2} ;Pointer to current vector RAM location.
TestSFXInit_ .eq $09 ;Used to start SFX during self test routines.
GenByte0B .eq $0b ;General use byte.
GenByte0C .eq $0c ;General use byte.
GenByte0D .eq $0d ;General use byte.
InitialIndex .eq $10 ;Current index to initial in high scores being processed.
BCDAddress .eq $15 ;Stored address of BCD data byte(can only be zero page address).
BCDIndex .eq $16 ;Index to BCD data byte.
ShipDrawUnused .eq $17 ;Always #$00. Was used for something in ship drawing routines.
ZeroBlankBypass .eq $17 ;Fag to determine if zero blanking should be overridden.
CurrentPlyr .eq $18 ;Current active player. #$00=Player 1, #$01=Player 2.
ScoreIndex .eq $19 ;Offset to current player's score registers.
PrevGamePlyrs .eq $1a ;Number of players in the game that just ended.
NumPlayers .eq $1c ;Indicates if there is 1 or 2 players.
HighScores .eq $1d {addr/20} ;Through $30. Top 10 high scores. 2 bytes each.
ThisInitial .eq $31 ;Current initial selected on high score entry screen(0-2).
Plyr1Rank .eq $32 ;Player 1 rank in top score list*3 (0,3,6,9, etc).
Plyr2Rank .eq $33 ;Player 2 rank in top score list*3 (0,3,6,9, etc).
HighScoreIntls .eq $34 {addr/30} ;Through $51. High score initials. 3 bytes each.
PlayerScores .eq $52 {addr/4} ;Base address of the player's scores.
Plr1ScoreBase .eq $52 ;Base address of Player 1's score.
Plr2ScoreBase .eq $54 ;Base address of Player 2's score.
ShipsPerGame .eq $56 ;Number of ships a player starts with.
Plyr1Ships .eq $57 ;Current number of player 1 ships.
Plyr2Ships .eq $58 ;Current number of player 2 ships.
HyprSpcFlag .eq $59 ;#$00=No hyperspace, #$01=Jump successful, #$80=Jump unsuccessful.
PlyrDispTimer .eq $5a ;Timer to display Player 1/Player 2 between waves.
FrameCounter .eq $5b ;Increments every 4 NMIs. If game loop not running, causes reset.
FrameTimer .eq $5c {addr/2} ;16-bit timer increments every frame, lower byte.
NmiCounter .eq $5e ;Increments every NMI period.
RandNum .eq $5f {addr/2} ;High byte of random number word.
ShipDir .eq $61 ;Player's ship direction.
ScrBulletDir .eq $62 ;Saucer bullet direction.
ShipBulletSR .eq $63 ;Shift register for limiting ship fire rate.
ShipXAccel .eq $64 ;Ship acceleration in the X direction.
ShipYAccel .eq $65 ;Ship acceleration in the Y direction.
SFXTimers .eq $66 {addr/6} ;Starting address for SFX timers.
FireSFXTimer .eq $66 ;Time to play fire SFX.
ScrFrSFXTimer .eq $67 ;Time to play saucer fire SFX.
ExLfSFXTimer .eq $68 ;Time to play extra life SFX.
ExplsnSFXTimer .eq $69 ;Time to play explosion SFX.
ShipFireSFX_ .eq $6a ;Controls the ship fire SFX.
ThisVolFreq .eq $6c ;Current settings for the thump frequency and volume.
ThmpOnTime .eq $6d ;Time thump SFX stays on.
ThumpOffTime .eq $6e ;Time thump SFX stays off.
MultiPurpBits .eq $6f ;Storage for bits to set in the MultiPurp register.
NumCredits .eq $70 ;Current number of credits.
DipSwitchBits .eq $71 ;Storage for dip switch values.
SlamTimer .eq $72 ;Decrements from #$0F if slam detected during coin insertion.
CoinMult .eq $73 ;Number of coins after multipliers.
ValidCoins .eq $74 {addr/3} ;Base address for valid coin registers below.
WaitCoinTimers .eq $77 {addr/3} ;Base address for timers below.
CoinDropTimers .eq $7a {addr/3} ;Base address for timers below.
ShpDebrisXVel .eq $7d {addr/12} ;Through $88. X velocity of ship debris pieces, lower byte.
ShpDebrisYVel .eq $89 {addr/12} ;Through $94. Y velocity of ship debris pieces, lower byte.
OnePageRam .eq $0100 {addr/256} ;Through $01FF. The stack resides here.
StackTop .eq $01d0 ;The stack should never grow past this point.
StackBottom .eq $01ff ;The stack should never shrink to this point.
Player1Ram .eq $0200 {addr/256} ;Through $02FF. A total of 1K MCU RAM.
AstStatus .eq $0200 {addr/27} ;Through $021A. 17 asteroids max-their current status:
ShipStatus .eq $021b ;0=No Ship Or In Hyperspace, 1=Alive, $A0-$FF=Ship Exploding.
ScrStatus .eq $021c ;0=No Saucer, 1=Small Saucer, 2=Large Saucer, MSB set=Exploding.
ShpShotTimer .eq $021f {addr/4} ;Through $0222. Timers for current ship bullets.
AstXSpeed .eq $0223 {addr/27} ;Through $023D. Asteroid horiz speed. 255-192=Left, 1-63=Right.
ShipXSpeed .eq $023e ;Ship horizontal speed.
SaucerXSpeed .eq $023f ;Saucer horizontal speed.
AstYSpeed .eq $0246 {addr/27} ;Through $0260. Asteroid vert speed. 255-192=Down, 1-63=Up.
ShipYSpeed .eq $0261 ;Ship vertical speed.
SaucerYSpeed .eq $0262 ;Saucer vertical speed.
AstXPosHi .eq $0269 ;Through $0283. Asteroid horz position, high byte.
ShipXPosHi .eq $0284 ;Ship X position, high byte.
ScrXPosHi .eq $0285 ;Saucer X position, high byte.
AstYPosHi .eq $028c ;Through $02A6. Asteroid vert position, high byte.
ShipYPosHi .eq $02a7 ;Ship Y position, high byte.
ScrYPosHi .eq $02a8 ;Saucer Y position, high byte.
AstXPosLo .eq $02af ;Through $02C9. Asteroid horz position, low byte.
ShipXPosLo .eq $02ca ;Ship X position, low byte.
ScrXPosLo .eq $02cb ;Saucer X position, low byte.
AstYPosLo .eq $02d2 ;Through $02EC. Asteroid vert position, low byte.
ShipYPosLo .eq $02ed ;Ship Y position, low byte.
ScrYPosLo .eq $02ee ;Saucer Y position, low byte.
AstPerWave .eq $02f5 ;Asteroids per wave.
CurAsteroids .eq $02f6 ;Current number of asteroids.
ScrTimer .eq $02f7 ;Countdown timer for saucer spawn.
ScrTmrReload .eq $02f8 ;Reload value for saucer timer.
AstBreakTimer .eq $02f9 ;Set after asteroid hit. Prevents saucer spawn after last asteroid.
ShipSpawnTmr .eq $02fa ;Ship spawn timer. #$81=waiting to re-spawn.
ThmpSpeedTmr .eq $02fb ;Timer That controls thump SFX speed.
ThmpOffReload .eq $02fc ;Reload value for ThumpOffTime register.
ScrSpeedup .eq $02fd ;Saucer occurrences increase if asteroid count is below this value.
Player2Ram .eq $0300 {addr/256} ;Through $03FF.
Clk3Khz .eq $2001 ;3KHz clock.
Halt .eq $2002 ;Halt gives the vector state machine status. 1=busy, 0=idle.
HyprSpcSw .eq $2003 ;Hyperspace button status.
FireSw .eq $2004 ;Fire button status.
DiagStep .eq $2005 ;Diagnostic step. Draws diagonal lines on screen.
SlamSw .eq $2006 ;Slam switch status.
SelfTestSw .eq $2007 ;Self test DIP switch status.
LeftCoinSw .eq $2400 ;Left coin switch status.
Player1Sw .eq $2403 ;Player 1 button status.
Player2Sw .eq $2404 ;Player 2 button status.
ThrustSw .eq $2405 ;Thrust button status.
RotRghtSw .eq $2406 ;Rotation right button status.
RotLeftSw .eq $2407 ;Rotation left button status.
DipSw .eq $2800 {addr/3} ;Base address for the DIP switches.
PlayTypeSw .eq $2800 ;Play type DIP switches (switches 7 and 8);
RghtCoinMechSw .eq $2801 ;Coin multiplier DIP switches for right coin mechanism.
CentCMShipsSw .eq $2802 ;Coin multiplier center coin mechanism, ships per play DIP switches.
LanguageSw .eq $2803 ;Language selection DIP switches.
DmaGo .eq $3000 ;Writing this address starts the vector state machine.
MultiPurp .eq $3200 ;Multipurpose write register. Below are the bit functions:
WdClear .eq $3400 ;Clears the watchdog timer.
ExpPitchVol .eq $3600 ;Controls the explosion SFX pitch and volume.
ThumpFreqVol .eq $3a00 ;Controls the thump frequency and volume.
SaucerSFX .eq $3c00 ;Controls the saucer sound.
SaucerFireSFX .eq $3c01 ;Controls the saucer fire SFX.
SaucerSFXSel .eq $3c02 ;Controls the frequency of the saucer SFX.
ShipThrustSFX .eq $3c03 ;Controls the ship thrust SFX.
ShipFireSFX .eq $3c04 ;Controls the ship fire SFX.
LifeSFX .eq $3c05 ;Controls the life SFX.
NoiseReset .eq $3e00 ;Resets the noise SFX.
VectorRam .eq $4000 {addr/2048} ;Through $47FF. A total of 2K of vector RAM.
VectorRom .eq $5000 {addr/2048} ;Through $57FF. A total of 2k of vector ROM.
VectorRomEnd .eq $5800
ProgramRom .eq $6800 {addr/6144}
ProgramRomEnd .eq $8000
;
; Game entry point and main loop.
;
.addrs $6800
6800: 4c f3 7c jmp RESET ;Initialize the game after power-up
6803: 20 fa 6e InitGame jsr SilenceSFX ;Turn off all SFX
6806: 20 d8 6e jsr InitGameVars ;Initialize various game variables
6809: 20 68 71 InitWaves jsr InitWaveVars ;Initialize variables for the current asteroid wave
;
680c: ad 07 20 GameRunningLoop lda SelfTestSw ;Get self test switch status
680f: 30 fe :Spin bmi :Spin ;Is self test active? If so, spin lock until watchdog reset
6811: 46 5b lsr FrameCounter ;Has a new frame started?
6813: 90 f7 bcc GameRunningLoop ;If not, no processing to do until next frame; branch to wait
;
6815: ad 02 20 VectorWaitLoop1 lda Halt ;Is the vector state machine busy?
6818: 30 fb bmi VectorWaitLoop1 ;If so, loop until it is idle
681a: ad 01 40 lda VectorRam+1 ;Swap which half of vector RAM is read and which half is
681d: 49 02 eor #$02 ; written. This is done by alternating the jump instruction
681f: 8d 01 40 sta VectorRam+1 ; at the beginning of the RAM between $4402 and $4002.
6822: 8d 00 30 sta DmaGo ;Start the vector state machine
6825: 8d 00 34 sta WdClear ;Clear the watchdog timer
6828: e6 5c inc FrameTimer
682a: d0 02 bne SetVecRamPtr ;Increment frame counter
682c: e6 5d inc FrameTimer+1
682e: a2 40 SetVecRamPtr ldx #>VectorRam ;Is vector RAM pointer currently pointing at $4400 range
6830: 29 02 and #$02
6832: d0 02 bne UpdateVecRamPtr ;If so, branch to switch to $4000
6834: a2 44 ldx #>VectorRam+$400 ;Prepare to switch to $4400
6836: a9 02 UpdateVecRamPtr lda #$02
6838: 85 02 sta VecRamPtr ;Swap vector RAM pointer
683a: 86 03 stx VecRamPtr+1
;
683c: 20 85 68 jsr ChkPreGameStuff ;Check if non game play functions need to be run
683f: b0 c2 bcs InitGame ;Branch if attract mode is starting
6841: 20 5c 76 jsr CheckHighScore ;Check if player just got the high score
6844: 20 90 6d jsr ChkHighScrMsg ;Do high score and initial entry message if appropriate
6847: 10 1b bpl DoScreenText ;Is game not in progress? If not, branch
6849: 20 c4 73 jsr ChkHighScrList ;Check if high score list needs to be displayed
684c: b0 16 bcs DoScreenText ;Is high scores list being displayed? If so, branch
684e: a5 5a lda PlyrDispTimer ;Is player not active?
6850: d0 0c bne DoAsteroids ;If not, branch
;
6852: 20 d7 6c jsr UpdateShip ;Update ship firing and position
6855: 20 74 6e jsr EnterHyperspc ;Check if player entered hyperspace
6858: 20 3f 70 jsr ChkExitHprspc ;Check if coming out of hyperspace
685b: 20 93 6b jsr UpdateScr ;Update saucer status
685e: 20 57 6f DoAsteroids jsr UpdateObjects ;Update objects(asteroids, ship, saucer and bullets)
6861: 20 f0 69 jsr HitDetection ;Do hit detection calculations for all objects
6864: 20 4f 72 DoScreenText jsr UpdateScreenText ;Update in-game screen text and reserve lives
6867: 20 55 75 jsr ChkUpdateSFX ;Check if SFX needs to be updated
;
686a: a9 7f lda #$7f ;X beam coordinate 4 * $7F = $1D0 = 464
686c: aa tax ;Y beam coordinate 4 * $7F = $1D0 = 464
686d: 20 03 7c jsr MoveBeam ;Move the CRT beam to a new location
6870: 20 b5 77 jsr GetRandNum ;Get a random number
6873: 20 c0 7b jsr VecHalt ;Halt the vector state machine
6876: ad fb 02 lda ThmpSpeedTmr
6879: f0 03 beq ChkGameRunning ;Is thump speed timer running? If so, decrement it
687b: ce fb 02 dec ThmpSpeedTmr
687e: 0d f6 02 ChkGameRunning ora CurAsteroids ;Is the game running?
6881: d0 89 bne GameRunningLoop ;If so, branch to keep it going
6883: f0 84 beq InitWaves ;Game not running, branch to initialize variables
;
; Helper routines.
;
6885: a5 1c ChkPreGameStuff lda NumPlayers ;Are there players currently playing?
6887: f0 14 beq ChkCoinsPerCredit ;If not, branch
6889: a5 5a lda PlyrDispTimer ;Is the Player 1/Player 2 message being displayed?
688b: d0 03 bne DecPlyrTimer ;If so, branch to decrement timer
688d: 4c 60 69 jmp ChkThmpFaster ;Jump to check if the Thump SFX should be sped up
6890: c6 5a DecPlyrTimer dec PlyrDispTimer ;Decrement player text display timer
6892: 20 e2 69 jsr DrawPlyrNum ;Draw player number on the display
6895: 18 NoResetReturn1 clc ;Return without reinitializing the game
6896: 60 rts
6897: a9 02 DoFreePlay lda #$02 ;Load 2 credits always for free play
6899: 85 70 sta NumCredits
689b: d0 13 bne CheckCredits ;Branch always
ChkCoinsPerCredit
689d: a5 71 lda DipSwitchBits ;Get the number of coins per credit
689f: 29 03 and #$03 ;Is free play active?
68a1: f0 f4 beq DoFreePlay ;If so, branch to add 2 credits
68a3: 18 clc
68a4: 69 07 adc #OneTwoText-1 ;Prepare to display the coins per play message on the display
68a6: a8 tay
68a7: a5 32 lda Plyr1Rank ;Is this the high score entry part?
68a9: 25 33 and Plyr2Rank ;If so, branch
68ab: 10 03 bpl CheckCredits
68ad: 20 f6 77 jsr WriteText ;Write coins per play text to the display
;
68b0: a4 70 CheckCredits ldy NumCredits ;Are credits available?
68b2: f0 e1 beq NoResetReturn1 ;If not, return
68b4: a2 01 ldx #$01 ;Has the Player 1 button been pressed?
68b6: ad 03 24 lda Player1Sw
68b9: 30 23 bmi Do1Player ;If so, branch to start 1 player game.
68bb: c0 02 cpy #$02 ;Are there at least 2 credits available?
68bd: 90 7c bcc ChkStartText ;If not, branch to skip 2 players check
68bf: ad 04 24 lda Player2Sw ;Is the Player 2 button being pressed?
68c2: 10 77 bpl ChkStartText ;If not, branch
;
68c4: a5 6f lda MultiPurpBits
68c6: 09 04 ora #RamSwap
68c8: 85 6f sta MultiPurpBits ;Switch to Player 2 RAM
68ca: 8d 00 32 sta MultiPurp
68cd: 20 d8 6e jsr InitGameVars ;Initialize various game variables
68d0: 20 68 71 jsr InitWaveVars ;Initialize variables for the current asteroid wave
68d3: 20 e8 71 jsr CenterShip ;Center ship on display and zero velocity.
68d6: a5 56 lda ShipsPerGame ;Initialize the Player's lives
68d8: 85 58 sta Plyr2Ships
68da: a2 02 ldx #$02 ;Indicate this is a 2 player game
68dc: c6 70 dec NumCredits ;Decrement credits for Player 2
;
68de: 86 1c Do1Player stx NumPlayers ;Store number of players this game (1 or 2)
68e0: c6 70 dec NumCredits ;Decrement credits for player 1
68e2: a5 6f lda MultiPurpBits ;Clear Player 1 and 2 LEDs and RAM swap bit
68e4: 29 f8 and #%11111000
68e6: 45 1c eor NumPlayers ;Turn on LEDs indicating 1 or 2 player game
68e8: 85 6f sta MultiPurpBits
68ea: 8d 00 32 sta MultiPurp
;
68ed: 20 e8 71 jsr CenterShip ;Center ship on display and zero velocity
68f0: a9 01 lda #$01
68f2: 8d fa 02 sta ShipSpawnTmr ;Initialize ship spawn timer for both players
68f5: 8d fa 03 sta ShipSpawnTmr+$100
68f8: a9 92 lda #$92
68fa: 8d f8 02 sta ScrTmrReload
68fd: 8d f8 03 sta ScrTmrReload+$100 ;Initialize saucer timer and reload value
6900: 8d f7 03 sta ScrTimer+$100
6903: 8d f7 02 sta ScrTimer
6906: a9 7f lda #$7f
6908: 8d fb 02 sta ThmpSpeedTmr ;Initialize thump speed timer for both players
690b: 8d fb 03 sta ThmpSpeedTmr+$100
690e: a9 05 lda #$05
6910: 8d fd 02 sta ScrSpeedup ;Load initial asteroid count that causes more frequent saucers
6913: 8d fd 03 sta ScrSpeedup+$100
6916: a9 ff lda #$ff
6918: 85 32 sta Plyr1Rank ;Zero out both Player's rank
691a: 85 33 sta Plyr2Rank
691c: a9 80 lda #$80 ;Load time for displaying Player 1/2
691e: 85 5a sta PlyrDispTimer
6920: 0a asl A
6921: 85 18 sta CurrentPlyr ;Set current player to 1 and the score index for Player 1
6923: 85 19 sta ScoreIndex
6925: a5 56 lda ShipsPerGame ;Set Player 1 reserve lives
6927: 85 57 sta Plyr1Ships
6929: a9 04 lda #$04
692b: 85 6c sta ThisVolFreq
692d: 85 6e sta ThumpOffTime ;Set initial thump SFX values
692f: a9 30 lda #$30
6931: 8d fc 02 sta ThmpOffReload
6934: 8d fc 03 sta ThmpOffReload+$100
6937: 8d 00 3e sta NoiseReset ;Reset the noise SFX hardware
693a: 60 rts
693b: a5 32 ChkStartText lda Plyr1Rank ;Is this the high score entry part?
693d: 25 32 and Plyr1Rank
693f: 10 0b bpl CheckUpdateLeds ;If so, branch to move on
6941: a5 5c lda FrameTimer ;Is it time to display "PUSH START" on the display?
6943: 29 20 and #%00100000
6945: d0 05 bne CheckUpdateLeds ;If not, branch
6947: a0 06 ldy #PshStrtText ;Display "PUSH START"
6949: 20 f6 77 jsr WriteText ;Write text to the display
;
694c: a5 5c CheckUpdateLeds lda FrameTimer ;Update LEDs every 16 frames
694e: 29 0f and #$0f ;Is this the 16th frame?
6950: d0 0c bne NoResetReturn2 ;If not, branch to return from function
;
6952: a9 01 lda #$01
6954: c5 70 cmp NumCredits
6956: 69 01 adc #$01 ;Turn on Player 1/Player 2 button LEDs
6958: 49 01 eor #$01
695a: 45 6f eor MultiPurpBits
695c: 85 6f sta MultiPurpBits
695e: 18 NoResetReturn2 clc ;Return without reinitializing the game
695f: 60 rts
6960: a5 5c ChkThmpFaster lda FrameTimer ;Is it time to speed up the thump SFX?
6962: 29 3f and #$3f
6964: d0 0a bne ChkMoreShips ;If not, branch
6966: ad fc 02 lda ThmpOffReload ;Is the thump SFX at max speed?
6969: c9 08 cmp #$08
696b: f0 03 beq ChkMoreShips ;If so, branch
696d: ce fc 02 dec ThmpOffReload ;Speed up thump SFX by decreasing off time
;
6970: a6 18 ChkMoreShips ldx CurrentPlyr ;Does the player have any ship remaining?
6972: b5 57 lda Plyr1Ships,x
6974: d0 1c bne ChkShipStatus ;If so, branch
6976: ad 1f 02 lda ShpShotTimer ;Are there any ship bullets on the display?
6979: 0d 20 02 ora ShpShotTimer+1
697c: 0d 21 02 ora ShpShotTimer+2
697f: 0d 22 02 ora ShpShotTimer+3
6982: d0 0e bne ChkShipStatus ;If so, branch
;
6984: a0 07 ldy #$07 ;Write "GAME OVER" to the display
6986: 20 f6 77 jsr WriteText ;Write text to the display
6989: a5 1c lda NumPlayers ;Is this a 2 player game?
698b: c9 02 cmp #$02
698d: 90 03 bcc ChkShipStatus ;If not, branch
698f: 20 e2 69 jsr DrawPlyrNum ;Draw player number on the display
6992: ad 1b 02 ChkShipStatus lda ShipStatus ;Does a ship still exist on the display?
6995: d0 36 bne NoResetReturn3 ;If so, branch to exit
6997: ad fa 02 lda ShipSpawnTmr ;Is ship about to re-spawn?
699a: c9 80 cmp #$80
699c: d0 2f bne NoResetReturn3 ;If so, branch to exit
699e: a9 10 lda #$10 ;Start ship re-spawn timer
69a0: 8d fa 02 sta ShipSpawnTmr
69a3: a6 1c ldx NumPlayers ;Get number of players
69a5: a5 57 lda Plyr1Ships ;Are there any ships in Player 1 or 2 reserves?
69a7: 05 58 ora Plyr2Ships
69a9: f0 24 beq NoCurntGame ;If not, branch; a game is not currently being played
69ab: 20 2d 70 jsr SaucerReset ;Reset saucer variables
69ae: ca dex ;Is this a 1 player game?
69af: f0 1c beq NoResetReturn3 ;If so, branch to exit
69b1: a9 80 lda #$80 ;Load player display timer for Player 2
69b3: 85 5a sta PlyrDispTimer
;
69b5: a5 18 lda CurrentPlyr ;Change to next player
69b7: 49 01 eor #$01
69b9: aa tax ;Does the new player have any lives remaining?
69ba: b5 57 lda Plyr1Ships,x
69bc: f0 0f beq NoResetReturn3 ;If not, branch to exit
69be: 86 18 stx CurrentPlyr
69c0: a9 04 lda #$04
69c2: 45 6f eor MultiPurpBits ;RAM swap to new player RAM
69c4: 85 6f sta MultiPurpBits
69c6: 8d 00 32 sta MultiPurp
69c9: 8a txa
69ca: 0a asl A ;Get index to new player score
69cb: 85 19 sta ScoreIndex
69cd: 18 NoResetReturn3 clc ;Return without reinitializing the game
69ce: 60 rts
69cf: 86 1a NoCurntGame stx PrevGamePlyrs ;Keep track of any previous players
69d1: a9 ff lda #$ff ;Set no current players
69d3: 85 1c sta NumPlayers
69d5: 20 fa 6e jsr SilenceSFX ;Turn off all SFX
69d8: a5 6f lda MultiPurpBits
69da: 29 f8 and #%11111000 ;Turn on both player button LEDs
69dc: 09 03 ora #PlyrLamps
69de: 85 6f sta MultiPurpBits
69e0: 18 clc ;Return without reinitializing the game
69e1: 60 rts
69e2: a0 01 DrawPlyrNum ldy #PlyrText ;Prepare to write "PLAYER" on the display
69e4: 20 f6 77 jsr WriteText ;Write text to the display
69e7: a4 18 ldy CurrentPlyr ;Get the current player number
69e9: c8 iny ;Set it to the proper index for drawing
69ea: 98 tya
69eb: 20 d1 7b jsr DrawDigit ;Draw a single digit on the display
69ee: 60 rts
69ef: 62 .dd1 $62 ;checksum byte
;
; Hit detection.
;
; Need to check hit detection between all the on-screen objects. Object 1 is
; either a bullet (from either the ship or saucer), the player's ship, or the
; saucer. Object 2 is either an asteroid, the player's ship or the saucer.
; Object 1 is the outer loop of the check and each object 1 is checked against
; all of the object 2s. The hit box value extends in both the positive and
; negative directions in both the X and Y directions.
;
• Clear variables
]ObjXDiff .var $08 {addr/1}
]ObjYDiff .var $09 {addr/1}
]Obj2Status .var $0b {addr/1}
69f0: a2 07 HitDetection ldx #$07 ;Prepare to check hit detection on bullets, ship and saucer
69f2: bd 1b 02 HitDetObj1Loop lda ShipStatus,x ;Is the current object 1 slot active?
69f5: f0 02 beq HitDetNextObj1 ;If not, branch to increment to the next object 1
69f7: 10 04 bpl HitDetObj2 ;If MSB clear, this object needs hit detection, branch if so
69f9: ca HitDetNextObj1 dex ;Move to next object to check
69fa: 10 f6 bpl HitDetObj1Loop ;More object to check? if so, branch to do another
69fc: 60 rts ;Done checking hit detection, exit
69fd: a0 1c HitDetObj2 ldy #28 ;Prepare to check hits against asteroids, ship and saucer
69ff: e0 04 cpx #$04 ;Are we checking hit detection against a ship bullet?
6a01: b0 07 bcs HitDetObj2Loop ;If so, branch to check hit detection
6a03: 88 dey ;Skip checking object 2 as a saucer, will be checked as object 1
6a04: 8a txa ;Is object 1 not the player's ship?
6a05: d0 03 bne HitDetObj2Loop ;If not, branch to do hit detection
6a07: 88 HitDetNextObj2 dey ;Have we checked all the object 2s?
6a08: 30 ef bmi HitDetNextObj1 ;If so, branch to increment to the next object 1
;
6a0a: b9 00 02 HitDetObj2Loop lda AstStatus,y ;Is the current object 2 slot active?
6a0d: f0 f8 beq HitDetNextObj2 ;If not, branch to increment to the next object 2
6a0f: 30 f6 bmi HitDetNextObj2 ;If MSB clear, this object needs hit detection, branch if not
6a11: 85 0b sta ]Obj2Status ;Store a copy of object 2's current status
;
6a13: b9 af 02 lda AstXPosLo,y
6a16: 38 sec ;Subtract objects 1 and 2 lower byte of
6a17: fd ca 02 sbc ShipXPosLo,x ; their X positions and save the result
6a1a: 85 08 sta ]ObjXDiff
6a1c: b9 69 02 lda AstXPosHi,y ;Subtract objects 1 and 2 upper byte of their X positions
6a1f: fd 84 02 sbc ShipXPosHi,x
6a22: 4a lsr A ;Keep bit 8 in the difference. XDiff holds bits 8 to 1
6a23: 66 08 ror ]ObjXDiff
6a25: 0a asl A ;Is the MSB of the positions the same?
6a26: f0 0c beq CalcObjYDiff ;If so, possible hit. Branch to calculate the Y difference
6a28: 10 6d bpl HitDetNextObj2_ ;Distance too great, no chance of a hit; move to next object
6a2a: 49 fe eor #%11111110 ;Negative value calculated; get ABS
6a2c: d0 69 bne HitDetNextObj2_ ;Is MSB the same? IF not, distance too great; move to next object
6a2e: a5 08 lda ]ObjXDiff ;Need to convert XDiff to ABS since its negative
6a30: 49 ff eor #$ff ;Perform 1s compliment; it is now its ABS value-1
6a32: 85 08 sta ]ObjXDiff
;
6a34: b9 d2 02 CalcObjYDiff lda AstYPosLo,y
6a37: 38 sec ;Subtract objects 1 and 2 lower byte of
6a38: fd ed 02 sbc ShipYPosLo,x ; their X positions and save the result
6a3b: 85 09 sta ]ObjYDiff
6a3d: b9 8c 02 lda AstYPosHi,y ;Subtract objects 1 and 2 upper byte of their Y positions
6a40: fd a7 02 sbc ShipYPosHi,x
6a43: 4a lsr A ;Keep bit 8 in the difference; YDiff holds bits 8 to 1
6a44: 66 09 ror ]ObjYDiff
6a46: 0a asl A ;Is the MSB of the positions the same?
6a47: f0 0c beq HitDetPart2 ;If so, possible hit; branch to calculate further
6a49: 10 4c bpl HitDetNextObj2_ ;Distance too great; no chance of a hit; move to next object
6a4b: 49 fe eor #%11111110 ;Negative value calculated; get ABS
6a4d: d0 48 bne HitDetNextObj2_ ;Is MSB the same? IF not, distance too great; move to next object
6a4f: a5 09 lda ]ObjYDiff ;Need to convert YDiff to ABS since its negative
6a51: 49 ff eor #$ff ;Perform 1s compliment. It is now its ABS value-1.
6a53: 85 09 sta ]ObjYDiff
;
6a55: a9 2a HitDetPart2 lda #42 ;Small asteroid hit box 42 X 42 from center
6a57: 46 0b lsr ]Obj2Status ;Is this a small asteroid, ship or saucer?
6a59: b0 08 bcs HitDetShip ;If so, branch
6a5b: a9 48 lda #72 ;Medium asteroid hit box 72 X 72 from center
6a5d: 46 0b lsr ]Obj2Status ;Is this a medium asteroid or a saucer?
6a5f: b0 02 bcs HitDetShip ;If so, branch
6a61: a9 84 lda #132 ;Large asteroid hit box 132 X 132 from center
;
6a63: e0 01 HitDetShip cpx #$01 ;Is object 1 not the player's ship?
6a65: b0 02 bcs HitDetSaucer ;If not, branch.
6a67: 69 1c adc #28 ;Ship hit box 42+28 = 70 X 70 from center
6a69: d0 0c HitDetSaucer bne CheckObjHit ;Is object a saucer? If not, branch
6a6b: 69 12 adc #18 ;Small saucer hit box 42+18 = 60 X 60 from center
6a6d: ae 1c 02 ldx ScrStatus
6a70: ca dex ;Is the object a small saucer?
6a71: f0 02 beq HitDetFinishScr ;If so, branch
6a73: 69 12 adc #18 ;Large saucer hit box 42+18+18 = 78 X 78 from center
6a75: a2 01 HitDetFinishScr ldx #$01 ;Reload object 1 as a saucer
;
]ObjHitBox .var $0b {addr/1}
6a77: c5 08 CheckObjHit cmp ]ObjXDiff ;Is object 1 X difference smaller than the hit box?
6a79: 90 1c bcc HitDetNextObj2_ ;If not, no hit detected. Branch to check next object
6a7b: c5 09 cmp ]ObjYDiff ;Is object 1 Y difference smaller than the hit box?
6a7d: 90 18 bcc HitDetNextObj2_ ;If not, no hit detected. Branch to check next object
6a7f: 85 0b sta ]ObjHitBox ;Store hit box value
6a81: 4a lsr A ;/2
6a82: 18 clc ;Add two hit box values together
6a83: 65 0b adc ]ObjHitBox ;Hit box value is now 1.5 X value set above, about sqrt(2)
6a85: 85 0b sta ]ObjHitBox ;This has the effect of making the hit box more circular
6a87: a5 09 lda ]ObjYDiff ;Add the two difference values together
6a89: 65 08 adc ]ObjXDiff ;If it causes a carry, The distance is too great
6a8b: b0 0a bcs HitDetNextObj2_ ;Branch to move to next object
6a8d: c5 0b cmp ]ObjHitBox ;Is combined difference values greater than the hit box?
6a8f: b0 06 bcs HitDetNextObj2_ ;If so, branch to move to the next object
6a91: 20 0f 6b jsr DoObjHit ;Update object that got hit.
6a94: 4c f9 69 HitDetNextObj1_ jmp HitDetNextObj1 ;Check next object 1 for a hit
6a97: 88 HitDetNextObj2_ dey ;Are there more object 2s to check?
6a98: 30 fa bmi HitDetNextObj1_ ;If not, branch to move to the next object 1
6a9a: 4c 0a 6a jmp HitDetObj2Loop ;Check next object 2 for a hit
;
; Asteroid update routine.
;
]GenByte08 .var $08 {addr/1}
6a9d: b9 00 02 UpdateAsteroid lda AstStatus,y
6aa0: 29 07 and #%00000111 ;Save current asteroid size.
6aa2: 85 08 sta ]GenByte08
6aa4: 20 b5 77 jsr GetRandNum ;Get a random number
6aa7: 29 18 and #%00011000 ;Use it to set the asteroid type.
6aa9: 05 08 ora ]GenByte08
6aab: 9d 00 02 sta AstStatus,x ;Save asteroid size and type.
;
6aae: b9 af 02 lda AstXPosLo,y
6ab1: 9d af 02 sta AstXPosLo,x ;Save asteroid X position
6ab4: b9 69 02 lda AstXPosHi,y
6ab7: 9d 69 02 sta AstXPosHi,x
6aba: b9 d2 02 lda AstYPosLo,y
6abd: 9d d2 02 sta AstYPosLo,x ;Save asteroid Y position
6ac0: b9 8c 02 lda AstYPosHi,y
6ac3: 9d 8c 02 sta AstYPosHi,x
6ac6: b9 23 02 lda AstXSpeed,y
6ac9: 9d 23 02 sta AstXSpeed,x ;Save asteroid velocity
6acc: b9 46 02 lda AstYSpeed,y
6acf: 9d 46 02 sta AstYSpeed,x
6ad2: 60 rts
;
; Ship draw routine.
;
• Clear variables
]ShipDrawXInv .var $08 {addr/1}
]ShipDrawYInv .var $09 {addr/1}
]VecPtr .var $0b {addr/2}
6ad3: 85 0b DrawShip sta ]VecPtr ;Save the pointer to the ship vector data
6ad5: 86 0c stx ]VecPtr+1
6ad7: a0 00 SetVecRAMData ldy #$00 ;Start at beginning of vector data
6ad9: c8 GetShipOpCode iny ;Get opcode byte from vector ROM
6ada: b1 0b lda (]VecPtr),y
6adc: 45 09 eor ]ShipDrawYInv
6ade: 91 02 sta (VecRamPtr),y ;Invert Y axis of VCTR data, if necessary
6ae0: 88 dey
6ae1: c9 f0 cmp #SvecOpcode ;Is this a SVEC vector opcode?
6ae3: b0 1e bcs DrawShipSVEC ;If so, branch to get the next SVEC byte
6ae5: c9 a0 cmp #LabsOpcode ;Is this a LABS opcode?
6ae7: b0 16 bcs DrawShipRTSL ;If not, branch because it must be an RTSL opcode
;
6ae9: b1 0b lda (]VecPtr),y ;Load second byte of VCTR data into vector RAM
6aeb: 91 02 sta (VecRamPtr),y
6aed: c8 iny
6aee: c8 iny ;Move to 3rd byte of VCTR data and store in vector RAM
6aef: b1 0b lda (]VecPtr),y
6af1: 91 02 sta (VecRamPtr),y
6af3: c8 iny
6af4: b1 0b lda (]VecPtr),y ;Move to 4th byte of VCTR data
6af6: 45 08 eor ]ShipDrawXInv ;Invert X axis of VCTR data, if necessary
6af8: 65 17 adc ShipDrawUnused
6afa: 91 02 sta (VecRamPtr),y ;Store 4th byte in vector RAM
6afc: c8 NextShipOpCode iny
6afd: d0 da bne GetShipOpCode ;Branch always
6aff: 88 DrawShipRTSL dey ;Done with this segment of ship vector data
6b00: 4c 39 7c jmp VecPtrUpdate ;Update Vector RAM pointer
6b03: b1 0b DrawShipSVEC lda (]VecPtr),y ;Load second byte of SVEC data into vector RAM
6b05: 45 08 eor ]ShipDrawXInv ;Invert X axis of SVEC data, if necessary
6b07: 18 clc
6b08: 65 17 adc ShipDrawUnused
6b0a: 91 02 sta (VecRamPtr),y
6b0c: c8 iny ;Branch always
6b0d: d0 ed bne NextShipOpCode
;
; Update hit object.
;
6b0f: e0 01 DoObjHit cpx #$01 ;Is object 1 that hit object 2 a saucer?
6b11: d0 08 bne ChkObj1Ship ;If not, branch
6b13: c0 1b cpy #ShipIndex ;Is object 2 that got hit the ship?
6b15: d0 12 bne ObjExplode ;If not, branch
6b17: a2 00 ldx #$00 ;Set object 1 as the ship
6b19: a0 1c ldy #ScrIndex ;Set object 2 as the saucer
6b1b: 8a ChkObj1Ship txa ;Is object 1 the ship?
6b1c: d0 1e bne ClearObjRAM ;If not, branch
;
6b1e: a9 81 lda #$81 ;Indicate the ship is waiting to re-spawn
6b20: 8d fa 02 sta ShipSpawnTmr
6b23: a6 18 ldx CurrentPlyr ;Remove a life from the current player
6b25: d6 57 dec Plyr1Ships,x
6b27: a2 00 ldx #$00 ;Indicate ship is object 1
;
6b29: a9 a0 ObjExplode lda #$a0 ;Indicate object is exploding
6b2b: 9d 1b 02 sta ShipStatus,x
6b2e: a9 00 lda #$00
6b30: 9d 3e 02 sta ShipXSpeed,x ;Zero out the ship's velocity
6b33: 9d 61 02 sta ShipYSpeed,x
6b36: c0 1b cpy #$1b ;Is object 2 an asteroid?
6b38: 90 0d bcc ObjAsteroid ;If so, branch
6b3a: b0 37 bcs SaucerHit ;Must have been a saucer hit; branch always
6b3c: a9 00 ClearObjRAM lda #$00 ;Remove the hit object from RAM
6b3e: 9d 1b 02 sta ShipStatus,x
6b41: c0 1b cpy #ShipIndex ;Is object 2 the ship?
6b43: f0 21 beq Obj2ShipHit ;If so, branch
6b45: b0 2c bcs SaucerHit ;Was object 2 a saucer? If so, branch
;
6b47: 20 ec 75 ObjAsteroid jsr BreakAsteroid ;Break down a hit asteroid
6b4a: b9 00 02 ObjHitSFX lda AstStatus,y ;Change length of hit SFX based on object size
6b4d: 29 03 and #%00000011
6b4f: 49 02 eor #%00000010
6b51: 4a lsr A
6b52: 6a ror A
6b53: 6a ror A
6b54: 09 3f ora #$3f ;Set hit SFX minimum time
6b56: 85 69 sta ExplsnSFXTimer ;Set hit SFX time
6b58: a9 a0 lda #$a0 ;Indicate object is exploding
6b5a: 99 00 02 sta AstStatus,y
6b5d: a9 00 lda #$00
6b5f: 99 23 02 sta AstXSpeed,y ;Zero out object velocity.
6b62: 99 46 02 sta AstYSpeed,y
6b65: 60 rts
6b66: 8a Obj2ShipHit txa ;Get index to current player's reserve ships
6b67: a6 18 ldx CurrentPlyr
6b69: d6 57 dec Plyr1Ships,x ;Remove a life from the current player
6b6b: aa tax
6b6c: a9 81 lda #$81 ;Indicate the ship is waiting to re-spawn
6b6e: 8d fa 02 sta ShipSpawnTmr
6b71: d0 d7 bne ObjHitSFX ;Branch always
6b73: ad f8 02 SaucerHit lda ScrTmrReload ;Reset the saucer timer.
6b76: 8d f7 02 sta ScrTimer
6b79: a5 1c lda NumPlayers ;Is someone playing the game?
6b7b: f0 cd beq ObjHitSFX ;If not, branch to skip updating score
6b7d: 86 0d stx GenByte0D ;Save object 1 index
6b7f: a6 19 ldx ScoreIndex ;Get index to current player's score
6b81: ad 1c 02 lda ScrStatus ;Check to see if a small saucer was hit
6b84: 4a lsr A
6b85: a9 99 lda #SmallScrPnts ;Prepare to add small saucer points to score
6b87: b0 02 bcs AddSaucerPoints ;Was a small saucer hit? If so, branch
6b89: a9 20 lda #LargeScrPnts ;A large saucer was hit. Load large saucer points.
6b8b: 20 97 73 AddSaucerPoints jsr UpdateScore ;Add points to the current player's score
6b8e: a6 0d ldx GenByte0D ;Restore object 1 index
6b90: 4c 4a 6b jmp ObjHitSFX ;Set SFX for object being hit based on object size
;
; Update saucer routines.
;
• Clear variables
]GenByte08 .var $08 {addr/1}
6b93: a5 5c UpdateScr lda FrameTimer ;Update saucers only every 4th frame
6b95: 29 03 and #$03 ;Is this the 4th frame?
6b97: f0 01 beq ChkScrExplode ;If so, branch to continue processing
6b99: 60 EndUpdateScr rts ;End update saucer routines
6b9a: ad 1c 02 ChkScrExplode lda ScrStatus ;Is the saucer currently exploding?
6b9d: 30 fa bmi EndUpdateScr ;If so, branch to exit
6b9f: f0 03 beq DoScrTimers ;Is no saucer active? if so, branch to update saucer timers
6ba1: 4c 34 6c jmp ScrYVelocity ;Saucer active. Update saucer Y velocity
6ba4: a5 1c DoScrTimers lda NumPlayers ;Is a game currently being played?
6ba6: f0 07 beq DoScrTmrUpdate ;If not, branch to continue
6ba8: ad 1b 02 lda ShipStatus ;Is the player's ship exploding or in hyperspace?
6bab: f0 ec beq EndUpdateScr ;If so, branch to exit saucer update routines
6bad: 30 ea bmi EndUpdateScr
6baf: ad f9 02 DoScrTmrUpdate lda AstBreakTimer ;Was an asteroid just hit?
6bb2: f0 03 beq UpdateScrTimer ;If not, branch to update saucer timer
6bb4: ce f9 02 dec AstBreakTimer ;Decrement asteroid hit timer
6bb7: ce f7 02 UpdateScrTimer dec ScrTimer ;Is it time to re-spawn a saucer?
6bba: d0 dd bne EndUpdateScr ;If not, branch to exit
;
6bbc: a9 01 lda #$01 ;Time to re-spawn a saucer. set timer just above 0
6bbe: 8d f7 02 sta ScrTimer ; Just in case another factor keeps it from spawning
6bc1: ad f9 02 lda AstBreakTimer ;Was an asteroid just hit?
6bc4: f0 0a beq GenNewSaucer ;If not, branch to spawn a saucer
6bc6: ad f6 02 lda CurAsteroids ;If an asteroid was just hit and it was the last asteroid,
6bc9: f0 ce beq EndUpdateScr ; branch to end function; no saucer spawn on an empty screen
6bcb: cd fd 02 cmp ScrSpeedup ;Has the asteroid number hit the saucer spawn speedup threshold?
6bce: b0 c9 bcs EndUpdateScr ;If not, branch to end.
;
6bd0: ad f8 02 GenNewSaucer lda ScrTmrReload
6bd3: 38 sec ;Saucer spawn speedup threshold hit. decrement saucer timer by 6
6bd4: e9 06 sbc #$06
6bd6: c9 20 cmp #32 ;Is spawn timer below minimum value of 32?
6bd8: 90 03 bcc InitNewSaucer ;If so, branch to initialize the new saucer
6bda: 8d f8 02 sta ScrTmrReload ;Maintain a minimum saucer spawn timer
;
6bdd: a9 00 InitNewSaucer lda #$00
6bdf: 8d cb 02 sta ScrXPosLo ;Start saucer at left edge of the display
6be2: 8d 85 02 sta ScrXPosHi
6be5: 20 b5 77 jsr GetRandNum ;Get a random number
6be8: 4a lsr A
6be9: 6e ee 02 ror ScrYPosLo
6bec: 4a lsr A ;Use three of the random bits to set the saucer Y position
6bed: 6e ee 02 ror ScrYPosLo
6bf0: 4a lsr A
6bf1: 6e ee 02 ror ScrYPosLo
6bf4: c9 18 cmp #$18 ;Is remaining random bits greater than limit?
6bf6: 90 02 bcc SetScrYPosHi ;If not, branch
6bf8: 29 17 and #$17 ;Limit max Y position high byte.
6bfa: 8d a8 02 SetScrYPosHi sta ScrYPosHi ;Set high byte of saucer Y starting position
6bfd: a2 10 ldx #$10 ;Randomly set saucer X movement direction
6bff: 24 60 bit RandNum+1 ;Is saucer moving from left to right?
6c01: 70 0c bvs ScrXVelocity ;If so, branch
6c03: a9 1f lda #$1f
6c05: 8d 85 02 sta ScrXPosHi ;Start saucer at right edge of the display
6c08: a9 ff lda #$ff
6c0a: 8d cb 02 sta ScrXPosLo
6c0d: a2 f0 ldx #$f0 ;Set saucer X velocity for a negative direction(right to left)
6c0f: 8e 3f 02 ScrXVelocity stx SaucerXSpeed ;Save final saucer X velocity
;
6c12: a2 02 ldx #$02 ;Prepare to make a large saucer
6c14: ad f8 02 lda ScrTmrReload ;Is it still early in the asteroid wave?
6c17: 30 17 bmi SetScrStatus ;If so, branch to create a large saucer
6c19: a4 19 ldy ScoreIndex ;Is the player's score above 3000?
6c1b: b9 53 00 lda PlayerScores+1,y
6c1e: c9 30 cmp #$30
6c20: b0 0d bcs SetSmallScr ;If so, branch to create a small saucer
6c22: 20 b5 77 jsr GetRandNum ;Get a random number.
6c25: 85 08 sta ]GenByte08
6c27: ad f8 02 lda ScrTmrReload ;Is the random number smaller than the saucer timer
6c2a: 4a lsr A ; reload value / 2? If so, create a small saucer
6c2b: c5 08 cmp ]GenByte08
6c2d: b0 01 bcs SetScrStatus ;Else branch to create a large saucer.
6c2f: ca SetSmallScr dex ;X=1; create a small saucer
6c30: 8e 1c 02 SetScrStatus stx ScrStatus ;Store size of saucer and exit
6c33: 60 rts
;
; For the routines below, a saucer is already active. These routines update the
; active saucer.
;
6c34: a5 5c ScrYVelocity lda FrameTimer ;Randomly change saucer Y velocity every 128 frames
6c36: 0a asl A ;Is it time to change the saucer's Y velocity?
6c37: d0 0c bne ChkScrUpdate ;If not, branch
6c39: 20 b5 77 jsr GetRandNum ;Get a random number
6c3c: 29 03 and #%00000011 ;Keep the lower 2 bits for index into table below
6c3e: aa tax
6c3f: bd d1 6c lda ScrYSpeedTbl,x ;Load new Y velocity value for the saucer
6c42: 8d 62 02 sta SaucerYSpeed
6c45: a5 1c ChkScrUpdate lda NumPlayers ;Is a game being played?
6c47: f0 05 beq ChkScrFire ;If not, branch to check saucer fire timer
6c49: ad fa 02 lda ShipSpawnTmr ;Is the player actively playing?
6c4c: d0 05 bne ScrUpdateEnd ;If not, branch to exit
6c4e: ce f7 02 ChkScrFire dec ScrTimer ;Is it time for the saucer's next action?
6c51: f0 01 beq ScrUpdateAction ;If so, branch to do saucer's next action
6c53: 60 ScrUpdateEnd rts
6c54: a9 0a ScrUpdateAction lda #$0a ;Reload saucer timer for next saucer action
6c56: 8d f7 02 sta ScrTimer
6c59: ad 1c 02 lda ScrStatus ;Is this a big of small saucer?
6c5c: 4a lsr A ;If its a large saucer, prepare to shoot a random shot
6c5d: f0 06 beq GetScrShpDistance ;If its a small saucer, prepare to shoot an aimed shot
6c5f: 20 b5 77 jsr GetRandNum ;Get a random number
6c62: 4c c2 6c jmp ScrShoot ;Prepare to generate a saucer bullet
GetScrShpDistance
6c65: ad 3f 02 lda SaucerXSpeed ;Get saucer X direction velocity
6c68: c9 80 cmp #$80
6c6a: 6a ror A ;/2 with sign extension
6c6b: 85 0c sta GenByte0C ;Save result
6c6d: ad ca 02 lda ShipXPosLo
6c70: 38 sec ;Get difference between saucer and ship X position low byte
6c71: ed cb 02 sbc ScrXPosLo
6c74: 85 0b sta GenByte0B ;Save result
6c76: ad 84 02 lda ShipXPosHi ;Get difference between saucer and ship X position high byte
6c79: ed 85 02 sbc ScrXPosHi
6c7c: 20 ec 77 jsr NextScrShpDist ;Calculate next frame saucer/ship X distance
6c7f: c9 40 cmp #$40 ;Is the saucer to the left of the ship?
6c81: 90 06 bcc SetSmallScrShotDir ;If so, branch to shoot bullet to the right
6c83: c9 c0 cmp #$c0 ;Is saucer to the far right of the ship?
6c85: b0 02 bcs SetSmallScrShotDir ;If so, branch to shoot bullet to right so it can screen wrap
6c87: 49 ff eor #$ff ;Change sign so bullet can shoot left
SetSmallScrShotDir
6c89: aa tax ;Save X distance data for bullet
;
6c8a: ad 62 02 lda SaucerYSpeed ;Get saucer Y velocity and set carry if traveling
6c8d: c9 80 cmp #$80 ; in a negative direction
6c8f: 6a ror A ;Divide speed by 2 and set MSB based on Y direction
6c90: 85 0c sta GenByte0C
6c92: ad ed 02 lda ShipYPosLo
6c95: 38 sec ;Get difference between saucer and ship X position low byte
6c96: ed ee 02 sbc ScrYPosLo
6c99: 85 0b sta GenByte0B ;Save result
6c9b: ad a7 02 lda ShipYPosHi ;Get difference between saucer and ship X position high byte
6c9e: ed a8 02 sbc ScrYPosHi
6ca1: 20 ec 77 jsr NextScrShpDist ;Calculate next frame saucer/ship Y distance
6ca4: a8 tay ;Save Y distance data for bullet
;
6ca5: 20 f0 76 jsr CalcScrShotDir ;Calculate the small saucer's shot direction
6ca8: 85 62 sta ScrBulletDir ;Saucer shot direction is the same type of data as ship direction
6caa: 20 b5 77 jsr GetRandNum ;Get a random number
6cad: a6 19 ldx ScoreIndex
6caf: b4 53 ldy PlayerScores+1,x ;Is the player's score less than 35,000?
6cb1: c0 35 cpy #$35 ;If so, add inaccuracy to small saucer's bullet
6cb3: a2 00 ldx #$00
6cb5: 90 01 bcc ScrShotAddOffset
6cb7: e8 inx ;Player's score is high, make saucer shot more accurate
ScrShotAddOffset
6cb8: 3d cd 6c and ShotRndAddTbl,x ;Mask random value to randomize saucer bullet
6cbb: 10 03 bpl RandomizeScrShot
6cbd: 1d cf 6c ora ShotRndAddTbl+2,x ;Is random value negative? If so, adjust bullet velocity.
RandomizeScrShot
6cc0: 65 62 adc ScrBulletDir ;Add randomized value to small saucer shot
6cc2: 85 62 ScrShoot sta ScrBulletDir ;Prepare to fire a bullet if a slot is available
]NumBulletSlots .var $0e {addr/1}
6cc4: a0 03 ldy #$03 ;Start index for saucer bullet slots
6cc6: a2 01 ldx #$01 ;2 bullet slots for the saucer
6cc8: 86 0e stx ]NumBulletSlots
6cca: 4c f2 6c jmp FindBulletSlot ;Find an empty saucer bullet slot
6ccd: 8f 87 ShotRndAddTbl .bulk $8f,$87 ;Mask for random value to add to small saucer shot
6ccf: 70 78 .bulk $70,$78 ;If negative random, set bits to bring it close to the ship
; This table sets the saucer Y velocity. It is randomly set and moves the
; saucer diagonally across the screen.
6cd1: f0 ScrYSpeedTbl .dd1 $f0 ;-16 moving down
6cd2: 00 .dd1 $00 ; 0 no Y velocity
6cd3: 00 .dd1 $00 ; 0 no Y velocity
6cd4: 10 .dd1 $10 ;+16 moving up
6cd5: 00 00 .junk 2 ;unused
;
; Update ship routine.
;
6cd7: a5 1c UpdateShip lda NumPlayers ;Is a game currently being played?
6cd9: f0 21 beq EndUpdateShip ;If not, branch to exit
6cdb: 0e 04 20 asl FireSw ;Shift current state of fire button into shift register
6cde: 66 63 ror ShipBulletSR
6ce0: 24 63 bit ShipBulletSR ;Is MSB of bullet shift register set?
6ce2: 10 18 bpl EndUpdateShip ;If not, branch to exit; limits fire rate
6ce4: 70 16 bvs EndUpdateShip ;Is bit 6 set? If so, branch to exit; prevents auto fire
6ce6: ad fa 02 lda ShipSpawnTmr ;Is ship waiting to spawn?
6ce9: d0 11 bne EndUpdateShip ;If so, branch to exit
6ceb: aa tax ;Zero out X; indicates ship is updating in following functions
6cec: a9 03 lda #$03 ;Prepare to check 4 bullet slots
6cee: 85 0e sta ]NumBulletSlots
6cf0: a0 07 ldy #$07 ;Set index to ship bullet slots.
; Bullet generation routine. The functions below are used for both ship bullets
; and saucer bullets.
6cf2: b9 1b 02 FindBulletSlot lda ShipStatus,y ;Get ship/saucer bullet status
6cf5: f0 06 beq BulletSlotFound ;Is slot available? If so, branch to continue
6cf7: 88 dey ;Move to next bullet slot
6cf8: c4 0e cpy ]NumBulletSlots ;Is there more bullet slots to check?
6cfa: d0 f6 bne FindBulletSlot ;If so, branch check next bullet slot
6cfc: 60 EndUpdateShip rts ;Done updating bullets
• Clear variables
]ObjectXPosNeg .var $08 {addr/1}
]ShotXDir .var $09 {addr/1}
]ObjectYPosNeg .var $0b {addr/1}
]ShotYDir .var $0c {addr/1}
]ShipScrShot .var $0d {addr/1}
6cfd: 86 0d BulletSlotFound stx ]ShipScrShot ;Store index to bullet type being processed
6cff: a9 12 lda #18 ;Set bullet to last for 18 frames
6d01: 99 1b 02 sta ShipStatus,y
6d04: b5 61 lda ShipDir,x ;Get ship direction/saucer bullet direction
6d06: 20 d2 77 jsr CalcXThrust ;Calculate X velocity for the bullet
6d09: a6 0d ldx ]ShipScrShot ;Reload index to ship direction/saucer bullet direction
6d0b: c9 80 cmp #$80 ;Is ship/bullet facing left? If so, set carry bit
6d0d: 6a ror A ;Divide direction value by 2 and save carry bit in MSB
6d0e: 85 09 sta ]ShotXDir
6d10: 18 clc ;Add X velocity change to existing velocity
6d11: 7d 3e 02 adc ShipXSpeed,x ;Is this a right to left traveling object?
6d14: 30 08 bmi ChkMaxNegXVel ;If so, branch to set a velocity limit
6d16: c9 70 cmp #112 ;Must be a left to right moving object
6d18: 90 0a bcc SaveObjXVel ;Has max X velocity been reached? if so, branch
6d1a: a9 6f lda #111 ;Set maximum X velocity (111 pixels per frame)
6d1c: d0 06 bne SaveObjXVel ;Branch always
6d1e: c9 91 ChkMaxNegXVel cmp #145 ;Has max X velocity been reached (right to left)?
6d20: b0 02 bcs SaveObjXVel ;If not, branch
6d22: a9 91 lda #$91 ;Maximum negative X velocity (-111 pixels per frame)
6d24: 99 3e 02 SaveObjXVel sta ShipXSpeed,y ;Save updated X velocity. Done only once for bullets
6d27: b5 61 lda ShipDir,x ;Get ship direction/saucer bullet direction
6d29: 20 d5 77 jsr CalcThrustDir ;Calculate Y velocity for the bullet
6d2c: a6 0d ldx ]ShipScrShot ;Reload index to ship direction/saucer bullet direction
6d2e: c9 80 cmp #$80 ;Is ship/bullet facing downward? If so, set carry bit
6d30: 6a ror A ;Divide direction value by 2 and save carry bit in MSB
6d31: 85 0c sta ]ShotYDir
6d33: 18 clc ;Add Y velocity change to existing velocity
6d34: 7d 61 02 adc ShipYSpeed,x ;Is this a top to bottom traveling object?
6d37: 30 08 bmi ChkMaxNegYVel ;If so, branch to set a velocity limit
6d39: c9 70 cmp #112 ;Must be a bottom to top moving object
6d3b: 90 0a bcc SaveObjYVel ;Has max Y velocity been reached? if so, branch
6d3d: a9 6f lda #111 ;Set maximum Y velocity (111 pixels per frame)
6d3f: d0 06 bne SaveObjYVel
6d41: c9 91 ChkMaxNegYVel cmp #145 ;Has max Y velocity been reached (top to bottom)?
6d43: b0 02 bcs SaveObjYVel ;If not, branch
6d45: a9 91 lda #145 ;Maximum negative Y velocity (-111 pixels per frame)
6d47: 99 61 02 SaveObjYVel sta ShipYSpeed,y ;Save updated Y velocity; done only once for bullets
6d4a: a2 00 ldx #$00 ;Assume shot moving left to right
6d4c: a5 09 lda ]ShotXDir ;Is shot moving left to right?
6d4e: 10 01 bpl SetShotXPos ;If so, branch
6d50: ca dex ;Shot is moving right to left
6d51: 86 08 SetShotXPos stx ]ObjectXPosNeg ;Store value used for properly updating shot X position
;
6d53: a6 0d ldx ]ShipScrShot ;Reload index to ship direction/saucer bullet direction
6d55: c9 80 cmp #$80 ;Is ship/bullet facing left? If so, set carry bit
6d57: 6a ror A ;Divide direction value by 2 and save carry bit in MSB
6d58: 18 clc ;Add value to the bullet X direction
6d59: 65 09 adc ]ShotXDir
6d5b: 18 clc
6d5c: 7d ca 02 adc ShipXPosLo,x ;Update lower byte of shot X position
6d5f: 99 ca 02 sta ShipXPosLo,y
6d62: a5 08 lda ]ObjectXPosNeg
6d64: 7d 84 02 adc ShipXPosHi,x ;Update upper byte of shot X position with proper sign
6d67: 99 84 02 sta ShipXPosHi,y
6d6a: a2 00 ldx #$00 ;Assume shot moving bottom to top
6d6c: a5 0c lda ]ShotYDir ;Is shot moving bottom to top?
6d6e: 10 01 bpl SetShotYPos ;If so, branch
6d70: ca dex ;Shot is moving top to bottom
6d71: 86 0b SetShotYPos stx ]ObjectYPosNeg ;Store value used for properly updating shot Y position
;
6d73: a6 0d ldx ]ShipScrShot ;Reload index to ship direction/saucer bullet direction
6d75: c9 80 cmp #$80 ;Is ship/bullet facing down? If so, set carry bit
6d77: 6a ror A ;Divide direction value by 2 and save carry bit in MSB
6d78: 18 clc ;Add value to the bullet Y direction
6d79: 65 0c adc ]ShotYDir
6d7b: 18 clc
6d7c: 7d ed 02 adc ShipYPosLo,x ;Update lower byte of shot Y position
6d7f: 99 ed 02 sta ShipYPosLo,y
6d82: a5 0b lda ]ObjectYPosNeg
6d84: 7d a7 02 adc ShipYPosHi,x ;Update upper byte of shot Y position with proper sign
6d87: 99 a7 02 sta ShipYPosHi,y
6d8a: a9 80 lda #$80
6d8c: 95 66 sta FireSFXTimer,x ;Turn on SFX for the shot fired
6d8e: 60 rts
6d8f: d6 .dd1 $d6 ;checksum byte
;
; High score message routines.
;
• Clear variables
]GlobalScale .var $00 {addr/1}
]SelInitial .var $0c {addr/1}
]InitialDebounce .var $63 {addr/1}
6d90: a5 32 ChkHighScrMsg lda Plyr1Rank ;Did one of the players get a ranking in the top 10?
6d92: 25 33 and Plyr2Rank
6d94: 10 01 bpl GetPrevPlayers ;If so, branch to keep going
6d96: 60 rts ;Else exit
6d97: a5 1a GetPrevPlayers lda PrevGamePlyrs ;Get the number of players in the game that just ended
6d99: 4a lsr A ;Was last game a single player game?
6d9a: f0 18 beq DoHighScrMsg ;If so, branch
6d9c: a0 01 ldy #PlyrText ;PLAYER
6d9e: 20 f6 77 jsr WriteText ;Write text to the display
6da1: a0 02 ldy #$02 ;Prepare to indicate player 2 high score
6da3: a6 33 ldx Plyr2Rank ;Did player 2 get a high score?
6da5: 10 01 bpl DoPlayerDigits ;If so, branch
6da7: 88 dey ;Indicate player 1 got high score
;
6da8: 84 18 DoPlayerDigits sty CurrentPlyr ;Indicate which player got the high score
6daa: a5 5c lda FrameTimer
6dac: 29 10 and #$10 ;Should the player number be displayed?
6dae: d0 04 bne DoHighScrMsg ;If not, branch
6db0: 98 tya ;Set player's digit(1 or 2)
6db1: 20 d1 7b jsr DrawDigit ;Draw a single digit on the display
;
6db4: 46 18 DoHighScrMsg lsr CurrentPlyr ;Get current player
6db6: 20 b2 73 jsr SwapRAM ;Set RAM for current player
6db9: a0 02 ldy #YrScrText ;YOUR SCORE IS ONE OF THE TEN BEST
6dbb: 20 f6 77 jsr WriteText ;Write text to the display
6dbe: a0 03 ldy #InitText ;PLEASE ENTER YOUR INITIALS
6dc0: 20 f6 77 jsr WriteText ;Write text to the display
6dc3: a0 04 ldy #PshRtText ;PUSH ROTATE TO SELECT LETTER
6dc5: 20 f6 77 jsr WriteText ;Write text to the display
6dc8: a0 05 ldy #PshHypText ;PUSH HYPERSPACE WHEN LETTER IS CORRECT
6dca: 20 f6 77 jsr WriteText ;Write text to the display
;
6dcd: a9 20 lda #$20 ;Set global scale=2(*4)
6dcf: 85 00 sta ]GlobalScale
6dd1: a9 64 lda #$64 ;X beam coordinate 4 * $64 = $190 = 400
6dd3: a2 39 ldx #$39 ;Y beam coordinate 4 * $39 = $E4 = 228
6dd5: 20 03 7c jsr MoveBeam ;Move the CRT beam to a new location
6dd8: a9 70 lda #$70 ;Set scale 7(/4)
6dda: 20 de 7c jsr SpotKill ;Draw zero vector to prevent spots on the screen
;
6ddd: a6 18 ldx CurrentPlyr
6ddf: b4 32 ldy Plyr1Rank,x ;Save the offset to the current player's initials
6de1: 84 0b sty GenByte0B
6de3: 98 tya ;Save index to player's current initial being changed
6de4: 18 clc
6de5: 65 31 adc ThisInitial
6de7: 85 0c sta ]SelInitial
6de9: 20 1a 6f jsr DrawInitial ;Draw a single initial on the display
6dec: a4 0b ldy GenByte0B ;Draw second initial
6dee: c8 iny
6def: 20 1a 6f jsr DrawInitial ;Draw a single initial on the display
6df2: a4 0b ldy GenByte0B ;Draw third initial
6df4: c8 iny
6df5: c8 iny
6df6: 20 1a 6f jsr DrawInitial ;Draw a single initial on the display
;
6df9: ad 03 20 lda HyprSpcSw ;Get hyperspace button status
6dfc: 2a rol A
6dfd: 26 63 rol ]InitialDebounce ;Roll value into debounce register
6dff: a5 63 lda ]InitialDebounce
6e01: 29 1f and #%00011111 ;Keep only lower 5 bits of debounce register
6e03: c9 07 cmp #%00000111 ;Hyperspace button must be pressed for 3 frames to register
6e05: d0 27 bne ChkScoreTimeUp ;Did player select an initial? If not, branch
6e07: e6 31 inc ThisInitial ;Move to the next initial
6e09: a5 31 lda ThisInitial
6e0b: c9 03 cmp #$03 ;Has the last initial been selected?
6e0d: 90 13 bcc NextInitial ;If not, branch
6e0f: a6 18 ldx CurrentPlyr
6e11: a9 ff lda #$ff ;Zero out the current player's rank
6e13: 95 32 sta Plyr1Rank,x
6e15: a2 00 FinishHighScore ldx #$00
6e17: 86 18 stx CurrentPlyr ;Move to player 1 and zero out initial index
6e19: 86 31 stx ThisInitial
6e1b: a2 f0 ldx #$f0 ;Reset frame timer
6e1d: 86 5d stx FrameTimer+1
6e1f: 4c b2 73 jmp SwapRAM ;Set RAM for current player
6e22: e6 0c NextInitial inc ]SelInitial ;Increment initial index
6e24: a6 0c ldx ]SelInitial
6e26: a9 f4 lda #$f4 ;Reset frame timer
6e28: 85 5d sta FrameTimer+1
6e2a: a9 0b lda #$0b ;Set value of new initial to A
6e2c: 95 34 sta HighScoreIntls,x
6e2e: a5 5d ChkScoreTimeUp lda FrameTimer+1 ;Has initial entry time expired?
6e30: d0 08 bne ScoreTimeRemain ;If not, branch
6e32: a9 ff lda #$ff
6e34: 85 32 sta Plyr1Rank ;Zero out player's ranks and finish
6e36: 85 33 sta Plyr2Rank
6e38: 30 db bmi FinishHighScore
6e3a: a5 5c ScoreTimeRemain lda FrameTimer ;Only update displayed initial every 8th frame
6e3c: 29 07 and #$07 ;Is this the 8th frame?
6e3e: d0 31 bne HighScoreEnd ;If not, branch
6e40: ad 07 24 lda RotLeftSw ;Has rotate left button been pressed?
6e43: 10 04 bpl ChkScoreRightBtn ;If not, branch
6e45: a9 01 lda #$01 ;Increment initial
6e47: d0 07 bne ChangeInitial ;Branch always
ChkScoreRightBtn
6e49: ad 06 24 lda RotRghtSw ;Has rotate right button been pressed?
6e4c: 10 23 bpl HighScoreEnd ;If not, branch to end
6e4e: a9 ff lda #$ff ;Decrement initial
;
6e50: a6 0c ChangeInitial ldx ]SelInitial ;Update the selected initial
6e52: 18 clc
6e53: 75 34 adc HighScoreIntls,x ;Does value need to wrap around to Z?
6e55: 30 10 bmi SetInitialMax ;If so, branch
6e57: c9 0b cmp #$0b ;Is initial less than the index for A?
6e59: b0 0e bcs ChkInitialMax ;If so, branch to force index to SPACE
6e5b: c9 01 cmp #$01 ;Is index for a number?
6e5d: f0 04 beq SetInitialMin ;If so, branch to force index to A
6e5f: a9 00 lda #$00 ;Set initial index to SPACE
6e61: f0 0c beq SetInitial ;Branch always
6e63: a9 0b SetInitialMin lda #$0b ;Set initial index to A
6e65: d0 08 bne SetInitial ;Branch always
6e67: a9 24 SetInitialMax lda #$24 ;Set selected initial to Z
6e69: c9 25 ChkInitialMax cmp #$25 ;Does initial index need to wrap to SPACE?
6e6b: 90 02 bcc SetInitial ;If not, branch
6e6d: a9 00 lda #$00 ;Set initial index to SPACE
6e6f: 95 34 SetInitial sta HighScoreIntls,x ;Store new initial value
6e71: a9 00 HighScoreEnd lda #$00 ;Done processing high score for this frame
6e73: 60 rts
;
; Enter hyperspace routine.
;
6e74: a5 1c EnterHyperspc lda NumPlayers ;Is a game currently being played?
6e76: f0 5f beq ChkHyprspcEnd ;If not, branch to exit
6e78: ad 1b 02 lda ShipStatus ;Is the player's ship currently exploding?
6e7b: 30 5a bmi ChkHyprspcEnd ;If so, branch to exit
6e7d: ad fa 02 lda ShipSpawnTmr ;Is the ship currently waiting to spawn?
6e80: d0 55 bne ChkHyprspcEnd ;If so, branch to exit
6e82: ad 03 20 lda HyprSpcSw ;Has the hyperspace button been pressed?
6e85: 10 50 bpl ChkHyprspcEnd ;If not, branch to exit
;
6e87: a9 00 lda #$00 ;Indicate the ship has entered hyperspace
6e89: 8d 1b 02 sta ShipStatus
6e8c: 8d 3e 02 sta ShipXSpeed ;Zero out ship velocity.
6e8f: 8d 61 02 sta ShipYSpeed
6e92: a9 30 lda #$30 ;Set ship spawn timer
6e94: 8d fa 02 sta ShipSpawnTmr
6e97: 20 b5 77 jsr GetRandNum ;Get a random number
6e9a: 29 1f and #%00011111 ;Get lower 5 bits for new ship X position
6e9c: c9 1d cmp #$1d ;Make sure value is capped
6e9e: 90 02 bcc MinHyprspcXPos ;Is value greater than the maximum allowed? If not, branch
6ea0: a9 1c lda #$1c ;Set X position to max value
6ea2: c9 03 MinHyprspcXPos cmp #$03 ;Is value less than the minimum allowed? If not, branch
6ea4: b0 02 bcs SetHyprspcXPos
6ea6: a9 03 lda #$03 ;Set X position to min value
6ea8: 8d 84 02 SetHyprspcXPos sta ShipXPosHi ;Set the new X position for the ship
;
6eab: a2 05 ldx #$05 ;Prepare to get a random number 5 times.
6ead: 20 b5 77 HyprspcRandLoop jsr GetRandNum ;Get a random number
6eb0: ca dex ;finished getting random numbers?
6eb1: d0 fa bne HyprspcRandLoop ;If not, branch to get another one
6eb3: 29 1f and #%00011111 ;Get lower 5 bits of random number
6eb5: e8 inx ;Assume a successful hyperspace jump
6eb6: c9 18 cmp #24 ;Check if random number causes a failed hyperspace jump
6eb8: 90 0c bcc MaxHyprspcYPos ;Jump failed? If not, branch
6eba: 29 07 and #%00000111 ;Take lower 3 bits of random number *2 + 4
6ebc: 0a asl A ;Is the resulting value < current number of asteroids?
6ebd: 69 04 adc #$04 ;If so, jump was unsuccessful
6ebf: cd f6 02 cmp CurAsteroids
6ec2: 90 02 bcc MaxHyprspcYPos ;Was jump successful? If so, branch
;
6ec4: a2 80 ldx #$80 ;Indicate an unsuccessful hyperspace jump.
6ec6: c9 15 MaxHyprspcYPos cmp #$15 ;Make sure value is capped.
6ec8: 90 02 bcc MinHyprspcYPos ;Is value greater than the maximum allowed? If not, branch
6eca: a9 14 lda #$14 ;Set Y position to max value
6ecc: c9 03 MinHyprspcYPos cmp #$03 ;Is value less than the minimum allowed? If not, branch
6ece: b0 02 bcs SetHyprspcYPos
6ed0: a9 03 lda #$03 ;Set Y position to min value
6ed2: 8d a7 02 SetHyprspcYPos sta ShipYPosHi ;Set the new Y position for the ship
6ed5: 86 59 stx HyprSpcFlag ;Set the success or failure of the hyperspace jump
6ed7: 60 ChkHyprspcEnd rts
;
; Initialize game variables.
;
6ed8: a9 02 InitGameVars lda #$02 ;Prepare to start wave 1 with 4 asteroids (+2 later)
6eda: 8d f5 02 sta AstPerWave
6edd: a2 03 ldx #$03 ;Is the DIP switches set for 3 ships per game?
6edf: 4e 02 28 lsr CentCMShipsSw
6ee2: b0 01 bcs InitShipsPerGame ;If so, branch
6ee4: e8 inx ;4 ships per game
InitShipsPerGame
6ee5: 86 56 stx ShipsPerGame ;Load initial ships to start this game with
6ee7: a9 00 lda #$00 ;Prepare to zero variables
6ee9: a2 03 ldx #$03
6eeb: 9d 1b 02 VarZeroLoop sta ShipStatus,x
6eee: 9d 1f 02 sta ShpShotTimer,x
6ef1: 95 52 sta Plr1ScoreBase,x ;Zero out ship status, saucer status and player scores
6ef3: ca dex
6ef4: 10 f5 bpl VarZeroLoop
6ef6: 8d f6 02 sta CurAsteroids ;Zero out current number of asteroids
6ef9: 60 rts
;
; Silence sound effects.
;
6efa: a9 00 SilenceSFX lda #$00
6efc: 8d 00 36 sta ExpPitchVol
6eff: 8d 00 3a sta ThumpFreqVol
6f02: 8d 00 3c sta SaucerSFX
6f05: 8d 01 3c sta SaucerFireSFX ;Zero out SFX control registers
6f08: 8d 03 3c sta ShipThrustSFX
6f0b: 8d 04 3c sta ShipFireSFX
6f0e: 8d 05 3c sta LifeSFX
;
6f11: 85 69 sta ExplsnSFXTimer
6f13: 85 66 sta FireSFXTimer
6f15: 85 67 sta ScrFrSFXTimer ;Zero out SFX timers
6f17: 85 68 sta ExLfSFXTimer
6f19: 60 rts
;
; Draw initial.
;
6f1a: b9 34 00 DrawInitial lda HighScoreIntls,y ;Get value of currently selected initial
6f1d: 0a asl A
6f1e: a8 tay ;Does it have a value?
6f1f: d0 14 bne DrawChar ;If so, branch to draw the initial
6f21: a5 32 lda Plyr1Rank ;Is one of the players in the top 10?
6f23: 25 33 and Plyr2Rank
6f25: 30 0e bmi DrawChar ;If not, branch to write the existing initial
6f27: a9 72 lda #$72 ;SVEC for drawing most of the underline
6f29: a2 f8 ldx #$f8
6f2b: 20 45 7d jsr VecWriteWord ;Write 2 bytes to vector RAM
6f2e: a9 01 lda #$01 ;SVEC for drawing the rest of the underline
6f30: a2 f8 ldx #$f8
6f32: 4c 45 7d jmp VecWriteWord ;Write 2 bytes to vector RAM
6f35: be d5 56 DrawChar ldx CharPtrTbl+1,y ;Draw the initial on the display
6f38: b9 d4 56 lda CharPtrTbl,y
6f3b: 4c 45 7d jmp VecWriteWord ;Write 2 bytes to vector RAM
;
; Draw reserve ship on display.
;
• Clear variables
]GlobalScale .var $00 {addr/1}
]GenByte08 .var $08 {addr/1}
6f3e: f0 16 DrawExtraLives beq EndDrawLives ;Does payer have ships in reserve? If not, branch to exit
6f40: 84 08 sty ]GenByte08 ;Create counter value for number of ships to draw
6f42: a2 d5 ldx #$d5 ;Y beam coordinate 4 * $D5 = $354 = 852
6f44: a0 e0 ldy #$e0 ;Set global scale=14(/4)
6f46: 84 00 sty ]GlobalScale
6f48: 20 03 7c jsr MoveBeam ;Move the CRT beam to a new location
6f4b: a2 da DrawLivesLoop ldx #$da ;Load JSRL to reserve ship vector data into vector RAM
6f4d: a9 54 lda #$54
6f4f: 20 fc 7b jsr VecRomJSRL ;Load JSRL command in vector RAM to vector ROM
6f52: c6 08 dec ]GenByte08 ;More ships to draw?
6f54: d0 f5 bne DrawLivesLoop ;If so, branch
6f56: 60 EndDrawLives rts
;
; Update objects routine.
;
• Clear variables
]ThisObjX .var $04 {addr/2}
]ThisObjY .var $06 {addr/2}
6f57: a2 22 UpdateObjects ldx #34 ;Prepare to check every object
6f59: bd 00 02 UpdateObjLoop lda AstStatus,x ;Is the current object active?
6f5c: d0 04 bne UpdateCurObject ;If so, branch to update it
6f5e: ca NextObjUpdate dex ;Move to next object
6f5f: 10 f8 bpl UpdateObjLoop ;Done checking objects? If not, branch to do the next one
6f61: 60 rts ;Done updating objects
6f62: 10 63 UpdateCurObject bpl UpdateObjPos ;Is current object exploding? If not, branch
6f64: 20 08 77 jsr TwosCompliment ;Calculate the 2's compliment of the value in A
6f67: 4a lsr A
6f68: 4a lsr A ;Move upper nibble to lower nibble
6f69: 4a lsr A
6f6a: 4a lsr A
6f6b: e0 1b cpx #ShipIndex ;Is it the ship that is exploding? If not, branch
6f6d: d0 07 bne IncExplosion
6f6f: a5 5c lda FrameTimer ;Update ship explosion once every other frame
6f71: 29 01 and #$01 ;Ship explosion is twice as slow as other objects
6f73: 4a lsr A ;Time to update ship explosion?
6f74: f0 01 beq SaveIncExplosion ;If not, branch
6f76: 38 IncExplosion sec ;Prepare to increment to next explosion state
SaveIncExplosion
6f77: 7d 00 02 adc AstStatus,x ;Save updated explosion timer
6f7a: 30 25 bmi ObjectExploding ;Is object still exploding? If so, branch
6f7c: e0 1b cpx #ShipIndex ;Did the ship just finish exploding?
6f7e: f0 13 beq ResetShip ;If so, branch
6f80: b0 17 bcs ResetSaucer ;Did the saucer just finish exploding? If so, branch
6f82: ce f6 02 dec CurAsteroids ;Must have been an asteroid that finished exploding
6f85: d0 05 bne ClearObjSlot ;Decrement number of asteroids. Any left? If so, branch
6f87: a0 7f ldy #$7f ;No more asteroids this wave
6f89: 8c fb 02 sty ThmpSpeedTmr ;Reset thump speed to slowest speed
6f8c: a9 00 ClearObjSlot lda #$00 ;Free up asteroid slot
6f8e: 9d 00 02 sta AstStatus,x
6f91: f0 cb beq NextObjUpdate ;Branch always to move to the next object slot
6f93: 20 e8 71 ResetShip jsr CenterShip ;Center ship on display and zero velocity
6f96: 4c 8c 6f jmp ClearObjSlot ;Set ship status to 0
6f99: ad f8 02 ResetSaucer lda ScrTmrReload ;Reset saucer timer
6f9c: 8d f7 02 sta ScrTimer
6f9f: d0 eb bne ClearObjSlot ;Branch always
6fa1: 9d 00 02 ObjectExploding sta AstStatus,x ;Save updated exploding timer
6fa4: 29 f0 and #$f0
6fa6: 18 clc ;Get scale to use for exploding object.
6fa7: 69 10 adc #$10
6fa9: e0 1b cpx #ShipIndex ;Special case. Is ship exploding?
6fab: d0 02 bne SetObjExplodeScale ;If not, branch to save exploding scale
6fad: a9 00 lda #$00 ;Prepare to set ship explode scale to 7(/4)
SetObjExplodeScale
6faf: a8 tay ;Save scale to use for object debris
6fb0: bd af 02 lda AstXPosLo,x
6fb3: 85 04 sta ]ThisObjX
6fb5: bd 69 02 lda AstXPosHi,x
6fb8: 85 05 sta ]ThisObjX+1 ;Make a copy of the object position in preparation for drawing
6fba: bd d2 02 lda AstYPosLo,x
6fbd: 85 06 sta ]ThisObjY
6fbf: bd 8c 02 lda AstYPosHi,x
6fc2: 85 07 sta ]ThisObjY+1
6fc4: 4c 27 70 jmp DoDrawObject ;Prepare to draw current object on the display
6fc7: 18 UpdateObjPos clc ;Assume object is moving from left to right
6fc8: a0 00 ldy #$00
6fca: bd 23 02 lda AstXSpeed,x ;Is object moving from left to right?
6fcd: 10 01 bpl UpdateObjXPos ;If so, branch
6fcf: 88 dey ;Indicate object moving from right to left
6fd0: 7d af 02 UpdateObjXPos adc AstXPosLo,x ;Add X velocity to current X position
6fd3: 9d af 02 sta AstXPosLo,x
6fd6: 85 04 sta ]ThisObjX ;Make a copy of location for drawing the object
6fd8: 98 tya ;Update the signed upper byte of the object X position
6fd9: 7d 69 02 adc AstXPosHi,x
6fdc: c9 20 cmp #$20 ;Is the object off the X edge of the display?
6fde: 90 0c bcc SaveObjXPos ;If not, branch
6fe0: 29 1f and #$1f ;Wrap object to the other X edge of the display
6fe2: e0 1c cpx #ScrIndex ;Is the object a saucer?
6fe4: d0 06 bne SaveObjXPos ;If not, branch
6fe6: 20 2d 70 jsr SaucerReset ;Reset saucer variables
6fe9: 4c 5e 6f jmp NextObjUpdate ;Check next object slot
6fec: 9d 69 02 SaveObjXPos sta AstXPosHi,x ;Save the updated object X position
6fef: 85 05 sta ]ThisObjX+1
6ff1: 18 clc ;Assume object is moving from top to bottom
6ff2: a0 00 ldy #$00
6ff4: bd 46 02 lda AstYSpeed,x ;Is object moving from top to bottom?
6ff7: 10 02 bpl UpdateObjYPos ;If so, branch
6ff9: a0 ff ldy #$ff ;Indicate object moving from top to bottom
6ffb: 7d d2 02 UpdateObjYPos adc AstYPosLo,x ;Add Y velocity to current Y position
6ffe: 9d d2 02 sta AstYPosLo,x
7001: 85 06 sta ]ThisObjY ;Make a copy of location for drawing the object
7003: 98 tya ;Update the signed upper byte of the object Y position
7004: 7d 8c 02 adc AstYPosHi,x
7007: c9 18 cmp #$18 ;Is the object off the Y edge of the display?
7009: 90 08 bcc SaveObjYPos ;If not, branch
700b: f0 04 beq WrapObjYPos ;Is object on Y edge border? If so, branch to wrap object
700d: a9 17 lda #$17 ;Place object at the upper edge of the display
700f: d0 02 bne SaveObjYPos ;Branch always
7011: a9 00 WrapObjYPos lda #$00 ;Put object at the bottom edge of the display
7013: 9d 8c 02 SaveObjYPos sta AstYPosHi,x ;Save the updated object Y position
7016: 85 07 sta ]ThisObjY+1
7018: bd 00 02 lda AstStatus,x ;Reload the object status for further processing
701b: a0 e0 ldy #$e0 ;Prepare to set scale to 9(/1)
701d: 4a lsr A ;Does object exist?
701e: b0 07 bcs DoDrawObject ;If so, branch to prepare to draw current object on the display
7020: a0 f0 ldy #$f0 ;Prepare to set scale to 8(/2)
7022: 4a lsr A ;Does object exist?
7023: b0 02 bcs DoDrawObject ;If so, branch to prepare to draw current object on the display
7025: a0 00 ldy #$00 ;Prepare to set scale to 7(/4)
7027: 20 fe 72 DoDrawObject jsr DrawObject ;Draw asteroid, ship, saucer
702a: 4c 5e 6f jmp NextObjUpdate ;Check next object slot
;
; Saucer reset.
;
702d: ad f8 02 SaucerReset lda ScrTmrReload ;Reset saucer timer
7030: 8d f7 02 sta ScrTimer
7033: a9 00 lda #$00
7035: 8d 1c 02 sta ScrStatus
7038: 8d 3f 02 sta SaucerXSpeed ;Clear other saucer variables
703b: 8d 62 02 sta SaucerYSpeed
703e: 60 rts
;
; Ship status updates.
;
703f: a5 1c ChkExitHprspc lda NumPlayers ;Is a game being played?
7041: f0 42 beq ShipStsExit1 ;If not, branch to exit.
7043: ad 1b 02 lda ShipStatus ;Is the Player's ship exploding?
7046: 30 3d bmi ShipStsExit1 ;If so, branch to exit
7048: ad fa 02 lda ShipSpawnTmr ;Is the ship currently waiting to respawn?
704b: f0 39 beq ChkPlyrInput ;If not, branch
704d: ce fa 02 dec ShipSpawnTmr ;Decrement the spawn timer. Still waiting to respawn?
7050: d0 33 bne ShipStsExit1 ;If so, branch to exit
7052: a4 59 ldy HyprSpcFlag ;Did a hyperspace jump just fail?
7054: 30 19 bmi HyprspcFailed ;If so, branch
7056: d0 10 bne HyprspcSuccess ;Is ship in hyperspace? If so, branch
7058: 20 39 71 jsr IsReturnSafe ;Check to see if safe for ship to exit hyperspace
705b: d0 24 bne ResetHyprspc ;Did safety check succeed? If not, branch
705d: ac 1c 02 ldy ScrStatus ;Is a saucer on the screen?
7060: f0 06 beq HyprspcSuccess ;If not, branch to bring player out of hyperspace
7062: a0 02 ldy #$02 ;Make sure spawn timer is not 0
7064: 8c fa 02 sty ShipSpawnTmr ;Not safe to return from hyperspace
7067: 60 rts
7068: a9 01 HyprspcSuccess lda #$01 ;Indicate ship is no longer in hyperspace
706a: 8d 1b 02 sta ShipStatus
706d: d0 12 bne ResetHyprspc ;Branch always
706f: a9 a0 HyprspcFailed lda #$a0 ;Indicate the ship is exploding
7071: 8d 1b 02 sta ShipStatus
7074: a2 3e ldx #$3e ;Set the explosion SFX timer
7076: 86 69 stx ExplsnSFXTimer
7078: a6 18 ldx CurrentPlyr ;Decrement the player's extra lives
707a: d6 57 dec Plyr1Ships,x
707c: a9 81 lda #$81 ;Set the ship spawn timer
707e: 8d fa 02 sta ShipSpawnTmr
7081: a9 00 ResetHyprspc lda #$00 ;Clear the hyperspace status
7083: 85 59 sta HyprSpcFlag
7085: 60 ShipStsExit1 rts ;Exit ship status update routines
7086: ad 07 24 ChkPlyrInput lda RotLeftSw ;Is rotate left being pressed?
7089: 10 04 bpl ChkRotRight ;If not, branch
708b: a9 03 lda #$03 ;Prepare to add 3 to ship direction
708d: d0 07 bne UpdateShipDir ;Branch always
708f: ad 06 24 ChkRotRight lda RotRghtSw ;Is rotate right being pressed?
7092: 10 07 bpl ChkThrust
7094: a9 fd lda #$fd ;Prepare to subtract 3 to ship direction
7096: 18 UpdateShipDir clc
7097: 65 61 adc ShipDir ;Update ship direction
7099: 85 61 sta ShipDir
;
709b: a5 5c ChkThrust lda FrameTimer ;Update ship velocity only every other frame
709d: 4a lsr A ;Time to update ship velocity?
709e: b0 e5 bcs ShipStsExit1 ;If not, branch to exit
70a0: ad 05 24 lda ThrustSw ;Is thrust being pressed?
70a3: 10 3c bpl ShipDecelerate ;If not, branch
70a5: a9 80 lda #$80 ;Enable the ship thrust SFX
70a7: 8d 03 3c sta ShipThrustSFX
70aa: a0 00 ldy #$00 ;Assume ship is facing right (positive X direction)
70ac: a5 61 lda ShipDir ;Get ship direction in preparation for thrust calculation
70ae: 20 d2 77 jsr CalcXThrust ;Calculate thrust in X direction
70b1: 10 01 bpl UpdateShipXVel ;Is ship facing right? If so, branch
70b3: 88 dey ;Ship is facing left; set X for negative direction
70b4: 0a UpdateShipXVel asl A ;Multiply thrust value by 2
70b5: 18 clc
70b6: 65 64 adc ShipXAccel ;Add thrust to ship's X acceleration
70b8: aa tax ;Save the acceleration in X
70b9: 98 tya
70ba: 6d 3e 02 adc ShipXSpeed ;Add the acceleration to the ship's X velocity
70bd: 20 25 71 jsr ChkShipMaxVel ;Ensure ship does not exceed maximum velocity
70c0: 8d 3e 02 sta ShipXSpeed ;Save current ship X velocity and acceleration
70c3: 86 64 stx ShipXAccel
;
70c5: a0 00 ldy #$00 ;Assume ship is facing up (positive Y direction)
70c7: a5 61 lda ShipDir ;Get ship direction in preparation for thrust calculation
70c9: 20 d5 77 jsr CalcThrustDir ;Calculate thrust in Y direction
70cc: 10 01 bpl UpdateShipYVel ;Is ship facing up? If so, branch
70ce: 88 dey ;Ship is facing down; set Y for negative direction
70cf: 0a UpdateShipYVel asl A ;Multiply thrust value by 2
70d0: 18 clc
70d1: 65 65 adc ShipYAccel ;Add thrust to ship's Y acceleration
70d3: aa tax ;Save the acceleration in X
70d4: 98 tya
70d5: 6d 61 02 adc ShipYSpeed ;Add the acceleration to the ship's Y velocity
70d8: 20 25 71 jsr ChkShipMaxVel ;Ensure ship does not exceed maximum velocity
70db: 8d 61 02 sta ShipYSpeed ;Save current ship Y velocity and acceleration
70de: 86 65 stx ShipYAccel
70e0: 60 rts ;Done calculating ship acceleration
70e1: a9 00 ShipDecelerate lda #$00 ;Turn off ship thrust SFX
70e3: 8d 03 3c sta ShipThrustSFX
70e6: ad 3e 02 lda ShipXSpeed ;Does ship need to be decelerated in the X direction?
70e9: 05 64 ora ShipXAccel
70eb: f0 18 beq DecelerateY ;If not, branch to check Y deceleration
70ed: ad 3e 02 lda ShipXSpeed ;Get ship X velocity and multiply by 2
70f0: 0a asl A
70f1: a2 ff ldx #$ff ;Assume positive X velocity; X acceleration = -1
70f3: 18 clc
70f4: 49 ff eor #$ff ;Is ship traveling in the positive X direction?
70f6: 30 02 bmi SetXDecelerate ;If so, branch
70f8: e8 inx ;Ship traveling in negative X direction
70f9: 38 sec ;Set X deceleration to +1
70fa: 65 64 SetXDecelerate adc ShipXAccel ;Update ship X acceleration
70fc: 85 64 sta ShipXAccel
70fe: 8a txa
70ff: 6d 3e 02 adc ShipXSpeed ;Update ship X velocity
7102: 8d 3e 02 sta ShipXSpeed
;
7105: a5 65 DecelerateY lda ShipYAccel ;Does ship need to be decelerated in the Y direction?
7107: 0d 61 02 ora ShipYSpeed
710a: f0 18 beq DecelerateExit ;If not, branch to exit
710c: ad 61 02 lda ShipYSpeed ;Get ship Y velocity and multiply by 2
710f: 0a asl A
7110: a2 ff ldx #$ff ;Assume positive Y velocity; Y acceleration = -1
7112: 18 clc
7113: 49 ff eor #$ff ;Is ship traveling in the positive Y direction?
7115: 30 02 bmi SetYDecelerate ;If so, branch
7117: 38 sec ;Ship traveling in negative Y direction
7118: e8 inx ;Set Y deceleration to +1
7119: 65 65 SetYDecelerate adc ShipYAccel ;Update ship Y acceleration
711b: 85 65 sta ShipYAccel
711d: 8a txa
711e: 6d 61 02 adc ShipYSpeed ;Update ship Y velocity
7121: 8d 61 02 sta ShipYSpeed
7124: 60 DecelerateExit rts
7125: 30 09 ChkShipMaxVel bmi ChkMaxNegVel ;Is ship traveling left/down (negative direction)? If so, branch
7127: c9 40 cmp #$40 ;Is ship moving less than max velocity in positive direction?
7129: 90 0d bcc ChkMaxExit ;If so, branch to exit
712b: a2 ff ldx #$ff ;Max positive velocity reached; set acceleration to -1
712d: a9 3f lda #$3f ;Set velocity to max positive value
712f: 60 rts
7130: c9 c0 ChkMaxNegVel cmp #$c0 ;Is ship moving less than max velocity in negative direction?
7132: b0 04 bcs ChkMaxExit ;If so, branch to exit
7134: a2 01 ldx #$01 ;Max negative velocity reached; set acceleration to +1
7136: a9 c0 lda #$c0 ;Set velocity to max negative value
7138: 60 ChkMaxExit rts ;Done checking maximum ship velocity
;
; Safe hyperspace return routine.
;
7139: a2 1c IsReturnSafe ldx #ScrIndex ;Prepare to check all asteroids and saucer.
713b: bd 00 02 SafeCheckLoop lda AstStatus,x ;Is current object slot active?
713e: f0 1e beq NextSafeCheck ;If not, branch to move to next object
7140: bd 69 02 lda AstXPosHi,x ;Get object X position and compare to ship X position
7143: 38 sec
7144: ed 84 02 sbc ShipXPosHi
7147: c9 04 cmp #$04 ;Is object within +4 pixels of ship?
7149: 90 04 bcc SafeCheckY ;If so, branch to check object's Y position
714b: c9 fc cmp #$fc ;Is object within -4 pixels of ship?
714d: 90 0f bcc NextSafeCheck ;If not, branch to check next object's position
714f: bd 8c 02 SafeCheckY lda AstYPosHi,x ;Get object Y position and compare to ship Y position
7152: 38 sec
7153: ed a7 02 sbc ShipYPosHi
7156: c9 04 cmp #$04 ;Is object within +4 pixels of ship?
7158: 90 09 bcc SafeCheckFail ;If so, branch; not safe to exit hyperspace
715a: c9 fc cmp #$fc ;Is object within -4 pixels of ship?
715c: b0 05 bcs SafeCheckFail ;If so, branch; not safe to exit hyperspace
715e: ca NextSafeCheck dex ;Is there another object to check?
715f: 10 da bpl SafeCheckLoop ;If so, branch to check the object
7161: e8 inx ;Safe to exit hyperspace; sets X to zero
7162: 60 rts
7163: ee fa 02 SafeCheckFail inc ShipSpawnTmr ;Not safe to exit hyperspace; ensures spawn timer is not zero
7166: 60 rts
7167: 90 .dd1 $90 ;checksum byte
;
; Initialize asteroid wave variables.
;
• Clear variables
]GenByte08 .var $08 {addr/1}
7168: a2 1a InitWaveVars ldx #MaxAsteroids ;Start at highest asteroid status slot
716a: ad fb 02 lda ThmpSpeedTmr ;Is wave about to start?
716d: d0 70 bne ZeroAstStatuses ;If so, branch to skip most of this routine
716f: ad 1c 02 lda ScrStatus ;Is a saucer active?
7172: d0 73 bne EndInitWave ;If so, branch to skip this routine
7174: 8d 3f 02 sta SaucerXSpeed ;Zero out saucer speed.
7177: 8d 62 02 sta SaucerYSpeed
717a: ee fd 02 inc ScrSpeedup ;Increment the min number of asteroids that triggers saucers
717d: ad fd 02 lda ScrSpeedup ; appearing more frequently
7180: c9 0b cmp #11 ;Max value is 11 asteroids
7182: 90 03 bcc InitAstPerWave
7184: ce fd 02 dec ScrSpeedup ;Make sure value does not exceed 11 asteroids
;
7187: ad f5 02 InitAstPerWave lda AstPerWave ;Increase number of asteroids by 2 every wave
718a: 18 clc
718b: 69 02 adc #$02
718d: c9 0b cmp #11 ;Ensure 11 asteroids max per wave
718f: 90 02 bcc SetWaveAst
7191: a9 0b lda #11 ;Max initial asteroids per wave is 11
7193: 8d f6 02 SetWaveAst sta CurAsteroids ;Set the number of asteroids for the current wave
7196: 8d f5 02 sta AstPerWave
7199: 85 08 sta ]GenByte08 ;Create a counter for decrementing through all asteroid slots
;
719b: a0 1c ldy #ScrIndex ;Offset to saucer speed X and Y values
InitWaveAsteroids
719d: 20 b5 77 jsr GetRandNum ;Get a random number
71a0: 29 18 and #$18 ;Randomly select asteroid type
71a2: 09 04 ora #LargeAst ;Make it a large asteroid
71a4: 9d 00 02 sta AstStatus,x ;Store the results
71a7: 20 03 72 jsr SetAstVel ;Set asteroid X and Y velocities
71aa: 20 b5 77 jsr GetRandNum ;Get a random number
71ad: 4a lsr A ;Shift right to save LSB in carry
71ae: 29 1f and #%00011111 ;Keep lower 5 bits
71b0: 90 13 bcc AstPosScrBot ;Is carry clear? If so, start asteroid at top/bottom of screen
71b2: c9 18 cmp #$18 ;Is value beyond max Y position(6144/8=768)
71b4: 90 02 bcc AstPosScrRight ;If not, branch to set Y position
71b6: 29 17 and #$17 ;Limit Y position to < 768
71b8: 9d 8c 02 AstPosScrRight sta AstYPosHi,x ;Set asteroid Y position
71bb: a9 00 lda #$00
71bd: 9d 69 02 sta AstXPosHi,x ;Set X to 0; asteroid originates at left/right of screen
71c0: 9d af 02 sta AstXPosLo,x
71c3: f0 0b beq NextAstPos ;Branch always
71c5: 9d 69 02 AstPosScrBot sta AstXPosHi,x ;Set asteroid X position
71c8: a9 00 lda #$00
71ca: 9d 8c 02 sta AstYPosHi,x ;Set Y to 0; asteroid originates at top/bottom of screen
71cd: 9d d2 02 sta AstYPosLo,x
71d0: ca NextAstPos dex ;Move to next asteroid index
71d1: c6 08 dec ]GenByte08 ;Are there more asteroid positions to process?
71d3: d0 c8 bne InitWaveAsteroids ;If so, branch to do another one
71d5: a9 7f lda #$7f
71d7: 8d f7 02 sta ScrTimer ;Set initial saucer timer and thump SFX values
71da: a9 30 lda #$30
71dc: 8d fc 02 sta ThmpOffReload
71df: a9 00 ZeroAstStatuses lda #$00 ;Zero out the asteroid statuses
71e1: 9d 00 02 :Loop sta AstStatus,x
71e4: ca dex ;More asteroid statuses to zero?
71e5: 10 fa bpl :Loop ;If so, branch to do another
71e7: 60 EndInitWave rts
;
; Center ship on screen.
;
71e8: a9 60 CenterShip lda #$60
71ea: 8d ca 02 sta ShipXPosLo ;Set lower XY ship position bytes for screen center
71ed: 8d ed 02 sta ShipYPosLo
71f0: a9 00 lda #$00
71f2: 8d 3e 02 sta ShipXSpeed ;Set ship XY speed to 0.
71f5: 8d 61 02 sta ShipYSpeed
71f8: a9 10 lda #$10
71fa: 8d 84 02 sta ShipXPosHi
71fd: a9 0c lda #$0c ;Set upper XY ship position bytes for screen center
71ff: 8d a7 02 sta ShipYPosHi
7202: 60 rts
;
; Set asteroid velocities.
;
7203: 20 b5 77 SetAstVel jsr GetRandNum ;Get a random number
7206: 29 8f and #$8f ;Keep the sign bit and lower nibble
7208: 10 02 bpl SetAstXVel ;Is this a negative number?
720a: 09 f0 ora #$f0 ;If so, sign extend the byte
720c: 18 SetAstXVel clc ;Add the new X velocity to the old velocity
720d: 79 23 02 adc AstXSpeed,y
7210: 20 33 72 jsr GetAstVelocity ;Get an X velocity to assign to the asteroid
7213: 9d 23 02 sta AstXSpeed,x
7216: 20 b5 77 jsr GetRandNum ;Get a random number
7219: 20 b5 77 jsr GetRandNum ;Get a random number
721c: 20 b5 77 jsr GetRandNum ;Get a random number
721f: 20 b5 77 jsr GetRandNum ;Get a random number
7222: 29 8f and #%10001111 ;Keep the sign bit and lower nibble
7224: 10 02 bpl SetAstYVel ;Is this a negative number?
7226: 09 f0 ora #$f0 ;If so, sign extend the byte
7228: 18 SetAstYVel clc ;Add the new Y velocity to the old velocity
7229: 79 46 02 adc AstYSpeed,y
722c: 20 33 72 jsr GetAstVelocity ;Get a Y velocity to assign to the asteroid
722f: 9d 46 02 sta AstYSpeed,x
7232: 60 rts
7233: 10 0d GetAstVelocity bpl SetPosVel ;Is speed faster than max speed of -31?
7235: c9 e1 cmp #$e1 ;If so, branch to check min negative speed
7237: b0 02 bcs ChkNegTooSlow
7239: a9 e1 lda #$e1 ;Set max negative speed to -31
723b: c9 fb ChkNegTooSlow cmp #$fb ;Is value faster than -6?
723d: 90 0f bcc AstVelExit ;If so, branch to exit
723f: a9 fa lda #$fa ;Set minimum negative speed to -6
7241: 60 rts
7242: c9 06 SetPosVel cmp #6 ;Is speed above min speed of +6?
7244: b0 02 bcs ChkPosTooFast ;If so, branch to check max speed
7246: a9 06 lda #6 ;Set min positive speed to +6
7248: c9 20 ChkPosTooFast cmp #32 ;Is value greater than +31?
724a: 90 02 bcc AstVelExit ;If not, branch to exit
724c: a9 1f lda #31 ;Set max positive speed to +31
724e: 60 AstVelExit rts ;Return the velocity in A
;
; Update screen text.
;
• Clear variables
]GlobalScale .var $00 {addr/1}
UpdateScreenText
724f: a9 10 lda #$10 ;Set global scale=1(*2)
7251: 85 00 sta ]GlobalScale
7253: a9 50 lda #>VecCredits ;Draw copyright text at bottom of the display
7255: a2 a4 ldx #<VecCredits
7257: 20 fc 7b jsr VecRomJSRL ;Load JSRL command in vector RAM to vector ROM
725a: a9 19 lda #$19 ;X beam coordinate 4 * $19 = $64 = 100
725c: a2 db ldx #$db ;Y beam coordinate 4 * $DB = $36C = 876.
725e: 20 03 7c jsr MoveBeam ;Move the CRT beam to a new location.
7261: a9 70 lda #$70 ;Set scale 7(/4)
7263: 20 de 7c jsr SpotKill ;Draw zero vector to prevent spots on the screen
;
7266: a2 00 ldx #$00 ;Indicate number string should be drawn on the display
7268: a5 1c lda NumPlayers ;Is this a 2 player game?
726a: c9 02 cmp #$02
726c: d0 18 bne DrawPlr1Score ;If not, branch to draw just player 1's score without blinking
726e: a5 18 lda CurrentPlyr ;Is player 2 playing?
7270: d0 14 bne DrawPlr1Score ;If so, branch to draw player 1's score without blinking
7272: a2 20 ldx #$20 ;Override the zero blanking function
7274: ad 1b 02 lda ShipStatus ;Is player 1's ship in play or in hyperspace?
7277: 05 59 ora HyprSpcFlag ;If so, branch to draw player 1's score without blinking
7279: d0 0b bne DrawPlr1Score
727b: ad fa 02 lda ShipSpawnTmr ;Is player 1 waiting to respawn?
727e: 30 06 bmi DrawPlr1Score ;If so, branch to draw player 1's score without blinking
7280: a5 5c lda FrameTimer ;Blink player 1's score every 16 frames. This occurs
7282: 29 10 and #$10 ; when switching from one player to the next
7284: f0 0d beq DrawShipLives ;Time to draw the score? If not, branch to turn it off
;
7286: a9 52 DrawPlr1Score lda #Plr1ScoreBase ;Prepare to draw Player 1's score on the display
7288: a0 02 ldy #$02 ;2 bytes for player 1's score
728a: 38 sec ;Blank leading zeros
728b: 20 3f 77 jsr DrawNumberString ;Draw a string of numbers on the display
728e: a9 00 lda #$00 ;Draw a trailing zero
7290: 20 8b 77 jsr ChkSetDigitPntr ;Prepare to draw a trailing zero after the score
7293: a9 28 DrawShipLives lda #$28 ;X beam coordinate 4 * $28 = $A0 = 160
7295: a4 57 ldy Plyr1Ships ;Get current number of reserve ships for Player 1
7297: 20 3e 6f jsr DrawExtraLives ;Draw player's reserve ships on the display
729a: a9 00 lda #$00 ;Set global scale to 0(*1)
729c: 85 00 sta ]GlobalScale
729e: a9 78 lda #$78 ;X beam coordinate 4 * $78 = $1E0 = 480
72a0: a2 db ldx #$db ;Y beam coordinate 4 * $DB = $36C = 876
72a2: 20 03 7c jsr MoveBeam ;Move the CRT beam to a new location
72a5: a9 50 lda #$50 ;Set scale 5(/16)
72a7: 20 de 7c jsr SpotKill ;Draw zero vector to prevent spots on the screen
;
72aa: a9 1d lda #HighScores ;Prepare to draw the high score on the display
72ac: a0 02 ldy #$02 ;2 bytes for the high score
72ae: 38 sec ;Blank leading zeros
72af: 20 3f 77 jsr DrawNumberString ;Draw a string of numbers on the display.
72b2: a9 00 lda #$00 ;Draw a trailing zero
72b4: 20 d1 7b jsr DrawDigit ;Draw a single digit on the display
72b7: a9 10 lda #$10 ;Set global scale=1(*2)
72b9: 85 00 sta ]GlobalScale
72bb: a9 c0 lda #$c0 ;X beam coordinate 4 * $C0 = $300 = 768
72bd: a2 db ldx #$db ;Y beam coordinate 4 * $DB = $36C = 876
72bf: 20 03 7c jsr MoveBeam ;Move the CRT beam to a new location
72c2: a9 50 lda #$50 ;Set scale 5(/16)
72c4: 20 de 7c jsr SpotKill ;Draw zero vector to prevent spots on the screen
;
72c7: a2 00 ldx #$00 ;Indicate number string should be drawn on the display
72c9: a5 1c lda NumPlayers ;Is this a 2 player game?
72cb: c9 01 cmp #$01
72cd: f0 2e beq EndScreenText ;If not, branch to exit
72cf: 90 18 bcc DrawPlr2Score ;Is a game active? If not, branch to draw player 2's score
72d1: a5 18 lda CurrentPlyr ;Is player 1 playing?
72d3: f0 14 beq DrawPlr2Score ;If so, branch to draw player 2's score without blinking
72d5: a2 20 ldx #$20 ;Override the zero blanking function
72d7: ad 1b 02 lda ShipStatus ;Is player 2's ship in play or in hyperspace?
72da: 05 59 ora HyprSpcFlag ;If so, branch to draw player 2's score without blinking
72dc: d0 0b bne DrawPlr2Score
72de: ad fa 02 lda ShipSpawnTmr ;Is player 2 waiting to respawn?
72e1: 30 06 bmi DrawPlr2Score ;If so, branch to draw player 2's score without blinking
72e3: a5 5c lda FrameTimer ;Blink player 2's score every 16 frames. This occurs
72e5: 29 10 and #$10 ; when switching from one player to the next
72e7: f0 0d beq DrawPlr2Ships ;Time to draw the score? If not, branch to turn it off
72e9: a9 54 DrawPlr2Score lda #Plr2ScoreBase ;Prepare to draw Player 2's score on the display
72eb: a0 02 ldy #$02 ;2 bytes for the high score
72ed: 38 sec ;Blank leading zeros
72ee: 20 3f 77 jsr DrawNumberString ;Draw a string of numbers on the display
72f1: a9 00 lda #$00 ;Draw a trailing zero
72f3: 20 8b 77 jsr ChkSetDigitPntr ;Prepare to draw a trailing zero after the score
72f6: a9 cf DrawPlr2Ships lda #$cf ;X beam coordinate 4 * $CF = $33C = 828
72f8: a4 58 ldy Plyr2Ships ;Get current number of reserve ships for Player 2
72fa: 4c 3e 6f jmp DrawExtraLives ;Draw player's reserve ships on the display
72fd: 60 EndScreenText rts ;Done drawing screen text
;
; Draw object routines.
;
• Clear variables
]GlobalScale .var $00 {addr/1}
]ThisObjX .var $04 {addr/2}
]ThisObjY .var $06 {addr/2}
72fe: 84 00 DrawObject sty ]GlobalScale ;Save scale data
7300: 86 0d stx GenByte0D ;Save a copy of the index to the object to draw.
7302: a5 05 lda ]ThisObjX+1
7304: 4a lsr A
7305: 66 04 ror ]ThisObjX
7307: 4a lsr A ;Divide the object's X position by 8
7308: 66 04 ror ]ThisObjX
730a: 4a lsr A
730b: 66 04 ror ]ThisObjX
730d: 85 05 sta ]ThisObjX+1
;
730f: a5 07 lda ]ThisObjY+1
7311: 18 clc
7312: 69 04 adc #$04
7314: 4a lsr A
7315: 66 06 ror ]ThisObjY
7317: 4a lsr A
7318: 66 06 ror ]ThisObjY ;Add 1024 object's Y position and divide by 8
731a: 4a lsr A
731b: 66 06 ror ]ThisObjY
731d: 85 07 sta ]ThisObjY+1
;
731f: a2 04 ldx #$04 ;Prepare to write 4 bytes to vector RAM
7321: 20 1c 7c jsr SetLABSData ;Write LABS instruction in vector RAM
7324: a9 70 lda #$70 ;Set the scale of the object
7326: 38 sec
7327: e5 00 sbc ]GlobalScale
7329: c9 a0 cmp #$a0 ;Is the scale 9 or smaller?
732b: 90 0e bcc DrawSpotKill ;If so, branch
DrawMultiSpotKill
732d: 48 pha ;Save A on the stack
732e: a9 90 lda #$90 ;Set scale 9(/1)
7330: 20 de 7c jsr SpotKill ;Draw zero vector to prevent spots on the screen
7333: 68 pla ;Restore A from the stack
7334: 38 sec ;Subtract #$10 from scale value
7335: e9 10 sbc #$10 ;Is value below #$A0?
7337: c9 a0 cmp #$a0 ;If not, branch to run the spot kill routine again.
7339: b0 f2 bcs DrawMultiSpotKill
;
733b: 20 de 7c DrawSpotKill jsr SpotKill ;Draw zero vector to prevent spots on the screen
733e: a6 0d ldx GenByte0D ;Restore index to object to draw
7340: bd 00 02 lda AstStatus,x ;Is the object exploding?
7343: 10 16 bpl DrawObjNoExplode ;If not, branch to draw the normal object
7345: e0 1b cpx #ShipIndex ;Is it the ship exploding?
7347: f0 0c beq DrawShipExplode ;If so, branch
7349: 29 0c and #$0c ;Get index into shrapnel table
734b: 4a lsr A
734c: a8 tay
734d: b9 f8 50 lda SharpPatPtrTbl,y ;Store JSRL data in vector RAM for the Shrapnel graphics
7350: be f9 50 ldx SharpPatPtrTbl+1,y
7353: d0 1b bne SaveObjVecData ;Branch always
7355: 20 65 74 DrawShipExplode jsr DoShipExplsn ;Draw the ship exploding
7358: a6 0d ldx GenByte0D ;Restore index to object being drawn
735a: 60 rts ;Exit after drawing ship fragments
DrawObjNoExplode
735b: e0 1b cpx #ShipIndex ;Is it the ship that needs to be drawn?
735d: f0 17 beq DoDrawShip ;If so, branch
735f: e0 1c cpx #ScrIndex ;Is it the saucer that needs to be drawn?
7361: f0 19 beq DoDrawSaucer ;If so, branch
7363: b0 1f bcs DoDrawBullet ;Is it a bullet that needs to be drawn? If so, branch
7365: 29 18 and #$18 ;Must be an asteroid
7367: 4a lsr A
7368: 4a lsr A ;Get the asteroid type bits
7369: a8 tay
736a: b9 de 51 lda AstPtrnPtrTbl,y ;Get asteroid vector data and write it to vector RAM
736d: be df 51 ldx AstPtrnPtrTbl+1,y
7370: 20 45 7d SaveObjVecData jsr VecWriteWord ;Write 2 bytes to vector RAM.
7373: a6 0d ldx GenByte0D ;Restore index to object
7375: 60 rts ;Finished loading object data into vector RAM
7376: 20 0b 75 DoDrawShip jsr UpdateShipDraw ;Update the drawing of the player's ship
7379: a6 0d ldx GenByte0D ;Restore index to object
737b: 60 rts ;Finished loading ship data into vector RAM
737c: ad 50 52 DoDrawSaucer lda ScrPtrnPtrTbl ;Get saucer vector data and write it to vector RAM
737f: ae 51 52 ldx ScrPtrnPtrTbl+1
7382: d0 ec bne SaveObjVecData ;Branch always
7384: a9 70 DoDrawBullet lda #$70 ;Set scale 7(/4)
7386: a2 f0 ldx #$f0 ;Prepare to draw a dot at full brightness(bullet)
7388: 20 e0 7c jsr DrawDot ;Draw a dot on the screen
738b: a6 0d ldx GenByte0D ;Restore index to object
738d: a5 5c lda FrameTimer ;Decrement shot timer every 4th frame
738f: 29 03 and #$03 ;Is it time to decrement the shot timer?
7391: d0 03 bne DrawObjectDone ;If not, branch
7393: de 00 02 dec AstStatus,x ;Decrement shot timer
7396: 60 DrawObjectDone rts ;Done with object vector data
;
; Update score.
;
7397: f8 UpdateScore sed ;Put ALU into decimal mode
7398: 75 52 adc Plr1ScoreBase,x ;Add value in Accumulator to score
739a: 95 52 sta Plr1ScoreBase,x ;Does upper byte need to be updated?
739c: 90 12 bcc UpdateScoreExit ;If not, branch to exit
739e: b5 53 lda PlayerScores+1,x
73a0: 69 00 adc #$00 ;Increment upper score byte.
73a2: 95 53 sta PlayerScores+1,x
73a4: 29 0f and #$0f ;Check if extra life should be granted
73a6: d0 08 bne UpdateScoreExit ;Extra life granted at 10,000 points
;
73a8: a9 b0 lda #$b0 ;Play extra life SFX
73aa: 85 68 sta ExLfSFXTimer
73ac: a6 18 ldx CurrentPlyr ;Increment reserve ships
73ae: f6 57 inc Plyr1Ships,x
73b0: d8 UpdateScoreExit cld ;Put ALU back into binary mode
73b1: 60 rts
;
; Swap RAM.
;
]GenByte08 .var $08 {addr/1}
73b2: a5 18 SwapRAM lda CurrentPlyr ;Get current player (0 or 1 value)
73b4: 0a asl A
73b5: 0a asl A
73b6: 85 08 sta ]GenByte08 ;Move the LSB to the third bit position
;
73b8: a5 6f lda MultiPurpBits
73ba: 29 fb and #%11111011
73bc: 05 08 ora ]GenByte08 ;Set the player RAM based on the current player
73be: 85 6f sta MultiPurpBits
73c0: 8d 00 32 sta MultiPurp
73c3: 60 rts
;
; Draw high scores list.
;
• Clear variables
]GlobalScale .var $00 {addr/1}
]HiScrRank .var $0d {addr/1}
]HiScrBeamYLoc .var $0e {addr/1}
]HiScrIndex .var $0f {addr/1}
73c4: a5 1c ChkHighScrList lda NumPlayers ;Is a game currently being played?
73c6: f0 02 beq ChkDrawScrList ;If not, branch to see if its time to show the high score list
73c8: 18 SkipScrList clc ;Indicate the high scores list is not being displayed
73c9: 60 rts ;Exit high score list drawing routines
73ca: a5 5d ChkDrawScrList lda FrameTimer+1 ;Is it time to draw the high scores list?
73cc: 29 04 and #$04
73ce: d0 f8 bne SkipScrList ;If not, branch to exit
73d0: a5 1d lda HighScores ;Is the high scores list empty?
73d2: 05 1e ora HighScores+1
73d4: f0 f2 beq SkipScrList ;If so, branch to exit
;
73d6: a0 00 ldy #$00 ;Prepare to display HIGH SCORES text
73d8: 20 f6 77 jsr WriteText ;Write text to the display
73db: a2 00 ldx #$00 ;Start at the first high score index
73dd: 86 10 stx InitialIndex ;Start at the first initial index
73df: a9 01 lda #$01 ;Appears not to be used
73e1: 85 00 sta ]GlobalScale
73e3: a9 a7 lda #$a7 ;Y beam coordinate = 4 * $A7 = $29C = 668
73e5: 85 0e sta ]HiScrBeamYLoc ;Set top row of high score list
73e7: a9 10 lda #$10 ;Set global scale=1(*2)
73e9: 85 00 sta ]GlobalScale
;
73eb: b5 1d HighScoresLoop lda HighScores,x ;Is there a high score at the current location?
73ed: 15 1e ora HighScores+1,x
73ef: f0 67 beq HighScoreExit ;If not, done with high score list; branch to exit
73f1: 86 0f stx ]HiScrIndex ;Store index to the current high score
73f3: a9 5f lda #$5f ;X beam coordinate 4 * $5F = $17C = 380
73f5: a6 0e ldx ]HiScrBeamYLoc ;Set the Y beam coordinate based on current line being written
73f7: 20 03 7c jsr MoveBeam ;Move the CRT beam to a new location
73fa: a9 40 lda #$40 ;Set scale 4(/32)
73fc: 20 de 7c jsr SpotKill ;Draw zero vector to prevent spots on the screen
;
73ff: a5 0f lda ]HiScrIndex ;Get index to current high score to draw
7401: 4a lsr A
7402: f8 sed
7403: 69 01 adc #$01 ;Increment by 1 (base 10)
7405: d8 cld
7406: 85 0d sta ]HiScrRank ;Get the rank number of the current high score
7408: a9 0d lda #GenByte0D ;[HiScrRank]
740a: 38 sec ;Blank leading zeros
740b: a0 01 ldy #$01 ;Single byte for player's rank
740d: a2 00 ldx #$00 ;No override of zero blanking
740f: 20 3f 77 jsr DrawNumberString ;Draw a string of numbers on the display
7412: a9 40 lda #$40 ;Set the brightness of the dot
7414: aa tax
7415: 20 e0 7c jsr DrawDot ;Draw a dot on the screen
7418: a0 00 ldy #$00 ;Draw a SPACE on the display
741a: 20 35 6f jsr DrawChar ;Draw a single character on the display
741d: a5 0f lda ]HiScrIndex ;Move to next high score to draw
741f: 18 clc
7420: 69 1d adc #HighScores ;Prepare to draw next high score on the display
7422: a0 02 ldy #$02 ;2 bytes per high score
7424: 38 sec ;Blank leading zeros
7425: a2 00 ldx #$00 ;No override of zero blanking
7427: 20 3f 77 jsr DrawNumberString ;Draw a string of numbers on the display
742a: a9 00 lda #$00 ;Draw a trailing zero
742c: 20 d1 7b jsr DrawDigit ;Draw a single digit on the display
742f: a0 00 ldy #$00 ;Draw a SPACE on the display
7431: 20 35 6f jsr DrawChar ;Draw a single character on the display
7434: a4 10 ldy InitialIndex ;Draw the first initial of this high score
7436: 20 1a 6f jsr DrawInitial ;Draw a single initial on the display.
7439: e6 10 inc InitialIndex ;Draw the second initial of this high score
743b: a4 10 ldy InitialIndex
743d: 20 1a 6f jsr DrawInitial ;Draw a single initial on the display.
7440: e6 10 inc InitialIndex ;Draw the third initial of this high score
7442: a4 10 ldy InitialIndex
7444: 20 1a 6f jsr DrawInitial ;Draw a single initial on the display.
;
7447: e6 10 inc InitialIndex ;Move to the next initial index
7449: a5 0e lda ]HiScrBeamYLoc
744b: 38 sec ;Move down to the next high score row on the display
744c: e9 08 sbc #$08
744e: 85 0e sta ]HiScrBeamYLoc
7450: a6 0f ldx ]HiScrIndex ;Move to the next high score slot
7452: e8 inx
7453: e8 inx ;Have all 10 high scores been drawn on the display?
7454: e0 14 cpx #20 ;If not, branch to draw the next one
7456: 90 93 bcc HighScoresLoop
7458: 38 HighScoreExit sec ;Indicate the high scores list is being displayed
7459: 60 rts ;Exit high score list drawing routines
;
; Find a free asteroid slot.
;
745a: a2 1a GetFreeAstSlot ldx #26 ;Prepare to check 27 asteroid slots
745c: bd 00 02 NextAstSlotLoop lda AstStatus,x ;Is this slot free?
745f: f0 03 beq EndFreeAstSlot ;If so, exit. A free slot is available
7461: ca dex ;More slots to test?
7462: 10 f8 bpl NextAstSlotLoop ;If so, branch to check the next slot
7464: 60 EndFreeAstSlot rts ;Asteroid slot found or no slot available
;
; Ship explosion routines.
;
• Clear variables
]ThisDebrisX .var $04 {addr/2}
]ThisDebrisY .var $06 {addr/2}
]ShipDebrisPtr .var $09 {addr/1}
]VecPtrCopy .var $0b {addr/2}
7465: ad 1b 02 DoShipExplsn lda ShipStatus ;Is this the first frame of the ship explosion?
7468: c9 a2 cmp #$a2 ;If so, load the initial debris data
746a: b0 22 bcs GetNumDebris ;If not, branch to skip loading data
;
746c: a2 0a ldx #10 ;Prepare to load 12 values from ShipExpVelTbl
LoadShipExplLoop
746e: bd ec 50 lda ShipExpVelTbl,x ;Get byte of ship debris X velocity
7471: 4a lsr A
7472: 4a lsr A
7473: 4a lsr A ;Save only the upper nibble and shift to lower nibble
7474: 4a lsr A
7475: 18 clc
7476: 69 f8 adc #$f8 ;Sign extend the nibble to fill the whole byte
7478: 49 f8 eor #$f8
747a: 95 7e sta ShpDebrisXVel+1,x ;Save signed value into RAM
;
747c: bd ed 50 lda ShipExpVelTbl+1,x ;Get byte of ship debris Y velocity
747f: 4a lsr A
7480: 4a lsr A
7481: 4a lsr A ;Save only the upper nibble and shift to lower nibble
7482: 4a lsr A
7483: 18 clc
7484: 69 f8 adc #$f8 ;Sign extend the nibble to fill the whole byte
7486: 49 f8 eor #$f8
7488: 95 8a sta ShpDebrisYVel+1,x ;Save signed value into RAM
748a: ca dex ;Move to next 2 bytes in the table
748b: ca dex ;Are there more bytes to load from the table?
748c: 10 e0 bpl LoadShipExplLoop ;if so, loop to load 2 more bytes
;
748e: ad 1b 02 GetNumDebris lda ShipStatus
7491: 49 ff eor #$ff
7493: 29 70 and #%01110000 ;Calculate the pointer into the ship debris data based
7495: 4a lsr A ; on the ship status counter. This has the effect of making
7496: 4a lsr A ; the debris disappear one by one over time
7497: 4a lsr A
7498: aa tax
7499: 86 09 ShipDebrisLoop stx ]ShipDebrisPtr ;Update ship debris index
749b: a0 00 ldy #$00 ;Assume the X velocity for this debris piece is positive
749d: bd ec 50 lda ShipExpVelTbl,x ;Is the debris piece moving in a positive X direction?
74a0: 10 01 bpl GetDebrisXVel ;If so, branch
74a2: 88 dey ;The X velocity for this debris piece is negative
74a3: 18 GetDebrisXVel clc ;Update fractional part of debris X position
74a4: 75 7d adc ShpDebrisXVel,x
74a6: 95 7d sta ShpDebrisXVel,x
74a8: 98 tya
74a9: 75 7e adc ShpDebrisXVel+1,x ;Update integer part of debris X position
74ab: 95 7e sta ShpDebrisXVel+1,x
74ad: 85 04 sta ]ThisDebrisX ;Save current debris X position
74af: 84 05 sty ]ThisDebrisX+1 ;Save current debris X direction
;
74b1: a0 00 ldy #$00 ;Assume the Y velocity for this debris piece is positive
74b3: bd ed 50 lda ShipExpVelTbl+1,x ;Is the debris piece moving in a positive Y direction?
74b6: 10 01 bpl GetDebrisYVel ;If so, branch
74b8: 88 dey ;The Y velocity for this debris piece is negative
74b9: 18 GetDebrisYVel clc ;Update fractional part of debris Y position
74ba: 75 89 adc ShpDebrisYVel,x
74bc: 95 89 sta ShpDebrisYVel,x
74be: 98 tya
74bf: 75 8a adc ShpDebrisYVel+1,x ;Update integer part of debris Y position
74c1: 95 8a sta ShpDebrisYVel+1,x
74c3: 85 06 sta ]ThisDebrisY ;Save current debris Y position
74c5: 84 07 sty ]ThisDebrisY+1 ;Save current debris Y direction
;
74c7: a5 02 lda VecRamPtr
74c9: 85 0b sta ]VecPtrCopy ;Save a copy of the vector RAM pointer
74cb: a5 03 lda VecRamPtr+1
74cd: 85 0c sta ]VecPtrCopy+1
74cf: 20 49 7c jsr CalcDebrisPos ;Calculate the position of the exploded ship pieces
74d2: a4 09 ldy ]ShipDebrisPtr ;Write the ship debris vector data to the vector RAM
74d4: b9 e0 50 lda ShipExpPtrTbl,y
74d7: be e1 50 ldx ShipExpPtrTbl+1,y
74da: 20 45 7d jsr VecWriteWord ;Write 2 bytes to vector RAM
74dd: a4 09 ldy ]ShipDebrisPtr ;Draw the exact same line from above except backwards
74df: b9 e1 50 lda ShipExpPtrTbl+1,y
74e2: 49 04 eor #$04 ;Backtrack in the Y direction
74e4: aa tax
74e5: b9 e0 50 lda ShipExpPtrTbl,y
74e8: 29 0f and #$0f ;Set the brightness of the backtracked vector to 0
74ea: 49 04 eor #$04 ;Backtrack in the X direction
74ec: 20 45 7d jsr VecWriteWord ;Write 2 bytes to vector RAM
;
74ef: a0 ff ldy #$ff ;Prepare to write 4 bytes to vector RAM
74f1: c8 VecBackTrack iny ;Get position of the data where this function first started
74f2: b1 0b lda (]VecPtrCopy),y ; writing to vector RAM
74f4: 91 02 sta (VecRamPtr),y ;Copy the data again into the current position in vector RAM
74f6: c8 iny ; except draw it backwards to backtrack the XY position to
74f7: b1 0b lda (]VecPtrCopy),y ; the starting point
74f9: 49 04 eor #$04 ;Draw the exact same line from CalcDebrisPos except backwards
74fb: 91 02 sta (VecRamPtr),y ;This places the pointer back to the middle of the ship's position
74fd: c0 03 cpy #$03 ;Does the second word of the VCTR opcode need to be written
74ff: 90 f0 bcc VecBackTrack ;If so, branch to write second word
;
7501: 20 39 7c jsr VecPtrUpdate ;Update Vector RAM pointer
7504: a6 09 ldx ]ShipDebrisPtr ;Move to next pair of ship debris data
7506: ca dex
7507: ca dex ;Is there more ship debris data to process?
7508: 10 8f bpl ShipDebrisLoop ;If so, branch
750a: 60 rts
;
; Update the player's ship drawing.
;
• Clear variables
]ShipDrawXInv .var $08 {addr/1}
]ShipDrawYInv .var $09 {addr/1}
]VecPtr .var $0b {addr/2}
750b: a2 00 UpdateShipDraw ldx #$00 ;Used for inverting index into ship direction table
750d: 86 17 stx ShipDrawUnused ;Always 0; not used for anything
750f: a0 00 ldy #$00 ;Assume ship is pointing up
7511: a5 61 lda ShipDir ;Is ship pointing down?
7513: 10 06 bpl SaveShipDir ;If not, branch
7515: a0 04 ldy #$04 ;Set value indicating ship Y direction is inverted
7517: 8a txa
7518: 38 sec ;Subtract ship direction from #$00 to invert index into
7519: e5 61 sbc ShipDir ; ShipDirPtrTbl
751b: 85 08 SaveShipDir sta ]ShipDrawXInv ;Save current index calculations
751d: 24 08 bit ]ShipDrawXInv ;Is ship pointing down and left?
751f: 30 02 bmi InvertShipX ;If so, branch to invert X axis of ship
7521: 50 07 bvc SetShipInvAxes ;Is ship pointing up and left? If not, branch
7523: a2 04 InvertShipX ldx #$04 ;Set value indicating ship X direction is inverted.
7525: a9 80 lda #$80
7527: 38 sec ;Subtract modified ship direction from #$80 to get
7528: e5 08 sbc ]ShipDrawXInv ; proper index into ShipDirPtrTbl
752a: 86 08 SetShipInvAxes stx ]ShipDrawXInv ;Save the X and Y axis inversion indicators
752c: 84 09 sty ]ShipDrawYInv
;
752e: 4a lsr A
752f: 29 fe and #$fe ;Do final calculations on index for ShipDirPtrTbl
7531: a8 tay
7532: b9 6e 52 lda ShipDirPtrTbl,y ;Get pointer to ship vector data for current direction
7535: be 6f 52 ldx ShipDirPtrTbl+1,y
7538: 20 d3 6a jsr DrawShip ;Draw the Player's ship on the display
753b: ad 05 24 lda ThrustSw ;Is the thrust button being pressed?
753e: 10 14 bpl EndUpdShpDraw ;If not, branch to exit
7540: a5 5c lda FrameTimer ;Show thrust animation every 4th frame
7542: 29 04 and #$04 ;Is this the fourth frame?
7544: f0 0e beq EndUpdShpDraw ;If not, branch to exit
7546: c8 iny ;Prepare to move vector ROM pointer to thrust data
7547: c8 iny
7548: 38 sec
7549: a6 0c ldx ]VecPtr+1 ;Increment vector ROM pointer by 2 bytes
754b: 98 tya
754c: 65 0b adc ]VecPtr ;Pointer is now at thrust vector data
754e: 90 01 bcc DrawShipThrust ;Draw thrust vectors on the display
7550: e8 inx ;Increment the upper byte of the vector data pointer
7551: 20 d3 6a DrawShipThrust jsr DrawShip ;Draw the Player's ship on the display
7554: 60 EndUpdShpDraw rts ;Finished updating the ship and thrust graphics
;
; SFX control routines.
;
7555: a5 1c ChkUpdateSFX lda NumPlayers ;Is an active game in progress?
7557: d0 01 bne UpdateSFX ;If so, branch to update SFX
7559: 60 rts
755a: a2 00 UpdateSFX ldx #$00 ;Prepare to turn off saucer SFX if it is exploding or not present
755c: ad 1c 02 lda ScrStatus ;Is a saucer currently exploding?
755f: 30 0a bmi UpdateScrSFX ;If so, branch
7561: f0 08 beq UpdateScrSFX ;Is a saucer present? If not, branch to ensure the SFX is off
7563: 6a ror A
7564: 6a ror A ;Use saucer size to set proper saucer SFX
7565: 6a ror A
7566: 8d 02 3c sta SaucerSFXSel
7569: a2 80 ldx #$80 ;Turn on saucer SFX
756b: 8e 00 3c UpdateScrSFX stx SaucerSFX ;Enable/disable saucer SFX
;
756e: a2 01 ldx #$01 ;Select the saucer fire SFX
7570: 20 cd 75 jsr StartSFXTimer ;Start SFX timer, if applicable
7573: 8d 01 3c sta SaucerFireSFX ;Store updated status of the SFX
;
7576: ca dex ;Select the ship fire SFX
7577: 20 cd 75 jsr StartSFXTimer ;Start SFX timer, if applicable
757a: 8d 04 3c sta ShipFireSFX ;Store updated status of the SFX
;
757d: ad 1b 02 lda ShipStatus ;Is the ship currently on the screen?
7580: c9 01 cmp #$01
7582: f0 04 beq ChkNumAsteroids ;If so, branch
7584: 8a txa ;Load A with #$00. No ship on the screen
7585: 8d 03 3c sta ShipThrustSFX ;Turn off the thrust SFX
;
7588: ad f6 02 ChkNumAsteroids lda CurAsteroids ;Are there asteroids left in this wave?
758b: f0 11 beq ThumpSFXOff ;If not, branch to reset thump SFX
758d: ad 1b 02 lda ShipStatus ;Is the ship exploding?
7590: 30 0c bmi ThumpSFXOff ;If so, branch to reset the thump SFX
7592: 05 59 ora HyprSpcFlag ;Is the ship not active and not in hyperspace?
7594: f0 08 beq ThumpSFXOff ;If so, branch to reset the thump SFX
7596: a5 6d lda ThmpOnTime ;Is the thump SFX currently playing?
7598: f0 14 beq ChkThumpOffTime ;If not, branch
759a: c6 6d dec ThmpOnTime ;Decrement thump on timer
759c: d0 21 bne ChkExplTimer ;Is thump on timer still active? if so, branch
;
759e: a5 6c ThumpSFXOff lda ThisVolFreq
75a0: 29 0f and #$0f ;Turn off the thump SFX
75a2: 85 6c sta ThisVolFreq
75a4: 8d 00 3a sta ThumpFreqVol
75a7: ad fc 02 lda ThmpOffReload
75aa: 85 6e sta ThumpOffTime ;Set thump off timer to max value
75ac: 10 11 bpl ChkExplTimer
75ae: c6 6e ChkThumpOffTime dec ThumpOffTime ;Decrement the thump off timer
75b0: d0 0d bne ChkExplTimer ;Is it time to turn thump SFX back on? If not, branch
75b2: a9 04 lda #$04 ;Set the thump on timer
75b4: 85 6d sta ThmpOnTime
75b6: a5 6c lda ThisVolFreq
75b8: 49 14 eor #%00010100 ;Toggle the thump volume bit on and set the frequency
75ba: 85 6c sta ThisVolFreq
75bc: 8d 00 3a sta ThumpFreqVol
75bf: a5 69 ChkExplTimer lda ExplsnSFXTimer
75c1: aa tax ;Is the explosion SFX timer active?
75c2: 29 3f and #$3f ;If not, branch to skip decrementing it
75c4: f0 01 beq UpdateExplTimer
75c6: ca dex ;Decrement explosion SFX timer.
75c7: 86 69 UpdateExplTimer stx ExplsnSFXTimer
75c9: 8e 00 36 stx ExpPitchVol ;Update explosion timer, pitch and volume
75cc: 60 rts
75cd: b5 6a StartSFXTimer lda ShipFireSFX_,x ;Is the selected SFX active?
75cf: 30 0c bmi ChkSFXTimer ;If so, branch to check SFX timer status
75d1: b5 66 lda SFXTimers,x ;Is the selected SFX timer currently active?
75d3: 10 12 bpl TurnOffSFX ;If so, branch to turn it off
75d5: a9 10 lda #$10 ;Initialize the timer for the selected SFX
75d7: 95 66 sta SFXTimers,x
75d9: a9 80 TurnOnSFX lda #$80 ;Turn on the selected SFX
75db: 30 0c bmi UpdateSFXStatus ;Branch always
75dd: b5 66 ChkSFXTimer lda SFXTimers,x ;Get the tier value for the selected SFX
75df: f0 06 beq TurnOffSFX ;Is the timer expired? If so, branch to turn off
75e1: 30 04 bmi TurnOffSFX ;Has the timer gone negative, if so, branch to turn off
75e3: d6 66 dec SFXTimers,x ;Decrement the selected SFX timer
75e5: d0 f2 bne TurnOnSFX ;Is the timer still active? If so, branch to turn SFX on
75e7: a9 00 TurnOffSFX lda #$00 ;Turn off the selected SFX
75e9: 95 6a UpdateSFXStatus sta ShipFireSFX_,x ;Update the SFX status
75eb: 60 rts
;
; Split asteroid.
;
• Clear variables
]GenByte0E .var $0e {addr/1}
75ec: 86 0d BreakAsteroid stx GenByte0D ;Save a copy of the object 1 index
75ee: a9 50 lda #80 ;Set asteroid break timer to 80 frames
75f0: 8d f9 02 sta AstBreakTimer
75f3: b9 00 02 lda AstStatus,y
75f6: 29 78 and #%01111000 ;Save the asteroid status except the size.
75f8: 85 0e sta ]GenByte0E
75fa: b9 00 02 lda AstStatus,y ;Reduce the asteroid size by 1
75fd: 29 07 and #%00000111
75ff: 4a lsr A
7600: aa tax ;Does the asteroid still exist?
7601: f0 02 beq SaveAstStatus ;If not, branch to skip combining size with status
7603: 05 0e ora ]GenByte0E ;Combine the other asteroid properties with the new size
7605: 99 00 02 SaveAstStatus sta AstStatus,y ;Save the status of the new asteroid back into RAM
;
7608: a5 1c lda NumPlayers ;Is a game currently being played?
760a: f0 11 beq SplitAsteroid ;If not, branch to skip updating score
760c: a5 0d lda GenByte0D ;Did the ship crash into the asteroid?
760e: f0 04 beq DoAstScore ;If so, branch to add points to score
7610: c9 04 cmp #$04 ;Was it a saucer or saucer bullet that hit the asteroid?
7612: 90 09 bcc SplitAsteroid ;If so, branch to skip updating the score
7614: bd 59 76 DoAstScore lda AstPointsTbl,x ;Get asteroid points from table based on asteroid size
7617: a6 19 ldx ScoreIndex
7619: 18 clc
761a: 20 97 73 jsr UpdateScore ;Add points to the current player's score
;
761d: be 00 02 SplitAsteroid ldx AstStatus,y ;Was the asteroid completely destroyed?
7620: f0 34 beq BreakAstEnd ;If so, branch to end; asteroid not split
7622: 20 5a 74 jsr GetFreeAstSlot ;Find a free asteroid slot
7625: 30 2f bmi BreakAstEnd ;Was a free slot available? If not, branch to end
7627: ee f6 02 inc CurAsteroids ;Increment total number of asteroids
762a: 20 9d 6a jsr UpdateAsteroid ;Update new asteroid
762d: 20 03 72 jsr SetAstVel ;Set asteroid X and Y velocities
7630: bd 23 02 lda AstXSpeed,x ;Get lower 5 bits asteroid X velocity and * 2
7633: 29 1f and #%00011111
7635: 0a asl A
7636: 5d af 02 eor AstXPosLo,x ;Use this value to offset the X position of the new asteroid
7639: 9d af 02 sta AstXPosLo,x
763c: 20 5c 74 jsr NextAstSlotLoop ;Find a free asteroid slot
763f: 30 15 bmi BreakAstEnd ;Was a free slot found? If not, branch to exit
7641: ee f6 02 inc CurAsteroids ;Increment total number of asteroids
7644: 20 9d 6a jsr UpdateAsteroid ;Update new asteroid
7647: 20 03 72 jsr SetAstVel ;Set asteroid X and Y velocities
764a: bd 46 02 lda AstYSpeed,x ;Get lower 5 bits asteroid Y velocity and * 2
764d: 29 1f and #%00011111
764f: 0a asl A
7650: 5d d2 02 eor AstYPosLo,x ;Use this value to offset the Y position of the new asteroid
7653: 9d d2 02 sta AstYPosLo,x
7656: a6 0d BreakAstEnd ldx GenByte0D ;Restore the object 1 index before exiting function
7658: 60 rts
;
; Points awarded for destroying asteroids of different sizes. These are BCD
; values divided by 10; the score increases will be 100, 50, 20.
;
7659: 10 05 02 AstPointsTbl .bulk $10,$05,$02
;
; Check for high score.
;
765c: a5 1c CheckHighScore lda NumPlayers ;Is a game currently being played?
765e: 10 38 bpl ChkHghScrEnd ;If not, branch to end
7660: a2 02 ldx #$02 ;Start with player 2's score
7662: 85 5d sta FrameTimer+1
7664: 85 32 sta Plyr1Rank ;Reset the frame timer and player's ranks
7666: 85 33 sta Plyr2Rank
7668: a0 00 PlyrScoreLoop ldy #$00 ;Start at the beginning of the high scores list
ChkHighScoreLoop
766a: b9 1d 00 lda HighScores,y ;Compare the player's score with each entry in the high
766d: d5 52 cmp PlayerScores,x ; score list
766f: b9 1e 00 lda HighScores+1,y
7672: f5 53 sbc PlayerScores+1,x ;Is the player's score higher than the current score entry?
7674: 90 23 bcc PlayerHighScore ;If so, branch to add player to the list
7676: c8 iny ;Move to next entry in the high score table
7677: c8 iny
7678: c0 14 cpy #$14 ;Have all 10 entries been checked(2 bytes per entry)?
767a: 90 ee bcc ChkHighScoreLoop ;If no, branch to check the next entry
767c: ca NextPlayerScore dex ;Move to next player to check their score
767d: ca dex ;Is there another player to check?
767e: 10 e8 bpl PlyrScoreLoop ;If so, branch
;
7680: a5 33 lda Plyr2Rank ;Did player 2 get a high score?
7682: 30 0e bmi FinishHghScore ;If not, branch to wrap up this routine
7684: c5 32 cmp Plyr1Rank ;Did player 1 get a better score than player 2?
7686: 90 0a bcc FinishHghScore ;If not, branch to wrap up this routine
7688: 69 02 adc #$02 ;Did player 1 make the last ranking?
768a: c9 1e cmp #30
768c: 90 02 bcc SetPlyrRank ;If not, branch so both players can enter scores
768e: a9 ff lda #$ff ;Player 2's score is scrubbed as it is 11th place.
7690: 85 33 SetPlyrRank sta Plyr2Rank ;Set player 2's rank
7692: a9 00 FinishHghScore lda #$00
7694: 85 1c sta NumPlayers ;Indicate game is over and prepare to enter high score initials
7696: 85 31 sta ThisInitial
7698: 60 ChkHghScrEnd rts ;Done checking for high a score
7699: 86 0b PlayerHighScore stx GenByte0B ;Store index to current player being processed
769b: 84 0c sty GenByte0C ;Store index into high scores table.
769d: 8a txa
769e: 4a lsr A ;Calculate player's rank(each rank increments by 3)
769f: aa tax
76a0: 98 tya
76a1: 4a lsr A ;Calculate index into high scores initials table
76a2: 65 0c adc GenByte0C
76a4: 85 0d sta GenByte0D ;Store index into high scores initials
76a6: 95 32 sta Plyr1Rank,x ;Store player's rank
76a8: a2 1b ldx #27 ;Start at lowest initials to preserve(rank 9)
76aa: a0 12 ldy #18 ;Start at lowest score to preserve(rank 9)
76ac: e4 0d ShiftScoresLoop cpx GenByte0D ;Has the the player's slot been reached in the high scores list?
76ae: f0 1f beq ClearInitials ;If so, branch to end shifting ranks
76b0: b5 31 lda ThisInitial,x
76b2: 95 34 sta HighScoreIntls,x
76b4: b5 32 lda Plyr1Rank,x ;Get initials in high score table and move them down a rank
76b6: 95 35 sta HighScoreIntls+1,x
76b8: b5 33 lda Plyr2Rank,x
76ba: 95 36 sta HighScoreIntls+2,x
76bc: b9 1b 00 lda HighScores-2,y
76bf: 99 1d 00 sta HighScores,y ;Get score in high score table and move it down a rank
76c2: b9 1c 00 lda HighScores-1,y
76c5: 99 1e 00 sta HighScores+1,y
76c8: 88 dey ;Move to next score in table
76c9: 88 dey
76ca: ca dex
76cb: ca dex ;Move to next initials in table
76cc: ca dex
76cd: d0 dd bne ShiftScoresLoop ;More scores to shift down the ranks? If so, branch
;
76cf: a9 0b ClearInitials lda #$0b ;Set first initial to A
76d1: 95 34 sta HighScoreIntls,x
76d3: a9 00 lda #$00 ;Set second and third initial to SPACE
76d5: 95 35 sta HighScoreIntls+1,x
76d7: 95 36 sta HighScoreIntls+2,x
76d9: a9 f0 lda #$f0 ;Set frame timer for displaying initials
76db: 85 5d sta FrameTimer+1
76dd: a6 0b ldx GenByte0B ;Load index to current player being processed
76df: a4 0c ldy GenByte0C ;Load player's index into high score table
76e1: b5 53 lda PlayerScores+1,x
76e3: 99 1e 00 sta HighScores+1,y ;Transfer player's score into the high score table
76e6: b5 52 lda PlayerScores,x
76e8: 99 1d 00 sta HighScores,y
76eb: a0 00 ldy #$00 ;Branch always to check next player's score
76ed: f0 8d beq NextPlayerScore
76ef: 6e .dd1 $6e ;checksum byte
;
; Calculate small saucer shot velocity.
;
76f0: 98 CalcScrShotDir tya ;Load the Y distance between the saucer and the ship
76f1: 10 09 bpl ScrShotXDir ;Is Y direction positive? If so, branch to do X direction
76f3: 20 08 77 jsr TwosCompliment ;Calculate the 2's compliment of the Y distance
76f6: 20 fc 76 jsr ScrShotXDir ;Calculate the X direction of the saucer shot
76f9: 4c 08 77 jmp TwosCompliment ;Calculate the 2's compliment of the value in A
76fc: a8 ScrShotXDir tay ;Save the modified Y shot distance
76fd: 8a txa ;Get the the raw X shot distance
76fe: 10 0e bpl CalcScrShotAngle ;Is X direction positive? If so, branch to calculate shot angle
7700: 20 08 77 jsr TwosCompliment ;Calculate the 2's compliment of the value in A
7703: 20 0e 77 jsr CalcScrShotAngle ;Calculate the small saucer's shot angle
7706: 49 80 eor #$80 ;Set the appropriate quadrant for the bullet
;
; 2's compliment.
;
7708: 49 ff TwosCompliment eor #$ff
770a: 18 clc ;Calculate the 2's compliment of the value in A
770b: 69 01 adc #$01
770d: 60 rts
;
; Calculate small saucer shot angle.
;
• Clear variables
]ShotXYDistance .var $0c {addr/1}
CalcScrShotAngle
770e: 85 0c sta ]ShotXYDistance ;Store shot modified X distance
7710: 98 tya
7711: c5 0c cmp ]ShotXYDistance ;Is X and Y distance the same?
7713: f0 10 beq ShotAngle45 ;If so, angle is 45 degrees. Branch to set and exit
7715: 90 11 bcc LookUpAngle ;Is angle in lower 45 degrees of quadrant? if so, branch
7717: a4 0c ldy ]ShotXYDistance ;Swap X and Y components as the shot is
7719: 85 0c sta ]ShotXYDistance ; in the upper 45 degrees of the quadrant
771b: 98 tya
771c: 20 28 77 jsr LookUpAngle ;Look up angle but return to find proper quadrant
771f: 38 sec ;Set the appropriate quadrant for the bullet
7720: e9 40 sbc #$40
7722: 4c 08 77 jmp TwosCompliment ;Calculate the 2's compliment of the value in A
7725: a9 20 ShotAngle45 lda #$20 ;Player's ship is at a 45 degree angle to the saucer
7727: 60 rts
7728: 20 6c 77 LookUpAngle jsr FindScrAngleIndex ;Find the index in the table below for the shot angle
772b: bd 2f 77 lda ShotAngleTbl,x
772e: 60 rts ;Look up the proper angle and exit
;
; The following table divides 45 degrees of a circle into 16 pieces. Its used
; to calculate the direction of a bullet from a small saucer to the player's
; ship. The other angles in the circle are derived from this table.
;
772f: 00 02 05 07+ ShotAngleTbl .bulk $00,$02,$05,$07,$0a,$0c,$0f,$11,$13,$15,$17,$19,$1a,$1c,$1d,$1f
;
; Draw a string of numbers.
;
• Clear variables
]ptr .var $00 {addr/2}
DrawNumberString
773f: 08 php ;Save carry bit status
7740: 86 17 stx ZeroBlankBypass ;Save flag indicating if Zero blank should be overridden
7742: 88 dey ;Adjust index so it is a zero based index
7743: 84 16 sty BCDIndex
7745: 18 clc
7746: 65 16 adc BCDIndex ;Use index to calculate actual address of BCD data byte
7748: 85 15 sta BCDAddress
774a: 28 plp ;Restore carry bit status
774b: aa tax ;Get address to BCD byte to draw
;
DrawNumStringLoop
774c: 08 php ;Save carry bit status.
774d: b5 00 lda ]ptr,x
774f: 4a lsr A
7750: 4a lsr A ;Get upper BCD digit to draw
7751: 4a lsr A
7752: 4a lsr A
7753: 28 plp ;Restore carry bit status
7754: 20 85 77 jsr SetDigitVecPtr ;Set vector RAM pointer to digit JSR
7757: a5 16 lda BCDIndex ;Is this the lower byte of the digit string?
7759: d0 01 bne DoLowerDigit ;If so, disable zero blank function
775b: 18 clc ;Draw zeros, if present
;
775c: a6 15 DoLowerDigit ldx BCDAddress ;Get lower BCD digit to draw
775e: b5 00 lda ]ptr,x
7760: 20 85 77 jsr SetDigitVecPtr ;Set vector RAM pointer to digit JSR
7763: c6 15 dec BCDAddress ;Decrement to next BCD data byte
7765: a6 15 ldx BCDAddress
7767: c6 16 dec BCDIndex ;Is there more digits to draw in the number string?
7769: 10 e1 bpl DrawNumStringLoop ;If so, branch to get next digit byte
776b: 60 rts
;
; Small saucer shot angle calculation.
;
• Clear variables
]ShotAngleTemp .var $0b {addr/1}
]ShotXYDistance .var $0c {addr/1}
FindScrAngleIndex
776c: a0 00 ldy #$00 ;Zero out working variable
776e: 84 0b sty ]ShotAngleTemp
7770: a0 04 ldy #$04 ;Prepare to loop 4 times
ScrAngleIndexLoop
7772: 26 0b rol ]ShotAngleTemp ;Roll upper bit of working variable into A
7774: 2a rol A
7775: c5 0c cmp ]ShotXYDistance ;Is A now larger than the given distance?
7777: 90 02 bcc UpdateAngleCount ;If not, branch to do next loop.
7779: e5 0c sbc ]ShotXYDistance ;Subtract Distance from A to get update proper angle index
UpdateAngleCount
777b: 88 dey ;Does another loop need to be run?
777c: d0 f4 bne ScrAngleIndexLoop ;If so, branch to do another loop
;
777e: a5 0b lda ]ShotAngleTemp ;Move the final index bit into position
7780: 2a rol A
7781: 29 0f and #$0f ;Limit the index to 16 values
7783: aa tax
7784: 60 rts ;Done finding angle index
;
; Score pointer calculation.
;
; This function can do one of two things:
; 1) it can write a command in vector RAM to draw a digit, or
; 2) or set a pointer to the next data to process, overriding the zero blanking
; function.
;
; This function is used to blink a zero score at the beginning of a 2 player
; game. If $17 is #$00, draw digit. If it is any other value, get a pointer to
; the draw JSR.
;
• Clear variables
]ShipDrawXInv .var $08 {addr/1}
]ShipDrawYInv .var $09 {addr/1}
]VecPtr .var $0b {addr/2}
7785: 90 04 SetDigitVecPtr bcc ChkSetDigitPntr ;Is zero blanking active? If not, branch
7787: 29 0f and #$0f ;Is the digit to draw 0?
7789: f0 27 beq DisplayDigit ;If so, branch
778b: a6 17 ChkSetDigitPntr ldx ZeroBlankBypass ;Is the zero blank override flag set?
778d: f0 23 beq DisplayDigit ;If not, branch to draw digit
778f: 29 0f and #$0f
7791: 18 clc ;Add 1 to digit index to skip the SPACE character.
7792: 69 01 adc #$01
7794: 08 php ;Save processor status
7795: 0a asl A ;Get lower byte of pointer
7796: a8 tay ;Manually set bits into the proper position.
7797: b9 d4 56 lda CharPtrTbl,y
779a: 0a asl A ;Store value in lower byte of vector pointer
779b: 85 0b sta ]VecPtr
779d: b9 d5 56 lda CharPtrTbl+1,y ;Get upper byte of pointer
77a0: 2a rol A ;Manually set bits into the proper position
77a1: 29 1f and #$1f ;Get rid of the opcode bits
77a3: 09 40 ora #$40 ;Set MSB of the address manually
77a5: 85 0c sta ]VecPtr+1 ;Store value in upper byte of vector pointer
;
77a7: a9 00 lda #$00 ;Disable XY axis inversion
77a9: 85 08 sta ]ShipDrawXInv
77ab: 85 09 sta ]ShipDrawYInv
77ad: 20 d7 6a jsr SetVecRAMData ;Update vector RAM with character data.
77b0: 28 plp ;Restore processor status and exit
77b1: 60 rts
77b2: 4c cb 7b DisplayDigit jmp PrepDrawDigit ;Draw a digit on the display
;
; Random number generator.
;
77b5: 06 5f GetRandNum asl RandNum
77b7: 26 60 rol RandNum+1 ;Use a shift register to store the random number
77b9: 10 02 bpl RandNumBit
77bb: e6 5f inc RandNum ;Increment lower byte
77bd: a5 5f RandNumBit lda RandNum ;If the second bit set in the random number?
77bf: 2c d1 77 bit RandNumBitTbl
77c2: f0 04 beq RandNumORUB ;If not, branch to move on
77c4: 49 01 eor #$01 ;Invert LSB of random number
77c6: 85 5f sta RandNum
77c8: 05 60 RandNumORUB ora RandNum+1 ;Is new random number = 0?
77ca: d0 02 bne RandNumDone ;If not, branch to exit
77cc: e6 5f inc RandNum ;Ensure random number is never 0
77ce: a5 5f RandNumDone lda RandNum ;Return lower byte or random number
77d0: 60 rts
77d1: 02 RandNumBitTbl .dd1 $02 ;Used by random number generator above
;
; Thrust calculation routines.
;
77d2: 18 CalcXThrust clc ;Adding #$40 to ship/bullet direction will set MSB if facing left
77d3: 69 40 adc #$40
77d5: 10 08 CalcThrustDir bpl GetVelocityVal ;Is ship/saucer bullet facing right/up? If so, branch
77d7: 29 7f and #$7f ;Ship/saucer bullet is facing left/down; cear direction MSB
77d9: 20 df 77 jsr GetVelocityVal ;Get ship/saucer bullet velocity for this XY component
77dc: 4c 08 77 jmp TwosCompliment ;Calculate the 2's compliment of the value in A
77df: c9 41 GetVelocityVal cmp #$41 ;Is ship/saucer bullet facing right/up?
77e1: 90 04 bcc LookupThrustVal ;If so, branch
77e3: 49 7f eor #$7f ;Ship/saucer bullet is facing left/down. Need to lookup
77e5: 69 00 adc #$00 ; table in reverse order
77e7: aa LookupThrustVal tax
77e8: bd b9 57 lda ThrustTbl,x ;Get velocity value from lookup table
77eb: 60 rts
;
; Next frame saucer/ship distance.
;
• Clear variables
77ec: 06 0b NextScrShpDist asl GenByte0B
77ee: 2a rol A ;Get the signed difference between
77ef: 06 0b asl GenByte0B ; the ship and saucer upper 4 bits
77f1: 2a rol A
77f2: 38 sec ;Predict next location of saucer with respect to the ship
77f3: e5 0c sbc GenByte0C ; by subtracting the current saucer XY velocity from the
77f5: 60 rts ; from the saucer/ship distance
;
; Text writing routines.
;
]VecRomPtr .var $08 {addr/2}
77f6: ad 03 28 WriteText lda LanguageSw ;Get the language dip switch settings
77f9: 29 03 and #%00000011
77fb: 0a asl A ;*2; 2 bytes per entry in the pointer table below
77fc: aa tax ;Save index into table in X
77fd: a9 10 lda #$10 ;Appears to have no effect
77ff: 85 00 sta ZeroPageRam
7801: bd 88 78 lda LanguagePtrTbl+1,x
7804: 85 09 sta ]VecRomPtr+1 ;Get pointer to language data from the table below
7806: bd 87 78 lda LanguagePtrTbl,x
7809: 85 08 sta ]VecRomPtr
780b: 71 08 adc (]VecRomPtr),y ;Add offset to desired text message
780d: 85 08 sta ]VecRomPtr
780f: 90 02 bcc GetTextPos ;Does upper byte need to be incremented?
7811: e6 09 inc ]VecRomPtr+1 ;If not, branch to move on
;
7813: 98 GetTextPos tya
7814: 0a asl A ;*2; each entry in the table below is 2 bytes
7815: a8 tay
7816: b9 71 78 lda TextPosTbl,y ;Get the screen position for the desired text
7819: be 72 78 ldx TextPosTbl+1,y
781c: 20 03 7c jsr MoveBeam ;Move the CRT beam to a new location
781f: a9 70 lda #$70 ;Set scale 7(/4)
7821: 20 de 7c jsr SpotKill ;Draw zero vector to prevent spots on the screen
;
7824: a0 00 ldy #$00 ;Zero out index values
7826: a2 00 ldx #$00
7828: a1 08 TextWriteLoop lda (]VecRomPtr,x) ;Get the character byte from ROM
782a: 85 0b sta GenByte0B
782c: 4a lsr A ;Move the upper 5 bits into the proper position
782d: 4a lsr A
782e: 20 4d 78 jsr TextWriteIncPtr ;Increment the vector ROM pointer and write to RAM
7831: a1 08 lda (]VecRomPtr,x) ;Get the next character byte from ROM
7833: 2a rol A
7834: 26 0b rol GenByte0B ;Roll the 2 upper bits into the working variable
7836: 2a rol A
7837: a5 0b lda GenByte0B ;;Move the next 5 character bits into the proper position
7839: 2a rol A
783a: 0a asl A
783b: 20 53 78 jsr CheckNextChar ;Check if the next character is valid and write to RAM
783e: a1 08 lda (]VecRomPtr,x) ;Get the next text character byte
7840: 85 0b sta GenByte0B
7842: 20 4d 78 jsr TextWriteIncPtr ;Increment the vector ROM pointer
7845: 46 0b lsr GenByte0B ;Is the last bit 0?
7847: 90 df bcc TextWriteLoop ;If not, branch to write another character
7849: 88 TextWriteDone dey ;Last byte was end string character, compensate
784a: 4c 39 7c jmp VecPtrUpdate ;Update Vector RAM pointer
784d: e6 08 TextWriteIncPtr inc ]VecRomPtr
784f: d0 02 bne CheckNextChar ;Increment vector ROM pointer
7851: e6 09 inc ]VecRomPtr+1
7853: 29 3e CheckNextChar and #%00111110 ;Is the data empty? If so, end of string found
7855: d0 04 bne PrepWriteChar ;If not, branch to write character to display
7857: 68 pla ;Pull last return address from stack and update
7858: 68 pla ; the vector RAM pointer
7859: d0 ee bne TextWriteDone
785b: c9 0a PrepWriteChar cmp #$0a ;Is the character non-indexed?
785d: 90 02 bcc VecRamWriteChar ;;If so, add offset to get to the indexed characters
785f: 69 0d adc #$0d
7861: aa VecRamWriteChar tax
7862: bd d2 56 lda CharPtrTbl-2,x
7865: 91 02 sta (VecRamPtr),y
7867: c8 iny
7868: bd d3 56 lda CharPtrTbl-1,x ;Store routine for writing desired character in vector RAM
786b: 91 02 sta (VecRamPtr),y
786d: c8 iny
786e: a2 00 ldx #$00
7870: 60 rts
7871: 64 b6 TextPosTbl .bulk $64,$b6 ;X=4*$64=$190=400. Y=4*$B6=$2D8=728
7873: 64 b6 .bulk $64,$b6 ;X=4*$64=$190=400. Y=4*$B6=$2D8=728
7875: 0c aa .bulk $0c,$aa ;X=4*$0C=$30 =48. Y=4*$AA=$2A8=680
7877: 0c a2 .bulk $0c,$a2 ;X=4*$0C=$30 =48. Y=4*$A2=$288=648
7879: 0c 9a .bulk $0c,$9a ;X=4*$0C=$30 =48. Y=4*$9A=$268=616
787b: 0c 92 .bulk $0c,$92 ;X=4*$0C=$30 =48. Y=4*$92=$248=584
787d: 64 c6 .bulk $64,$c6 ;X=4*$64=$190=400. Y=4*$C6=$318=792
787f: 64 9d .bulk $64,$9d ;X=4*$64=$190=400. Y=4*$9D=$274=628
7881: 50 39 .bulk $50,$39 ;X=4*$50=$140=320. Y=4*$39=$E4 =228
7883: 50 39 .bulk $50,$39 ;X=4*$50=$140=320. Y=4*$39=$E4 =228
7885: 50 39 .bulk $50,$39 ;X=4*$50=$140=320. Y=4*$39=$E4 =228
; Text table pointers.
7887: 1e 57 LanguagePtrTbl .dd2 EnglishTextTbl
7889: 8f 78 .dd2 GermanTextTbl ;Text table pointers
788b: 46 79 .dd2 FrenchTextTbl
788d: f3 79 .dd2 SpanishTextTbl
;
; German message offsets.
;
788f: 0b GermanTextTbl .dd1 $0b
7890: 15 .dd1 $15
7891: 1b .dd1 $1b
7892: 35 .dd1 $35
7893: 4d .dd1 $4d
7894: 65 .dd1 $65
7895: 7f .dd1 $7f
7896: 8d .dd1 $8d
7897: 93 .dd1 $93
7898: 9f .dd1 $9f
7899: ab .dd1 $ab
;
; Message text, 5 bits per char. (See comments at $5729.)
;
789a: 64 d2 3b 2e+ .bulk $64,$d2,$3b,$2e,$c2,$6c,$5a,$4c,$93,$6f ;HOECHSTERGEBNIS
78a4: bd 1a 4c 12+ .bulk $bd,$1a,$4c,$12,$b0,$40 ;SPIELER
78aa: 6b 2c 0a 6c+ .bulk $6b,$2c,$0a,$6c,$5a,$4c,$93,$6e,$0b,$6e,$c0,$52,$6c,$92,$b8,$50 ;IHR ERGEBNIS IST EINES DER ZEHN BESTEN
+ $4d,$82,$f2,$58,$90,$4c,$4d,$f0,$4c,$80
78c4: 33 70 c2 42+ .bulk $33,$70,$c2,$42,$5a,$4c,$4c,$82,$bb,$52,$0b,$58,$b2,$42,$6c,$9a ;BITTE GEBEN SIE IHRE INITIALEN EIN
+ $c3,$4a,$82,$64,$0a,$5a,$90,$00
78dc: f6 6c 09 b2+ .bulk $f6,$6c,$09,$b2,$3b,$2e,$c1,$4c,$4c,$b6,$2b,$20,$0d,$a6,$c1,$70 ;ZUR BUCHSTABENWAHL ROTATE DRUECKEN
+ $48,$50,$b6,$52,$3b,$d2,$90,$00
78f4: da 64 90 4c+ .bulk $da,$64,$90,$4c,$c9,$d8,$be,$0a,$32,$42,$9b,$c2,$67,$68,$4d,$ae ;WENN BUCHSTABE OK HYPERSPACE DRUECKEN
+ $a1,$4e,$48,$50,$b6,$52,$3b,$d2,$90,$00
790e: be 0a b6 1e+ .bulk $be,$0a,$b6,$1e,$94,$d2,$a2,$92,$0a,$2c,$ca,$4e,$7a,$65 ;STARTKNOEPFE DRUECKEN
791c: bd 1a 4c 12+ .bulk $bd,$1a,$4c,$12,$92,$13 ;SPIELENDE
7922: 18 62 ca 64+ .bulk $18,$62,$ca,$64,$f2,$42,$20,$6e,$a3,$52,$82,$40 ;1 MUENZE 2 SPIELE
792e: 18 62 ca 64+ .bulk $18,$62,$ca,$64,$f2,$42,$18,$6e,$a3,$52,$80,$00 ;1 MUENZE 1 SPIEL
793a: 20 62 ca 64+ .bulk $20,$62,$ca,$64,$f2,$64,$08,$c2,$bd,$1a,$4c,$00 ;2 MUENZEN 1 SPIEL
;
; French message offsets.
;
7946: 0b FrenchTextTbl .dd1 $0b
7947: 15 .dd1 $15
7948: 19 .dd1 $19
7949: 31 .dd1 $31
794a: 41 .dd1 $41
794b: 57 .dd1 $57
794c: 73 .dd1 $73
794d: 7f .dd1 $7f
794e: 89 .dd1 $89
794f: 95 .dd1 $95
7950: a1 .dd1 $a1
;
; Message text, 5 bits per char.
;
7951: 8a 5a 84 12+ .bulk $8a,$5a,$84,$12,$cd,$82,$b9,$e6,$b2,$40 ;MEILLEUR SCORE
795b: 74 f2 4d 83 .bulk $74,$f2,$4d,$83 ;JOUER
795f: d4 f0 b2 42+ .bulk $d4,$f0,$b2,$42,$b9,$e6,$b2,$42,$4d,$f0,$0e,$64,$0a,$12,$b8,$46 ;VOTRE SCORE EST UN DES 10 MEILLEURS
+ $10,$62,$4b,$60,$82,$72,$b5,$c0
7977: be a8 0a 64+ .bulk $be,$a8,$0a,$64,$c5,$92,$f0,$74,$9d,$c2,$6c,$9a,$c3,$4a,$82,$6f ;SVP ENTREZ VOS INITIALES
7987: a4 f2 bd d2+ .bulk $a4,$f2,$bd,$d2,$f0,$6c,$9e,$0a,$c2,$42,$a4,$f2,$b0,$74,$9d,$c2 ;POUSSEZ ROTATE POUR VOS INITIALES
+ $6c,$9a,$c3,$4a,$82,$6f
799d: a4 f2 bd d2+ .bulk $a4,$f2,$bd,$d2,$f0,$58,$ed,$12,$b5,$e8,$29,$d2,$0d,$72,$2c,$90 ;POUSSEZ HYPERSPACE QUAND LETTRE CORRECTE
+ $0c,$12,$c6,$2c,$48,$4e,$9d,$ac,$49,$f0,$48,$00
79b9: 2d 28 cf 52+ .bulk $2d,$28,$cf,$52,$b0,$6e,$cd,$82,$be,$0a,$b6,$00 ;APPUYER SUR START
79c5: 53 64 0a 12+ .bulk $53,$64,$0a,$12,$0d,$0a,$b6,$1a,$48,$00 ;FIN DE PARTIE
79cf: 18 68 6a 4e+ .bulk $18,$68,$6a,$4e,$48,$48,$0b,$a6,$ca,$72,$b5,$c0 ;1 PIECE 2 JOUEURS
79db: 18 68 6a 4e+ .bulk $18,$68,$6a,$4e,$48,$46,$0b,$a6,$ca,$72,$b0,$00 ;1 PIECE 1 JOUEUR
79e7: 20 68 6a 4e+ .bulk $20,$68,$6a,$4e,$4d,$c2,$18,$5c,$9e,$52,$cd,$80 ;2 PIECES 1 JOUEUR
;
; Spanish message offsets.
;
79f3: 0b SpanishTextTbl .dd1 $0b
79f4: 11 .dd1 $11
79f5: 17 .dd1 $17
79f6: 31 .dd1 $31
79f7: 45 .dd1 $45
79f8: 5f .dd1 $5f
79f9: 6b .dd1 $6b
79fa: 73 .dd1 $73
79fb: 7d .dd1 $7d
79fc: 89 .dd1 $89
79fd: 93 .dd1 $93
;
; Message text, 5 bits per char.
;
79fe: b2 4e 9d 90+ .bulk $b2,$4e,$9d,$90,$b8,$00 ;RECORDS
7a04: 76 56 2a 26+ .bulk $76,$56,$2a,$26,$b0,$40 ;JUGADOR
7a0a: be 42 a6 64+ .bulk $be,$42,$a6,$64,$c1,$5c,$48,$52,$be,$0a,$0a,$64,$c5,$92,$0c,$26 ;SU PUNTAJE ESTA ENTRE LOS DIEZ MEJORES
+ $b8,$50,$6a,$7c,$0c,$52,$74,$ec,$4d,$c0
7a24: a4 ec 0a 8a+ .bulk $a4,$ec,$0a,$8a,$d4,$ec,$0a,$64,$c5,$92,$0d,$f2,$b8,$5a,$93,$4e ;POR FAVOR ENTRE SUS INICIALES
+ $69,$60,$4d,$c0
7a38: 9d 2c 6c 4a+ .bulk $9d,$2c,$6c,$4a,$0d,$a6,$c1,$70,$48,$68,$2d,$8a,$0d,$d2,$82,$4e ;OPRIMA ROTATE PARA SELECCIONAR LA LETRA
+ $3b,$66,$91,$6c,$0c,$0a,$0c,$12,$c5,$8b
7a52: 9d 2c 6c 4a+ .bulk $9d,$2c,$6c,$4a,$0b,$3a,$a2,$6c,$bd,$0a,$3a,$40 ;OPRIMA HYPERSPACE
7a5e: a6 60 b9 6c+ .bulk $a6,$60,$b9,$6c,$0d,$f0,$2d,$b1 ;PULSAR START
7a66: 76 52 5c c2+ .bulk $76,$52,$5c,$c2,$c2,$6c,$8b,$64,$2a,$27 ;JUEGO TERMINADO
7a70: 18 54 69 d8+ .bulk $18,$54,$69,$d8,$28,$48,$0b,$b2,$4a,$e6,$b8,$00 ;1 FICHA 2 JUEGOS
7a7c: 18 54 69 d8+ .bulk $18,$54,$69,$d8,$28,$46,$0b,$b2,$4a,$e7 ;1 FICHA 1 JUEGO
7a86: 20 54 69 d8+ .bulk $20,$54,$69,$d8,$2d,$c2,$18,$5c,$ca,$56,$98,$00 ;2 FICHAS 1 JUEGO
;
7a92: 52 .dd1 $52 ;checksum byte
;
; Check coin insertion routines.
;
CheckCoinsInserted
7a93: a2 02 ldx #$02 ;Prepare to check all 3 coin mechanisms
7a95: bd 00 24 CheckCoinsLoop lda LeftCoinSw,x ;Get status of coin switch and store it in the carry bit
7a98: 0a asl A
7a99: b5 7a lda CoinDropTimers,x ;Get coin drop timer value
7a9b: 29 1f and #$1f ;Was a coin insertion detected?
7a9d: 90 37 bcc CheckDropTimerVal ;If not, branch to check coin drop timer
7a9f: f0 10 beq CheckSlamSw ;Has coin drop timer run until it hit 0? If so, branch
7aa1: c9 1b cmp #$1b ;Has timer just started with detected coin insertion?
7aa3: b0 0a bcs DecDropTimer ;If so, branch
7aa5: a8 tay ;Wait 7 NMI periods(28ms). During this time, the coin
7aa6: a5 5e lda NmiCounter ; switch should be active, the drop timer should be active
7aa8: 29 07 and #$07 ; and the slam switch should not be active. If these
7aaa: c9 07 cmp #$07 ; conditions are true, decrement the coin drop timer
7aac: 98 tya
7aad: 90 02 bcc CheckSlamSw ;Check slam switch during first 7 NMIs
7aaf: e9 01 DecDropTimer sbc #$01 ;Things check out so far, decrement coin drop timer
7ab1: 95 7a CheckSlamSw sta CoinDropTimers,x ;Update the coin drop timer.
;
7ab3: ad 06 20 lda SlamSw ;Get the slam switch status
7ab6: 29 80 and #$80 ;Was a slam detected?
7ab8: f0 04 beq CheckSlamTimer ;If not, branch to move on
7aba: a9 f0 lda #$f0 ;Slam detected. Set slam timer
7abc: 85 72 sta SlamTimer
7abe: a5 72 CheckSlamTimer lda SlamTimer ;Is the slam timer active?
7ac0: f0 08 beq CheckWaitTimer ;If not, branch to move on
7ac2: c6 72 dec SlamTimer
7ac4: a9 00 lda #$00 ;Decrement the slam timer and hold the other timers
7ac6: 95 7a sta CoinDropTimers,x ; in their zero state until the slam timer clears
7ac8: 95 77 sta WaitCoinTimers,x
7aca: 18 CheckWaitTimer clc ;Is this wait timer finished?
7acb: b5 77 lda WaitCoinTimers,x
7acd: f0 23 beq CheckNextMech ;If so, branch to see if another mechanism needs to be checked
7acf: d6 77 dec WaitCoinTimers,x ;Is this timer still active? decrement and branch if done
7ad1: d0 1f bne CheckNextMech
7ad3: 38 sec ;Branch always
7ad4: b0 1c bcs CheckNextMech
CheckDropTimerVal
7ad6: c9 1b cmp #$1b ;If timer is a high value, the coin switch cleared too
7ad8: b0 09 bcs ResetDropTimer ; soon. False flag. Branch to reset the drop timer
7ada: b5 7a lda CoinDropTimers,x ;Max value after add is #$3F
7adc: 69 20 adc #$20
7ade: 90 d1 bcc CheckSlamSw ;Branch always
7ae0: f0 01 beq ResetDropTimer ;This code does not appear to be accessed
7ae2: 18 clc
7ae3: a9 1f ResetDropTimer lda #$1f ;Prepare to reset the coin drop timer
7ae5: b0 ca bcs CheckSlamSw ;If carry is set, something funny happened, check slam switch
7ae7: 95 7a sta CoinDropTimers,x ;Reset the coin drop timer
7ae9: b5 77 lda WaitCoinTimers,x ;is this the first transition of the wait timer?
7aeb: f0 01 beq SetWaitTimer ;If so, branch to set timer and move to next coin mech
7aed: 38 sec ;Timer transition already happened, prepare to do more processing
7aee: a9 78 SetWaitTimer lda #$78 ;Load the wait timer
7af0: 95 77 sta WaitCoinTimers,x
7af2: 90 23 CheckNextMech bcc DoNextCoinMech ;Branch to check next coin mech if timer transition just happened
7af4: a9 00 lda #$00 ;Is this the left coin mech?
7af6: e0 01 cpx #$01
7af8: 90 16 bcc CalcMult ;If so, branch to increment coins; no multipliers this coin mech
7afa: f0 0c beq CCoinMechMult ;Is this the center coin mech? If so, branch to calc multiplier
;
7afc: a5 71 lda DipSwitchBits ;Only option left is the right coin mechanism
7afe: 29 0c and #$0c
7b00: 4a lsr A ;Get the Dip switch values and /4
7b01: 4a lsr A
7b02: f0 0c beq CalcMult ;If no multiplier active, branch to increment coins
7b04: 69 02 adc #$02 ;Multiplier active on the right coin mech. Get the shifted
7b06: d0 08 bne CalcMult ; DIP switch value and add 2 for a range between 4-6; Branch always
7b08: a5 71 CCoinMechMult lda DipSwitchBits ;Check if there is a multiplier active on the center coin mech.
7b0a: 29 10 and #$10
7b0c: f0 02 beq CalcMult ;If not, branch to increment the coins
7b0e: a9 01 lda #$01 ;Multiplier active; add an additional coin
7b10: 38 CalcMult sec ;Add at least one coin
7b11: 65 73 adc CoinMult ;Add the any others from multipliers
7b13: 85 73 sta CoinMult ;Update the total coins
7b15: f6 74 inc ValidCoins,x ;Indicate a valid coin; used for incrementing coin counter
7b17: ca DoNextCoinMech dex ;Are there coin mechanisms left to check?
7b18: 30 03 bmi CalcCoinsPerPlay ;If not, next step is to update coins
7b1a: 4c 95 7a jmp CheckCoinsLoop ;Check next coin mechanism
CalcCoinsPerPlay
7b1d: a5 71 lda DipSwitchBits ;Get the coins per play value; On = 0, Off = 1
7b1f: 29 03 and #$03
7b21: a8 tay ;Is free play active?
7b22: f0 12 beq UpdateCoinMult ;If so, branch to add 0 coins
7b24: 4a lsr A
7b25: 69 00 adc #$00 ;Get the number of coins required to get a credit
7b27: 49 ff eor #$ff ; and subtract the number of current coins; if more
7b29: 38 sec ; coins are needed, branch to finish for this frame
7b2a: 65 73 adc CoinMult ;Else add up to 2 credits this frame
7b2c: 90 0a bcc CreditUpdateDone
7b2e: c0 02 cpy #$02 ;Do 2 credits need to be added?
7b30: b0 02 bcs Add1Credit ;If not, branch to add only 1
7b32: e6 70 inc NumCredits ;Add the first of 2 credits
7b34: e6 70 Add1Credit inc NumCredits ;Increment the credits
7b36: 85 73 UpdateCoinMult sta CoinMult ;Store updated coin value
;
CreditUpdateDone
7b38: a5 5e lda NmiCounter ;Is this an odd NMI period?
7b3a: 4a lsr A
7b3b: b0 27 bcs EndCoinCheck ;If so, branch to end, if not, keep processing
7b3d: a0 00 ldy #$00 ;Prepare to check all 3 valid coin indicators
7b3f: a2 02 ldx #$02
7b41: b5 74 ValidCoinLoop1 lda ValidCoins,x
7b43: f0 09 beq NextValidCoin1
7b45: c9 10 cmp #$10 ;This function continues a valid coin timer
7b47: 90 05 bcc NextValidCoin1 ;During this time, the coin counters are enabled
7b49: 69 ef adc #$ef ;The counter will last for 16 NMIs when a single
7b4b: c8 iny ; coin is inserted; the counter will last longer
7b4c: 95 74 sta ValidCoins,x ; if more coins are added
7b4e: ca NextValidCoin1 dex
7b4f: 10 f0 bpl ValidCoinLoop1
7b51: 98 tya ;Is a valid coin counter active from above?
7b52: d0 10 bne EndCoinCheck
;
7b54: a2 02 ldx #$02 ;Prepare to check all 3 valid coin indicators
7b56: b5 74 ValidCoinLoop2 lda ValidCoins,x
7b58: f0 07 beq NextValidCoin2
7b5a: 18 clc
7b5b: 69 ef adc #$ef ;This function will initiate a valid coin
7b5d: 95 74 sta ValidCoins,x ; timer; the coin counters will be enabled
7b5f: 30 03 bmi EndCoinCheck ; at this time
7b61: ca NextValidCoin2 dex
7b62: 10 f2 bpl ValidCoinLoop2
7b64: 60 EndCoinCheck rts ;Done checking coin insertion
;
; NMI handler. These arrive at 3000/12 = 250Hz.
;
7b65: 48 NMI pha ;Push A, Y and X onto the stack
7b66: 98 tya
7b67: 48 pha
7b68: 8a txa
7b69: 48 pha
7b6a: d8 cld ;Set processor to binary mode
7b6b: ad ff 01 lda StackBottom ;Has the stack overflowed or underflowed?
7b6e: 0d d0 01 ora StackTop ;If so, spin lock until watchdog reset
7b71: d0 fe :Spin bne :Spin
;
7b73: e6 5e inc NmiCounter ;Is it time to start a new frame(every 4th NMI)?
7b75: a5 5e lda NmiCounter
7b77: 29 03 and #$03
7b79: d0 08 bne CheckCoins ;If not, branch to skip frame counter increment
7b7b: e6 5b inc FrameCounter ;Start a new frame. 62.5 frames per second
7b7d: a5 5b lda FrameCounter ;Have more than 3 frames passed without being acknowledged?
7b7f: c9 04 cmp #$04
7b81: b0 fe :Spin bcs :Spin ;If so, something is wrong. Spin lock until watchdog reset
;
7b83: 20 93 7a CheckCoins jsr CheckCoinsInserted ;Check if player inserted any coins
7b86: a5 6f lda MultiPurpBits ;Get the multipurpose bits and discard the coin
7b88: 29 c7 and #%11000111 ; counter enable bits. They will be set next
7b8a: 24 74 bit LValidCoin ;Was a valid coin detected in the left coin mech?
7b8c: 10 02 bpl CheckCValidCoin ;If not, branch to check the next coin mech
7b8e: 09 08 ora #CoinCtrLeft ;Activate the left coin counter
7b90: 24 75 CheckCValidCoin bit CValidCoin ;Was a valid coin detected in the center coin mech?
7b92: 10 02 bpl CheckRValidCoin ;If not, branch to check the next coin mech
7b94: 09 10 ora #CoinCtrCntr ;Activate the center coin counter.
7b96: 24 76 CheckRValidCoin bit RValidCoin ;Was a valid coin detected in the right coin mech?
7b98: 10 02 bpl UpdateCoinCounters ;If not, branch to update the active coin counters
7b9a: 09 20 ora #CoinCtrRght ;Activate the right coin counter
UpdateCoinCounters
7b9c: 85 6f sta MultiPurpBits ;Update the current states of the coin counters
7b9e: 8d 00 32 sta MultiPurp
;
7ba1: a5 72 lda SlamTimer ;Is slam timer active?
7ba3: f0 04 beq UpdateSlamSFX ;If not, branch
7ba5: a9 80 lda #$80 ;Slam detected; start the slam SFX
7ba7: d0 0e bne EnDisSlamSFX
7ba9: a5 68 UpdateSlamSFX lda ExLfSFXTimer ;Slam has not recently been active; disable slam SFX
7bab: f0 0a beq EnDisSlamSFX
7bad: a5 5c lda FrameTimer ;Is this an odd frame?
7baf: 6a ror A
7bb0: 90 02 bcc FrameTimerRoll3 ;If not, branch to skip decrementing SFX timer
7bb2: c6 68 dec ExLfSFXTimer ;Decrement SFX timer every other frame
7bb4: 6a FrameTimerRoll3 ror A
7bb5: 6a ror A ;Rolling the value creates a unique SFX
7bb6: 6a ror A
7bb7: 8d 05 3c EnDisSlamSFX sta LifeSFX ;Enables or disables slam SFX
7bba: 68 pla ;Pull A, Y and X from the stack
7bbb: aa tax
7bbc: 68 pla
7bbd: a8 tay
7bbe: 68 pla
7bbf: 40 rti ;Return from interrupt
;
; Vector drawing routines.
;
7bc0: a9 b0 VecHalt lda #HaltOpcode ;Write HALT command to vector RAM
7bc2: a0 00 VecRam2Write ldy #$00 ;Write 2 bytes to vector RAM
7bc4: 91 02 sta (VecRamPtr),y
7bc6: c8 iny
7bc7: 91 02 sta (VecRamPtr),y
7bc9: d0 6e bne VecPtrUpdate ;Branch always; update Vector RAM pointer
7bcb: 90 04 PrepDrawDigit bcc DrawDigit ;Draw a single digit on the display
7bcd: 29 0f and #$0f ;Is a blank space to be drawn?
7bcf: f0 05 beq PrepDigitPointer ;If so, branch
7bd1: 29 0f DrawDigit and #$0f ;Save lower nibble and add 1 to it
7bd3: 18 clc
7bd4: 69 01 adc #$01 ;Adding 1 skips the "space" character.
;
PrepDigitPointer
7bd6: 08 php ;Save the processor status on the stack
7bd7: 0a asl A ;*2; the digit pointers are 2 bytes
7bd8: a0 00 ldy #$00 ;Start at current vector RAM pointer position
7bda: aa tax
7bdb: bd d4 56 lda CharPtrTbl,x ;Load the JSRL command that draws the appropriate digit
7bde: 91 02 sta (VecRamPtr),y
7be0: bd d5 56 lda CharPtrTbl+1,x
7be3: c8 iny
7be4: 91 02 sta (VecRamPtr),y
7be6: 20 39 7c jsr VecPtrUpdate ;Update Vector RAM pointer
7be9: 28 plp ;Restore the processor status from the stack
7bea: 60 rts
7beb: 4a UnusedFunc00 lsr A
7bec: 29 0f and #$0f ;Appears to be an unused function
7bee: 09 e0 ora #$e0
;
7bf0: a0 01 VecRamPtrUpdate ldy #$01 ;Load upper byte of JSRL word into vector RAM
7bf2: 91 02 sta (VecRamPtr),y
7bf4: 88 dey ;Decrement index to load lower byte
7bf5: 8a txa
7bf6: 6a ror A ;Convert byte into proper address format
7bf7: 91 02 sta (VecRamPtr),y ;Store lower byte
7bf9: c8 iny ;Increment index for proper JSRL return address
7bfa: d0 3d bne VecPtrUpdate ;Update Vector RAM pointer
7bfc: 4a VecRomJSRL lsr A ;Shift right to preserve JSRL upper address bit
7bfd: 29 0f and #$0f ;Keep upper address nibble
7bff: 09 c0 ora #JsrlOpcode ;Add JSRL opcode
7c01: d0 ed bne VecRamPtrUpdate ;Branch always; update vector RAM with JSR
• Clear variables
]GlobalScale .var $00 {addr/1}
]MovBeamX .var $04 {addr/2}
]MovBeamY .var $06 {addr/2}
7c03: a0 00 MoveBeam ldy #$00
7c05: 84 05 sty ]MovBeamX+1 ;Zero out X and Y upper address bytes
7c07: 84 07 sty ]MovBeamY+1
7c09: 0a asl A
7c0a: 26 05 rol ]MovBeamX+1
7c0c: 0a asl A ;Break X address byte into the proper opcode format
7c0d: 26 05 rol ]MovBeamX+1
7c0f: 85 04 sta ]MovBeamX
7c11: 8a txa ;Move Y address byte into A
7c12: 0a asl A
7c13: 26 07 rol ]MovBeamY+1
7c15: 0a asl A ;Break Y address byte into the proper opcode format
7c16: 26 07 rol ]MovBeamY+1
7c18: 85 06 sta ]MovBeamY
;
7c1a: a2 04 ldx #$04 ;Prepare to load 4 bytes into vector RAM
7c1c: b5 02 SetLABSData lda VecRamPtr,x ;Get lower byte of upper LABS word
7c1e: a0 00 ldy #$00
7c20: 91 02 sta (VecRamPtr),y ;Store it in vector RAM
7c22: b5 03 lda VecRamPtr+1,x ;Get upper byte of upper LABS word
7c24: 29 0f and #$0f
7c26: 09 a0 ora #LabsOpcode ;Add LABS opcode to the LABS instruction
7c28: c8 iny
7c29: 91 02 sta (VecRamPtr),y ;Store it in vector RAM
7c2b: b5 00 lda VecRamPtr-2,x ;Get lower byte of lower LABS word
7c2d: c8 iny
7c2e: 91 02 sta (VecRamPtr),y ;Store it in vector RAM
7c30: b5 01 lda VecRamPtr-1,x ;Get upper byte of lower LABS word
7c32: 29 0f and #$0f
7c34: 05 00 ora ]GlobalScale ;Add global scale data to the CUR instruction
7c36: c8 iny
7c37: 91 02 sta (VecRamPtr),y ;Store it in vector RAM
7c39: 98 VecPtrUpdate tya ;Y has the number of bytes to increment vector ROM pointer by
7c3a: 38 sec
7c3b: 65 02 adc VecRamPtr ;Update vector ROM pointer
7c3d: 85 02 sta VecRamPtr
7c3f: 90 02 bcc :Return ;Does upper byte of pointer need to increment? if not, branch
7c41: e6 03 inc VecRamPtr+1 ;Increment upper pointer byte
7c43: 60 :Return rts
; Unused?
7c44: a9 d0 VecRamRTS lda #RtslOpcode ;Prepare to write RTSL opcode to vector RAM
7c46: 4c c2 7b jmp VecRam2Write ;Write the same byte twice to vector RAM
;
; Calculate ship debris position.
;
; The purpose of this function is to calculate the proper starting point for the
; selected piece of ship debris. It needs to take into account any out of
; bounds conditions if the ship is close to any of the 4 edges of the display.
; It draws a VCTR with zero brightness to the proper starting position.
;
• Clear variables
]GenByte01 .var $01 {addr/1}
]ThisDebrisX .var $04 {addr/2}
]ThisDebrisY .var $06 {addr/2}
]GenByte08 .var $08 {addr/1}
7c49: a5 05 CalcDebrisPos lda ]ThisDebrisX+1 ;Is the debris traveling in a negative X direction?
7c4b: c9 80 cmp #$80
7c4d: 90 11 bcc ChkYDebris ;If not, branch
7c4f: 49 ff eor #$ff ;Convert negative direction into a positive
7c51: 85 05 sta ]ThisDebrisX+1 ; number by using two's compliment
7c53: a5 04 lda ]ThisDebrisX
7c55: 49 ff eor #$ff ;Lower byte contains debris absolute value position
7c57: 69 00 adc #$00 ;Upper byte contains debris direction
7c59: 85 04 sta ]ThisDebrisX
7c5b: 90 02 bcc :NoInc
7c5d: e6 05 inc ]ThisDebrisX+1
7c5f: 38 :NoInc sec ;Set bit to indicate debris is moving in negative X direction
7c60: 26 08 ChkYDebris rol ]GenByte08 ;Save X direction bit
7c62: a5 07 lda ]ThisDebrisY+1 ;Is the debris traveling in a negative Y direction?
7c64: c9 80 cmp #$80
7c66: 90 11 bcc ChkPosXYUB ;If not, branch
7c68: 49 ff eor #$ff ;Convert negative direction into a positive
7c6a: 85 07 sta ]ThisDebrisY+1 ; number by using two's compliment
7c6c: a5 06 lda ]ThisDebrisY
7c6e: 49 ff eor #$ff ;Lower byte contains debris absolute value position
7c70: 69 00 adc #$00 ;Upper byte contains debris direction
7c72: 85 06 sta ]ThisDebrisY
7c74: 90 02 bcc :NoInc
7c76: e6 07 inc ]ThisDebrisY+1
7c78: 38 :NoInc sec ;Set bit to indicate debris is moving in negative Y direction
7c79: 26 08 ChkPosXYUB rol ]GenByte08 ;Save Y direction bit
7c7b: a5 05 lda ]ThisDebrisX+1 ;Is debris piece close to the lowest X or Y border?
7c7d: 05 07 ora ]ThisDebrisY+1
7c7f: f0 0a beq ChkPosXYLB ;If so, branch to check lower byte for edge proximity
7c81: a2 00 ldx #$00 ;Prepare to clip debris if at max XY position
7c83: c9 02 cmp #$02 ;Is debris at maximum XY edge of screen?
7c85: b0 24 bcs SetScaleAndDirBits ;If so, branch
7c87: a0 01 ldy #$01 ;Not at edge of screen; prepare to calculate proper scaling
7c89: d0 10 bne PrepXYMult2
7c8b: a0 02 ChkPosXYLB ldy #$02 ;Prepare to set scaling if not at screen edge
7c8d: a2 09 ldx #$09 ;Prepare to clip debris if at min XY position
7c8f: a5 04 lda ]ThisDebrisX
7c91: 05 06 ora ]ThisDebrisY ;Is debris at minimum XY edge of screen?
7c93: f0 16 beq SetScaleAndDirBits ;If so, branch
7c95: 30 04 bmi PrepXYMult2 ;Is proper scaling already set? If so, branch
7c97: c8 CalcShiftVal iny
7c98: 0a asl A ;Calculate proper scaling value for displacing this debris
7c99: 10 fc bpl CalcShiftVal
;
7c9b: 98 PrepXYMult2 tya ;Transfer scaling value to X
7c9c: aa tax
7c9d: a5 05 lda ]ThisDebrisX+1 ;Move debris X direction into A
RestoreDebrisPos
7c9f: 06 04 asl ]ThisDebrisX
7ca1: 2a rol A
7ca2: 06 06 asl ]ThisDebrisY ;Restore the debris position from a single byte back to 2 bytes
7ca4: 26 07 rol ]ThisDebrisY+1
7ca6: 88 dey
7ca7: d0 f6 bne RestoreDebrisPos
7ca9: 85 05 sta ]ThisDebrisX+1 ;Save restored upper byte of debris X position
;
SetScaleAndDirBits
7cab: 8a txa
7cac: 38 sec
7cad: e9 0a sbc #$0a ;Compute scaling bits
7caf: 49 ff eor #$ff
7cb1: 0a asl A
7cb2: 66 08 ror ]GenByte08 ;Get Y direction bit
7cb4: 2a rol A
7cb5: 66 08 ror ]GenByte08
7cb7: 2a rol A ;Get X direction bit
7cb8: 0a asl A
7cb9: 85 08 sta ]GenByte08 ;Save the completed configuration bits back to RAM
;
7cbb: a0 00 ldy #$00 ;Write the Y position lower byte to vector RAM
7cbd: a5 06 lda ]ThisDebrisY
7cbf: 91 02 sta (VecRamPtr),y
7cc1: a5 08 lda ]GenByte08
7cc3: 29 f4 and #%11110100 ;Get the scale and Y direction bits for the VCTR opcode
7cc5: 05 07 ora ]ThisDebrisY+1 ;Combine the Y position upper byte
7cc7: c8 iny
7cc8: 91 02 sta (VecRamPtr),y ;Write the byte to vector RAM
7cca: a5 04 lda ]ThisDebrisX
7ccc: c8 iny
7ccd: 91 02 sta (VecRamPtr),y ;Write the X position lower byte to vector RAM
7ccf: a5 08 lda ]GenByte08
7cd1: 29 02 and #$02 ;Get the X direction bit
7cd3: 0a asl A
7cd4: 05 01 ora ]GenByte01 ;Set brightness for this vector(should be 0)
7cd6: 05 05 ora ]ThisDebrisX+1 ;Combine the X position upper byte
7cd8: c8 iny
7cd9: 91 02 sta (VecRamPtr),y ;Write the byte to vector RAM
7cdb: 4c 39 7c jmp VecPtrUpdate ;Update Vector RAM pointer
;
; Spot kill.
;
7cde: a2 00 SpotKill ldx #$00 ;Prepare to draw a dot with brightness 0
7ce0: a0 01 DrawDot ldy #$01 ;Store scale in vector RAM
7ce2: 91 02 sta (VecRamPtr),y
7ce4: 88 dey
7ce5: 98 tya
7ce6: 91 02 sta (VecRamPtr),y ;Set X and Y delta values to 0
7ce8: c8 iny
7ce9: c8 iny
7cea: 91 02 sta (VecRamPtr),y
7cec: c8 iny
7ced: 8a txa ;Store dot brightness in vector RAM
7cee: 91 02 sta (VecRamPtr),y
7cf0: 4c 39 7c jmp VecPtrUpdate ;Update Vector RAM pointer
;
; Reset.
;
7cf3: a2 fe RESET ldx #$fe ;Set stack pointer to #$FE
7cf5: 9a txs
7cf6: d8 cld ;Set processor to binary mode
7cf7: a9 00 lda #$00 ;Prepare to clear the RAM
7cf9: aa tax
7cfa: ca RamClearLoop dex ;Loop until all RAM is zeroed
7cfb: 9d 00 03 sta Player2Ram,x
7cfe: 9d 00 02 sta Player1Ram,x
7d01: 9d 00 01 sta OnePageRam,x
7d04: 95 00 sta ZeroPageRam,x
7d06: d0 f2 bne RamClearLoop ;More bytes to clear? If so, loop to write more
;
7d08: ac 07 20 ldy SelfTestSw ;Is the self test switch set for test mode?
7d0b: 30 43 bmi DoSelfTest ;If so, branch to do self test routine
7d0d: e8 inx ;Write JUMP to RAM address $4402 opcode to vector RAM
7d0e: 8e 00 40 stx VectorRam ;The vector RAM is divided in half and one half is written to
7d11: a9 e2 lda #JmplOpcode+2 ; while the other half is read. The read/write halves are
7d13: 8d 01 40 sta VectorRam+1 ; swapped every frame
7d16: a9 b0 lda #HaltOpcode
7d18: 8d 03 40 sta VectorRam+3 ;Write HALT opcode to vector RAM address $4002
;
7d1b: 85 32 sta Plyr1Rank ;Write some initial data to player's rank
7d1d: 85 33 sta Plyr2Rank
7d1f: a9 03 lda #PlyrLamps
7d21: 85 6f sta MultiPurpBits ;Turn on the Player 1 and 2 LEDs
7d23: 8d 00 32 sta MultiPurp
7d26: 2d 00 28 and PlayTypeSw ;Get how many coins to play a game
7d29: 85 71 sta DipSwitchBits
7d2b: ad 01 28 lda RghtCoinMechSw
7d2e: 29 03 and #%00000011
7d30: 0a asl A ;Get the coin multiplier for the Right coin mech
7d31: 0a asl A
7d32: 05 71 ora DipSwitchBits
7d34: 85 71 sta DipSwitchBits
7d36: ad 02 28 lda CentCMShipsSw
7d39: 29 02 and #$02
7d3b: 0a asl A
7d3c: 0a asl A ;Get the coin multiplier for the center coin mech
7d3d: 0a asl A
7d3e: 05 71 ora DipSwitchBits
7d40: 85 71 sta DipSwitchBits
7d42: 4c 03 68 jmp InitGame ;Initialize the game after reset
7d45: a0 00 VecWriteWord ldy #$00 ;Write 2 bytes into vector RAM
7d47: 91 02 sta (VecRamPtr),y
7d49: c8 iny
7d4a: 8a txa
7d4b: 91 02 sta (VecRamPtr),y
7d4d: 4c 39 7c jmp VecPtrUpdate ;Update Vector RAM pointer
;
; Self test routines.
;
7d50: 9d 00 40 DoSelfTest sta VectorRam,x ;Loop and clear all 2K of vector RAM
7d53: 9d 00 41 sta VectorRam+$100,x
7d56: 9d 00 42 sta VectorRam+$200,x
7d59: 9d 00 43 sta VectorRam+$300,x
7d5c: 9d 00 44 sta VectorRam+$400,x
7d5f: 9d 00 45 sta VectorRam+$500,x
7d62: 9d 00 46 sta VectorRam+$600,x
7d65: 9d 00 47 sta VectorRam+$700,x
7d68: e8 inx
7d69: d0 e5 bne DoSelfTest ;More RAM to clear? If so, branch
7d6b: 8d 00 34 sta WdClear ;Clear the watchdog timer
;
7d6e: a2 00 ldx #$00 ;Prepare for RAM check test
RamPage0TestLoop
7d70: b5 00 lda ZeroPageRam,x ;RAM address to check should always start out as 0
7d72: d0 47 bne RamPage0Fail
7d74: a9 11 lda #$11 ;Four bit RAM; load a single bit per RAM
RamPage0ByteTest
7d76: 95 00 sta ZeroPageRam,x ;Store the bit pattern in RAM
7d78: a8 tay ;Read the value back out of RAM
7d79: 55 00 eor ZeroPageRam,x ;Compare it with itself
7d7b: d0 3e bne RamPage0Fail ;Is the value the same? If not, branch to failure
7d7d: 98 tya ;Rotate the bit pattern in the RAM
7d7e: 0a asl A
7d7f: 90 f5 bcc RamPage0ByteTest ;More bits to test at this address? If so, branch
7d81: e8 inx ;Done testing that RAM address
7d82: d0 ec bne RamPage0TestLoop ;More addresses in Page 0 to test? If so, branch
7d84: 8d 00 34 sta WdClear ;Clear the watchdog timer.
;
• Clear variables
]GenPtr00 .var $00 {addr/2}
7d87: 8a txa ;Clear A by transferring the #$00 in X
7d88: 85 00 sta ]GenPtr00 ;Clear address $00
7d8a: 2a rol A ;Get the set carry bit and put in A; A = #$01
7d8b: 85 01 RamTestNextPage sta ]GenPtr00+1 ;Load the next bank upper address
;
7d8d: a0 00 ldy #$00 ;Start at beginning of the bank
RamPageNTestLoop
7d8f: a2 11 ldx #$11 ;Four bit RAM; load a single bit per RAM
7d91: b1 00 lda (]GenPtr00),y ;Byte read should be equal to 0 at first
7d93: d0 2a bne RamPageNFail ;If not 0, branch; bad RAM found
RamPageNByteTest
7d95: 8a txa ;Store the bit pattern in RAM
7d96: 91 00 sta (]GenPtr00),y
7d98: 51 00 eor (]GenPtr00),y ;Read the value back out and compare to the original
7d9a: d0 23 bne RamPageNFail ;Do the values match? If not, branch; bad RAM
7d9c: 8a txa ;Shift the bit pattern left by one
7d9d: 0a asl A
7d9e: aa tax
7d9f: 90 f4 bcc RamPageNByteTest ;Done writing to this address? If not branch
7da1: c8 iny ;Increment to next address
7da2: d0 eb bne RamPageNTestLoop ;Done with this page? If not, branch to write another byte
7da4: 8d 00 34 sta WdClear ;Clear the watchdog timer.
;
7da7: e6 01 inc ]GenPtr00+1 ;Increment to the next page
7da9: a6 01 ldx ]GenPtr00+1
7dab: e0 04 cpx #MpuRamPages ;Have the 4 MPU RAM pages been checked?
7dad: 90 e0 bcc RamPageNTestLoop ;If not, branch to check next page
;
7daf: a9 40 lda #$40 ;MPU RAM check complete; move on to vector RAM.
7db1: e0 40 cpx #$40 ;More vector RAM to check?
7db3: 90 d6 bcc RamTestNextPage ;If so, branch to check more
7db5: e0 48 cpx #$48 ;Have all the vector RAM pages been checked?
7db7: 90 d6 bcc RamPageNTestLoop ;If not, branch to check the next one
7db9: b0 69 bcs RomTest ;RAM test passed; move to the ROM/PROM test
7dbb: a0 00 RamPage0Fail ldy #$00 ;Zero page RAM failed, Y = #$00
7dbd: f0 0e beq MakeRamList ;Branch always
7dbf: a0 00 RamPageNFail ldy #$00 ;MPU RAM failed, Y = #$00
7dc1: a6 01 ldx ]GenPtr00+1 ;Get RAM page that failed
7dc3: e0 04 cpx #MpuRamPages ;Was it MPU RAM that failed?
7dc5: 90 06 bcc MakeRamList ;If so, branch
7dc7: c8 iny ;Lower vector RAM failed, Y = #$01
7dc8: e0 44 cpx #>VectorRam+$400 ;Was it lower vector RAM half that failed?
7dca: 90 01 bcc MakeRamList ;If so, branch
7dcc: c8 iny ;Upper vector RAM failed, Y = #$02
7dcd: c9 10 MakeRamList cmp #$10 ;Detected difference stored in A. If difference was in upper
7dcf: 2a rol A ; nibble, upper RAM is bad and bit is rolled into LSB A
7dd0: 29 1f and #%00011111 ;Check for lower nibble difference
7dd2: c9 02 cmp #$02 ;If one exists, a bit will be rolled into LSB A
7dd4: 2a rol A
7dd5: 29 03 and #$03 ;Keep only two lower bits as they are the failure bits
7dd7: 88 ShiftRamPairs dey ;Decrement Y to move to next RAM pairs
7dd8: 30 04 bmi BadRamToneLoop ;Finished shifting? If so, play RAM tones
7dda: 0a asl A ;Need to move the bad RAM pairs up in memory
7ddb: 0a asl A ; to make room for the next RAM pairs
7ddc: 90 f9 bcc ShiftRamPairs ;More Ram pairs to shift? If so, branch
;
7dde: 4a BadRamToneLoop lsr A ;Move RAM good/bad bit to carry
7ddf: a2 14 ldx #GoodRamFreq ;Assume RAM is good and prepare to play good RAM tone
7de1: 90 02 bcc LoadRamThump ;Is good/bad bit cleared? If so, branch; RAM is good
7de3: a2 1d ldx #BadRamFreq ;This is bad RAM; load bad RAM thump frequency
;
7de5: 8e 00 3a LoadRamThump stx ThumpFreqVol ;Play RAM tone
7de8: a2 00 ldx #$00
7dea: a0 08 ldy #$08 ;Play tone for 256*8 3KHz periods (.68 seconds)
7dec: 2c 01 20 BadRamPlayTone bit Clk3Khz
7def: 10 fb bpl BadRamPlayTone ;Wait for 1 3KHz period (333us)
7df1: 2c 01 20 :Loop bit Clk3Khz
7df4: 30 fb bmi :Loop
7df6: ca dex ;One more 3KHz period has passed
7df7: 8d 00 34 sta WdClear ;Clear the watchdog timer
7dfa: d0 f0 bne BadRamPlayTone ;Has 256 3KHz periods elapsed? If not, branch to wait more
7dfc: 88 dey ;Another 256 3KHz periods have passed
7dfd: d0 ed bne BadRamPlayTone ;More time left to play RAM tone? If so, branch
;
7dff: 8e 00 3a stx ThumpFreqVol ;Turn off thump SFX
7e02: a0 08 ldy #$08 ;Prepare to wait another .68 seconds
7e04: 2c 01 20 BadRamWaitTone bit Clk3Khz
7e07: 10 fb bpl BadRamWaitTone ;Wait for 1 3KHz period (333us)
7e09: 2c 01 20 :Loop2 bit Clk3Khz
7e0c: 30 fb bmi :Loop2
7e0e: ca dex ;One more 3KHz period has passed
7e0f: 8d 00 34 sta WdClear ;Clear the watchdog timer
7e12: d0 f0 bne BadRamWaitTone ;Has 256 3KHz periods elapsed? If not, branch to wait more
7e14: 88 dey ;Another 256 3KHz periods have passed
7e15: d0 ed bne BadRamWaitTone ;More time left to play RAM tone? If so, branch
7e17: aa tax ;Are there still more RAMs to play tones for?
7e18: d0 c4 bne BadRamToneLoop ;If so, branch to do the next RAM chip
7e1a: 8d 00 34 BadRamCheckTest sta WdClear ;Clear the watchdog timer
;
7e1d: ad 07 20 lda SelfTestSw ;Is self test still enabled?
7e20: 30 f8 bmi BadRamCheckTest ;If so, loop until it is disabled
7e22: 10 fe BadRamSpinLock bpl BadRamSpinLock ;Self test released; spin lock until watchdog reset
• Clear variables
]GenByte00 .var $00 {addr/1}
]VecRomPtr .var $08 {addr/2}
]RomChecksum .var $0d {addr/8}
]DiagStepState .var $15 {addr/1}
]RamSwapResults .var $16 {addr/1}
7e24: a9 00 RomTest lda #<VectorRom
7e26: a8 tay
7e27: aa tax ;Point to the start of the vector ROM
7e28: 85 08 sta ]VecRomPtr
7e2a: a9 50 lda #>VectorRom
7e2c: 85 09 RomTestKBLoop sta ]VecRomPtr+1 ;Prepare to test 1Kb of ROM (#$0400 bytes)
7e2e: a9 04 lda #$04
7e30: 85 0b sta GenByte0B
;
7e32: a9 ff lda #$ff ;Prepare to invert all the bits
7e34: 51 08 RomTestBankLoop eor (]VecRomPtr),y ;Keep a running checksum on ROM contents
7e36: c8 iny ;Move to the next address
7e37: d0 fb bne RomTestBankLoop ;Is this page done? If not, branch to get another byte
7e39: e6 09 inc ]VecRomPtr+1 ;Move to next ROM page
7e3b: c6 0b dec GenByte0B ;Is 1 KB of ROM done?
7e3d: d0 f5 bne RomTestBankLoop ;If not, branch to start next page
7e3f: 95 0d sta ]RomChecksum,x ;Store checksum for this 1Kb of ROM
7e41: e8 inx ;Move to next checksum storage byte
7e42: 8d 00 34 sta WdClear ;Clear the watchdog timer
;
7e45: a5 09 lda ]VecRomPtr+1 ;Are we at the end of the vector ROM?
7e47: c9 58 cmp #>VectorRomEnd ;If not, branch to get checksum of another Kb
7e49: 90 e1 bcc RomTestKBLoop
7e4b: d0 02 bne RomChecksumDone ;Are checking the program ROM? If so, branch
7e4d: a9 68 lda #>ProgramRom ;Start checking the program ROM
7e4f: c9 80 RomChecksumDone cmp #>ProgramRomEnd ;Are we done checking the program ROM?
7e51: 90 d9 bcc RomTestKBLoop ;If not, branch to do another Kb
7e53: 8d 00 03 sta Player2Ram ;Store ProgramRomEndUB(#$80) into RAM location $0300
7e56: a2 04 ldx #RamSwap ;Swap RAM locations $0200-$02FF with $0300-$03FF
7e58: 8e 00 32 stx MultiPurp
7e5b: 86 15 stx ]DiagStepState ;Initialize DiagStepState with #$04; draws initial
7e5d: a2 00 ldx #$00 ; line on screen if DiagStep is active
7e5f: cd 00 02 cmp AstStatus ;The value of A stored in Player2Ram should now be here.
7e62: f0 01 beq CheckPlr2Ram ;Did the RAM swap successfully? If so, branch
7e64: e8 inx ;There was a RAM swap problem; increment X
7e65: ad 00 03 CheckPlr2Ram lda Player2Ram ;The final bit pattern written in the RAM test routine
7e68: c9 88 cmp #$88 ; should be here
7e6a: f0 01 beq CheckSwapDone
7e6c: e8 inx ;There was a RAM swap problem; increment X
7e6d: 86 16 CheckSwapDone stx ]RamSwapResults ;Store the results of the RAM swap test
7e6f: a9 10 lda #$10 ;Written but not read
7e71: 85 00 sta ]GenByte00
;
SelfTestMainLoop
7e73: a2 24 ldx #SelfTestWait ;Wait for 36 3KHz periods(12 ms)
SelfTestWaitLoop
7e75: ad 01 20 lda Clk3Khz
7e78: 10 fb bpl SelfTestWaitLoop ;Wait for 1 3KHz period (333us)
7e7a: ad 01 20 :Loop lda Clk3Khz
7e7d: 30 fb bmi :Loop
7e7f: ca dex ;Has 12 ms elapsed?
7e80: 10 f3 bpl SelfTestWaitLoop ;If not, branch to wait some more
;
7e82: 2c 02 20 VectorWaitLoop2 bit Halt ;Is the vector state machine busy?
7e85: 30 fb bmi VectorWaitLoop2 ;If so, loop until it is idle
7e87: 8d 00 34 sta WdClear
;
7e8a: a9 00 lda #<VectorRam
7e8c: 85 02 sta VecRamPtr ;Set vector RAM pointer to start of RAM
7e8e: a9 40 lda #>VectorRam
7e90: 85 03 sta VecRamPtr+1
7e92: ad 05 20 lda DiagStep ;Is diagnostic step active?
7e95: 10 5b bpl ShowDipStatus ;If not, branch to next test
7e97: a6 15 ldx ]DiagStepState ;Get current diagnostic step state
7e99: ad 03 20 lda HyprSpcSw ;Has the hyperspace button been pressed?
7e9c: 10 0a bpl LoadDiagVects ;If so, update diagnostic step
7e9e: 4d 09 00 eor: TestSFXInit_ ;Was hyperspace button just pressed?
7ea1: 10 05 bpl LoadDiagVects ;If not, branch to display current DiagStep lines
7ea3: ca dex ;Hyperspace was pressed; can anymore DiagStep lines be added?
7ea4: f0 02 beq LoadDiagVects ;If not, branch to draw existing DiagStep lines
7ea6: 86 15 stx ]DiagStepState ;Add another DiagStep line to the display
;
7ea8: bc bb 7e LoadDiagVects ldy DiagStepIdxTbl-1,x ;Get the current address into the vector RAM
7eab: a9 b0 lda #HaltOpcode ;Add a HALT to the last addresses
7ead: 91 02 sta (VecRamPtr),y
7eaf: 88 dey ;Move down to the next word in the vector RAM
7eb0: 88 dey
DiagStepWriteLoop
7eb1: b9 c0 7e lda DiagStepDatTbl,y ;Get next byte from the table below and write to vector RAM
7eb4: 91 02 sta (VecRamPtr),y
7eb6: 88 dey ;Any more bytes to write to vector RAM?
7eb7: 10 f8 bpl DiagStepWriteLoop ;If so, branch to get another byte
7eb9: 4c 9d 7f jmp GetTestButtons ;Jump to get user inputs
;
; The values in the table are indexes to the data tables below. The actual
; index is the value in the table - 2. Must account for $B000 (HALT) written to
; the end of each segment. The $B000 is overwritten by the next segment allowing
; drawing continuation.
;
7ebc: 33 1d 17 0d DiagStepIdxTbl .bulk $33,$1d,$17,$0d
; Draws the first line. Written to vector RAM at $4000.
7ec0: 80 a0 DiagStepDatTbl .dd2 $a080 ;LABS x=0 y=128 sc=0
7ec2: 00 00 .dd2 $0000
7ec4: 00 70 .dd2 $7000 ;VCTR x=+0 y=+0 sc=7 b=0
7ec6: 00 00 .dd2 $0000
7ec8: ff 92 .dd2 $92ff ;VCTR x=+1023 y=+767 sc=9 b=7
7eca: ff 73 .dd2 $73ff
; Draws the second line. Written to vector RAM at $400C.
7ecc: d0 a1 .dd2 $a1d0 ;LABS x=560 y=464 sc=0
7ece: 30 02 .dd2 $0230
7ed0: 00 70 .dd2 $7000 ;VCTR x=+0 y=+0 sc=7 b=0
7ed2: 00 00 .dd2 $0000
7ed4: 7f fb .dd2 $fb7f ;SVEC x=+-3 y=+3 sc=3 b=7
; Draws the third line. Written to vector RAM at $4016.
7ed6: 0d e0 .dd2 $e00d ;JMPL a=$000d ($401a)
7ed8: 00 b0 .dd2 $b000 ;HALT
7eda: 7e fa .dd2 $fa7e ;SVEC x=+-2 y=+2 sc=3 b=7
; Draws the last triangle. Written to vector RAM at $401C.
7edc: 11 c0 .dd2 $c011 ;JSRL a=$0011 ($4022)
7ede: 78 fe .dd2 $fe78 ;SVEC x=+0 y=+-2 sc=3 b=7
7ee0: 00 b0 .dd2 $b000 ;HALT
7ee2: 13 c0 .dd2 $c013 ;JSRL a=$0013 ($4026)
7ee4: 00 d0 .dd2 $d000 ;RTSL
7ee6: 15 c0 .dd2 $c015 ;JSRL a=$0015 ($402a)
7ee8: 00 d0 .dd2 $d000 ;RTSL
7eea: 17 c0 .dd2 $c017 ;JSRL a=$0017 ($402e)
7eec: 00 d0 .dd2 $d000 ;RTSL
7eee: 7a f8 .dd2 $f87a ;SVEC x=+2 y=+0 sc=3 b=7
7ef0: 00 d0 .dd2 $d000 ;RTSL
]tmp_08 .var $08 {addr/1}
]TestSFXInit .var $09 {addr/1}
]tmp_0a .var $0a {addr/1}
7ef2: a9 50 ShowDipStatus lda #>VectorRom ;Prepare to load cross-hatch pattern on the screen
7ef4: a2 00 ldx #<VectorRom
7ef6: 20 fc 7b jsr VecRomJSRL ;Load JSRL command in vector RAM to vector ROM
7ef9: a9 69 lda #$69 ;X beam coordinate 4 * $69 = $1A4 = 420
7efb: a2 93 ldx #$93 ;Y beam coordinate 4 * $93 = $24C = 588
7efd: 20 03 7c jsr MoveBeam ;Move the CRT beam to a new location
7f00: a9 30 lda #$30 ;Set scale 3(/64)
7f02: 20 de 7c jsr SpotKill ;Draw zero vector to prevent spots on the screen
;
7f05: a2 03 ldx #$03 ;Prepare to read the 4 pairs of DIP switches
DrawDipStatusLoop
7f07: bd 00 28 lda DipSw,x ;Get selected DIP switch pair status
7f0a: 29 01 and #%00000001 ;Keep only lower DIP switch status
7f0c: 86 0b stx GenByte0B ;Save a copy of the DIP pair currently being checked
7f0e: 20 d1 7b jsr DrawDigit ;Draw a single digit on the display
7f11: a6 0b ldx GenByte0B ;Restore a copy of the DIP pair currently being checked
7f13: bd 00 28 lda DipSw,x ;Reload the selected DIP switch pair status
7f16: 29 02 and #%00000010 ;Keep only upper DIP switch status
7f18: 4a lsr A ;Move it to the LSB
7f19: 20 d1 7b jsr DrawDigit ;Draw a single digit on the display
7f1c: a6 0b ldx GenByte0B ;Reload the selected DIP switch pair status
7f1e: ca dex ;Does another DIP switch pair need to be checked?
7f1f: 10 e6 bpl DrawDipStatusLoop ;If so, branch to get the next pair
;
7f21: a9 7a lda #$7a ;X beam coordinate 4 * $7A = $1E8 = 488
7f23: a2 9d ldx #$9d ;Y beam coordinate 4 * $9D = $274 = 628
7f25: 20 03 7c jsr MoveBeam ;Move the CRT beam to a new location
7f28: a9 10 lda #$10 ;Set scale 1(/256)
7f2a: 20 de 7c jsr SpotKill ;Draw zero vector to prevent spots on the screen
;
7f2d: ad 02 28 lda CentCMShipsSw ;Get the center coin mechanism switch status and display it
7f30: 29 02 and #%00000010
7f32: 4a lsr A
7f33: 69 01 adc #$01
7f35: 20 d1 7b jsr DrawDigit ;Draw a single digit on the display
7f38: ad 01 28 lda RghtCoinMechSw ;Get the right coin mechanism switches status
7f3b: 29 03 and #%00000011
7f3d: aa tax ;Use the switches status to display the coin multiplier value
7f3e: bd f5 7f lda CoinMultTbl,x
7f41: 20 d1 7b jsr DrawDigit ;Draw a single digit on the display
7f44: a5 16 lda ]RamSwapResults ;Was there a RAM swap error?
7f46: f0 07 beq VerifyChecksum ;If not, branch to move to the next test
7f48: a2 88 ldx #<VecBankErr ;Prepare to write bank error message to the display
7f4a: a9 50 lda #>VecBankErr
7f4c: 20 fc 7b jsr VecRomJSRL ;Load JSR command in vector RAM to vector ROM.
;
7f4f: a2 96 VerifyChecksum ldx #$96 ;Y beam coordinate 4 * $96 = $258 = 600
7f51: 8e 0c 00 stx: GenByte0C ;Store base value for Y beam coordinate
7f54: a2 07 ldx #$07 ;Prepare to check all 8 checksum values
7f56: b5 0d ChecksumLoop lda ]RomChecksum,x ;Is this checksum correct?
7f58: f0 37 beq NextChecksum ;If so, branch to get next checksum
7f5a: 48 pha ;Incorrect checksum; save checksum value on stack
7f5b: 8e 0b 00 stx: GenByte0B ;Save current checksum index
7f5e: ae 0c 00 ldx: GenByte0C ;Prepare to move the Y beam position to display failure info
7f61: 8a txa ;Move the Y bean position down by 32
7f62: 38 sec
7f63: e9 08 sbc #$08
7f65: 8d 0c 00 sta: GenByte0C ;Save new beam position
7f68: a9 20 lda #$20 ;X beam coordinate 4 * $20 = $80 = 128
7f6a: 20 03 7c jsr MoveBeam ;Move the CRT beam to a new location
7f6d: a9 70 lda #$70 ;Set scale 7(/4)
7f6f: 20 de 7c jsr SpotKill ;Draw zero vector to prevent spots on the screen
;
7f72: ad 0b 00 lda: GenByte0B ;Write failing checksum index to the display
7f75: 20 d1 7b jsr DrawDigit ;Draw a single digit on the display
7f78: ad d4 56 lda CharPtrTbl ;Point to first entry in character pointer table (space)
7f7b: ae d5 56 ldx CharPtrTbl+1 ;Prepare to write a space to the display
7f7e: 20 45 7d jsr VecWriteWord ;Write 2 bytes to vector RAM
7f81: 68 pla ;Get the incorrect checksum value again
7f82: 48 pha ;Store it right back on the stack
7f83: 4a lsr A
7f84: 4a lsr A ;Prepare to write the upper nibble to the display
7f85: 4a lsr A
7f86: 4a lsr A
7f87: 20 d1 7b jsr DrawDigit ;Draw a single digit on the display
7f8a: 68 pla ;Prepare to write the lower nibble to the display
7f8b: 20 d1 7b jsr DrawDigit ;Draw a single digit on the display
7f8e: ae 0b 00 ldx: GenByte0B ;Get the next checksum index to check
7f91: ca NextChecksum dex ;Is there another checksum to check?
7f92: 10 c2 bpl ChecksumLoop ;If so, branch
;
7f94: a9 7f lda #$7f ;X beam coordinate 4 * $7F = $1FC = 508
7f96: aa tax ;Y beam coordinate 4 * $7F = $1FC = 508
7f97: 20 03 7c jsr MoveBeam ;Move the CRT beam to a new location
7f9a: 20 c0 7b jsr VecHalt ;Halt the vector state machine
;
7f9d: a9 00 GetTestButtons lda #$00 ;Prepare to get the statuses of 5 switches
7f9f: a2 04 ldx #$04
7fa1: 3e 03 20 GetBtnsLoop1 rol HyprSpcSw,x ;Get the status of: self test, slam, diagnostic step,
7fa4: 6a ror A ; fire and hyperspace switches
7fa5: ca dex ;More switches to get the status of?
7fa6: 10 f9 bpl GetBtnsLoop1 ;If so, branch
7fa8: a8 tay ;Prepare to get the statuses of 8 switches
7fa9: a2 07 ldx #$07
7fab: 3e 00 24 GetBtnsLoop2 rol LeftCoinSw,x ;Get the status of: rotate left, rotate right, thrust,
7fae: 2a rol A ; 2 player start, 1 player start, right coin, center coin
7faf: ca dex ; left coin switches
7fb0: 10 f9 bpl GetBtnsLoop2 ;More switches to get the status of? If so, branch
;
7fb2: aa tax
7fb3: 45 08 eor ]tmp_08 ;Store bits indicating button changes
7fb5: 86 08 stx ]tmp_08
7fb7: 08 php ;Save processor status.
7fb8: a9 04 lda #RamSwap ;Swap RAM pages
7fba: 8d 00 32 sta MultiPurp
7fbd: 2e 03 20 rol HyprSpcSw
7fc0: 2a rol A
7fc1: 2e 04 20 rol FireSw
7fc4: 2a rol A
7fc5: 2e 07 24 rol RotLeftSw ;Save the statuses of the player inputs into X
7fc8: 2a rol A
7fc9: 2e 06 24 rol RotRghtSw
7fcc: 2a rol A
7fcd: 2e 05 24 rol ThrustSw
7fd0: 2a rol A
7fd1: aa tax
7fd2: 28 plp ;Restore processor status
7fd3: d0 09 bne ButtonChanged ;Were buttons changed? if so, branch
7fd5: 45 0a eor ]tmp_0a ;Was a button change detected?
7fd7: d0 05 bne ButtonChanged ;If so, branch to make a sound
7fd9: 98 tya ;Was a button changed detected?
7fda: 45 09 eor ]TestSFXInit
7fdc: f0 02 beq DoHardwareWrite ;If not, branch to turn off the SFX
;
7fde: a9 80 ButtonChanged lda #EnableBit ;Button change detected, set the MSB
7fe0: 8d 05 3c DoHardwareWrite sta LifeSFX ;Play/halt SFX
7fe3: 8d 00 32 sta MultiPurp ;No effect
7fe6: 8d 00 30 sta DmaGo ;Start/stop the vector state machine
7fe9: 86 0a stx ]tmp_0a ;Store current button statuses
7feb: 84 09 sty ]TestSFXInit
7fed: ad 07 20 lda SelfTestSw ;Is self test switch still on? If so, loop
7ff0: 10 fe :Spin bpl :Spin ;self test released; spin lock until watchdog reset
7ff2: 4c 73 7e jmp SelfTestMainLoop ;Stay in self test loop
;
; The table below sets the right coin mechanism multiplier based on the settings
; of DIP switches 5 and 6.
;
7ff5: 01 04 05 06 CoinMultTbl .bulk $01,$04,$05,$06
;
7ff9: 4e .dd1 $4e ;checksum byte
;
7ffa: 65 7b .dd2 NMI ;NMI vector
7ffc: f3 7c .dd2 RESET ;RESET vector
7ffe: f3 7c .dd2 RESET ;IRQ vector
.adrend ↑ $6800
********************************************************************************
* *
* Start of vector ROM. *
* *
* The first item is a test pattern: diamond grid with a series of horizontal *
* lines of varying brightness in the center. *
* *
********************************************************************************
.addrs $5000
5000: 80 a0 .dd2 $a080 ;LABS x=0 y=128 sc=0
5002: 00 00 .dd2 $0000
5004: 00 70 .dd2 $7000 ;VCTR x=+0 y=+0 sc=7 b=0
5006: 00 00 .dd2 $0000
5008: 00 90 .dd2 $9000 ;VCTR x=+1023 y=+0 sc=9 b=7
500a: ff 73 .dd2 $73ff
500c: ff 92 .dd2 $92ff ;VCTR x=+0 y=+767 sc=9 b=7
500e: 00 70 .dd2 $7000
5010: 00 90 .dd2 $9000 ;VCTR x=-1023 y=+0 sc=9 b=7
5012: ff 77 .dd2 $77ff
5014: ff 96 .dd2 $96ff ;VCTR x=+0 y=-767 sc=9 b=7
5016: 00 70 .dd2 $7000
5018: ff 92 .dd2 $92ff ;VCTR x=+767 y=+767 sc=9 b=7
501a: ff 72 .dd2 $72ff
501c: 00 86 .dd2 $8600 ;VCTR x=+512 y=-512 sc=8 b=7
501e: 00 72 .dd2 $7200
5020: fe 87 .dd2 $87fe ;VCTR x=-1022 y=-1022 sc=8 b=7
5022: fe 77 .dd2 $77fe
5024: 00 92 .dd2 $9200 ;VCTR x=-512 y=+512 sc=9 b=7
5026: 00 76 .dd2 $7600
5028: fe 81 .dd2 $81fe ;VCTR x=+512 y=+510 sc=8 b=7
502a: 00 72 .dd2 $7200
502c: ff 96 .dd2 $96ff ;VCTR x=+767 y=-767 sc=9 b=7
502e: ff 72 .dd2 $72ff
5030: 7f a3 .dd2 $a37f ;LABS x=1023 y=895 sc=0
5032: ff 03 .dd2 $03ff
5034: 00 70 .dd2 $7000 ;VCTR x=+0 y=+0 sc=7 b=0
5036: 00 00 .dd2 $0000
5038: ff 96 .dd2 $96ff ;VCTR x=-767 y=-767 sc=9 b=7
503a: ff 76 .dd2 $76ff
503c: fe 81 .dd2 $81fe ;VCTR x=-512 y=+510 sc=8 b=7
503e: 00 76 .dd2 $7600
5040: 00 92 .dd2 $9200 ;VCTR x=+512 y=+512 sc=9 b=7
5042: 00 72 .dd2 $7200
5044: fe 87 .dd2 $87fe ;VCTR x=+1022 y=-1022 sc=8 b=7
5046: fe 73 .dd2 $73fe
5048: 00 86 .dd2 $8600 ;VCTR x=-512 y=-512 sc=8 b=7
504a: 00 76 .dd2 $7600
504c: ff 92 .dd2 $92ff ;VCTR x=-767 y=+767 sc=9 b=7
504e: ff 76 .dd2 $76ff
5050: fc a1 .dd2 $a1fc ;LABS x=500 y=508 sc=0
5052: f4 01 .dd2 $01f4
5054: 00 70 .dd2 $7000 ;VCTR x=+0 y=+0 sc=7 b=0
5056: 00 00 .dd2 $0000
5058: db f0 .dd2 $f0db ;SVEC x=+3 y=+0 sc=2 b=13
505a: 00 f9 .dd2 $f900 ;SVEC x=+0 y=+1 sc=1 b=0
505c: cf f0 .dd2 $f0cf ;SVEC x=-3 y=+0 sc=2 b=12
505e: 00 f9 .dd2 $f900 ;SVEC x=+0 y=+1 sc=1 b=0
5060: bb f0 .dd2 $f0bb ;SVEC x=+3 y=+0 sc=2 b=11
5062: 00 f9 .dd2 $f900 ;SVEC x=+0 y=+1 sc=1 b=0
5064: af f0 .dd2 $f0af ;SVEC x=-3 y=+0 sc=2 b=10
5066: 00 f9 .dd2 $f900 ;SVEC x=+0 y=+1 sc=1 b=0
5068: 9b f0 .dd2 $f09b ;SVEC x=+3 y=+0 sc=2 b=9
506a: 00 f9 .dd2 $f900 ;SVEC x=+0 y=+1 sc=1 b=0
506c: 8f f0 .dd2 $f08f ;SVEC x=-3 y=+0 sc=2 b=8
506e: 00 f9 .dd2 $f900 ;SVEC x=+0 y=+1 sc=1 b=0
5070: 7b f0 .dd2 $f07b ;SVEC x=+3 y=+0 sc=2 b=7
5072: 00 f9 .dd2 $f900 ;SVEC x=+0 y=+1 sc=1 b=0
5074: 6f f0 .dd2 $f06f ;SVEC x=-3 y=+0 sc=2 b=6
5076: 00 f9 .dd2 $f900 ;SVEC x=+0 y=+1 sc=1 b=0
5078: 5b f0 .dd2 $f05b ;SVEC x=+3 y=+0 sc=2 b=5
507a: 00 f9 .dd2 $f900 ;SVEC x=+0 y=+1 sc=1 b=0
507c: 4f f0 .dd2 $f04f ;SVEC x=-3 y=+0 sc=2 b=4
507e: 00 f9 .dd2 $f900 ;SVEC x=+0 y=+1 sc=1 b=0
5080: 3b f0 .dd2 $f03b ;SVEC x=+3 y=+0 sc=2 b=3
5082: 00 f9 .dd2 $f900 ;SVEC x=+0 y=+1 sc=1 b=0
5084: 2f f0 .dd2 $f02f ;SVEC x=-3 y=+0 sc=2 b=2
5086: 7c d0 .dd2 $d07c ;RTSL
;
; Bank error message, for self test.
;
5088: e4 a0 VecBankErr .dd2 $a0e4 ;LABS x=350 y=228 sc=1
508a: 5e 11 .dd2 $115e
508c: 00 70 .dd2 $7000 ;VCTR x=+0 y=+0 sc=7 b=0
508e: 00 00 .dd2 $0000
5090: 80 ca .dd2 $ca80 ;JSRL a=$0a80 ($5500)
5092: 78 ca .dd2 $ca78 ;JSRL a=$0a78 ($54f0)
5094: d8 ca .dd2 $cad8 ;JSRL a=$0ad8 ($55b0)
5096: c7 ca .dd2 $cac7 ;JSRL a=$0ac7 ($558e)
5098: 2c cb .dd2 $cb2c ;JSRL a=$0b2c ($5658)
509a: 9b ca .dd2 $ca9b ;JSRL a=$0a9b ($5536)
509c: f3 ca .dd2 $caf3 ;JSRL a=$0af3 ($55e6)
509e: f3 ca .dd2 $caf3 ;JSRL a=$0af3 ($55e6)
50a0: dd ca .dd2 $cadd ;JSRL a=$0add ($55ba)
50a2: f3 ea .dd2 $eaf3 ;JMPL a=$0af3 ($55e6)
;
; Copyright notice.
;
50a4: 80 a0 VecCredits .dd2 $a080 ;LABS x=400 y=128 sc=0
50a6: 90 01 .dd2 $0190
50a8: 00 70 .dd2 $7000 ;VCTR x=+0 y=+0 sc=7 b=0
50aa: 00 00 .dd2 $0000
50ac: 73 f5 .dd2 $f573 ;SVEC x=+3 y=-1 sc=0 b=7
50ae: 73 f1 .dd2 $f173 ;SVEC x=+3 y=+1 sc=0 b=7
50b0: 78 f1 .dd2 $f178 ;SVEC x=+0 y=+1 sc=2 b=7
50b2: 77 f1 .dd2 $f177 ;SVEC x=-3 y=+1 sc=0 b=7
50b4: 77 f5 .dd2 $f577 ;SVEC x=-3 y=-1 sc=0 b=7
50b6: 78 f5 .dd2 $f578 ;SVEC x=+0 y=-1 sc=2 b=7
50b8: 80 31 .dd2 $3180 ;VCTR x=+512 y=+384 sc=3 b=0
50ba: 00 02 .dd2 $0200
50bc: 75 f8 .dd2 $f875 ;SVEC x=-1 y=+0 sc=1 b=7
50be: 70 fd .dd2 $fd70 ;SVEC x=+0 y=-1 sc=1 b=7
50c0: 71 f8 .dd2 $f871 ;SVEC x=+1 y=+0 sc=1 b=7
50c2: 02 fd .dd2 $fd02 ;SVEC x=+2 y=-1 sc=1 b=0
50c4: 2e cb .dd2 $cb2e ;JSRL a=$0b2e ($565c)
50c6: 63 cb .dd2 $cb63 ;JSRL a=$0b63 ($56c6)
50c8: 56 cb .dd2 $cb56 ;JSRL a=$0b56 ($56ac)
50ca: 63 cb .dd2 $cb63 ;JSRL a=$0b63 ($56c6)
50cc: 2c cb .dd2 $cb2c ;JSRL a=$0b2c ($5658)
50ce: 78 ca .dd2 $ca78 ;JSRL a=$0a78 ($54f0)
50d0: 02 cb .dd2 $cb02 ;JSRL a=$0b02 ($5604)
50d2: 78 ca .dd2 $ca78 ;JSRL a=$0a78 ($54f0)
50d4: f3 ca .dd2 $caf3 ;JSRL a=$0af3 ($55e6)
50d6: ba ca .dd2 $caba ;JSRL a=$0aba ($5574)
50d8: 2c cb .dd2 $cb2c ;JSRL a=$0b2c ($5658)
50da: ba ca .dd2 $caba ;JSRL a=$0aba ($5574)
50dc: d8 ca .dd2 $cad8 ;JSRL a=$0ad8 ($55b0)
50de: 8d ea .dd2 $ea8d ;JMPL a=$0a8d ($551a)
;
; Exploding ship pieces. Parts are copied into RAM.
;
50e0: c6 ff ShipExpPtrTbl .dd2 $ffc6 ;SVEC x=-2 y=-3 sc=1 b=12
50e2: c1 fe .dd2 $fec1 ;SVEC x=+1 y=-2 sc=1 b=12
50e4: c3 f1 .dd2 $f1c3 ;SVEC x=+3 y=+1 sc=0 b=12
50e6: cd f1 .dd2 $f1cd ;SVEC x=-1 y=+1 sc=2 b=12
50e8: c7 f1 .dd2 $f1c7 ;SVEC x=-3 y=+1 sc=0 b=12
50ea: c1 fd .dd2 $fdc1 ;SVEC x=+1 y=-1 sc=1 b=12
;
; Ship explosion velocity (X,Y).
;
50ec: d8 1e ShipExpVelTbl .bulk $d8,$1e
50ee: 32 ec .bulk $32,$ec
50f0: 00 c4 .bulk $00,$c4
50f2: 3c 14 .bulk $3c,$14
50f4: 0a 46 .bulk $0a,$46
50f6: d8 d8 .bulk $d8,$d8
;
; Shrapnel Patterns. This is used when the player's shot hits something. Notice
; that all four patterns are the same just slightly spread out. This is
; extremely clever. You could use one pattern and vary the scale to make it look
; like it is spreading out. But the scale jumps are powers-of-two. These
; slightly-scaled patterns can be used to take up the gaps in the large scaling
; doubles!
;
; JSRLs to four shrapnel patterns.
;
50f8: d0 c8 SharpPatPtrTbl .dd2 $c8d0 ;JSRL a=$08d0 ($51a0)
50fa: b5 c8 .dd2 $c8b5 ;JSRL a=$08b5 ($516a)
50fc: 96 c8 .dd2 $c896 ;JSRL a=$0896 ($512c)
50fe: 80 c8 .dd2 $c880 ;JSRL a=$0880 ($5100)
;
; Shrapnel pattern 1.
;
5100: 0d f8 .dd2 $f80d ;SVEC x=-1 y=+0 sc=3 b=0 <<<
5102: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5104: 0d fd .dd2 $fd0d ;SVEC x=-1 y=-1 sc=3 b=0
5106: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5108: 09 fd .dd2 $fd09 ;SVEC x=+1 y=-1 sc=3 b=0
510a: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
510c: 0b f1 .dd2 $f10b ;SVEC x=+3 y=+1 sc=2 b=0
510e: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5110: 0a f5 .dd2 $f50a ;SVEC x=+2 y=-1 sc=2 b=0
5112: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5114: 08 f9 .dd2 $f908 ;SVEC x=+0 y=+1 sc=3 b=0
5116: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5118: 09 f3 .dd2 $f309 ;SVEC x=+1 y=+3 sc=2 b=0
511a: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
511c: 0d f3 .dd2 $f30d ;SVEC x=-1 y=+3 sc=2 b=0
511e: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5120: 80 54 .dd2 $5480 ;VCTR x=-512 y=-128 sc=5 b=0
5122: 00 06 .dd2 $0600
5124: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5126: 0f f1 .dd2 $f10f ;SVEC x=-3 y=+1 sc=2 b=0
5128: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
512a: 00 d0 .dd2 $d000 ;RTSL
;
; Shrapnel pattern 2.
;
512c: 00 30 .dd2 $3000 ;VCTR x=-896 y=+0 sc=3 b=0 <<<
512e: 80 07 .dd2 $0780
5130: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5132: 80 37 .dd2 $3780 ;VCTR x=-896 y=-896 sc=3 b=0
5134: 80 07 .dd2 $0780
5136: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5138: 80 37 .dd2 $3780 ;VCTR x=+896 y=-896 sc=3 b=0
513a: 80 03 .dd2 $0380
513c: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
513e: e0 40 .dd2 $40e0 ;VCTR x=+672 y=+224 sc=4 b=0
5140: a0 02 .dd2 $02a0
5142: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5144: c0 35 .dd2 $35c0 ;VCTR x=+896 y=-448 sc=3 b=0
5146: 80 03 .dd2 $0380
5148: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
514a: 80 33 .dd2 $3380 ;VCTR x=+0 y=+896 sc=3 b=0
514c: 00 00 .dd2 $0000
514e: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5150: a0 42 .dd2 $42a0 ;VCTR x=+224 y=+672 sc=4 b=0
5152: e0 00 .dd2 $00e0
5154: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5156: a0 42 .dd2 $42a0 ;VCTR x=-224 y=+672 sc=4 b=0
5158: e0 04 .dd2 $04e0
515a: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
515c: e0 44 .dd2 $44e0 ;VCTR x=-896 y=-224 sc=4 b=0
515e: 80 07 .dd2 $0780
5160: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5162: e0 40 .dd2 $40e0 ;VCTR x=-672 y=+224 sc=4 b=0
5164: a0 06 .dd2 $06a0
5166: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5168: 00 d0 .dd2 $d000 ;RTSL
;
; Shrapnel patern 3.
;
516a: 07 f8 .dd2 $f807 ;SVEC x=-3 y=+0 sc=1 b=0 <<<
516c: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
516e: 07 ff .dd2 $ff07 ;SVEC x=-3 y=-3 sc=1 b=0
5170: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5172: 03 ff .dd2 $ff03 ;SVEC x=+3 y=-3 sc=1 b=0
5174: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5176: c0 40 .dd2 $40c0 ;VCTR x=+576 y=+192 sc=4 b=0
5178: 40 02 .dd2 $0240
517a: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
517c: 80 35 .dd2 $3580 ;VCTR x=+768 y=-384 sc=3 b=0
517e: 00 03 .dd2 $0300
5180: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5182: 00 fb .dd2 $fb00 ;SVEC x=+0 y=+3 sc=1 b=0
5184: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5186: 40 42 .dd2 $4240 ;VCTR x=+192 y=+576 sc=4 b=0
5188: c0 00 .dd2 $00c0
518a: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
518c: 40 42 .dd2 $4240 ;VCTR x=-192 y=+576 sc=4 b=0
518e: c0 04 .dd2 $04c0
5190: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5192: c0 44 .dd2 $44c0 ;VCTR x=-768 y=-192 sc=4 b=0
5194: 00 07 .dd2 $0700
5196: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
5198: c0 40 .dd2 $40c0 ;VCTR x=-576 y=+192 sc=4 b=0
519a: 40 06 .dd2 $0640
519c: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
519e: 00 d0 .dd2 $d000 ;RTSL
;
; Shrapnel pattern 4.
;
51a0: 00 30 .dd2 $3000 ;VCTR x=-640 y=+0 sc=3 b=0 <<<
51a2: 80 06 .dd2 $0680
51a4: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
51a6: 80 36 .dd2 $3680 ;VCTR x=-640 y=-640 sc=3 b=0
51a8: 80 06 .dd2 $0680
51aa: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
51ac: 80 36 .dd2 $3680 ;VCTR x=+640 y=-640 sc=3 b=0
51ae: 80 02 .dd2 $0280
51b0: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
51b2: 40 31 .dd2 $3140 ;VCTR x=+960 y=+320 sc=3 b=0
51b4: c0 03 .dd2 $03c0
51b6: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
51b8: 40 35 .dd2 $3540 ;VCTR x=+640 y=-320 sc=3 b=0
51ba: 80 02 .dd2 $0280
51bc: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
51be: 80 32 .dd2 $3280 ;VCTR x=+0 y=+640 sc=3 b=0
51c0: 00 00 .dd2 $0000
51c2: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
51c4: c0 33 .dd2 $33c0 ;VCTR x=+320 y=+960 sc=3 b=0
51c6: 40 01 .dd2 $0140
51c8: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
51ca: c0 33 .dd2 $33c0 ;VCTR x=-320 y=+960 sc=3 b=0
51cc: 40 05 .dd2 $0540
51ce: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
51d0: a0 44 .dd2 $44a0 ;VCTR x=-640 y=-160 sc=4 b=0
51d2: 80 06 .dd2 $0680
51d4: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
51d6: 40 31 .dd2 $3140 ;VCTR x=-960 y=+320 sc=3 b=0
51d8: c0 07 .dd2 $07c0
51da: 78 f8 .dd2 $f878 ;SVEC x=+0 y=+0 sc=3 b=7
51dc: 00 d0 .dd2 $d000 ;RTSL
;
; Asteroid patterns.
;
51de: f3 c8 AstPtrnPtrTbl .dd2 $c8f3 ;JSRL a=$08f3 ($51e6)
51e0: ff c8 .dd2 $c8ff ;JSRL a=$08ff ($51fe)
51e2: 0d c9 .dd2 $c90d ;JSRL a=$090d ($521a)
51e4: 1a c9 .dd2 $c91a ;JSRL a=$091a ($5234)
51e6: 08 f9 .dd2 $f908 ;SVEC x=+0 y=+1 sc=3 b=0 <<<
51e8: 79 f9 .dd2 $f979 ;SVEC x=+1 y=+1 sc=3 b=7
51ea: 79 fd .dd2 $fd79 ;SVEC x=+1 y=-1 sc=3 b=7
51ec: 7d f6 .dd2 $f67d ;SVEC x=-1 y=-2 sc=2 b=7
51ee: 79 f6 .dd2 $f679 ;SVEC x=+1 y=-2 sc=2 b=7
51f0: 8f f6 .dd2 $f68f ;SVEC x=-3 y=-2 sc=2 b=8
51f2: 8f f0 .dd2 $f08f ;SVEC x=-3 y=+0 sc=2 b=8
51f4: 7d f9 .dd2 $f97d ;SVEC x=-1 y=+1 sc=3 b=7
51f6: 78 fa .dd2 $fa78 ;SVEC x=+0 y=+2 sc=3 b=7
51f8: 79 f9 .dd2 $f979 ;SVEC x=+1 y=+1 sc=3 b=7
51fa: 79 fd .dd2 $fd79 ;SVEC x=+1 y=-1 sc=3 b=7
51fc: 00 d0 .dd2 $d000 ;RTSL
51fe: 0a f1 .dd2 $f10a ;SVEC x=+2 y=+1 sc=2 b=0 <<<
5200: 7a f1 .dd2 $f17a ;SVEC x=+2 y=+1 sc=2 b=7
5202: 7d f9 .dd2 $f97d ;SVEC x=-1 y=+1 sc=3 b=7
5204: 7e f5 .dd2 $f57e ;SVEC x=-2 y=-1 sc=2 b=7
5206: 7e f1 .dd2 $f17e ;SVEC x=-2 y=+1 sc=2 b=7
5208: 7d fd .dd2 $fd7d ;SVEC x=-1 y=-1 sc=3 b=7
520a: 79 f6 .dd2 $f679 ;SVEC x=+1 y=-2 sc=2 b=7
520c: 7d f6 .dd2 $f67d ;SVEC x=-1 y=-2 sc=2 b=7
520e: 79 fd .dd2 $fd79 ;SVEC x=+1 y=-1 sc=3 b=7
5210: 79 f1 .dd2 $f179 ;SVEC x=+1 y=+1 sc=2 b=7
5212: 8b f5 .dd2 $f58b ;SVEC x=+3 y=-1 sc=2 b=8
5214: 8a f3 .dd2 $f38a ;SVEC x=+2 y=+3 sc=2 b=8
5216: 7d f9 .dd2 $f97d ;SVEC x=-1 y=+1 sc=3 b=7
5218: 00 d0 .dd2 $d000 ;RTSL
521a: 0d f8 .dd2 $f80d ;SVEC x=-1 y=+0 sc=3 b=0 <<<
521c: 7e f5 .dd2 $f57e ;SVEC x=-2 y=-1 sc=2 b=7
521e: 7a f7 .dd2 $f77a ;SVEC x=+2 y=-3 sc=2 b=7
5220: 7a f3 .dd2 $f37a ;SVEC x=+2 y=+3 sc=2 b=7
5222: 78 f7 .dd2 $f778 ;SVEC x=+0 y=-3 sc=2 b=7
5224: 79 f8 .dd2 $f879 ;SVEC x=+1 y=+0 sc=3 b=7
5226: 7a f3 .dd2 $f37a ;SVEC x=+2 y=+3 sc=2 b=7
5228: 78 f9 .dd2 $f978 ;SVEC x=+0 y=+1 sc=3 b=7
522a: 7e f3 .dd2 $f37e ;SVEC x=-2 y=+3 sc=2 b=7
522c: 7f f0 .dd2 $f07f ;SVEC x=-3 y=+0 sc=2 b=7
522e: 7f f7 .dd2 $f77f ;SVEC x=-3 y=-3 sc=2 b=7
5230: 7a f5 .dd2 $f57a ;SVEC x=+2 y=-1 sc=2 b=7
5232: 00 d0 .dd2 $d000 ;RTSL
5234: 09 f0 .dd2 $f009 ;SVEC x=+1 y=+0 sc=2 b=0 <<<
5236: 7b f1 .dd2 $f17b ;SVEC x=+3 y=+1 sc=2 b=7
5238: 68 f1 .dd2 $f168 ;SVEC x=+0 y=+1 sc=2 b=6
523a: 7f f2 .dd2 $f27f ;SVEC x=-3 y=+2 sc=2 b=7
523c: 7f f0 .dd2 $f07f ;SVEC x=-3 y=+0 sc=2 b=7
523e: 69 f6 .dd2 $f669 ;SVEC x=+1 y=-2 sc=2 b=6
5240: 7f f0 .dd2 $f07f ;SVEC x=-3 y=+0 sc=2 b=7
5242: 78 f7 .dd2 $f778 ;SVEC x=+0 y=-3 sc=2 b=7
5244: 7a f7 .dd2 $f77a ;SVEC x=+2 y=-3 sc=2 b=7
5246: 7b f1 .dd2 $f17b ;SVEC x=+3 y=+1 sc=2 b=7
5248: 69 f5 .dd2 $f569 ;SVEC x=+1 y=-1 sc=2 b=6
524a: 69 f9 .dd2 $f969 ;SVEC x=+1 y=+1 sc=3 b=6
524c: 7f f2 .dd2 $f27f ;SVEC x=-3 y=+2 sc=2 b=7
524e: 00 d0 .dd2 $d000 ;RTSL
;
; Flying saucer. The same shape is used for big and small versions.
;
5250: 29 c9 ScrPtrnPtrTbl .dd2 $c929 ;JSRL a=$0929 ($5252)
5252: 0e f1 .dd2 $f10e ;SVEC x=-2 y=+1 sc=2 b=0 <<<
5254: ca f8 .dd2 $f8ca ;SVEC x=+2 y=+0 sc=3 b=12
5256: 0b f6 .dd2 $f60b ;SVEC x=+3 y=-2 sc=2 b=0
5258: 00 60 .dd2 $6000 ;VCTR x=-640 y=+0 sc=6 b=13
525a: 80 d6 .dd2 $d680
525c: db f6 .dd2 $f6db ;SVEC x=+3 y=-2 sc=2 b=13
525e: ca f8 .dd2 $f8ca ;SVEC x=+2 y=+0 sc=3 b=12
5260: db f2 .dd2 $f2db ;SVEC x=+3 y=+2 sc=2 b=13
5262: df f2 .dd2 $f2df ;SVEC x=-3 y=+2 sc=2 b=13
5264: cd f2 .dd2 $f2cd ;SVEC x=-1 y=+2 sc=2 b=12
5266: cd f8 .dd2 $f8cd ;SVEC x=-1 y=+0 sc=3 b=12
5268: cd f6 .dd2 $f6cd ;SVEC x=-1 y=-2 sc=2 b=12
526a: df f6 .dd2 $f6df ;SVEC x=-3 y=-2 sc=2 b=13
526c: 00 d0 .dd2 $d000 ;RTSL
;
; Pointers to ship and thrust vector shape data.
;
; The code doesn't perform rotations, so there is a different shape for each
; direction in the first quadrant. Other quadrants are handled by flipping
; about the X and/or Y axis.
;
; Each ship shape is paired with a matching thrust cone. The thrust is only
; drawn if the player is accelerating.
;
526e: 90 52 ShipDirPtrTbl .dd2 ShipDir0
5270: a8 52 .dd2 ShipDir4
5272: cc 52 .dd2 ShipDir8
5274: f0 52 .dd2 ShipDir12
5276: 14 53 .dd2 ShipDir16
5278: 36 53 .dd2 ShipDir20
527a: 5a 53 .dd2 ShipDir24
527c: 7e 53 .dd2 ShipDir28
527e: a2 53 .dd2 ShipDir32
5280: c6 53 .dd2 ShipDir36
5282: ea 53 .dd2 ShipDir40
5284: 0e 54 .dd2 ShipDir44
5286: 32 54 .dd2 ShipDir48
5288: 56 54 .dd2 ShipDir52
528a: 7a 54 .dd2 ShipDir56
528c: 9e 54 .dd2 ShipDir60
528e: c2 54 .dd2 ShipDir64
;
5290: 0f f6 ShipDir0 .dd2 $f60f ;SVEC x=-3 y=-2 sc=2 b=0
5292: c8 fa .dd2 $fac8 ;SVEC x=+0 y=+2 sc=3 b=12
5294: bd f9 .dd2 $f9bd ;SVEC x=-1 y=+1 sc=3 b=11
5296: 00 65 .dd2 $6500 ;VCTR x=+768 y=-256 sc=6 b=12
5298: 00 c3 .dd2 $c300
529a: 00 65 .dd2 $6500 ;VCTR x=-768 y=-256 sc=6 b=12
529c: 00 c7 .dd2 $c700
529e: b9 f9 .dd2 $f9b9 ;SVEC x=+1 y=+1 sc=3 b=11
52a0: 00 d0 .dd2 $d000 ;RTSL
52a2: ce f9 ThrustDir0 .dd2 $f9ce ;SVEC x=-2 y=+1 sc=3 b=12
52a4: ca f9 .dd2 $f9ca ;SVEC x=+2 y=+1 sc=3 b=12
52a6: 00 d0 .dd2 $d000 ;RTSL
52a8: 40 46 ShipDir4 .dd2 $4640 ;VCTR x=-704 y=-576 sc=4 b=0
52aa: c0 06 .dd2 $06c0
52ac: 00 52 .dd2 $5200 ;VCTR x=-48 y=+512 sc=5 b=12
52ae: 30 c4 .dd2 $c430
52b0: c0 41 .dd2 $41c0 ;VCTR x=-544 y=+448 sc=4 b=12
52b2: 20 c6 .dd2 $c620
52b4: b0 64 .dd2 $64b0 ;VCTR x=+792 y=-176 sc=6 b=12
52b6: 18 c3 .dd2 $c318
52b8: 48 65 .dd2 $6548 ;VCTR x=-736 y=-328 sc=6 b=12
52ba: e0 c6 .dd2 $c6e0
52bc: 20 42 .dd2 $4220 ;VCTR x=+448 y=+544 sc=4 b=12
52be: c0 c1 .dd2 $c1c0
52c0: 00 d0 .dd2 $d000 ;RTSL
52c2: d0 50 ThrustDir4 .dd2 $50d0 ;VCTR x=-528 y=+208 sc=5 b=12
52c4: 10 c6 .dd2 $c610
52c6: 60 42 .dd2 $4260 ;VCTR x=+960 y=+608 sc=4 b=12
52c8: c0 c3 .dd2 $c3c0
52ca: 00 d0 .dd2 $d000 ;RTSL
52cc: 80 46 ShipDir8 .dd2 $4680 ;VCTR x=-640 y=-640 sc=4 b=0
52ce: 80 06 .dd2 $0680
52d0: e0 43 .dd2 $43e0 ;VCTR x=-192 y=+992 sc=4 b=12
52d2: c0 c4 .dd2 $c4c0
52d4: a0 41 .dd2 $41a0 ;VCTR x=-608 y=+416 sc=4 b=12
52d6: 60 c6 .dd2 $c660
52d8: 68 64 .dd2 $6468 ;VCTR x=+800 y=-104 sc=6 b=12
52da: 20 c3 .dd2 $c320
52dc: 90 65 .dd2 $6590 ;VCTR x=-704 y=-400 sc=6 b=12
52de: c0 c6 .dd2 $c6c0
52e0: 60 42 .dd2 $4260 ;VCTR x=+416 y=+608 sc=4 b=12
52e2: a0 c1 .dd2 $c1a0
52e4: 00 d0 .dd2 $d000 ;RTSL
52e6: 90 50 .dd2 $5090 ;VCTR x=-560 y=+144 sc=5 b=12
52e8: 30 c6 .dd2 $c630
52ea: c0 42 .dd2 $42c0 ;VCTR x=+896 y=+704 sc=4 b=12
52ec: 80 c3 .dd2 $c380
52ee: 00 d0 .dd2 $d000 ;RTSL
52f0: c0 46 ShipDir12 .dd2 $46c0 ;VCTR x=-576 y=-704 sc=4 b=0
52f2: 40 06 .dd2 $0640
52f4: e0 43 .dd2 $43e0 ;VCTR x=-288 y=+992 sc=4 b=12
52f6: 20 c5 .dd2 $c520
52f8: 60 41 .dd2 $4160 ;VCTR x=-640 y=+352 sc=4 b=12
52fa: 80 c6 .dd2 $c680
52fc: 18 64 .dd2 $6418 ;VCTR x=+808 y=-24 sc=6 b=12
52fe: 28 c3 .dd2 $c328
5300: d0 65 .dd2 $65d0 ;VCTR x=-664 y=-464 sc=6 b=12
5302: 98 c6 .dd2 $c698
5304: 80 42 .dd2 $4280 ;VCTR x=+352 y=+640 sc=4 b=12
5306: 60 c1 .dd2 $c160
5308: 00 d0 .dd2 $d000 ;RTSL
530a: 60 50 .dd2 $5060 ;VCTR x=-560 y=+96 sc=5 b=12
530c: 30 c6 .dd2 $c630
530e: 20 43 .dd2 $4320 ;VCTR x=+832 y=+800 sc=4 b=12
5310: 40 c3 .dd2 $c340
5312: 00 d0 .dd2 $d000 ;RTSL
5314: 0e f7 ShipDir16 .dd2 $f70e ;SVEC x=-2 y=-3 sc=2 b=0
5316: c0 43 .dd2 $43c0 ;VCTR x=-384 y=+960 sc=4 b=12
5318: 80 c5 .dd2 $c580
531a: 20 41 .dd2 $4120 ;VCTR x=-672 y=+288 sc=4 b=12
531c: a0 c6 .dd2 $c6a0
531e: 38 60 .dd2 $6038 ;VCTR x=+808 y=+56 sc=6 b=12
5320: 28 c3 .dd2 $c328
5322: 10 66 .dd2 $6610 ;VCTR x=-608 y=-528 sc=6 b=12
5324: 60 c6 .dd2 $c660
5326: a0 42 .dd2 $42a0 ;VCTR x=+288 y=+672 sc=4 b=12
5328: 20 c1 .dd2 $c120
532a: 00 d0 .dd2 $d000 ;RTSL
532c: 30 50 .dd2 $5030 ;VCTR x=-576 y=+48 sc=5 b=12
532e: 40 c6 .dd2 $c640
5330: 60 43 .dd2 $4360 ;VCTR x=+736 y=+864 sc=4 b=12
5332: e0 c2 .dd2 $c2e0
5334: 00 d0 .dd2 $d000 ;RTSL
5336: 20 47 ShipDir20 .dd2 $4720 ;VCTR x=-448 y=-800 sc=4 b=0
5338: c0 05 .dd2 $05c0
533a: 80 43 .dd2 $4380 ;VCTR x=-480 y=+896 sc=4 b=12
533c: e0 c5 .dd2 $c5e0
533e: e0 40 .dd2 $40e0 ;VCTR x=-704 y=+224 sc=4 b=12
5340: c0 c6 .dd2 $c6c0
5342: 88 60 .dd2 $6088 ;VCTR x=+800 y=+136 sc=6 b=12
5344: 20 c3 .dd2 $c320
5346: 48 66 .dd2 $6648 ;VCTR x=-560 y=-584 sc=6 b=12
5348: 30 c6 .dd2 $c630
534a: c0 42 .dd2 $42c0 ;VCTR x=+224 y=+704 sc=4 b=12
534c: e0 c0 .dd2 $c0e0
534e: 00 d0 .dd2 $d000 ;RTSL
5350: 10 54 .dd2 $5410 ;VCTR x=-576 y=-16 sc=5 b=12
5352: 40 c6 .dd2 $c640
5354: a0 43 .dd2 $43a0 ;VCTR x=+672 y=+928 sc=4 b=12
5356: a0 c2 .dd2 $c2a0
5358: 00 d0 .dd2 $d000 ;RTSL
535a: 60 47 ShipDir24 .dd2 $4760 ;VCTR x=-352 y=-864 sc=4 b=0
535c: 60 05 .dd2 $0560
535e: 60 43 .dd2 $4360 ;VCTR x=-576 y=+864 sc=4 b=12
5360: 40 c6 .dd2 $c640
5362: 80 40 .dd2 $4080 ;VCTR x=-704 y=+128 sc=4 b=12
5364: c0 c6 .dd2 $c6c0
5366: d8 60 .dd2 $60d8 ;VCTR x=+784 y=+216 sc=6 b=12
5368: 10 c3 .dd2 $c310
536a: 80 66 .dd2 $6680 ;VCTR x=-496 y=-640 sc=6 b=12
536c: f0 c5 .dd2 $c5f0
536e: c0 42 .dd2 $42c0 ;VCTR x=+128 y=+704 sc=4 b=12
5370: 80 c0 .dd2 $c080
5372: 00 d0 .dd2 $d000 ;RTSL
5374: 40 54 .dd2 $5440 ;VCTR x=-560 y=-64 sc=5 b=12
5376: 30 c6 .dd2 $c630
5378: e0 43 .dd2 $43e0 ;VCTR x=+576 y=+992 sc=4 b=12
537a: 40 c2 .dd2 $c240
537c: 00 d0 .dd2 $d000 ;RTSL
537e: 80 47 ShipDir28 .dd2 $4780 ;VCTR x=-256 y=-896 sc=4 b=0
5380: 00 05 .dd2 $0500
5382: 20 43 .dd2 $4320 ;VCTR x=-640 y=+800 sc=4 b=12
5384: 80 c6 .dd2 $c680
5386: 40 40 .dd2 $4040 ;VCTR x=-736 y=+64 sc=4 b=12
5388: e0 c6 .dd2 $c6e0
538a: 20 61 .dd2 $6120 ;VCTR x=+760 y=+288 sc=6 b=12
538c: f8 c2 .dd2 $c2f8
538e: b0 66 .dd2 $66b0 ;VCTR x=-432 y=-688 sc=6 b=12
5390: b0 c5 .dd2 $c5b0
5392: e0 42 .dd2 $42e0 ;VCTR x=+64 y=+736 sc=4 b=12
5394: 40 c0 .dd2 $c040
5396: 00 d0 .dd2 $d000 ;RTSL
5398: 80 54 .dd2 $5480 ;VCTR x=-560 y=-128 sc=5 b=12
539a: 30 c6 .dd2 $c630
539c: 10 52 .dd2 $5210 ;VCTR x=+240 y=+528 sc=5 b=12
539e: f0 c0 .dd2 $c0f0
53a0: 00 d0 .dd2 $d000 ;RTSL
53a2: 80 47 ShipDir32 .dd2 $4780 ;VCTR x=-192 y=-896 sc=4 b=0
53a4: c0 04 .dd2 $04c0
53a6: e0 42 .dd2 $42e0 ;VCTR x=-736 y=+736 sc=4 b=12
53a8: e0 c6 .dd2 $c6e0
53aa: 00 40 .dd2 $4000 ;VCTR x=-736 y=+0 sc=4 b=12
53ac: e0 c6 .dd2 $c6e0
53ae: 68 61 .dd2 $6168 ;VCTR x=+728 y=+360 sc=6 b=12
53b0: d8 c2 .dd2 $c2d8
53b2: d8 66 .dd2 $66d8 ;VCTR x=-360 y=-728 sc=6 b=12
53b4: 68 c5 .dd2 $c568
53b6: e0 42 .dd2 $42e0 ;VCTR x=+0 y=+736 sc=4 b=12
53b8: 00 c0 .dd2 $c000
53ba: 00 d0 .dd2 $d000 ;RTSL
53bc: b0 54 .dd2 $54b0 ;VCTR x=-544 y=-176 sc=5 b=12
53be: 20 c6 .dd2 $c620
53c0: 20 52 .dd2 $5220 ;VCTR x=+176 y=+544 sc=5 b=12
53c2: b0 c0 .dd2 $c0b0
53c4: 00 d0 .dd2 $d000 ;RTSL
53c6: a0 47 ShipDir36 .dd2 $47a0 ;VCTR x=-96 y=-928 sc=4 b=0
53c8: 60 04 .dd2 $0460
53ca: 80 42 .dd2 $4280 ;VCTR x=-800 y=+640 sc=4 b=12
53cc: 20 c7 .dd2 $c720
53ce: 40 44 .dd2 $4440 ;VCTR x=-736 y=-64 sc=4 b=12
53d0: e0 c6 .dd2 $c6e0
53d2: b0 61 .dd2 $61b0 ;VCTR x=+688 y=+432 sc=6 b=12
53d4: b0 c2 .dd2 $c2b0
53d6: f8 66 .dd2 $66f8 ;VCTR x=-288 y=-760 sc=6 b=12
53d8: 20 c5 .dd2 $c520
53da: e0 42 .dd2 $42e0 ;VCTR x=-64 y=+736 sc=4 b=12
53dc: 40 c4 .dd2 $c440
53de: 00 d0 .dd2 $d000 ;RTSL
53e0: f0 54 .dd2 $54f0 ;VCTR x=-528 y=-240 sc=5 b=12
53e2: 10 c6 .dd2 $c610
53e4: 30 52 .dd2 $5230 ;VCTR x=+128 y=+560 sc=5 b=12
53e6: 80 c0 .dd2 $c080
53e8: 00 d0 .dd2 $d000 ;RTSL
53ea: a0 47 ShipDir40 .dd2 $47a0 ;VCTR x=+0 y=-928 sc=4 b=0
53ec: 00 00 .dd2 $0000
53ee: 40 42 .dd2 $4240 ;VCTR x=-864 y=+576 sc=4 b=12
53f0: 60 c7 .dd2 $c760
53f2: 80 44 .dd2 $4480 ;VCTR x=-704 y=-128 sc=4 b=12
53f4: c0 c6 .dd2 $c6c0
53f6: f0 61 .dd2 $61f0 ;VCTR x=+640 y=+496 sc=6 b=12
53f8: 80 c2 .dd2 $c280
53fa: 10 67 .dd2 $6710 ;VCTR x=-216 y=-784 sc=6 b=12
53fc: d8 c4 .dd2 $c4d8
53fe: c0 42 .dd2 $42c0 ;VCTR x=-128 y=+704 sc=4 b=12
5400: 80 c4 .dd2 $c480
5402: 00 d0 .dd2 $d000 ;RTSL
5404: 40 46 .dd2 $4640 ;VCTR x=-992 y=-576 sc=4 b=12
5406: e0 c7 .dd2 $c7e0
5408: 30 52 .dd2 $5230 ;VCTR x=+64 y=+560 sc=5 b=12
540a: 40 c0 .dd2 $c040
540c: 00 d0 .dd2 $d000 ;RTSL
540e: a0 47 ShipDir44 .dd2 $47a0 ;VCTR x=+96 y=-928 sc=4 b=0
5410: 60 00 .dd2 $0060
5412: e0 41 .dd2 $41e0 ;VCTR x=-896 y=+480 sc=4 b=12
5414: 80 c7 .dd2 $c780
5416: e0 44 .dd2 $44e0 ;VCTR x=-704 y=-224 sc=4 b=12
5418: c0 c6 .dd2 $c6c0
541a: 30 62 .dd2 $6230 ;VCTR x=+584 y=+560 sc=6 b=12
541c: 48 c2 .dd2 $c248
541e: 20 67 .dd2 $6720 ;VCTR x=-136 y=-800 sc=6 b=12
5420: 88 c4 .dd2 $c488
5422: c0 42 .dd2 $42c0 ;VCTR x=-224 y=+704 sc=4 b=12
5424: e0 c4 .dd2 $c4e0
5426: 00 d0 .dd2 $d000 ;RTSL
5428: a0 46 .dd2 $46a0 ;VCTR x=-928 y=-672 sc=4 b=12
542a: a0 c7 .dd2 $c7a0
542c: 40 52 .dd2 $5240 ;VCTR x=+16 y=+576 sc=5 b=12
542e: 10 c0 .dd2 $c010
5430: 00 d0 .dd2 $d000 ;RTSL
5432: 80 47 ShipDir48 .dd2 $4780 ;VCTR x=+192 y=-896 sc=4 b=0
5434: c0 00 .dd2 $00c0
5436: 80 41 .dd2 $4180 ;VCTR x=-960 y=+384 sc=4 b=12
5438: c0 c7 .dd2 $c7c0
543a: 20 45 .dd2 $4520 ;VCTR x=-672 y=-288 sc=4 b=12
543c: a0 c6 .dd2 $c6a0
543e: 60 62 .dd2 $6260 ;VCTR x=+528 y=+608 sc=6 b=12
5440: 10 c2 .dd2 $c210
5442: 28 67 .dd2 $6728 ;VCTR x=-56 y=-808 sc=6 b=12
5444: 38 c4 .dd2 $c438
5446: a0 42 .dd2 $42a0 ;VCTR x=-288 y=+672 sc=4 b=12
5448: 20 c5 .dd2 $c520
544a: 00 d0 .dd2 $d000 ;RTSL
544c: e0 46 .dd2 $46e0 ;VCTR x=-864 y=-736 sc=4 b=12
544e: 60 c7 .dd2 $c760
5450: 40 52 .dd2 $5240 ;VCTR x=-48 y=+576 sc=5 b=12
5452: 30 c4 .dd2 $c430
5454: 00 d0 .dd2 $d000 ;RTSL
5456: 80 47 ShipDir52 .dd2 $4780 ;VCTR x=+256 y=-896 sc=4 b=0
5458: 00 01 .dd2 $0100
545a: 20 41 .dd2 $4120 ;VCTR x=-992 y=+288 sc=4 b=12
545c: e0 c7 .dd2 $c7e0
545e: 60 45 .dd2 $4560 ;VCTR x=-640 y=-352 sc=4 b=12
5460: 80 c6 .dd2 $c680
5462: 98 62 .dd2 $6298 ;VCTR x=+464 y=+664 sc=6 b=12
5464: d0 c1 .dd2 $c1d0
5466: 28 67 .dd2 $6728 ;VCTR x=+24 y=-808 sc=6 b=12
5468: 18 c0 .dd2 $c018
546a: 80 42 .dd2 $4280 ;VCTR x=-352 y=+640 sc=4 b=12
546c: 60 c5 .dd2 $c560
546e: 00 d0 .dd2 $d000 ;RTSL
5470: 40 47 .dd2 $4740 ;VCTR x=-800 y=-832 sc=4 b=12
5472: 20 c7 .dd2 $c720
5474: 30 52 .dd2 $5230 ;VCTR x=-96 y=+560 sc=5 b=12
5476: 60 c4 .dd2 $c460
5478: 00 d0 .dd2 $d000 ;RTSL
547a: 60 47 ShipDir56 .dd2 $4760 ;VCTR x=+352 y=-864 sc=4 b=0
547c: 60 01 .dd2 $0160
547e: c0 40 .dd2 $40c0 ;VCTR x=-992 y=+192 sc=4 b=12
5480: e0 c7 .dd2 $c7e0
5482: a0 45 .dd2 $45a0 ;VCTR x=-608 y=-416 sc=4 b=12
5484: 60 c6 .dd2 $c660
5486: c0 62 .dd2 $62c0 ;VCTR x=+400 y=+704 sc=6 b=12
5488: 90 c1 .dd2 $c190
548a: 20 67 .dd2 $6720 ;VCTR x=+104 y=-800 sc=6 b=12
548c: 68 c0 .dd2 $c068
548e: 60 42 .dd2 $4260 ;VCTR x=-416 y=+608 sc=4 b=12
5490: a0 c5 .dd2 $c5a0
5492: 00 d0 .dd2 $d000 ;RTSL
5494: 80 47 .dd2 $4780 ;VCTR x=-704 y=-896 sc=4 b=12
5496: c0 c6 .dd2 $c6c0
5498: 30 52 .dd2 $5230 ;VCTR x=-144 y=+560 sc=5 b=12
549a: 90 c4 .dd2 $c490
549c: 00 d0 .dd2 $d000 ;RTSL
549e: 20 47 ShipDir60 .dd2 $4720 ;VCTR x=+448 y=-800 sc=4 b=0
54a0: c0 01 .dd2 $01c0
54a2: 30 50 .dd2 $5030 ;VCTR x=-512 y=+48 sc=5 b=12
54a4: 00 c6 .dd2 $c600
54a6: c0 45 .dd2 $45c0 ;VCTR x=-544 y=-448 sc=4 b=12
54a8: 20 c6 .dd2 $c620
54aa: e0 62 .dd2 $62e0 ;VCTR x=+328 y=+736 sc=6 b=12
54ac: 48 c1 .dd2 $c148
54ae: 18 67 .dd2 $6718 ;VCTR x=+176 y=-792 sc=6 b=12
54b0: b0 c0 .dd2 $c0b0
54b2: 20 42 .dd2 $4220 ;VCTR x=-448 y=+544 sc=4 b=12
54b4: c0 c5 .dd2 $c5c0
54b6: 00 d0 .dd2 $d000 ;RTSL
54b8: c0 47 .dd2 $47c0 ;VCTR x=-608 y=-960 sc=4 b=12
54ba: 60 c6 .dd2 $c660
54bc: 10 52 .dd2 $5210 ;VCTR x=-208 y=+528 sc=5 b=12
54be: d0 c4 .dd2 $c4d0
54c0: 00 d0 .dd2 $d000 ;RTSL
54c2: 0a f7 ShipDir64 .dd2 $f70a ;SVEC x=+2 y=-3 sc=2 b=0
54c4: ce f8 .dd2 $f8ce ;SVEC x=-2 y=+0 sc=3 b=12
54c6: cd fd .dd2 $fdcd ;SVEC x=-1 y=-1 sc=3 b=12
54c8: 00 63 .dd2 $6300 ;VCTR x=+256 y=+768 sc=6 b=12
54ca: 00 c1 .dd2 $c100
54cc: 00 67 .dd2 $6700 ;VCTR x=+256 y=-768 sc=6 b=12
54ce: 00 c1 .dd2 $c100
54d0: cd f9 .dd2 $f9cd ;SVEC x=-1 y=+1 sc=3 b=12
54d2: 00 d0 .dd2 $d000 ;RTSL
54d4: cd fe .dd2 $fecd ;SVEC x=-1 y=-2 sc=3 b=12
54d6: cd fa .dd2 $facd ;SVEC x=-1 y=+2 sc=3 b=12
54d8: 00 d0 .dd2 $d000 ;RTSL
;
; Extra lives vector data. Draw one of these for each remaining life.
;
54da: 0e f7 ExtLivesDat .dd2 $f70e ;SVEC x=-2 y=-3 sc=2 b=0
54dc: 7a f8 .dd2 $f87a ;SVEC x=+2 y=+0 sc=3 b=7
54de: 79 fd .dd2 $fd79 ;SVEC x=+1 y=-1 sc=3 b=7
54e0: 00 63 .dd2 $6300 ;VCTR x=-256 y=+768 sc=6 b=7
54e2: 00 75 .dd2 $7500
54e4: 00 67 .dd2 $6700 ;VCTR x=-256 y=-768 sc=6 b=7
54e6: 00 75 .dd2 $7500
54e8: 79 f9 .dd2 $f979 ;SVEC x=+1 y=+1 sc=3 b=7
54ea: c0 60 .dd2 $60c0 ;VCTR x=+640 y=+192 sc=6 b=0
54ec: 80 02 .dd2 $0280
54ee: 9f d0 .dd2 $d09f ;RTSL
;
; Alphanumeric vector data.
;
; Each character leaves the vector pointed a short distance to the right of the
; initial position, so that you can output multiple characters without having to
; explicitly reposition each time.
;
54f0: 70 fa .dd2 $fa70 ;SVEC x=+0 y=+2 sc=1 b=7 <<<
54f2: 72 f2 .dd2 $f272 ;SVEC x=+2 y=+2 sc=0 b=7
54f4: 72 f6 .dd2 $f672 ;SVEC x=+2 y=-2 sc=0 b=7
54f6: 70 fe .dd2 $fe70 ;SVEC x=+0 y=-2 sc=1 b=7
54f8: 06 f9 .dd2 $f906 ;SVEC x=-2 y=+1 sc=1 b=0
54fa: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
54fc: 02 f6 .dd2 $f602 ;SVEC x=+2 y=-2 sc=0 b=0
54fe: 00 d0 .dd2 $d000 ;RTSL
5500: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
5502: 73 f0 .dd2 $f073 ;SVEC x=+3 y=+0 sc=0 b=7
5504: 71 f5 .dd2 $f571 ;SVEC x=+1 y=-1 sc=0 b=7
5506: 70 f5 .dd2 $f570 ;SVEC x=+0 y=-1 sc=0 b=7
5508: 75 f5 .dd2 $f575 ;SVEC x=-1 y=-1 sc=0 b=7
550a: 77 f0 .dd2 $f077 ;SVEC x=-3 y=+0 sc=0 b=7
550c: 03 f0 .dd2 $f003 ;SVEC x=+3 y=+0 sc=0 b=0
550e: 71 f5 .dd2 $f571 ;SVEC x=+1 y=-1 sc=0 b=7
5510: 70 f5 .dd2 $f570 ;SVEC x=+0 y=-1 sc=0 b=7
5512: 75 f5 .dd2 $f575 ;SVEC x=-1 y=-1 sc=0 b=7
5514: 77 f0 .dd2 $f077 ;SVEC x=-3 y=+0 sc=0 b=7
5516: 03 f8 .dd2 $f803 ;SVEC x=+3 y=+0 sc=1 b=0
5518: 00 d0 .dd2 $d000 ;RTSL
551a: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
551c: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
551e: 06 ff .dd2 $ff06 ;SVEC x=-2 y=-3 sc=1 b=0
5520: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
5522: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0
5524: 00 d0 .dd2 $d000 ;RTSL
5526: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
5528: 72 f0 .dd2 $f072 ;SVEC x=+2 y=+0 sc=0 b=7
552a: 72 f6 .dd2 $f672 ;SVEC x=+2 y=-2 sc=0 b=7
552c: 70 f6 .dd2 $f670 ;SVEC x=+0 y=-2 sc=0 b=7
552e: 76 f6 .dd2 $f676 ;SVEC x=-2 y=-2 sc=0 b=7
5530: 76 f0 .dd2 $f076 ;SVEC x=-2 y=+0 sc=0 b=7
5532: 03 f8 .dd2 $f803 ;SVEC x=+3 y=+0 sc=1 b=0
5534: 00 d0 .dd2 $d000 ;RTSL
5536: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
5538: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
553a: 05 f7 .dd2 $f705 ;SVEC x=-1 y=-3 sc=0 b=0
553c: 77 f0 .dd2 $f077 ;SVEC x=-3 y=+0 sc=0 b=7
553e: 00 f7 .dd2 $f700 ;SVEC x=+0 y=-3 sc=0 b=0
5540: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
5542: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0
5544: 00 d0 .dd2 $d000 ;RTSL
5546: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
5548: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
554a: 05 f7 .dd2 $f705 ;SVEC x=-1 y=-3 sc=0 b=0
554c: 77 f0 .dd2 $f077 ;SVEC x=-3 y=+0 sc=0 b=7
554e: 00 f7 .dd2 $f700 ;SVEC x=+0 y=-3 sc=0 b=0
5550: 03 f8 .dd2 $f803 ;SVEC x=+3 y=+0 sc=1 b=0
5552: 00 d0 .dd2 $d000 ;RTSL
5554: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
5556: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
5558: 70 f6 .dd2 $f670 ;SVEC x=+0 y=-2 sc=0 b=7
555a: 06 f6 .dd2 $f606 ;SVEC x=-2 y=-2 sc=0 b=0
555c: 72 f0 .dd2 $f072 ;SVEC x=+2 y=+0 sc=0 b=7
555e: 70 f6 .dd2 $f670 ;SVEC x=+0 y=-2 sc=0 b=7
5560: 76 f8 .dd2 $f876 ;SVEC x=-2 y=+0 sc=1 b=7
5562: 03 f8 .dd2 $f803 ;SVEC x=+3 y=+0 sc=1 b=0
5564: 00 d0 .dd2 $d000 ;RTSL
5566: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
5568: 00 f7 .dd2 $f700 ;SVEC x=+0 y=-3 sc=0 b=0
556a: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
556c: 00 f3 .dd2 $f300 ;SVEC x=+0 y=+3 sc=0 b=0
556e: 70 ff .dd2 $ff70 ;SVEC x=+0 y=-3 sc=1 b=7
5570: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0
5572: 00 d0 .dd2 $d000 ;RTSL
5574: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7 <<<
5576: 06 f0 .dd2 $f006 ;SVEC x=-2 y=+0 sc=0 b=0
5578: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7
557a: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0
557c: 76 f8 .dd2 $f876 ;SVEC x=-2 y=+0 sc=1 b=7
557e: 03 ff .dd2 $ff03 ;SVEC x=+3 y=-3 sc=1 b=0
5580: 00 d0 .dd2 $d000 ;RTSL
5582: 00 f2 .dd2 $f200 ;SVEC x=+0 y=+2 sc=0 b=0 <<<
5584: 72 f6 .dd2 $f672 ;SVEC x=+2 y=-2 sc=0 b=7
5586: 72 f0 .dd2 $f072 ;SVEC x=+2 y=+0 sc=0 b=7
5588: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7
558a: 01 ff .dd2 $ff01 ;SVEC x=+1 y=-3 sc=1 b=0
558c: 00 d0 .dd2 $d000 ;RTSL
558e: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
5590: 03 f0 .dd2 $f003 ;SVEC x=+3 y=+0 sc=0 b=0
5592: 77 f7 .dd2 $f777 ;SVEC x=-3 y=-3 sc=0 b=7
5594: 73 f7 .dd2 $f773 ;SVEC x=+3 y=-3 sc=0 b=7
5596: 03 f0 .dd2 $f003 ;SVEC x=+3 y=+0 sc=0 b=0
5598: 00 d0 .dd2 $d000 ;RTSL
559a: 00 fb .dd2 $fb00 ;SVEC x=+0 y=+3 sc=1 b=0 <<<
559c: 70 ff .dd2 $ff70 ;SVEC x=+0 y=-3 sc=1 b=7
559e: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
55a0: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0
55a2: 00 d0 .dd2 $d000 ;RTSL
55a4: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
55a6: 72 f6 .dd2 $f672 ;SVEC x=+2 y=-2 sc=0 b=7
55a8: 72 f2 .dd2 $f272 ;SVEC x=+2 y=+2 sc=0 b=7
55aa: 70 ff .dd2 $ff70 ;SVEC x=+0 y=-3 sc=1 b=7
55ac: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0
55ae: 00 d0 .dd2 $d000 ;RTSL
55b0: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
55b2: 72 ff .dd2 $ff72 ;SVEC x=+2 y=-3 sc=1 b=7
55b4: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7
55b6: 01 ff .dd2 $ff01 ;SVEC x=+1 y=-3 sc=1 b=0
55b8: 00 d0 .dd2 $d000 ;RTSL
55ba: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
55bc: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
55be: 70 ff .dd2 $ff70 ;SVEC x=+0 y=-3 sc=1 b=7
55c0: 76 f8 .dd2 $f876 ;SVEC x=-2 y=+0 sc=1 b=7
55c2: 03 f8 .dd2 $f803 ;SVEC x=+3 y=+0 sc=1 b=0
55c4: 00 d0 .dd2 $d000 ;RTSL
55c6: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
55c8: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
55ca: 70 f7 .dd2 $f770 ;SVEC x=+0 y=-3 sc=0 b=7
55cc: 76 f8 .dd2 $f876 ;SVEC x=-2 y=+0 sc=1 b=7
55ce: 03 f7 .dd2 $f703 ;SVEC x=+3 y=-3 sc=0 b=0
55d0: 03 f0 .dd2 $f003 ;SVEC x=+3 y=+0 sc=0 b=0
55d2: 00 d0 .dd2 $d000 ;RTSL
55d4: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
55d6: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
55d8: 70 fe .dd2 $fe70 ;SVEC x=+0 y=-2 sc=1 b=7
55da: 76 f6 .dd2 $f676 ;SVEC x=-2 y=-2 sc=0 b=7
55dc: 76 f0 .dd2 $f076 ;SVEC x=-2 y=+0 sc=0 b=7
55de: 02 f2 .dd2 $f202 ;SVEC x=+2 y=+2 sc=0 b=0
55e0: 72 f6 .dd2 $f672 ;SVEC x=+2 y=-2 sc=0 b=7
55e2: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0
55e4: 00 d0 .dd2 $d000 ;RTSL
55e6: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7 <<<
55e8: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
55ea: 70 f7 .dd2 $f770 ;SVEC x=+0 y=-3 sc=0 b=7
55ec: 76 f8 .dd2 $f876 ;SVEC x=-2 y=+0 sc=1 b=7
55ee: 01 f0 .dd2 $f001 ;SVEC x=+1 y=+0 sc=0 b=0
55f0: 73 f7 .dd2 $f773 ;SVEC x=+3 y=-3 sc=0 b=7
55f2: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0
55f4: 00 d0 .dd2 $d000 ;RTSL
55f6: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7 <<<
55f8: 70 f3 .dd2 $f370 ;SVEC x=+0 y=+3 sc=0 b=7
55fa: 76 f8 .dd2 $f876 ;SVEC x=-2 y=+0 sc=1 b=7
55fc: 70 f3 .dd2 $f370 ;SVEC x=+0 y=+3 sc=0 b=7
55fe: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
5600: 01 ff .dd2 $ff01 ;SVEC x=+1 y=-3 sc=1 b=0
5602: 00 d0 .dd2 $d000 ;RTSL
5604: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0 <<<
5606: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7
5608: 06 f0 .dd2 $f006 ;SVEC x=-2 y=+0 sc=0 b=0
560a: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
560c: 01 ff .dd2 $ff01 ;SVEC x=+1 y=-3 sc=1 b=0
560e: 00 d0 .dd2 $d000 ;RTSL
5610: 00 fb .dd2 $fb00 ;SVEC x=+0 y=+3 sc=1 b=0 <<<
5612: 70 ff .dd2 $ff70 ;SVEC x=+0 y=-3 sc=1 b=7
5614: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
5616: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7
5618: 01 ff .dd2 $ff01 ;SVEC x=+1 y=-3 sc=1 b=0
561a: 00 d0 .dd2 $d000 ;RTSL
561c: 00 fb .dd2 $fb00 ;SVEC x=+0 y=+3 sc=1 b=0 <<<
561e: 71 ff .dd2 $ff71 ;SVEC x=+1 y=-3 sc=1 b=7
5620: 71 fb .dd2 $fb71 ;SVEC x=+1 y=+3 sc=1 b=7
5622: 01 ff .dd2 $ff01 ;SVEC x=+1 y=-3 sc=1 b=0
5624: 00 d0 .dd2 $d000 ;RTSL
5626: 00 fb .dd2 $fb00 ;SVEC x=+0 y=+3 sc=1 b=0 <<<
5628: 70 ff .dd2 $ff70 ;SVEC x=+0 y=-3 sc=1 b=7
562a: 72 f2 .dd2 $f272 ;SVEC x=+2 y=+2 sc=0 b=7
562c: 72 f6 .dd2 $f672 ;SVEC x=+2 y=-2 sc=0 b=7
562e: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7
5630: 01 ff .dd2 $ff01 ;SVEC x=+1 y=-3 sc=1 b=0
5632: 00 d0 .dd2 $d000 ;RTSL
5634: 72 fb .dd2 $fb72 ;SVEC x=+2 y=+3 sc=1 b=7 <<<
5636: 06 f8 .dd2 $f806 ;SVEC x=-2 y=+0 sc=1 b=0
5638: 72 ff .dd2 $ff72 ;SVEC x=+2 y=-3 sc=1 b=7
563a: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0
563c: 00 d0 .dd2 $d000 ;RTSL
563e: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0 <<<
5640: 70 fa .dd2 $fa70 ;SVEC x=+0 y=+2 sc=1 b=7
5642: 76 f2 .dd2 $f276 ;SVEC x=-2 y=+2 sc=0 b=7
5644: 02 f8 .dd2 $f802 ;SVEC x=+2 y=+0 sc=1 b=0
5646: 76 f6 .dd2 $f676 ;SVEC x=-2 y=-2 sc=0 b=7
5648: 02 fe .dd2 $fe02 ;SVEC x=+2 y=-2 sc=1 b=0
564a: 00 d0 .dd2 $d000 ;RTSL
564c: 00 fb .dd2 $fb00 ;SVEC x=+0 y=+3 sc=1 b=0 <<<
564e: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
5650: 76 ff .dd2 $ff76 ;SVEC x=-2 y=-3 sc=1 b=7
5652: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
5654: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0
5656: 00 d0 .dd2 $d000 ;RTSL
5658: 03 f8 .dd2 $f803 ;SVEC x=+3 y=+0 sc=1 b=0 <<<
565a: 00 d0 .dd2 $d000 ;RTSL
565c: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0 <<<
565e: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7
5660: 02 ff .dd2 $ff02 ;SVEC x=+2 y=-3 sc=1 b=0
5662: 00 d0 .dd2 $d000 ;RTSL
5664: 00 fb .dd2 $fb00 ;SVEC x=+0 y=+3 sc=1 b=0 <<<
5666: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
5668: 70 f7 .dd2 $f770 ;SVEC x=+0 y=-3 sc=0 b=7
566a: 76 f8 .dd2 $f876 ;SVEC x=-2 y=+0 sc=1 b=7
566c: 70 f7 .dd2 $f770 ;SVEC x=+0 y=-3 sc=0 b=7
566e: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
5670: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0
5672: 00 d0 .dd2 $d000 ;RTSL
5674: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7 <<<
5676: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7
5678: 76 f8 .dd2 $f876 ;SVEC x=-2 y=+0 sc=1 b=7
567a: 00 f7 .dd2 $f700 ;SVEC x=+0 y=-3 sc=0 b=0
567c: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
567e: 02 f7 .dd2 $f702 ;SVEC x=+2 y=-3 sc=0 b=0
5680: 00 d0 .dd2 $d000 ;RTSL
5682: 00 fb .dd2 $fb00 ;SVEC x=+0 y=+3 sc=1 b=0 <<<
5684: 70 f7 .dd2 $f770 ;SVEC x=+0 y=-3 sc=0 b=7
5686: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
5688: 00 f3 .dd2 $f300 ;SVEC x=+0 y=+3 sc=0 b=0
568a: 70 ff .dd2 $ff70 ;SVEC x=+0 y=-3 sc=1 b=7
568c: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0
568e: 00 d0 .dd2 $d000 ;RTSL
5690: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7 <<<
5692: 70 f3 .dd2 $f370 ;SVEC x=+0 y=+3 sc=0 b=7
5694: 76 f8 .dd2 $f876 ;SVEC x=-2 y=+0 sc=1 b=7
5696: 70 f3 .dd2 $f370 ;SVEC x=+0 y=+3 sc=0 b=7
5698: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
569a: 01 ff .dd2 $ff01 ;SVEC x=+1 y=-3 sc=1 b=0
569c: 00 d0 .dd2 $d000 ;RTSL
569e: 00 f3 .dd2 $f300 ;SVEC x=+0 y=+3 sc=0 b=0 <<<
56a0: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
56a2: 70 f7 .dd2 $f770 ;SVEC x=+0 y=-3 sc=0 b=7
56a4: 76 f8 .dd2 $f876 ;SVEC x=-2 y=+0 sc=1 b=7
56a6: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7
56a8: 03 ff .dd2 $ff03 ;SVEC x=+3 y=-3 sc=1 b=0
56aa: 00 d0 .dd2 $d000 ;RTSL
56ac: 00 fb .dd2 $fb00 ;SVEC x=+0 y=+3 sc=1 b=0 <<<
56ae: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
56b0: 70 ff .dd2 $ff70 ;SVEC x=+0 y=-3 sc=1 b=7
56b2: 02 f0 .dd2 $f002 ;SVEC x=+2 y=+0 sc=0 b=0
56b4: 00 d0 .dd2 $d000 ;RTSL
56b6: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7 <<<
56b8: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7
56ba: 76 f8 .dd2 $f876 ;SVEC x=-2 y=+0 sc=1 b=7
56bc: 70 ff .dd2 $ff70 ;SVEC x=+0 y=-3 sc=1 b=7
56be: 00 f3 .dd2 $f300 ;SVEC x=+0 y=+3 sc=0 b=0
56c0: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
56c2: 02 f7 .dd2 $f702 ;SVEC x=+2 y=-3 sc=0 b=0
56c4: 00 d0 .dd2 $d000 ;RTSL
56c6: 02 f8 .dd2 $f802 ;SVEC x=+2 y=+0 sc=1 b=0 <<<
56c8: 70 fb .dd2 $fb70 ;SVEC x=+0 y=+3 sc=1 b=7
56ca: 76 f8 .dd2 $f876 ;SVEC x=-2 y=+0 sc=1 b=7
56cc: 70 f7 .dd2 $f770 ;SVEC x=+0 y=-3 sc=0 b=7
56ce: 72 f8 .dd2 $f872 ;SVEC x=+2 y=+0 sc=1 b=7
56d0: 02 f7 .dd2 $f702 ;SVEC x=+2 y=-3 sc=0 b=0
56d2: 00 d0 .dd2 $d000 ;RTSL
;
; JSRL commands to access the characters above.
;
56d4: 2c cb CharPtrTbl .dd2 $cb2c ;JSRL a=$0b2c ($5658) ' '
56d6: dd ca .dd2 $cadd ;JSRL a=$0add ($55ba) '0'
56d8: 2e cb .dd2 $cb2e ;JSRL a=$0b2e ($565c)
56da: 32 cb .dd2 $cb32 ;JSRL a=$0b32 ($5664)
56dc: 3a cb .dd2 $cb3a ;JSRL a=$0b3a ($5674)
56de: 41 cb .dd2 $cb41 ;JSRL a=$0b41 ($5682)
56e0: 48 cb .dd2 $cb48 ;JSRL a=$0b48 ($5690)
56e2: 4f cb .dd2 $cb4f ;JSRL a=$0b4f ($569e)
56e4: 56 cb .dd2 $cb56 ;JSRL a=$0b56 ($56ac)
56e6: 5b cb .dd2 $cb5b ;JSRL a=$0b5b ($56b6)
56e8: 63 cb .dd2 $cb63 ;JSRL a=$0b63 ($56c6) '9'
56ea: 78 ca .dd2 $ca78 ;JSRL a=$0a78 ($54f0) 'A'
56ec: 80 ca .dd2 $ca80 ;JSRL a=$0a80 ($5500)
56ee: 8d ca .dd2 $ca8d ;JSRL a=$0a8d ($551a)
56f0: 93 ca .dd2 $ca93 ;JSRL a=$0a93 ($5526)
56f2: 9b ca .dd2 $ca9b ;JSRL a=$0a9b ($5536)
56f4: a3 ca .dd2 $caa3 ;JSRL a=$0aa3 ($5546)
56f6: aa ca .dd2 $caaa ;JSRL a=$0aaa ($5554)
56f8: b3 ca .dd2 $cab3 ;JSRL a=$0ab3 ($5566)
56fa: ba ca .dd2 $caba ;JSRL a=$0aba ($5574)
56fc: c1 ca .dd2 $cac1 ;JSRL a=$0ac1 ($5582)
56fe: c7 ca .dd2 $cac7 ;JSRL a=$0ac7 ($558e)
5700: cd ca .dd2 $cacd ;JSRL a=$0acd ($559a)
5702: d2 ca .dd2 $cad2 ;JSRL a=$0ad2 ($55a4)
5704: d8 ca .dd2 $cad8 ;JSRL a=$0ad8 ($55b0)
5706: dd ca .dd2 $cadd ;JSRL a=$0add ($55ba)
5708: e3 ca .dd2 $cae3 ;JSRL a=$0ae3 ($55c6)
570a: ea ca .dd2 $caea ;JSRL a=$0aea ($55d4)
570c: f3 ca .dd2 $caf3 ;JSRL a=$0af3 ($55e6)
570e: fb ca .dd2 $cafb ;JSRL a=$0afb ($55f6)
5710: 02 cb .dd2 $cb02 ;JSRL a=$0b02 ($5604)
5712: 08 cb .dd2 $cb08 ;JSRL a=$0b08 ($5610)
5714: 0e cb .dd2 $cb0e ;JSRL a=$0b0e ($561c)
5716: 13 cb .dd2 $cb13 ;JSRL a=$0b13 ($5626)
5718: 1a cb .dd2 $cb1a ;JSRL a=$0b1a ($5634)
571a: 1f cb .dd2 $cb1f ;JSRL a=$0b1f ($563e)
571c: 26 cb .dd2 $cb26 ;JSRL a=$0b26 ($564c) 'Z'
;
; English message offsets.
;
571e: 0b EnglishTextTbl .dd1 $0b ;HIGH SCORES
571f: 13 .dd1 $13 ;PLAYER
5720: 19 .dd1 $19 ;YOUR SCORE IS ...
5721: 2f .dd1 $2f ;PLEASE ENTER YOUR ...
5722: 41 .dd1 $41 ;PUSH ROTATE TO ...
5723: 55 .dd1 $55 ;PUSH HYPERSPACE WHEN ...
5724: 6f .dd1 $6f ;PUSH START
5725: 77 .dd1 $77 ;GAME OVER
5726: 7d .dd1 $7d ;1 COIN 2 PLAYS
5727: 87 .dd1 $87 ;1 COIN 1 PLAY
5728: 91 .dd1 $91 ;2 COINS 1 PLAY
;
; Message text. This uses 5 bits per character, storing 3 characters in 2
; bytes. The character index mapping is:
;
; 1 - space
; 2 - '0'
; 3 - '1'
; 4 - '2'
; [5,30] - [A,Z]
;
; For example, the first message begins with "HIG", which is stored:
;
; H I G
; 01100 01101 01011 0 = 01100011 01010110 = $63 $56
;
; The end of the string is identified by index zero, or (if all three characters
; are present) by setting the low bit of the word to 1.
;
5729: 63 56 60 6e+ .bulk $63,$56,$60,$6e,$3c,$ec,$4d,$c0 ;HIGH SCORES
5731: a4 0a ea 6c+ .bulk $a4,$0a,$ea,$6c,$08,$00 ;PLAYER
5737: ec f2 b0 6e+ .bulk $ec,$f2,$b0,$6e,$3c,$ec,$48,$5a,$b8,$66,$92,$42,$9a,$82,$c3,$12 ;YOUR SCORE IS ONE OF THE TEN BEST
+ $0e,$12,$90,$4c,$4d,$f1
574d: a4 12 2d d2+ .bulk $a4,$12,$2d,$d2,$0a,$64,$c2,$6c,$0f,$66,$cd,$82,$6c,$9a,$c3,$4a ;PLEASE ENTER YOUR INITIALS
+ $85,$c0
575f: a6 6e 60 6c+ .bulk $a6,$6e,$60,$6c,$9e,$0a,$c2,$42,$c4,$c2,$ba,$60,$49,$f0,$0c,$12 ;PUSH ROTATE TO SELECT LETTER
+ $c6,$12,$b0,$00
5773: a6 6e 60 58+ .bulk $a6,$6e,$60,$58,$ed,$12,$b5,$e8,$29,$d2,$0e,$d8,$4c,$82,$82,$70 ;PUSH HYPERSPACE WHEN LETTER IS CORRECT
+ $c2,$6c,$0b,$6e,$09,$e6,$b5,$92,$3e,$00
578d: a6 6e 60 6e+ .bulk $a6,$6e,$60,$6e,$c1,$6c,$c0,$00 ;PUSH START
5795: 59 62 48 66+ .bulk $59,$62,$48,$66,$d2,$6d ;GAME OVER
579b: 18 4e 9b 64+ .bulk $18,$4e,$9b,$64,$09,$02,$a4,$0a,$ed,$c0 ;1 COIN 2 PLAYS
57a5: 18 4e 9b 64+ .bulk $18,$4e,$9b,$64,$08,$c2,$a4,$0a,$e8,$00 ;1 COIN 1 PLAY
57af: 20 4e 9b 64+ .bulk $20,$4e,$9b,$64,$b8,$46,$0d,$20,$2f,$40 ;2 COINS 1 PLAY
;
; Sine lookup table, for vertical thrust. Offset by 64 to get cosine for
; horizontal thrust.
;
57b9: 00 03 06 09+ ThrustTbl .bulk $00,$03,$06,$09,$0c,$10,$13,$16,$19,$1c,$1f,$22,$25,$28,$2b,$2e
+ $31,$33,$36,$39,$3c,$3f,$41,$44,$47,$49,$4c,$4e,$51,$53,$55,$58
+ $5a,$5c,$5e,$60,$62,$64,$66,$68,$6a,$6b,$6d,$6f,$70,$71,$73,$74
+ $75,$76,$78,$79,$7a,$7a,$7b,$7c,$7d,$7d,$7e,$7e,$7e,$7f,$7f,$7f
+ $7f
57fa: 00 00 00 00+ .junk 6 ;unused
.adrend ↑ $5000
No exported symbols found.