cpu 6502
memoryTable hard Hardware Info
This is the listing file from the assembler. TODO Make the listing file the same as the other disassembly files so it web-ifies nicely.
TODO include the assembly input file(s) in the nav list. TODO disassemble the output in the usual way. I have the raw ASM file here if needed.
; RAM Usage
.TMP0 = 128
.TMP1 = 129
.TMP2 = 130
.PLAYR0Y = 131
.PLAYR1Y = 132
.MUS_TMP0 = 133
.MUS_TMP1 = 134
.SCANCNT = 135
.MODE = 136
.WALL_INC = 137
.WALLCNT = 138
.WALLDELY = 139
.WALLDELYR = 140
.ENTROPYA = 141
.ENTROPYB = 142
.ENTROPYC = 143
.DEBOUNCE = 144
.WALLDRELA = 145
.WALLDRELB = 146
.WALLDRELC = 147
.WALLSTART = 148
.WALLHEI = 149
.GAPBITS = 150
.SCORE_PF1 = 151
.SCORE_PF2 = 157
.MUSADEL = 163
.MUSAIND = 164
.MUSAVOL = 165
.MUSBDEL = 166
.MUSBIND = 167
.MUSBVOL = 168
F000:
main:
F000: 78 SEI ; Turn off interrupts
F001: D8 CLD ; Clear the "decimal" flag
F002: A2 FF LDX #0xFF ; Set stack ...
F004: 9A TXS ; ... to the end of RAM
F005: 20 07 F1 JSR INIT ; Initialize game environment
F008: 20 DB F1 JSR INIT_SELMODE ; Start out in SELECT-MODE
VIDEO_KERNEL:
F00B: A9 02 LDA #2 ; D1 bit ON
F00D: 85 02 STA WSYNC ; Wait for the end of the current line
F00F: 85 01 STA VBLANK ; Turn the electron beam off
F011: 85 02 STA WSYNC ; Wait for all ...
F013: 85 02 STA WSYNC ; ... the electrons ...
F015: 85 02 STA WSYNC ; ... to drain out.
F017: 85 00 STA VSYNC ; Trigger the vertical sync signal
F019: 85 02 STA WSYNC ; Hold the vsync signal for ...
F01B: 85 02 STA WSYNC ; ... three ...
F01D: 85 02 STA WSYNC ; ... scanlines
F01F: 85 2A STA HMOVE ; Tell hardware to move all game objects
F021: A9 00 LDA #0 ; D1 bit OFF
F023: 85 00 STA VSYNC ; Release the vertical sync signal
F025: A9 2B LDA #43 ; Set timer to 43*64 = 2752 machine ...
F027: 8D 96 02 STA TIM64T ; ... cycles 2752/(228/3) = 36 scanlines
; ***** LENGTHY GAME LOGIC PROCESSING BEGINS HERE *****
; Do one of 3 routines while the beam travels back to the top
; 0 = Game Over processing
; 1 = Playing-Game processing
; 2 = Selecting-Game processing
F02A: E6 8D INC ENTROPYA ; Counting video frames as part of the random number
F02C: A5 88 LDA MODE ; What are we doing between frames?
F02E: C9 00 CMP #0 ; Mode is ...
F030: F0 10 BEQ DoGameOverMode ; ... "game over"
F032: C9 01 CMP #1 ; Mode is ...
F034: F0 06 BEQ DoPlayMode ; ... "game play"
F036: 20 EA F1 JSR SELMODE ; Mode is "select game"
F039: 4C 45 F0 JMP DrawFrame ; Continue to the visible screen area
DoPlayMode:
F03C: 20 64 F1 JSR PLAYMODE ; Playing-game processing
F03F: 4C 45 F0 JMP DrawFrame ; Continue to the visible screen area
DoGameOverMode:
F042: 20 43 F2 JSR GOMODE ; Game-over processing
; ***** LENGTHY GAME LOGIC PROCESSING ENDS HERE *****
DrawFrame:
F045: AD 84 02 LDA INTIM ; Wait for ...
F048: C9 00 CMP #0 ; ... the visible area ...
F04A: D0 F9 BNE DrawFrame ; ... of the screen
F04C: 85 02 STA WSYNC ; 37th scanline
F04E: A9 00 LDA #0 ; Turn the ...
F050: 85 01 STA VBLANK ; ... electron beam back on
F052: A9 00 LDA #0 ; Zero out ...
F054: 85 87 STA SCANCNT ; ... scanline count ...
F056: 85 80 STA TMP0 ; ... and all ...
F058: 85 81 STA TMP1 ; ... returns ...
F05A: 85 82 STA TMP2 ; ... expected ...
F05C: AA TAX ; ... to come from ...
F05D: A8 TAY ; ... BUILDROW
F05E: 85 2C STA CXCLR ; Clear collision detection
DrawVisibleRows:
F060: A5 80 LDA TMP0 ; Get A ready (PF0 value)
F062: 85 02 STA WSYNC ; Wait for very start of row
F064: 86 1B STX GRP0 ; Player 0 -- in X
F066: 84 1C STY GRP1 ; Player 1 -- in Y
F068: 85 0D STA PF0 ; PF0 -- in TMP0 (already in A)
F06A: A5 81 LDA TMP1 ; PF1 -- in TMP1
F06C: 85 0E STA PF1 ; ...
F06E: A5 82 LDA TMP2 ; PP2 -- in TMP2
F070: 85 0F STA PF2 ; ...
F072: 20 90 F0 JSR BUILDROW ; This MUST take through to the next line
F075: E6 87 INC SCANCNT ; Next scan line
F077: A5 87 LDA SCANCNT ; Do 109*2 = 218 lines
F079: C9 6D CMP #109 ; All done?
F07B: D0 E3 BNE DrawVisibleRows ; No ... get all the visible rows
; END VISIBLE PART OF FRAME
F07D: A9 00 LDA #0 ; Turn off electron beam
F07F: 85 02 STA WSYNC ; Next scanline
F081: 85 0D STA PF0 ; Play field 0 off
F083: 85 1B STA GRP0 ; Player 0 off
F085: 85 1C STA GRP1 ; Player 1 off
F087: 85 0E STA PF1 ; Play field 1 off
F089: 85 0F STA PF2 ; Play field 2 off
F08B: 85 02 STA WSYNC ; Next scanline
F08D: 4C 0B F0 JMP VIDEO_KERNEL
BUILDROW:
F090: A5 87 LDA SCANCNT ; Where are we on the screen?
F092: C9 06 CMP #6 ; If we are in the ...
F094: 90 40 BCC ShowScore ; ... score area
F096: 29 07 AND #7 ; Lower 3 bits as an index again
F098: A8 TAY ; Using Y to lookup graphics
F099: B9 3C F5 LDA GR_PLAYER,Y ; Get the graphics (if enabled on this row)
F09C: AA TAX ; Hold it (for return as player 0)
F09D: A8 TAY ; Hold it (for return as player 1)
F09E: A5 87 LDA SCANCNT ; Scanline count again
F0A0: 4A LSR A ; This time ...
F0A1: 4A LSR A ; ... we divide ...
F0A2: 4A LSR A ; ... by eight (8 rows in picture)
F0A3: C5 83 CMP PLAYR0Y ; Scanline group of the P0 object?
F0A5: F0 02 BEQ ShowP0 ; Yes ... keep the picture
F0A7: A2 00 LDX #0 ; Not time for Player 0 ... no graphics
ShowP0:
F0A9: C5 84 CMP PLAYR1Y ; Scanline group of the P1 object?
F0AB: F0 02 BEQ ShowP1 ; Yes ... keep the picture
F0AD: A0 00 LDY #0 ; Not time for Player 0 ... no graphics
ShowP1:
F0AF: A5 94 LDA WALLSTART ; Calculate ...
F0B1: 18 CLC ; ... the bottom ...
F0B2: 65 95 ADC WALLHEI ; ... of ...
F0B4: 85 80 STA TMP0 ; ... the wall
F0B6: A5 87 LDA SCANCNT ; Scanline count
F0B8: C5 94 CMP WALLSTART ; Past upper part of wall?
F0BA: 90 11 BCC NoWall ; No ... skip it
F0BC: C5 80 CMP TMP0 ; Past lower part of wall
F0BE: B0 0D BCS NoWall ; Yes ... skip it
; The wall is on this row
F0C0: A5 91 LDA WALLDRELA ; Draw wall ...
F0C2: 85 80 STA TMP0 ; ... by transfering ...
F0C4: A5 92 LDA WALLDRELB ; ... playfield ...
F0C6: 85 81 STA TMP1 ; ... patterns ...
F0C8: A5 93 LDA WALLDRELC ; ... to ...
F0CA: 85 82 STA TMP2 ; ... return area
F0CC: 60 RTS ; Done
NoWall:
; The wall is NOT on this row
F0CD: A9 00 LDA #0 ; No walls on this row
F0CF: 85 80 STA TMP0 ; ... clear ...
F0D1: 85 81 STA TMP1 ; ... out ...
F0D3: 85 82 STA TMP2 ; ... the playfield
F0D5: 60 RTS ; Done
ShowScore:
F0D6: 29 07 AND #7 ; OLine=182 Only need the lower 3 bits
F0D8: A8 TAY ; OLine=183 Soon to be an index into a list
; At this point, the beam is past the loading of the
; playfield for the left half. We want to make sure
; that the right half of the playfield is off, so do that
; now.
F0D9: A2 00 LDX #0 ; Blank bit pattern
F0DB: 86 80 STX TMP0 ; This will always be blank
F0DD: 86 0E STX PF1 ; Turn off playfield ...
F0DF: 86 0F STX PF2 ; ... for right half of the screen
F0E1: AA TAX ; Another index
F0E2: B9 97 00 LDA SCORE_PF1,Y ; Lookup the PF1 graphics for this row
F0E5: 85 81 STA TMP1 ; Return it to the caller
F0E7: A8 TAY ; We'll need this value again in a second
F0E8: B5 9D LDA SCORE_PF2,X ; Lookup the PF2 graphics for this row
F0EA: 85 82 STA TMP2 ; Return it to the caller
F0EC: 85 02 STA WSYNC ; Now on the next row
F0EE: 84 0E STY PF1 ; Repeat the left-side playfield ...
F0F0: 85 0F STA PF2 ; ... onto the new row
F0F2: B5 9D LDA SCORE_PF2,X ; Kill some time waiting for the ...
F0F4: B5 9D LDA SCORE_PF2,X ; ... beam to pass the left half ...
F0F6: B5 9D LDA SCORE_PF2,X ; ... of the playfield again
F0F8: B5 9D LDA SCORE_PF2,X ; ...
F0FA: B5 9D LDA SCORE_PF2,X ; ...
F0FC: B5 9D LDA SCORE_PF2,X ; ...
F0FE: A2 00 LDX #0 ; Return 0 (off) for player 0 ...
F100: A0 00 LDY #0 ; ... and player 1
; The beam is past the left half of the field again.
; Turn off the playfield.
F102: 86 0E STX PF1 ; 0 to PF1 ...
F104: 86 0F STX PF2 ; ... and PF2
F106: 60 RTS ; Done
INIT:
; This function is called ONCE at power-up/reset to initialize various
; game settings and variables.
F107: A9 40 LDA #64 ; Wall is ...
F109: 85 08 STA COLUPF ; ... redish
F10B: A9 7E LDA #126 ; P0 is ...
F10D: 85 06 STA COLUP0 ; ... white
F10F: A9 00 LDA #0 ; P1 ...
F111: 85 07 STA COLUP1 ; ... black
F113: A9 05 LDA #5 ; Right half of playfield is reflection of left ...
F115: 85 0A STA CTRLPF ; ... and playfield is on top of players
; TODO other hardware inits here
F117: A2 04 LDX #4 ; Player 0 position count
F119: A0 03 LDY #3 ; Player 1 position count
F11B: 85 02 STA WSYNC ; Get a fresh scanline
TimeP0Pos:
F11D: CA DEX ; Kill time while the beam moves ...
F11E: E0 00 CPX #0 ; ... to desired ...
F120: D0 FB BNE TimeP0Pos ; ... position
F122: 85 10 STA RESP0 ; Mark player 0's X position
TimeP1Pos:
F124: 88 DEY ; Kill time while the beam moves ...
F125: C0 00 CPY #0 ; ... to desired ...
F127: D0 FB BNE TimeP1Pos ; ... position
F129: 85 11 STA RESP1 ; Mark player 1's X position
F12B: 20 1D F3 JSR EXPERTISE ; Initialize the players' Y positions base on expert-settings
F12E: A9 0A LDA #10 ; Wall is ...
F130: 85 95 STA WALLHEI ; ... 10 double-scanlines high
F132: A9 00 LDA #0 ; Set score to ...
F134: 85 8A STA WALLCNT ; ... 0
F136: 20 9D F2 JSR MAKE_SCORE ; Blank the score digits
F139: A9 00 LDA #0 ; Blank bits ...
F13B: 85 A2 STA SCORE_PF2+5 ; ... on the end of each ...
F13D: 85 9C STA SCORE_PF1+5 ; ... digit pattern
F13F: 20 48 F3 JSR ADJUST_DIF ; Initialize the wall parameters
F142: 20 6F F2 JSR NEW_GAPS ; Build the wall's initial gap
F145: A9 70 LDA #112 ; Set wall position off bottom ...
F147: 85 94 STA WALLSTART ; ... to force a restart on first move
F149: A9 00 LDA #0 ; Zero out ...
F14B: 85 20 STA HMP0 ; ... player 0 motion ...
F14D: 85 21 STA HMP1 ; ... and player 1 motion
F14F: 60 RTS ; Done
INIT_PLAYMODE:
; This function initializes the game play mode
F150: A9 C0 LDA #192 ; Background is ...
F152: 85 09 STA COLUBK ; ... greenish
F154: A9 01 LDA #1 ; Game mode is ...
F156: 85 88 STA MODE ; ... SELECT
F158: A9 FF LDA #255 ; Restart wall score to ...
F15A: 85 8A STA WALLCNT ; ... 0 on first move
F15C: A9 70 LDA #112 ; Force wall to start ...
F15E: 85 94 STA WALLSTART ; ... over on first move
F160: 20 9B F3 JSR INIT_MUSIC ; Initialize the music
F163: 60 RTS ; Done
PLAYMODE:
; This function is called once per frame to process the main game play.
F164: 20 86 F3 JSR SEL_RESET_CHK ; Check to see if Reset/Select has changed
F167: C9 00 CMP #0 ; Is select pressed?
F169: F0 06 BEQ NoSelect ; No ... skip
F16B: 86 90 STX DEBOUNCE ; Restore the old value ...
F16D: 20 DB F1 JSR INIT_SELMODE ; ... and let select-mode process the toggle
F170: 60 RTS ; Done
NoSelect:
F171: 20 B8 F3 JSR PROCESS_MUSIC ; Process any playing music
F174: 20 4E F2 JSR MOVE_WALLS ; Move the walls
F177: C9 01 CMP #1 ; Wall on first row?
F179: D0 0D BNE NoFirst ; No ... move on
F17B: E6 8A INC WALLCNT ; Bump the score
F17D: 20 48 F3 JSR ADJUST_DIF ; Change the wall parameters based on score
F180: A5 8A LDA WALLCNT ; Change the ...
F182: 20 9D F2 JSR MAKE_SCORE ; ... score pattern
F185: 20 6F F2 JSR NEW_GAPS ; Calculate the new gap position
NoFirst:
F188: A5 02 LDA CXP0FB ; Player 0 collision with playfield
F18A: 85 80 STA TMP0 ; Hold it
F18C: A5 03 LDA CXP1FB ; Player 1 collision with playfield
F18E: 05 80 ORA TMP0 ; Did either ...
F190: 29 80 AND #128 ; ... player hit ...
F192: C9 00 CMP #0 ; ... wall?
F194: F0 04 BEQ NoHit ; No ... move on
F196: 20 17 F2 JSR INIT_GOMODE ; Go to Game-Over mode
F199: 60 RTS ; Done
NoHit:
F19A: AD 80 02 LDA SWCHA ; Joystick
F19D: 29 80 AND #128 ; Player 0 ...
F19F: C9 00 CMP #0 ; ... moving left?
F1A1: F0 13 BEQ MoveP0Left ; Yes ... move left
F1A3: AD 80 02 LDA SWCHA ; Joystick
F1A6: 29 40 AND #64 ; Player 0 ...
F1A8: C9 00 CMP #0 ; ... moving right?
F1AA: F0 05 BEQ MoveP0Right ; Yes ... move right
F1AC: A9 00 LDA #0 ; Not moving value
F1AE: 4C B8 F1 JMP SetMoveP0 ; Don't move the player
MoveP0Right:
F1B1: A9 10 LDA #16 ; +1
F1B3: 4C B8 F1 JMP SetMoveP0 ; Set HMP0
MoveP0Left:
F1B6: A9 F0 LDA #240 ; -1
SetMoveP0:
F1B8: 85 20 STA HMP0 ; New movement value P0
F1BA: AD 80 02 LDA SWCHA ; Joystick
F1BD: 29 08 AND #8 ; Player 1 ...
F1BF: C9 00 CMP #0 ; ... moving left?
F1C1: F0 13 BEQ MoveP1Left ; Yes ... move left
F1C3: AD 80 02 LDA SWCHA ; Joystick
F1C6: 29 04 AND #4 ; Player 0 ...
F1C8: C9 00 CMP #0 ; ... moving right?
F1CA: F0 05 BEQ MoveP1Right ; Yes ... move right
F1CC: A9 00 LDA #0 ; Not moving value
F1CE: 4C D8 F1 JMP SetMoveP1 ; Don't move the player
MoveP1Right:
F1D1: A9 10 LDA #16 ; +1
F1D3: 4C D8 F1 JMP SetMoveP1 ; Set HMP0
MoveP1Left:
F1D6: A9 F0 LDA #240 ; -1
SetMoveP1:
F1D8: 85 21 STA HMP1 ; New movement value P1
F1DA: 60 RTS ; Done
INIT_SELMODE:
; This function initializes the games SELECT-MODE
F1DB: A9 00 LDA #0 ; Turn off ...
F1DD: 85 19 STA AUDV0 ; ... all ...
F1DF: 85 1A STA AUDV1 ; ... sound
F1E1: A9 C8 LDA #200 ; Background ...
F1E3: 85 09 STA COLUBK ; ... greenish bright
F1E5: A9 02 LDA #2 ; Now in ...
F1E7: 85 88 STA MODE ; SELECT game mode
F1E9: 60 RTS ; Done
SELMODE:
; This function is called once per frame to process the SELECT-MODE.
; The wall moves here, but doesn't change or collide with players.
; This function selects between 1 and 2 player game.
F1EA: 20 4E F2 JSR MOVE_WALLS ; Move the walls
F1ED: 20 86 F3 JSR SEL_RESET_CHK ; Check the reset/select switches
F1F0: C9 01 CMP #1 ; RESET button?
F1F2: F0 1C BEQ SelStartGame ; Yes ... start game
F1F4: C9 03 CMP #3 ; RESET and SELECT?
F1F6: F0 18 BEQ SelStartGame ; Yes ... start game
F1F8: C9 02 CMP #2 ; Select only?
F1FA: D0 17 BNE SelExp ; No ... stay in this mode
F1FC: A5 84 LDA PLAYR1Y ; Select toggled. Get player 1 Y coordinate
F1FE: C9 FF CMP #255 ; 2nd player on the screen?
F200: F0 07 BEQ SelP1On ; No ... toggle it on
F202: A9 FF LDA #255 ; Yes ...
F204: 85 84 STA PLAYR1Y ; ... toggle it off
F206: 4C 13 F2 JMP SelExp ; Move to expertise
SelP1On:
F209: A9 0C LDA #12 ; Y coordinate
F20B: 85 84 STA PLAYR1Y ; On screen now
F20D: 4C 13 F2 JMP SelExp ; Move to expertise
SelStartGame:
F210: 20 50 F1 JSR INIT_PLAYMODE ; Reset toggled ... start game
SelExp:
F213: 20 1D F3 JSR EXPERTISE ; Adjust both players for pro settings
F216: 60 RTS ; Done
INIT_GOMODE:
; This function initializes the GAME-OVER game mode.
F217: 85 2B STA HMCLR ; Stop both players from moving
F219: A5 02 LDA CXP0FB ; P0 collision ...
F21B: 29 80 AND #128 ; ... with wall
F21D: C9 00 CMP #0 ; Did P0 hit the wall?
F21F: D0 04 BNE GoCheckP1 ; Yes ... leave it at bottom
F221: A9 02 LDA #2 ; No ... move player 0 ...
F223: 85 83 STA PLAYR0Y ; ... up the screen to show win
GoCheckP1:
F225: A5 03 LDA CXP1FB ; P1 collision ...
F227: 29 80 AND #128 ; ... with wall
F229: C9 00 CMP #0 ; Did P1 hit the wall?
F22B: D0 0A BNE GoP1Hit ; Yes ... leave it at the bottom
F22D: A5 84 LDA PLAYR1Y ; Is P1 even ...
F22F: C9 FF CMP #255 ; ... on the screen (2 player game?)
F231: F0 04 BEQ GoP1Hit ; No ... skip it
F233: A9 02 LDA #2 ; Player 1 is onscreen and didn't collide ...
F235: 85 84 STA PLAYR1Y ; ... move up the screen to show win
GoP1Hit:
F237: A9 00 LDA #0 ; Going to ...
F239: 85 88 STA MODE ; ... game-over mode
F23B: 85 19 STA AUDV0 ; Turn off any ...
F23D: 85 1A STA AUDV1 ; ... sound
F23F: 20 71 F4 JSR INIT_GO_FX ; Initialize sound effects
F242: 60 RTS ; Done
GOMODE:
; This function is called every frame to process the game
; over sequence. When the sound effect has finished, the
; game switches to select mode.
F243: 20 88 F4 JSR PROCESS_GO_FX ; Process the sound effects
F246: C9 00 CMP #0 ; Effects still running?
F248: F0 03 BEQ GoKeepGoing ; Yes ... let them run
F24A: 20 DB F1 JSR INIT_SELMODE ; When effect is over, go to select mode
GoKeepGoing:
F24D: 60 RTS ; Done
MOVE_WALLS:
; This function moves the wall down the screen and back to position 0
; when it reaches (or passes) 112.
F24E: C6 8B DEC WALLDELY ; Wall motion timer
F250: A5 8B LDA WALLDELY ; Time to ...
F252: C9 00 CMP #0 ; ... move the wall?
F254: D0 16 BNE WallDone ; No ... leave it alone
F256: A5 8C LDA WALLDELYR ; Reset the ...
F258: 85 8B STA WALLDELY ; ... delay count
F25A: A5 94 LDA WALLSTART ; Current wall position
F25C: 18 CLC ; Increment ...
F25D: 65 89 ADC WALL_INC ; ... wall position
F25F: C9 70 CMP #112 ; At the bottom?
F261: 90 07 BCC WallOK ; No ... leave it alone
F263: A9 00 LDA #0 ; Else restart ...
F265: 85 94 STA WALLSTART ; ... wall at top of screen
F267: A9 01 LDA #1 ; Return flag that wall DID restart
F269: 60 RTS ; Done
WallOK:
F26A: 85 94 STA WALLSTART ; Store new wall position
WallDone:
F26C: A9 00 LDA #0 ; Return flag that wall did NOT restart
F26E: 60 RTS ; Done
NEW_GAPS:
; This function builds the PF0, PF1, and PF2 graphics for a wall
; with the gap pattern (GAPBITS) placed at random in the 20 bit
; area.
F26F: A9 FF LDA #255 ; Start with ...
F271: 85 91 STA WALLDRELA ; ... solid wall in PF0 ...
F273: 85 92 STA WALLDRELB ; ... and PF1
F275: A5 96 LDA GAPBITS ; Store the gap pattern ...
F277: 85 93 STA WALLDRELC ; ... in PF2
F279: A5 8D LDA ENTROPYA ; Get ...
F27B: 65 8E ADC ENTROPYB ; ... a randomish ...
F27D: 65 8F ADC ENTROPYC ; ... number ...
F27F: 85 8F STA ENTROPYC ; Update the random seed
F281: 29 0F AND #15 ; 0 to 15
F283: C9 0C CMP #12 ; Too far to the right?
F285: F0 04 BEQ GapOK ; No ... 12 is OK
F287: 90 02 BCC GapOK ; No ... less than 12 is OK
F289: E9 09 SBC #9 ; Back up 9
GapOK:
F28B: C9 00 CMP #0 ; Gap already at far left?
F28D: F0 0D BEQ GapDone ; Yes ... done
F28F: 38 SEC ; Roll gap ...
F290: 66 93 ROR WALLDRELC ; ... left ...
F292: 26 92 ROL WALLDRELB ; ... desired ...
F294: 66 91 ROR WALLDRELA ; ... times ...
F296: 38 SEC ; All rolls ...
F297: E9 01 SBC #1 ; ... done?
F299: 4C 8B F2 JMP GapOK ; No ... do them all
GapDone:
F29C: 60 RTS ; New wall pattern is ready
MAKE_SCORE:
; This function builds the PF1 and PF2 graphics rows for
; the byte value passed in A. The current implementation is
; two-digits only ... PF2 is blank.
F29D: A2 00 LDX #0 ; 100's digit
F29F: A0 00 LDY #0 ; 10's digit
Count100s:
F2A1: C9 64 CMP #100 ; Need another 100s digit?
F2A3: 90 07 BCC Count10s ; No ... move on to 10s
F2A5: E8 INX ; Count ...
F2A6: 38 SEC ; ... value
F2A7: E9 64 SBC #100 ; Take off this 100
F2A9: 4C A1 F2 JMP Count100s ; Keep counting
Count10s:
F2AC: C9 0A CMP #10 ; Need another 10s digit?
F2AE: 90 07 BCC CountDone ; No ... got all the tens
F2B0: C8 INY ; Count ...
F2B1: 38 SEC ; ... value
F2B2: E9 0A SBC #10 ; Take off this 10
F2B4: 4C AC F2 JMP Count10s ; Keep counting
CountDone:
F2B7: 0A ASL A ; One's digit ...
F2B8: 0A ASL A ; ... *8 ....
F2B9: 0A ASL A ; ... to find picture
F2BA: AA TAX ; One's digit picture to X
F2BB: 98 TYA ; Now the 10's digit
F2BC: 0A ASL A ; Multiply ...
F2BD: 0A ASL A ; ... by 8 ...
F2BE: 0A ASL A ; ... to find picture
F2BF: A8 TAY ; 10's picture in Y
F2C0: B9 44 F5 LDA DIGITS,Y ; Get the 10's digit
F2C3: 29 F0 AND #0xF0 ; Upper nibble
F2C5: 85 97 STA SCORE_PF1 ; Store left side
F2C7: BD 44 F5 LDA DIGITS,X ; Get the 1's digit
F2CA: 29 0F AND #0x0F ; Lower nibble
F2CC: 05 97 ORA SCORE_PF1 ; Put left and right half together
F2CE: 85 97 STA SCORE_PF1 ; And store image
; We have plenty of code space. Time and registers are at a premium.
; So copy/past the code for each row
F2D0: B9 45 F5 LDA DIGITS+1,Y ; Repeat for 2nd line of picture ...
F2D3: 29 F0 AND #0xF0 ; ...
F2D5: 85 98 STA SCORE_PF1+1 ; ...
F2D7: BD 45 F5 LDA DIGITS+1,X ; ...
F2DA: 29 0F AND #15 ; ...
F2DC: 05 98 ORA SCORE_PF1+1 ; ...
F2DE: 85 98 STA SCORE_PF1+1 ; ...
F2E0: B9 46 F5 LDA DIGITS+2,Y ; Repeat for 3nd line of picture
F2E3: 29 F0 AND #0xF0 ; ...
F2E5: 85 99 STA SCORE_PF1+2 ; ...
F2E7: BD 46 F5 LDA DIGITS+2,X ; ...
F2EA: 29 0F AND #0x0F ; ...
F2EC: 05 99 ORA SCORE_PF1+2 ; ...
F2EE: 85 99 STA SCORE_PF1+2 ; ...
F2F0: B9 47 F5 LDA DIGITS+3,Y ; Repeat for 4th line of picture
F2F3: 29 F0 AND #0xF0 ; ...
F2F5: 85 9A STA SCORE_PF1+3 ; ...
F2F7: BD 47 F5 LDA DIGITS+3,X ; ...
F2FA: 29 0F AND #0x0F ; ...
F2FC: 05 9A ORA SCORE_PF1+3 ; ...
F2FE: 85 9A STA SCORE_PF1+3 ; ...
F300: B9 48 F5 LDA DIGITS+4,Y ; Repeat for 5th line of picture
F303: 29 F0 AND #0xF0 ; ...
F305: 85 9B STA SCORE_PF1+4 ; ...
F307: BD 48 F5 LDA DIGITS+4,X ; ...
F30A: 29 0F AND #0x0F ; ...
F30C: 05 9B ORA SCORE_PF1+4 ; ...
F30E: 85 9B STA SCORE_PF1+4 ; ...
F310: A9 00 LDA #0 ; For now ...
F312: 85 9D STA SCORE_PF2 ; ... there ...
F314: 85 9E STA SCORE_PF2+1 ; ... is ...
F316: 85 9F STA SCORE_PF2+2 ; ... no ...
F318: 85 A0 STA SCORE_PF2+3 ; ... 100s ...
F31A: 85 A1 STA SCORE_PF2+4 ; ... digit drawn
F31C: 60 RTS ; Done
EXPERTISE:
; This function changes the Y position of the players based on the
; position of their respective pro/novice switches. The player 1
; position is NOT changed if the mode is a single-player game.
F31D: AD 82 02 LDA SWCHB ; Check P0 ...
F320: 29 40 AND #0x40 ; ... pro/novice settings
F322: C9 00 CMP #0 ; Amateur?
F324: F0 05 BEQ ExpP0Ama ; Yes ... near the bottom of screen
F326: A9 08 LDA #8 ; Pro ... near the top
F328: 4C 2D F3 JMP ExpP1 ; Store and check P0
ExpP0Ama:
F32B: A9 0C LDA #12 ; near the bottom
ExpP1:
F32D: 85 83 STA PLAYR0Y ; Player 0 Y coordinate
F32F: A6 84 LDX PLAYR1Y ; Is P1 on ...
F331: E0 FF CPX #255 ; ... the screen?
F333: F0 12 BEQ ExpNoP1 ; No ... skip all this
F335: AD 82 02 LDA SWCHB ; Check P1 ...
F338: 29 80 AND #0x80 ; ... pro/novice settings
F33A: C9 00 CMP #0 ; Amateur?
F33C: F0 05 BEQ ExpP1Ama ; Yes ... near the bottom of the screen
F33E: A2 08 LDX #8 ; Pro ... near the top
F340: 4C 45 F3 JMP ExpDone ; Store and out
ExpP1Ama:
F343: A2 0C LDX #12 ; Novice ... near the bottom
ExpDone:
F345: 86 84 STX PLAYR1Y ; Player 1 Y coordinate
ExpNoP1:
F347: 60 RTS ; Done
ADJUST_DIF:
; This function adjusts the wall game difficulty values based on the
; current score. The music can also change with the difficulty. A single
; table describes the new values and when they take effect.
F348: A2 00 LDX #0 ; Starting at index 0
AdjNextRow:
F34A: BD F9 F4 LDA SKILL_VALUES,X ; Get the score match
F34D: C9 FF CMP #255 ; At the end of the table?
F34F: D0 01 BNE AdjCheckTable ; No ... check this row
F351: 60 RTS ; End of the table ... leave it alone
AdjCheckTable:
F352: C5 8A CMP WALLCNT ; Is this our row?
F354: D0 27 BNE AdjBump ; No ... bump to next
F356: E8 INX ; Copy ...
F357: BD F9 F4 LDA SKILL_VALUES,X ; ... new ...
F35A: 85 89 STA WALL_INC ; ... wall increment
F35C: E8 INX ; Copy ...
F35D: BD F9 F4 LDA SKILL_VALUES,X ; ... new ...
F360: 85 8B STA WALLDELY ; ... wall ...
F362: 85 8C STA WALLDELYR ; ... delay
F364: E8 INX ; Copy ...
F365: BD F9 F4 LDA SKILL_VALUES,X ; ... new ...
F368: 85 96 STA GAPBITS ; ... gap pattern
F36A: E8 INX ; Copy ...
F36B: BD F9 F4 LDA SKILL_VALUES,X ; ... new ...
F36E: 85 A4 STA MUSAIND ; ... MusicA index
F370: E8 INX ; Copy ...
F371: BD F9 F4 LDA SKILL_VALUES,X ; ... new ...
F374: 85 A7 STA MUSBIND ; ... MusicB index
F376: A9 01 LDA #1 ; Force ...
F378: 85 A3 STA MUSADEL ; ... music to ...
F37A: 85 A6 STA MUSBDEL ; ... start new
F37C: 60 RTS ; Done
AdjBump:
F37D: E8 INX ; Move ...
F37E: E8 INX ; ... X ...
F37F: E8 INX ; ... to ...
F380: E8 INX ; ... next ...
F381: E8 INX ; ... row of ...
F382: E8 INX ; ... table
F383: 4C 4A F3 JMP AdjNextRow ; Try next row
SEL_RESET_CHK:
; This function checks for changes to the reset/select
; switches and debounces the transitions.
; xxxxxxSR (Select, Reset)
F386: A6 90 LDX DEBOUNCE ; Get the last value
F388: AD 82 02 LDA SWCHB ; New value
F38B: 29 03 AND #3 ; Only need bottom 2 bits
F38D: C5 90 CMP DEBOUNCE ; Same as before?
F38F: F0 07 BEQ SelDebounce ; Yes ... return nothing changed
F391: 85 90 STA DEBOUNCE ; Hold new last value
F393: 49 FF EOR #255 ; Active low to active high
F395: 29 03 AND #3 ; Only need select/reset
F397: 60 RTS ; Return changes
SelDebounce:
F398: A9 00 LDA #0 ; Return 0 ...
F39A: 60 RTS ; ... nothing changed
INIT_MUSIC:
; This function initializes the hardware and temporaries
; for 2-channel music
F39B: A9 06 LDA #6 ; Audio control ...
F39D: 85 15 STA AUDC0 ; ... to pure ...
F39F: 85 16 STA AUDC1 ; ... tones
F3A1: A9 00 LDA #0 ; Turn off ...
F3A3: 85 19 STA AUDV0 ; ... all ...
F3A5: 85 1A STA AUDV1 ; ... sound
F3A7: 85 A4 STA MUSAIND ; Music pointers ...
F3A9: 85 A7 STA MUSBIND ; ... to top of data
F3AB: A9 01 LDA #1 ; Force ...
F3AD: 85 A3 STA MUSADEL ; ... music ...
F3AF: 85 A6 STA MUSBDEL ; ... reload
F3B1: A9 0F LDA #15 ; Set volume levels ...
F3B3: 85 A5 STA MUSAVOL ; ... to ...
F3B5: 85 A8 STA MUSBVOL ; ... maximum
F3B7: 60 RTS ; Done
PROCESS_MUSIC:
; This function is called once per frame to process the
; 2 channel music. Two tables contain the commands/notes
; for individual channels. This function changes the
; notes at the right time.
F3B8: C6 A3 DEC MUSADEL ; Current note on Channel A ended?
F3BA: D0 58 BNE MusDoB ; No ... let it play
MusChanA:
F3BC: A6 A4 LDX MUSAIND ; Voice-A index
F3BE: BD A0 F4 LDA MUSICA,X ; Get the next music command
F3C1: C9 00 CMP #0 ; Jump?
F3C3: F0 22 BEQ MusCmdJumpA ; Yes ... handle it
F3C5: C9 01 CMP #1 ; Control?
F3C7: F0 11 BEQ MusCmdCtrlA ; Yes ... handle it
F3C9: C9 02 CMP #2 ; Volume?
F3CB: D0 28 BNE MusCmdToneA ; No ... must be a note
F3CD: E8 INX ; Point to volume value
F3CE: E6 A4 INC MUSAIND ; Bump the music pointer
F3D0: BD A0 F4 LDA MUSICA,X ; Get the volume value
F3D3: E6 A4 INC MUSAIND ; Bump the music pointer
F3D5: 85 A5 STA MUSAVOL ; Store the new volume value
F3D7: 4C BC F3 JMP MusChanA ; Keep processing through a tone
MusCmdCtrlA:
F3DA: E8 INX ; Point to the control value
F3DB: E6 A4 INC MUSAIND ; Bump the music pointer
F3DD: BD A0 F4 LDA MUSICA,X ; Get the control value
F3E0: E6 A4 INC MUSAIND ; Bump the music pointer
F3E2: 85 15 STA AUDC0 ; Store the new control value
F3E4: 4C BC F3 JMP MusChanA ; Keep processing through a tone
MusCmdJumpA:
F3E7: E8 INX ; Point to jump value
F3E8: 8A TXA ; X to ...
F3E9: A8 TAY ; ... Y (pointer to jump value)
F3EA: E8 INX ; Point one past jump value
F3EB: 8A TXA ; Into A so we can subtract
F3EC: 38 SEC ; New ...
F3ED: F9 A0 F4 SBC MUSICA,Y ; ... index
F3F0: 85 A4 STA MUSAIND ; Store it
F3F2: 4C BC F3 JMP MusChanA ; Keep processing through a tone
MusCmdToneA:
F3F5: A4 A5 LDY MUSAVOL ; Get the volume
F3F7: 29 1F AND #0x1F ; Lower 5 bits are frequency
F3F9: C9 1F CMP #0x1F ; Is this a silence?
F3FB: D0 02 BNE MusNoteA ; No ... play it
F3FD: A0 00 LDY #0 ; Frequency of 31 flags silence
MusNoteA:
F3FF: 85 17 STA AUDF0 ; Store the frequency
F401: 84 19 STY AUDV0 ; Store the volume
F403: BD A0 F4 LDA MUSICA,X ; Get the note value again
F406: E6 A4 INC MUSAIND ; Bump to the next command
F408: 6A ROR A ; The upper ...
F409: 6A ROR A ; ... three ...
F40A: 6A ROR A ; ... bits ...
F40B: 6A ROR A ; ... hold ...
F40C: 6A ROR A ; ... the ...
F40D: 29 07 AND #7 ; ... delay
F40F: 18 CLC ; No accidental carry
F410: 2A ROL A ; Every delay tick ...
F411: 2A ROL A ; ... is *4 frames
F412: 85 A3 STA MUSADEL ; Store the note delay
MusDoB:
F414: C6 A6 DEC MUSBDEL
F416: D0 58 BNE MusDoDone
MusChanB:
F418: A6 A7 LDX MUSBIND
F41A: BD CD F4 LDA MUSICB,X
F41D: C9 00 CMP #0
F41F: F0 22 BEQ MusCmdJumpB
F421: C9 01 CMP #1
F423: F0 11 BEQ MusCmdCtrlB
F425: C9 02 CMP #2
F427: D0 28 BNE MusCmdToneB
F429: E8 INX
F42A: E6 A7 INC MUSBIND
F42C: BD CD F4 LDA MUSICB,X
F42F: E6 A7 INC MUSBIND
F431: 85 A8 STA MUSBVOL
F433: 4C 18 F4 JMP MusChanB
MusCmdCtrlB:
F436: E8 INX
F437: E6 A7 INC MUSBIND
F439: BD CD F4 LDA MUSICB,X
F43C: E6 A7 INC MUSBIND
F43E: 85 16 STA AUDC1
F440: 4C 18 F4 JMP MusChanB
MusCmdJumpB:
F443: E8 INX
F444: 8A TXA
F445: A8 TAY
F446: E8 INX
F447: 8A TXA
F448: 38 SEC
F449: F9 CD F4 SBC MUSICB,Y
F44C: 85 A7 STA MUSBIND
F44E: 4C 18 F4 JMP MusChanB
MusCmdToneB:
F451: A4 A8 LDY MUSBVOL
F453: 29 1F AND #0x1F
F455: C9 1F CMP #0x1F
F457: D0 02 BNE MusNoteB
F459: A0 00 LDY #0
MusNoteB:
F45B: 85 18 STA AUDF1
F45D: 84 1A STY AUDV1
F45F: BD CD F4 LDA MUSICB,X
F462: E6 A7 INC MUSBIND
F464: 6A ROR A
F465: 6A ROR A
F466: 6A ROR A
F467: 6A ROR A
F468: 6A ROR A
F469: 29 07 AND #7
F46B: 18 CLC
F46C: 2A ROL A
F46D: 2A ROL A
F46E: 85 A6 STA MUSBDEL
MusDoDone:
F470: 60 RTS ; Done
INIT_GO_FX:
; This function initializes the hardware and temporaries
; to play the soundeffect of a player hitting the wall
F471: A9 05 LDA #5 ; Set counter for frame delay ...
F473: 85 86 STA MUS_TMP1 ; ... between frequency change
F475: A9 03 LDA #3 ; Tone type ...
F477: 85 15 STA AUDC0 ; ... poly tone
F479: A9 0F LDA #15 ; Volume A ...
F47B: 85 19 STA AUDV0 ; ... to max
F47D: A9 00 LDA #0 ; Volume B ...
F47F: 85 1A STA AUDV1 ; ... silence
F481: A9 F0 LDA #240 ; Initial ...
F483: 85 85 STA MUS_TMP0 ; ... sound ...
F485: 85 17 STA AUDF0 ; ... frequency
F487: 60 RTS ; Done
PROCESS_GO_FX:
; This function is called once per scanline to play the
; soundeffects of a player hitting the wall.
F488: C6 86 DEC MUS_TMP1 ; Time to change the frequency?
F48A: D0 11 BNE FxRun ; No ... let it run
F48C: A9 05 LDA #5 ; Reload ...
F48E: 85 86 STA MUS_TMP1 ; ... the frame count
F490: E6 85 INC MUS_TMP0 ; Increment ...
F492: A5 85 LDA MUS_TMP0 ; ... the frequency divisor
F494: 85 17 STA AUDF0 ; Change the frequency
F496: C9 00 CMP #0
F498: D0 03 BNE FxRun
F49A: A9 01 LDA #1 ; All done ... return 1
F49C: 60 RTS ; Done
FxRun:
F49D: A9 00 LDA #0 ; Keep playing
F49F: 60 RTS ; Done
; Music commands for Channel A and Channel B
; A word on music and wall timing ...
; Wall moves between scanlines 0 and 111 (112 total)
; Wall-increment frames-to-top
; 3 336
; 2 224
; 1 112
; 0.5 56 ; Ah ... but we are getting one less
; Each tick is multiplied by 4 to yield 4 frames per tick
; 32 ticks/song = 32*4 = 128 frames / song
; We want songs to start with wall at top ...
; Find the least-common-multiple
; 336 and 128 : 2688 8 walls, 21 musics
; 224 and 128 : 896 4 walls, 7 musics
; 112 and 128 : 896 8 walls, 7 musics
; 56 and 128 : 896 16 walls, 7 musics
; Wall moving every other gives us 112*2=224 scanlines
; Song and wall are at start every 4
; 1 scanline, every 8
; Wall delay=3 gives us 128*3=336 scanlines 2
.MUSCMD_JUMP = 0 ; Music command value for JUMP
.MUSCMD_CONTROL = 1 ; Music command value for CONTROL
.MUSCMD_VOLUME = 2 ; Music command value for VOLUME
.MUS_REST = 31 ; Frequency value for silence
.MUS_DEL_1 = 32*1 ; Note duration 1
.MUS_DEL_2 = 32*2 ; Note duration 2
.MUS_DEL_3 = 32*3 ; Note duration 3
.MUS_DEL_4 = 32*4 ; Note duration 4
MUSICA:
MA_SONG_1:
F4A0: 01 0C .byte MUSCMD_CONTROL, 12
F4A2: 02 0F .byte MUSCMD_VOLUME, 15 ; Volume (full)
MA1_01:
F4A4: 6F .byte MUS_DEL_3 + 15
F4A5: 3F .byte MUS_DEL_1 + MUS_REST
F4A6: 6F .byte MUS_DEL_3 + 15
F4A7: 3F .byte MUS_DEL_1 + MUS_REST
F4A8: 27 .byte MUS_DEL_1 + 7
F4A9: 3F .byte MUS_DEL_1 + MUS_REST
F4AA: 27 .byte MUS_DEL_1 + 7
F4AB: 3F .byte MUS_DEL_1 + MUS_REST
F4AC: 5F .byte MUS_DEL_2 + MUS_REST
F4AD: 28 .byte MUS_DEL_1 + 8
F4AE: 3F .byte MUS_DEL_1 + MUS_REST
F4AF: 9F .byte MUS_DEL_4 + MUS_REST
F4B0: 51 .byte MUS_DEL_2 + 17
F4B1: 5F .byte MUS_DEL_2 + MUS_REST
F4B2: 51 .byte MUS_DEL_2 + 17
F4B3: 5F .byte MUS_DEL_2 + MUS_REST
F4B4: 70 .byte MUS_DEL_3 + 16
F4B5: 3F .byte MUS_DEL_1 + MUS_REST
F4B6: 00 14 .byte MUSCMD_JUMP, (MA1_END - MA1_01) ; Repeat back to top
MA1_END:
MA_SONG_2:
F4B8: 01 0C .byte MUSCMD_CONTROL, 12
F4BA: 02 0F .byte MUSCMD_VOLUME, 15
MA2_01:
F4BC: 2F .byte MUS_DEL_1 + 15
F4BD: 3F .byte MUS_DEL_1 + MUS_REST
F4BE: 2F .byte MUS_DEL_1 + 15
F4BF: 3F .byte MUS_DEL_1 + MUS_REST
F4C0: 5F .byte MUS_DEL_2 + MUS_REST
F4C1: 87 .byte MUS_DEL_4 + 7
F4C2: 9F .byte MUS_DEL_4 + MUS_REST
F4C3: 4F .byte MUS_DEL_2 + 15
F4C4: 9F .byte MUS_DEL_4 + MUS_REST
F4C5: 4C .byte MUS_DEL_2 + 12
F4C6: 5F .byte MUS_DEL_2 + MUS_REST
F4C7: 4F .byte MUS_DEL_2 + 15
F4C8: 5F .byte MUS_DEL_2 + MUS_REST
F4C9: 51 .byte MUS_DEL_2 + 17
F4CA: 5F .byte MUS_DEL_2 + MUS_REST
F4CB: 00 11 .byte MUSCMD_JUMP, (MA2_END - MA2_01) ; Repeat back to top
MA2_END:
MUSICB:
MB_SONG_1:
F4CD: 01 08 .byte MUSCMD_CONTROL, 8
F4CF: 02 08 .byte MUSCMD_VOLUME, 8 ; Volume (half)
MB1_01:
F4D1: 2A .byte MUS_DEL_1 + 10
F4D2: 3F .byte MUS_DEL_1 + MUS_REST
F4D3: 34 .byte MUS_DEL_1 + 20
F4D4: 3F .byte MUS_DEL_1 + MUS_REST
F4D5: 3E .byte MUS_DEL_1 + 30
F4D6: 3F .byte MUS_DEL_1 + MUS_REST
F4D7: 2F .byte MUS_DEL_1 + 15
F4D8: 3F .byte MUS_DEL_1 + MUS_REST
F4D9: 2A .byte MUS_DEL_1 + 10
F4DA: 3F .byte MUS_DEL_1 + MUS_REST
F4DB: 34 .byte MUS_DEL_1 + 20
F4DC: 3F .byte MUS_DEL_1 + MUS_REST
F4DD: 3E .byte MUS_DEL_1 + 30
F4DE: 3F .byte MUS_DEL_1 + MUS_REST
F4DF: 2F .byte MUS_DEL_1 + 15
F4E0: 3F .byte MUS_DEL_1 + MUS_REST
F4E1: 00 12 .byte MUSCMD_JUMP, (MB1_END - MB1_01) ; Repeat back to top
MB1_END:
MB_SONG_2:
F4E3: 01 08 .byte MUSCMD_CONTROL, 8
F4E5: 02 08 .byte MUSCMD_VOLUME, 8
MB2_01:
F4E7: 21 .byte MUS_DEL_1 + 1
F4E8: 3F .byte MUS_DEL_1 + MUS_REST
F4E9: 21 .byte MUS_DEL_1 + 1
F4EA: 3F .byte MUS_DEL_1 + MUS_REST
F4EB: 21 .byte MUS_DEL_1 + 1
F4EC: 3F .byte MUS_DEL_1 + MUS_REST
F4ED: 21 .byte MUS_DEL_1 + 1
F4EE: 3F .byte MUS_DEL_1 + MUS_REST
F4EF: 3E .byte MUS_DEL_1 + 30
F4F0: 3F .byte MUS_DEL_1 + MUS_REST
F4F1: 3E .byte MUS_DEL_1 + 30
F4F2: 3F .byte MUS_DEL_1 + MUS_REST
F4F3: 3E .byte MUS_DEL_1 + 30
F4F4: 3F .byte MUS_DEL_1 + MUS_REST
F4F5: 3E .byte MUS_DEL_1 + 30
F4F6: 3F .byte MUS_DEL_1 + MUS_REST
F4F7: 00 12 .byte MUSCMD_JUMP, (MB2_END - MB2_01) ; Repeat back to top
MB2_END:
SKILL_VALUES:
; This table describes how to change the various
; difficulty parameters as the game progresses.
; For instance, the second entry in the table
; says that when the score is 4, change the values of
; wall-increment to 1, frame-delay to 2, gap-pattern to 0,
; MusicA to 24, and MusicB to 22.
; A 255 on the end of the table indicates the end
; Wall Inc Delay Gap MA MB
F4F9: 00 01 03 00 00 00 .byte 0, 1, 3, 0 ,MA_SONG_1-MUSICA , MB_SONG_1-MUSICB
F4FF: 04 01 02 00 18 16 .byte 4, 1, 2, 0 ,MA_SONG_2-MUSICA , MB_SONG_2-MUSICB
F505: 08 01 01 00 00 00 .byte 8, 1, 1, 0 ,MA_SONG_1-MUSICA , MB_SONG_1-MUSICB
F50B: 10 01 01 01 18 16 .byte 16, 1, 1, 1 ,MA_SONG_2-MUSICA , MB_SONG_2-MUSICB
F511: 18 01 01 03 00 00 .byte 24, 1, 1, 3 ,MA_SONG_1-MUSICA , MB_SONG_1-MUSICB
F517: 20 01 01 07 18 16 .byte 32, 1, 1, 7 ,MA_SONG_2-MUSICA , MB_SONG_2-MUSICB
F51D: 28 01 01 0F 00 00 .byte 40, 1, 1, 15 ,MA_SONG_1-MUSICA , MB_SONG_1-MUSICB
F523: 30 02 01 00 18 16 .byte 48, 2, 1, 0 ,MA_SONG_2-MUSICA , MB_SONG_2-MUSICB
F529: 40 02 01 01 00 00 .byte 64, 2, 1, 1 ,MA_SONG_1-MUSICA , MB_SONG_1-MUSICB
F52F: 50 02 01 03 18 16 .byte 80, 2, 1, 3 ,MA_SONG_2-MUSICA , MB_SONG_2-MUSICB
F535: 60 02 01 07 00 00 .byte 96 , 2, 1, 7 ,MA_SONG_1-MUSICA , MB_SONG_1-MUSICB
F53B: FF .byte 255
GR_PLAYER:
; Image for players (8x8)
.subs .=0, *=1
;
F53C: 10 .byte 0b__...*....
F53D: 10 .byte 0b__...*....
F53E: 28 .byte 0b__..*.*...
F53F: 28 .byte 0b__..*.*...
F540: 54 .byte 0b__.*.*.*..
F541: 54 .byte 0b__.*.*.*..
F542: AA .byte 0b__*.*.*.*.
F543: 7C .byte 0b__.*****..
DIGITS:
; Images for numbers
; We only need 5 rows, but the extra space on the end makes each digit 8 rows,
; which makes it the multiplication easier.
F544: 0E .byte 0b__....***. ; 0 (leading 0 is blank)
F545: 0A .byte 0b__....*.*.
F546: 0A .byte 0b__....*.*.
F547: 0A .byte 0b__....*.*.
F548: 0E .byte 0b__....***.
F549: 00 .byte 0b__........
F54A: 00 .byte 0b__........
F54B: 00 .byte 0b__........
F54C: 22 .byte 0b__..*...*. ; 1
F54D: 22 .byte 0b__..*...*.
F54E: 22 .byte 0b__..*...*.
F54F: 22 .byte 0b__..*...*.
F550: 22 .byte 0b__..*...*.
F551: 00 .byte 0b__........
F552: 00 .byte 0b__........
F553: 00 .byte 0b__........
F554: EE .byte 0b__***.***. ; 2
F555: 22 .byte 0b__..*...*.
F556: EE .byte 0b__***.***.
F557: 88 .byte 0b__*...*...
F558: EE .byte 0b__***.***.
F559: 00 .byte 0b__........
F55A: 00 .byte 0b__........
F55B: 00 .byte 0b__........
F55C: EE .byte 0b__***.***. ; 3
F55D: 22 .byte 0b__..*...*.
F55E: 66 .byte 0b__.**..**.
F55F: 22 .byte 0b__..*...*.
F560: EE .byte 0b__***.***.
F561: 00 .byte 0b__........
F562: 00 .byte 0b__........
F563: 00 .byte 0b__........
F564: AA .byte 0b__*.*.*.*. ; 4
F565: AA .byte 0b__*.*.*.*.
F566: EE .byte 0b__***.***.
F567: 22 .byte 0b__..*...*.
F568: 22 .byte 0b__..*...*.
F569: 00 .byte 0b__........
F56A: 00 .byte 0b__........
F56B: 00 .byte 0b__........
F56C: EE .byte 0b__***.***. ; 5
F56D: 88 .byte 0b__*...*...
F56E: EE .byte 0b__***.***.
F56F: 22 .byte 0b__..*...*.
F570: EE .byte 0b__***.***.
F571: 00 .byte 0b__........
F572: 00 .byte 0b__........
F573: 00 .byte 0b__........
F574: EE .byte 0b__***.***. ; 6
F575: 88 .byte 0b__*...*...
F576: EE .byte 0b__***.***.
F577: AA .byte 0b__*.*.*.*.
F578: EE .byte 0b__***.***.
F579: 00 .byte 0b__........
F57A: 00 .byte 0b__........
F57B: 00 .byte 0b__........
F57C: EE .byte 0b__***.***. ; 7
F57D: 22 .byte 0b__..*...*.
F57E: 22 .byte 0b__..*...*.
F57F: 22 .byte 0b__..*...*.
F580: 22 .byte 0b__..*...*.
F581: 00 .byte 0b__........
F582: 00 .byte 0b__........
F583: 00 .byte 0b__........
F584: EE .byte 0b__***.***. ; 8
F585: AA .byte 0b__*.*.*.*.
F586: EE .byte 0b__***.***.
F587: AA .byte 0b__*.*.*.*.
F588: EE .byte 0b__***.***.
F589: 00 .byte 0b__........
F58A: 00 .byte 0b__........
F58B: 00 .byte 0b__........
F58C: EE .byte 0b__***.***. ; 9
F58D: AA .byte 0b__*.*.*.*.
F58E: EE .byte 0b__***.***.
F58F: 22 .byte 0b__..*...*.
F590: EE .byte 0b__***.***.
F591: 00 .byte 0b__........
F592: 00 .byte 0b__........
F593: 00 .byte 0b__........
F7FA:
; 6502 vectors
F7FA: 00 F0 .word main
F7FC: 00 F0 .word main ; Reset vector (top of program)
F7FE: 00 F0 .word main