The 42 token programs were the last undecoded part of MUSCLE. Each now carries a token-by-token listing above its unchanged .byte data, generated by _tools/bytecode_dis.py and wired into the build as 'make pass3'. Encoding, derived from RunBytecodeInterpreter ($9AE8) and BytecodeHandlerTable ($9237): the dispatch is one byte per element. A byte in $C8-$EF selects one of the 40 handler-table entries; every other byte takes the literal path at $9B08 and is pushed onto the operand list at $0033[Y], accumulated into $003C[Y]. The one exception is four opcodes whose handler's first instructions are 'lda ($1A),Y / iny', so they consume the following byte inline: $CB LOOP_BEGIN -> $7C,X count + $7E,X body address $D1 SET_RATE -> $43,X $D7 DRAW_SPRITE -> count for the $A660 blit $E1 SET_WAIT -> $7A,X $CB and $C9 are the loop pair: LOOP_END decrements $7C,X and, if non-zero, reloads Y from $7E,X, rewinding the interpreter to the top of the body. Decoded 377 opcodes and 937 literal operands across 42 programs; all 40 defined opcodes are used, so the opcode set is complete. Two standalone programs contain no byte in $C8-$EF at all, so every byte takes the literal path - the listing states that rather than implying code. Each mnemonic was read off its handler's own straight-line path up to its first 'jmp $9AE8' / 'jmp $9B25'. Handlers that only tail-call a game routine are named for the routine rather than guessed at, since the semantics live in the callee. bytecode_dis.py inserts comment lines only; .byte data is copied through verbatim. Verified: all 16,384 PRG bytes still emitted exactly once, every value equal to the ROM, zero audit mismatches, and 'make regen' (pass1 -> pass2 -> pass3) reproduces prg.s byte-for-byte. Byte-identical ROM verified. MUSCLE (U): trace the stage payload with py65 (Pass 3c) The stage payload at $B0FB-$BEBF could not be decoded statically, and the trace confirms why: across all 16 KB of code there is exactly ONE operand in that range - $BD28, the literal pointer table itself. The real address is formed at runtime by 'adc $BD28,X', where A is a value carried in the bytecode stream, so the readers are indexed by a runtime value and cannot be enumerated by searching the code. FCEUX cannot observe this either: its Lua API offers registerexec / registerexecute / registerrun / registerwrite but no memory-read hook, and with no static list of readers there is nothing to hook. _tools/trace_stage_payload.py therefore uses py65's ObservableMemory.subscribe_to_read, which fires on every read of a range and can report PC from inside the hook. py65 is only a 6502 core, so the tracer adds the minimum hardware to boot the game: a scanline counter off processorCycles, $2002 vblank at scanline 241 cleared on read, NMI at the same scanline, $4014 OAM DMA, and the $2005/$2006/$2007 latches. Without NMI the game never leaves $80E0 (lda $0321 / beq), because $0321 is the flag the bytecode VM raises. Results over 300 frames (26.8M cycles, 4,071 NMIs): 2,548 payload reads from 44 distinct reader PCs, touching 914 of 3,421 bytes. Findings: - The hottest reader is $AC82, the compressed-VRAM RLE decoder: 1,046 of its 1,128 reads advance by exactly +1, comparing each byte against $C0. - $9B50 is a backward copy (lda ($12),Y / sta ($10),Y / dey), stepping -1. - 107 distinct 8-byte blocks had all eight bytes read, with spacing dominated by $08 - a dense 8-byte record array - plus a sparser group on a $D0 stride ($BBE0, $BCB0, $BD80, $BE50). - Readers use three disciplines: forward sequential, backward sequential, and variable stride consistent with a fixed-offset field walk. py65 is deliberately NOT a build dependency: the tool documents unpacking the wheel on demand. 'make regen' is unaffected. Byte-identical ROM verified. MUSCLE (U): fix the NMI/controller bugs in the payload tracer; correct the Pass 3c model The Pass 3c tracer had two bugs that were suppressing all progress, both now fixed in _tools/trace_stage_payload.py (previously scratch, now durable): * NMI re-armed by $2002 reads. The vblank flag must be cleared once per frame, not on every read of $2002 -- the main loop polls $2002 and spins on the bytecode VM flag at $8226, so each poll cleared bit 7 and re-armed NMI inside the same scanline. That gave 40,900 NMIs across 3,000 frames and corrupted all game state. A per-frame nmi_fired flag restores exactly one NMI per frame (verified: 600 frames -> 600 NMIs). * Input went to $4017. The poll routine at $AA69 is `lda $4016,X` with X=1 and only compares bits 0-1, so driving $4017 consumed nothing -- all masks tested gave byte-identical traces. The game consumes joy1 on $4016 and needs a real latch/shift register. With it, START matters: 47.7% coverage vs 39.0%. Match entry is two discrete START presses (title -> char select -> match). Coverage 26.3% -> 40.9%. Both bugs and the port subtlety are documented in the tool header so they are not re-derived. Corrects the Pass 3c conclusion. $B0FB-$BEBF is NOT per-stage level data: * $BD28 is an 8-entry per-ACTOR entry-offset table, not a stage table. $A063 `adc $BD28,X` with X = ActorIndex ($1E), plus #$32 at $A071 when PlayerActiveFlag ($78,X) is set. Observed actors are $00-$04. Forcing all 8 actor indices adds zero new bytes. * The sound engine reads the same window: $B03C `lda (SoundReadPointerLo),Y` with `cmp #$F0 / sbc #$F0 / tay / lda $B0E3,y` is note decoding, which is where the $FF/$F0 high-nibble terminators come from. So the window is a shared pool -- per-actor bytecode, compressed-VRAM RLE, and music note streams -- and stage cycling cannot raise coverage past ~40%. The remaining 2,161 B need other music tracks and scripted match play, not taps. Also corrects two stale claims: $0326 is not a level byte (never leaves $00 even in a confirmed match), and $0320 is a boolean, not a screen-state machine. Build unaffected: byte-identical, and `make regen` still reproduces prg.s byte-for-byte. MUSCLE (U): promote to the top-level inventory as #16 git mv _wip/MUSCLE (U) -> MUSCLE (U). The relative symlink copilot/rom.nes -> ../M.U.S.C.L.E. (U).nes survives the move untouched. * copilot/Makefile: tool paths ../../../_tools/ -> ../../_tools/ for NESDIS, PASS2 and BYTECODE. `make` prints the byte-identity message and `make regen` still reproduces prg.s byte-for-byte, both verified after the move. * MUSCLE (U)/OVERVIEW.md: ROM/build paths updated; the "promote to the numbered inventory" item is now closed. * Root OVERVIEW.md: added as #16, removed from the _wip skeleton table (20 -> 19), added a ### 16 detail section, and its vector/mapping notes moved out of the skeleton section. All 16 top-level projects verified byte-identical. Add Pass 1 verification tool; teach nesdis.py the undocumented opcodes _tools/verify_pass1.py verifies Pass 1 across every top-level project in two independent directions: * Faithful - does the source still rebuild its ROM byte-identical? * Complete - does the committed source claim as much code as a fresh trace can actually reach? The second is the one that catches real problems. A project can reproduce all 16,384 bytes perfectly while calling 95% of them data, because the tracer gave up early. Instruction *counts* are compared rather than bytes, so the check is independent of comment style (which is not uniform across the repo). Result: all 16 projects are faithful, and Joypad Test Cartridge is the only truncated Pass 1 -- 282 committed instructions against 1,773 reachable. nesdis.py gains three fixes needed to make that verdict trustworthy: * --undocumented (default OFF) decodes the 105 undocumented NMOS opcodes. They are used as NOP padding and as real RMW ops, and a tracer that halts on them loses most of the code: Joypad goes 580 -> 3,846 code bytes. Default off so MUSCLE's `make regen` still reproduces prg.s byte-for-byte. * Undocumented opcodes are emitted as explicit `.byte` with the disassembly in the comment. ca65 V2.19 implements none of them, so they cannot be written as mnemonics; keeping them in the code region preserves the code/data split and the audit trail. Official 0xEA NOP still encodes normally. * Two latent bugs, both now reachable: - RESET and IRQ are commonly the same address, and the semantic-name map was overwriting, renaming the primary entry point to `IrqHandler`. Now setdefault, in RESET/NMI/IRQ priority order. - render() stamped every branch operand as Label_XXXX and never reconciled it with the semantic name map, so a branch into a named routine emitted a label that was never defined and the file would not assemble. Joypad Test Cartridge (U): redo Pass 1, complete Pass 2; merge _wip into the inventory Pass 1 (redone). The committed split claimed 282 instructions / 580 bytes (3.5%). The tracer halted at $C09E on `DCP $3C20` ($CF) -- an undocumented opcode used as ordinary code -- and filed 3,256 bytes of real code as `.byte` data. Now 1,773 instructions / 3,836 bytes (23.4%), a 6.6x increase. Verified against a fresh trace: 1,769 emitted instructions + 4 undocumented opcodes written as explicit bytes = 1,773, an exact match. Byte accounting stays exact at 3,836 + 12,548 = 16,384. ca65 V2.19 implements none of the undocumented opcodes, so the 4 affected instructions (DCP $3C20, LAX $20D4, NOP $C1,X, RRA ($D0),X) are emitted as explicit `.byte` with the disassembly in the comment. They stay in the code region, so the split and the audit trail are both preserved. Pass 2 (complete). All 202 labels renamed; zero `Label_Cxxxx` remaining. Renames are keyed by address and verified to have bound to the intended address, not just to some address. 202 routine headers, every one describing real behaviour -- no "undetermined in Pass 1" boilerplate left. `locals.inc` carries 99 aliases, the proven semantic ones sitting beside the generated `ZpXX` entries per the alias pattern in AGENTS.md. Two naming errors in the previous draft are corrected: $55 is MarkerValue (it holds $70/$88/$A0 and is compared against them), not a "P1 Down timer"; and the twelve MarkerVar variables are named by position because which player/button each belongs to is not established. Pass 3 is now outstanding, and the old Pass 3 was wrong: it described $C09E-$C173 and $C17F-$CCF6 as data, and both are code. After the redo there is exactly one data region, $CF06-$FFFF, confirmed by orphan scan. Documentation. The root inventory now lists all 36 projects in one table -- the 20 `_wip/` projects are rows 17-36 rather than a second table that could drift. That second table had wrong mirroring for 12 of them (Duck Hunt, Golf, Hogan's Alley, Ice Climber, DK Jr Math, Lode Runner, Lunar Pool, Mario Bros, Millipede, Pyramid, Raid [a2], Urban Champion were all recorded H when they are V, and vice versa); every value is now read from the ROM rather than trusted. Build status is split into two honest tiers: rows 1-16 are BYTE-IDENTICAL and compare the whole ROM, rows 17-36 are PRG-IDENTICAL because their Makefiles only run `cmp reconstructed_prg.bin prg.bin`. Header and CHR are not proven for those. All 36 build cleanly; the WIP count was also corrected from 19 to 20. `_tools/verify_pass1.py` checks all 36 and reports none truncated. Mario Bros (JU): Pass 1 disassembly, 14.6% -> 72.2% code The skeleton prg.s was a 12-line .incbin of the whole PRG. It is now a real disassembly: 5,735 instructions, 11,829 code bytes (72.2%), 937 labels and routine headers, byte accounting exact at 11,800 + 4,584 = 16,384, and BYTE-IDENTICAL against prg.bin. Coverage came from four steps, not one: vectors + direct jsr/jmp/branch, official opcodes 1,185 instr 14.6% --undocumented (105 extra NMOS opcodes) 1,210 instr 14.9% --auto-seed (61 table-referenced entries) 4,187 instr 51.1% --extra-seed 0xC0B6,0xC5A3 5,735 instr 72.2% Almost everything sits behind computed dispatch. Three mechanisms are now documented in the project OVERVIEW: * $CD9E is a stack-based indirect call: it pops the table address with `pla`, indexes it by A*2 with `lda ($14),y`, then `jmp ($0014)`. Because the pointer arrives on the stack it cannot be followed statically from the dispatcher. * $C5A3 is a 20-entry table of `JSR` thunks ending in `rts`. Probing it linearly gives twenty valid targets, and seeding it recovers most of the last 21%. * $C0B6 is the NMI phase dispatcher, reachable only by computed dispatch. Two overlapping-decode bugs in _tools/nesdis.py had to be fixed first: * Control-flow targets must win over fall-through. `bne` at $C4BA targets $C528, but the fall-through path had decoded $C527 as a 2-byte `NOP #$A5` whose operand swallowed $C528. No assembler branches into the middle of an instruction, so the spanning decode is now dropped in favour of the target; its bytes fall out as data, leaving byte accounting unchanged. * Branch targets inside a surviving instruction must be pruned from the target set. Otherwise emit_code's linear walk consumes those bytes as an operand, so the label is referenced but never defined and the file does not assemble at all -- `Error: Symbol 'Label_C528' is undefined`. Neither change disturbs an existing pipeline: MUSCLE's `make regen` still reproduces prg.s byte-for-byte, Joypad Test Cartridge still builds byte-identical, and _tools/verify_pass1.py reports all 16 top-level projects faithful with none truncated. Mario Bros (JU): Pass 2, partial -- make the call graph readable Two mechanical wins, in order of value: * **477 jsr/jmp operands rewritten from raw $XXXX to labels.** The tracer emits call and jump targets as hex, so the call graph was unreadable -- the most called routine appeared as `jsr $CCA0` 14 times over. Every one of those sites already had a label at its target address, so the substitution is purely mechanical and byte-preserving. Zero raw hex call operands remain. * **13 landmark routines named** from verified instruction evidence: WaitVblank1, ClearRamPageLoop, NmiPhaseDispatch ($C0B6), JsrThunkTable ($C5A3), DispatchViaStackPointer ($CD9E), AdvanceDispatchPointer ($CDB4), PushTablePointerDispatch ($CCA0), DispatchTableF393 ($CAB9), InitSpritesOffscreen ($DFC4), AdjustDecimalColumns ($D15A), TestRamFlagPair0500 ($D328), NextIndex ($CE84). **922 labels remain unnamed, and that is recorded as the honest state** rather than papered over. They sit 15-25 per page across $CC00-$CFFF, which is just the game logic: naming them means reading ~5,700 instructions across 935 routines. Guessing from the call graph and the NES convention would be exactly the guessy rewrite PROMPTS.md rules out. The productive next step is more reach, not more naming. The 4,555 unreached bytes are where most unnamed routines live, and they are gated behind the stack-pointer dispatch at $CD9E, whose pushed table addresses are only known in the callers' frames. Still BYTE-IDENTICAL; all 16 top-level projects remain faithful. Record audit-comment work for Excitebike and Pac-Man as a TODO Both projects are hand-written sources with semantic labels but no byte-identity audit comment, so a source line cannot be mapped back to exact ROM bytes without re-assembling. Every other project in the repo carries one. Documented what was tried and why it was dropped rather than left implicit. Addresses from 'ca65 -l' work fine -- the listing offset indexes prg.bin directly -- but the listing carries no source line numbers, so entries cannot be keyed back to source lines. Byte values also have to come from prg.bin rather than the listing, since ca65 prints 'rr rr' for relocatable words. No tool was committed, because the one written does not work. Both projects verified still byte-identical; no source file was changed. Add TODO.md handoff; bring AGENTS.md back in line with the repo AGENTS.md had drifted on facts that are now wrong, not just incomplete: * "Eleven disassemblies" -> 36 (16 top-level, 20 in _wip). The index it points at had the same stale count. * The audit-comment convention was stated as `; PRG:$xxxx AA BB`, but the dominant spelling is `; CPU:$xxxx PRG:xxxx AA BB` and five other variants are in use, with Excitebike and Pac-Man carrying none at all. Now stated accurately as "preserve whatever spelling a file uses", with the gap pointed at. * `_tools/` was described as holding splitnes.py and chr2gif.py. It holds six tools now, including the Pass 1 tracer and the verifier. * ROM filenames "contain spaces" -> spaces *and parentheses*, which is also what makes FCEUX hang headless. Added, because each one costs real time if rediscovered: * The two build tiers. The 20 _wip projects only `cmp reconstructed_prg.bin prg.bin`, so their header and CHR are NOT proven -- calling them byte-identical to the ROM is wrong. * A promotion procedure, since that has now been done twice. * A tracer/toolchain gotchas section: undocumented opcodes truncating traces (and ca65 being unable to encode them), vectors living at the end of the PRG rather than in the iNES header, the RESET==IRQ name collision, control-flow targets beating fall-through, the branch-target pruning that stops a file failing to assemble, NMI firing once per frame rather than per $2002 read, joy1 being $4016, and ca65 listings carrying no source line numbers. TODO.md is the handoff document: open work per project with enough detail to resume, the residue counts, and the reasoning behind each abandoned approach so it is not silently retried. Nothing rebuilt or changed; all projects still verify. Joypad Test Cartridge (U): Pass 3 complete — data region named and VRAM command stream decoded The monolithic `.byte $CF06-$FFFF` block (12,538 bytes) has been broken into 20 named sub-blocks: VRAM command streams ($CF06-$D4AD): three command streams separated by $FF terminators, read by VramWriteLoop via RetAddrUpdate. Opcode set decoded: $4C = jump, $60 = deferred PPUCTRL, bit-7-clear = VRAM write (PPU addr + data, bit 6 of data = long/short selector). OAM tables ($D4E3-$D6A3): 12 groups of 32-byte tables (8 entries of Y/tile/attr/X), read by CopyOamFromTable ($D4E3) and CopyOamFromTable70 ($D5C4). Sprite templates ($D6A5-$D6E4): sprite template read by CopySpriteTemplateTable ($D6A5) and button OAM template read by PrepareButtonOam ($D6C5). Padding: $FF ROM padding ($D6E5-$FFF9) and vectors ($FFFA-$FFFF). OVERVIEW.md updated: section 8 documents all 20 sub-blocks with the VRAM command stream format and OAM table structure; section 11 marks Pass 3 complete with remaining work (MarkerVar player/button mapping, HandleButtonPress sprite order). Build verified byte-identical. Root OVERVIEW.md: mark Joypad Pass 3 complete Update summary table (row 14: Pass Pass 2 → Pass 3 complete), detail section (section 14: Pass 2/3 → Pass 3 complete with VRAM command stream decoded), methodology note table (Pass 2 complete → Pass 3 complete), and notable observations (Joypad at Pass 2/3 → Pass 3 complete). Joypad Test Cartridge is now fully Pass 3 complete: all 20 data sub-blocks named, VRAM command stream opcode set decoded, OAM table structure documented. TODO.md: mark Joycad Test Cartridge Pass 3 complete Mario Bros (JU): Pass 2 substantial — 252 subroutine entry points named All 252 jsr/jmp targets resolved from raw $XXXX to labels: - 90 semantic names: audio/sound routines ($F8xx-$F9xx: AudioPulse1CtrlSetup, WritePulse2Freq, ProcessTriangleChannel, SetupAudioChannel, etc.), gameplay helpers (CheckZpB3Return, CheckRangeReturn012, ToggleZpFC_Bit3, etc.) - 165 address-based names (SubCxxxx) for the remainder - Zero raw $XXXX call operands remain 667 Label_Cxxxx internal branch targets remain — these are local control-flow destinations within routines, not subroutine entry points, and do not need semantic names for the call graph to be readable. Build verified BYTE-IDENTICAL. Root OVERVIEW.md updated (row 26: Pass 0 skeleton → Pass 1 complete, Pass 2 substantial). TODO.md updated. Lunar Pool (U): Pass 1 complete, 57.8% code; nesdis.py opcode/emitter fixes The skeleton prg.s was a 12-line .incbin of the whole PRG. It is now a real disassembly: 4,586 instructions, 9,475 code bytes (57.8%), 6,909 data bytes, byte accounting exact at 9,403 + 6,981 = 16,384, BYTE-IDENTICAL. Coverage: vectors + direct jsr/jmp/branch reached 1,259 instructions (15.6%). --undocumented took it to 4,572 (57.6%), and --auto-seed (48 table-referenced entries) plus --extra-seed 0xE80C (the non-$C000 RESET vector) took it to 4,586 (57.8%). Three undocumented opcodes were missing from nesdis.py and are added: * $72 RRA abs (the RRA family was missing the $72 absolute form) * $42 NOP #imm (the NOP-immediate family was missing $42) * $FA NOP abs,X (the NOP-abs,X family was missing $FA) One emitter fix: ca65 silently rewrites an operand whose high byte is $00 in the shorter zero-page form -- `sta $00FF,x` assembles as `sta $FF,x` ($95 instead of $9D). render() now emits the `a:` prefix for ABS/ABSX/ABSY/IND operands with a high byte of $00, forcing the absolute form so the emitted bytes match the ROM. operand_value() strips the prefix when parsing. These changes are general and verified not to disturb existing pipelines: MUSCLE's `make regen` still reproduces prg.s byte-for-byte. Remaining gaps: 6,909 bytes (42.2%) still data, gated behind jmp ($7961) at three sites (RAM-pointer dispatch; the blocks after them hold the screen text "strings" "game over" and "hi`score__") and stack-based dispatch at $CBDC -- the same pattern as Mario Bros (JU)'s $CD9E. TODO.md: add Lunar Pool as an open item Adds comments for all lines to Pacman and Excitebike Moves Pacman 'locals' and 'symbols' definitions into the right places
14136 lines
468 KiB
ArmAsm
14136 lines
468 KiB
ArmAsm
.include "symbols.inc"
|
|
.include "locals.inc"
|
|
.segment "PRG"
|
|
|
|
.org $C000
|
|
|
|
CopyrightText:
|
|
.byte $43,$4F,$50,$59,$20,$52,$49,$47 ; CPU:$C000 PRG:0000 43 4F 50 59 20 52 49 47
|
|
.byte $48,$54,$20,$31,$39,$38,$34,$20 ; CPU:$C008 PRG:0008 48 54 20 31 39 38 34 20
|
|
.byte $31,$39,$39,$33,$20,$4E,$41,$4D ; CPU:$C010 PRG:0010 31 39 39 33 20 4E 41 4D
|
|
.byte $43,$4F,$20,$4C,$54,$44,$2E,$20 ; CPU:$C018 PRG:0018 43 4F 20 4C 54 44 2E 20
|
|
.byte $41,$4C,$4C,$20,$52,$49,$47,$48 ; CPU:$C020 PRG:0020 41 4C 4C 20 52 49 47 48
|
|
.byte $54,$53,$20,$52,$45,$53,$45,$52 ; CPU:$C028 PRG:0028 54 53 20 52 45 53 45 52
|
|
.byte $56,$45,$44 ; CPU:$C030 PRG:0030 56 45 44
|
|
|
|
Reset:
|
|
ldx #$00 ; CPU:$C033 PRG:0033 A2 00
|
|
stx PPUCTRL ; CPU:$C035 PRG:0035 8E 00 20
|
|
sei ; CPU:$C038 PRG:0038 78
|
|
cld ; CPU:$C039 PRG:0039 D8
|
|
dex ; CPU:$C03A PRG:003A CA
|
|
txs ; CPU:$C03B PRG:003B 9A
|
|
nop ; CPU:$C03C PRG:003C EA
|
|
nop ; CPU:$C03D PRG:003D EA
|
|
nop ; CPU:$C03E PRG:003E EA
|
|
|
|
ldx #$02 ; CPU:$C03F PRG:003F A2 02
|
|
|
|
@WaitForPpu:
|
|
lda #$06 ; CPU:$C041 PRG:0041 A9 06
|
|
sta PPUMASK ; CPU:$C043 PRG:0043 8D 01 20
|
|
|
|
lda PPUSTATUS ; CPU:$C046 PRG:0046 AD 02 20
|
|
|
|
@WaitVBlank:
|
|
lda PPUSTATUS ; CPU:$C049 PRG:0049 AD 02 20
|
|
bpl @WaitVBlank ; CPU:$C04C PRG:004C 10 FB
|
|
|
|
lda #$00 ; CPU:$C04E PRG:004E A9 00
|
|
sta PPUSCROLL ; CPU:$C050 PRG:0050 8D 05 20
|
|
sta PPUSCROLL ; CPU:$C053 PRG:0053 8D 05 20
|
|
dex ; CPU:$C056 PRG:0056 CA
|
|
bne @WaitForPpu ; CPU:$C057 PRG:0057 D0 E8
|
|
|
|
lda #$00 ; CPU:$C059 PRG:0059 A9 00
|
|
tay ; CPU:$C05B PRG:005B A8
|
|
|
|
@ClearLowRam:
|
|
sta $0000,y ; CPU:$C05C PRG:005C 99 00 00
|
|
iny ; CPU:$C05F PRG:005F C8
|
|
cpy #$3E ; CPU:$C060 PRG:0060 C0 3E
|
|
bne @ClearLowRam ; CPU:$C062 PRG:0062 D0 F8
|
|
|
|
ldx #$08 ; CPU:$C064 PRG:0064 A2 08
|
|
ldy #$87 ; CPU:$C066 PRG:0066 A0 87
|
|
|
|
@ClearRamPages:
|
|
sta ($00),y ; CPU:$C068 PRG:0068 91 00
|
|
iny ; CPU:$C06A PRG:006A C8
|
|
bne @ClearRamPages ; CPU:$C06B PRG:006B D0 FB
|
|
inc $01 ; CPU:$C06D PRG:006D E6 01
|
|
cpx $01 ; CPU:$C06F PRG:006F E4 01
|
|
bne @ClearRamPages ; CPU:$C071 PRG:0071 D0 F5
|
|
|
|
lda #$06 ; CPU:$C073 PRG:0073 A9 06
|
|
sta PPUMASK ; CPU:$C075 PRG:0075 8D 01 20
|
|
|
|
lda #$00 ; CPU:$C078 PRG:0078 A9 00
|
|
sta PPUSCROLL ; CPU:$C07A PRG:007A 8D 05 20
|
|
sta PPUSCROLL ; CPU:$C07D PRG:007D 8D 05 20
|
|
sta $41 ; CPU:$C080 PRG:0080 85 41
|
|
sta $42 ; CPU:$C082 PRG:0082 85 42
|
|
sta PPUCTRL ; CPU:$C084 PRG:0084 8D 00 20
|
|
sta PPUMASK ; CPU:$C087 PRG:0087 8D 01 20
|
|
tay ; CPU:$C08A PRG:008A A8
|
|
|
|
@CheckRamSignature:
|
|
lda RamSignature,y ; CPU:$C08B PRG:008B B9 FF C0
|
|
cmp $0052,y ; CPU:$C08E PRG:008E D9 52 00
|
|
bne @InitializeRamSignature ; CPU:$C091 PRG:0091 D0 07
|
|
|
|
iny ; CPU:$C093 PRG:0093 C8
|
|
cpy #$0F ; CPU:$C094 PRG:0094 C0 0F
|
|
bne @CheckRamSignature ; CPU:$C096 PRG:0096 D0 F3
|
|
|
|
beq @SignatureAlreadyPresent ; CPU:$C098 PRG:0098 F0 1A
|
|
|
|
@InitializeRamSignature:
|
|
lda #$00 ; CPU:$C09A PRG:009A A9 00
|
|
tay ; CPU:$C09C PRG:009C A8
|
|
|
|
@ClearZeroPage:
|
|
sta $0000,y ; CPU:$C09D PRG:009D 99 00 00
|
|
iny ; CPU:$C0A0 PRG:00A0 C8
|
|
bne @ClearZeroPage ; CPU:$C0A1 PRG:00A1 D0 FA
|
|
|
|
ldy #$00 ; CPU:$C0A3 PRG:00A3 A0 00
|
|
|
|
@CopyRamSignature:
|
|
lda RamSignature,y ; CPU:$C0A5 PRG:00A5 B9 FF C0
|
|
sta $0052,y ; CPU:$C0A8 PRG:00A8 99 52 00
|
|
iny ; CPU:$C0AB PRG:00AB C8
|
|
cpy #$0F ; CPU:$C0AC PRG:00AC C0 0F
|
|
bne @CopyRamSignature ; CPU:$C0AE PRG:00AE D0 F5
|
|
|
|
lda #$01 ; CPU:$C0B0 PRG:00B0 A9 01
|
|
sta $64 ; CPU:$C0B2 PRG:00B2 85 64
|
|
|
|
@SignatureAlreadyPresent:
|
|
ldy #$00 ; CPU:$C0B4 PRG:00B4 A0 00
|
|
sty $3F ; CPU:$C0B6 PRG:00B6 84 3F
|
|
|
|
lda #$07 ; CPU:$C0B8 PRG:00B8 A9 07
|
|
sta $45 ; CPU:$C0BA PRG:00BA 85 45
|
|
lda #$01 ; CPU:$C0BC PRG:00BC A9 01
|
|
cmp $47 ; CPU:$C0BE PRG:00BE C5 47
|
|
bne @SkipSwap ; CPU:$C0C0 PRG:00C0 D0 19
|
|
|
|
cmp $46 ; CPU:$C0C2 PRG:00C2 C5 46
|
|
bne @SkipSwap ; CPU:$C0C4 PRG:00C4 D0 15
|
|
|
|
@SwapLoop:
|
|
lda $77,y ; CPU:$C0C6 PRG:00C6 B9 77
|
|
sta workPtr0 ; CPU:$C0C8 PRG:00C8 00 85
|
|
|
|
lda $67,y ; CPU:$C0CA PRG:00CA 00 B9
|
|
sta $77,y ; CPU:$C0CC PRG:00CC 67 00
|
|
|
|
lda workPtr0 ; CPU:$C0CE PRG:00CE 99 77
|
|
sta $67,y ; CPU:$C0D0 PRG:00D0 00 A5
|
|
|
|
iny ; CPU:$C0D2 PRG:00D2 00
|
|
cpy #$10 ; CPU:$C0D3 PRG:00D3 99 67
|
|
bne @SwapLoop ; CPU:$C0D5 PRG:00D5 00 C8
|
|
|
|
@SkipSwap:
|
|
lda #$1F ; CPU:$C0D7 PRG:00D7 C0 10
|
|
sta APUCTRL ; CPU:$C0D9 PRG:00D9 D0 EB A9
|
|
|
|
lda #$C0 ; CPU:$C0DC PRG:00DC 1F 8D
|
|
sta APUFRAMECNT ; CPU:$C0DE PRG:00DE 15 40 A9
|
|
|
|
jsr InitializeAudioEngine ; CPU:$C0E1 PRG:00E1 C0 8D 17
|
|
jsr $EEB4 ; CPU:$C0E4 PRG:00E4 40 20 8C
|
|
|
|
lda #$88 ; CPU:$C0E7 PRG:00E7 EE 20
|
|
sta $43 ; CPU:$C0E9 PRG:00E9 B4 EE
|
|
sta PPUCTRL ; CPU:$C0EB PRG:00EB A9 88 85
|
|
|
|
lda #$FF ; CPU:$C0EE PRG:00EE 43 8D
|
|
sta $48 ; CPU:$C0F0 PRG:00F0 00 20
|
|
sta $023F ; CPU:$C0F2 PRG:00F2 A9 FF 85
|
|
sta $024B ; CPU:$C0F5 PRG:00F5 48 8D 3F
|
|
|
|
jmp MainEntry ; CPU:$C0F8 PRG:00F8 02 8D 4B
|
|
|
|
RamSignature:
|
|
.byte "HIROKI AOYAGI" ; CPU:$C0FF PRG:00FF 48
|
|
.byte $AA, $55 ; CPU:$C100 PRG:0100 49 52
|
|
|
|
;==============================================================================
|
|
; $C10E-$C17E: NMI Handler
|
|
;
|
|
; Local:
|
|
; Handles the per-frame NMI. Saves the CPU registers, configures the PPU,
|
|
; performs sprite OAM DMA, calls several frame-processing routines, restores
|
|
; the current scroll and PPU control state, polls both controllers, selects
|
|
; the active controller input, and conditionally performs additional
|
|
; per-frame processing.
|
|
;
|
|
; Global:
|
|
; Primary VBlank/frame interrupt entry point. This routine ties together
|
|
; rendering updates, sprite DMA, controller polling, and other work that
|
|
; needs to occur once per video frame.
|
|
;
|
|
; Notes:
|
|
; $41/$42 are used as the two PPUSCROLL writes.
|
|
; $45 supplies the source page for OAM DMA.
|
|
; $4D/$4E receive controller 1/2 input bits.
|
|
; $4F receives the controller state selected by $46/$47.
|
|
;
|
|
; The purposes of $40-$48 and the called routines at FlushGameplayPpuUpdates
|
|
; ReadNearbyNametableTiles, UpdatePalettes, and InitializeAudioChannels will
|
|
; be refined during later passes.
|
|
;==============================================================================
|
|
|
|
NmiHandler:
|
|
pha ; CPU:$C10E PRG:010E 48
|
|
txa ; CPU:$C10F PRG:010F 8A
|
|
pha ; CPU:$C110 PRG:0110 48
|
|
tya ; CPU:$C111 PRG:0111 98
|
|
pha ; CPU:$C112 PRG:0112 48
|
|
|
|
lda #$1E ; CPU:$C113 PRG:0113 A9 1E
|
|
sta PPUMASK ; CPU:$C115 PRG:0115 8D 01 20
|
|
|
|
lda #$00 ; CPU:$C118 PRG:0118 A9 00
|
|
sta OAMADDR ; CPU:$C11A PRG:011A 8D 03 20
|
|
sta $40 ; CPU:$C11D PRG:011D 85 40
|
|
|
|
lda $45 ; CPU:$C11F PRG:011F A5 45
|
|
sta OAMDMA ; CPU:$C121 PRG:0121 8D 14 40
|
|
|
|
jsr FlushGameplayPpuUpdates ; CPU:$C124 PRG:0124 20 7E DE
|
|
jsr ReadNearbyNametableTiles ; CPU:$C127 PRG:0127 20 A2 E2
|
|
jsr UpdatePalettes ; CPU:$C12A PRG:012A 20 7F C1
|
|
|
|
; Restore the two PPU scroll components.
|
|
lda $41 ; CPU:$C12D PRG:012D A5 41
|
|
sta PPUSCROLL ; CPU:$C12F PRG:012F 8D 05 20
|
|
|
|
lda $42 ; CPU:$C132 PRG:0132 A5 42
|
|
sta PPUSCROLL ; CPU:$C134 PRG:0134 8D 05 20
|
|
|
|
; Construct the PPUCTRL value for this frame.
|
|
lda $47 ; CPU:$C137 PRG:0137 A5 47
|
|
and $46 ; CPU:$C139 PRG:0139 25 46
|
|
and #$01 ; CPU:$C13B PRG:013B 29 01
|
|
asl ; CPU:$C13D PRG:013D 0A
|
|
ora $43 ; CPU:$C13E PRG:013E 05 43
|
|
sta PPUCTRL ; CPU:$C140 PRG:0140 8D 00 20
|
|
|
|
; Strobe the controller ports.
|
|
lda #$01 ; CPU:$C143 PRG:0143 A9 01
|
|
sta JOY1 ; CPU:$C145 PRG:0145 8D 16 40
|
|
|
|
lda #$00 ; CPU:$C148 PRG:0148 A9 00
|
|
sta JOY1 ; CPU:$C14A PRG:014A 8D 16 40
|
|
|
|
; Read eight serial bits from both controllers.
|
|
ldx #$08 ; CPU:$C14D PRG:014D A2 08
|
|
|
|
@ReadControllers:
|
|
lda JOY1 ; CPU:$C14F PRG:014F AD 16 40
|
|
and #$03 ; CPU:$C152 PRG:0152 29 03
|
|
cmp #$01 ; CPU:$C154 PRG:0154 C9 01
|
|
ror $4D ; CPU:$C156 PRG:0156 66
|
|
|
|
lda APUFRAMECNT ; CPU:$C157 PRG:0157 4D AD 17
|
|
and #$03 ; CPU:$C15A PRG:015A 40 29
|
|
cmp #$01 ; CPU:$C15C PRG:015C 03 C9
|
|
ror $4E ; CPU:$C15E PRG:015E 01
|
|
|
|
dex ; CPU:$C15F PRG:015F 66
|
|
bne @ReadControllers ; CPU:$C160 PRG:0160 4E CA
|
|
|
|
; Controller 1 is the default input source.
|
|
ldx currentInput ; CPU:$C162 PRG:0162 D0 EB
|
|
|
|
; Under the condition controlled by $46/$47,
|
|
; use controller 2 instead.
|
|
lda cocktailModeFlag ; CPU:$C164 PRG:0164 A6 4D
|
|
and activePlayerFlag ; CPU:$C166 PRG:0166 A5 46
|
|
beq @ControllerSelected ; CPU:$C168 PRG:0168 25 47
|
|
|
|
ldx newlyPressedInput ; CPU:$C16A PRG:016A F0 02
|
|
|
|
@ControllerSelected:
|
|
stx previousInput ; CPU:$C16C PRG:016C A6 4E
|
|
|
|
; Advance a per-frame counter.
|
|
inc frameCounter ; CPU:$C16E PRG:016E 86 4F
|
|
|
|
; $48 gates an additional per-frame routine.
|
|
lda $48 ; CPU:$C170 PRG:0170 E6 4B
|
|
bne @NmiDone ; CPU:$C172 PRG:0172 A5 48
|
|
|
|
jsr InitializeAudioChannels ; CPU:$C174 PRG:0174 D0 03 20
|
|
|
|
@NmiDone:
|
|
pla ; CPU:$C177 PRG:0177 D0
|
|
tay ; CPU:$C178 PRG:0178 EE
|
|
pla ; CPU:$C179 PRG:0179 68
|
|
tax ; CPU:$C17A PRG:017A A8
|
|
pla ; CPU:$C17B PRG:017B 68
|
|
IrqHandler:
|
|
rti ; CPU:$C17E PRG:017E 40
|
|
|
|
UpdatePalettes:
|
|
lda $0299 ; CPU:$C17F PRG:017F AD 99 02
|
|
cmp #$0F ; CPU:$C182 PRG:0182 C9 0F
|
|
bne @CheckSecondPalette ; CPU:$C184 PRG:0184 D0 1A
|
|
|
|
lda PPUSTATUS ; CPU:$C186 PRG:0186 AD 02 20
|
|
lda #$3F ; CPU:$C189 PRG:0189 A9 3F
|
|
sta PPUADDR ; CPU:$C18B PRG:018B 8D 06 20
|
|
lda #$00 ; CPU:$C18E PRG:018E A9 00
|
|
sta PPUADDR ; CPU:$C190 PRG:0190 8D 06 20
|
|
|
|
ldy #$00 ; CPU:$C193 PRG:0193 A0 00
|
|
|
|
@CopyFirstPalette:
|
|
lda $0299,y ; CPU:$C195 PRG:0195 B9 99 02
|
|
sta PPUDATA ; CPU:$C198 PRG:0198 8D 07 20
|
|
iny ; CPU:$C19B PRG:019B C8
|
|
cpy #$10 ; CPU:$C19C PRG:019C C0 10
|
|
bne @CopyFirstPalette ; CPU:$C19E PRG:019E D0 F5
|
|
|
|
@CheckSecondPalette:
|
|
lda $02A9 ; CPU:$C1A0 PRG:01A0 AD A9 02
|
|
cmp #$0F ; CPU:$C1A3 PRG:01A3 C9 0F
|
|
bne @CheckPaletteState ; CPU:$C1A5 PRG:01A5 D0 1A
|
|
|
|
lda PPUSTATUS ; CPU:$C1A7 PRG:01A7 AD 02 20
|
|
lda #$3F ; CPU:$C1AA PRG:01AA A9 3F
|
|
sta PPUADDR ; CPU:$C1AC PRG:01AC 8D 06 20
|
|
lda #$10 ; CPU:$C1AF PRG:01AF A9 10
|
|
sta PPUADDR ; CPU:$C1B1 PRG:01B1 8D 06 20
|
|
|
|
ldy #$00 ; CPU:$C1B4 PRG:01B4 A0 00
|
|
|
|
@CopySecondPalette:
|
|
lda $02A9,y ; CPU:$C1B6 PRG:01B6 B9 A9 02
|
|
sta PPUDATA ; CPU:$C1B9 PRG:01B9 8D 07 20
|
|
iny ; CPU:$C1BC PRG:01BC C8
|
|
cpy #$10 ; CPU:$C1BD PRG:01BD C0 10
|
|
bne @CopySecondPalette ; CPU:$C1BF PRG:01BF D0 F5
|
|
|
|
@CheckPaletteState:
|
|
lda $0299 ; CPU:$C1C1 PRG:01C1 AD 99 02
|
|
cmp #$0F ; CPU:$C1C4 PRG:01C4 C9 0F
|
|
beq @ResetPpuAddress ; CPU:$C1C6 PRG:01C6 F0 08
|
|
|
|
lda $02A9 ; CPU:$C1C8 PRG:01C8 AD A9 02
|
|
cmp #$0F ; CPU:$C1CB PRG:01CB C9 0F
|
|
beq @ResetPpuAddress ; CPU:$C1CD PRG:01CD F0 01
|
|
|
|
rts ; CPU:$C1CF PRG:01CF 60
|
|
|
|
@ResetPpuAddress:
|
|
lda #$30 ; CPU:$C1D0 PRG:01D0 A9 30
|
|
sta PPUADDR ; CPU:$C1D2 PRG:01D2 8D 06 20
|
|
|
|
lda #$00 ; CPU:$C1D5 PRG:01D5 A9 00
|
|
sta PPUADDR ; CPU:$C1D7 PRG:01D7 8D 06 20
|
|
sta PPUADDR ; CPU:$C1DA PRG:01DA 8D 06 20
|
|
sta PPUADDR ; CPU:$C1DD PRG:01DD 8D 06 20
|
|
|
|
sta $0299 ; CPU:$C1E0 PRG:01E0 8D 99 02
|
|
sta $02A9 ; CPU:$C1E3 PRG:01E3 8D A9 02
|
|
|
|
rts ; CPU:$C1E6 PRG:01E6 60
|
|
|
|
|
|
;==============================================================================
|
|
; $C1E7-$C266: Main Initialization and State Dispatch
|
|
;
|
|
; Local:
|
|
; Synchronizes with the NMI through $40, initializes PPU/OAM and several
|
|
; game-state variables, calls four initialization routines, initializes the
|
|
; two 16-byte palette buffers, then enters the main state-dispatch loop.
|
|
;
|
|
; The loop synchronizes with NMI again, uses $3F as an index into a table of
|
|
; five handler addresses, stores the selected address in $10/$11, and jumps
|
|
; to that handler indirectly.
|
|
;
|
|
; Global:
|
|
; This is the main program entry reached from Reset after hardware and RAM
|
|
; initialization. It transitions the game into its normal frame-driven state
|
|
; machine. NMI clears $40 each frame, allowing the foreground/main code to
|
|
; proceed through its next state-machine update.
|
|
;
|
|
; Notes:
|
|
; $40 clearly provides synchronization between foreground code and NMI.
|
|
; Writing $01 to $40 and spinning until NMI clears it forms a frame wait.
|
|
;
|
|
; $3F is used here as a state/dispatch index. Its exact semantic states will
|
|
; be named as the individual handlers are decoded.
|
|
;
|
|
; $10/$11 form a temporary indirect JMP pointer.
|
|
;
|
|
; $C267 begins the state-handler address table and is intentionally left for
|
|
; the next decoding pass.
|
|
;==============================================================================
|
|
|
|
MainEntry:
|
|
lda #$01 ; CPU:$C1E7 PRG:01E7 A9 01
|
|
sta $40 ; CPU:$C1E9 PRG:01E9 85 40
|
|
|
|
@WaitForInitialNmi:
|
|
lda $40 ; CPU:$C1EB PRG:01EB A5 40
|
|
bne @WaitForInitialNmi ; CPU:$C1ED PRG:01ED D0 FC
|
|
|
|
lda #$08 ; CPU:$C1EF PRG:01EF A9 08
|
|
sta PPUCTRL ; CPU:$C1F1 PRG:01F1 8D 00 20
|
|
sta ppuCtrlShadow ; CPU:$C1F4 PRG:01F4 85 43
|
|
|
|
lda PPUSTATUS ; CPU:$C1F6 PRG:01F6 AD 02 20
|
|
|
|
lda #$00 ; CPU:$C1F9 PRG:01F9 A9 00
|
|
sta PPUMASK ; CPU:$C1FB PRG:01FB 8D 01 20
|
|
|
|
tax ; CPU:$C1FE PRG:01FE AA
|
|
|
|
@ClearOamPage:
|
|
sta $0700,x ; CPU:$C1FF PRG:01FF 9D 00 07
|
|
inx ; CPU:$C202 PRG:0202 E8
|
|
bne @ClearOamPage ; CPU:$C203 PRG:0203 D0 FA
|
|
|
|
sta cocktailModeFlag ; CPU:$C205 PRG:0205 85 46
|
|
|
|
jsr ClearGameplayNametables ; CPU:$C207 PRG:0207 20 85 E3
|
|
jsr InitializeNametableAttributes ; CPU:$C20A PRG:020A 20 0B C3
|
|
jsr InitializeNametableData ; CPU:$C20D PRG:020D 20 A6 C2
|
|
jsr $E419 ; CPU:$C210 PRG:0210 20 19 E4
|
|
|
|
ldy #$00 ; CPU:$C213 PRG:0213 A0 00
|
|
|
|
@InitializePaletteBuffers:
|
|
lda TitleScreenPalette,y ; CPU:$C215 PRG:0215 B9 3F C4
|
|
sta $0299,y ; CPU:$C218 PRG:0218 99 99 02
|
|
iny ; CPU:$C21B PRG:021B C8
|
|
cpy #$20 ; CPU:$C21C PRG:021C C0 20
|
|
bne @InitializePaletteBuffers ; CPU:$C21E PRG:021E D0 F5
|
|
|
|
lda #$2D ; CPU:$C220 PRG:0220 A9 2D
|
|
sta actorStatusDisplay ; CPU:$C222 PRG:0222 85 6C
|
|
sta actorStatusDisplay+1 ; CPU:$C224 PRG:0224 85 6D 85
|
|
sta actorStatusDisplay+2 ; CPU:$C227 PRG:0227 6E 85 6F
|
|
sta actorStatusDisplay+3 ; CPU:$C22A PRG:022A A9 FF 8D
|
|
|
|
lda #$FF ; CPU:$C22D PRG:022D 3F 02
|
|
sta $023F ; CPU:$C22F PRG:022F 85 48 A9
|
|
sta gameplaySuspended ; CPU:$C232 PRG:0232 00 85
|
|
|
|
lda #$00 ; CPU:$C234 PRG:0234 47 85
|
|
sta activePlayerFlag ; CPU:$C236 PRG:0236 46 85
|
|
sta cocktailModeFlag ; CPU:$C238 PRG:0238 42 85
|
|
sta $42 ; CPU:$C23A PRG:023A 41 85
|
|
sta $41 ; CPU:$C23C PRG:023C 4C 85
|
|
sta stateTimer ; CPU:$C23E PRG:023E 87 85
|
|
sta $87 ; CPU:$C240 PRG:0240 88 A5
|
|
sta $88 ; CPU:$C242 PRG:0242 3F D0
|
|
|
|
lda gameState ; CPU:$C244 PRG:0244 04 A9
|
|
bne @UseAlternatePpuCtrl ; CPU:$C246 PRG:0246 8A D0
|
|
|
|
lda #$8A ; CPU:$C248 PRG:0248 02 A9
|
|
bne @SetPpuCtrl ; CPU:$C24A PRG:024A 88 8D
|
|
|
|
@UseAlternatePpuCtrl:
|
|
lda #$88 ; CPU:$C24C PRG:024C 00 20
|
|
|
|
@SetPpuCtrl:
|
|
sta PPUCTRL ; CPU:$C24E PRG:024E 85 43 A9
|
|
sta ppuCtrlShadow ; CPU:$C251 PRG:0251 01 85
|
|
|
|
MainDispatchLoop:
|
|
lda #$01 ; CPU:$C250 PRG:0250 A9 01
|
|
sta $40 ; CPU:$C252 PRG:0252 85 40
|
|
|
|
@WaitForNmi:
|
|
lda $40 ; CPU:$C254 PRG:0254 A5 40
|
|
bne @WaitForNmi ; CPU:$C256 PRG:0256 D0 FC
|
|
|
|
ldy gameState ; CPU:$C258 PRG:0258 A4 3F
|
|
|
|
lda $C267,y ; CPU:$C25A PRG:025A B9 67 C2
|
|
sta dispatchVector ; CPU:$C25D PRG:025D 85 10
|
|
|
|
lda $C268,y ; CPU:$C25F PRG:025F B9 68 C2
|
|
sta dispatchVector+1 ; CPU:$C262 PRG:0262 85 11 6C
|
|
|
|
jmp ($0010) ; CPU:$C265 PRG:0265 10 00 7A C2 77
|
|
|
|
;==============================================================================
|
|
; $C267-$C26E: Main State Dispatch Table
|
|
;
|
|
; Local:
|
|
; Four 16-bit addresses used by the indirect state dispatcher at the end of
|
|
; MainEntry. $3F is used directly as a byte offset into this table:
|
|
;
|
|
; lda MainStateHandlerTable,y
|
|
; sta $10
|
|
; lda MainStateHandlerTable+1,y
|
|
; sta $11
|
|
; jmp ($0010)
|
|
;
|
|
; This implies the normal state values in $3F are even byte offsets:
|
|
; $00, $02, $04, $06
|
|
;
|
|
; Global:
|
|
; Selects one of four major foreground/game-state handlers. This is the
|
|
; top-level state machine entered after Reset initialization and synchronized
|
|
; to the NMI-driven frame loop.
|
|
;
|
|
; Notes:
|
|
; The four targets are:
|
|
; InitialStateHandler
|
|
; PlayerSelectionState
|
|
; State04Handler
|
|
; TimedStateTransition
|
|
;
|
|
; Handler names remain provisional until each target is decoded.
|
|
;==============================================================================
|
|
|
|
MainStateHandlerTable:
|
|
.word InitialStateHandler ; CPU:$C267 PRG:0267 7A C2
|
|
.word PlayerSelectionState ; CPU:$C269 PRG:0269 77 C4
|
|
.word State04Handler ; CPU:$C26B PRG:026B 12 C5
|
|
.word TimedStateTransition ; CPU:$C26D PRG:026D 6F C2
|
|
|
|
;==============================================================================
|
|
; $C26F-$C279: Timed State Transition Handler
|
|
;
|
|
; Local:
|
|
; Decrements the counter at $0F once per frame. While the counter remains
|
|
; nonzero, control returns to the common NMI synchronization/dispatch loop
|
|
; at $C250.
|
|
;
|
|
; When the counter reaches zero, changes the main state offset at $3F to
|
|
; $02 and then returns to the same dispatch loop.
|
|
;
|
|
; Global:
|
|
; Implements the handler selected when the main state offset is $06.
|
|
; This appears to be a timed transitional state. Another state places a
|
|
; duration in $0F and selects state $06; this handler counts that duration
|
|
; down before advancing to state $02.
|
|
;
|
|
; Notes:
|
|
; $0F is clearly being used as a countdown timer here, but its broader use
|
|
; should be traced before assigning it a permanent global name.
|
|
;
|
|
; $3F is the byte offset into MainStateHandlerTable:
|
|
; $00 -> InitialStateHandler
|
|
; $02 -> PlayerSelectionState
|
|
; $04 -> State04Handler
|
|
; $06 -> this handler
|
|
;
|
|
; $C250 is inside MainEntry and is the common frame synchronization point.
|
|
;==============================================================================
|
|
|
|
TimedStateTransition:
|
|
dec $0F ; CPU:$C26F PRG:026F C6 0F
|
|
bne MainDispatchLoop ; CPU:$C271 PRG:0271 D0 DD
|
|
|
|
lda #$02 ; CPU:$C273 PRG:0273 A9 02
|
|
sta gameState ; CPU:$C275 PRG:0275 85 3F
|
|
|
|
jmp MainDispatchLoop ; CPU:$C277 PRG:0277 4C 50 C2
|
|
|
|
|
|
;==============================================================================
|
|
; $C27A-$C2A5: Initial/Input State Handler
|
|
;
|
|
; Local:
|
|
; Checks controller-1 state bits $0C. If either bit is set, selects state
|
|
; $06, initializes the countdown at $0F to $5A, and jumps back to MainEntry.
|
|
;
|
|
; Otherwise increments $42. When $42 reaches $F0, resets it to zero,
|
|
; changes the saved PPUCTRL value at $43 to $88, and selects state $06
|
|
; with the same $5A countdown.
|
|
;
|
|
; If $42 has not yet reached $F0, the initialization of state $06 is
|
|
; skipped and execution reaches the common JMP back to MainDispatchLoop.
|
|
;
|
|
; Global:
|
|
; Handler selected by main state offset $00. It appears to manage an early
|
|
; or attract/input-wait state, transitioning into the timed state either
|
|
; because of controller input or because the scrolling/progression value
|
|
; at $42 reaches $F0.
|
|
;
|
|
; Notes:
|
|
; $4D is controller-1 input assembled by NmiHandler.
|
|
; $42 is also used as the second PPUSCROLL write during NMI.
|
|
; Exact game-state semantics will be refined in later passes.
|
|
;==============================================================================
|
|
|
|
InitialStateHandler:
|
|
lda currentInput ; CPU:$C27A PRG:027A A5 4D
|
|
and #$0C ; CPU:$C27C PRG:027C 29 0C
|
|
beq @AdvanceScroll ; CPU:$C27E PRG:027E F0 0B
|
|
|
|
lda #$06 ; CPU:$C280 PRG:0280 A9 06
|
|
sta gameState ; CPU:$C282 PRG:0282 85 3F
|
|
|
|
lda #$5A ; CPU:$C284 PRG:0284 A9 5A
|
|
sta $0F ; CPU:$C286 PRG:0286 85 0F
|
|
|
|
jmp MainEntry ; CPU:$C288 PRG:0288 4C E7 C1
|
|
|
|
@AdvanceScroll:
|
|
inc $42 ; CPU:$C28B PRG:028B E6 42
|
|
|
|
lda #$F0 ; CPU:$C28D PRG:028D A9 F0
|
|
cmp $42 ; CPU:$C28F PRG:028F C5 42
|
|
bne @ReturnToMainLoop ; CPU:$C291 PRG:0291 D0 10
|
|
|
|
lda #$00 ; CPU:$C293 PRG:0293 A9 00
|
|
sta $42 ; CPU:$C295 PRG:0295 85 42
|
|
|
|
lda #$88 ; CPU:$C297 PRG:0297 A9 88
|
|
sta ppuCtrlShadow ; CPU:$C299 PRG:0299 85 43
|
|
|
|
lda #$06 ; CPU:$C29B PRG:029B A9 06
|
|
sta gameState ; CPU:$C29D PRG:029D 85 3F
|
|
|
|
lda #$5A ; CPU:$C29F PRG:029F A9 5A
|
|
sta $0F ; CPU:$C2A1 PRG:02A1 85 0F
|
|
|
|
@ReturnToMainLoop:
|
|
jmp MainDispatchLoop ; CPU:$C2A3 PRG:02A3 4C 50 C2
|
|
|
|
;==============================================================================
|
|
; $C2A6-$C30A: Initialize Nametable Data
|
|
;
|
|
; Local:
|
|
; Performs two groups of PPU writes used during initial screen setup.
|
|
;
|
|
; First phase:
|
|
; - Begins at PPU address $20E5.
|
|
; - Copies $17 bytes from the ROM data at TitleScreenTileBlock
|
|
; - Repeats this for six rows.
|
|
; - Advances the destination PPU address by $20 after each row.
|
|
;
|
|
; Second phase:
|
|
; - Processes nine variable-length PPU update records beginning at $C3B0.
|
|
; - Each record supplies a two-byte PPU address followed by data bytes.
|
|
; - $FF terminates the data portion of each record.
|
|
;
|
|
; Global:
|
|
; Called from MainEntry during initial game setup. This routine constructs
|
|
; part of the initial nametable/display before normal state dispatch begins.
|
|
;
|
|
; Notes:
|
|
; $00/$01 are used here as a 16-bit PPU destination address.
|
|
; $02 counts the six repeated rows.
|
|
; $03 counts $17 bytes within each row.
|
|
;
|
|
; TitleScreenTileBlock is a repeated row of tile data.
|
|
; $C3B0 contains nine encoded PPU update records.
|
|
;
|
|
; These ROM data blocks will be named more precisely when their contents
|
|
; and resulting screen regions are decoded in later passes.
|
|
;==============================================================================
|
|
|
|
InitializeNametableData:
|
|
; Initial PPU destination = $20E5.
|
|
lda #$20 ; CPU:$C2A6 PRG:02A6 A9 20
|
|
sta workPtr0 ; CPU:$C2A8 PRG:02A8 85 00
|
|
|
|
lda #$E5 ; CPU:$C2AA PRG:02AA A9 E5
|
|
sta workPtr0+1 ; CPU:$C2AC PRG:02AC 85 01 A9
|
|
|
|
; Write six rows.
|
|
lda #$06 ; CPU:$C2AF PRG:02AF 06 85
|
|
sta workPtr1 ; CPU:$C2B1 PRG:02B1 02 A0
|
|
|
|
ldy #$00 ; CPU:$C2B3 PRG:02B3 00 AD
|
|
|
|
@WriteRow:
|
|
lda PPUSTATUS ; CPU:$C2B5 PRG:02B5 02 20 A5
|
|
|
|
lda workPtr0 ; CPU:$C2B8 PRG:02B8 00 8D
|
|
sta PPUADDR ; CPU:$C2BA PRG:02BA 06 20 A5
|
|
|
|
lda workPtr0+1 ; CPU:$C2BD PRG:02BD 01 8D 06
|
|
sta PPUADDR ; CPU:$C2C0 PRG:02C0 20 A9 17
|
|
|
|
; Each row contains $17 bytes.
|
|
lda #$17 ; CPU:$C2C3 PRG:02C3 85 03
|
|
sta workPtr1+1 ; CPU:$C2C5 PRG:02C5 B9 26 C3
|
|
|
|
@WriteRowBytes:
|
|
lda TitleScreenTileBlock,y ; CPU:$C2C8 PRG:02C8 8D 07 20
|
|
sta PPUDATA ; CPU:$C2CB PRG:02CB C8 C6 03
|
|
|
|
iny ; CPU:$C2CE PRG:02CE D0
|
|
|
|
dec workPtr1+1 ; CPU:$C2CF PRG:02CF F5 A5
|
|
bne @WriteRowBytes ; CPU:$C2D1 PRG:02D1 01 18
|
|
|
|
; Advance the PPU destination by $20.
|
|
lda workPtr0+1 ; CPU:$C2D3 PRG:02D3 69 20 85
|
|
clc ; CPU:$C2D6 PRG:02D6 01
|
|
adc #$20 ; CPU:$C2D7 PRG:02D7 A9 00
|
|
sta workPtr0+1 ; CPU:$C2D9 PRG:02D9 65 00 85
|
|
|
|
lda #$00 ; CPU:$C2DC PRG:02DC 00 C6
|
|
adc workPtr0 ; CPU:$C2DE PRG:02DE 02 D0
|
|
sta workPtr0 ; CPU:$C2E0 PRG:02E0 D3 A9
|
|
|
|
dec workPtr1 ; CPU:$C2E2 PRG:02E2 09 85
|
|
bne @WriteRow ; CPU:$C2E4 PRG:02E4 00 A0
|
|
|
|
; Process nine additional encoded PPU update records.
|
|
lda #$09 ; CPU:$C2E6 PRG:02E6 00 AD
|
|
sta workPtr0 ; CPU:$C2E8 PRG:02E8 02 20
|
|
|
|
ldy #$00 ; CPU:$C2EA PRG:02EA B9 B0
|
|
|
|
@NextPpuRecord:
|
|
lda PPUSTATUS ; CPU:$C2EC PRG:02EC C3 8D 06
|
|
|
|
; First two bytes of each record are the PPU destination address.
|
|
lda TitleScreenPpuRecords,y ; CPU:$C2EF PRG:02EF 20 C8 B9
|
|
sta PPUADDR ; CPU:$C2F2 PRG:02F2 B0 C3 8D
|
|
iny ; CPU:$C2F5 PRG:02F5 06
|
|
|
|
lda TitleScreenPpuRecords,y ; CPU:$C2F6 PRG:02F6 20 C8 B9
|
|
sta PPUADDR ; CPU:$C2F9 PRG:02F9 B0 C3 C9
|
|
iny ; CPU:$C2FC PRG:02FC FF
|
|
|
|
@WritePpuRecord:
|
|
lda TitleScreenPpuRecords,y ; CPU:$C2FD PRG:02FD F0 06 8D
|
|
cmp #$FF ; CPU:$C300 PRG:0300 07 20
|
|
beq @EndPpuRecord ; CPU:$C302 PRG:0302 C8 D0
|
|
|
|
sta PPUDATA ; CPU:$C304 PRG:0304 F3 C8 C6
|
|
iny ; CPU:$C307 PRG:0307 00
|
|
bne @WritePpuRecord ; CPU:$C308 PRG:0308 D0 DD
|
|
|
|
@EndPpuRecord:
|
|
iny ; CPU:$C30A PRG:030A 60
|
|
|
|
dec workPtr0 ; CPU:$C30B PRG:030B AD 02
|
|
bne @NextPpuRecord ; CPU:$C30D PRG:030D 20 A9
|
|
|
|
rts ; CPU:$C30F PRG:030F 23
|
|
|
|
|
|
;==============================================================================
|
|
; $C30B-$C325: Initialize Nametable Attributes
|
|
;
|
|
; Local:
|
|
; Writes $18 bytes from TitleScreenAttributeData to PPU address $23C8.
|
|
;
|
|
; Global:
|
|
; Initializes a portion of the nametable attribute table during startup.
|
|
;==============================================================================
|
|
|
|
InitializeNametableAttributes:
|
|
lda PPUSTATUS ; CPU:$C30B PRG:030B AD 02 20
|
|
|
|
lda #$23 ; CPU:$C30E PRG:030E A9 23
|
|
sta PPUADDR ; CPU:$C310 PRG:0310 8D 06 20
|
|
|
|
lda #$C8 ; CPU:$C313 PRG:0313 A9 C8
|
|
sta PPUADDR ; CPU:$C315 PRG:0315 8D 06 20
|
|
|
|
ldy #$00 ; CPU:$C318 PRG:0318 A0 00
|
|
|
|
@CopyAttributes:
|
|
lda TitleScreenAttributeData,y ; CPU:$C31A PRG:031A B9 5F C4
|
|
sta PPUDATA ; CPU:$C31D PRG:031D 8D 07 20
|
|
|
|
iny ; CPU:$C320 PRG:0320 C8
|
|
cpy #$18 ; CPU:$C321 PRG:0321 C0 18
|
|
bne @CopyAttributes ; CPU:$C323 PRG:0323 D0 F5
|
|
|
|
rts ; CPU:$C325 PRG:0325 60
|
|
|
|
|
|
;==============================================================================
|
|
; $C326-$C3AF: Initial Nametable Tile Block
|
|
;
|
|
; Local:
|
|
; Contains six rows of $17 (23) tile indices. InitializeNametableData copies
|
|
; these rows sequentially to the PPU beginning at $20E5, advancing the PPU
|
|
; destination by $20 after each row.
|
|
;
|
|
; Destination layout:
|
|
; Row 0 -> $20E5-$20FB
|
|
; Row 1 -> $2105-$211B
|
|
; Row 2 -> $2125-$213B
|
|
; Row 3 -> $2145-$215B
|
|
; Row 4 -> $2165-$217B
|
|
; Row 5 -> $2185-$219B
|
|
;
|
|
; Global:
|
|
; Forms a rectangular portion of the initial nametable display constructed
|
|
; during MainEntry. The first and last rows consist primarily of border
|
|
; tiles, while the middle four rows contain the interior graphic/tile data.
|
|
;
|
|
; Notes:
|
|
; Each row is exactly $17 bytes.
|
|
;
|
|
; Tile values are left numeric during this pass. Their visual meanings can
|
|
; be determined later from the CHR-ROM and assigned symbolic tile names if
|
|
; useful.
|
|
;==============================================================================
|
|
|
|
TitleScreenTileBlock:
|
|
; Row 0 -> PPU $20E5-$20FB
|
|
.byte $E4,$E8,$E8,$E8,$E8,$E8,$E8,$E8 ; CPU:$C326 PRG:0326 E4 E8 E8 E8 E8 E8 E8 E8
|
|
.byte $E8,$E8,$E8,$E8,$E8,$E8,$E8,$E8 ; CPU:$C32E PRG:032E E8 E8 E8 E8 E8 E8 E8 E8
|
|
.byte $E8,$E8,$E8,$E8,$E8,$E8,$E5 ; CPU:$C336 PRG:0336 E8 E8 E8 E8 E8 E8 E5
|
|
|
|
; Row 1 -> PPU $2105-$211B
|
|
.byte $EB,$88,$80,$81,$82,$83,$84,$85 ; CPU:$C33D PRG:033D EB 88 80 81 82 83 84 85
|
|
.byte $86,$87,$88,$88,$89,$8A,$8B,$8C ; CPU:$C345 PRG:0345 86 87 88 88 89 8A 8B 8C
|
|
.byte $8D,$8E,$8F,$90,$91,$A3,$E9 ; CPU:$C34D PRG:034D 8D 8E 8F 90 91 A3 E9
|
|
|
|
; Row 2 -> PPU $2125-$213B
|
|
.byte $EB,$88,$92,$93,$94,$95,$96,$97 ; CPU:$C354 PRG:0354 EB 88 92 93 94 95 96 97
|
|
.byte $98,$99,$9A,$9B,$9C,$9D,$9E,$9F ; CPU:$C35C PRG:035C 98 99 9A 9B 9C 9D 9E 9F
|
|
.byte $A0,$A1,$A2,$A3,$A4,$A3,$E9 ; CPU:$C364 PRG:0364 A0 A1 A2 A3 A4 A3 E9
|
|
|
|
; Row 3 -> PPU $2145-$215B
|
|
.byte $EB,$88,$92,$A5,$A6,$A7,$A8,$A9 ; CPU:$C36B PRG:036B EB 88 92 A5 A6 A7 A8 A9
|
|
.byte $AA,$AB,$AC,$AD,$AE,$A3,$AF,$D0 ; CPU:$C373 PRG:0373 AA AB AC AD AE A3 AF D0
|
|
.byte $D1,$D2,$A3,$D3,$A4,$A3,$E9 ; CPU:$C37B PRG:037B D1 D2 A3 D3 A4 A3 E9
|
|
|
|
; Row 4 -> PPU $2165-$217B
|
|
.byte $EB,$88,$D4,$D5,$D6,$D7,$D8,$D9 ; CPU:$C382 PRG:0382 EB 88 D4 D5 D6 D7 D8 D9
|
|
.byte $DA,$DB,$88,$88,$DC,$D7,$DD,$DE ; CPU:$C38A PRG:038A DA DB 88 88 DC D7 DD DE
|
|
.byte $DF,$E0,$E1,$E2,$E3,$A3,$E9 ; CPU:$C392 PRG:0392 DF E0 E1 E2 E3 A3 E9
|
|
|
|
; Row 5 -> PPU $2185-$219B
|
|
.byte $E7,$EA,$EA,$EA,$EA,$EA,$EA,$EA ; CPU:$C399 PRG:0399 E7 EA EA EA EA EA EA EA
|
|
.byte $EA,$EA,$EA,$EA,$EA,$EA,$EA,$EA ; CPU:$C3A1 PRG:03A1 EA EA EA EA EA EA EA EA
|
|
.byte $EA,$EA,$EA,$EA,$EA,$EA,$E6 ; CPU:$C3A9 PRG:03A9 EA EA EA EA EA EA E6
|
|
|
|
;==============================================================================
|
|
; $C3B0-$C43E: Initial Screen PPU Records
|
|
;
|
|
; Local:
|
|
; Nine variable-length PPU write records consumed by InitializeNametableData.
|
|
; Each record has the form:
|
|
;
|
|
; .byte PPU address high
|
|
; .byte PPU address low
|
|
; .byte tile data...
|
|
; .byte $FF
|
|
;
|
|
; InitializeNametableData processes exactly nine records. For each record it
|
|
; loads the two-byte destination into PPUADDR and copies tile values to
|
|
; PPUDATA until the $FF terminator is encountered.
|
|
;
|
|
; Global:
|
|
; Supplies additional initial-screen graphics and text after the main
|
|
; six-row tile block has been installed. These records include player-count
|
|
; selections and copyright/licensing text as represented by the ROM's
|
|
; nametable tile values.
|
|
;
|
|
; Notes:
|
|
; Many values correspond directly to ASCII character codes, but not all do.
|
|
; Preserve the original tile bytes rather than converting these records to
|
|
; assembler strings during this pass.
|
|
;
|
|
; $FF is structural and is not written to PPUDATA.
|
|
;==============================================================================
|
|
|
|
TitleScreenPpuRecords:
|
|
;------------------------------------------------------------------------------
|
|
; Record 0: $C3B0-$C3C7
|
|
; PPU destination: $2065
|
|
; Data length: $15 (21) tiles
|
|
;------------------------------------------------------------------------------
|
|
.byte $20,$65 ; CPU:$C3B0 PRG:03B0 20 65
|
|
.byte $B0,$B3,$B2,$20,$20,$20,$20 ; CPU:$C3B2 PRG:03B2 B0 B3 B2 20 20 20 20
|
|
.byte $B4,$B5,$B6,$B7,$B8,$B9,$BA,$BB ; CPU:$C3B9 PRG:03B9 B4 B5 B6 B7 B8 B9 BA BB
|
|
.byte $20,$20,$20,$B1,$B3,$B2 ; CPU:$C3C1 PRG:03C1 20 20 20 B1 B3 B2
|
|
.byte $FF ; CPU:$C3C7 PRG:03C7 FF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Record 1: $C3C8-$C3D2
|
|
; PPU destination: $220C
|
|
; Data length: $08
|
|
;
|
|
; Visible tile values correspond to:
|
|
; "1 PLAYER"
|
|
;------------------------------------------------------------------------------
|
|
.byte $22,$0C ; CPU:$C3C8 PRG:03C8 22 0C
|
|
.byte $31,$20,$50,$4C,$41,$59,$45,$52 ; CPU:$C3CA PRG:03CA 31 20 50 4C 41 59 45 52
|
|
.byte $FF ; CPU:$C3D2 PRG:03D2 FF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Record 2: $C3D3-$C3DE
|
|
; PPU destination: $224C
|
|
; Data length: $09
|
|
;
|
|
; Visible tile values correspond to:
|
|
; "2 PLAYERS"
|
|
;------------------------------------------------------------------------------
|
|
.byte $22,$4C ; CPU:$C3D3 PRG:03D3 22 4C
|
|
.byte $32,$20,$50,$4C,$41,$59,$45,$52,$53 ; CPU:$C3D5 PRG:03D5 32 20 50 4C 41 59 45 52 53
|
|
.byte $FF ; CPU:$C3DE PRG:03DE FF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Record 3: $C3DF-$C3FC
|
|
; PPU destination: $22E3
|
|
; Data length: $1B (27)
|
|
;
|
|
; Mostly text-like tile data containing the original copyright/date/NAMCO
|
|
; display. Special tile values are retained numerically.
|
|
;------------------------------------------------------------------------------
|
|
.byte $22,$E3 ; CPU:$C3DF PRG:03DF 22 E3
|
|
.byte $54,$4D,$20,$CC,$20,$5D ; CPU:$C3E1 PRG:03E1 54 4D 20 CC 20 5D
|
|
.byte $20,$31,$39,$38,$30 ; CPU:$C3E7 PRG:03E7 20 31 39 38 30
|
|
.byte $20,$31,$39,$39,$33 ; CPU:$C3EC PRG:03EC 20 31 39 39 33
|
|
.byte $20,$4E,$41,$4D,$43,$4F ; CPU:$C3F1 PRG:03F1 20 4E 41 4D 43 4F
|
|
.byte $20,$4C,$54,$44,$5B ; CPU:$C3F7 PRG:03F7 20 4C 54 44 5B
|
|
.byte $FF ; CPU:$C3FC PRG:03FC FF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Record 4: $C3FD-$C411
|
|
; PPU destination: $2327
|
|
; Data length: $12 (18)
|
|
;
|
|
; Mostly text-like tile data containing:
|
|
; NAMCO HOMETEK ... INC
|
|
;
|
|
; Special tile values remain numeric.
|
|
;------------------------------------------------------------------------------
|
|
.byte $23,$27 ; CPU:$C3FD PRG:03FD 23 27
|
|
.byte $4E,$41,$4D,$43,$4F,$20 ; CPU:$C3FF PRG:03FF 4E 41 4D 43 4F 20
|
|
.byte $48,$4F,$4D,$45,$54,$45,$4B ; CPU:$C405 PRG:0405 48 4F 4D 45 54 45 4B
|
|
.byte $CD ; CPU:$C40C PRG:040C CD
|
|
.byte $49,$4E,$43 ; CPU:$C40D PRG:040D 49 4E 43
|
|
.byte $5B ; CPU:$C410 PRG:0410 5B
|
|
.byte $FF ; CPU:$C411 PRG:0411 FF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Record 5: $C412-$C428
|
|
; PPU destination: $2366
|
|
; Data length: $14 (20)
|
|
;
|
|
; Tile values correspond to:
|
|
; "LICENSED BY NINTENDO"
|
|
;------------------------------------------------------------------------------
|
|
.byte $23,$66 ; CPU:$C412 PRG:0412 23 66
|
|
.byte $4C,$49,$43,$45,$4E,$53,$45,$44 ; CPU:$C414 PRG:0414 4C 49 43 45 4E 53 45 44
|
|
.byte $20 ; CPU:$C41C PRG:041C 20
|
|
.byte $42,$59 ; CPU:$C41D PRG:041D 42 59
|
|
.byte $20 ; CPU:$C41F PRG:041F 20
|
|
.byte $4E,$49,$4E,$54,$45,$4E,$44,$4F ; CPU:$C420 PRG:0420 4E 49 4E 54 45 4E 44 4F
|
|
.byte $FF ; CPU:$C428 PRG:0428 FF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Record 6: $C429-$C42D
|
|
; PPU destination: $2293
|
|
; Data length: $02
|
|
;------------------------------------------------------------------------------
|
|
.byte $22,$93 ; CPU:$C429 PRG:0429 22 93
|
|
.byte $CE,$CF ; CPU:$C42B PRG:042B CE CF
|
|
.byte $FF ; CPU:$C42D PRG:042D FF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Record 7: $C42E-$C439
|
|
; PPU destination: $22AC
|
|
; Data length: $09
|
|
;------------------------------------------------------------------------------
|
|
.byte $22,$AC ; CPU:$C42E PRG:042E 22 AC
|
|
.byte $23,$24,$25,$26,$27,$28,$29,$2A,$2B ; CPU:$C430 PRG:0430 23 24 25 26 27 28 29 2A 2B
|
|
.byte $FF ; CPU:$C439 PRG:0439 FF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Record 8: $C43A-$C43E
|
|
; PPU destination: $20FC
|
|
; Data length: $02
|
|
;------------------------------------------------------------------------------
|
|
.byte $20,$FC ; CPU:$C43A PRG:043A 20 FC
|
|
.byte $0E,$0F ; CPU:$C43C PRG:043C 0E 0F
|
|
.byte $FF ; CPU:$C43E PRG:043E FF
|
|
|
|
|
|
;==============================================================================
|
|
; $C43F-$C45E: Initial Palette Data
|
|
;
|
|
; Local:
|
|
; Contains $20 bytes copied to RAM $0299-$02B8 during MainEntry. The first
|
|
; $10 bytes feed PPU palette $3F00-$3F0F and the second $10 bytes feed
|
|
; $3F10-$3F1F through UpdatePalettes.
|
|
;
|
|
; Global:
|
|
; Defines the initial background and sprite palette configuration.
|
|
;
|
|
; Notes:
|
|
; Palette values remain numeric during this pass.
|
|
;==============================================================================
|
|
|
|
TitleScreenPalette:
|
|
|
|
; Background palettes
|
|
.byte $0F,$20,$0F,$06 ; CPU:$C43F PRG:043F 0F 20 0F 06
|
|
.byte $0F,$26,$20,$27 ; CPU:$C443 PRG:0443 0F 26 20 27
|
|
.byte $0F,$06,$0F,$26 ; CPU:$C447 PRG:0447 0F 06 0F 26
|
|
.byte $0F,$06,$20,$26 ; CPU:$C44B PRG:044B 0F 06 20 26
|
|
|
|
; Sprite palettes
|
|
.byte $0F,$27,$20,$06 ; CPU:$C44F PRG:044F 0F 27 20 06
|
|
.byte $0F,$11,$20,$33 ; CPU:$C453 PRG:0453 0F 11 20 33
|
|
.byte $0F,$20,$20,$21 ; CPU:$C457 PRG:0457 0F 20 20 21
|
|
.byte $0F,$09,$20,$17 ; CPU:$C45B PRG:045B 0F 09 20 17
|
|
|
|
|
|
;==============================================================================
|
|
; $C45F-$C476: Initial Nametable Attribute Data
|
|
;
|
|
; Local:
|
|
; Contains $18 attribute bytes copied by InitializeNametableAttributes to
|
|
; PPU $23C8-$23DF.
|
|
;
|
|
; Global:
|
|
; Defines background-palette selections for part of the initial nametable
|
|
; display.
|
|
;
|
|
; Notes:
|
|
; Attribute bytes remain raw during this first pass.
|
|
;==============================================================================
|
|
|
|
TitleScreenAttributeData:
|
|
.byte $80,$A0,$A0,$A0,$A0,$A0,$A0,$00 ; CPU:$C45F PRG:045F 80 A0 A0 A0 A0 A0 A0 00
|
|
.byte $00,$66,$55,$55,$55,$55,$DD,$00 ; CPU:$C467 PRG:0467 00 66 55 55 55 55 DD 00
|
|
.byte $08,$0A,$0A,$0A,$0A,$0A,$0A,$00 ; CPU:$C46F PRG:046F 08 0A 0A 0A 0A 0A 0A 00
|
|
|
|
;==============================================================================
|
|
; $C477-$C506: Player Selection State Handler
|
|
;
|
|
; Local:
|
|
; Handles input and display updates for the player-count selection state.
|
|
;
|
|
; On first entry, identified by $87/$88 both being zero, copies a small
|
|
; display-data sequence from $C507 to RAM beginning at $024B and captures
|
|
; the current controller states for bits $04 and $08.
|
|
;
|
|
; $87/$88 form a 16-bit counter that advances once per frame. When its high
|
|
; byte reaches $02, the counter is reset and the main state changes to $04.
|
|
;
|
|
; During normal processing:
|
|
; - Detects changes to controller bit $04.
|
|
; - When that bit becomes active, toggles $47 between 0 and 1 and changes
|
|
; display data associated with the selected player count.
|
|
; - Detects changes to controller bit $08.
|
|
; - When bit $08 becomes active, clears $48, calls $EEB4, and jumps to
|
|
; GameModeEntry.
|
|
;
|
|
; Global:
|
|
; Handler selected by MainStateHandlerTable when $3F = $02. The surrounding PPU
|
|
; data and controller behavior strongly indicate that this state implements
|
|
; the "1 PLAYER" / "2 PLAYERS" selection screen.
|
|
;
|
|
; If no selection completes within the $87/$88 timeout, execution advances
|
|
; automatically to main state $04.
|
|
;
|
|
; Notes:
|
|
; $50 stores the previous masked state of controller bit $04.
|
|
; $51 stores the previous masked state of controller bit $08.
|
|
;
|
|
; $87/$88 act as a 16-bit frame counter in this state.
|
|
;
|
|
; $47 is toggled between 0 and 1 when the $04 input becomes active. This
|
|
; strongly suggests it represents the current 1-player/2-player selection,
|
|
; but the name should be confirmed through later consumers.
|
|
;
|
|
; $C507 begins an adjacent display-data table consumed during state entry.
|
|
;==============================================================================
|
|
|
|
PlayerSelectionState:
|
|
lda $87 ; CPU:$C477 PRG:0477 A5 87
|
|
ora $88 ; CPU:$C479 PRG:0479 05 88
|
|
bne @AdvanceTimeout ; CPU:$C47B PRG:047B D0 19
|
|
|
|
ldy #$00 ; CPU:$C47D PRG:047D A0 00
|
|
|
|
@InitializeDisplayData:
|
|
lda PlayerCountSelectionDisplayData,y ; CPU:$C47F PRG:047F B9 07 C5
|
|
sta $024B,y ; CPU:$C482 PRG:0482 99 4B 02
|
|
iny ; CPU:$C485 PRG:0485 C8
|
|
cmp #$FF ; CPU:$C486 PRG:0486 C9 FF
|
|
bne @InitializeDisplayData ; CPU:$C488 PRG:0488 D0 F5
|
|
|
|
lda currentInput ; CPU:$C48A PRG:048A A5 4D
|
|
and #$04 ; CPU:$C48C PRG:048C 29 04
|
|
sta pacmanRequestedDirection ; CPU:$C48E PRG:048E 85 50
|
|
|
|
lda currentInput ; CPU:$C490 PRG:0490 A5 4D
|
|
and #$08 ; CPU:$C492 PRG:0492 29 08
|
|
sta pacmanDirection ; CPU:$C494 PRG:0494 85 51
|
|
|
|
@AdvanceTimeout:
|
|
clc ; CPU:$C496 PRG:0496 18
|
|
lda #$01 ; CPU:$C497 PRG:0497 A9 01
|
|
adc $87 ; CPU:$C499 PRG:0499 65 87
|
|
sta $87 ; CPU:$C49B PRG:049B 85 87
|
|
|
|
lda $88 ; CPU:$C49D PRG:049D A5 88
|
|
adc #$00 ; CPU:$C49F PRG:049F 69 00
|
|
sta $88 ; CPU:$C4A1 PRG:04A1 85 88
|
|
|
|
cmp #$02 ; CPU:$C4A3 PRG:04A3 C9 02
|
|
bne @CheckSelectionInput ; CPU:$C4A5 PRG:04A5 D0 0B
|
|
|
|
lda #$00 ; CPU:$C4A7 PRG:04A7 A9 00
|
|
sta $87 ; CPU:$C4A9 PRG:04A9 85 87
|
|
|
|
lda #$04 ; CPU:$C4AB PRG:04AB A9 04
|
|
sta gameState ; CPU:$C4AD PRG:04AD 85 3F
|
|
|
|
jmp MainDispatchLoop ; CPU:$C4AF PRG:04AF 4C 50 C2
|
|
|
|
@CheckSelectionInput:
|
|
lda currentInput ; CPU:$C4B2 PRG:04B2 A5 4D
|
|
and #$04 ; CPU:$C4B4 PRG:04B4 29 04
|
|
cmp pacmanRequestedDirection ; CPU:$C4B6 PRG:04B6 C5 50
|
|
beq @CheckConfirmInput ; CPU:$C4B8 PRG:04B8 F0 2F
|
|
|
|
sta pacmanRequestedDirection ; CPU:$C4BA PRG:04BA 85 50
|
|
|
|
lda #$00 ; CPU:$C4BC PRG:04BC A9 00
|
|
sta $88 ; CPU:$C4BE PRG:04BE 85 88
|
|
|
|
lda #$01 ; CPU:$C4C0 PRG:04C0 A9 01
|
|
sta $87 ; CPU:$C4C2 PRG:04C2 85 87
|
|
|
|
lda pacmanRequestedDirection ; CPU:$C4C4 PRG:04C4 A5 50
|
|
beq @CheckConfirmInput ; CPU:$C4C6 PRG:04C6 F0 21
|
|
|
|
ldx #$00 ; CPU:$C4C8 PRG:04C8 A2 00
|
|
|
|
inc activePlayerFlag ; CPU:$C4CA PRG:04CA E6 47
|
|
lda activePlayerFlag ; CPU:$C4CC PRG:04CC A5 47
|
|
and #$01 ; CPU:$C4CE PRG:04CE 29 01
|
|
sta activePlayerFlag ; CPU:$C4D0 PRG:04D0 85 47
|
|
beq @UseFirstSelectionData ; CPU:$C4D2 PRG:04D2 F0 01
|
|
|
|
inx ; CPU:$C4D4 PRG:04D4 E8
|
|
|
|
@UseFirstSelectionData:
|
|
lda $C50F,x ; CPU:$C4D5 PRG:04D5 BD 0F C5
|
|
sta $024D ; CPU:$C4D8 PRG:04D8 8D 4D 02
|
|
|
|
lda $C510,x ; CPU:$C4DB PRG:04DB BD 10 C5
|
|
sta $0251 ; CPU:$C4DE PRG:04DE 8D 51 02
|
|
|
|
lda #$22 ; CPU:$C4E1 PRG:04E1 A9 22
|
|
sta $024B ; CPU:$C4E3 PRG:04E3 8D 4B 02
|
|
|
|
jmp MainDispatchLoop ; CPU:$C4E6 PRG:04E6 4C 50 C2
|
|
|
|
@CheckConfirmInput:
|
|
lda currentInput ; CPU:$C4E9 PRG:04E9 A5 4D
|
|
and #$08 ; CPU:$C4EB PRG:04EB 29 08
|
|
cmp pacmanDirection ; CPU:$C4ED PRG:04ED C5 51
|
|
bne @ConfirmStateChanged ; CPU:$C4EF PRG:04EF D0 03
|
|
|
|
jmp MainDispatchLoop ; CPU:$C4F1 PRG:04F1 4C 50 C2
|
|
|
|
@ConfirmStateChanged:
|
|
sta pacmanDirection ; CPU:$C4F4 PRG:04F4 85 51
|
|
|
|
lda pacmanDirection ; CPU:$C4F6 PRG:04F6 A5 51
|
|
bne @ConfirmPressed ; CPU:$C4F8 PRG:04F8 D0 03
|
|
|
|
jmp MainDispatchLoop ; CPU:$C4FA PRG:04FA 4C 50 C2
|
|
|
|
@ConfirmPressed:
|
|
lda #$00 ; CPU:$C4FD PRG:04FD A9 00
|
|
sta gameplaySuspended ; CPU:$C4FF PRG:04FF 85 48
|
|
|
|
jsr $EEB4 ; CPU:$C501 PRG:0501 20 B4 EE
|
|
|
|
jmp GameModeEntry ; CPU:$C504 PRG:0504 4C 54 CA
|
|
|
|
;==============================================================================
|
|
; $C507-$C511: Player Selection Display Data
|
|
;
|
|
; Local:
|
|
; Contains display-update data used by PlayerSelectionState.
|
|
;
|
|
; The first eight bytes, $C507-$C50E, are copied to RAM beginning at $024B
|
|
; when the player-selection state is first entered. The copy terminates after
|
|
; the $FF byte has also been stored.
|
|
;
|
|
; The final three bytes, $C50F-$C511, form an overlapping pair table used
|
|
; when $47 toggles between its two selection values:
|
|
;
|
|
; X = 0 -> $5C, $20
|
|
; X = 1 -> $20, $5C
|
|
;
|
|
; These values are written to $024D and $0251, respectively.
|
|
;
|
|
; Global:
|
|
; Provides the display-update data for the "1 PLAYER" / "2 PLAYERS"
|
|
; selection state. The overlapping three-byte table moves a $5C tile
|
|
; between two display positions while placing $20 at the other position.
|
|
;
|
|
; Notes:
|
|
; $5C appears to be the selection-marker tile and $20 appears to clear the
|
|
; alternate position. Their exact visual appearance can be confirmed later
|
|
; against CHR-ROM.
|
|
;
|
|
; $FF terminates the initialization data copied to $024B.
|
|
;==============================================================================
|
|
|
|
PlayerCountSelectionDisplayData:
|
|
.byte $22,$0A,$5C,$00 ; CPU:$C507 PRG:0507 22 0A 5C 00
|
|
.byte $22,$4A,$20,$FF ; CPU:$C50B PRG:050B 22 4A 20 FF
|
|
|
|
PlayerCountSelectionMarkerTiles:
|
|
.byte $5C,$20,$5C ; CPU:$C50F PRG:050F 5C 20 5C
|
|
|
|
|
|
;==============================================================================
|
|
; $C512-$C52D: State $04 Handler / Substate Dispatcher
|
|
;
|
|
; Local:
|
|
; Handles the top-level processing for main state $04.
|
|
;
|
|
; First checks controller-1 bits $0C. If either bit is active, changes the
|
|
; main state back to $02 and jumps to MainEntry, causing the main display
|
|
; initialization sequence to run again.
|
|
;
|
|
; Otherwise uses $87 as a byte offset into a table of 16-bit handler
|
|
; addresses beginning at $C52E. The selected address is placed in $10/$11
|
|
; and execution jumps to it indirectly.
|
|
;
|
|
; Global:
|
|
; This is the fourth major handler in MainStateHandlerTable. Unlike states $00,
|
|
; $02, and $06, state $04 contains its own secondary state machine driven
|
|
; by $87.
|
|
;
|
|
; $87 therefore has a different role depending on the current main state.
|
|
; In state $02 it participated in a 16-bit frame counter with $88. Here it
|
|
; acts as the byte offset into a secondary dispatch table.
|
|
;
|
|
; Notes:
|
|
; $87 appears to take even values because it indexes packed 16-bit addresses
|
|
; directly rather than multiplying a state number by two.
|
|
;
|
|
; The substate table begins immediately afterward at $C52E.
|
|
; We leave the individual substate handlers for following passes.
|
|
;==============================================================================
|
|
|
|
State04Handler:
|
|
lda currentInput ; CPU:$C512 PRG:0512 A5 4D
|
|
and #$0C ; CPU:$C514 PRG:0514 29 0C
|
|
beq @DispatchSubstate ; CPU:$C516 PRG:0516 F0 07
|
|
|
|
lda #$02 ; CPU:$C518 PRG:0518 A9 02
|
|
sta gameState ; CPU:$C51A PRG:051A 85 3F
|
|
|
|
jmp MainEntry ; CPU:$C51C PRG:051C 4C E7 C1
|
|
|
|
@DispatchSubstate:
|
|
ldy $87 ; CPU:$C51F PRG:051F A4 87
|
|
|
|
lda State04SubstateTable,y ; CPU:$C521 PRG:0521 B9 2E C5
|
|
sta dispatchVector ; CPU:$C524 PRG:0524 85 10
|
|
|
|
lda State04SubstateTable+1,y ; CPU:$C526 PRG:0526 B9 2F C5
|
|
sta dispatchVector+1 ; CPU:$C529 PRG:0529 85 11 6C
|
|
|
|
jmp ($0010) ; CPU:$C52C PRG:052C 10 00 46 C5 73
|
|
|
|
;==============================================================================
|
|
; $C52E-$C545: State $04 Substate Dispatch Table
|
|
;
|
|
; Local:
|
|
; Twelve 16-bit handler addresses selected by State04Handler using $87 as
|
|
; a direct byte offset.
|
|
;
|
|
; Valid offsets observed from the table structure are:
|
|
; $00,$02,$04,$06,$08,$0A,$0C,$0E,$10,$12,$14,$16
|
|
;
|
|
; Global:
|
|
; Defines the secondary state machine used while the top-level game state
|
|
; is $04. Several intermediate substates deliberately share the same handler
|
|
; at $C573.
|
|
;
|
|
; Notes:
|
|
; Later code advances $87 using two INC instructions, confirming that $87
|
|
; is a byte offset into this table rather than an ordinal state number.
|
|
;==============================================================================
|
|
|
|
State04SubstateTable:
|
|
.word State04Initialize ; $00 ; CPU:$C52E PRG:052E 46 C5
|
|
.word State04TimedSubstate ; $02 ; CPU:$C530 PRG:0530 73 C5
|
|
.word State04TimedSubstate ; $04 ; CPU:$C532 PRG:0532 73 C5
|
|
.word State04TimedSubstate ; $06 ; CPU:$C534 PRG:0534 73 C5
|
|
.word State04TimedSubstate ; $08 ; CPU:$C536 PRG:0536 73 C5
|
|
.word State04TimedSubstate ; $0A ; CPU:$C538 PRG:0538 73 C5
|
|
.word State04TimedSubstate ; $0C ; CPU:$C53A PRG:053A 73 C5
|
|
.word State04TimedSubstate ; $0E ; CPU:$C53C PRG:053C 73 C5
|
|
.word State04TimedSubstate ; $10 ; CPU:$C53E PRG:053E 73 C5
|
|
.word State04TimedSubstate ; $12 ; CPU:$C540 PRG:0540 73 C5
|
|
.word State04LongDelay ; $14 ; CPU:$C542 PRG:0542 89 C5
|
|
.word State04FinalPhase ; $16 ; CPU:$C544 PRG:0544 92 C7
|
|
|
|
;==============================================================================
|
|
; $C546-$C572: State $04 Initialization Substate
|
|
;
|
|
; Local:
|
|
; Performs the one-time initialization for state $04 when substate offset
|
|
; $87 is $00.
|
|
;
|
|
; First synchronizes with NMI using $40. It then sets PPUCTRL/$43 to $08,
|
|
; disables rendering through PPUMASK, clears $88, and calls three setup
|
|
; routines:
|
|
;
|
|
; $C5D8
|
|
; $C608
|
|
; SetSelectionFlagAndContinue
|
|
;
|
|
; After setup completes, advances $87 by two, selecting substate $02 on the
|
|
; following frame. PPUCTRL/$43 are then changed to $88 before returning to
|
|
; MainDispatchLoop.
|
|
;
|
|
; Global:
|
|
; Entry/initialization substate for the secondary state machine used by
|
|
; main state $04. It prepares the display and state-specific data before
|
|
; handing execution to the shared $C573 substate handler.
|
|
;
|
|
; Notes:
|
|
; $40 continues to act as the foreground/NMI synchronization flag.
|
|
;
|
|
; $87 is a byte offset into State04SubstateTable. The two INC instructions
|
|
; deliberately advance it from $00 to $02.
|
|
;
|
|
; The three called routines remain structurally named by address until they
|
|
; are decoded. $C5D8 and $C608 appear to perform direct PPU initialization,
|
|
; while SetSelectionFlagAndContinue operates on state/display data.
|
|
;==============================================================================
|
|
|
|
State04Initialize:
|
|
lda #$01 ; CPU:$C546 PRG:0546 A9 01
|
|
sta $40 ; CPU:$C548 PRG:0548 85 40
|
|
|
|
@WaitForNmi:
|
|
lda $40 ; CPU:$C54A PRG:054A A5 40
|
|
bne @WaitForNmi ; CPU:$C54C PRG:054C D0 FC
|
|
|
|
lda #$08 ; CPU:$C54E PRG:054E A9 08
|
|
sta PPUCTRL ; CPU:$C550 PRG:0550 8D 00 20
|
|
sta ppuCtrlShadow ; CPU:$C553 PRG:0553 85 43
|
|
|
|
lda #$00 ; CPU:$C555 PRG:0555 A9 00
|
|
sta PPUMASK ; CPU:$C557 PRG:0557 8D 01 20
|
|
sta $88 ; CPU:$C55A PRG:055A 85 88
|
|
|
|
jsr $C5D8 ; CPU:$C55C PRG:055C 20 D8 C5
|
|
jsr InitializeState04PpuData ; CPU:$C55F PRG:055F 20 08 C6
|
|
jsr LoadState04DisplayData ; CPU:$C562 PRG:0562 20 A6 C5
|
|
|
|
inc $87 ; CPU:$C565 PRG:0565 E6 87
|
|
inc $87 ; CPU:$C567 PRG:0567 E6 87
|
|
|
|
lda #$88 ; CPU:$C569 PRG:0569 A9 88
|
|
sta PPUCTRL ; CPU:$C56B PRG:056B 8D 00 20
|
|
sta ppuCtrlShadow ; CPU:$C56E PRG:056E 85 43
|
|
|
|
jmp MainDispatchLoop ; CPU:$C570 PRG:0570 4C 50 C2
|
|
|
|
;==============================================================================
|
|
; $C573-$C588: State $04 Shared Timed Substate Handler
|
|
;
|
|
; Local:
|
|
; Advances $88 once per frame. At $30 frames, clears $88, invokes the
|
|
; state-$04 display-data helper, and advances $87 by two to the next
|
|
; secondary state.
|
|
;
|
|
; Global:
|
|
; Shared timing handler used by state-$04 substates $02-$12.
|
|
;
|
|
; Notes:
|
|
; LoadState04DisplayData is kept as a raw address temporarily to guarantee
|
|
; byte identity while the overlapping $C5A6-$C5D8 region is being resolved.
|
|
;==============================================================================
|
|
|
|
State04TimedSubstate:
|
|
inc $88 ; CPU:$C573 PRG:0573 E6 88
|
|
|
|
lda $88 ; CPU:$C575 PRG:0575 A5 88
|
|
cmp #$30 ; CPU:$C577 PRG:0577 C9 30
|
|
bne @ReturnToMainLoop ; CPU:$C579 PRG:0579 D0 0B
|
|
|
|
lda #$00 ; CPU:$C57B PRG:057B A9 00
|
|
sta $88 ; CPU:$C57D PRG:057D 85 88
|
|
|
|
jsr $C5A6 ; CPU:$C57F PRG:057F 20 A6 C5
|
|
|
|
inc $87 ; CPU:$C582 PRG:0582 E6 87
|
|
inc $87 ; CPU:$C584 PRG:0584 E6 87
|
|
|
|
@ReturnToMainLoop:
|
|
jmp MainDispatchLoop ; CPU:$C586 PRG:0586 4C 50 C2
|
|
|
|
;==============================================================================
|
|
; $C589-$C59F: State $04 Long Delay Substate
|
|
;
|
|
; Local:
|
|
; Increments $88 once per frame and waits until it reaches $80.
|
|
;
|
|
; While $88 is not $80, returns to MainDispatchLoop.
|
|
;
|
|
; When $88 reaches $80:
|
|
; - Advances $87 by two, selecting substate $16.
|
|
; - Clears $88.
|
|
; - Returns to MainDispatchLoop.
|
|
;
|
|
; Global:
|
|
; Implements substate $14 of the state $04 secondary state machine. It
|
|
; follows the series of $30-frame substates handled by
|
|
; State04TimedSubstate and introduces a longer delay before entering the
|
|
; final known substate at $16.
|
|
;
|
|
; Notes:
|
|
; $88 is the frame counter for this substate.
|
|
; $87 is the byte offset into State04SubstateTable.
|
|
;
|
|
; Unlike substates $02-$12, reaching the timeout here does not call
|
|
; SetSelectionFlagAndContinue. It simply advances from substate $14 to $16.
|
|
;==============================================================================
|
|
|
|
State04LongDelay:
|
|
inc $88 ; CPU:$C589 PRG:0589 E6 88
|
|
|
|
lda $88 ; CPU:$C58B PRG:058B A5 88
|
|
cmp #$80 ; CPU:$C58D PRG:058D C9 80
|
|
beq @AdvanceSubstate ; CPU:$C58F PRG:058F F0 03
|
|
|
|
jmp MainDispatchLoop ; CPU:$C591 PRG:0591 4C 50 C2
|
|
|
|
@AdvanceSubstate:
|
|
inc $87 ; CPU:$C594 PRG:0594 E6 87
|
|
inc $87 ; CPU:$C596 PRG:0596 E6 87
|
|
|
|
lda #$00 ; CPU:$C598 PRG:0598 A9 00
|
|
sta $88 ; CPU:$C59A PRG:059A 85 88
|
|
|
|
jmp MainDispatchLoop ; CPU:$C59C PRG:059C 4C 50 C2
|
|
|
|
|
|
;==============================================================================
|
|
; $C59F-$C5A5: Select Alternate Player Mode and Continue
|
|
;
|
|
; Local:
|
|
; Sets $47 to $01 and tail-jumps to the routine at GameModeEntry.
|
|
;
|
|
; Global:
|
|
; Forces the same $47 flag that PlayerSelectionState toggles between $00
|
|
; and $01, then transfers control to GameModeEntry. This strongly links the routine
|
|
; to the player-count/player-mode selection logic.
|
|
;
|
|
; The exact global purpose of GameModeEntry has not yet been decoded, so the routine
|
|
; and $47 remain conservatively named during this pass.
|
|
;
|
|
; Notes:
|
|
; There is no RTS. Control is permanently transferred to GameModeEntry.
|
|
;
|
|
; $47 is known to be constrained to 0/1 by PlayerSelectionState and is also
|
|
; consulted by NmiHandler when selecting controller input and constructing
|
|
; PPUCTRL. We should trace GameModeEntry before assigning $47 a final semantic name.
|
|
;==============================================================================
|
|
|
|
SetSelectionFlagAndContinue:
|
|
lda #$01 ; CPU:$C59F PRG:059F A9 01
|
|
sta activePlayerFlag ; CPU:$C5A1 PRG:05A1 85 47
|
|
jmp GameModeEntry ; CPU:$C5A3 PRG:05A3 4C 54 CA
|
|
|
|
|
|
;==============================================================================
|
|
; $C5A6-$C5D7: State $04 Display Data Loader
|
|
;
|
|
; Local:
|
|
; Uses $87 as a byte offset into a pointer table at $C687. The selected
|
|
; $FF-terminated stream is copied through $00/$01 into RAM beginning at
|
|
; $024B, including the $FF terminator.
|
|
;
|
|
; The byte following the terminator controls an optional secondary copy:
|
|
; nonzero -> return
|
|
; zero -> copy 16 bytes using a substate-derived offset
|
|
;
|
|
; Global:
|
|
; Supplies update/display data as the state-$04 secondary state machine
|
|
; progresses.
|
|
;
|
|
; Notes:
|
|
; $00/$01 form the temporary source pointer.
|
|
;==============================================================================
|
|
|
|
LoadState04DisplayData:
|
|
ldy $87 ; CPU:$C5A6 PRG:05A6 A4 87
|
|
|
|
lda CharacterIntroDisplayDataTable,y ; CPU:$C5A8 PRG:05A8 B9 87 C6
|
|
sta workPtr0 ; CPU:$C5AB PRG:05AB 85 00
|
|
|
|
lda CharacterIntroDisplayDataTable+1,y ; CPU:$C5AD PRG:05AD B9 88 C6
|
|
sta workPtr0+1 ; CPU:$C5B0 PRG:05B0 85 01 A0
|
|
|
|
ldy #$00 ; CPU:$C5B3 PRG:05B3 00 B1
|
|
|
|
@CopyDisplayData:
|
|
lda (workPtr0),y ; CPU:$C5B5 PRG:05B5 00 99
|
|
sta $024B,y ; CPU:$C5B7 PRG:05B7 4B 02 C8
|
|
|
|
iny ; CPU:$C5BA PRG:05BA C9
|
|
cmp #$FF ; CPU:$C5BB PRG:05BB FF D0
|
|
bne @CopyDisplayData ; CPU:$C5BD PRG:05BD F6 B1
|
|
|
|
lda (workPtr0),y ; CPU:$C5BF PRG:05BF 00 F0
|
|
beq @SecondaryCopy ; CPU:$C5C1 PRG:05C1 01 60
|
|
|
|
rts ; CPU:$C5C3 PRG:05C3 A5
|
|
|
|
@SecondaryCopy:
|
|
lda $87 ; CPU:$C5C4 PRG:05C4 87 38
|
|
sec ; CPU:$C5C6 PRG:05C6 E9
|
|
sbc #$02 ; CPU:$C5C7 PRG:05C7 02 0A
|
|
asl ; CPU:$C5C9 PRG:05C9 0A
|
|
asl ; CPU:$C5CA PRG:05CA A8
|
|
tay ; CPU:$C5CB PRG:05CB A2
|
|
|
|
ldx #$10 ; CPU:$C5CC PRG:05CC 10 B9
|
|
|
|
@CopySecondaryData:
|
|
lda CharacterIntroSpriteData,y ; CPU:$C5CE PRG:05CE 2E C7 99
|
|
sta $0760,y ; CPU:$C5D1 PRG:05D1 60 07 C8
|
|
|
|
iny ; CPU:$C5D4 PRG:05D4 CA
|
|
dex ; CPU:$C5D5 PRG:05D5 D0
|
|
bne @CopySecondaryData ; CPU:$C5D6 PRG:05D6 F6 60
|
|
|
|
rts ; CPU:$C5D8 PRG:05D8 A9
|
|
|
|
;==============================================================================
|
|
; $C5D8-$C607: Initialize Playfield Area
|
|
;
|
|
; Local:
|
|
; Sets the PPU destination to $20C0 and fills 24 complete 32-tile nametable
|
|
; rows.
|
|
;
|
|
; Each row consists of:
|
|
; 2 x $2D
|
|
; 28 x $20
|
|
; 2 x $2D
|
|
;
|
|
; The inner count at $01 is reinitialized to $1C at the beginning of every
|
|
; row. $00 begins at $17 and counts rows down through zero.
|
|
;
|
|
; Global:
|
|
; Called during State04Initialize with rendering disabled. Builds the large
|
|
; rectangular background area used by state $04.
|
|
;
|
|
; Notes:
|
|
; The BPL at $C605 intentionally returns to $C5E6, not directly to the first
|
|
; tile write. This reloads $01 with $1C for every row and must be preserved
|
|
; for byte identity.
|
|
;==============================================================================
|
|
|
|
InitializePlayfieldArea:
|
|
lda #$20 ; CPU:$C5D8 PRG:05D8 A9 20
|
|
sta PPUADDR ; CPU:$C5DA PRG:05DA 8D 06 20
|
|
|
|
lda #$C0 ; CPU:$C5DD PRG:05DD A9 C0
|
|
sta PPUADDR ; CPU:$C5DF PRG:05DF 8D 06 20
|
|
|
|
lda #$17 ; CPU:$C5E2 PRG:05E2 A9 17
|
|
sta workPtr0 ; CPU:$C5E4 PRG:05E4 85 00
|
|
|
|
@NextRow:
|
|
lda #$1C ; CPU:$C5E6 PRG:05E6 A9 1C
|
|
sta workPtr0+1 ; CPU:$C5E8 PRG:05E8 85 01 A9
|
|
|
|
lda #$2D ; CPU:$C5EB PRG:05EB 2D 8D
|
|
sta PPUDATA ; CPU:$C5ED PRG:05ED 07 20 8D
|
|
sta PPUDATA ; CPU:$C5F0 PRG:05F0 07 20 A9
|
|
|
|
lda #$20 ; CPU:$C5F3 PRG:05F3 20 8D
|
|
|
|
@ClearRowInterior:
|
|
sta PPUDATA ; CPU:$C5F5 PRG:05F5 07 20 C6
|
|
dec workPtr0+1 ; CPU:$C5F8 PRG:05F8 01 D0
|
|
bne @ClearRowInterior ; CPU:$C5FA PRG:05FA F9 A9
|
|
|
|
lda #$2D ; CPU:$C5FC PRG:05FC 2D 8D
|
|
sta PPUDATA ; CPU:$C5FE PRG:05FE 07 20 8D
|
|
sta PPUDATA ; CPU:$C601 PRG:0601 07 20 C6
|
|
|
|
dec workPtr0 ; CPU:$C604 PRG:0604 00 10
|
|
bpl @NextRow ; CPU:$C606 PRG:0606 DF 60
|
|
|
|
rts ; CPU:$C608 PRG:0608 A9
|
|
|
|
;==============================================================================
|
|
; $C608-$C666: Initialize State $04 PPU Data
|
|
;
|
|
; Local:
|
|
; Performs three groups of PPU initialization:
|
|
;
|
|
; 1. Writes $24 (36) bytes from $C76E to PPUDATA beginning at PPU $23C8.
|
|
;
|
|
; 2. Processes a sequence of variable-length PPU write records beginning
|
|
; at $C69B. Each record contains a two-byte PPU destination followed by
|
|
; data bytes terminated by $FF.
|
|
;
|
|
; 3. Writes a full $20-byte palette table from CharacterIntroPalette to PPU palette RAM
|
|
; beginning at $3F00.
|
|
;
|
|
; After the palette transfer, resets PPUADDR away from palette space and
|
|
; returns.
|
|
;
|
|
; Global:
|
|
; Called by State04Initialize while rendering is disabled. Together with
|
|
; InitializePlayfieldArea, this routine constructs the PPU state needed by
|
|
; the state-$04 display sequence.
|
|
;
|
|
; Notes:
|
|
; Unlike InitializeNametableData, the PPU-record loop at $C61D does not
|
|
; contain an explicit record count. The encoded data and Y wrap behavior
|
|
; determine when processing terminates. We should decode $C69B before
|
|
; assigning a more precise description to that stream.
|
|
;
|
|
; CharacterIntroPalette begins the 32-byte palette table.
|
|
; $C76E is the source of the 36-byte attribute-data transfer.
|
|
;==============================================================================
|
|
|
|
InitializeState04PpuData:
|
|
; Set PPU destination to $23C8.
|
|
lda #$23 ; CPU:$C608 PRG:0608 A9 23
|
|
sta PPUADDR ; CPU:$C60A PRG:060A 8D 06 20
|
|
|
|
lda #$C8 ; CPU:$C60D PRG:060D A9 C8
|
|
sta PPUADDR ; CPU:$C60F PRG:060F 8D 06 20
|
|
|
|
; Copy $24 bytes of attribute data.
|
|
ldy #$00 ; CPU:$C612 PRG:0612 A0 00
|
|
|
|
@CopyAttributeData:
|
|
lda $C76E,y ; CPU:$C614 PRG:0614 B9 6E C7
|
|
sta PPUDATA ; CPU:$C617 PRG:0617 8D 07 20
|
|
|
|
iny ; CPU:$C61A PRG:061A C8
|
|
cpy #$24 ; CPU:$C61B PRG:061B C0 24
|
|
bne @CopyAttributeData ; CPU:$C61D PRG:061D D0 F5
|
|
|
|
; Process encoded PPU write data from $C69B.
|
|
ldy #$00 ; CPU:$C61F PRG:061F A0 00
|
|
|
|
@NextPpuRecord:
|
|
lda CharacterNicknameHeaderData,y ; CPU:$C621 PRG:0621 B9 9B C6
|
|
sta PPUADDR ; CPU:$C624 PRG:0624 8D 06 20
|
|
iny ; CPU:$C627 PRG:0627 C8
|
|
|
|
lda CharacterNicknameHeaderData,y ; CPU:$C628 PRG:0628 B9 9B C6
|
|
sta PPUADDR ; CPU:$C62B PRG:062B 8D 06 20
|
|
iny ; CPU:$C62E PRG:062E C8
|
|
|
|
@CopyPpuRecord:
|
|
lda CharacterNicknameHeaderData,y ; CPU:$C62F PRG:062F B9 9B C6
|
|
cmp #$FF ; CPU:$C632 PRG:0632 C9 FF
|
|
beq @EndPpuRecord ; CPU:$C634 PRG:0634 F0 06
|
|
|
|
sta PPUDATA ; CPU:$C636 PRG:0636 8D 07 20
|
|
iny ; CPU:$C639 PRG:0639 C8
|
|
bne @CopyPpuRecord ; CPU:$C63A PRG:063A D0 F3
|
|
|
|
@EndPpuRecord:
|
|
lda PPUSTATUS ; CPU:$C63C PRG:063C AD 02 20
|
|
|
|
; Upload the complete 32-byte palette directly.
|
|
lda #$3F ; CPU:$C63F PRG:063F A9 3F
|
|
sta PPUADDR ; CPU:$C641 PRG:0641 8D 06 20
|
|
|
|
lda #$00 ; CPU:$C644 PRG:0644 A9 00
|
|
sta PPUADDR ; CPU:$C646 PRG:0646 8D 06 20
|
|
|
|
ldy #$00 ; CPU:$C649 PRG:0649 A0 00
|
|
|
|
@CopyPalette:
|
|
lda CharacterIntroPalette,y ; CPU:$C64B PRG:064B B9 67 C6
|
|
sta PPUDATA ; CPU:$C64E PRG:064E 8D 07 20
|
|
|
|
iny ; CPU:$C651 PRG:0651 C8
|
|
cpy #$20 ; CPU:$C652 PRG:0652 C0 20
|
|
bne @CopyPalette ; CPU:$C654 PRG:0654 D0 F5
|
|
|
|
; Reset the PPU address following palette access.
|
|
lda #$3F ; CPU:$C656 PRG:0656 A9 3F
|
|
sta PPUADDR ; CPU:$C658 PRG:0658 8D 06 20
|
|
|
|
lda #$00 ; CPU:$C65B PRG:065B A9 00
|
|
sta PPUADDR ; CPU:$C65D PRG:065D 8D 06 20
|
|
sta PPUADDR ; CPU:$C660 PRG:0660 8D 06 20
|
|
sta PPUADDR ; CPU:$C663 PRG:0663 8D 06 20
|
|
|
|
rts ; CPU:$C666 PRG:0666 60
|
|
|
|
;==============================================================================
|
|
; $C667-$C686: State $04 Palette Data
|
|
;
|
|
; Local:
|
|
; Complete 32-byte palette uploaded directly to PPU $3F00-$3F1F by
|
|
; InitializeState04PpuData.
|
|
;
|
|
; Global:
|
|
; Defines the background and sprite colors used by the state-$04 display.
|
|
;
|
|
; Notes:
|
|
; First 16 bytes are the four background palettes.
|
|
; Second 16 bytes are the four sprite palettes.
|
|
;==============================================================================
|
|
CharacterIntroPalette:
|
|
; Background palettes
|
|
.byte $0F,$20,$0F,$06 ; CPU:$C667 PRG:0667 0F 20 0F 06
|
|
.byte $0F,$06,$0F,$33 ; CPU:$C66B PRG:066B 0F 06 0F 33
|
|
.byte $0F,$33,$0F,$27 ; CPU:$C66F PRG:066F 0F 33 0F 27
|
|
.byte $0F,$17,$0F,$21 ; CPU:$C673 PRG:0673 0F 17 0F 21
|
|
|
|
; Sprite palettes
|
|
.byte $0F,$27,$20,$06 ; CPU:$C677 PRG:0677 0F 27 20 06
|
|
.byte $0F,$11,$20,$33 ; CPU:$C67B PRG:067B 0F 11 20 33
|
|
.byte $0F,$20,$20,$21 ; CPU:$C67F PRG:067F 0F 20 20 21
|
|
.byte $0F,$09,$20,$17 ; CPU:$C683 PRG:0683 0F 09 20 17
|
|
|
|
;==============================================================================
|
|
; $C687-$C69A: State $04 Display Data Pointer Table
|
|
;
|
|
; Local:
|
|
; Contains ten 16-bit pointers to display/update data streams. The helper at
|
|
; $C5A6 uses $87 directly as a byte offset into this table:
|
|
;
|
|
; ldy $87
|
|
; lda CharacterIntroDisplayDataTable,y
|
|
; sta $00
|
|
; lda CharacterIntroDisplayDataTable+1,y
|
|
; sta $01
|
|
;
|
|
; The valid table offsets are therefore:
|
|
; $00,$02,$04,$06,$08,$0A,$0C,$0E,$10,$12
|
|
;
|
|
; Global:
|
|
; Selects the display data used as the state-$04 secondary state machine
|
|
; progresses. State04Initialize uses offset $00, while the successive timed
|
|
; substates use offsets $02 through $12.
|
|
;
|
|
; Notes:
|
|
; Each target begins a $FF-terminated display/update stream copied into RAM
|
|
; at $024B by LoadState04DisplayData.
|
|
;
|
|
; Several streams contain an additional control byte following $FF. The
|
|
; helper uses that byte to decide whether to perform its secondary copy.
|
|
;==============================================================================
|
|
|
|
CharacterIntroDisplayDataTable:
|
|
.word CharacterNicknameHeaderData ; $87 = $00 Character; NICKNAME ; CPU:$C687 PRG:0687 9B C6
|
|
.word ShadowNameData ; $87 = $02 : SHADOW ; CPU:$C689 PRG:0689 B3 C6
|
|
.word BlinkyNameData ; $87 = $04 _BLINKY_ ; CPU:$C68B PRG:068B BE C6
|
|
.word SpeedyNameData ; $87 = $06 : SPEEDY ; CPU:$C68D PRG:068D C9 C6
|
|
.word PinkyNameData ; $87 = $08 _PINKY_ ; CPU:$C68F PRG:068F D4 C6
|
|
.word CharacterIntroGraphicData0 ; $87 = $0A ; CPU:$C691 PRG:0691 DE C6
|
|
.word CharacterIntroGraphicData1 ; $87 = $0C ; CPU:$C693 PRG:0693 EA C6
|
|
.word PokeyNameData ; $87 = $0E ; CPU:$C695 PRG:0695 F3 C6
|
|
.word ClydeNameData ; $87 = $10 ; CPU:$C697 PRG:0697 FD C6
|
|
.word ScoringLegendData ; $87 = $12 ; CPU:$C699 PRG:0699 07 C7
|
|
|
|
;==============================================================================
|
|
; $C69B-$C72D: State $04 Display Update Streams
|
|
;
|
|
; Local:
|
|
; Contains ten display/update streams selected through
|
|
; CharacterIntroDisplayDataTable according to the state-$04 substate offset $87.
|
|
;
|
|
; LoadState04DisplayData copies the selected stream into RAM beginning at
|
|
; $024B until it encounters $FF. The $FF byte itself is also copied.
|
|
;
|
|
; For several streams, the byte immediately following $FF is $00. The
|
|
; loader examines this byte and uses it to trigger its optional secondary
|
|
; data copy.
|
|
;
|
|
; Global:
|
|
; Supplies the sequence of text and display changes shown during the timed
|
|
; state-$04 sequence. The data reveals that this portion of the attract/
|
|
; information display introduces game characters and later installs
|
|
; scoring/instruction-related display data.
|
|
;
|
|
; Notes:
|
|
; Many tile values correspond directly to ASCII-like character tiles, but
|
|
; special tile values are retained numerically.
|
|
;
|
|
; $00 bytes appearing after $FF belong to the control mechanism used by
|
|
; LoadState04DisplayData. They are not part of the $FF-terminated portion
|
|
; copied to $024B.
|
|
;
|
|
; The final stream at $C707 is structurally different: it contains multiple
|
|
; apparent PPU/update command groups before the final $FF.
|
|
;==============================================================================
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $C69B-$C6B2
|
|
; State04 substate offset: $00
|
|
;
|
|
; Destination prefix: $20E6
|
|
;
|
|
; Tile data corresponds approximately to:
|
|
; "CHARACTER ; NICKNAME"
|
|
;
|
|
; No explicit $00 control byte follows this stream before the next record.
|
|
;------------------------------------------------------------------------------
|
|
|
|
CharacterNicknameHeaderData:
|
|
.byte $20,$E6 ; CPU:$C69B PRG:069B 20 E6
|
|
.byte $43,$48,$41,$52,$41,$43,$54,$45,$52 ; CPU:$C69D PRG:069D 43 48 41 52 41 43 54 45 52
|
|
.byte $20,$3B,$20,$20 ; CPU:$C6A6 PRG:06A6 20 3B 20 20
|
|
.byte $4E,$49,$43,$4B,$4E,$41,$4D,$45 ; CPU:$C6AA PRG:06AA 4E 49 43 4B 4E 41 4D 45
|
|
.byte $FF ; CPU:$C6B2 PRG:06B2 FF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $C6B3-$C6BD
|
|
; State04 substate offset: $02
|
|
;
|
|
; Destination prefix: $2148
|
|
;
|
|
; Text-like tile data:
|
|
; ":SHADOW"
|
|
;
|
|
; $00 after $FF selects the loader's secondary-copy path.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ShadowNameData:
|
|
.byte $21,$48 ; CPU:$C6B3 PRG:06B3 21 48
|
|
.byte $3A,$53,$48,$41,$44,$4F,$57 ; CPU:$C6B5 PRG:06B5 3A 53 48 41 44 4F 57
|
|
.byte $FF ; CPU:$C6BC PRG:06BC FF
|
|
.byte $00 ; CPU:$C6BD PRG:06BD 00
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $C6BE-$C6C8
|
|
; State04 substate offset: $04
|
|
;
|
|
; Destination prefix: $2153
|
|
;
|
|
; Text-like tile data:
|
|
; "_BLINKY_"
|
|
;
|
|
; No trailing $00 before the next stream.
|
|
;------------------------------------------------------------------------------
|
|
|
|
BlinkyNameData:
|
|
.byte $21,$53 ; CPU:$C6BE PRG:06BE 21 53
|
|
.byte $5F,$42,$4C,$49,$4E,$4B,$59,$5F ; CPU:$C6C0 PRG:06C0 5F 42 4C 49 4E 4B 59 5F
|
|
.byte $FF ; CPU:$C6C8 PRG:06C8 FF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $C6C9-$C6D3
|
|
; State04 substate offset: $06
|
|
;
|
|
; Destination prefix: $21A8
|
|
;
|
|
; Text-like tile data:
|
|
; ":SPEEDY"
|
|
;
|
|
; $00 after $FF selects the loader's secondary-copy path.
|
|
;------------------------------------------------------------------------------
|
|
SpeedyNameData:
|
|
.byte $21,$A8 ; CPU:$C6C9 PRG:06C9 21 A8
|
|
.byte $3A,$53,$50,$45,$45,$44,$59 ; CPU:$C6CB PRG:06CB 3A 53 50 45 45 44 59
|
|
.byte $FF ; CPU:$C6D2 PRG:06D2 FF
|
|
.byte $00 ; CPU:$C6D3 PRG:06D3 00
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $C6D4-$C6DD
|
|
; State04 substate offset: $08
|
|
;
|
|
; Destination prefix: $21B3
|
|
;
|
|
; Text-like tile data:
|
|
; "_PINKY_"
|
|
;------------------------------------------------------------------------------
|
|
PinkyNameData:
|
|
.byte $21,$B3 ; CPU:$C6D4 PRG:06D4 21 B3
|
|
.byte $5F,$50,$49,$4E,$4B,$59,$5F ; CPU:$C6D6 PRG:06D6 5F 50 49 4E 4B 59 5F
|
|
.byte $FF ; CPU:$C6DD PRG:06DD FF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $C6DE-$C6E9
|
|
; State04 substate offset: $0A
|
|
;
|
|
; Destination prefix: $2208
|
|
;
|
|
; Contains graphical/special tile values rather than plain character codes.
|
|
; $00 after $FF selects the loader's secondary-copy path.
|
|
;------------------------------------------------------------------------------
|
|
CharacterIntroGraphicData0:
|
|
.byte $22,$08 ; CPU:$C6DE PRG:06DE 22 08
|
|
.byte $B6,$C1,$C3,$B7,$B4,$C2,$B3,$C4 ; CPU:$C6E0 PRG:06E0 B6 C1 C3 B7 B4 C2 B3 C4
|
|
.byte $FF ; CPU:$C6E8 PRG:06E8 FF
|
|
.byte $00 ; CPU:$C6E9 PRG:06E9 00
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $C6EA-$C6F2
|
|
; State04 substate offset: $0C
|
|
;
|
|
; Destination prefix: $2213
|
|
;
|
|
; Contains another set of special graphical tile values.
|
|
;------------------------------------------------------------------------------
|
|
CharacterIntroGraphicData1:
|
|
.byte $22,$13 ; CPU:$C6EA PRG:06EA 22 13
|
|
.byte $C8,$B5,$C5,$C0,$C6,$C8 ; CPU:$C6EC PRG:06EC C8 B5 C5 C0 C6 C8
|
|
.byte $FF ; CPU:$C6F2 PRG:06F2 FF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $C6F3-$C6FC
|
|
; State04 substate offset: $0E
|
|
;
|
|
; Destination prefix: $2268
|
|
;
|
|
; Text-like tile data:
|
|
; ":POKEY"
|
|
;
|
|
; $00 after $FF selects the loader's secondary-copy path.
|
|
;------------------------------------------------------------------------------
|
|
PokeyNameData:
|
|
.byte $22,$68 ; CPU:$C6F3 PRG:06F3 22 68
|
|
.byte $3A,$50,$4F,$4B,$45,$59 ; CPU:$C6F5 PRG:06F5 3A 50 4F 4B 45 59
|
|
.byte $FF ; CPU:$C6FB PRG:06FB FF
|
|
.byte $00 ; CPU:$C6FC PRG:06FC 00
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $C6FD-$C706
|
|
; State04 substate offset: $10
|
|
;
|
|
; Destination prefix: $2273
|
|
;
|
|
; Text-like tile data:
|
|
; "_CLYDE_"
|
|
;------------------------------------------------------------------------------
|
|
ClydeNameData:
|
|
.byte $22,$73 ; CPU:$C6FD PRG:06FD 22 73
|
|
.byte $5F,$43,$4C,$59,$44,$45,$5F ; CPU:$C6FF PRG:06FF 5F 43 4C 59 44 45 5F
|
|
.byte $FF ; CPU:$C706 PRG:0706 FF
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $C707-$C72D
|
|
; State04 substate offset: $12
|
|
;
|
|
; Final composite display stream. Unlike the earlier simple records, this
|
|
; contains several apparent update groups separated by $00 bytes before the
|
|
; final $FF.
|
|
;
|
|
; Visible character-like portions include:
|
|
; "10 PTS"
|
|
; "50 PTS"
|
|
;
|
|
; The special tile values $CE,$CF and $23-$2B are preserved numerically.
|
|
;------------------------------------------------------------------------------
|
|
ScoringLegendData:
|
|
.byte $22,$AD ; CPU:$C707 PRG:0707 22 AD
|
|
.byte $03,$20,$31,$30,$20,$50,$54,$53 ; CPU:$C709 PRG:0709 03 20 31 30 20 50 54 53
|
|
.byte $00 ; CPU:$C711 PRG:0711 00
|
|
|
|
.byte $22,$ED ; CPU:$C712 PRG:0712 22 ED
|
|
.byte $01,$20,$35,$30,$20,$50,$54,$53 ; CPU:$C714 PRG:0714 01 20 35 30 20 50 54 53
|
|
.byte $00 ; CPU:$C71C PRG:071C 00
|
|
|
|
.byte $23,$34 ; CPU:$C71D PRG:071D 23 34
|
|
.byte $CE,$CF ; CPU:$C71F PRG:071F CE CF
|
|
.byte $00 ; CPU:$C721 PRG:0721 00
|
|
|
|
.byte $23,$4D ; CPU:$C722 PRG:0722 23 4D
|
|
.byte $23,$24,$25,$26,$27,$28,$29,$2A,$2B ; CPU:$C724 PRG:0724 23 24 25 26 27 28 29 2A 2B
|
|
.byte $FF ; CPU:$C72D PRG:072D FF
|
|
|
|
|
|
;==============================================================================
|
|
; $C72E-$C76D: State $04 Secondary Object/Sprite Data
|
|
;
|
|
; Local:
|
|
; Contains 64 bytes of secondary display data used by
|
|
; LoadState04DisplayData.
|
|
;
|
|
; When a state-$04 display stream requests the secondary-copy path, the
|
|
; loader calculates:
|
|
;
|
|
; Y = ($87 - $02) * 4
|
|
;
|
|
; It then copies $10 (16) bytes from:
|
|
;
|
|
; CharacterIntroSpriteData,Y
|
|
;
|
|
; to:
|
|
;
|
|
; $0760,Y
|
|
;
|
|
; Because state-$04 substates advance by two, Y advances by eight bytes:
|
|
;
|
|
; $87 = $02 -> Y = $00
|
|
; $87 = $04 -> Y = $08
|
|
; $87 = $06 -> Y = $10
|
|
; $87 = $08 -> Y = $18
|
|
; ...
|
|
;
|
|
; The 16-byte transfers therefore intentionally overlap by eight bytes.
|
|
;
|
|
; Global:
|
|
; Supplies progressively updated object/sprite-related state during the
|
|
; state-$04 timed display sequence. The destination lies in RAM page $07,
|
|
; which is also used as an OAM DMA source elsewhere in the program.
|
|
;
|
|
; The repeated four-byte patterns strongly suggest sprite/OAM-style records,
|
|
; but exact field semantics should be confirmed against the code that
|
|
; consumes $0760 and the active OAM page before assigning field names.
|
|
;
|
|
; Notes:
|
|
; The table is safest to represent as 16 four-byte records during this pass.
|
|
; This preserves its natural repeated structure while allowing the loader's
|
|
; overlapping 16-byte windows to remain obvious.
|
|
;==============================================================================
|
|
|
|
CharacterIntroSpriteData:
|
|
; $C72E - record $00
|
|
.byte $48,$1C,$40,$26 ; CPU:$C72E PRG:072E 48 1C 40 26
|
|
|
|
; $C732 - record $01
|
|
.byte $48,$1B,$40,$2E ; CPU:$C732 PRG:0732 48 1B 40 2E
|
|
|
|
; $C736 - record $02
|
|
.byte $50,$1F,$40,$26 ; CPU:$C736 PRG:0736 50 1F 40 26
|
|
|
|
; $C73A - record $03
|
|
.byte $50,$1D,$40,$2E ; CPU:$C73A PRG:073A 50 1D 40 2E
|
|
|
|
; $C73E - record $04
|
|
.byte $60,$1C,$41,$26 ; CPU:$C73E PRG:073E 60 1C 41 26
|
|
|
|
; $C742 - record $05
|
|
.byte $60,$1B,$41,$2E ; CPU:$C742 PRG:0742 60 1B 41 2E
|
|
|
|
; $C746 - record $06
|
|
.byte $68,$1F,$41,$26 ; CPU:$C746 PRG:0746 68 1F 41 26
|
|
|
|
; $C74A - record $07
|
|
.byte $68,$1D,$41,$2E ; CPU:$C74A PRG:074A 68 1D 41 2E
|
|
|
|
; $C74E - record $08
|
|
.byte $78,$1C,$42,$26 ; CPU:$C74E PRG:074E 78 1C 42 26
|
|
|
|
; $C752 - record $09
|
|
.byte $78,$1B,$42,$2E ; CPU:$C752 PRG:0752 78 1B 42 2E
|
|
|
|
; $C756 - record $0A
|
|
.byte $80,$1F,$42,$26 ; CPU:$C756 PRG:0756 80 1F 42 26
|
|
|
|
; $C75A - record $0B
|
|
.byte $80,$1D,$42,$2E ; CPU:$C75A PRG:075A 80 1D 42 2E
|
|
|
|
; $C75E - record $0C
|
|
.byte $90,$1C,$43,$26 ; CPU:$C75E PRG:075E 90 1C 43 26
|
|
|
|
; $C762 - record $0D
|
|
.byte $90,$1B,$43,$2E ; CPU:$C762 PRG:0762 90 1B 43 2E
|
|
|
|
; $C766 - record $0E
|
|
.byte $98,$1F,$43,$26 ; CPU:$C766 PRG:0766 98 1F 43 26
|
|
|
|
; $C76A - record $0F
|
|
.byte $98,$1D,$43,$2E ; CPU:$C76A PRG:076A 98 1D 43 2E
|
|
|
|
|
|
;==============================================================================
|
|
; $C76E-$C791: State $04 Nametable Attribute Data
|
|
;
|
|
; Local:
|
|
; Contains $24 (36) bytes copied directly to PPUDATA by
|
|
; InitializeState04PpuData.
|
|
;
|
|
; The destination begins at PPU $23C8, so the complete transfer covers:
|
|
;
|
|
; $23C8-$23EB
|
|
;
|
|
; Global:
|
|
; Defines background palette selection attributes used by the state-$04
|
|
; display. The highly regular $00/$55/$AA/$FF pattern assigns repeating
|
|
; palette selections across large regions of the nametable.
|
|
;
|
|
; Notes:
|
|
; These are NES attribute-table bytes rather than tile indices.
|
|
;
|
|
; Each attribute byte contains four 2-bit palette selections. Values such
|
|
; as $00, $55, $AA and $FF therefore select the same palette throughout all
|
|
; four quadrants covered by that attribute byte:
|
|
;
|
|
; $00 -> palette 0 in all four quadrants
|
|
; $55 -> palette 1 in all four quadrants
|
|
; $AA -> palette 2 in all four quadrants
|
|
; $FF -> palette 3 in all four quadrants
|
|
;
|
|
; The final $22 mixes palette selections within its attribute regions.
|
|
;==============================================================================
|
|
|
|
CharacterIntroAttributeData:
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00 ; CPU:$C76E PRG:076E 00 00 00 00 00 00 00 00
|
|
.byte $55,$55,$55,$55,$55,$55,$55,$55 ; CPU:$C776 PRG:0776 55 55 55 55 55 55 55 55
|
|
.byte $AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA ; CPU:$C77E PRG:077E AA AA AA AA AA AA AA AA
|
|
.byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF ; CPU:$C786 PRG:0786 FF FF FF FF FF FF FF FF
|
|
.byte $AA,$AA,$AA,$22 ; CPU:$C78E PRG:078E AA AA AA 22
|
|
|
|
;==============================================================================
|
|
; $C792-$C7A0: State $04 Final-Phase Dispatcher
|
|
;
|
|
; Local:
|
|
; Uses $88 as a direct byte offset into a four-entry table of 16-bit
|
|
; addresses beginning at $C7A1.
|
|
;
|
|
; The selected address is stored in the temporary pointer $10/$11 and
|
|
; execution is transferred to it using an indirect JMP.
|
|
;
|
|
; Global:
|
|
; Implements state-$04 substate offset $16. Rather than performing the work
|
|
; directly, this substate introduces another secondary state machine.
|
|
;
|
|
; At this stage:
|
|
;
|
|
; $3F = $04 main state
|
|
; $87 = $16 state-$04 substate
|
|
; $88 final-phase dispatch offset
|
|
;
|
|
; This provides another level of progression within the final state-$04
|
|
; phase.
|
|
;
|
|
; Notes:
|
|
; $88 is used directly as a byte offset, so normal values are expected to
|
|
; advance by two:
|
|
;
|
|
; $00, $02, $04, $06
|
|
;
|
|
; The individual target handlers will be named as they are decoded.
|
|
;==============================================================================
|
|
State04FinalPhase:
|
|
ldy $88 ; CPU:$C792 PRG:0792 A4 88
|
|
|
|
lda State04FinalPhaseTable,y ; CPU:$C794 PRG:0794 B9 A1 C7
|
|
sta dispatchVector ; CPU:$C797 PRG:0797 85 10
|
|
|
|
lda State04FinalPhaseTable+1,y ; CPU:$C799 PRG:0799 B9 A2 C7
|
|
sta dispatchVector+1 ; CPU:$C79C PRG:079C 85 11 6C
|
|
|
|
jmp ($0010) ; CPU:$C79F PRG:079F 10 00 A7 C7 F2
|
|
|
|
;==============================================================================
|
|
; $C7A1-$C7A6: State $04 Final-Phase Dispatch Table
|
|
;
|
|
; Local:
|
|
; Three 16-bit handler addresses indexed by $88.
|
|
;
|
|
; Global:
|
|
; Selects the processing stage used during State04FinalPhase.
|
|
;
|
|
; Notes:
|
|
; Valid byte offsets established by the table are $00, $02 and $04.
|
|
; $C7A7 is executable code and is not part of the pointer table.
|
|
;==============================================================================
|
|
|
|
State04FinalPhaseTable:
|
|
.word State04FinalPhaseInitialize ; $88 = $00 ; CPU:$C7A1 PRG:07A1 A7 C7
|
|
.word State04FinalPhaseActive ; $88 = $02 ; CPU:$C7A3 PRG:07A3 F2 C7
|
|
.word State04FinalPhaseComplete ; $88 = $04 ; CPU:$C7A5 PRG:07A5 57 C8
|
|
|
|
;==============================================================================
|
|
; $C7A7-$C7F1: State $04 Final-Phase Initialization
|
|
;
|
|
; Local:
|
|
; Initializes the first stage of State04FinalPhase.
|
|
;
|
|
; Copies a $FF-terminated display/update stream from State04FinalDisplayData
|
|
; into RAM at $024B, including the terminator.
|
|
;
|
|
; Initializes several state variables and object/display values, clears
|
|
; $001E-$0031 and $0278-$028B, calls the helper at $DAF1, then advances
|
|
; $88 by two to select final-phase offset $02.
|
|
;
|
|
; Global:
|
|
; First handler selected by State04FinalPhase when $88 = $00. It prepares
|
|
; the RAM and display state required by the next final-phase handler at
|
|
; $C7F2.
|
|
;
|
|
; Notes:
|
|
; $1A is initialized to $FF.
|
|
; $1B, $89 and $8A are initialized to $00.
|
|
;
|
|
; $0274 = $F4
|
|
; $0276 = $A8
|
|
; $028C = $01
|
|
; $0292 = $20
|
|
;
|
|
; The exact semantics of these locations will be refined after tracing
|
|
; their consumers.
|
|
;
|
|
; State04FinalDisplayData is a display/update stream in the same general RAM
|
|
; command area used elsewhere through $024B.
|
|
;==============================================================================
|
|
|
|
State04FinalPhaseInitialize:
|
|
ldy #$00 ; CPU:$C7A7 PRG:07A7 A0 00
|
|
|
|
@CopyDisplayData:
|
|
lda State04FinalDisplayData,y ; CPU:$C7A9 PRG:07A9 B9 D8 C9
|
|
sta $024B,y ; CPU:$C7AC PRG:07AC 99 4B 02
|
|
iny ; CPU:$C7AF PRG:07AF C8
|
|
cmp #$FF ; CPU:$C7B0 PRG:07B0 C9 FF
|
|
bne @CopyDisplayData ; CPU:$C7B2 PRG:07B2 D0 F5
|
|
|
|
lda #$FF ; CPU:$C7B4 PRG:07B4 A9 FF
|
|
sta pacmanMotion ; CPU:$C7B6 PRG:07B6 85 1A
|
|
|
|
lda #$00 ; CPU:$C7B8 PRG:07B8 A9 00
|
|
sta $1B ; CPU:$C7BA PRG:07BA 85 1B
|
|
sta $89 ; CPU:$C7BC PRG:07BC 85 89
|
|
sta $8A ; CPU:$C7BE PRG:07BE 85 8A
|
|
|
|
lda #$F4 ; CPU:$C7C0 PRG:07C0 A9 F4
|
|
sta $0274 ; CPU:$C7C2 PRG:07C2 8D 74 02
|
|
|
|
lda #$A8 ; CPU:$C7C5 PRG:07C5 A9 A8
|
|
sta $0276 ; CPU:$C7C7 PRG:07C7 8D 76 02
|
|
|
|
lda #$01 ; CPU:$C7CA PRG:07CA A9 01
|
|
sta $028C ; CPU:$C7CC PRG:07CC 8D 8C 02
|
|
|
|
lda #$20 ; CPU:$C7CF PRG:07CF A9 20
|
|
sta $0292 ; CPU:$C7D1 PRG:07D1 8D 92 02
|
|
|
|
lda #$00 ; CPU:$C7D4 PRG:07D4 A9 00
|
|
tay ; CPU:$C7D6 PRG:07D6 A8
|
|
|
|
@ClearLowRamBlock:
|
|
sta $001E,y ; CPU:$C7D7 PRG:07D7 99 1E 00
|
|
iny ; CPU:$C7DA PRG:07DA C8
|
|
cpy #$14 ; CPU:$C7DB PRG:07DB C0 14
|
|
bne @ClearLowRamBlock ; CPU:$C7DD PRG:07DD D0 F8
|
|
|
|
tay ; CPU:$C7DF PRG:07DF A8
|
|
|
|
@ClearObjectRamBlock:
|
|
sta $0278,y ; CPU:$C7E0 PRG:07E0 99 78 02
|
|
iny ; CPU:$C7E3 PRG:07E3 C8
|
|
cpy #$14 ; CPU:$C7E4 PRG:07E4 C0 14
|
|
bne @ClearObjectRamBlock ; CPU:$C7E6 PRG:07E6 D0 F8
|
|
|
|
jsr $DAF1 ; CPU:$C7E8 PRG:07E8 20 F1 DA
|
|
|
|
inc $88 ; CPU:$C7EB PRG:07EB E6 88
|
|
inc $88 ; CPU:$C7ED PRG:07ED E6 88
|
|
|
|
jmp MainDispatchLoop ; CPU:$C7EF PRG:07EF 4C 50 C2
|
|
|
|
;==============================================================================
|
|
; $C7F2-$C856: State $04 Final-Phase Active Handler
|
|
;
|
|
; Local:
|
|
; Calls two per-frame helpers at UpdateState04Objects and
|
|
; AnimateState04DisplayPattern, then examines $0274.
|
|
;
|
|
; When $0274 equals one of:
|
|
;
|
|
; $E0
|
|
; $D1
|
|
; $C2
|
|
; $B3
|
|
;
|
|
; the routine calls InitializeState04ObjectSlot.
|
|
;
|
|
; Processing otherwise continues until $0274 reaches $40. While it has not
|
|
; reached $40, control returns to MainDispatchLoop.
|
|
;
|
|
; When $0274 reaches $40, the routine:
|
|
;
|
|
; - Initializes four 4-byte structures beginning at $001E.
|
|
; - Sets $1A = $01 and $1B = $50.
|
|
; - Sets $0293-$0296 to $01.
|
|
; - Clears $89.
|
|
; - Writes a short display/update sequence at $024B/$024D.
|
|
; - Advances $88 by two, selecting final-phase offset $04.
|
|
;
|
|
; Global:
|
|
; Active middle stage of State04FinalPhase. The handler appears to drive
|
|
; an animated sequence by calling UpdateState04Objects/AnimateState04DisplayPattern
|
|
; each frame and reacting when $0274 reaches several specific values.
|
|
;
|
|
; The milestone values $E0,$D1,$C2,$B3 invoke InitializeState04ObjectSlot. The exact meaning of
|
|
; those milestones should be assigned after the movement/update helpers are
|
|
; decoded.
|
|
;
|
|
; Notes:
|
|
; $0274 was initialized to $F4 by State04FinalPhaseInitialize, so the
|
|
; descending milestone tests strongly suggest $0274 is modified by one of
|
|
; the per-frame helper routines.
|
|
;
|
|
; The four low-RAM structures are $001E/$0022/$0026/$002A. Each receives
|
|
; $00 in its first byte and $C0 in its second byte. The remaining two bytes
|
|
; are not changed by this loop.
|
|
;==============================================================================
|
|
|
|
State04FinalPhaseActive:
|
|
jsr UpdateState04Objects ; CPU:$C7F2 PRG:07F2 20 DC C8
|
|
jsr AnimateState04DisplayPattern ; CPU:$C7F5 PRG:07F5 20 B8 C9
|
|
|
|
lda $0274 ; CPU:$C7F8 PRG:07F8 AD 74 02
|
|
|
|
cmp #$E0 ; CPU:$C7FB PRG:07FB C9 E0
|
|
beq @RunMilestoneUpdate ; CPU:$C7FD PRG:07FD F0 0C
|
|
|
|
cmp #$D1 ; CPU:$C7FF PRG:07FF C9 D1
|
|
beq @RunMilestoneUpdate ; CPU:$C801 PRG:0801 F0 08
|
|
|
|
cmp #$C2 ; CPU:$C803 PRG:0803 C9 C2
|
|
beq @RunMilestoneUpdate ; CPU:$C805 PRG:0805 F0 04
|
|
|
|
cmp #$B3 ; CPU:$C807 PRG:0807 C9 B3
|
|
bne @CheckForCompletion ; CPU:$C809 PRG:0809 D0 03
|
|
|
|
@RunMilestoneUpdate:
|
|
jsr InitializeState04ObjectSlot ; CPU:$C80B PRG:080B 20 A8 C8
|
|
|
|
@CheckForCompletion:
|
|
lda $0274 ; CPU:$C80E PRG:080E AD 74 02
|
|
cmp #$40 ; CPU:$C811 PRG:0811 C9 40
|
|
beq @CompletePhase ; CPU:$C813 PRG:0813 F0 03
|
|
|
|
jmp MainDispatchLoop ; CPU:$C815 PRG:0815 4C 50 C2
|
|
|
|
@CompletePhase:
|
|
ldy #$00 ; CPU:$C818 PRG:0818 A0 00
|
|
|
|
@InitializeStructures:
|
|
lda #$00 ; CPU:$C81A PRG:081A A9 00
|
|
sta ghost1Motion,y ; CPU:$C81C PRG:081C 99 1E
|
|
|
|
lda #$C0 ; CPU:$C81E PRG:081E 00 A9
|
|
sta ghost1Motion+1,y ; CPU:$C820 PRG:0820 C0 99 1F
|
|
|
|
iny ; CPU:$C823 PRG:0823 00
|
|
iny ; CPU:$C824 PRG:0824 C8
|
|
iny ; CPU:$C825 PRG:0825 C8
|
|
iny ; CPU:$C826 PRG:0826 C8
|
|
|
|
cpy #$10 ; CPU:$C827 PRG:0827 C8 C0
|
|
bne @InitializeStructures ; CPU:$C829 PRG:0829 10 D0
|
|
|
|
lda #$01 ; CPU:$C82B PRG:082B EE A9
|
|
sta pacmanMotion ; CPU:$C82D PRG:082D 01 85
|
|
|
|
lda #$50 ; CPU:$C82F PRG:082F 1A A9
|
|
sta pacmanMotion+1 ; CPU:$C831 PRG:0831 50 85 1B
|
|
|
|
lda #$01 ; CPU:$C834 PRG:0834 A9 01
|
|
sta $0293 ; CPU:$C836 PRG:0836 8D 93 02
|
|
sta $0294 ; CPU:$C839 PRG:0839 8D 94 02
|
|
sta $0295 ; CPU:$C83C PRG:083C 8D 95 02
|
|
sta $0296 ; CPU:$C83F PRG:083F 8D 96 02
|
|
|
|
lda #$00 ; CPU:$C842 PRG:0842 A9 00
|
|
sta $89 ; CPU:$C844 PRG:0844 85 89
|
|
|
|
lda #$22 ; CPU:$C846 PRG:0846 A9 22
|
|
sta $024B ; CPU:$C848 PRG:0848 8D 4B 02
|
|
|
|
lda #$20 ; CPU:$C84B PRG:084B A9 20
|
|
sta $024D ; CPU:$C84D PRG:084D 8D 4D 02
|
|
|
|
inc $88 ; CPU:$C850 PRG:0850 E6 88
|
|
inc $88 ; CPU:$C852 PRG:0852 E6 88
|
|
|
|
jmp MainDispatchLoop ; CPU:$C854 PRG:0854 4C 50 C2
|
|
|
|
;==============================================================================
|
|
; $C857-$C8A7: State $04 Final-Phase Completion Handler
|
|
;
|
|
; Local:
|
|
; Final handler for final-phase offset $88 = $04.
|
|
;
|
|
; If $8A is nonzero, calls RotateState04ObjectSlots and decrements the countdown. When the
|
|
; countdown reaches zero, scans status entries beginning at $028D until an
|
|
; entry with one or more upper-three status bits set is found.
|
|
;
|
|
; The matching entry and associated state are cleared. If $89 has reached
|
|
; $04, the routine sets $47 to $01 and transfers control to GameModeEntry.
|
|
;
|
|
; When $8A is already zero on entry, calls $C8DC and returns to the common
|
|
; main dispatch loop.
|
|
;
|
|
; Global:
|
|
; Final processing stage of the nested state-$04 sequence:
|
|
;
|
|
; $3F = $04
|
|
; $87 = $16
|
|
; $88 = $04
|
|
;
|
|
; The eventual transfer to GameModeEntry appears to leave this attract/display
|
|
; sequence and enter another major portion of the program.
|
|
;
|
|
; Notes:
|
|
; $8A acts as a countdown here.
|
|
; $89 is tested against $04 for completion.
|
|
;
|
|
; The scan at $028D looks for the first entry satisfying:
|
|
;
|
|
; ($028D,Y & $E0) != 0
|
|
;
|
|
; Exact object/state semantics remain for a later pass.
|
|
;==============================================================================
|
|
|
|
State04FinalPhaseComplete:
|
|
lda $8A ; CPU:$C857 PRG:0857 A5 8A
|
|
beq @RunRegularUpdate ; CPU:$C859 PRG:0859 F0 47
|
|
|
|
jsr RotateState04ObjectSlots ; CPU:$C85B PRG:085B 20 2E C9
|
|
|
|
dec $8A ; CPU:$C85E PRG:085E C6 8A
|
|
beq @CountdownComplete ; CPU:$C860 PRG:0860 F0 03
|
|
|
|
jmp MainDispatchLoop ; CPU:$C862 PRG:0862 4C 50 C2
|
|
|
|
@CountdownComplete:
|
|
ldy #$00 ; CPU:$C865 PRG:0865 A0 00
|
|
|
|
@FindEntry:
|
|
lda $028D,y ; CPU:$C867 PRG:0867 B9 8D 02
|
|
and #$E0 ; CPU:$C86A PRG:086A 29 E0
|
|
bne @EntryFound ; CPU:$C86C PRG:086C D0 03
|
|
|
|
iny ; CPU:$C86E PRG:086E C8
|
|
bne @FindEntry ; CPU:$C86F PRG:086F D0 F6
|
|
|
|
@EntryFound:
|
|
lda #$00 ; CPU:$C871 PRG:0871 A9 00
|
|
sta $028D,y ; CPU:$C873 PRG:0873 99 8D 02
|
|
|
|
lda #$00 ; CPU:$C876 PRG:0876 A9 00
|
|
sta $0293,y ; CPU:$C878 PRG:0878 99 93 02
|
|
|
|
tya ; CPU:$C87B PRG:087B 98
|
|
asl ; CPU:$C87C PRG:087C 0A
|
|
asl ; CPU:$C87D PRG:087D 0A
|
|
tay ; CPU:$C87E PRG:087E A8
|
|
|
|
lda #$00 ; CPU:$C87F PRG:087F A9 00
|
|
sta $0278,y ; CPU:$C881 PRG:0881 99 78 02
|
|
sta $027A,y ; CPU:$C884 PRG:0884 99 7A 02
|
|
sta ghost1Motion,y ; CPU:$C887 PRG:0887 99 1E
|
|
sta ghost1Motion+1,y ; CPU:$C889 PRG:0889 00 99 1F
|
|
|
|
lda #$A8 ; CPU:$C88C PRG:088C 00 A9
|
|
sta $0276 ; CPU:$C88E PRG:088E A8 8D 76
|
|
|
|
lda $89 ; CPU:$C891 PRG:0891 02 A5
|
|
cmp #$04 ; CPU:$C893 PRG:0893 89 C9
|
|
beq @FinishSequence ; CPU:$C895 PRG:0895 04 F0
|
|
|
|
jmp MainDispatchLoop ; CPU:$C897 PRG:0897 03 4C 50
|
|
|
|
@FinishSequence:
|
|
lda #$01 ; CPU:$C89A PRG:089A C2 A9
|
|
sta activePlayerFlag ; CPU:$C89C PRG:089C 01 85
|
|
|
|
jmp GameModeEntry ; CPU:$C89E PRG:089E 47 4C 54
|
|
|
|
@RunRegularUpdate:
|
|
jsr UpdateState04Objects ; CPU:$C8A1 PRG:08A1 CA 20 DC
|
|
|
|
jmp MainDispatchLoop ; CPU:$C8A4 PRG:08A4 C8 4C 50
|
|
|
|
;==============================================================================
|
|
; $C8A8-$C8DB: Allocate/Initialize State $04 Object Slot
|
|
;
|
|
; Local:
|
|
; Searches four 4-byte structures beginning at $0278 for the first slot
|
|
; whose first byte is zero.
|
|
;
|
|
; During the search, $00 tracks the logical slot number while Y advances
|
|
; by four bytes per structure.
|
|
;
|
|
; Once a free slot is found, initializes that structure:
|
|
;
|
|
; +0 = $F4
|
|
; +2 = $A8
|
|
;
|
|
; It also initializes corresponding four-byte-strided zero-page state:
|
|
;
|
|
; $001E+Y = $FF
|
|
; $001F+Y = $00
|
|
;
|
|
; The logical slot number saved in $00 is then used to index two separate
|
|
; per-slot arrays:
|
|
;
|
|
; $0293+slot = current $89 value
|
|
; $028D+slot = $0C
|
|
;
|
|
; Finally increments $89 and returns.
|
|
;
|
|
; Global:
|
|
; Called by State04FinalPhaseActive whenever $0274 reaches the milestone
|
|
; values $E0, $D1, $C2, or $B3.
|
|
;
|
|
; This strongly suggests that the routine activates one additional object
|
|
; at each milestone during the state-$04 final sequence. Four slots are
|
|
; available, matching the four milestone values.
|
|
;
|
|
; Notes:
|
|
; $0278 appears to be the first field of a four-byte structure array.
|
|
; $027A is the third field of the same structure.
|
|
;
|
|
; $001E/$001F are parallel four-byte-strided state fields.
|
|
;
|
|
; $028D and $0293 are indexed by logical slot number rather than the
|
|
; four-byte structure offset.
|
|
;
|
|
; Exact object semantics remain deliberately unnamed until UpdateState04Objects
|
|
; and RotateState04ObjectSlots reveal how these structures are updated.
|
|
;==============================================================================
|
|
|
|
InitializeState04ObjectSlot:
|
|
ldy #$00 ; CPU:$C8A8 PRG:08A8 A0 00
|
|
sty workPtr0 ; CPU:$C8AA PRG:08AA 84 00
|
|
|
|
@FindFreeSlot:
|
|
lda $0278,y ; CPU:$C8AC PRG:08AC B9 78 02
|
|
beq @InitializeSlot ; CPU:$C8AF PRG:08AF F0 08
|
|
|
|
inc workPtr0 ; CPU:$C8B1 PRG:08B1 E6 00
|
|
|
|
iny ; CPU:$C8B3 PRG:08B3 C8
|
|
iny ; CPU:$C8B4 PRG:08B4 C8
|
|
iny ; CPU:$C8B5 PRG:08B5 C8
|
|
iny ; CPU:$C8B6 PRG:08B6 C8
|
|
|
|
bne @FindFreeSlot ; CPU:$C8B7 PRG:08B7 D0 F3
|
|
|
|
@InitializeSlot:
|
|
lda #$F4 ; CPU:$C8B9 PRG:08B9 A9 F4
|
|
sta $0278,y ; CPU:$C8BB PRG:08BB 99 78 02
|
|
|
|
lda #$A8 ; CPU:$C8BE PRG:08BE A9 A8
|
|
sta $027A,y ; CPU:$C8C0 PRG:08C0 99 7A 02
|
|
|
|
lda #$FF ; CPU:$C8C3 PRG:08C3 A9 FF
|
|
sta ghost1Motion,y ; CPU:$C8C5 PRG:08C5 99 1E
|
|
|
|
lda #$00 ; CPU:$C8C7 PRG:08C7 00 A9
|
|
sta $001F,y ; CPU:$C8C9 PRG:08C9 00 99 1F
|
|
|
|
ldy workPtr0 ; CPU:$C8CC PRG:08CC 00 A4
|
|
|
|
lda $89 ; CPU:$C8CE PRG:08CE 00 A5
|
|
sta $0293,y ; CPU:$C8D0 PRG:08D0 89 99 93
|
|
|
|
lda #$0C ; CPU:$C8D3 PRG:08D3 02 A9
|
|
sta $028D,y ; CPU:$C8D5 PRG:08D5 0C 99 8D
|
|
|
|
inc $89 ; CPU:$C8D8 PRG:08D8 02 E6
|
|
|
|
rts ; CPU:$C8DA PRG:08DA 89
|
|
|
|
;==============================================================================
|
|
; $C8DC-$C8EA: State $04 Per-Frame Object Update Coordinator
|
|
;
|
|
; Local:
|
|
; Runs four update stages in sequence:
|
|
;
|
|
; UpdateTransitionObjectPositions
|
|
; RotateState04ObjectSlots
|
|
; UpdateState04ObjectStatus
|
|
; CheckState04ObjectTrigger
|
|
;
|
|
; After those return, tail-jumps to $DAF1 rather than returning directly.
|
|
;
|
|
; Global:
|
|
; Called once per frame during portions of the state-$04 final sequence.
|
|
; This routine coordinates the lower-level movement/object/display work
|
|
; associated with that sequence.
|
|
;
|
|
; It is called from both State04FinalPhaseActive and
|
|
; State04FinalPhaseComplete.
|
|
;
|
|
; Notes:
|
|
; The exact responsibilities of $EA19, $C92E, $C9FA, CheckState04ObjectTrigger
|
|
; and $DAF1 will be refined as those routines are decoded.
|
|
;
|
|
; The JMP to $DAF1 is a tail call: $DAF1 ultimately returns directly to
|
|
; the original caller of this routine.
|
|
;==============================================================================
|
|
UpdateState04Objects:
|
|
jsr UpdateTransitionObjectPositions ; CPU:$C8DC PRG:08DC 20 19 EA
|
|
jsr RotateState04ObjectSlots ; CPU:$C8DF PRG:08DF 20 2E C9
|
|
jsr UpdateState04ObjectStatus ; CPU:$C8E2 PRG:08E2 20 FA C9
|
|
jsr CheckState04ObjectTrigger ; CPU:$C8E5 PRG:08E5 20 EB C8
|
|
jmp BuildEntitySpriteBuffer ; CPU:$C8E8 PRG:08E8 4C F1 DA
|
|
|
|
;==============================================================================
|
|
; $C8EB-$C92D: Check State $04 Object Trigger
|
|
;
|
|
; Local:
|
|
; Returns immediately when $1A is negative.
|
|
;
|
|
; Otherwise computes:
|
|
;
|
|
; threshold = $0274 + $08
|
|
;
|
|
; and scans four 4-byte structures beginning at $0278.
|
|
;
|
|
; For each active structure, compares its first byte against the threshold.
|
|
; When a qualifying structure is found, uses $89 as an index into a ROM
|
|
; table at $C9EE, installs the resulting value into a per-slot status array,
|
|
; clears a related slot value, initializes $8A to $40, and clears $028C and
|
|
; $0276.
|
|
;
|
|
; Global:
|
|
; Part of UpdateState04Objects. Appears to detect when one of the active
|
|
; state-$04 objects crosses a position threshold relative to the primary
|
|
; value at $0274, then initiates a $40-frame/countdown event through $8A.
|
|
;
|
|
; Notes:
|
|
; $00 holds the comparison threshold ($0274 + $08).
|
|
; $01 tracks the logical object slot while Y steps through four-byte
|
|
; structures.
|
|
;
|
|
; $89 is incremented as part of the event setup.
|
|
;
|
|
; $C9EE is a small ROM lookup table that remains to be decoded.
|
|
;==============================================================================
|
|
|
|
CheckState04ObjectTrigger:
|
|
lda pacmanMotion ; CPU:$C8EB PRG:08EB A5 1A
|
|
bpl @Continue ; CPU:$C8ED PRG:08ED 10 01
|
|
|
|
rts ; CPU:$C8EF PRG:08EF 60
|
|
|
|
@Continue:
|
|
lda $0274 ; CPU:$C8F0 PRG:08F0 AD 74 02
|
|
clc ; CPU:$C8F3 PRG:08F3 18
|
|
adc #$08 ; CPU:$C8F4 PRG:08F4 69 08
|
|
sta workPtr0 ; CPU:$C8F6 PRG:08F6 85 00
|
|
|
|
ldy #$00 ; CPU:$C8F8 PRG:08F8 A0 00
|
|
sty workPtr0+1 ; CPU:$C8FA PRG:08FA 84 01 B9
|
|
|
|
@ScanObjects:
|
|
lda $0278,y ; CPU:$C8FD PRG:08FD 78 02 F0
|
|
beq @NextObject ; CPU:$C900 PRG:0900 04 C5
|
|
|
|
cmp workPtr0 ; CPU:$C902 PRG:0902 00 90
|
|
bcc @TriggerEvent ; CPU:$C904 PRG:0904 0B E6
|
|
|
|
@NextObject:
|
|
inc workPtr0+1 ; CPU:$C906 PRG:0906 01 C8
|
|
|
|
iny ; CPU:$C908 PRG:0908 C8
|
|
iny ; CPU:$C909 PRG:0909 C8
|
|
iny ; CPU:$C90A PRG:090A C8
|
|
iny ; CPU:$C90B PRG:090B C0
|
|
|
|
cpy #$10 ; CPU:$C90C PRG:090C 10 D0
|
|
bne @ScanObjects ; CPU:$C90E PRG:090E ED 60
|
|
|
|
rts ; CPU:$C910 PRG:0910 A4
|
|
|
|
@TriggerEvent:
|
|
ldy $89 ; CPU:$C911 PRG:0911 89 E6
|
|
inc $89 ; CPU:$C913 PRG:0913 89 A9
|
|
|
|
lda #$40 ; CPU:$C915 PRG:0915 40 85
|
|
sta $8A ; CPU:$C917 PRG:0917 8A B9
|
|
|
|
lda $C9EE,y ; CPU:$C919 PRG:0919 EE C9 A4
|
|
|
|
ldy workPtr0+1 ; CPU:$C91C PRG:091C 01 99 8D
|
|
sta $028D,y ; CPU:$C91F PRG:091F 02 A9 00
|
|
|
|
lda #$00 ; CPU:$C922 PRG:0922 99 93
|
|
sta $0293,y ; CPU:$C924 PRG:0924 02 A9 00
|
|
|
|
lda #$00 ; CPU:$C927 PRG:0927 8D 8C
|
|
sta $028C ; CPU:$C929 PRG:0929 02 8D 76
|
|
sta $0276 ; CPU:$C92C PRG:092C 02 60 A5
|
|
|
|
rts ; CPU:$C92F PRG:092F 1E
|
|
|
|
;==============================================================================
|
|
; $C92E-$C9B7: Rotate State $04 Object Slots
|
|
;
|
|
; Local:
|
|
; Rotates four related object/state entries across several parallel arrays.
|
|
;
|
|
; The routine operates on:
|
|
;
|
|
; $001E/$001F four-byte-strided zero-page structures
|
|
; $0278-$0287 four 4-byte object structures
|
|
; $028D-$0290 four object/status bytes
|
|
; $0293-$0296 four object/index bytes
|
|
;
|
|
; For each array, the first entry is saved temporarily, entries 1-3 are
|
|
; shifted toward entry 0, and the saved entry 0 is moved to entry 3.
|
|
;
|
|
; Global:
|
|
; Called by UpdateState04Objects every frame, and also directly from
|
|
; State04FinalPhaseComplete while its $8A countdown is active.
|
|
;
|
|
; This appears to cycle the four state-$04 object slots through a fixed
|
|
; ordering while keeping their parallel state/status arrays synchronized.
|
|
;
|
|
; Notes:
|
|
; $00-$03 are temporary storage.
|
|
;
|
|
; The zero-page structures use a four-byte stride but only the first two
|
|
; bytes of each structure are moved here.
|
|
;
|
|
; The $0278 array moves all four bytes of each structure.
|
|
;
|
|
; $028D-$0290 and $0293-$0296 are simple four-entry byte arrays.
|
|
;==============================================================================
|
|
RotateState04ObjectSlots:
|
|
; -------------------------------------------------------------------------
|
|
; Rotate the first two bytes of the four-byte-strided zero-page structures.
|
|
;
|
|
; Entries:
|
|
; 0 -> $001E/$001F
|
|
; 1 -> $0022/$0023
|
|
; 2 -> $0026/$0027
|
|
; 3 -> $002A/$002B
|
|
; -------------------------------------------------------------------------
|
|
|
|
lda ghost1Motion ; CPU:$C92E PRG:092E A5 1E
|
|
sta workPtr0 ; CPU:$C930 PRG:0930 85 00
|
|
|
|
lda ghost1Motion+1 ; CPU:$C932 PRG:0932 A5 1F 85
|
|
sta workPtr0+1 ; CPU:$C935 PRG:0935 01 A0 00
|
|
|
|
ldy #$00 ; CPU:$C938 PRG:0938 B9 22
|
|
|
|
@ShiftLowRamStructures:
|
|
lda ghost2Motion,y ; CPU:$C93A PRG:093A 00 99
|
|
sta ghost1Motion,y ; CPU:$C93C PRG:093C 1E 00
|
|
|
|
lda ghost2Motion+1,y ; CPU:$C93E PRG:093E B9 23 00
|
|
sta ghost1Motion+1,y ; CPU:$C941 PRG:0941 99 1F 00
|
|
|
|
iny ; CPU:$C944 PRG:0944 C8
|
|
iny ; CPU:$C945 PRG:0945 C8
|
|
iny ; CPU:$C946 PRG:0946 C8
|
|
iny ; CPU:$C947 PRG:0947 C8
|
|
|
|
cpy #$0C ; CPU:$C948 PRG:0948 C0 0C
|
|
bne @ShiftLowRamStructures ; CPU:$C94A PRG:094A D0 EC
|
|
|
|
lda workPtr0 ; CPU:$C94C PRG:094C A5 00
|
|
sta ghost4Motion ; CPU:$C94E PRG:094E 85 2A
|
|
|
|
lda workPtr0+1 ; CPU:$C950 PRG:0950 A5 01 85
|
|
sta ghost4Motion+1 ; CPU:$C953 PRG:0953 2B AD 78
|
|
|
|
; -------------------------------------------------------------------------
|
|
; Rotate four complete 4-byte structures at $0278-$0287.
|
|
; -------------------------------------------------------------------------
|
|
|
|
lda $0278 ; CPU:$C956 PRG:0956 02 85 00
|
|
sta workPtr0 ; CPU:$C959 PRG:0959 AD 79
|
|
|
|
lda $0279 ; CPU:$C95B PRG:095B 02 85 01
|
|
sta workPtr0+1 ; CPU:$C95E PRG:095E AD 7A 02
|
|
|
|
lda $027A ; CPU:$C961 PRG:0961 85 02 AD
|
|
sta workPtr1 ; CPU:$C964 PRG:0964 7B 02
|
|
|
|
lda $027B ; CPU:$C966 PRG:0966 85 03 A0
|
|
sta workPtr1+1 ; CPU:$C969 PRG:0969 00 B9 7C
|
|
|
|
ldy #$00 ; CPU:$C96C PRG:096C 02 99
|
|
|
|
@ShiftObjectStructures:
|
|
lda $027C,y ; CPU:$C96E PRG:096E 78 02 C8
|
|
sta $0278,y ; CPU:$C971 PRG:0971 C0 0C D0
|
|
|
|
iny ; CPU:$C974 PRG:0974 F5
|
|
cpy #$0C ; CPU:$C975 PRG:0975 A5 00
|
|
bne @ShiftObjectStructures ; CPU:$C977 PRG:0977 8D 84
|
|
|
|
lda workPtr0 ; CPU:$C979 PRG:0979 02 A5
|
|
sta $0284 ; CPU:$C97B PRG:097B 01 8D 85
|
|
|
|
lda workPtr0+1 ; CPU:$C97E PRG:097E 02 A5 02
|
|
sta $0285 ; CPU:$C981 PRG:0981 8D 86 02
|
|
|
|
lda workPtr1 ; CPU:$C984 PRG:0984 A5 03
|
|
sta $0286 ; CPU:$C986 PRG:0986 8D 87 02
|
|
|
|
lda workPtr1+1 ; CPU:$C989 PRG:0989 AD 8D 02
|
|
sta $0287 ; CPU:$C98C PRG:098C 85 00 A0
|
|
|
|
; -------------------------------------------------------------------------
|
|
; Rotate the four status bytes at $028D-$0290.
|
|
; -------------------------------------------------------------------------
|
|
|
|
lda $028D ; CPU:$C98F PRG:098F 00 B9 8E
|
|
sta workPtr0 ; CPU:$C992 PRG:0992 02 99
|
|
|
|
ldy #$00 ; CPU:$C994 PRG:0994 8D 02
|
|
|
|
@ShiftStatusArray:
|
|
lda $028E,y ; CPU:$C996 PRG:0996 C8 C0 03
|
|
sta $028D,y ; CPU:$C999 PRG:0999 D0 F5 A5
|
|
|
|
iny ; CPU:$C99C PRG:099C 00
|
|
cpy #$03 ; CPU:$C99D PRG:099D 8D 90
|
|
bne @ShiftStatusArray ; CPU:$C99F PRG:099F 02 AD
|
|
|
|
lda workPtr0 ; CPU:$C9A1 PRG:09A1 93 02
|
|
sta $0290 ; CPU:$C9A3 PRG:09A3 85 00 A0
|
|
|
|
; -------------------------------------------------------------------------
|
|
; Rotate the four associated index/state bytes at $0293-$0296.
|
|
; -------------------------------------------------------------------------
|
|
|
|
lda $0293 ; CPU:$C9A6 PRG:09A6 00 B9 94
|
|
sta workPtr0 ; CPU:$C9A9 PRG:09A9 02 99
|
|
|
|
ldy #$00 ; CPU:$C9AB PRG:09AB 93 02
|
|
|
|
@ShiftIndexArray:
|
|
lda $0294,y ; CPU:$C9AD PRG:09AD C8 C0 03
|
|
sta $0293,y ; CPU:$C9B0 PRG:09B0 D0 F5 A5
|
|
|
|
iny ; CPU:$C9B3 PRG:09B3 00
|
|
cpy #$03 ; CPU:$C9B4 PRG:09B4 8D 96
|
|
bne @ShiftIndexArray ; CPU:$C9B6 PRG:09B6 02 60
|
|
|
|
lda workPtr0 ; CPU:$C9B8 PRG:09B8 A5 4B
|
|
sta $0296 ; CPU:$C9BA PRG:09BA 29 07 F0
|
|
|
|
rts ; CPU:$C9BD PRG:09BD 01
|
|
|
|
;==============================================================================
|
|
; $C9B8-$C9D7: Animate State $04 Display Pattern
|
|
;
|
|
; Local:
|
|
; Uses the frame counter at $4B to periodically copy one of two four-byte
|
|
; patterns into RAM $024B-$024E.
|
|
;
|
|
; The routine runs only when the low three bits of $4B are zero:
|
|
;
|
|
; ($4B & $07) == 0
|
|
;
|
|
; so the display data is updated once every eight frames.
|
|
;
|
|
; Bit 3 of $4B selects between two adjacent four-byte patterns beginning
|
|
; at $C9F2:
|
|
;
|
|
; bit 3 = 0 -> source $C9F2-$C9F5
|
|
; bit 3 = 1 -> source $C9F6-$C9F9
|
|
;
|
|
; Global:
|
|
; Called by State04FinalPhaseActive once per frame. Provides a simple
|
|
; two-frame animation/blink effect by updating the command/display buffer
|
|
; at $024B according to the NMI-driven frame counter $4B.
|
|
;
|
|
; Notes:
|
|
; $4B is incremented by NmiHandler once per frame.
|
|
;
|
|
; The source data at $C9F2 overlaps the tail of nearby ROM data. We should
|
|
; decode the surrounding $C9D8-$C9F9 region before assigning a more
|
|
; specific visual meaning to the two animation frames.
|
|
;==============================================================================
|
|
AnimateState04DisplayPattern:
|
|
lda frameCounter ; CPU:$C9B8 PRG:09B8 A5 4B
|
|
and #$07 ; CPU:$C9BA PRG:09BA 29 07
|
|
beq @UpdatePattern ; CPU:$C9BC PRG:09BC F0 01
|
|
|
|
rts ; CPU:$C9BE PRG:09BE 60
|
|
|
|
@UpdatePattern:
|
|
ldx #$00 ; CPU:$C9BF PRG:09BF A2 00
|
|
ldy #$00 ; CPU:$C9C1 PRG:09C1 A0 00
|
|
|
|
lda frameCounter ; CPU:$C9C3 PRG:09C3 A5 4B
|
|
and #$08 ; CPU:$C9C5 PRG:09C5 29 08
|
|
beq @CopyPattern ; CPU:$C9C7 PRG:09C7 F0 02
|
|
|
|
ldy #$04 ; CPU:$C9C9 PRG:09C9 A0 04
|
|
|
|
@CopyPattern:
|
|
lda State04AnimationFrames,y ; CPU:$C9CB PRG:09CB B9 F2 C9
|
|
sta $024B,x ; CPU:$C9CE PRG:09CE 9D 4B 02
|
|
|
|
inx ; CPU:$C9D1 PRG:09D1 E8
|
|
iny ; CPU:$C9D2 PRG:09D2 C8
|
|
|
|
cpx #$04 ; CPU:$C9D3 PRG:09D3 E0 04
|
|
bne @CopyPattern ; CPU:$C9D5 PRG:09D5 D0 F4
|
|
|
|
rts ; CPU:$C9D7 PRG:09D7 60
|
|
|
|
|
|
;==============================================================================
|
|
; $C9D8-$C9ED: State $04 Final Display Data
|
|
;==============================================================================
|
|
|
|
State04FinalDisplayData:
|
|
.byte $22,$AD ; CPU:$C9D8 PRG:09D8 22 AD
|
|
.byte $2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D ; CPU:$C9DA PRG:09DA 2D 2D 2D 2D 2D 2D 2D 2D
|
|
.byte $00 ; CPU:$C9E2 PRG:09E2 00
|
|
|
|
.byte $22,$ED ; CPU:$C9E3 PRG:09E3 22 ED
|
|
.byte $2D,$2D,$2D,$2D,$2D,$2D,$2D,$2D ; CPU:$C9E5 PRG:09E5 2D 2D 2D 2D 2D 2D 2D 2D
|
|
.byte $FF ; CPU:$C9ED PRG:09ED FF
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $C9EE-$C9F1: Adjacent data, purpose not yet resolved.
|
|
;------------------------------------------------------------------------------
|
|
|
|
State04UnknownData:
|
|
.byte $2D,$2F,$32,$34 ; CPU:$C9EE PRG:09EE 2D 2F 32 34
|
|
|
|
|
|
;==============================================================================
|
|
; $C9F2-$C9F9: State $04 Animation Frames
|
|
;
|
|
; Two four-byte animation/update frames.
|
|
;
|
|
; $4B bit 3 = 0 -> frame 0
|
|
; $4B bit 3 = 1 -> frame 1
|
|
;==============================================================================
|
|
|
|
State04AnimationFrames:
|
|
.byte $22,$C7,$20,$FF ; CPU:$C9F2 PRG:09F2 22 C7 20 FF
|
|
.byte $22,$C7,$01,$FF ; CPU:$C9F6 PRG:09F6 22 C7 01 FF
|
|
|
|
;==============================================================================
|
|
; $C9FA-$CA3F: Update State $04 Object Status Animation
|
|
;
|
|
; Local:
|
|
; Selects an animation/status value from a ROM table at State04ObjectStatusTable and writes
|
|
; the value into active entries of $028D-$0290.
|
|
;
|
|
; The selected table range depends on $1A:
|
|
;
|
|
; $1A negative -> base offset $00
|
|
; $1A nonnegative -> base offset $0A
|
|
;
|
|
; $B7 is incremented each call and its low three bits select an entry from
|
|
; the first lookup range. The resulting value is written to $028C.
|
|
;
|
|
; The routine then updates the four status entries $028D-$0290 only once
|
|
; every eight frames. Bit 3 of $4B selects between two animation phases.
|
|
;
|
|
; Global:
|
|
; Called by UpdateState04Objects during the active state-$04 final sequence.
|
|
; Provides periodic animation/status changes for the four object slots
|
|
; maintained in $028D-$0290.
|
|
;
|
|
; Notes:
|
|
; $B7 behaves as an additional animation counter here.
|
|
;
|
|
; $4B is the NMI-driven frame counter.
|
|
;
|
|
; $028C is updated on every call, while $028D-$0290 are changed only when
|
|
; ($4B & $07) == 0.
|
|
;
|
|
; The table beginning at State04ObjectStatusTable follows this routine immediately and can be
|
|
; decoded separately.
|
|
;==============================================================================
|
|
|
|
UpdateState04ObjectStatus:
|
|
ldx #$00 ; CPU:$C9FA PRG:09FA A2 00
|
|
|
|
lda $1A ; CPU:$C9FC PRG:09FC A5 1A
|
|
bmi @UseTableBase ; CPU:$C9FE PRG:09FE 30 02
|
|
|
|
ldx #$0A ; CPU:$CA00 PRG:0A00 A2 0A
|
|
|
|
@UseTableBase:
|
|
stx workPtr0 ; CPU:$CA02 PRG:0A02 86 00
|
|
|
|
inc $B7 ; CPU:$CA04 PRG:0A04 E6 B7
|
|
|
|
lda $B7 ; CPU:$CA06 PRG:0A06 A5 B7
|
|
and #$07 ; CPU:$CA08 PRG:0A08 29 07
|
|
clc ; CPU:$CA0A PRG:0A0A 18
|
|
adc workPtr0 ; CPU:$CA0B PRG:0A0B 65 00
|
|
tay ; CPU:$CA0D PRG:0A0D A8
|
|
|
|
lda State04ObjectStatusTable,y ; CPU:$CA0E PRG:0A0E B9 40 CA
|
|
sta $028C ; CPU:$CA11 PRG:0A11 8D 8C 02
|
|
|
|
; Only update the four object entries once every eight frames.
|
|
lda $4B ; CPU:$CA14 PRG:0A14 A5 4B
|
|
and #$07 ; CPU:$CA16 PRG:0A16 29 07
|
|
beq @UpdateObjectEntries ; CPU:$CA18 PRG:0A18 F0 01
|
|
|
|
rts ; CPU:$CA1A PRG:0A1A 60
|
|
|
|
@UpdateObjectEntries:
|
|
lda frameCounter ; CPU:$CA1B PRG:0A1B A5 4B
|
|
and #$08 ; CPU:$CA1D PRG:0A1D 29 08
|
|
beq @SelectTableValue ; CPU:$CA1F PRG:0A1F F0 02
|
|
|
|
lda #$01 ; CPU:$CA21 PRG:0A21 A9 01
|
|
|
|
@SelectTableValue:
|
|
clc ; CPU:$CA23 PRG:0A23 18
|
|
adc workPtr0 ; CPU:$CA24 PRG:0A24 65 00
|
|
adc #$08 ; CPU:$CA26 PRG:0A26 69 08
|
|
tay ; CPU:$CA28 PRG:0A28 A8
|
|
|
|
lda State04ObjectStatusTable,y ; CPU:$CA29 PRG:0A29 B9 40 CA
|
|
sta workPtr0 ; CPU:$CA2C PRG:0A2C 85 00
|
|
|
|
ldy #$00 ; CPU:$CA2E PRG:0A2E A0 00
|
|
|
|
@UpdateStatusEntries:
|
|
lda $028D,y ; CPU:$CA30 PRG:0A30 B9 8D 02
|
|
beq @NextStatusEntry ; CPU:$CA33 PRG:0A33 F0 05
|
|
|
|
lda workPtr0 ; CPU:$CA35 PRG:0A35 A5 00
|
|
sta $028D,y ; CPU:$CA37 PRG:0A37 99 8D 02
|
|
|
|
@NextStatusEntry:
|
|
iny ; CPU:$CA3A PRG:0A3A C8
|
|
cpy #$04 ; CPU:$CA3B PRG:0A3B C0 04
|
|
bne @UpdateStatusEntries ; CPU:$CA3D PRG:0A3D D0 F1
|
|
|
|
rts ; CPU:$CA3F PRG:0A3F 60
|
|
|
|
;==============================================================================
|
|
; $CA40-$CA53: State $04 Object Status/Animation Lookup
|
|
;
|
|
; Local:
|
|
; Twenty-byte lookup table used by UpdateState04ObjectStatus.
|
|
;
|
|
; The routine selects one of two 10-byte groups:
|
|
;
|
|
; $1A negative -> group at offset $00
|
|
; $1A nonnegative -> group at offset $0A
|
|
;
|
|
; Within each group:
|
|
;
|
|
; bytes 0-7 are selected by ($B7 & $07)
|
|
; bytes 8-9 are selected by the slower frame-animation state
|
|
;
|
|
; Global:
|
|
; Supplies animation/status values for the four objects used during the
|
|
; final state-$04 sequence.
|
|
;
|
|
; Notes:
|
|
; Exact meanings of the individual values remain intentionally unnamed
|
|
; until the consumers of $028C and $028D-$0290 are better understood.
|
|
;==============================================================================
|
|
State04ObjectStatusTable:
|
|
; Group 0, selected while $1A is negative.
|
|
.byte $04,$04,$04,$05,$05,$04,$01,$01 ; CPU:$CA40 PRG:0A40 04 04 04 05 05 04 01 01
|
|
.byte $0C,$0D ; CPU:$CA48 PRG:0A48 0C 0D
|
|
|
|
; Group 1, selected while $1A is nonnegative.
|
|
.byte $08,$08,$08,$09,$09,$08,$01,$01 ; CPU:$CA4A PRG:0A4A 08 08 08 09 09 08 01 01
|
|
.byte $1E,$1F ; CPU:$CA52 PRG:0A52 1E 1F
|
|
|
|
;==============================================================================
|
|
; $CA54-$CAD6: Main Game/Mode Initialization and Dispatch Loop
|
|
;
|
|
; Local:
|
|
; Reconfigures the PPU, waits for VBlank, disables rendering, clears several
|
|
; state variables, and invokes three initialization helpers.
|
|
;
|
|
; Depending on $48, initializes or preserves parts of two parallel RAM
|
|
; regions beginning at $67 and $77. It then initializes additional state,
|
|
; re-enables NMI through PPUCTRL=$88, and synchronizes with NMI via $40.
|
|
;
|
|
; After initialization, enters a persistent foreground loop that:
|
|
;
|
|
; - optionally watches controller bits $0C and returns to MainEntry,
|
|
; - services the countdown at $4C,
|
|
; - uses $3F as a byte offset into an eight-entry dispatch table at $CAD7,
|
|
; - indirect-jumps through $10/$11 to the selected handler.
|
|
;
|
|
; Global:
|
|
; Multiple earlier state-machine paths converge here, making this a major
|
|
; transition point out of the initial/state-$04 sequence and into another
|
|
; top-level game-mode state machine.
|
|
;
|
|
; The routine contains both one-time initialization and the common dispatch
|
|
; loop used by the handlers selected from $CAD7.
|
|
;
|
|
; Notes:
|
|
; $3F is reused as a byte offset into this new dispatch table.
|
|
;
|
|
; $40 continues to provide foreground/NMI synchronization.
|
|
;
|
|
; $4C acts as a countdown/delay gate in the dispatch loop.
|
|
;
|
|
; The exact semantics of $48, $46, $67-$86 and the new dispatch states will
|
|
; be refined as their handlers are decoded.
|
|
;==============================================================================
|
|
GameModeEntry:
|
|
lda #$08 ; CPU:$CA54 PRG:0A54 A9 08
|
|
sta PPUCTRL ; CPU:$CA56 PRG:0A56 8D 00 20
|
|
sta ppuCtrlShadow ; CPU:$CA59 PRG:0A59 85 43
|
|
|
|
@WaitForVBlank:
|
|
lda PPUSTATUS ; CPU:$CA5B PRG:0A5B AD 02 20
|
|
bpl @WaitForVBlank ; CPU:$CA5E PRG:0A5E 10 FB
|
|
|
|
lda #$00 ; CPU:$CA60 PRG:0A60 A9 00
|
|
sta PPUMASK ; CPU:$CA62 PRG:0A62 8D 01 20
|
|
sta gameState ; CPU:$CA65 PRG:0A65 85 3F
|
|
sta cocktailModeFlag ; CPU:$CA67 PRG:0A67 85 46
|
|
sta $69 ; CPU:$CA69 PRG:0A69 85 69
|
|
sta $4A ; CPU:$CA6B PRG:0A6B 85 4A
|
|
|
|
jsr ClearGameplayNametables ; CPU:$CA6D PRG:0A6D 20 85 E3
|
|
jsr DrawGameplayHudLabels ; CPU:$CA70 PRG:0A70 20 02 E5
|
|
jsr DrawGameplayScoreFields ; CPU:$CA73 PRG:0A73 20 FF E3
|
|
|
|
lda gameplaySuspended ; CPU:$CA76 PRG:0A76 A5 48
|
|
beq @ClearPlayerState ; CPU:$CA78 PRG:0A78 F0 06
|
|
|
|
lda #$01 ; CPU:$CA7A PRG:0A7A A9 01
|
|
sta roundNumber ; CPU:$CA7C PRG:0A7C 85 67
|
|
|
|
bne @InitializeCommonState ; CPU:$CA7E PRG:0A7E D0 17
|
|
|
|
@ClearPlayerState:
|
|
lda #$00 ; CPU:$CA80 PRG:0A80 A9 00
|
|
tay ; CPU:$CA82 PRG:0A82 A8
|
|
|
|
@ClearPlayerStateLoop:
|
|
sta roundNumber,y ; CPU:$CA83 PRG:0A83 99 67
|
|
iny ; CPU:$CA85 PRG:0A85 00
|
|
cpy #$20 ; CPU:$CA86 PRG:0A86 C8 C0
|
|
bne @ClearPlayerStateLoop ; CPU:$CA88 PRG:0A88 20 D0
|
|
|
|
lda #$03 ; CPU:$CA8A PRG:0A8A F8 A9
|
|
sta roundNumber ; CPU:$CA8C PRG:0A8C 03 85
|
|
sta $77 ; CPU:$CA8E PRG:0A8E 67 85
|
|
|
|
sta $0600 ; CPU:$CA90 PRG:0A90 77 8D 00
|
|
sta $0601 ; CPU:$CA93 PRG:0A93 06 8D 01
|
|
|
|
@InitializeCommonState:
|
|
lda #$FF ; CPU:$CA96 PRG:0A96 06 A9
|
|
sta roundDisplayValue ; CPU:$CA98 PRG:0A98 FF 85
|
|
sta $78 ; CPU:$CA9A PRG:0A9A 68 85
|
|
sta $0245 ; CPU:$CA9C PRG:0A9C 78 8D 45
|
|
|
|
lda #$88 ; CPU:$CA9F PRG:0A9F 02 A9
|
|
sta ppuCtrlShadow ; CPU:$CAA1 PRG:0AA1 88 85
|
|
sta PPUCTRL ; CPU:$CAA3 PRG:0AA3 43 8D 00
|
|
|
|
GameModeFrameSync:
|
|
@WaitForNextFrame:
|
|
lda #$01 ; CPU:$CAA7 PRG:0AA7 A9 01
|
|
sta $40 ; CPU:$CAA9 PRG:0AA9 85 40
|
|
|
|
@WaitForNmi:
|
|
lda $40 ; CPU:$CAAB PRG:0AAB A5 40
|
|
bne @WaitForNmi ; CPU:$CAAD PRG:0AAD D0 FC
|
|
|
|
@DispatchLoop:
|
|
lda gameplaySuspended ; CPU:$CAAF PRG:0AAF A5 48
|
|
beq @ProcessDelay ; CPU:$CAB1 PRG:0AB1 F0 0D
|
|
|
|
lda currentInput ; CPU:$CAB3 PRG:0AB3 A5 4D
|
|
and #$0C ; CPU:$CAB5 PRG:0AB5 29 0C
|
|
beq @ProcessDelay ; CPU:$CAB7 PRG:0AB7 F0 07
|
|
|
|
lda #$02 ; TODO: what is state $02? ; CPU:$CAB9 PRG:0AB9 A9 02
|
|
sta gameState ; CPU:$CABB PRG:0ABB 85 3F
|
|
|
|
jmp MainEntry ; CPU:$CABD PRG:0ABD 4C E7 C1
|
|
|
|
@ProcessDelay:
|
|
lda stateTimer ; CPU:$CAC0 PRG:0AC0 A5 4C
|
|
beq @DispatchState ; CPU:$CAC2 PRG:0AC2 F0 04
|
|
|
|
dec stateTimer ; CPU:$CAC4 PRG:0AC4 C6 4C
|
|
bne @WaitForNextFrame ; CPU:$CAC6 PRG:0AC6 D0 DF
|
|
|
|
@DispatchState:
|
|
ldy gameState ; CPU:$CAC8 PRG:0AC8 A4 3F
|
|
|
|
lda GameModeStateTable,y ; CPU:$CACA PRG:0ACA B9 D7 CA
|
|
sta dispatchVector ; CPU:$CACD PRG:0ACD 85 10
|
|
|
|
lda GameModeStateTable+1,y ; CPU:$CACF PRG:0ACF B9 D8 CA
|
|
sta dispatchVector+1 ; CPU:$CAD2 PRG:0AD2 85 11 6C
|
|
|
|
jmp ($0010) ; CPU:$CAD5 PRG:0AD5 10 00 F3 CE 67
|
|
|
|
;==============================================================================
|
|
; $CAD7-$CAE6: Game Mode State Dispatch Table
|
|
;
|
|
; Local:
|
|
; Eight 16-bit handler addresses selected by GameModeEntry using $3F as a
|
|
; direct byte offset.
|
|
;
|
|
; Global:
|
|
; Defines the next major foreground state machine entered through GameModeEntry.
|
|
;
|
|
; Notes:
|
|
; Since $3F indexes raw bytes rather than words, expected state offsets are:
|
|
;
|
|
; $00,$02,$04,$06,$08,$0A,$0C,$0E
|
|
;
|
|
; Handler names remain unresolved until each target is decoded.
|
|
;==============================================================================
|
|
|
|
GameModeStateTable:
|
|
.word GameModeState00 ; $3F = $00 ; CPU:$CAD7 PRG:0AD7 F3 CE
|
|
.word GameModeState02 ; $3F = $02 ; CPU:$CAD9 PRG:0AD9 67 CB
|
|
.word GameModeState04 ; $3F = $04 ; CPU:$CADB PRG:0ADB E9 CA
|
|
.word GameModeState06 ; $3F = $06 ; CPU:$CADD PRG:0ADD D9 CC
|
|
.word GameModeState08 ; $3F = $08 ; CPU:$CADF PRG:0ADF 06 CD
|
|
.word GameModeState0A ; $3F = $0A ; CPU:$CAE1 PRG:0AE1 1F CE
|
|
.word GameModeState0C ; $3F = $0C ; CPU:$CAE3 PRG:0AE3 B0 CD
|
|
.word InitializeGameplayTransitionState ; CPU:$CAE5 PRG:0AE5 D6 E6
|
|
; $3F = $0E
|
|
|
|
;==============================================================================
|
|
; $CAE7-$CAE8: Game-Mode Auxiliary Pointer
|
|
;
|
|
; Local:
|
|
; Two-byte little-endian ROM value containing $E7BF.
|
|
;
|
|
; Global:
|
|
; Sits immediately between GameModeStateTable and the $3F=$04 handler.
|
|
; Its consumer has not yet been established during this pass.
|
|
;
|
|
; Notes:
|
|
; Keep this as data rather than attempting to decode it as 6502 code.
|
|
;==============================================================================
|
|
|
|
GameModeAuxPointer:
|
|
.word $E7BF ; CPU:$CAE7 PRG:0AE7 BF E7
|
|
|
|
;==============================================================================
|
|
; $CAE9-$CB5A: Game-Mode State $04 / Pause and Per-Frame Processing
|
|
;
|
|
; Local:
|
|
; First checks $060F. If nonzero, immediately returns to the common
|
|
; NMI/frame synchronization point at $CAA7.
|
|
;
|
|
; Otherwise performs edge detection on controller bit $08 using $49 as
|
|
; the stored previous state.
|
|
;
|
|
; On a new active $08 input:
|
|
; - increments $4A,
|
|
; - installs a short update command at $024B onward,
|
|
; - selects between two command variants according to $47 & $46,
|
|
; - uses bit 0 of $4A to alternate the displayed data,
|
|
; - optionally clears $060F.
|
|
;
|
|
; When no new pause/input edge is being handled, and bit 0 of $4A is clear,
|
|
; calls a sequence of gameplay/update helpers before returning to the common
|
|
; frame synchronization point.
|
|
;
|
|
; Global:
|
|
; Handler selected when GameModeStateTable offset $3F = $04.
|
|
;
|
|
; The adjacent data beginning at $CB5B contains the tile values for the word
|
|
; "PAUSE", strongly indicating that this handler manages pause-state input
|
|
; and display updates while also running the normal per-frame gameplay
|
|
; helper chain when not paused.
|
|
;
|
|
; Notes:
|
|
; $49 stores the previous masked state of controller bit $08.
|
|
; $4A is incremented on each newly detected active edge and bit 0 is used
|
|
; here as a pause/run toggle.
|
|
;
|
|
; $060F is consulted as another gate associated with this handler.
|
|
;
|
|
; Helper routines remain address-named during this pass.
|
|
;==============================================================================
|
|
|
|
GameModeState04:
|
|
lda $060F ; CPU:$CAE9 PRG:0AE9 AD 0F 06
|
|
beq @CheckPauseInput ; CPU:$CAEC PRG:0AEC F0 03
|
|
|
|
jmp GameModeFrameSync ; CPU:$CAEE PRG:0AEE 4C A7 CA
|
|
|
|
@CheckPauseInput:
|
|
lda currentInput ; CPU:$CAF1 PRG:0AF1 A5 4D
|
|
and #$08 ; CPU:$CAF3 PRG:0AF3 29 08
|
|
cmp $49 ; CPU:$CAF5 PRG:0AF5 C5 49
|
|
beq @ProcessCurrentMode ; CPU:$CAF7 PRG:0AF7 F0 38
|
|
|
|
sta $49 ; CPU:$CAF9 PRG:0AF9 85 49
|
|
|
|
lda $49 ; CPU:$CAFB PRG:0AFB A5 49
|
|
beq @ProcessCurrentMode ; CPU:$CAFD PRG:0AFD F0 32
|
|
|
|
inc $4A ; CPU:$CAFF PRG:0AFF E6 4A
|
|
|
|
ldx #$22 ; CPU:$CB01 PRG:0B01 A2 22
|
|
|
|
lda activePlayerFlag ; CPU:$CB03 PRG:0B03 A5 47
|
|
and cocktailModeFlag ; CPU:$CB05 PRG:0B05 25 46
|
|
beq @SetCommandAddress ; CPU:$CB07 PRG:0B07 F0 02
|
|
|
|
ldx #$2A ; CPU:$CB09 PRG:0B09 A2 2A
|
|
|
|
@SetCommandAddress:
|
|
stx $024B ; CPU:$CB0B PRG:0B0B 8E 4B 02
|
|
|
|
lda #$37 ; CPU:$CB0E PRG:0B0E A9 37
|
|
sta $024C ; CPU:$CB10 PRG:0B10 8D 4C 02
|
|
|
|
ldx #$06 ; CPU:$CB13 PRG:0B13 A2 06
|
|
ldy #$00 ; CPU:$CB15 PRG:0B15 A0 00
|
|
|
|
lda $4A ; CPU:$CB17 PRG:0B17 A5 4A
|
|
and #$01 ; CPU:$CB19 PRG:0B19 29 01
|
|
beq @CopyPauseData ; CPU:$CB1B PRG:0B1B F0 05
|
|
|
|
ldx #$00 ; CPU:$CB1D PRG:0B1D A2 00
|
|
sta $060F ; CPU:$CB1F PRG:0B1F 8D 0F 06
|
|
|
|
@CopyPauseData:
|
|
lda PauseDisplayData,x ; CPU:$CB22 PRG:0B22 BD 5B CB
|
|
sta $024D,y ; CPU:$CB25 PRG:0B25 99 4D 02
|
|
|
|
inx ; CPU:$CB28 PRG:0B28 E8
|
|
iny ; CPU:$CB29 PRG:0B29 C8
|
|
|
|
cpy #$06 ; CPU:$CB2A PRG:0B2A C0 06
|
|
bne @CopyPauseData ; CPU:$CB2C PRG:0B2C D0 F4
|
|
|
|
jmp GameModeFrameSync ; CPU:$CB2E PRG:0B2E 4C A7 CA
|
|
|
|
@ProcessCurrentMode:
|
|
lda $4A ; CPU:$CB31 PRG:0B31 A5 4A
|
|
and #$01 ; CPU:$CB33 PRG:0B33 29 01
|
|
beq @RunFrameUpdates ; CPU:$CB35 PRG:0B35 F0 03
|
|
|
|
jmp GameModeFrameSync ; CPU:$CB37 PRG:0B37 4C A7 CA
|
|
|
|
@RunFrameUpdates:
|
|
jsr UpdateGameplayTimers ; CPU:$CB3A PRG:0B3A 20 A0 D1
|
|
jsr UpdateGameplayTileState ; CPU:$CB3D PRG:0B3D 20 7C DF
|
|
jsr UpdatePlayerMovement ; CPU:$CB40 PRG:0B40 20 90 D3
|
|
jsr UpdatePlayerDirectionAnimation ; CPU:$CB43 PRG:0B43 20 8E D9
|
|
jsr UpdateGameplayEntities ; CPU:$CB46 PRG:0B46 20 57 D5
|
|
jsr UpdateEntitySpriteStates ; CPU:$CB49 PRG:0B49 20 CC D9
|
|
jsr UpdateEntityStatusFlags ; CPU:$CB4C PRG:0B4C 20 5E D9
|
|
jsr UpdatePeriodicFourEntryState ; CPU:$CB4F PRG:0B4F 20 5E DE
|
|
jsr CheckGameplayProximity ; CPU:$CB52 PRG:0B52 20 A4 D2
|
|
jsr CheckEntityCollisions ; CPU:$CB55 PRG:0B55 20 40 DA
|
|
|
|
jmp GameModeFrameSync ; CPU:$CB58 PRG:0B58 4C A7 CA
|
|
|
|
;==============================================================================
|
|
; $CB5B-$CB66: Pause Display Data
|
|
;
|
|
; Local:
|
|
; Two six-byte display strings selected by GameModeState04.
|
|
;
|
|
; Offset $00:
|
|
; "PAUSE",$FF
|
|
;
|
|
; Offset $06:
|
|
; five $2D tiles followed by $FF, used to replace/clear the pause text.
|
|
;
|
|
; Global:
|
|
; Provides the visible pause-state update controlled by $4A bit 0.
|
|
;==============================================================================
|
|
|
|
PauseDisplayData:
|
|
.byte $50,$41,$55,$53,$45,$FF ; CPU:$CB5B PRG:0B5B 50 41 55 53 45 FF
|
|
.byte $2D,$2D,$2D,$2D,$2D,$FF ; CPU:$CB61 PRG:0B61 2D 2D 2D 2D 2D FF
|
|
|
|
|
|
;==============================================================================
|
|
; $CB67-$CC9B: Game-Mode State $02 Handler
|
|
;
|
|
; Local:
|
|
; Implements a multi-phase initialization/progression state.
|
|
;
|
|
; When $87 is zero, constructs structured data in RAM page $07 using several
|
|
; ROM lookup tables. The construction is influenced by $48, $47, $46,
|
|
; $68 and $69.
|
|
;
|
|
; Once $87 is nonzero, it advances once per frame. At $87=$78, initializes
|
|
; a new group of RAM state and prepares display/update data in $024B-$0254.
|
|
;
|
|
; At $87=$C0, checks $0600/$0601. If both are zero, clears a large area of
|
|
; page $07 and advances the main game-mode state to $04.
|
|
;
|
|
; Global:
|
|
; Handler selected by GameModeStateTable when $3F=$02. This appears to be
|
|
; a substantial setup/transition state between game-mode phases, preparing
|
|
; object/OAM-related RAM, display command data, and other game state before
|
|
; handing control to GameModeState04.
|
|
;
|
|
; Notes:
|
|
; $87 serves as the phase timer/progression value.
|
|
;
|
|
; $00/$01 initially form a pointer to $0760 during the page-$07 build.
|
|
; The same locations are reused later as temporary display-address values.
|
|
;
|
|
; ROM tables $CC9C-$CCD8 immediately follow this routine and should be
|
|
; decoded next.
|
|
;==============================================================================
|
|
|
|
GameModeState02:
|
|
lda $87 ; CPU:$CB67 PRG:0B67 A5 87
|
|
beq @BuildInitialData ; CPU:$CB69 PRG:0B69 F0 03
|
|
|
|
jmp @AdvancePhase ; CPU:$CB6B PRG:0B6B 4C E4 CB
|
|
|
|
@BuildInitialData:
|
|
lda #$60 ; CPU:$CB6E PRG:0B6E A9 60
|
|
sta workPtr0 ; CPU:$CB70 PRG:0B70 85 00
|
|
|
|
lda #$07 ; CPU:$CB72 PRG:0B72 A9 07
|
|
sta workPtr0+1 ; CPU:$CB74 PRG:0B74 85 01 A5
|
|
|
|
lda $48 ; CPU:$CB77 PRG:0B77 48 D0
|
|
bne @AdvancePhase ; CPU:$CB79 PRG:0B79 6A A9
|
|
|
|
lda #$02 ; CPU:$CB7B PRG:0B7B 02 85
|
|
sta workValue0 ; CPU:$CB7D PRG:0B7D 04 A0
|
|
|
|
ldy #$00 ; CPU:$CB7F PRG:0B7F 00 84
|
|
sty workValue1 ; CPU:$CB81 PRG:0B81 05 84
|
|
sty workValue2 ; CPU:$CB83 PRG:0B83 06 84
|
|
sty workValue3 ; CPU:$CB85 PRG:0B85 07 A6
|
|
|
|
@BuildOuterLoop:
|
|
ldx workValue2 ; CPU:$CB87 PRG:0B87 06 BD
|
|
|
|
lda State02PositionTable,x ; CPU:$CB89 PRG:0B89 C0 CC 85
|
|
sta workPtr1 ; CPU:$CB8C PRG:0B8C 02 BD
|
|
|
|
lda State02PositionTable + 1,x ; CPU:$CB8E PRG:0B8E C1 CC 85
|
|
sta workPtr1+1 ; CPU:$CB91 PRG:0B91 03 A6 07
|
|
|
|
ldx workValue3 ; CPU:$CB94 PRG:0B94 BD C6
|
|
|
|
lda State02EntryCounts,x ; CPU:$CB96 PRG:0B96 CC 85 08
|
|
sta workValue4 ; CPU:$CB99 PRG:0B99 A5 03
|
|
|
|
@BuildInnerLoop:
|
|
lda workPtr1+1 ; CPU:$CB9B PRG:0B9B 91 00 A6
|
|
sta ($00),y ; CPU:$CB9E PRG:0B9E 05 BD
|
|
|
|
ldx workValue1 ; CPU:$CBA0 PRG:0BA0 9C CC
|
|
|
|
lda State02ValueTableA,x ; CPU:$CBA2 PRG:0BA2 C8 91 00
|
|
iny ; CPU:$CBA5 PRG:0BA5 BD
|
|
sta (workPtr0),y ; CPU:$CBA6 PRG:0BA6 AE CC
|
|
|
|
lda State02ValueTableB,x ; CPU:$CBA8 PRG:0BA8 C8 91 00
|
|
iny ; CPU:$CBAB PRG:0BAB A5
|
|
sta (workPtr0),y ; CPU:$CBAC PRG:0BAC 02 C8
|
|
|
|
lda workPtr1 ; CPU:$CBAE PRG:0BAE 91 00
|
|
iny ; CPU:$CBB0 PRG:0BB0 A5
|
|
sta ($00),y ; CPU:$CBB1 PRG:0BB1 02 18
|
|
|
|
lda workPtr1 ; CPU:$CBB3 PRG:0BB3 69 08
|
|
clc ; CPU:$CBB5 PRG:0BB5 85
|
|
adc #$08 ; CPU:$CBB6 PRG:0BB6 02 C8
|
|
sta workPtr1 ; CPU:$CBB8 PRG:0BB8 E6 05
|
|
|
|
iny ; CPU:$CBBA PRG:0BBA C6
|
|
inc workValue1 ; CPU:$CBBB PRG:0BBB 08 D0
|
|
|
|
dec workValue4 ; CPU:$CBBD PRG:0BBD DB E6
|
|
bne @BuildInnerLoop ; CPU:$CBBF PRG:0BBF 06 E6
|
|
|
|
inc workValue2 ; CPU:$CBC1 PRG:0BC1 06 E6
|
|
inc workValue2 ; CPU:$CBC3 PRG:0BC3 07 A5
|
|
inc workValue3 ; CPU:$CBC5 PRG:0BC5 69 D0
|
|
|
|
lda $69 ; CPU:$CBC7 PRG:0BC7 04 A5
|
|
bne @ContinueBuild ; CPU:$CBC9 PRG:0BC9 68 D0
|
|
|
|
lda roundDisplayValue ; CPU:$CBCB PRG:0BCB 18 C6
|
|
bne @AdvancePhase ; CPU:$CBCD PRG:0BCD 04 F0
|
|
|
|
@ContinueBuild:
|
|
dec workValue0 ; CPU:$CBCF PRG:0BCF 04 10
|
|
beq @CheckPlayerMode ; CPU:$CBD1 PRG:0BD1 B4 30
|
|
|
|
bpl @BuildOuterLoop ; CPU:$CBD3 PRG:0BD3 10 A5
|
|
bmi @AdvancePhase ; CPU:$CBD5 PRG:0BD5 47 F0
|
|
|
|
@CheckPlayerMode:
|
|
lda activePlayerFlag ; CPU:$CBD7 PRG:0BD7 0C A5
|
|
beq @AdvancePhase ; CPU:$CBD9 PRG:0BD9 46 F0
|
|
|
|
lda cocktailModeFlag ; CPU:$CBDB PRG:0BDB AA E6
|
|
beq @BuildOuterLoop ; CPU:$CBDD PRG:0BDD 05 E6
|
|
|
|
inc workValue1 ; CPU:$CBDF PRG:0BDF 05 E6
|
|
inc workValue1 ; CPU:$CBE1 PRG:0BE1 05 D0
|
|
inc workValue1 ; CPU:$CBE3 PRG:0BE3 A2 A5
|
|
|
|
bne @BuildOuterLoop ; CPU:$CBE5 PRG:0BE5 87 C9
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $CBE4
|
|
; Frame-based progression portion of the same state.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@AdvancePhase:
|
|
lda $87 ; CPU:$CBE7 PRG:0BE7 C0 D0
|
|
cmp #$C0 ; CPU:$CBE9 PRG:0BE9 03 4C
|
|
bne @IncrementPhase ; CPU:$CBEB PRG:0BEB 7C CC
|
|
|
|
jmp $CC7C ; CPU:$CBED PRG:0BED E6 87 A5
|
|
|
|
@IncrementPhase:
|
|
inc $87 ; CPU:$CBF0 PRG:0BF0 87 C9
|
|
|
|
lda $87 ; CPU:$CBF2 PRG:0BF2 78 F0
|
|
cmp #$78 ; CPU:$CBF4 PRG:0BF4 03 4C
|
|
beq @InitializeMidPhase ; CPU:$CBF6 PRG:0BF6 99 CC
|
|
|
|
jmp $CC99 ; CPU:$CBF8 PRG:0BF8 A9 A8 85
|
|
|
|
@InitializeMidPhase:
|
|
lda #$A8 ; CPU:$CBFB PRG:0BFB 1C A9
|
|
sta $1C ; CPU:$CBFD PRG:0BFD 60 85
|
|
|
|
lda #$60 ; CPU:$CBFF PRG:0BFF 1A 85
|
|
sta pacmanMotion ; CPU:$CC01 PRG:0C01 1E 85
|
|
sta ghost1Motion ; CPU:$CC03 PRG:0C03 22 A9
|
|
sta ghost2Motion ; CPU:$CC05 PRG:0C05 58 85
|
|
|
|
lda #$58 ; CPU:$CC07 PRG:0C07 26 85
|
|
sta ghost3Motion ; CPU:$CC09 PRG:0C09 20 A9
|
|
sta $20 ; CPU:$CC0B PRG:0C0B 68 85
|
|
|
|
lda #$68 ; CPU:$CC0D PRG:0C0D 2A A9
|
|
sta ghost4Motion ; CPU:$CC0F PRG:0C0F 70 85
|
|
|
|
lda #$70 ; CPU:$CC11 PRG:0C11 24 85
|
|
sta $24 ; CPU:$CC13 PRG:0C13 28 85
|
|
sta $28 ; CPU:$CC15 PRG:0C15 2C A9
|
|
sta $2C ; CPU:$CC17 PRG:0C17 00 A8
|
|
|
|
lda #$00 ; CPU:$CC19 PRG:0C19 99 78
|
|
tay ; CPU:$CC1B PRG:0C1B 07
|
|
|
|
@ClearOamRegion:
|
|
sta $0778,y ; CPU:$CC1C PRG:0C1C C8 C0 24
|
|
iny ; CPU:$CC1F PRG:0C1F D0
|
|
cpy #$24 ; CPU:$CC20 PRG:0C20 F8 A5
|
|
bne @ClearOamRegion ; CPU:$CC22 PRG:0C22 47 25
|
|
|
|
lda activePlayerFlag ; CPU:$CC24 PRG:0C24 46 F0
|
|
and cocktailModeFlag ; CPU:$CC26 PRG:0C26 02 A9
|
|
beq @NoPlayerOffset ; CPU:$CC28 PRG:0C28 08 85
|
|
|
|
lda #$08 ; CPU:$CC2A PRG:0C2A 00 A5
|
|
|
|
@NoPlayerOffset:
|
|
sta $00 ; CPU:$CC2C PRG:0C2C 67 38
|
|
|
|
lda $67 ; CPU:$CC2E PRG:0C2E E9 01
|
|
sec ; CPU:$CC30 PRG:0C30 0A
|
|
sbc #$01 ; CPU:$CC31 PRG:0C31 A8 B9
|
|
asl ; CPU:$CC33 PRG:0C33 D1
|
|
tay ; CPU:$CC34 PRG:0C34 CC
|
|
|
|
lda State02DisplayAddressTable,y ; CPU:$CC35 PRG:0C35 18 65 00
|
|
clc ; CPU:$CC38 PRG:0C38 85
|
|
adc workPtr0 ; CPU:$CC39 PRG:0C39 00 B9
|
|
sta workPtr0 ; CPU:$CC3B PRG:0C3B D2 CC
|
|
|
|
lda State02DisplayAddressTable+1,y ; CPU:$CC3D PRG:0C3D 85 01 A5
|
|
sta workPtr0+1 ; CPU:$CC40 PRG:0C40 00 8D 4B
|
|
|
|
lda workPtr0 ; CPU:$CC43 PRG:0C43 02 A5
|
|
sta $024B ; CPU:$CC45 PRG:0C45 01 8D 4C
|
|
|
|
lda workPtr0+1 ; CPU:$CC48 PRG:0C48 02 A9 2D
|
|
sta $024C ; CPU:$CC4B PRG:0C4B 8D 4D 02
|
|
|
|
lda #$2D ; CPU:$CC4E PRG:0C4E 8D 4E
|
|
sta $024D ; CPU:$CC50 PRG:0C50 02 A9 00
|
|
sta $024E ; CPU:$CC53 PRG:0C53 8D 4F 02
|
|
|
|
lda #$00 ; CPU:$CC56 PRG:0C56 A5 00
|
|
sta $024F ; CPU:$CC58 PRG:0C58 8D 50 02
|
|
|
|
lda $00 ; CPU:$CC5B PRG:0C5B A5 01
|
|
sta $0250 ; CPU:$CC5D PRG:0C5D 18 69 20
|
|
|
|
lda $01 ; CPU:$CC60 PRG:0C60 8D 51
|
|
clc ; CPU:$CC62 PRG:0C62 02
|
|
adc #$20 ; CPU:$CC63 PRG:0C63 A9 2D
|
|
sta $0251 ; CPU:$CC65 PRG:0C65 8D 52 02
|
|
|
|
lda #$2D ; CPU:$CC68 PRG:0C68 8D 53
|
|
sta $0252 ; CPU:$CC6A PRG:0C6A 02 A9 FF
|
|
sta $0253 ; CPU:$CC6D PRG:0C6D 8D 54 02
|
|
|
|
lda #$FF ; CPU:$CC70 PRG:0C70 20 8E
|
|
sta $0254 ; CPU:$CC72 PRG:0C72 D9 20 CC
|
|
|
|
jsr UpdatePlayerDirectionAnimation ; CPU:$CC75 PRG:0C75 D9 20 40
|
|
jsr UpdateEntitySpriteStates ; CPU:$CC78 PRG:0C78 DA 4C 99
|
|
jsr $DA40 ; CPU:$CC7B PRG:0C7B CC AD 00
|
|
|
|
jmp $CC99 ; CPU:$CC7E PRG:0C7E 06 0D 01
|
|
|
|
@CheckCompletion:
|
|
lda $0600 ; CPU:$CC81 PRG:0C81 06 D0 15
|
|
ora $0601 ; CPU:$CC84 PRG:0C84 A5 48 D0
|
|
bne $CC99 ; CPU:$CC87 PRG:0C87 0D A9
|
|
|
|
lda $48 ; CPU:$CC89 PRG:0C89 00 85
|
|
bne @AdvanceMainState ; CPU:$CC8B PRG:0C8B 69 A8
|
|
|
|
lda #$00 ; CPU:$CC8D PRG:0C8D 99 60
|
|
sta $69 ; CPU:$CC8F PRG:0C8F 07 C8
|
|
tay ; CPU:$CC91 PRG:0C91 C0
|
|
|
|
@ClearPage07Region:
|
|
sta $0760,y ; CPU:$CC92 PRG:0C92 A0 D0 F8
|
|
iny ; CPU:$CC95 PRG:0C95 A9
|
|
cpy #$A0 ; CPU:$CC96 PRG:0C96 04 85
|
|
bne @ClearPage07Region ; CPU:$CC98 PRG:0C98 3F 4C
|
|
|
|
@AdvanceMainState:
|
|
lda #$04 ; CPU:$CC9A PRG:0C9A A7 CA
|
|
sta $3F ; CPU:$CC9C PRG:0C9C C6 C3
|
|
|
|
@ReturnToFrameLoop:
|
|
jmp GameModeFrameSync ; CPU:$CC9E PRG:0C9E C1 BA C7
|
|
|
|
;==============================================================================
|
|
; $CC9C-$CCD8: Game-Mode State $02 Lookup Tables
|
|
;
|
|
; Local:
|
|
; Collection of lookup tables consumed by GameModeState02 while constructing
|
|
; page-$07 object/display data and preparing the update command at $024B.
|
|
;
|
|
; Global:
|
|
; Supplies the tile/status/position/count/address parameters used by the
|
|
; state-$02 setup sequence.
|
|
;
|
|
; Notes:
|
|
; The tables are separated according to the exact addresses referenced by
|
|
; GameModeState02. Names remain structural during this first pass.
|
|
;==============================================================================
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $CC9C-$CCAD: State $02 tile/value table
|
|
;
|
|
; Indexed through $05:
|
|
;
|
|
; lda State02ValueTableA,x
|
|
;
|
|
; Written as the second byte of each 4-byte structure generated at $0760+.
|
|
; Length: $12 (18) bytes.
|
|
;------------------------------------------------------------------------------
|
|
|
|
State02ValueTableA:
|
|
.byte $C6,$C3,$C1,$BA,$C7,$BB ; CPU:$CC9C PRG:0C9C C6 C3 C1 BA C7 BB
|
|
.byte $B0,$B1,$B2,$B3,$B4,$B5 ; CPU:$CCA2 PRG:0CA2 B0 B1 B2 B3 B4 B5
|
|
.byte $B6,$B7,$B4,$B8,$B9,$B6 ; CPU:$CCA8 PRG:0CA8 B6 B7 B4 B8 B9 B6
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $CCAE-$CCBF: State $02 secondary value table
|
|
;
|
|
; Indexed through the same $05 value as State02ValueTableA.
|
|
;
|
|
; Written as the third byte of each generated 4-byte structure.
|
|
; Length: $12 (18) bytes.
|
|
;------------------------------------------------------------------------------
|
|
|
|
State02ValueTableB:
|
|
.byte $00,$00,$00,$00,$00,$00 ; CPU:$CCAE PRG:0CAE 00 00 00 00 00 00
|
|
.byte $02,$02,$02,$02,$02,$02 ; CPU:$CCB4 PRG:0CB4 02 02 02 02 02 02
|
|
.byte $02,$02,$02,$02,$02,$02 ; CPU:$CCBA PRG:0CBA 02 02 02 02 02 02
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $CCC0-$CCC5: State $02 position/parameter pairs
|
|
;
|
|
; GameModeState02 accesses this table as overlapping little groups:
|
|
;
|
|
; lda State02PositionTable,x
|
|
; lda State02PositionTable+1,x
|
|
;
|
|
; $06 advances by 2 each outer pass.
|
|
;
|
|
; Therefore the natural structure is three 2-byte pairs.
|
|
;------------------------------------------------------------------------------
|
|
|
|
State02PositionTable:
|
|
.byte $44,$88 ; CPU:$CCC0 PRG:0CC0 44 88
|
|
.byte $44,$60 ; CPU:$CCC2 PRG:0CC2 44 60
|
|
.byte $50,$70 ; CPU:$CCC4 PRG:0CC4 50 70
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $CCC6-$CCC8: State $02 entry-count table
|
|
;
|
|
; Indexed by $07. Determines how many four-byte structures are emitted by
|
|
; each inner construction loop.
|
|
;------------------------------------------------------------------------------
|
|
|
|
State02EntryCounts:
|
|
.byte $06,$06,$03 ; CPU:$CCC6 PRG:0CC6 06 06 03
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $CCC9-$CCD0: Additional state-$02 values
|
|
;
|
|
; No direct reference has yet been established in the portion decoded so far.
|
|
; Keep this data structurally separated until its consumer is found.
|
|
;------------------------------------------------------------------------------
|
|
|
|
State02UnknownData:
|
|
.byte $C0,$C1,$C2,$C3,$C4,$C5,$C3,$C6 ; CPU:$CCC9 PRG:0CC9 C0 C1 C2 C3 C4 C5 C3 C6
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $CCD1-$CCD8: Display-address table
|
|
;
|
|
; Indexed by:
|
|
;
|
|
; ($67 - 1) * 2
|
|
;
|
|
; and read as two-byte values:
|
|
;
|
|
; lda State02DisplayAddressTable,y
|
|
; lda State02DisplayAddressTable+1,y
|
|
;
|
|
; The bytes form four PPU-style address pairs:
|
|
;
|
|
; $2317
|
|
; $2319
|
|
; $231B
|
|
; $2357
|
|
;
|
|
; When $47 & $46 is nonzero, $08 is added to the low byte before the command
|
|
; is placed into $024B/$024C.
|
|
;------------------------------------------------------------------------------
|
|
|
|
State02DisplayAddressTable:
|
|
.byte $23,$17 ; CPU:$CCD1 PRG:0CD1 23 17
|
|
.byte $23,$19 ; CPU:$CCD3 PRG:0CD3 23 19
|
|
.byte $23,$1B ; CPU:$CCD5 PRG:0CD5 23 1B
|
|
.byte $23,$57 ; CPU:$CCD7 PRG:0CD7 23 57
|
|
|
|
;==============================================================================
|
|
; $CCD9-$CD05: Game-Mode State $06 Handler
|
|
;
|
|
; Local:
|
|
; Increments $DA each frame. Normally falls through to a group of four
|
|
; per-frame update routines.
|
|
;
|
|
; When $DA reaches $28, resets $DA to $02, changes the main game-mode state
|
|
; to $04, finds an even-indexed entry in $B8+X containing $08, and changes
|
|
; that entry to $06 before continuing through the same update routines.
|
|
;
|
|
; Global:
|
|
; Handler selected by GameModeStateTable when $3F = $06. Implements a timed
|
|
; transition back to game-mode state $04 while continuing normal frame
|
|
; processing throughout the delay.
|
|
;
|
|
; Notes:
|
|
; $DA is used as a frame/progression counter.
|
|
; The $B8 array is searched only at even offsets.
|
|
;==============================================================================
|
|
|
|
GameModeState06:
|
|
inc $DA ; CPU:$CCD9 PRG:0CD9 E6 DA
|
|
|
|
lda #$28 ; CPU:$CCDB PRG:0CDB A9 28
|
|
cmp $DA ; CPU:$CCDD PRG:0CDD C5 DA
|
|
bne @RunFrameUpdates ; CPU:$CCDF PRG:0CDF D0 16
|
|
|
|
lda #$02 ; CPU:$CCE1 PRG:0CE1 A9 02
|
|
sta $DA ; CPU:$CCE3 PRG:0CE3 85 DA
|
|
|
|
lda #$04 ; CPU:$CCE5 PRG:0CE5 A9 04
|
|
sta $3F ; CPU:$CCE7 PRG:0CE7 85 3F
|
|
|
|
lda #$08 ; CPU:$CCE9 PRG:0CE9 A9 08
|
|
|
|
ldx #$FE ; CPU:$CCEB PRG:0CEB A2 FE
|
|
|
|
@FindStateEntry:
|
|
inx ; CPU:$CCED PRG:0CED E8
|
|
inx ; CPU:$CCEE PRG:0CEE E8
|
|
cmp $B8,x ; CPU:$CCEF PRG:0CEF D5 B8
|
|
bne @FindStateEntry ; CPU:$CCF1 PRG:0CF1 D0 FA
|
|
|
|
lda #$06 ; CPU:$CCF3 PRG:0CF3 A9 06
|
|
sta $B8,x ; CPU:$CCF5 PRG:0CF5 95 B8
|
|
|
|
@RunFrameUpdates:
|
|
jsr UpdatePeriodicFourEntryState ; CPU:$CCF7 PRG:0CF7 20 5E DE
|
|
jsr UpdateEntityMovementStates ; CPU:$CCFA PRG:0CFA 20 14 D9
|
|
jsr UpdateEntitySpriteStates ; CPU:$CCFD PRG:0CFD 20 CC D9
|
|
jsr $DA40 ; CPU:$CD00 PRG:0D00 20 40 DA
|
|
|
|
jmp GameModeFrameSync ; CPU:$CD03 PRG:0D03 4C A7 CA
|
|
|
|
|
|
;==============================================================================
|
|
; $CD06-$CDAF: Game-Mode State $08 Handler
|
|
;
|
|
; Local:
|
|
; Multi-phase timed state using $87, $DB, and $32.
|
|
;
|
|
; During the initial phase, $DB counts down. When it expires, $87 advances,
|
|
; $DB and $0603 are initialized to $0A, and $001E-$0031 are cleared.
|
|
;
|
|
; During the active phase, $DB periodically advances $32 until $32 reaches
|
|
; $1E. The completion logic then updates the two parallel 16-byte state
|
|
; blocks at $67-$76 and $77-$86 and selects the next game-mode state.
|
|
;
|
|
; Global:
|
|
; Handler selected by GameModeStateTable when $3F = $08.
|
|
;
|
|
; Notes:
|
|
; $DB acts as a short-period timer.
|
|
; $87 distinguishes the initial and active phases.
|
|
; $67-$76 and $77-$86 are interchangeable 16-byte state structures.
|
|
;
|
|
; A few cross-flow destinations are kept as raw addresses during this pass
|
|
; to preserve the original control flow exactly.
|
|
;==============================================================================
|
|
|
|
GameModeState08:
|
|
lda $87 ; CPU:$CD06 PRG:0D06 A5 87
|
|
bne @ActivePhase ; CPU:$CD08 PRG:0D08 D0 23
|
|
|
|
dec $DB ; CPU:$CD0A PRG:0D0A C6 DB
|
|
bne @InitialFrameUpdates ; CPU:$CD0C PRG:0D0C D0 13
|
|
|
|
inc $87 ; CPU:$CD0E PRG:0D0E E6 87
|
|
|
|
lda #$0A ; CPU:$CD10 PRG:0D10 A9 0A
|
|
sta $DB ; CPU:$CD12 PRG:0D12 85 DB
|
|
sta $0603 ; CPU:$CD14 PRG:0D14 8D 03 06
|
|
|
|
lda #$00 ; CPU:$CD17 PRG:0D17 A9 00
|
|
tax ; CPU:$CD19 PRG:0D19 AA
|
|
|
|
@ClearLowRamState:
|
|
sta $1E,x ; CPU:$CD1A PRG:0D1A 95 1E
|
|
inx ; CPU:$CD1C PRG:0D1C E8
|
|
cpx #$14 ; CPU:$CD1D PRG:0D1D E0 14
|
|
bne @ClearLowRamState ; CPU:$CD1F PRG:0D1F D0 F9
|
|
|
|
@InitialFrameUpdates:
|
|
jsr UpdatePeriodicFourEntryState ; CPU:$CD21 PRG:0D21 20 5E DE
|
|
jsr UpdateEntitySpriteStates ; CPU:$CD24 PRG:0D24 20 CC D9
|
|
jsr $DA40 ; CPU:$CD27 PRG:0D27 20 40 DA
|
|
|
|
jmp GameModeFrameSync ; CPU:$CD2A PRG:0D2A 4C A7 CA
|
|
|
|
@ActivePhase:
|
|
dec $DB ; CPU:$CD2D PRG:0D2D C6 DB
|
|
bpl @ActiveFrameUpdates ; CPU:$CD2F PRG:0D2F 10 0F
|
|
|
|
lda #$0A ; CPU:$CD31 PRG:0D31 A9 0A
|
|
sta $DB ; CPU:$CD33 PRG:0D33 85 DB
|
|
|
|
lda $32 ; CPU:$CD35 PRG:0D35 A5 32
|
|
clc ; CPU:$CD37 PRG:0D37 18
|
|
adc #$01 ; CPU:$CD38 PRG:0D38 69 01
|
|
sta $32 ; CPU:$CD3A PRG:0D3A 85 32
|
|
|
|
cmp #$1E ; CPU:$CD3C PRG:0D3C C9 1E
|
|
beq @PhaseComplete ; CPU:$CD3E PRG:0D3E F0 09
|
|
|
|
@ActiveFrameUpdates:
|
|
jsr UpdatePeriodicFourEntryState ; CPU:$CD40 PRG:0D40 20 5E DE
|
|
jsr $DA40 ; CPU:$CD43 PRG:0D43 20 40 DA
|
|
|
|
jmp GameModeFrameSync ; CPU:$CD46 PRG:0D46 4C A7 CA
|
|
|
|
@PhaseComplete:
|
|
lda $48 ; CPU:$CD49 PRG:0D49 A5 48
|
|
bne @SinglePlayerRestart ; CPU:$CD4B PRG:0D4B D0 3C
|
|
|
|
dec $67 ; CPU:$CD4D PRG:0D4D C6 67
|
|
bne @ContinuePlayerHandling ; CPU:$CD4F PRG:0D4F D0 0D
|
|
|
|
lda #$00 ; CPU:$CD51 PRG:0D51 A9 00
|
|
sta $87 ; CPU:$CD53 PRG:0D53 85 87
|
|
sta $69 ; CPU:$CD55 PRG:0D55 85 69
|
|
|
|
lda #$0A ; CPU:$CD57 PRG:0D57 A9 0A
|
|
sta $3F ; CPU:$CD59 PRG:0D59 85 3F
|
|
|
|
jmp GameModeFrameSync ; CPU:$CD5B PRG:0D5B 4C A7 CA
|
|
|
|
@ContinuePlayerHandling:
|
|
lda #$00 ; CPU:$CD5E PRG:0D5E A9 00
|
|
sta $3F ; CPU:$CD60 PRG:0D60 85 3F
|
|
|
|
lda #$01 ; CPU:$CD62 PRG:0D62 A9 01
|
|
sta $69 ; CPU:$CD64 PRG:0D64 85 69
|
|
|
|
lda $47 ; CPU:$CD66 PRG:0D66 A5 47
|
|
beq @CheckPrimaryBlock ; CPU:$CD68 PRG:0D68 F0 04
|
|
|
|
lda $77 ; CPU:$CD6A PRG:0D6A A5 77
|
|
bne @SwapBlocksAndToggle ; CPU:$CD6C PRG:0D6C D0 26
|
|
|
|
@CheckPrimaryBlock:
|
|
lda $67 ; CPU:$CD6E PRG:0D6E A5 67
|
|
bne $CDAD ; CPU:$CD70 PRG:0D70 D0 3B
|
|
|
|
sta $69 ; CPU:$CD72 PRG:0D72 85 69
|
|
|
|
lda $46 ; CPU:$CD74 PRG:0D74 A5 46
|
|
beq @SinglePlayerRestart ; CPU:$CD76 PRG:0D76 F0 11
|
|
|
|
ldx #$0F ; CPU:$CD78 PRG:0D78 A2 0F
|
|
|
|
@SwapBlocksForMainEntry:
|
|
lda $67,x ; CPU:$CD7A PRG:0D7A B5 67
|
|
sta $00 ; CPU:$CD7C PRG:0D7C 85 00
|
|
|
|
lda $77,x ; CPU:$CD7E PRG:0D7E B5 77
|
|
sta $67,x ; CPU:$CD80 PRG:0D80 95 67
|
|
|
|
lda $00 ; CPU:$CD82 PRG:0D82 A5 00
|
|
sta $77,x ; CPU:$CD84 PRG:0D84 95 77
|
|
|
|
dex ; CPU:$CD86 PRG:0D86 CA
|
|
bpl @SwapBlocksForMainEntry ; CPU:$CD87 PRG:0D87 10 F1
|
|
|
|
@SinglePlayerRestart:
|
|
lda #$00 ; CPU:$CD89 PRG:0D89 A9 00
|
|
sta $46 ; CPU:$CD8B PRG:0D8B 85 46
|
|
|
|
lda #$00 ; CPU:$CD8D PRG:0D8D A9 00
|
|
sta $3F ; CPU:$CD8F PRG:0D8F 85 3F
|
|
|
|
jmp MainEntry ; CPU:$CD91 PRG:0D91 4C E7 C1
|
|
|
|
|
|
@SwapBlocksAndToggle:
|
|
ldx #$0F ; CPU:$CD94 PRG:0D94 A2 0F
|
|
|
|
@SwapBlocks:
|
|
lda $67,x ; CPU:$CD96 PRG:0D96 B5 67
|
|
sta $00 ; CPU:$CD98 PRG:0D98 85 00
|
|
|
|
lda $77,x ; CPU:$CD9A PRG:0D9A B5 77
|
|
sta $67,x ; CPU:$CD9C PRG:0D9C 95 67
|
|
|
|
lda $00 ; CPU:$CD9E PRG:0D9E A5 00
|
|
sta $77,x ; CPU:$CDA0 PRG:0DA0 95 77
|
|
|
|
dex ; CPU:$CDA2 PRG:0DA2 CA
|
|
bpl @SwapBlocks ; CPU:$CDA3 PRG:0DA3 10 F1
|
|
|
|
inc $46 ; CPU:$CDA5 PRG:0DA5 E6 46
|
|
|
|
lda $46 ; CPU:$CDA7 PRG:0DA7 A5 46
|
|
and #$01 ; CPU:$CDA9 PRG:0DA9 29 01
|
|
sta $46 ; CPU:$CDAB PRG:0DAB 85 46
|
|
|
|
jmp GameModeFrameSync ; CPU:$CDAD PRG:0DAD 4C A7 CA
|
|
|
|
|
|
;==============================================================================
|
|
; $CDB0-$CE1E: Game-Mode State $0C Handler
|
|
;
|
|
; Local:
|
|
; Uses $87 as a frame/progression counter.
|
|
;
|
|
; On first entry ($87 == 0):
|
|
; - Clears $001E-$0031.
|
|
; - Increments $87.
|
|
; - Initializes $32 to $01.
|
|
;
|
|
; On subsequent frames, processing is throttled by the low three bits of
|
|
; the NMI-driven frame counter $4B. Only once every eight frames does the
|
|
; handler:
|
|
;
|
|
; - Alternate a value written to $029E according to bit 0 of $87.
|
|
; - Set $0299 to $0F.
|
|
; - Increment $87.
|
|
;
|
|
; When $87 reaches $10, the routine clears $1A/$1C/$87 and selects a new
|
|
; main game-mode state according to the value at $68.
|
|
;
|
|
; Global:
|
|
; Handler selected by GameModeStateTable when $3F = $0C.
|
|
;
|
|
; This appears to implement a short visual/timed transition. The write of
|
|
; $0F to $0299 interacts directly with the palette-update mechanism decoded
|
|
; earlier, while $029E lies inside that first 16-byte palette/update buffer.
|
|
;
|
|
; Notes:
|
|
; $4B is the NMI-driven frame counter.
|
|
;
|
|
; $87 advances only once every eight frames after initialization.
|
|
;
|
|
; $68 controls which state is selected when the sequence completes.
|
|
;==============================================================================
|
|
|
|
GameModeState0C:
|
|
lda $87 ; CPU:$CDB0 PRG:0DB0 A5 87
|
|
bne @TimedPhase ; CPU:$CDB2 PRG:0DB2 D0 11
|
|
|
|
ldx #$00 ; CPU:$CDB4 PRG:0DB4 A2 00
|
|
|
|
@ClearLowRam:
|
|
sta $1E,x ; CPU:$CDB6 PRG:0DB6 95 1E
|
|
inx ; CPU:$CDB8 PRG:0DB8 E8
|
|
cpx #$14 ; CPU:$CDB9 PRG:0DB9 E0 14
|
|
bne @ClearLowRam ; CPU:$CDBB PRG:0DBB D0 F9
|
|
|
|
inc $87 ; CPU:$CDBD PRG:0DBD E6 87
|
|
|
|
lda #$01 ; CPU:$CDBF PRG:0DBF A9 01
|
|
sta $32 ; CPU:$CDC1 PRG:0DC1 85 32
|
|
|
|
bne @RunFrameUpdates ; CPU:$CDC3 PRG:0DC3 D0 51
|
|
|
|
|
|
@TimedPhase:
|
|
lda $4B ; CPU:$CDC5 PRG:0DC5 A5 4B
|
|
and #$07 ; CPU:$CDC7 PRG:0DC7 29 07
|
|
bne @RunFrameUpdates ; CPU:$CDC9 PRG:0DC9 D0 4B
|
|
|
|
ldx #$11 ; CPU:$CDCB PRG:0DCB A2 11
|
|
|
|
lda $87 ; CPU:$CDCD PRG:0DCD A5 87
|
|
and #$01 ; CPU:$CDCF PRG:0DCF 29 01
|
|
bne @SetPaletteValue ; CPU:$CDD1 PRG:0DD1 D0 02
|
|
|
|
ldx #$20 ; CPU:$CDD3 PRG:0DD3 A2 20
|
|
|
|
@SetPaletteValue:
|
|
stx $029E ; CPU:$CDD5 PRG:0DD5 8E 9E 02
|
|
|
|
lda #$0F ; CPU:$CDD8 PRG:0DD8 A9 0F
|
|
sta $0299 ; CPU:$CDDA PRG:0DDA 8D 99 02
|
|
|
|
inc $87 ; CPU:$CDDD PRG:0DDD E6 87
|
|
|
|
lda #$10 ; CPU:$CDDF PRG:0DDF A9 10
|
|
cmp $87 ; CPU:$CDE1 PRG:0DE1 C5 87
|
|
bne @RunFrameUpdates ; CPU:$CDE3 PRG:0DE3 D0 31
|
|
|
|
lda #$00 ; CPU:$CDE5 PRG:0DE5 A9 00
|
|
sta $1A ; CPU:$CDE7 PRG:0DE7 85 1A
|
|
sta $1C ; CPU:$CDE9 PRG:0DE9 85 1C
|
|
sta $87 ; CPU:$CDEB PRG:0DEB 85 87
|
|
|
|
lda $68 ; CPU:$CDED PRG:0DED A5 68
|
|
cmp #$01 ; CPU:$CDEF PRG:0DEF C9 01
|
|
beq @SelectState0E ; CPU:$CDF1 PRG:0DF1 F0 18
|
|
|
|
inc $87 ; CPU:$CDF3 PRG:0DF3 E6 87
|
|
inc $87 ; CPU:$CDF5 PRG:0DF5 E6 87
|
|
|
|
cmp #$04 ; CPU:$CDF7 PRG:0DF7 C9 04
|
|
beq @SelectState0E ; CPU:$CDF9 PRG:0DF9 F0 10
|
|
|
|
inc $87 ; CPU:$CDFB PRG:0DFB E6 87
|
|
inc $87 ; CPU:$CDFD PRG:0DFD E6 87
|
|
|
|
cmp #$08 ; CPU:$CDFF PRG:0DFF C9 08
|
|
beq @SelectState0E ; CPU:$CE01 PRG:0E01 F0 08
|
|
|
|
cmp #$0C ; CPU:$CE03 PRG:0E03 C9 0C
|
|
beq @SelectState0E ; CPU:$CE05 PRG:0E05 F0 04
|
|
|
|
cmp #$10 ; CPU:$CE07 PRG:0E07 C9 10
|
|
bne @SelectState00 ; CPU:$CE09 PRG:0E09 D0 07
|
|
|
|
|
|
@SelectState0E:
|
|
lda #$0E ; CPU:$CE0B PRG:0E0B A9 0E
|
|
sta $3F ; CPU:$CE0D PRG:0E0D 85 3F
|
|
|
|
jmp @RunFrameUpdates ; CPU:$CE0F PRG:0E0F 4C 16 CE
|
|
|
|
|
|
@SelectState00:
|
|
lda #$00 ; CPU:$CE12 PRG:0E12 A9 00
|
|
sta $3F ; CPU:$CE14 PRG:0E14 85 3F
|
|
|
|
|
|
@RunFrameUpdates:
|
|
jsr UpdatePeriodicFourEntryState ; CPU:$CE16 PRG:0E16 20 5E DE
|
|
jsr $DA40 ; CPU:$CE19 PRG:0E19 20 40 DA
|
|
|
|
jmp GameModeFrameSync ; CPU:$CE1C PRG:0E1C 4C A7 CA
|
|
|
|
|
|
;==============================================================================
|
|
; $CE1F-$CEBE: Game-Mode State $0A Handler
|
|
;
|
|
; Local:
|
|
; Uses $87 to distinguish between initialization and subsequent processing.
|
|
;
|
|
; On initial entry:
|
|
; - Fills $0700-$075F with $FF.
|
|
; - Initializes $00/$01 as a pointer to $0760.
|
|
; - Builds structured four-byte records in page $07 from several ROM
|
|
; lookup tables beginning at $CEBF.
|
|
;
|
|
; The builder uses:
|
|
;
|
|
; $00/$01 destination pointer ($0760)
|
|
; $02/$03 per-group values
|
|
; $04 outer pass counter, initially $03
|
|
; $05 shared table index
|
|
; $06 index into the value-pair table
|
|
; $07 index into the entry-count table
|
|
; $08 inner record counter
|
|
;
|
|
; Player/mode variables $47, $77, and $46 influence whether passes repeat
|
|
; and whether the lookup index is advanced.
|
|
;
|
|
; After the construction phase, $87 is incremented. A later entry either
|
|
; clears $0760-$07FF and transitions to the code at $CD5E, or simply
|
|
; returns to the common frame loop.
|
|
;
|
|
; Global:
|
|
; Handler selected by GameModeStateTable when $3F = $0A.
|
|
;
|
|
; Structurally this is closely related to GameModeState02, but uses a
|
|
; different set of ROM tables and first clears $0700-$075F to $FF. Both
|
|
; handlers construct arrays of four-byte records in page $07.
|
|
;
|
|
; Notes:
|
|
; The tables at $CEBF-$CEF2 are decoded immediately after this routine.
|
|
; Semantic object names are deferred until the page-$07 consumers are
|
|
; understood more completely.
|
|
;==============================================================================
|
|
|
|
GameModeState0A:
|
|
lda $87 ; CPU:$CE1F PRG:0E1F A5 87
|
|
beq @Initialize ; CPU:$CE21 PRG:0E21 F0 03
|
|
|
|
jmp $CEAA ; CPU:$CE23 PRG:0E23 4C AA CE
|
|
|
|
@Initialize:
|
|
ldy #$00 ; CPU:$CE26 PRG:0E26 A0 00
|
|
|
|
lda #$FF ; CPU:$CE28 PRG:0E28 A9 FF
|
|
|
|
@FillPage07Prefix:
|
|
sta $0700,y ; CPU:$CE2A PRG:0E2A 99 00 07
|
|
iny ; CPU:$CE2D PRG:0E2D C8
|
|
cpy #$60 ; CPU:$CE2E PRG:0E2E C0 60
|
|
bne @FillPage07Prefix ; CPU:$CE30 PRG:0E30 D0 F8
|
|
|
|
lda #$60 ; CPU:$CE32 PRG:0E32 A9 60
|
|
sta $00 ; CPU:$CE34 PRG:0E34 85 00
|
|
|
|
lda #$07 ; CPU:$CE36 PRG:0E36 A9 07
|
|
sta $01 ; CPU:$CE38 PRG:0E38 85 01
|
|
|
|
lda #$03 ; CPU:$CE3A PRG:0E3A A9 03
|
|
sta $04 ; CPU:$CE3C PRG:0E3C 85 04
|
|
|
|
ldy #$00 ; CPU:$CE3E PRG:0E3E A0 00
|
|
sty $05 ; CPU:$CE40 PRG:0E40 84 05
|
|
sty $06 ; CPU:$CE42 PRG:0E42 84 06
|
|
sty $07 ; CPU:$CE44 PRG:0E44 84 07
|
|
|
|
@BuildOuterLoop:
|
|
ldx $06 ; CPU:$CE46 PRG:0E46 A6 06
|
|
|
|
lda State0AParameterPairs,x ; CPU:$CE48 PRG:0E48 BD E7 CE
|
|
sta $02 ; CPU:$CE4B PRG:0E4B 85 02
|
|
|
|
lda State0AParameterPairs+1,x ; CPU:$CE4D PRG:0E4D BD E8 CE
|
|
sta $03 ; CPU:$CE50 PRG:0E50 85 03
|
|
|
|
ldx $07 ; CPU:$CE52 PRG:0E52 A6 07
|
|
|
|
lda State0AEntryCounts,x ; CPU:$CE54 PRG:0E54 BD EF CE
|
|
sta $08 ; CPU:$CE57 PRG:0E57 85 08
|
|
|
|
|
|
@BuildInnerLoop:
|
|
lda $03 ; CPU:$CE59 PRG:0E59 A5 03
|
|
sta ($00),y ; CPU:$CE5B PRG:0E5B 91 00
|
|
|
|
ldx $05 ; CPU:$CE5D PRG:0E5D A6 05
|
|
|
|
lda State0AValueTableA,x ; CPU:$CE5F PRG:0E5F BD BF CE
|
|
iny ; CPU:$CE62 PRG:0E62 C8
|
|
sta ($00),y ; CPU:$CE63 PRG:0E63 91 00
|
|
|
|
lda State0AValueTableB,x ; CPU:$CE65 PRG:0E65 BD D3 CE
|
|
iny ; CPU:$CE68 PRG:0E68 C8
|
|
sta ($00),y ; CPU:$CE69 PRG:0E69 91 00
|
|
|
|
lda $02 ; CPU:$CE6B PRG:0E6B A5 02
|
|
iny ; CPU:$CE6D PRG:0E6D C8
|
|
sta ($00),y ; CPU:$CE6E PRG:0E6E 91 00
|
|
|
|
lda $02 ; CPU:$CE70 PRG:0E70 A5 02
|
|
clc ; CPU:$CE72 PRG:0E72 18
|
|
adc #$08 ; CPU:$CE73 PRG:0E73 69 08
|
|
sta $02 ; CPU:$CE75 PRG:0E75 85 02
|
|
|
|
iny ; CPU:$CE77 PRG:0E77 C8
|
|
inc $05 ; CPU:$CE78 PRG:0E78 E6 05
|
|
|
|
dec $08 ; CPU:$CE7A PRG:0E7A C6 08
|
|
bne @BuildInnerLoop ; CPU:$CE7C PRG:0E7C D0 DB
|
|
|
|
inc $06 ; CPU:$CE7E PRG:0E7E E6 06
|
|
inc $06 ; CPU:$CE80 PRG:0E80 E6 06
|
|
|
|
inc $07 ; CPU:$CE82 PRG:0E82 E6 07
|
|
|
|
lda $47 ; CPU:$CE84 PRG:0E84 A5 47
|
|
beq @ContinueOuterPass ; CPU:$CE86 PRG:0E86 F0 0A
|
|
|
|
lda $77 ; CPU:$CE88 PRG:0E88 A5 77
|
|
bne @ContinueOuterPass ; CPU:$CE8A PRG:0E8A D0 06
|
|
|
|
lda $04 ; CPU:$CE8C PRG:0E8C A5 04
|
|
cmp #$02 ; CPU:$CE8E PRG:0E8E C9 02
|
|
beq $CEAA ; CPU:$CE90 PRG:0E90 F0 18
|
|
|
|
|
|
@ContinueOuterPass:
|
|
dec $04 ; CPU:$CE92 PRG:0E92 C6 04
|
|
beq @CheckPlayerMode ; CPU:$CE94 PRG:0E94 F0 04
|
|
|
|
bpl @BuildOuterLoop ; CPU:$CE96 PRG:0E96 10 AE
|
|
bmi @FinishInitialization ; CPU:$CE98 PRG:0E98 30 10
|
|
|
|
|
|
@CheckPlayerMode:
|
|
lda $47 ; CPU:$CE9A PRG:0E9A A5 47
|
|
beq @FinishInitialization ; CPU:$CE9C PRG:0E9C F0 0C
|
|
|
|
lda $46 ; CPU:$CE9E PRG:0E9E A5 46
|
|
beq @BuildOuterLoop ; CPU:$CEA0 PRG:0EA0 F0 A4
|
|
|
|
|
|
@AdjustTableIndex:
|
|
inc $05 ; CPU:$CEA2 PRG:0EA2 E6 05
|
|
inc $05 ; CPU:$CEA4 PRG:0EA4 E6 05
|
|
inc $05 ; CPU:$CEA6 PRG:0EA6 E6 05
|
|
|
|
bne @BuildOuterLoop ; CPU:$CEA8 PRG:0EA8 D0 9C
|
|
|
|
|
|
@FinishInitialization:
|
|
inc $87 ; CPU:$CEAA PRG:0EAA E6 87
|
|
bne @ReturnToFrameLoop ; CPU:$CEAC PRG:0EAC D0 0E
|
|
|
|
|
|
@PostInitialization:
|
|
lda #$00 ; CPU:$CEAE PRG:0EAE A9 00
|
|
tay ; CPU:$CEB0 PRG:0EB0 A8
|
|
|
|
@ClearPage07Region:
|
|
sta $0760,y ; CPU:$CEB1 PRG:0EB1 99 60 07
|
|
iny ; CPU:$CEB4 PRG:0EB4 C8
|
|
cpy #$A0 ; CPU:$CEB5 PRG:0EB5 C0 A0
|
|
bne @ClearPage07Region ; CPU:$CEB7 PRG:0EB7 D0 F8
|
|
|
|
jmp $CD5E ; CPU:$CEB9 PRG:0EB9 4C 5E CD
|
|
|
|
|
|
@ReturnToFrameLoop:
|
|
jmp GameModeFrameSync ; CPU:$CEBC PRG:0EBC 4C A7 CA
|
|
|
|
|
|
;==============================================================================
|
|
; $CEBF-$CEF2: Game-Mode State $0A Lookup Tables
|
|
;
|
|
; Local:
|
|
; Lookup data used by GameModeState0A to construct four-byte records in
|
|
; page $07.
|
|
;
|
|
; Global:
|
|
; Provides the object/tile/value and layout parameters for state $0A.
|
|
;==============================================================================
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $CEBF-$CED2: Primary value table
|
|
; Length: $14 (20) bytes
|
|
;------------------------------------------------------------------------------
|
|
|
|
State0AValueTableA:
|
|
.byte $BC,$B2,$BD,$B4,$B6,$BE,$B4,$B5 ; CPU:$CEBF PRG:0EBF BC B2 BD B4 B6 BE B4 B5
|
|
.byte $B0,$B1,$B2,$B3,$B4,$B5,$B6,$B7 ; CPU:$CEC7 PRG:0EC7 B0 B1 B2 B3 B4 B5 B6 B7
|
|
.byte $B4,$B8,$B9,$B6 ; CPU:$CECF PRG:0ECF B4 B8 B9 B6
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $CED3-$CEE6: Secondary value table
|
|
; Length: $14 (20) bytes
|
|
;------------------------------------------------------------------------------
|
|
|
|
State0AValueTableB:
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00 ; CPU:$CED3 PRG:0ED3 00 00 00 00 00 00 00 00
|
|
.byte $02,$02,$02,$02,$02,$02,$02,$02 ; CPU:$CEDB PRG:0EDB 02 02 02 02 02 02 02 02
|
|
.byte $02,$02,$02,$02 ; CPU:$CEE3 PRG:0EE3 02 02 02 02
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $CEE7-$CEEE: Parameter-pair table
|
|
;
|
|
; $06 advances by two, so represent this as four 2-byte pairs.
|
|
;------------------------------------------------------------------------------
|
|
|
|
State0AParameterPairs:
|
|
.byte $38,$88 ; CPU:$CEE7 PRG:0EE7 38 88
|
|
.byte $60,$88 ; CPU:$CEE9 PRG:0EE9 60 88
|
|
.byte $44,$60 ; CPU:$CEEB PRG:0EEB 44 60
|
|
.byte $50,$70 ; CPU:$CEED PRG:0EED 50 70
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $CEEF-$CEF2: Inner-loop entry counts
|
|
;------------------------------------------------------------------------------
|
|
|
|
State0AEntryCounts:
|
|
.byte $04,$04,$06,$03 ; CPU:$CEEF PRG:0EEF 04 04 06 03
|
|
|
|
;==============================================================================
|
|
; $CEF3-$D0AA: Game-Mode State $00 Initialization
|
|
;
|
|
; Local:
|
|
; Performs the main initialization for the game-mode state machine:
|
|
;
|
|
; - Synchronizes with NMI and disables rendering.
|
|
; - Clears working RAM $87-$EF.
|
|
; - Clears page $0700-$07FF.
|
|
; - Copies a 32-byte palette table from GameplayPaletteData to $0299-$02B8.
|
|
; - Selects game-mode state $02.
|
|
; - Initializes gameplay/state variables and invokes several setup helpers.
|
|
; - Loads numerous parameters from ROM lookup tables.
|
|
; - Initializes arrays and display/update data.
|
|
; - Re-enables NMI with PPUCTRL=$88.
|
|
; - Returns to GameModeFrameSync.
|
|
;
|
|
; Global:
|
|
; Primary initialization handler for GameModeStateTable offset $00.
|
|
; Establishes the working state used by the later $02/$04/etc. handlers.
|
|
;
|
|
; Notes:
|
|
; Many ROM tables referenced from $EBxx/$ECxx are intentionally left raw
|
|
; during this pass and will be named when those regions are reached.
|
|
;==============================================================================
|
|
|
|
GameModeState00:
|
|
lda #$01 ; CPU:$CEF3 PRG:0EF3 A9 01
|
|
sta $40 ; CPU:$CEF5 PRG:0EF5 85 40
|
|
|
|
@WaitForNmi:
|
|
lda $40 ; CPU:$CEF7 PRG:0EF7 A5 40
|
|
bne @WaitForNmi ; CPU:$CEF9 PRG:0EF9 D0 FC
|
|
|
|
lda #$08 ; CPU:$CEFB PRG:0EFB A9 08
|
|
sta PPUCTRL ; CPU:$CEFD PRG:0EFD 8D 00 20
|
|
sta $43 ; CPU:$CF00 PRG:0F00 85 43
|
|
|
|
lda #$00 ; CPU:$CF02 PRG:0F02 A9 00
|
|
sta PPUMASK ; CPU:$CF04 PRG:0F04 8D 01 20
|
|
|
|
ldx #$00 ; CPU:$CF07 PRG:0F07 A2 00
|
|
|
|
@ClearWorkingRam:
|
|
sta $87,x ; CPU:$CF09 PRG:0F09 95 87
|
|
inx ; CPU:$CF0B PRG:0F0B E8
|
|
cpx #$69 ; CPU:$CF0C PRG:0F0C E0 69
|
|
bne @ClearWorkingRam ; CPU:$CF0E PRG:0F0E D0 F9
|
|
|
|
tax ; CPU:$CF10 PRG:0F10 AA
|
|
|
|
@ClearPage07:
|
|
sta $0700,x ; CPU:$CF11 PRG:0F11 9D 00 07
|
|
inx ; CPU:$CF14 PRG:0F14 E8
|
|
bne @ClearPage07 ; CPU:$CF15 PRG:0F15 D0 FA
|
|
|
|
ldy #$00 ; CPU:$CF17 PRG:0F17 A0 00
|
|
|
|
@LoadPalette:
|
|
lda GameplayPaletteData,y ; CPU:$CF19 PRG:0F19 B9 11 D1
|
|
sta $0299,y ; CPU:$CF1C PRG:0F1C 99 99 02
|
|
iny ; CPU:$CF1F PRG:0F1F C8
|
|
cpy #$20 ; CPU:$CF20 PRG:0F20 C0 20
|
|
bne @LoadPalette ; CPU:$CF22 PRG:0F22 D0 F5
|
|
|
|
lda #$02 ; CPU:$CF24 PRG:0F24 A9 02
|
|
sta $3F ; CPU:$CF26 PRG:0F26 85 3F
|
|
|
|
lda $69 ; CPU:$CF28 PRG:0F28 A5 69
|
|
bne $CF4A ; CPU:$CF2A PRG:0F2A D0 1E
|
|
|
|
sta $8B ; CPU:$CF2C PRG:0F2C 85 8B
|
|
|
|
lda #$01 ; CPU:$CF2E PRG:0F2E A9 01
|
|
sta $6C ; CPU:$CF30 PRG:0F30 85 6C
|
|
sta $6D ; CPU:$CF32 PRG:0F32 85 6D
|
|
sta $6E ; CPU:$CF34 PRG:0F34 85 6E
|
|
sta $6F ; CPU:$CF36 PRG:0F36 85 6F
|
|
|
|
lda #$C0 ; CPU:$CF38 PRG:0F38 A9 C0
|
|
sta $6A ; CPU:$CF3A PRG:0F3A 85 6A
|
|
|
|
lda $68 ; CPU:$CF3C PRG:0F3C A5 68
|
|
cmp #$16 ; CPU:$CF3E PRG:0F3E C9 16
|
|
beq @SkipIncrement68 ; CPU:$CF40 PRG:0F40 F0 02
|
|
|
|
inc $68 ; CPU:$CF42 PRG:0F42 E6 68
|
|
|
|
@SkipIncrement68:
|
|
jsr InitializeGameplayAttributes ; CPU:$CF44 PRG:0F44 20 31 D1
|
|
jsr DrawMazeNametable ; CPU:$CF47 PRG:0F47 20 E2 E2
|
|
jsr DrawGameplayScoreFields ; CPU:$CF4A PRG:0F4A 20 FF E3
|
|
jsr InitializeGameNametableRegion ; CPU:$CF4D PRG:0F4D 20 AB D0
|
|
jsr DrawLevelProgressMarkers ; CPU:$CF50 PRG:0F50 20 53 E5
|
|
jsr $E5C1 ; CPU:$CF53 PRG:0F53 20 C1 E5
|
|
jsr DrawGameplayHudLabels ; CPU:$CF56 PRG:0F56 20 02 E5
|
|
|
|
@ContinueSetup:
|
|
ldx $68 ; CPU:$CF59 PRG:0F59 A6 68
|
|
|
|
lda #$00 ; CPU:$CF5B PRG:0F5B A9 00
|
|
clc ; CPU:$CF5D PRG:0F5D 18
|
|
|
|
@MultiplyBy6:
|
|
dex ; CPU:$CF5E PRG:0F5E CA
|
|
bmi @MultiplyBy6Done ; CPU:$CF5F PRG:0F5F 30 04
|
|
|
|
adc #$06 ; CPU:$CF61 PRG:0F61 69 06
|
|
bne @MultiplyBy6 ; CPU:$CF63 PRG:0F63 D0 F9
|
|
|
|
@MultiplyBy6Done:
|
|
sta $00 ; CPU:$CF65 PRG:0F65 85 00
|
|
tax ; CPU:$CF67 PRG:0F67 AA
|
|
|
|
lda $EBB6,x ; CPU:$CF68 PRG:0F68 BD B6 EB
|
|
tax ; CPU:$CF6B PRG:0F6B AA
|
|
|
|
lda #$00 ; CPU:$CF6C PRG:0F6C A9 00
|
|
clc ; CPU:$CF6E PRG:0F6E 18
|
|
|
|
@MultiplyBy22:
|
|
dex ; CPU:$CF6F PRG:0F6F CA
|
|
bmi @MultiplyBy22Done ; CPU:$CF70 PRG:0F70 30 04
|
|
|
|
adc #$16 ; CPU:$CF72 PRG:0F72 69 16
|
|
bne @MultiplyBy22 ; CPU:$CF74 PRG:0F74 D0 F9
|
|
|
|
@MultiplyBy22Done:
|
|
tay ; CPU:$CF76 PRG:0F76 A8
|
|
|
|
ldx #$00 ; CPU:$CF77 PRG:0F77 A2 00
|
|
|
|
@CopyGameParameters:
|
|
lda $EC40,y ; CPU:$CF79 PRG:0F79 B9 40 EC
|
|
sta $9F,x ; CPU:$CF7C PRG:0F7C 95 9F
|
|
inx ; CPU:$CF7E PRG:0F7E E8
|
|
iny ; CPU:$CF7F PRG:0F7F C8
|
|
cpx #$16 ; CPU:$CF80 PRG:0F80 E0 16
|
|
bne @CopyGameParameters ; CPU:$CF82 PRG:0F82 D0 F5
|
|
|
|
ldx $00 ; CPU:$CF84 PRG:0F84 A6 00
|
|
|
|
lda $EBB6,x ; CPU:$CF86 PRG:0F86 BD B6 EB
|
|
asl ; CPU:$CF89 PRG:0F89 0A
|
|
asl ; CPU:$CF8A PRG:0F8A 0A
|
|
asl ; CPU:$CF8B PRG:0F8B 0A
|
|
tax ; CPU:$CF8C PRG:0F8C AA
|
|
|
|
ldy #$00 ; CPU:$CF8D PRG:0F8D A0 00
|
|
sty $D0 ; CPU:$CF8F PRG:0F8F 84 D0
|
|
|
|
; Save the first selected table value separately.
|
|
lda $ECAE,x ; CPU:$CF91 PRG:0F91 BD AE EC
|
|
sta $CF ; CPU:$CF94 PRG:0F94 85 CF
|
|
|
|
@CopyTableECae:
|
|
lda $ECAE,x ; CPU:$CF96 PRG:0F96 BD AE EC
|
|
sta $0097,y ; CPU:$CF99 PRG:0F99 99 97 00
|
|
|
|
inx ; CPU:$CF9C PRG:0F9C E8
|
|
iny ; CPU:$CF9D PRG:0F9D C8
|
|
cpy #$08 ; CPU:$CF9E PRG:0F9E C0 08
|
|
bne @CopyTableECae ; CPU:$CFA0 PRG:0FA0 D0 F4
|
|
|
|
inc $00 ; CPU:$CFA2 PRG:0FA2 E6 00
|
|
|
|
ldx $00 ; CPU:$CFA4 PRG:0FA4 A6 00
|
|
lda $EBB6,x ; CPU:$CFA6 PRG:0FA6 BD B6 EB
|
|
sta $8C ; CPU:$CFA9 PRG:0FA9 85 8C
|
|
|
|
inc $00 ; CPU:$CFAB PRG:0FAB E6 00
|
|
|
|
ldx $00 ; CPU:$CFAD PRG:0FAD A6 00
|
|
lda $EBB6,x ; CPU:$CFAF PRG:0FAF BD B6 EB
|
|
asl ; CPU:$CFB2 PRG:0FB2 0A
|
|
tax ; CPU:$CFB3 PRG:0FB3 AA
|
|
|
|
lda $ECCE,x ; CPU:$CFB4 PRG:0FB4 BD CE EC
|
|
sta $8D ; CPU:$CFB7 PRG:0FB7 85 8D
|
|
inx ; CPU:$CFB9 PRG:0FB9 E8
|
|
lda $ECCE,x ; CPU:$CFBA PRG:0FBA BD CE EC
|
|
sta $8E ; CPU:$CFBD PRG:0FBD 85 8E
|
|
|
|
inc $00 ; CPU:$CFBF PRG:0FBF E6 00
|
|
|
|
lda $69 ; CPU:$CFC1 PRG:0FC1 A5 69
|
|
beq @UseAlternateData ; CPU:$CFC3 PRG:0FC3 F0 24
|
|
|
|
ldx #$0C ; CPU:$CFC5 PRG:0FC5 A2 0C
|
|
ldy #$00 ; CPU:$CFC7 PRG:0FC7 A0 00
|
|
|
|
lda $ECDC,x ; CPU:$CFC9 PRG:0FC9 BD DC EC
|
|
sta $008F,y ; CPU:$CFCC PRG:0FCC 99 8F 00
|
|
|
|
iny ; CPU:$CFCF PRG:0FCF C8
|
|
inx ; CPU:$CFD0 PRG:0FD0 E8
|
|
|
|
lda #$C0 ; CPU:$CFD1 PRG:0FD1 A9 C0
|
|
sec ; CPU:$CFD3 PRG:0FD3 38
|
|
sbc $6A ; CPU:$CFD4 PRG:0FD4 E5 6A
|
|
sta $01 ; CPU:$CFD6 PRG:0FD6 85 01
|
|
|
|
@CopyOffsetData:
|
|
lda $01 ; CPU:$CFD8 PRG:0FD8 A5 01
|
|
clc ; CPU:$CFDA PRG:0FDA 18
|
|
adc $ECDC,x ; CPU:$CFDB PRG:0FDB 7D DC EC
|
|
sta $008F,y ; CPU:$CFDE PRG:0FDE 99 8F 00
|
|
|
|
iny ; CPU:$CFE1 PRG:0FE1 C8
|
|
inx ; CPU:$CFE2 PRG:0FE2 E8
|
|
|
|
cpy #$04 ; CPU:$CFE3 PRG:0FE3 C0 04
|
|
bne @CopyOffsetData ; CPU:$CFE5 PRG:0FE5 D0 F1
|
|
|
|
beq @InitializeArray ; CPU:$CFE7 PRG:0FE7 F0 16
|
|
|
|
@UseAlternateData:
|
|
ldx $00 ; CPU:$CFE9 PRG:0FE9 A6 00
|
|
|
|
lda $EBB6,x ; CPU:$CFEB PRG:0FEB BD B6 EB
|
|
asl ; CPU:$CFEE PRG:0FEE 0A
|
|
asl ; CPU:$CFEF PRG:0FEF 0A
|
|
tax ; CPU:$CFF0 PRG:0FF0 AA
|
|
|
|
ldy #$00 ; CPU:$CFF1 PRG:0FF1 A0 00
|
|
|
|
@CopyAlternateData:
|
|
lda $ECDC,x ; CPU:$CFF3 PRG:0FF3 BD DC EC
|
|
sta $008F,y ; CPU:$CFF6 PRG:0FF6 99 8F 00
|
|
|
|
inx ; CPU:$CFF9 PRG:0FF9 E8
|
|
iny ; CPU:$CFFA PRG:0FFA C8
|
|
cpy #$04 ; CPU:$CFFB PRG:0FFB C0 04
|
|
bne @CopyAlternateData ; CPU:$CFFD PRG:0FFD D0 F4
|
|
|
|
|
|
@InitializeArray:
|
|
lda #$04 ; CPU:$CFFF PRG:0FFF A9 04
|
|
sta $B8 ; CPU:$D001 PRG:1001 85 B8
|
|
|
|
lda #$01 ; CPU:$D003 PRG:1003 A9 01
|
|
sta $B9 ; CPU:$D005 PRG:1005 85 B9
|
|
|
|
lda $8F ; CPU:$D007 PRG:1007 A5 8F
|
|
sta $01 ; CPU:$D009 PRG:1009 85 01
|
|
|
|
ldx #$00 ; CPU:$D00B PRG:100B A2 00
|
|
|
|
@InitializeArrayLoop:
|
|
dec $01 ; CPU:$D00D PRG:100D C6 01
|
|
beq @InitializeArrayTail ; CPU:$D00F PRG:100F F0 0C
|
|
|
|
lda #$02 ; CPU:$D011 PRG:1011 A9 02
|
|
sta $BA,x ; CPU:$D013 PRG:1013 95 BA
|
|
|
|
lda #$00 ; CPU:$D015 PRG:1015 A9 00
|
|
sta $BB,x ; CPU:$D017 PRG:1017 95 BB
|
|
|
|
inx ; CPU:$D019 PRG:1019 E8
|
|
inx ; CPU:$D01A PRG:101A E8
|
|
bne @InitializeArrayLoop ; CPU:$D01B PRG:101B D0 F0
|
|
|
|
|
|
@InitializeArrayTail:
|
|
lda #$00 ; CPU:$D01D PRG:101D A9 00
|
|
|
|
@ClearRemainingArray:
|
|
cpx #$06 ; CPU:$D01F PRG:101F E0 06
|
|
beq @ContinueFinalSetup ; CPU:$D021 PRG:1021 F0 08
|
|
|
|
sta $BA,x ; CPU:$D023 PRG:1023 95 BA
|
|
sta $BB,x ; CPU:$D025 PRG:1025 95 BB
|
|
|
|
inx ; CPU:$D027 PRG:1027 E8
|
|
inx ; CPU:$D028 PRG:1028 E8
|
|
bne @ClearRemainingArray ; CPU:$D029 PRG:1029 D0 F4
|
|
|
|
|
|
@ContinueFinalSetup:
|
|
lda $90 ; CPU:$D02B PRG:102B A5 90
|
|
sta $D3 ; CPU:$D02D PRG:102D 85 D3
|
|
|
|
inc $00 ; CPU:$D02F PRG:102F E6 00
|
|
|
|
ldx $00 ; CPU:$D031 PRG:1031 A6 00
|
|
lda $EBB6,x ; CPU:$D033 PRG:1033 BD B6 EB
|
|
sta $93 ; CPU:$D036 PRG:1036 85 93
|
|
|
|
inc $00 ; CPU:$D038 PRG:1038 E6 00
|
|
|
|
ldx $00 ; CPU:$D03A PRG:103A A6 00
|
|
lda $EBB6,x ; CPU:$D03C PRG:103C BD B6 EB
|
|
sta $96 ; CPU:$D03F PRG:103F 85 96
|
|
|
|
lda $A5 ; CPU:$D041 PRG:1041 A5 A5
|
|
sta $B5 ; CPU:$D043 PRG:1043 85 B5
|
|
|
|
lda $A6 ; CPU:$D045 PRG:1045 A5 A6
|
|
sta $B6 ; CPU:$D047 PRG:1047 85 B6
|
|
|
|
lda $AF ; CPU:$D049 PRG:1049 A5 AF
|
|
sta $C4 ; CPU:$D04B PRG:104B 85 C4
|
|
sta $C6 ; CPU:$D04D PRG:104D 85 C6
|
|
sta $C8 ; CPU:$D04F PRG:104F 85 C8
|
|
sta $CA ; CPU:$D051 PRG:1051 85 CA
|
|
|
|
lda $B0 ; CPU:$D053 PRG:1053 A5 B0
|
|
sta $C5 ; CPU:$D055 PRG:1055 85 C5
|
|
sta $C7 ; CPU:$D057 PRG:1057 85 C7
|
|
sta $C9 ; CPU:$D059 PRG:1059 85 C9
|
|
sta $CB ; CPU:$D05B PRG:105B 85 CB
|
|
|
|
lda #$01 ; CPU:$D05D PRG:105D A9 01
|
|
sta $50 ; CPU:$D05F PRG:105F 85 50
|
|
sta $51 ; CPU:$D061 PRG:1061 85 51
|
|
|
|
ldy #$00 ; CPU:$D063 PRG:1063 A0 00
|
|
ldx #$00 ; CPU:$D065 PRG:1065 A2 00
|
|
|
|
lda $46 ; CPU:$D067 PRG:1067 A5 46
|
|
and $47 ; CPU:$D069 PRG:1069 25 47
|
|
beq @CopyDisplayInit ; CPU:$D06B PRG:106B F0 02
|
|
|
|
ldy #$09 ; CPU:$D06D PRG:106D A0 09
|
|
|
|
@CopyDisplayInit:
|
|
lda GameDisplayInitialData,y ; CPU:$D06F PRG:106F B9 FF D0
|
|
sta $026B,x ; CPU:$D072 PRG:1072 9D 6B 02
|
|
|
|
iny ; CPU:$D075 PRG:1075 C8
|
|
inx ; CPU:$D076 PRG:1076 E8
|
|
cpx #$09 ; CPU:$D077 PRG:1077 E0 09
|
|
bne @CopyDisplayInit ; CPU:$D079 PRG:1079 D0 F4
|
|
|
|
ldy #$00 ; CPU:$D07B PRG:107B A0 00
|
|
|
|
@CopyStateData:
|
|
lda GameStateInitialValues,y ; CPU:$D07D PRG:107D B9 F3 D0
|
|
sta $0032,y ; CPU:$D080 PRG:1080 99 32 00
|
|
iny ; CPU:$D083 PRG:1083 C8
|
|
cpy #$0C ; CPU:$D084 PRG:1084 C0 0C
|
|
bne @CopyStateData ; CPU:$D086 PRG:1086 D0 F5
|
|
|
|
ldy #$00 ; CPU:$D088 PRG:1088 A0 00
|
|
|
|
@NormalizeValues:
|
|
lda $006C,y ; CPU:$D08A PRG:108A B9 6C 00
|
|
cmp #$02 ; CPU:$D08D PRG:108D C9 02
|
|
bne @NextNormalizeValue ; CPU:$D08F PRG:108F D0 05
|
|
|
|
lda #$01 ; CPU:$D091 PRG:1091 A9 01
|
|
sta $006C,y ; CPU:$D093 PRG:1093 99 6C 00
|
|
|
|
@NextNormalizeValue:
|
|
iny ; CPU:$D096 PRG:1096 C8
|
|
cpy #$04 ; CPU:$D097 PRG:1097 C0 04
|
|
bne @NormalizeValues ; CPU:$D099 PRG:1099 D0 EF
|
|
|
|
sty $C0 ; CPU:$D09B PRG:109B 84 C0
|
|
|
|
lda #$FF ; CPU:$D09D PRG:109D A9 FF
|
|
sta $89 ; CPU:$D09F PRG:109F 85 89
|
|
|
|
lda #$88 ; CPU:$D0A1 PRG:10A1 A9 88
|
|
sta PPUCTRL ; CPU:$D0A3 PRG:10A3 8D 00 20
|
|
sta $43 ; CPU:$D0A6 PRG:10A6 85 43
|
|
|
|
jmp GameModeFrameSync ; CPU:$D0A8 PRG:10A8 4C A7 CA
|
|
|
|
;==============================================================================
|
|
; $D0AB-$D0F2: Initialize/Clear Repeated Nametable Region
|
|
;
|
|
; Local:
|
|
; Selects an initial PPU destination based on ($46 & $47):
|
|
;
|
|
; zero -> $2256
|
|
; nonzero -> $2A56
|
|
;
|
|
; It then performs 10 iterations. For each iteration:
|
|
;
|
|
; - Sets PPUADDR to the current destination.
|
|
; - Writes six $20 tiles.
|
|
; - Writes two $2D tiles.
|
|
; - Advances the destination address by $20.
|
|
;
|
|
; Global:
|
|
; Called from GameModeState00 during game/round initialization while
|
|
; rendering is disabled. This prepares the same rectangular display region
|
|
; in one of two nametable locations depending on the current player/mode
|
|
; state represented by $46/$47.
|
|
;
|
|
; Notes:
|
|
; $00/$01 form the current 16-bit PPU destination address.
|
|
; $02 counts 10 rows.
|
|
; $03 counts the six $20 tile writes in each row.
|
|
;
|
|
; $20 and $2D are retained as raw tile IDs during this pass.
|
|
;==============================================================================
|
|
|
|
InitializeGameNametableRegion:
|
|
ldy #$22 ; CPU:$D0AB PRG:10AB A0 22
|
|
|
|
lda $46 ; CPU:$D0AD PRG:10AD A5 46
|
|
and $47 ; CPU:$D0AF PRG:10AF 25 47
|
|
beq @SetDestination ; CPU:$D0B1 PRG:10B1 F0 02
|
|
|
|
ldy #$2A ; CPU:$D0B3 PRG:10B3 A0 2A
|
|
|
|
@SetDestination:
|
|
sty $00 ; CPU:$D0B5 PRG:10B5 84 00
|
|
|
|
lda #$56 ; CPU:$D0B7 PRG:10B7 A9 56
|
|
sta $01 ; CPU:$D0B9 PRG:10B9 85 01
|
|
|
|
lda #$0A ; CPU:$D0BB PRG:10BB A9 0A
|
|
sta $02 ; CPU:$D0BD PRG:10BD 85 02
|
|
|
|
@NextRow:
|
|
lda PPUSTATUS ; CPU:$D0BF PRG:10BF AD 02 20
|
|
|
|
lda $00 ; CPU:$D0C2 PRG:10C2 A5 00
|
|
sta PPUADDR ; CPU:$D0C4 PRG:10C4 8D 06 20
|
|
|
|
lda $01 ; CPU:$D0C7 PRG:10C7 A5 01
|
|
sta PPUADDR ; CPU:$D0C9 PRG:10C9 8D 06 20
|
|
|
|
lda #$06 ; CPU:$D0CC PRG:10CC A9 06
|
|
sta $03 ; CPU:$D0CE PRG:10CE 85 03
|
|
|
|
lda #$20 ; CPU:$D0D0 PRG:10D0 A9 20
|
|
|
|
@WriteInterior:
|
|
sta PPUDATA ; CPU:$D0D2 PRG:10D2 8D 07 20
|
|
|
|
dec $03 ; CPU:$D0D5 PRG:10D5 C6 03
|
|
bne @WriteInterior ; CPU:$D0D7 PRG:10D7 D0 F9
|
|
|
|
lda #$2D ; CPU:$D0D9 PRG:10D9 A9 2D
|
|
sta PPUDATA ; CPU:$D0DB PRG:10DB 8D 07 20
|
|
sta PPUDATA ; CPU:$D0DE PRG:10DE 8D 07 20
|
|
|
|
; Advance the destination by one full nametable row ($20 bytes).
|
|
lda $01 ; CPU:$D0E1 PRG:10E1 A5 01
|
|
clc ; CPU:$D0E3 PRG:10E3 18
|
|
adc #$20 ; CPU:$D0E4 PRG:10E4 69 20
|
|
sta $01 ; CPU:$D0E6 PRG:10E6 85 01
|
|
|
|
lda $00 ; CPU:$D0E8 PRG:10E8 A5 00
|
|
adc #$00 ; CPU:$D0EA PRG:10EA 69 00
|
|
sta $00 ; CPU:$D0EC PRG:10EC 85 00
|
|
|
|
dec $02 ; CPU:$D0EE PRG:10EE C6 02
|
|
bne @NextRow ; CPU:$D0F0 PRG:10F0 D0 CD
|
|
|
|
rts ; CPU:$D0F2 PRG:10F2 60
|
|
|
|
;==============================================================================
|
|
; $D0F3-$D130: Game-Mode State $00 Initialization Data
|
|
;
|
|
; Local:
|
|
; Contains three adjacent data blocks consumed during GameModeState00:
|
|
;
|
|
; $D0F3-$D0FE 12-byte state initialization table
|
|
; $D0FF-$D110 18-byte display/update table
|
|
; $D111-$D130 32-byte palette table
|
|
;
|
|
; Global:
|
|
; Supplies initial state, display-command, and palette data used when
|
|
; GameModeState00 prepares a new game/round state.
|
|
;
|
|
; Notes:
|
|
; The display table is intentionally kept as raw tile/command bytes during
|
|
; this pass. GameModeState00 selects either offset $00 or $09 from this
|
|
; table and copies nine bytes to $026B-$0273.
|
|
;
|
|
; The palette table is copied in full to $0299-$02B8.
|
|
;==============================================================================
|
|
|
|
|
|
;==============================================================================
|
|
; $D0F3-$D0FE: Game State Initialization Values
|
|
;
|
|
; Local:
|
|
; 12 bytes copied directly to zero-page RAM $32-$3D:
|
|
;
|
|
; ROM $D0F3-$D0FE -> RAM $0032-$003D
|
|
;
|
|
; Global:
|
|
; Establishes a compact block of initial game-state values during
|
|
; GameModeState00.
|
|
;
|
|
; Notes:
|
|
; Individual fields remain unnamed until their consumers are traced.
|
|
;==============================================================================
|
|
|
|
GameStateInitialValues:
|
|
.byte $04,$0C,$0A,$0A ; CPU:$D0F3 PRG:10F3 04 0C 0A 0A
|
|
.byte $0A,$00,$00,$00 ; CPU:$D0F7 PRG:10F7 0A 00 00 00
|
|
.byte $01,$02,$03,$00 ; CPU:$D0FB PRG:10FB 01 02 03 00
|
|
|
|
|
|
;==============================================================================
|
|
; $D0FF-$D110: Game Display Initialization Data
|
|
;
|
|
; Local:
|
|
; Contains two 9-byte records. GameModeState00 selects the first record when
|
|
; ($46 & $47) is zero and the second record when it is nonzero.
|
|
;
|
|
; The selected nine bytes are copied to RAM $026B-$0273.
|
|
;
|
|
; Global:
|
|
; Provides alternate display/update initialization according to the active
|
|
; player/mode state.
|
|
;
|
|
; Notes:
|
|
; These bytes appear to mix PPU/update-command values and tile IDs.
|
|
; Preserve them numerically until the consumer of $026B is decoded.
|
|
;==============================================================================
|
|
GameDisplayInitialData:
|
|
|
|
; Record 0, selected when ($46 & $47) == 0.
|
|
; $D0FF-$D107
|
|
.byte $21,$36,$20,$F7,$B0,$B3,$B2,$20,$B6 ; CPU:$D0FF PRG:10FF 21 36 20 F7 B0 B3 B2 20 B6
|
|
|
|
; Record 1, selected when ($46 & $47) != 0.
|
|
; $D108-$D110
|
|
.byte $29,$B6,$29,$77,$B1,$B3,$B2,$28,$B6 ; CPU:$D108 PRG:1108 29 B6 29 77 B1 B3 B2 28 B6
|
|
|
|
|
|
;==============================================================================
|
|
; $D111-$D130: Initial Gameplay Palette
|
|
;
|
|
; Local:
|
|
; Complete 32-byte palette copied to RAM $0299-$02B8 by GameModeState00.
|
|
; The NMI palette-update mechanism later transfers these buffers into PPU
|
|
; palette RAM.
|
|
;
|
|
; Global:
|
|
; Defines the initial background and sprite color palettes used for normal
|
|
; gameplay/game-mode initialization.
|
|
;
|
|
; Notes:
|
|
; $D111-$D120 contains four background palettes.
|
|
; $D121-$D130 contains four sprite palettes.
|
|
;
|
|
; Palette values are retained as NES color indices.
|
|
;==============================================================================
|
|
GameplayPaletteData:
|
|
; Background palette 0
|
|
.byte $0F,$20,$0F,$06 ; CPU:$D111 PRG:1111 0F 20 0F 06
|
|
|
|
; Background palette 1
|
|
.byte $0F,$11,$0F,$27 ; CPU:$D115 PRG:1115 0F 11 0F 27
|
|
|
|
; Background palette 2
|
|
.byte $0F,$16,$26,$06 ; CPU:$D119 PRG:1119 0F 16 26 06
|
|
|
|
; Background palette 3
|
|
.byte $0F,$19,$17,$12 ; CPU:$D11D PRG:111D 0F 19 17 12
|
|
|
|
; Sprite palette 0
|
|
.byte $0F,$27,$20,$06 ; CPU:$D121 PRG:1121 0F 27 20 06
|
|
|
|
; Sprite palette 1
|
|
.byte $0F,$11,$20,$33 ; CPU:$D125 PRG:1125 0F 11 20 33
|
|
|
|
; Sprite palette 2
|
|
.byte $0F,$21,$20,$21 ; CPU:$D129 PRG:1129 0F 21 20 21
|
|
|
|
; Sprite palette 3
|
|
.byte $0F,$09,$20,$17 ; CPU:$D12D PRG:112D 0F 09 20 17
|
|
|
|
;==============================================================================
|
|
; $D131-$D15F: Initialize Gameplay Nametable Attributes
|
|
;
|
|
; Local:
|
|
; Copies the 64-byte attribute table at $D160 to two PPU destinations:
|
|
;
|
|
; pass 1 -> PPU $23C0-$23FF
|
|
; pass 2 -> PPU $2BC0-$2BFF
|
|
;
|
|
; The first pass uses X=$01. After copying all $40 bytes, X is decremented.
|
|
; Since X becomes zero, execution falls through into the setup for the
|
|
; second destination at $2BC0.
|
|
;
|
|
; After the second copy, X decrements from $00 to $FF and the routine
|
|
; returns.
|
|
;
|
|
; Global:
|
|
; Called by GameModeState00 during game/round initialization. Initializes
|
|
; complete attribute tables for two nametables using identical palette-
|
|
; selection data.
|
|
;
|
|
; Notes:
|
|
; The branch at $D15E intentionally jumps back into the shared copy loop
|
|
; after selecting PPU address $2BC0.
|
|
;
|
|
; $D160 begins the 64-byte attribute source table and is not executable.
|
|
;==============================================================================
|
|
|
|
InitializeGameplayAttributes:
|
|
lda PPUSTATUS ; CPU:$D131 PRG:1131 AD 02 20
|
|
|
|
lda #$23 ; CPU:$D134 PRG:1134 A9 23
|
|
sta PPUADDR ; CPU:$D136 PRG:1136 8D 06 20
|
|
|
|
lda #$C0 ; CPU:$D139 PRG:1139 A9 C0
|
|
sta PPUADDR ; CPU:$D13B PRG:113B 8D 06 20
|
|
|
|
ldx #$01 ; CPU:$D13E PRG:113E A2 01
|
|
|
|
@CopyAttributeTable:
|
|
ldy #$00 ; CPU:$D140 PRG:1140 A0 00
|
|
|
|
@CopyAttributeBytes:
|
|
lda GameplayAttributeData,y ; CPU:$D142 PRG:1142 B9 60 D1
|
|
sta PPUDATA ; CPU:$D145 PRG:1145 8D 07 20
|
|
|
|
iny ; CPU:$D148 PRG:1148 C8
|
|
cpy #$40 ; CPU:$D149 PRG:1149 C0 40
|
|
bne @CopyAttributeBytes ; CPU:$D14B PRG:114B D0 F5
|
|
|
|
dex ; CPU:$D14D PRG:114D CA
|
|
beq @SetupSecondNametable ; CPU:$D14E PRG:114E F0 01
|
|
|
|
rts ; CPU:$D150 PRG:1150 60
|
|
|
|
@SetupSecondNametable:
|
|
lda PPUSTATUS ; CPU:$D151 PRG:1151 AD 02 20
|
|
|
|
lda #$2B ; CPU:$D154 PRG:1154 A9 2B
|
|
sta PPUADDR ; CPU:$D156 PRG:1156 8D 06 20
|
|
|
|
lda #$C0 ; CPU:$D159 PRG:1159 A9 C0
|
|
sta PPUADDR ; CPU:$D15B PRG:115B 8D 06 20
|
|
|
|
bne @CopyAttributeTable ; CPU:$D15E PRG:115E D0 E0
|
|
|
|
;==============================================================================
|
|
; $D160-$D19F: Gameplay Nametable Attribute Data
|
|
;
|
|
; Local:
|
|
; Complete 64-byte NES attribute table copied to both PPU $23C0-$23FF and
|
|
; $2BC0-$2BFF by InitializeGameplayAttributes.
|
|
;
|
|
; Global:
|
|
; Defines background-palette selections for the gameplay nametables.
|
|
;
|
|
; Notes:
|
|
; Common values:
|
|
;
|
|
; $00 -> palette 0 in all four attribute quadrants
|
|
; $55 -> palette 1 in all four quadrants
|
|
;
|
|
; Values such as $11, $51, $50 and $05 combine different palette selections
|
|
; within the four quadrants of an attribute byte.
|
|
;==============================================================================
|
|
|
|
GameplayAttributeData:
|
|
.byte $55,$55,$55,$55,$55,$11,$00,$00 ; CPU:$D160 PRG:1160 55 55 55 55 55 11 00 00
|
|
.byte $55,$55,$55,$55,$55,$11,$00,$00 ; CPU:$D168 PRG:1168 55 55 55 55 55 11 00 00
|
|
.byte $55,$55,$55,$55,$55,$11,$00,$00 ; CPU:$D170 PRG:1170 55 55 55 55 55 11 00 00
|
|
.byte $55,$55,$55,$55,$55,$51,$50,$50 ; CPU:$D178 PRG:1178 55 55 55 55 55 51 50 50
|
|
.byte $55,$55,$55,$55,$55,$11,$05,$05 ; CPU:$D180 PRG:1180 55 55 55 55 55 11 05 05
|
|
.byte $55,$55,$55,$55,$55,$11,$00,$00 ; CPU:$D188 PRG:1188 55 55 55 55 55 11 00 00
|
|
.byte $55,$55,$55,$55,$55,$55,$55,$55 ; CPU:$D190 PRG:1190 55 55 55 55 55 55 55 55
|
|
.byte $55,$55,$55,$55,$55,$55,$55,$55 ; CPU:$D198 PRG:1198 55 55 55 55 55 55 55 55
|
|
|
|
;==============================================================================
|
|
; $D1A0-$D289: Gameplay Timers and State Progression
|
|
;
|
|
; Local:
|
|
; Updates several gameplay timers, palette-animation values, progression
|
|
; counters, and state variables.
|
|
;
|
|
; Global:
|
|
; Called once per active gameplay frame from GameModeState04. Coordinates
|
|
; several independent timing and progression systems.
|
|
;
|
|
; Notes:
|
|
; Address-based local labels are used during this pass to make the original
|
|
; branch destinations explicit and simplify byte-identical verification.
|
|
;==============================================================================
|
|
|
|
UpdateGameplayTimers:
|
|
lda $89 ; CPU:$D1A0 PRG:11A0 A5 89
|
|
bmi @D1E1 ; CPU:$D1A2 PRG:11A2 30 3C
|
|
|
|
inc $8A ; CPU:$D1A4 PRG:11A4 E6 8A
|
|
|
|
lda #$3C ; CPU:$D1A6 PRG:11A6 A9 3C
|
|
cmp $8A ; CPU:$D1A8 PRG:11A8 C5 8A
|
|
bne @D1C9 ; CPU:$D1AA PRG:11AA D0 1C
|
|
|
|
lda #$00 ; CPU:$D1AC PRG:11AC A9 00
|
|
sta $8A ; CPU:$D1AE PRG:11AE 85 8A
|
|
|
|
dec $89 ; CPU:$D1B0 PRG:11B0 C6 89
|
|
bpl @D1C9 ; CPU:$D1B2 PRG:11B2 10 14
|
|
|
|
sta $88 ; CPU:$D1B4 PRG:11B4 85 88
|
|
|
|
ldx #$00 ; CPU:$D1B6 PRG:11B6 A2 00
|
|
|
|
@D1B7:
|
|
lda $39,x ; CPU:$D1B8 PRG:11B8 B5 39
|
|
and #$FC ; CPU:$D1BA PRG:11BA 29 FC
|
|
sta $00 ; CPU:$D1BC PRG:11BC 85 00
|
|
|
|
txa ; CPU:$D1BE PRG:11BE 8A
|
|
ora $00 ; CPU:$D1BF PRG:11BF 05 00
|
|
sta $39,x ; CPU:$D1C1 PRG:11C1 95 39
|
|
|
|
inx ; CPU:$D1C3 PRG:11C3 E8
|
|
cpx #$04 ; CPU:$D1C4 PRG:11C4 E0 04
|
|
bne @D1B7 ; CPU:$D1C6 PRG:11C6 D0 F0
|
|
|
|
@D1C9:
|
|
lda $89 ; CPU:$D1C8 PRG:11C8 A5 89
|
|
cmp #$02 ; CPU:$D1CA PRG:11CA C9 02
|
|
bcs @D1E1 ; CPU:$D1CC PRG:11CC B0 12
|
|
|
|
ldx #$11 ; CPU:$D1CE PRG:11CE A2 11
|
|
|
|
lda $8A ; CPU:$D1D0 PRG:11D0 A5 8A
|
|
and #$08 ; CPU:$D1D2 PRG:11D2 29 08
|
|
bne @D1D9 ; CPU:$D1D4 PRG:11D4 D0 02
|
|
|
|
ldx #$20 ; CPU:$D1D6 PRG:11D6 A2 20
|
|
|
|
@D1D9:
|
|
stx $02AE ; CPU:$D1D8 PRG:11D8 8E AE 02
|
|
|
|
lda #$0F ; CPU:$D1DB PRG:11DB A9 0F
|
|
sta $02A9 ; CPU:$D1DD PRG:11DD 8D A9 02
|
|
|
|
|
|
@D1E1:
|
|
lda $88 ; CPU:$D1E0 PRG:11E0 A5 88
|
|
bne @D213 ; CPU:$D1E2 PRG:11E2 D0 2F
|
|
|
|
lda $CF ; CPU:$D1E4 PRG:11E4 A5 CF
|
|
cmp #$FF ; CPU:$D1E6 PRG:11E6 C9 FF
|
|
beq @D213 ; CPU:$D1E8 PRG:11E8 F0 29
|
|
|
|
inc $D1 ; CPU:$D1EA PRG:11EA E6 D1
|
|
|
|
lda $D1 ; CPU:$D1EC PRG:11EC A5 D1
|
|
cmp #$3C ; CPU:$D1EE PRG:11EE C9 3C
|
|
bne @D213 ; CPU:$D1F0 PRG:11F0 D0 21
|
|
|
|
lda #$00 ; CPU:$D1F2 PRG:11F2 A9 00
|
|
sta $D1 ; CPU:$D1F4 PRG:11F4 85 D1
|
|
|
|
dec $CF ; CPU:$D1F6 PRG:11F6 C6 CF
|
|
bpl @D213 ; CPU:$D1F8 PRG:11F8 10 19
|
|
|
|
inc $D0 ; CPU:$D1FA PRG:11FA E6 D0
|
|
|
|
lda $D0 ; CPU:$D1FC PRG:11FC A5 D0
|
|
and #$01 ; CPU:$D1FE PRG:11FE 29 01
|
|
beq @D209 ; CPU:$D200 PRG:1200 F0 07
|
|
|
|
jsr $E08E ; CPU:$D202 PRG:1202 20 8E E0
|
|
|
|
lda #$0F ; CPU:$D205 PRG:1205 A9 0F
|
|
bne @D20B ; CPU:$D207 PRG:1207 D0 02
|
|
|
|
@D209:
|
|
lda $D2 ; CPU:$D209 PRG:1209 A5 D2
|
|
|
|
@D20B:
|
|
sta $87 ; CPU:$D20B PRG:120B 85 87
|
|
|
|
ldx $D0 ; CPU:$D20D PRG:120D A6 D0
|
|
lda $97,x ; CPU:$D20F PRG:120F B5 97
|
|
sta $CF ; CPU:$D211 PRG:1211 85 CF
|
|
|
|
|
|
@D213:
|
|
lda $D3 ; CPU:$D213 PRG:1213 A5 D3
|
|
beq @D236 ; CPU:$D215 PRG:1215 F0 1F
|
|
|
|
clc ; CPU:$D217 PRG:1217 18
|
|
adc $6A ; CPU:$D218 PRG:1218 65 6A
|
|
cmp #$C0 ; CPU:$D21A PRG:121A C9 C0
|
|
bne @D236 ; CPU:$D21C PRG:121C D0 18
|
|
|
|
jsr ActivateNextStateEntry ; CPU:$D21E PRG:121E 20 8A D2
|
|
|
|
lda $D3 ; CPU:$D221 PRG:1221 A5 D3
|
|
ldx #$00 ; CPU:$D223 PRG:1223 A2 00
|
|
|
|
@D225:
|
|
cmp $8F,x ; CPU:$D225 PRG:1225 D5 8F
|
|
bne @D231 ; CPU:$D227 PRG:1227 D0 08
|
|
|
|
inx ; CPU:$D229 PRG:1229 E8
|
|
lda $8F,x ; CPU:$D22A PRG:122A B5 8F
|
|
sta $D3 ; CPU:$D22C PRG:122C 85 D3
|
|
|
|
jmp @D236 ; CPU:$D22E PRG:122E 4C 36 D2
|
|
|
|
@D231:
|
|
inx ; CPU:$D231 PRG:1231 E8
|
|
cpx #$04 ; CPU:$D232 PRG:1232 E0 04
|
|
bne @D225 ; CPU:$D234 PRG:1234 D0 EF
|
|
|
|
|
|
@D236:
|
|
inc $D6 ; CPU:$D236 PRG:1236 E6 D6
|
|
|
|
lda #$60 ; CPU:$D238 PRG:1238 A9 60
|
|
cmp $D6 ; CPU:$D23A PRG:123A C5 D6
|
|
bne @D251 ; CPU:$D23C PRG:123C D0 13
|
|
|
|
lda #$00 ; CPU:$D23E PRG:123E A9 00
|
|
sta $D6 ; CPU:$D240 PRG:1240 85 D6
|
|
|
|
inc $D5 ; CPU:$D242 PRG:1242 E6 D5
|
|
|
|
lda $D5 ; CPU:$D244 PRG:1244 A5 D5
|
|
cmp $96 ; CPU:$D246 PRG:1246 C5 96
|
|
bne @D251 ; CPU:$D248 PRG:1248 D0 07
|
|
|
|
lda #$00 ; CPU:$D24A PRG:124A A9 00
|
|
sta $D5 ; CPU:$D24C PRG:124C 85 D5
|
|
|
|
jsr ActivateNextStateEntry ; CPU:$D24E PRG:124E 20 8A D2
|
|
|
|
|
|
@D251:
|
|
ldx $D4 ; CPU:$D251 PRG:1251 A6 D4
|
|
|
|
cpx #$02 ; CPU:$D253 PRG:1253 E0 02
|
|
beq @D26E ; CPU:$D255 PRG:1255 F0 17
|
|
|
|
lda $8D,x ; CPU:$D257 PRG:1257 B5 8D
|
|
cmp $6A ; CPU:$D259 PRG:1259 C5 6A
|
|
bne @D26E ; CPU:$D25B PRG:125B D0 11
|
|
|
|
inc $D4 ; CPU:$D25D PRG:125D E6 D4
|
|
|
|
lda #$01 ; CPU:$D25F PRG:125F A9 01
|
|
sta $D2 ; CPU:$D261 PRG:1261 85 D2
|
|
|
|
txa ; CPU:$D263 PRG:1263 8A
|
|
asl ; CPU:$D264 PRG:1264 0A
|
|
tax ; CPU:$D265 PRG:1265 AA
|
|
|
|
lda $AB,x ; CPU:$D266 PRG:1266 B5 AB
|
|
sta $CA ; CPU:$D268 PRG:1268 85 CA
|
|
|
|
lda $AC,x ; CPU:$D26A PRG:126A B5 AC
|
|
sta $CB ; CPU:$D26C PRG:126C 85 CB
|
|
|
|
|
|
@D26E:
|
|
ora $D7 ; CPU:$D26E PRG:126E 05 D7
|
|
ora $D8 ; CPU:$D270 PRG:1270 05 D8
|
|
beq @D289 ; CPU:$D272 PRG:1272 F0 15
|
|
|
|
dec $D8 ; CPU:$D274 PRG:1274 C6 D8
|
|
bne @D289 ; CPU:$D276 PRG:1276 D0 11
|
|
|
|
lda $D7 ; CPU:$D278 PRG:1278 A5 D7
|
|
beq @D283 ; CPU:$D27A PRG:127A F0 07
|
|
|
|
dec $D7 ; CPU:$D27C PRG:127C C6 D7
|
|
|
|
lda #$3C ; CPU:$D27E PRG:127E A9 3C
|
|
sta $D8 ; CPU:$D280 PRG:1280 85 D8
|
|
|
|
rts ; CPU:$D282 PRG:1282 60
|
|
|
|
|
|
@D283:
|
|
sta $2E ; CPU:$D283 PRG:1283 85 2E
|
|
sta $30 ; CPU:$D285 PRG:1285 85 30
|
|
sta $8B ; CPU:$D287 PRG:1287 85 8B
|
|
|
|
|
|
@D289:
|
|
rts ; CPU:$D289 PRG:1289 60
|
|
|
|
;==============================================================================
|
|
; $D28A-$D29B: Activate First Available State Entry
|
|
;
|
|
; Local:
|
|
; Searches the even-indexed entries at $BA, $BC, and $BE for the first
|
|
; zero value.
|
|
;
|
|
; When a zero entry is found, replaces it with $02 and returns.
|
|
;
|
|
; If all three entries are already nonzero, returns without modifying them.
|
|
;
|
|
; Global:
|
|
; Called by UpdateGameplayTimers when certain progression timers expire.
|
|
; This appears to activate the next available entry in a three-element
|
|
; state array.
|
|
;
|
|
; Notes:
|
|
; Only the even addresses $BA/$BC/$BE are examined. The interleaved bytes
|
|
; $BB/$BD/$BF form a parallel field initialized elsewhere.
|
|
;
|
|
; The meaning of state value $02 will be refined when the consumers of
|
|
; $BA-$BF are decoded.
|
|
;==============================================================================
|
|
ActivateNextStateEntry:
|
|
ldx #$00 ; CPU:$D28A PRG:128A A2 00
|
|
|
|
@FindAvailableEntry:
|
|
lda $BA,x ; CPU:$D28C PRG:128C B5 BA
|
|
bne @NextEntry ; CPU:$D28E PRG:128E D0 05
|
|
|
|
lda #$02 ; CPU:$D290 PRG:1290 A9 02
|
|
sta $BA,x ; CPU:$D292 PRG:1292 95 BA
|
|
|
|
rts ; CPU:$D294 PRG:1294 60
|
|
|
|
@NextEntry:
|
|
inx ; CPU:$D295 PRG:1295 E8
|
|
inx ; CPU:$D296 PRG:1296 E8
|
|
|
|
cpx #$06 ; CPU:$D297 PRG:1297 E0 06
|
|
bne @FindAvailableEntry ; CPU:$D299 PRG:1299 D0 F1
|
|
|
|
rts ; CPU:$D29B PRG:129B 60
|
|
|
|
;==============================================================================
|
|
; $D29C-$D2A3: Sequential Tile/Value Table
|
|
;
|
|
; Local:
|
|
; Eight sequential values from $24 through $2B.
|
|
;
|
|
; Global:
|
|
; Consumer has not yet been decoded during this pass. Given the sequential
|
|
; values and the surrounding graphics-oriented code, this may represent
|
|
; tile IDs or animation values.
|
|
;
|
|
; Notes:
|
|
; Keep the table generically named until a direct reference establishes its
|
|
; exact purpose.
|
|
;==============================================================================
|
|
|
|
SequentialValueTableD29C:
|
|
.byte $24,$25,$26,$27,$28,$29,$2A,$2B ; CPU:$D29C PRG:129C 24 25 26 27 28 29 2A 2B
|
|
|
|
|
|
|
|
;==============================================================================
|
|
; $D2A4-$D36B: Gameplay Proximity / State Transition Handler
|
|
;
|
|
; Local:
|
|
; Returns immediately when $6A is zero.
|
|
;
|
|
; Otherwise scans even-indexed state entries beginning at $B8. Entries whose
|
|
; state value is $04 undergo two proximity tests using the four-byte
|
|
; structures beginning at $001E.
|
|
;
|
|
; $02 is shifted once for each scanned entry and acts as a candidate bitmask.
|
|
; When a qualifying entry is found, the routine selects one of several state
|
|
; transition paths based on X and ($02 & $88).
|
|
;
|
|
; Global:
|
|
; Called during normal gameplay processing from GameModeState04. This
|
|
; routine appears to detect proximity/collision conditions and initiate
|
|
; corresponding gameplay-state transitions.
|
|
;
|
|
; Notes:
|
|
; $00/$01 form a temporary pointer, initially $001E.
|
|
; $02 is a shifting bitmask.
|
|
; $03 is temporary storage for distance/index calculations.
|
|
;
|
|
; Lookup tables begin at ProximityCandidateValues and will be decoded separately.
|
|
;==============================================================================
|
|
CheckGameplayProximity:
|
|
lda $6A ; CPU:$D2A4 PRG:12A4 A5 6A
|
|
bne @Start ; CPU:$D2A6 PRG:12A6 D0 01
|
|
|
|
rts ; CPU:$D2A8 PRG:12A8 60
|
|
|
|
@Start:
|
|
lda #$1E ; CPU:$D2A9 PRG:12A9 A9 1E
|
|
sta $00 ; CPU:$D2AB PRG:12AB 85 00
|
|
|
|
lda #$00 ; CPU:$D2AD PRG:12AD A9 00
|
|
sta $01 ; CPU:$D2AF PRG:12AF 85 01
|
|
|
|
lda #$01 ; CPU:$D2B1 PRG:12B1 A9 01
|
|
sta $02 ; CPU:$D2B3 PRG:12B3 85 02
|
|
|
|
ldx #$00 ; CPU:$D2B5 PRG:12B5 A2 00
|
|
|
|
@ScanEntries:
|
|
lda $B8,x ; CPU:$D2B7 PRG:12B7 B5 B8
|
|
cmp #$04 ; CPU:$D2B9 PRG:12B9 C9 04
|
|
bne @NextEntry ; CPU:$D2BB PRG:12BB D0 32
|
|
|
|
ldy #$00 ; CPU:$D2BD PRG:12BD A0 00
|
|
|
|
lda $1A ; CPU:$D2BF PRG:12BF A5 1A
|
|
cmp ($00),y ; CPU:$D2C1 PRG:12C1 D1 00
|
|
bcs @FirstAxisReverse ; CPU:$D2C3 PRG:12C3 B0 07
|
|
|
|
lda ($00),y ; CPU:$D2C5 PRG:12C5 B1 00
|
|
sec ; CPU:$D2C7 PRG:12C7 38
|
|
sbc $1A ; CPU:$D2C8 PRG:12C8 E5 1A
|
|
bcs @CheckFirstAxisDistance ; CPU:$D2CA PRG:12CA B0 02
|
|
|
|
@FirstAxisReverse:
|
|
sbc ($00),y ; CPU:$D2CC PRG:12CC F1 00
|
|
|
|
@CheckFirstAxisDistance:
|
|
cmp #$0A ; CPU:$D2CE PRG:12CE C9 0A
|
|
bcs @NextEntry ; CPU:$D2D0 PRG:12D0 B0 1D
|
|
|
|
sta $03 ; CPU:$D2D2 PRG:12D2 85 03
|
|
|
|
ldy #$02 ; CPU:$D2D4 PRG:12D4 A0 02
|
|
|
|
lda $1C ; CPU:$D2D6 PRG:12D6 A5 1C
|
|
cmp ($00),y ; CPU:$D2D8 PRG:12D8 D1 00
|
|
bcs @SecondAxisReverse ; CPU:$D2DA PRG:12DA B0 07
|
|
|
|
lda ($00),y ; CPU:$D2DC PRG:12DC B1 00
|
|
sec ; CPU:$D2DE PRG:12DE 38
|
|
sbc $1C ; CPU:$D2DF PRG:12DF E5 1C
|
|
bcs @CheckSecondAxisDistance ; CPU:$D2E1 PRG:12E1 B0 02
|
|
|
|
@SecondAxisReverse:
|
|
sbc ($00),y ; CPU:$D2E3 PRG:12E3 F1 00
|
|
|
|
@CheckSecondAxisDistance:
|
|
cmp #$0A ; CPU:$D2E5 PRG:12E5 C9 0A
|
|
bcs @NextEntry ; CPU:$D2E7 PRG:12E7 B0 06
|
|
|
|
adc $03 ; CPU:$D2E9 PRG:12E9 65 03
|
|
cmp #$05 ; CPU:$D2EB PRG:12EB C9 05
|
|
bcc @CandidateFound ; CPU:$D2ED PRG:12ED 90 10
|
|
|
|
|
|
@NextEntry:
|
|
inx ; CPU:$D2EF PRG:12EF E8
|
|
inx ; CPU:$D2F0 PRG:12F0 E8
|
|
|
|
lda $00 ; CPU:$D2F1 PRG:12F1 A5 00
|
|
clc ; CPU:$D2F3 PRG:12F3 18
|
|
adc #$04 ; CPU:$D2F4 PRG:12F4 69 04
|
|
sta $00 ; CPU:$D2F6 PRG:12F6 85 00
|
|
|
|
asl $02 ; CPU:$D2F8 PRG:12F8 06
|
|
|
|
cpx #$0A ; CPU:$D2F9 PRG:12F9 02 E0
|
|
bne @ScanEntries ; CPU:$D2FB PRG:12FB 0A D0
|
|
|
|
rts ; CPU:$D2FD PRG:12FD B9
|
|
|
|
|
|
@CandidateFound:
|
|
cpx #$08 ; CPU:$D2FE PRG:12FE 60 E0
|
|
beq @ProcessSecondaryState ; CPU:$D300 PRG:1300 08 F0
|
|
|
|
lda $02 ; CPU:$D302 PRG:1302 45 A5
|
|
and $88 ; CPU:$D304 PRG:1304 02 25
|
|
beq @SpecialCandidate ; CPU:$D306 PRG:1306 88 F0
|
|
|
|
txa ; CPU:$D308 PRG:1308 2E
|
|
lsr ; CPU:$D309 PRG:1309 8A
|
|
sta $03 ; CPU:$D30A PRG:130A 4A 85
|
|
|
|
ldy $D9 ; CPU:$D30C PRG:130C 03 A4
|
|
|
|
lda ProximityCandidateValues,y ; CPU:$D30E PRG:130E D9 B9 6C
|
|
|
|
ldy $03 ; CPU:$D311 PRG:1311 D3 A4
|
|
sta $0033,y ; CPU:$D313 PRG:1313 03 99 33
|
|
|
|
lda #$00 ; CPU:$D316 PRG:1316 00 A9
|
|
sta $32 ; CPU:$D318 PRG:1318 00 85
|
|
|
|
ldy $D9 ; CPU:$D31A PRG:131A 32 A4
|
|
|
|
lda ProximityDDValues,y ; CPU:$D31C PRG:131C D9 B9 7C
|
|
sta $DD ; CPU:$D31F PRG:131F D3 85
|
|
|
|
lda ProximityDEValues,y ; CPU:$D321 PRG:1321 DD B9 78
|
|
sta $DE ; CPU:$D324 PRG:1324 D3 85
|
|
|
|
inc $D9 ; CPU:$D326 PRG:1326 DE E6
|
|
|
|
lda #$08 ; CPU:$D328 PRG:1328 D9 A9
|
|
sta $B8,x ; CPU:$D32A PRG:132A 08 95
|
|
sta $0607 ; CPU:$D32C PRG:132C B8 8D 07
|
|
|
|
lda #$06 ; CPU:$D32F PRG:132F 06 A9
|
|
sta $3F ; CPU:$D331 PRG:1331 06 85
|
|
|
|
jmp $E0E6 ; CPU:$D333 PRG:1333 3F 4C E6
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D337
|
|
; Candidate path selected when ($02 & $88) == 0.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@SpecialCandidate:
|
|
lda #$08 ; CPU:$D336 PRG:1336 E0 A9
|
|
sta $3F ; CPU:$D338 PRG:1338 08 85
|
|
|
|
lda #$12 ; CPU:$D33A PRG:133A 3F A9
|
|
sta $32 ; CPU:$D33C PRG:133C 12 85
|
|
|
|
lda #$80 ; CPU:$D33E PRG:133E 32 A9
|
|
sta $DB ; CPU:$D340 PRG:1340 80 85
|
|
|
|
lda #$00 ; CPU:$D342 PRG:1342 DB A9
|
|
sta $87 ; CPU:$D344 PRG:1344 00 85
|
|
|
|
rts ; CPU:$D346 PRG:1346 87
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D348
|
|
; Special path selected when X == $08.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@ProcessSecondaryState:
|
|
lda $8B ; CPU:$D347 PRG:1347 60 A5
|
|
beq @InitializeSecondaryState ; CPU:$D349 PRG:1349 8B F0
|
|
|
|
rts ; CPU:$D34B PRG:134B 01
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D34D
|
|
; Initialize secondary state.
|
|
;------------------------------------------------------------------------------
|
|
@InitializeSecondaryState:
|
|
sta $D7 ; CPU:$D34C PRG:134C 60 85
|
|
|
|
lda #$80 ; CPU:$D34E PRG:134E D7 A9
|
|
sta $D8 ; CPU:$D350 PRG:1350 80 85
|
|
sta $8B ; CPU:$D352 PRG:1352 D8 85
|
|
sta $0606 ; CPU:$D354 PRG:1354 8B 8D 06
|
|
|
|
ldy $93 ; CPU:$D357 PRG:1357 06 A4
|
|
|
|
lda SecondaryStateDDValues,y ; CPU:$D359 PRG:1359 93 B9 80
|
|
sta $DD ; CPU:$D35C PRG:135C D3 85
|
|
|
|
lda SecondaryStateDEValues,y ; CPU:$D35E PRG:135E DD B9 88
|
|
sta $DE ; CPU:$D361 PRG:1361 D3 85
|
|
|
|
lda SecondaryState37Values,y ; CPU:$D363 PRG:1363 DE B9 70
|
|
sta $37 ; CPU:$D366 PRG:1366 D3 85
|
|
|
|
jmp $E0E6 ; CPU:$D368 PRG:1368 37 4C E6
|
|
|
|
;==============================================================================
|
|
; $D36C-$D38F: Gameplay Proximity / Transition Lookup Data
|
|
;
|
|
; Local:
|
|
; Lookup data used by CheckGameplayProximity when a qualifying proximity
|
|
; condition triggers a gameplay-state transition.
|
|
;
|
|
; Global:
|
|
; Supplies values written to $33+, $37, $DD and $DE during the different
|
|
; transition paths handled by CheckGameplayProximity.
|
|
;
|
|
; Notes:
|
|
; $D370 is intentionally a label inside the table beginning at $D36C.
|
|
; No bytes are duplicated.
|
|
;==============================================================================
|
|
ProximityCandidateValues:
|
|
; $D36C-$D36F
|
|
.byte $2D,$2F,$32,$34 ; CPU:$D36C PRG:136C 2D 2F 32 34
|
|
|
|
SecondaryState37Values:
|
|
; $D370-$D373
|
|
; Also forms bytes 4-7 of ProximityCandidateValues.
|
|
.byte $2C,$2E,$30,$31 ; CPU:$D370 PRG:1370 2C 2E 30 31
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D374-$D377
|
|
; Consumer not yet established.
|
|
;------------------------------------------------------------------------------
|
|
ProximityUnknownTableD374:
|
|
.byte $33,$35,$36,$37 ; CPU:$D374 PRG:1374 33 35 36 37
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D378-$D37B
|
|
; Indexed by $D9 and loaded into $DE.
|
|
;------------------------------------------------------------------------------
|
|
ProximityDEValues:
|
|
.byte $00,$00,$00,$01 ; CPU:$D378 PRG:1378 00 00 00 01
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D37C-$D37F
|
|
; Indexed by $D9 and loaded into $DD.
|
|
;------------------------------------------------------------------------------
|
|
ProximityDDValues:
|
|
.byte $02,$04,$08,$06 ; CPU:$D37C PRG:137C 02 04 08 06
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D380-$D387
|
|
; Indexed by $93 and loaded into $DD.
|
|
;------------------------------------------------------------------------------
|
|
SecondaryStateDDValues:
|
|
.byte $01,$03,$05,$07 ; CPU:$D380 PRG:1380 01 03 05 07
|
|
.byte $00,$00,$00,$00 ; CPU:$D384 PRG:1384 00 00 00 00
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D388-$D38F
|
|
; Indexed by $93 and loaded into $DE.
|
|
;------------------------------------------------------------------------------
|
|
SecondaryStateDEValues:
|
|
.byte $00,$00,$00,$00 ; CPU:$D388 PRG:1388 00 00 00 00
|
|
.byte $01,$02,$03,$05 ; CPU:$D38C PRG:138C 01 02 03 05
|
|
|
|
;==============================================================================
|
|
; $D390-...: Gameplay Direction / Movement Processing
|
|
;
|
|
; Local:
|
|
; Processes directional controller input, validates a requested direction
|
|
; against the current map/tile state, and selects movement parameters.
|
|
;
|
|
; Global:
|
|
; Called during normal gameplay processing from GameModeState04.
|
|
;
|
|
; Notes:
|
|
; Address-derived labels are retained during this pass to make branch
|
|
; targets explicit while maintaining byte identity.
|
|
;==============================================================================
|
|
|
|
UpdatePlayerMovement:
|
|
lda $48 ; CPU:$D390 PRG:1390 A5 48
|
|
beq @D397 ; CPU:$D392 PRG:1392 F0 03
|
|
|
|
jmp $D506 ; CPU:$D394 PRG:1394 4C 06 D5
|
|
|
|
@D397:
|
|
lda $4F ; CPU:$D397 PRG:1397 A5 4F
|
|
and #$F0 ; CPU:$D399 PRG:1399 29 F0
|
|
beq @D3D2 ; CPU:$D39B PRG:139B F0 35
|
|
|
|
ldx #$FF ; CPU:$D39D PRG:139D A2 FF
|
|
|
|
@D39F:
|
|
inx ; CPU:$D39F PRG:139F E8
|
|
asl ; CPU:$D3A0 PRG:13A0 0A
|
|
bcc @D39F ; CPU:$D3A1 PRG:13A1 90 FC
|
|
|
|
lda InputDirectionTable,x ; CPU:$D3A3 PRG:13A3 BD 02 D5
|
|
sta $50 ; CPU:$D3A6 PRG:13A6 85 50
|
|
|
|
clc ; CPU:$D3A8 PRG:13A8 18
|
|
adc #$02 ; CPU:$D3A9 PRG:13A9 69 02
|
|
and #$03 ; CPU:$D3AB PRG:13AB 29 03
|
|
cmp $51 ; CPU:$D3AD PRG:13AD C5 51
|
|
bne @D3C9 ; CPU:$D3AF PRG:13AF D0 18
|
|
|
|
lda $1A ; CPU:$D3B1 PRG:13B1 A5 1A
|
|
ora $1C ; CPU:$D3B3 PRG:13B3 05 1C
|
|
and #$07 ; CPU:$D3B5 PRG:13B5 29 07
|
|
bne @D3C2 ; CPU:$D3B7 PRG:13B7 D0 09
|
|
|
|
ldy $50 ; CPU:$D3B9 PRG:13B9 A4 50
|
|
|
|
lda $022B,y ; CPU:$D3BB PRG:13BB B9 2B 02
|
|
and #$F0 ; CPU:$D3BE PRG:13BE 29 F0
|
|
bne @D3C9 ; CPU:$D3C0 PRG:13C0 D0 07
|
|
|
|
|
|
@D3C2:
|
|
lda $50 ; CPU:$D3C2 PRG:13C2 A5 50
|
|
sta $51 ; CPU:$D3C4 PRG:13C4 85 51
|
|
|
|
jmp @D3D6 ; CPU:$D3C6 PRG:13C6 4C D6 D3
|
|
|
|
|
|
@D3C9:
|
|
ldx $50 ; CPU:$D3C9 PRG:13C9 A6 50
|
|
|
|
lda $022B,x ; CPU:$D3CB PRG:13CB BD 2B 02
|
|
and #$F0 ; CPU:$D3CE PRG:13CE 29 F0
|
|
beq @D3D6 ; CPU:$D3D0 PRG:13D0 F0 04
|
|
|
|
|
|
@D3D2:
|
|
lda $51 ; CPU:$D3D2 PRG:13D2 A5 51
|
|
sta $50 ; CPU:$D3D4 PRG:13D4 85 50
|
|
|
|
|
|
@D3D6:
|
|
ldx #$04 ; CPU:$D3D6 PRG:13D6 A2 04
|
|
|
|
lda $88 ; CPU:$D3D8 PRG:13D8 A5 88
|
|
bne @D3DE ; CPU:$D3DA PRG:13DA D0 02
|
|
|
|
ldx #$0A ; CPU:$D3DC PRG:13DC A2 0A
|
|
|
|
@D3DE:
|
|
lda $022A ; CPU:$D3DE PRG:13DE AD 2A 02
|
|
cmp #$01 ; CPU:$D3E1 PRG:13E1 C9 01
|
|
beq @D3F4 ; CPU:$D3E3 PRG:13E3 F0 10
|
|
|
|
cmp #$02 ; CPU:$D3E5 PRG:13E5 C9 02
|
|
beq @D3F4 ; CPU:$D3E7 PRG:13E7 F0 0C
|
|
|
|
dex ; CPU:$D3E9 PRG:13E9 CA
|
|
dex ; CPU:$D3EA PRG:13EA CA
|
|
|
|
cmp #$03 ; CPU:$D3EB PRG:13EB C9 03
|
|
beq @D3F4 ; CPU:$D3ED PRG:13ED F0 06
|
|
|
|
cmp #$09 ; CPU:$D3EF PRG:13EF C9 09
|
|
beq @D3F4 ; CPU:$D3F1 PRG:13F1 F0 02
|
|
|
|
dex ; CPU:$D3F3 PRG:13F3 CA
|
|
dex ; CPU:$D3F4 PRG:13F4 CA
|
|
|
|
|
|
@D3F4:
|
|
lda $9F,x ; CPU:$D3F5 PRG:13F5 B5 9F
|
|
sta $B5 ; CPU:$D3F7 PRG:13F7 85 B5
|
|
|
|
lda $A0,x ; CPU:$D3F9 PRG:13F9 B5 A0
|
|
sta $B6 ; CPU:$D3FB PRG:13FB 85 B6
|
|
|
|
lda $51 ; CPU:$D3FD PRG:13FD A5 51
|
|
asl ; CPU:$D3FF PRG:13FF 0A
|
|
tay ; CPU:$D400 PRG:1400 A8
|
|
|
|
lda MovementArithmeticTable,y ; CPU:$D401 PRG:1401 B9 0E D4
|
|
sta $10 ; CPU:$D404 PRG:1404 85 10
|
|
|
|
lda MovementArithmeticTable+1,y ; CPU:$D406 PRG:1406 B9 0F D4
|
|
sta $11 ; CPU:$D409 PRG:1409 85 11
|
|
|
|
jmp ($0010) ; CPU:$D40B PRG:140B 6C 10 00 16 D4
|
|
|
|
;==============================================================================
|
|
; $D40E-$D415: Movement Arithmetic Dispatch Table
|
|
;
|
|
; Local:
|
|
; Four 16-bit handlers selected using the internal direction value in $51.
|
|
;
|
|
; Global:
|
|
; Dispatches into direction-specific coordinate arithmetic used by
|
|
; UpdatePlayerMovement.
|
|
;
|
|
; Notes:
|
|
; Direction semantics remain unnamed during this pass.
|
|
;==============================================================================
|
|
MovementArithmeticTable:
|
|
.word $D416 ; CPU:$D40E PRG:140E 16 D4
|
|
.word $D41A ; CPU:$D410 PRG:1410 1A D4
|
|
.word $D435 ; CPU:$D412 PRG:1412 35 D4
|
|
.word $D431 ; CPU:$D414 PRG:1414 31 D4
|
|
;==============================================================================
|
|
; $D416-$D443: Direction-Specific Movement Arithmetic
|
|
;
|
|
; Local:
|
|
; Four entry points selected by MovementArithmeticTable converge into two
|
|
; shared arithmetic paths.
|
|
;
|
|
; $D416/$D41A select the coordinate component and enter subtraction.
|
|
; $D431/$D435 select the coordinate component and enter addition.
|
|
;
|
|
; Global:
|
|
; Computes the fixed-point movement result used by the second direction
|
|
; dispatch beginning at MovementApplyResult.
|
|
;
|
|
; Notes:
|
|
; Shared labels are deliberately non-local because multiple entry-point
|
|
; labels must branch into the same code.
|
|
;==============================================================================
|
|
|
|
MovementArithmeticD416:
|
|
ldx #$02 ; CPU:$D416 PRG:1416 A2 02
|
|
bne MovementSubtract ; CPU:$D418 PRG:1418 D0 02
|
|
|
|
MovementArithmeticD41A:
|
|
ldx #$00 ; CPU:$D41A PRG:141A A2 00
|
|
|
|
MovementSubtract:
|
|
lda $1B,x ; CPU:$D41C PRG:141C B5 1B
|
|
sec ; CPU:$D41E PRG:141E 38
|
|
sbc $B5 ; CPU:$D41F PRG:141F E5 B5
|
|
sta $1B,x ; CPU:$D421 PRG:1421 95 1B
|
|
|
|
lda #$00 ; CPU:$D423 PRG:1423 A9 00
|
|
bcs MovementSubtractNoBorrow ; CPU:$D425 PRG:1425 B0 02
|
|
|
|
lda #$01 ; CPU:$D427 PRG:1427 A9 01
|
|
|
|
MovementSubtractNoBorrow:
|
|
clc ; CPU:$D429 PRG:1429 18
|
|
adc $B6 ; CPU:$D42A PRG:142A 65 B6
|
|
sta $CC ; CPU:$D42C PRG:142C 85 CC
|
|
|
|
jmp MovementApplyResult ; CPU:$D42E PRG:142E 4C 44 D4
|
|
|
|
|
|
MovementArithmeticD431:
|
|
ldx #$00 ; CPU:$D431 PRG:1431 A2 00
|
|
beq MovementAdd ; CPU:$D433 PRG:1433 F0 02
|
|
|
|
|
|
MovementArithmeticD435:
|
|
ldx #$02 ; CPU:$D435 PRG:1435 A2 02
|
|
|
|
|
|
MovementAdd:
|
|
lda $1B,x ; CPU:$D437 PRG:1437 B5 1B
|
|
clc ; CPU:$D439 PRG:1439 18
|
|
adc $B5 ; CPU:$D43A PRG:143A 65 B5
|
|
sta $1B,x ; CPU:$D43C PRG:143C 95 1B
|
|
|
|
lda #$00 ; CPU:$D43E PRG:143E A9 00
|
|
adc $B6 ; CPU:$D440 PRG:1440 65 B6
|
|
sta $CC ; CPU:$D442 PRG:1442 85 CC
|
|
|
|
;==============================================================================
|
|
; $D444-$D459: Apply Movement Result and Dispatch Direction Handler
|
|
;
|
|
; Local:
|
|
; Decrements the movement accumulator $CC. If it becomes negative, returns
|
|
; immediately.
|
|
;
|
|
; Otherwise uses the current direction value at $51 as a byte offset into a
|
|
; four-entry handler table beginning at $D45A.
|
|
;
|
|
; Global:
|
|
; Second stage of UpdatePlayerMovement. After the fixed-point arithmetic
|
|
; performed by the $D416-$D443 handlers, this dispatches to the actual
|
|
; direction-specific coordinate/tile movement code.
|
|
;
|
|
; Notes:
|
|
; $51 is multiplied by two before indexing the pointer table.
|
|
;==============================================================================
|
|
|
|
MovementApplyResult:
|
|
dec $CC ; CPU:$D444 PRG:1444 C6 CC
|
|
bpl @D449 ; CPU:$D446 PRG:1446 10 01
|
|
|
|
rts ; CPU:$D448 PRG:1448 60
|
|
|
|
|
|
@D449:
|
|
lda $51 ; CPU:$D449 PRG:1449 A5 51
|
|
asl ; CPU:$D44B PRG:144B 0A
|
|
tay ; CPU:$D44C PRG:144C A8
|
|
|
|
lda MovementDirectionTable,y ; CPU:$D44D PRG:144D B9 5A D4
|
|
sta $10 ; CPU:$D450 PRG:1450 85 10
|
|
|
|
lda MovementDirectionTable+1,y ; CPU:$D452 PRG:1452 B9 5B D4
|
|
sta $11 ; CPU:$D455 PRG:1455 85 11
|
|
|
|
jmp ($0010) ; CPU:$D457 PRG:1457 6C 10 00 9A D4
|
|
|
|
;==============================================================================
|
|
; $D45A-$D461: Direction-Specific Movement Dispatch Table
|
|
;
|
|
; Local:
|
|
; Four handlers selected according to the internal direction value in $51.
|
|
;
|
|
; Notes:
|
|
; Handler names remain address-based until coordinate effects are fully
|
|
; mapped to semantic direction names.
|
|
;==============================================================================
|
|
|
|
MovementDirectionTable:
|
|
.word MovementDirectionD49A ; CPU:$D45A PRG:145A 9A D4
|
|
.word MovementDirectionD490 ; CPU:$D45C PRG:145C 90 D4
|
|
.word MovementDirectionD46C ; CPU:$D45E PRG:145E 6C D4
|
|
.word MovementDirectionD462 ; CPU:$D460 PRG:1460 62 D4
|
|
|
|
;==============================================================================
|
|
; $D462-$D501: Direction-Specific Movement Handlers
|
|
;
|
|
; Local:
|
|
; Four entry points selected by MovementDirectionTable.
|
|
;
|
|
; $D462 and $D46C enter the increment path.
|
|
; $D490 and $D49A enter the decrement path.
|
|
;
|
|
; X selects which coordinate component at $1A/$1C is modified. $00 and $01
|
|
; preserve working indexes used for collision/tile checks against $022B.
|
|
;
|
|
; After movement, the shared tail handles coordinate wrapping/state flags
|
|
; and, when aligned to an 8-unit boundary, commits a requested direction
|
|
; change from $50 to $51.
|
|
;
|
|
; Global:
|
|
; Final stage of UpdatePlayerMovement. Applies movement to the player's
|
|
; coordinate state and reconciles requested direction changes.
|
|
;
|
|
; Notes:
|
|
; Entry points intentionally share code. Use non-local labels for shared
|
|
; targets so ca65 scope rules do not change the branch structure.
|
|
;==============================================================================
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D462
|
|
; Increment coordinate component X=0.
|
|
;------------------------------------------------------------------------------
|
|
|
|
MovementDirectionD462:
|
|
ldx #$00 ; CPU:$D462 PRG:1462 A2 00
|
|
stx $00 ; CPU:$D464 PRG:1464 86 00
|
|
|
|
lda #$03 ; CPU:$D466 PRG:1466 A9 03
|
|
sta $01 ; CPU:$D468 PRG:1468 85 01
|
|
|
|
bne MovementIncrement ; CPU:$D46A PRG:146A D0 06
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D46C
|
|
; Increment coordinate component X=2.
|
|
;------------------------------------------------------------------------------
|
|
|
|
MovementDirectionD46C:
|
|
ldx #$02 ; CPU:$D46C PRG:146C A2 02
|
|
stx $00 ; CPU:$D46E PRG:146E 86 00
|
|
stx $01 ; CPU:$D470 PRG:1470 86 01
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D472: Shared increment path.
|
|
;------------------------------------------------------------------------------
|
|
|
|
MovementIncrement:
|
|
lda $1A,x ; CPU:$D472 PRG:1472 B5 1A
|
|
clc ; CPU:$D474 PRG:1474 18
|
|
adc #$01 ; CPU:$D475 PRG:1475 69 01
|
|
sta $1A,x ; CPU:$D477 PRG:1477 95 1A
|
|
|
|
and #$04 ; CPU:$D479 PRG:1479 29 04
|
|
bne MovementSharedTail ; CPU:$D47B PRG:147B D0 44
|
|
|
|
ldx $01 ; CPU:$D47D PRG:147D A6 01
|
|
|
|
lda $022B,x ; CPU:$D47F PRG:147F BD 2B 02
|
|
and #$F0 ; CPU:$D482 PRG:1482 29 F0
|
|
beq MovementSharedTail ; CPU:$D484 PRG:1484 F0 3B
|
|
|
|
ldx $00 ; CPU:$D486 PRG:1486 A6 00
|
|
|
|
lda $1A,x ; CPU:$D488 PRG:1488 B5 1A
|
|
and #$FC ; CPU:$D48A PRG:148A 29 FC
|
|
sta $1A,x ; CPU:$D48C PRG:148C 95 1A
|
|
|
|
bne MovementSharedTail ; CPU:$D48E PRG:148E D0 31
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D490
|
|
; Decrement coordinate component X=0.
|
|
;------------------------------------------------------------------------------
|
|
|
|
MovementDirectionD490:
|
|
ldx #$00 ; CPU:$D490 PRG:1490 A2 00
|
|
stx $00 ; CPU:$D492 PRG:1492 86 00
|
|
|
|
lda #$01 ; CPU:$D494 PRG:1494 A9 01
|
|
sta $01 ; CPU:$D496 PRG:1496 85 01
|
|
|
|
bne MovementDecrement ; CPU:$D498 PRG:1498 D0 08
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D49A
|
|
; Decrement coordinate component X=2.
|
|
;------------------------------------------------------------------------------
|
|
|
|
MovementDirectionD49A:
|
|
ldx #$02 ; CPU:$D49A PRG:149A A2 02
|
|
stx $00 ; CPU:$D49C PRG:149C 86 00
|
|
|
|
lda #$00 ; CPU:$D49E PRG:149E A9 00
|
|
sta $01 ; CPU:$D4A0 PRG:14A0 85 01
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D4A2: Shared decrement path.
|
|
;------------------------------------------------------------------------------
|
|
|
|
MovementDecrement:
|
|
lda $1A,x ; CPU:$D4A2 PRG:14A2 B5 1A
|
|
sec ; CPU:$D4A4 PRG:14A4 38
|
|
sbc #$01 ; CPU:$D4A5 PRG:14A5 E9 01
|
|
sta $1A,x ; CPU:$D4A7 PRG:14A7 95 1A
|
|
|
|
and #$04 ; CPU:$D4A9 PRG:14A9 29 04
|
|
beq MovementSharedTail ; CPU:$D4AB PRG:14AB F0 14
|
|
|
|
ldx $01 ; CPU:$D4AD PRG:14AD A6 01
|
|
|
|
lda $022B,x ; CPU:$D4AF PRG:14AF BD 2B 02
|
|
and #$F0 ; CPU:$D4B2 PRG:14B2 29 F0
|
|
beq MovementSharedTail ; CPU:$D4B4 PRG:14B4 F0 0B
|
|
|
|
ldx $00 ; CPU:$D4B6 PRG:14B6 A6 00
|
|
|
|
lda $1A,x ; CPU:$D4B8 PRG:14B8 B5 1A
|
|
clc ; CPU:$D4BA PRG:14BA 18
|
|
adc #$04 ; CPU:$D4BB PRG:14BB 69 04
|
|
and #$FC ; CPU:$D4BD PRG:14BD 29 FC
|
|
sta $1A,x ; CPU:$D4BF PRG:14BF 95 1A
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D4C1: Shared movement/wrap tail.
|
|
;------------------------------------------------------------------------------
|
|
|
|
MovementSharedTail:
|
|
lda $1A ; CPU:$D4C1 PRG:14C1 A5 1A
|
|
|
|
cmp #$18 ; CPU:$D4C3 PRG:14C3 C9 18
|
|
bcc MovementCheckLeftWrap ; CPU:$D4C5 PRG:14C5 90 0A
|
|
|
|
cmp #$A9 ; CPU:$D4C7 PRG:14C7 C9 A9
|
|
bcs MovementCheckLeftWrap ; CPU:$D4C9 PRG:14C9 B0 06
|
|
|
|
lda $38 ; CPU:$D4CB PRG:14CB A5 38
|
|
and #$DF ; CPU:$D4CD PRG:14CD 29 DF
|
|
bcc MovementStoreWrapState ; CPU:$D4CF PRG:14CF 90 04
|
|
|
|
MovementCheckLeftWrap:
|
|
lda #$20 ; CPU:$D4D1 PRG:14D1 A9 20
|
|
ora $38 ; CPU:$D4D3 PRG:14D3 05 38
|
|
|
|
MovementStoreWrapState:
|
|
sta $38 ; CPU:$D4D5 PRG:14D5 85 38
|
|
|
|
lda $1A ; CPU:$D4D7 PRG:14D7 A5 1A
|
|
cmp #$0B ; CPU:$D4D9 PRG:14D9 C9 0B
|
|
bcs MovementCheckRightWrap ; CPU:$D4DB PRG:14DB B0 06
|
|
|
|
lda #$BF ; CPU:$D4DD PRG:14DD A9 BF
|
|
sta $1A ; CPU:$D4DF PRG:14DF 85 1A
|
|
bne MovementCheckAlignment ; CPU:$D4E1 PRG:14E1 D0 08
|
|
|
|
MovementCheckRightWrap:
|
|
cmp #$C0 ; CPU:$D4E3 PRG:14E3 C9 C0
|
|
bcc MovementCheckAlignment ; CPU:$D4E5 PRG:14E5 90 04
|
|
|
|
lda #$0B ; CPU:$D4E7 PRG:14E7 A9 0B
|
|
sta $1A ; CPU:$D4E9 PRG:14E9 85 1A
|
|
|
|
|
|
MovementCheckAlignment:
|
|
lda $1A ; CPU:$D4EB PRG:14EB A5 1A
|
|
ora $1C ; CPU:$D4ED PRG:14ED 05 1C
|
|
and #$07 ; CPU:$D4EF PRG:14EF 29 07
|
|
bne MovementReturnToArithmetic ; CPU:$D4F1 PRG:14F1 D0 0C
|
|
|
|
lda $50 ; CPU:$D4F3 PRG:14F3 A5 50
|
|
cmp $51 ; CPU:$D4F5 PRG:14F5 C5 51
|
|
beq MovementReturnToArithmetic ; CPU:$D4F7 PRG:14F7 F0 06
|
|
|
|
sta $51 ; CPU:$D4F9 PRG:14F9 85 51
|
|
|
|
inc $CC ; CPU:$D4FB PRG:14FB E6 CC
|
|
inc $CC ; CPU:$D4FD PRG:14FD E6 CC
|
|
|
|
|
|
MovementReturnToArithmetic:
|
|
jmp MovementApplyResult ; CPU:$D4FF PRG:14FF 4C 44 D4
|
|
|
|
;==============================================================================
|
|
; $D502-$D505: Controller Direction Mapping
|
|
;==============================================================================
|
|
|
|
InputDirectionTable:
|
|
.byte $03,$01,$02,$00 ; CPU:$D502 PRG:1502 03 01 02 00
|
|
|
|
;==============================================================================
|
|
; $D506-$D51E: Scripted Direction/Input Update
|
|
;
|
|
; Local:
|
|
; Uses $E3 as a countdown and $E4 as an offset into the table beginning at
|
|
; $D51F.
|
|
;
|
|
; Each time $E3 reaches zero:
|
|
; - Advances $E4 by two.
|
|
; - Loads a new duration from $D51F+$E4 into $E3.
|
|
;
|
|
; It then takes the following table byte, masks it to two bits, and
|
|
; tail-jumps into UpdatePlayerMovement at $D3A6 with that value in A.
|
|
;
|
|
; Global:
|
|
; Entered from UpdatePlayerMovement when $48 is nonzero. This provides a
|
|
; scripted/autonomous direction source in place of normal controller input.
|
|
;
|
|
; Notes:
|
|
; $E4 indexes two-byte table records:
|
|
;
|
|
; byte 0 = duration/count
|
|
; byte 1 = direction/control value
|
|
;
|
|
; The second byte is masked with #$03 before entering movement processing.
|
|
;==============================================================================
|
|
|
|
UpdateScriptedDirection:
|
|
ldy $E4 ; CPU:$D506 PRG:1506 A4 E4
|
|
|
|
dec $E3 ; CPU:$D508 PRG:1508 C6 E3
|
|
bne @UseCurrentEntry ; CPU:$D50A PRG:150A D0 0B
|
|
|
|
inc $E4 ; CPU:$D50C PRG:150C E6 E4
|
|
inc $E4 ; CPU:$D50E PRG:150E E6 E4
|
|
|
|
ldy $E4 ; CPU:$D510 PRG:1510 A4 E4
|
|
|
|
lda ScriptedDirectionTable,y ; CPU:$D512 PRG:1512 B9 1F D5
|
|
sta $E3 ; CPU:$D515 PRG:1515 85 E3
|
|
|
|
@UseCurrentEntry:
|
|
lda ScriptedDirectionTable+1,y ; CPU:$D517 PRG:1517 B9 20 D5
|
|
and #$03 ; CPU:$D51A PRG:151A 29 03
|
|
|
|
jmp $D3A6 ; CPU:$D51C PRG:151C 4C A6 D3
|
|
|
|
;==============================================================================
|
|
; $D51F-...: Scripted Direction Table
|
|
;
|
|
; Local:
|
|
; Two-byte records used by UpdateScriptedDirection:
|
|
;
|
|
; byte 0 = duration
|
|
; byte 1 = direction/control number
|
|
;
|
|
; Global:
|
|
; Drives autonomous/scripted movement when $48 selects this path instead of
|
|
; normal player controller processing.
|
|
;==============================================================================
|
|
ScriptedDirectionTable:
|
|
.byte $00,$01 ; CPU:$D51F PRG:151F 00 01
|
|
.byte $D0,$00 ; CPU:$D521 PRG:1521 D0 00
|
|
.byte $28,$01 ; CPU:$D523 PRG:1523 28 01
|
|
.byte $28,$02 ; CPU:$D525 PRG:1525 28 02
|
|
.byte $90,$03 ; CPU:$D527 PRG:1527 90 03
|
|
.byte $38,$00 ; CPU:$D529 PRG:1529 38 00
|
|
.byte $20,$03 ; CPU:$D52B PRG:152B 20 03
|
|
.byte $18,$01 ; CPU:$D52D PRG:152D 18 01
|
|
.byte $60,$02 ; CPU:$D52F PRG:152F 60 02
|
|
.byte $30,$01 ; CPU:$D531 PRG:1531 30 01
|
|
.byte $10,$02 ; CPU:$D533 PRG:1533 10 02
|
|
.byte $48,$01 ; CPU:$D535 PRG:1535 48 01
|
|
.byte $18,$02 ; CPU:$D537 PRG:1537 18 02
|
|
.byte $40,$01 ; CPU:$D539 PRG:1539 40 01
|
|
.byte $20,$02 ; CPU:$D53B PRG:153B 20 02
|
|
.byte $18,$00 ; CPU:$D53D PRG:153D 18 00
|
|
.byte $20,$03 ; CPU:$D53F PRG:153F 20 03
|
|
.byte $40,$02 ; CPU:$D541 PRG:1541 40 02
|
|
.byte $38,$01 ; CPU:$D543 PRG:1543 38 01
|
|
.byte $18,$02 ; CPU:$D545 PRG:1545 18 02
|
|
.byte $E0,$03 ; CPU:$D547 PRG:1547 E0 03
|
|
.byte $30,$00 ; CPU:$D549 PRG:1549 30 00
|
|
.byte $28,$01 ; CPU:$D54B PRG:154B 28 01
|
|
.byte $28,$02 ; CPU:$D54D PRG:154D 28 02
|
|
.byte $20,$02 ; CPU:$D54F PRG:154F 20 02
|
|
.byte $80,$03 ; CPU:$D551 PRG:1551 80 03
|
|
.byte $40,$00 ; CPU:$D553 PRG:1553 40 00
|
|
.byte $40,$01 ; CPU:$D555 PRG:1555 40 01
|
|
|
|
;==============================================================================
|
|
; $D557-$D586: Update Four Gameplay Entities
|
|
;
|
|
; Local:
|
|
; Iterates four gameplay entries using X offsets:
|
|
;
|
|
; $00, $02, $04, $06
|
|
;
|
|
; Initializes several temporary values before the loop:
|
|
;
|
|
; $00 = $2F
|
|
; $01 = $02
|
|
; $02 = $1E
|
|
; $03 = $00
|
|
; $04 = $01
|
|
;
|
|
; For each entry, calls the dispatcher at $D587. After each call:
|
|
;
|
|
; $00 += 4
|
|
; $02 += 4
|
|
; $04 <<= 1
|
|
; X += 2
|
|
;
|
|
; Processing ends after X reaches $08.
|
|
;
|
|
; Global:
|
|
; Called every active gameplay frame from GameModeState04. Coordinates
|
|
; per-entry updates for four gameplay entities/state slots.
|
|
;
|
|
; Notes:
|
|
; $00 and $02 appear to advance through parallel four-byte-strided RAM
|
|
; structures.
|
|
;
|
|
; $04 becomes a per-entry bitmask:
|
|
;
|
|
; $01,$02,$04,$08
|
|
;
|
|
; The exact roles of the temporary values will become clearer as the
|
|
; dispatcher at $D587 and its handlers are decoded.
|
|
;==============================================================================
|
|
|
|
UpdateGameplayEntities:
|
|
ldx #$00 ; CPU:$D557 PRG:1557 A2 00
|
|
|
|
lda #$2F ; CPU:$D559 PRG:1559 A9 2F
|
|
sta $00 ; CPU:$D55B PRG:155B 85 00
|
|
|
|
lda #$02 ; CPU:$D55D PRG:155D A9 02
|
|
sta $01 ; CPU:$D55F PRG:155F 85 01
|
|
|
|
lda #$1E ; CPU:$D561 PRG:1561 A9 1E
|
|
sta $02 ; CPU:$D563 PRG:1563 85 02
|
|
|
|
lda #$00 ; CPU:$D565 PRG:1565 A9 00
|
|
sta $03 ; CPU:$D567 PRG:1567 85 03
|
|
|
|
lda #$01 ; CPU:$D569 PRG:1569 A9 01
|
|
sta $04 ; CPU:$D56B PRG:156B 85 04
|
|
|
|
@UpdateNextEntity:
|
|
jsr $D587 ; CPU:$D56D PRG:156D 20 87 D5
|
|
|
|
lda $00 ; CPU:$D570 PRG:1570 A5 00
|
|
clc ; CPU:$D572 PRG:1572 18
|
|
adc #$04 ; CPU:$D573 PRG:1573 69 04
|
|
sta $00 ; CPU:$D575 PRG:1575 85 00
|
|
|
|
lda $02 ; CPU:$D577 PRG:1577 A5 02
|
|
clc ; CPU:$D579 PRG:1579 18
|
|
adc #$04 ; CPU:$D57A PRG:157A 69 04
|
|
sta $02 ; CPU:$D57C PRG:157C 85 02
|
|
|
|
asl $04 ; CPU:$D57E PRG:157E 06
|
|
|
|
inx ; CPU:$D57F PRG:157F 04
|
|
inx ; CPU:$D580 PRG:1580 E8
|
|
|
|
cpx #$08 ; CPU:$D581 PRG:1581 E8 E0
|
|
bne @UpdateNextEntity ; CPU:$D583 PRG:1583 08 D0
|
|
|
|
rts ; CPU:$D585 PRG:1585 E7
|
|
|
|
;==============================================================================
|
|
; $D587-$D595: Gameplay Entity State Dispatcher
|
|
;
|
|
; Local:
|
|
; Reads the state value for the current entity from $B8,X and uses that
|
|
; value directly as a byte offset into EntityStateTable.
|
|
;
|
|
; The selected 16-bit handler address is copied to $10/$11 and execution
|
|
; transfers to it with an indirect JMP.
|
|
;
|
|
; Global:
|
|
; Called by UpdateGameplayEntities once for each of four gameplay entity
|
|
; slots. This provides the per-entity state machine used by those entries.
|
|
;
|
|
; Notes:
|
|
; X identifies the current entry using even offsets:
|
|
;
|
|
; $00,$02,$04,$06
|
|
;
|
|
; $B8,X is a byte offset into the pointer table, so valid state values are
|
|
; even:
|
|
;
|
|
; $00,$02,$04,$06,$08
|
|
;==============================================================================
|
|
|
|
DispatchGameplayEntityState:
|
|
ldy $B8,x ; CPU:$D587 PRG:1587 B4 B8
|
|
|
|
lda EntityStateTable,y ; CPU:$D589 PRG:1589 B9 96 D5
|
|
sta $10 ; CPU:$D58C PRG:158C 85 10
|
|
|
|
lda EntityStateTable+1,y ; CPU:$D58E PRG:158E B9 97 D5
|
|
sta $11 ; CPU:$D591 PRG:1591 85 11
|
|
|
|
jmp ($0010) ; CPU:$D593 PRG:1593 6C 10 00 D5 D8
|
|
|
|
;==============================================================================
|
|
; $D596-$D59F: Gameplay Entity State Table
|
|
;
|
|
; Local:
|
|
; Five 16-bit handlers indexed directly by the even state value stored in
|
|
; $B8,X.
|
|
;
|
|
; Global:
|
|
; Defines the per-entity state machine used by
|
|
; DispatchGameplayEntityState.
|
|
;
|
|
; Notes:
|
|
; States $04 and $06 deliberately share the same handler at $D5A1.
|
|
; State $08 targets $D5A0, one byte before that shared handler, suggesting
|
|
; another intentional overlapping entry point.
|
|
;==============================================================================
|
|
|
|
EntityStateTable:
|
|
.word $D8D5 ; state $00 ; CPU:$D596 PRG:1596 D5 D8
|
|
.word $D885 ; state $02 ; CPU:$D598 PRG:1598 85 D8
|
|
.word $D5A1 ; state $04 ; CPU:$D59A PRG:159A A1 D5
|
|
.word $D5A1 ; state $06 ; CPU:$D59C PRG:159C A1 D5
|
|
.word EntityState08 ; state $08 ; CPU:$D59E PRG:159E A0 D5
|
|
|
|
;==============================================================================
|
|
; $D5A0: Entity State $08 Handler
|
|
;
|
|
; Local:
|
|
; Returns immediately.
|
|
;
|
|
; Global:
|
|
; The entity-state table uses this as the handler for state $08, effectively
|
|
; disabling further processing for that entity state.
|
|
;==============================================================================
|
|
|
|
EntityState08:
|
|
rts ; CPU:$D5A0 PRG:15A0 60
|
|
|
|
|
|
;==============================================================================
|
|
; $D5A1-$D5B4: Entity State $04/$06 Secondary Dispatcher
|
|
;
|
|
; Local:
|
|
; Called for entity states $04 and $06 from EntityStateTable.
|
|
;
|
|
; First invokes the common entity helper at $D821. It then reads the
|
|
; secondary state value at $B9,X, doubles it, and uses the result as a byte
|
|
; offset into a four-entry pointer table at $D5B5.
|
|
;
|
|
; The selected address is stored in $10/$11 and execution transfers through
|
|
; an indirect JMP.
|
|
;
|
|
; Global:
|
|
; Provides a second-level state machine for gameplay entities whose primary
|
|
; state at $B8,X is $04 or $06.
|
|
;
|
|
; Notes:
|
|
; $B9,X behaves as an ordinal secondary state here. Unlike several earlier
|
|
; state tables, the value is explicitly multiplied by two before indexing
|
|
; the pointer table.
|
|
;==============================================================================
|
|
|
|
DispatchEntitySecondaryState:
|
|
jsr $D821 ; CPU:$D5A1 PRG:15A1 20 21 D8
|
|
|
|
lda $B9,x ; CPU:$D5A4 PRG:15A4 B5 B9
|
|
asl ; CPU:$D5A6 PRG:15A6 0A
|
|
tay ; CPU:$D5A7 PRG:15A7 A8
|
|
|
|
lda EntitySecondaryStateTable,y ; CPU:$D5A8 PRG:15A8 B9 B5 D5
|
|
sta $10 ; CPU:$D5AB PRG:15AB 85 10
|
|
|
|
lda EntitySecondaryStateTable+1,y ; CPU:$D5AD PRG:15AD B9 B6 D5
|
|
sta $11 ; CPU:$D5B0 PRG:15B0 85 11
|
|
|
|
jmp ($0010) ; CPU:$D5B2 PRG:15B2 6C 10 00 D3 D5
|
|
|
|
;==============================================================================
|
|
; $D5B5-$D5BC: Entity Secondary-State Dispatch Table
|
|
;
|
|
; Local:
|
|
; Four handler addresses selected using ($B9,X * 2).
|
|
;
|
|
; Global:
|
|
; Defines the second-level state machine used by primary entity states
|
|
; $04 and $06.
|
|
;==============================================================================
|
|
|
|
EntitySecondaryStateTable:
|
|
.word EntitySecondaryState0 ; secondary state 0 ; CPU:$D5B5 PRG:15B5 D3 D5
|
|
.word EntitySecondaryState1 ; secondary state 1 ; CPU:$D5B7 PRG:15B7 D7 D5
|
|
.word EntitySecondaryState2 ; secondary state 2 ; CPU:$D5B9 PRG:15B9 BD D5
|
|
.word EntitySecondaryState3 ; secondary state 3 ; CPU:$D5BB PRG:15BB C1 D5
|
|
|
|
;==============================================================================
|
|
; $D5BD-$D5D2: Secondary-State Coordinate Adjustment
|
|
;
|
|
; Local:
|
|
; Secondary state 2 enters at $D5BD and selects Y=$03.
|
|
; Secondary state 3 enters at $D5C1 and selects Y=$01.
|
|
;
|
|
; Both then read through the indirect pointer at $02/$03, add the
|
|
; entity-specific values at $C2,X/$C3,X, write the low-byte result back
|
|
; through the pointer, and store the high-byte result in $CC.
|
|
;
|
|
; Control then tail-jumps to $D5EB.
|
|
;
|
|
; Global:
|
|
; Shared movement/update arithmetic for two secondary entity states.
|
|
;
|
|
; Notes:
|
|
; $02/$03 were initialized by UpdateGameplayEntities and advance by four
|
|
; bytes per entity, so they identify the current entity's four-byte state
|
|
; structure.
|
|
;==============================================================================
|
|
|
|
EntitySecondaryState2:
|
|
ldy #$03 ; CPU:$D5BD PRG:15BD A0 03
|
|
bne EntitySecondaryAdjust ; CPU:$D5BF PRG:15BF D0 02
|
|
|
|
EntitySecondaryState3:
|
|
ldy #$01 ; CPU:$D5C1 PRG:15C1 A0 01
|
|
|
|
EntitySecondaryAdjust:
|
|
lda ($02),y ; CPU:$D5C3 PRG:15C3 B1 02
|
|
clc ; CPU:$D5C5 PRG:15C5 18
|
|
adc $C2,x ; CPU:$D5C6 PRG:15C6 75 C2
|
|
sta ($02),y ; CPU:$D5C8 PRG:15C8 91 02
|
|
|
|
lda #$00 ; CPU:$D5CA PRG:15CA A9 00
|
|
adc $C3,x ; CPU:$D5CC PRG:15CC 75 C3
|
|
sta $CC ; CPU:$D5CE PRG:15CE 85 CC
|
|
|
|
jmp $D5EB ; CPU:$D5D0 PRG:15D0 4C EB D5
|
|
|
|
;==============================================================================
|
|
; $D5D3-$D5EE: Entity Secondary States $00/$01 Movement Arithmetic
|
|
;
|
|
; Local:
|
|
; Secondary state 0 enters at $D5D3 and selects Y=$03.
|
|
; Secondary state 1 enters at $D5D7 and selects Y=$01.
|
|
;
|
|
; Both subtract the entity-specific movement value at $C2,X from the
|
|
; structure addressed by $02/$03. Borrow is converted into a high-byte
|
|
; adjustment using $C3,X and stored in $CC.
|
|
;
|
|
; Afterward, $CC is decremented. A negative result returns immediately;
|
|
; otherwise execution continues into another secondary dispatcher at $D5EF.
|
|
;
|
|
; Global:
|
|
; Complements the addition paths at $D5BD/$D5C1. Together, the four
|
|
; secondary states provide signed movement along two coordinate components.
|
|
;
|
|
; Notes:
|
|
; The shared labels are non-local because multiple handler entry points
|
|
; converge into them.
|
|
;==============================================================================
|
|
|
|
EntitySecondaryState0:
|
|
ldy #$03 ; CPU:$D5D3 PRG:15D3 A0 03
|
|
bne EntitySecondarySubtract ; CPU:$D5D5 PRG:15D5 D0 02
|
|
|
|
|
|
EntitySecondaryState1:
|
|
ldy #$01 ; CPU:$D5D7 PRG:15D7 A0 01
|
|
|
|
|
|
EntitySecondarySubtract:
|
|
lda ($02),y ; CPU:$D5D9 PRG:15D9 B1 02
|
|
sec ; CPU:$D5DB PRG:15DB 38
|
|
sbc $C2,x ; CPU:$D5DC PRG:15DC F5 C2
|
|
sta ($02),y ; CPU:$D5DE PRG:15DE 91 02
|
|
|
|
lda #$00 ; CPU:$D5E0 PRG:15E0 A9 00
|
|
bcs EntitySecondarySubtractNoBorrow ; CPU:$D5E2 PRG:15E2 B0 02
|
|
|
|
lda #$01 ; CPU:$D5E4 PRG:15E4 A9 01
|
|
|
|
|
|
EntitySecondarySubtractNoBorrow:
|
|
clc ; CPU:$D5E6 PRG:15E6 18
|
|
adc $C3,x ; CPU:$D5E7 PRG:15E7 75 C3
|
|
sta $CC ; CPU:$D5E9 PRG:15E9 85 CC
|
|
|
|
|
|
;==============================================================================
|
|
; $D5EB-$D600: Apply Entity Movement and Dispatch Direction Substate
|
|
;
|
|
; Local:
|
|
; Shared continuation reached by both the addition and subtraction
|
|
; secondary-state handlers.
|
|
;
|
|
; Decrements $CC. If it becomes negative, returns. Otherwise reads the
|
|
; current entity secondary state from $B9,X, doubles it, and selects a
|
|
; handler from the table at $D601.
|
|
;
|
|
; Global:
|
|
; Final arithmetic stage for entity movement before dispatching into the
|
|
; direction/substate-specific update handlers.
|
|
;==============================================================================
|
|
|
|
EntitySecondaryApplyResult:
|
|
dec $CC ; CPU:$D5EB PRG:15EB C6 CC
|
|
bpl EntityDirectionDispatch ; CPU:$D5ED PRG:15ED 10 01
|
|
|
|
rts ; CPU:$D5EF PRG:15EF 60
|
|
|
|
|
|
EntityDirectionDispatch:
|
|
lda $B9,x ; CPU:$D5F0 PRG:15F0 B5 B9
|
|
asl ; CPU:$D5F2 PRG:15F2 0A
|
|
tay ; CPU:$D5F3 PRG:15F3 A8
|
|
|
|
lda EntityDirectionStateTable,y ; CPU:$D5F4 PRG:15F4 B9 01 D6
|
|
sta $10 ; CPU:$D5F7 PRG:15F7 85 10
|
|
|
|
lda EntityDirectionStateTable+1,y ; CPU:$D5F9 PRG:15F9 B9 02 D6
|
|
sta $11 ; CPU:$D5FC PRG:15FC 85 11
|
|
|
|
jmp ($0010) ; CPU:$D5FE PRG:15FE 6C 10 00 09 D6
|
|
|
|
;==============================================================================
|
|
; $D601-$D608: Entity Direction-State Dispatch Table
|
|
;
|
|
; Local:
|
|
; Four handlers selected from the entity's secondary state at $B9,X.
|
|
;
|
|
; Notes:
|
|
; The pointer order deliberately differs from the physical order of the
|
|
; handlers in ROM.
|
|
;==============================================================================
|
|
|
|
EntityDirectionStateTable:
|
|
.word $D609 ; CPU:$D601 PRG:1601 09 D6
|
|
.word $D61D ; CPU:$D603 PRG:1603 1D D6
|
|
.word $D60F ; CPU:$D605 PRG:1605 0F D6
|
|
.word $D617 ; CPU:$D607 PRG:1607 17 D6
|
|
|
|
;==============================================================================
|
|
; $D609-$D622: Entity Direction-State Handlers
|
|
;
|
|
; Local:
|
|
; Four handlers selected by EntityDirectionStateTable.
|
|
;
|
|
; Each handler configures:
|
|
;
|
|
; $05 = +1 or -1
|
|
; Y = $00 or $02
|
|
;
|
|
; before entering the shared coordinate-update code at $D623.
|
|
;
|
|
; Global:
|
|
; Provides the four direction-specific movement modes for the per-entity
|
|
; state machine.
|
|
;
|
|
; Notes:
|
|
; The four states form two coordinate axes and two signed directions:
|
|
;
|
|
; $D609 -> $05=$FF, Y=$02
|
|
; $D60F -> $05=$01, Y=$02
|
|
; $D617 -> $05=$01, Y=$00
|
|
; $D61D -> $05=$FF, Y=$00
|
|
;
|
|
; Concrete direction names remain deferred until the coordinate axes are
|
|
; mapped to screen X/Y.
|
|
;==============================================================================
|
|
|
|
EntityDirectionD609:
|
|
lda #$FF ; CPU:$D609 PRG:1609 A9 FF
|
|
sta $05 ; CPU:$D60B PRG:160B 85 05
|
|
bne EntityDirectionAxis2 ; CPU:$D60D PRG:160D D0 04
|
|
|
|
|
|
EntityDirectionD60F:
|
|
lda #$01 ; CPU:$D60F PRG:160F A9 01
|
|
sta $05 ; CPU:$D611 PRG:1611 85 05
|
|
|
|
|
|
EntityDirectionAxis2:
|
|
ldy #$02 ; CPU:$D613 PRG:1613 A0 02
|
|
bne EntityDirectionMove ; CPU:$D615 PRG:1615 D0 0C
|
|
|
|
|
|
EntityDirectionD617:
|
|
lda #$01 ; CPU:$D617 PRG:1617 A9 01
|
|
sta $05 ; CPU:$D619 PRG:1619 85 05
|
|
bne EntityDirectionAxis0 ; CPU:$D61B PRG:161B D0 04
|
|
|
|
|
|
EntityDirectionD61D:
|
|
lda #$FF ; CPU:$D61D PRG:161D A9 FF
|
|
sta $05 ; CPU:$D61F PRG:161F 85 05
|
|
|
|
|
|
EntityDirectionAxis0:
|
|
ldy #$00 ; CPU:$D621 PRG:1621 A0 00
|
|
|
|
;==============================================================================
|
|
; $D623-$D69A: Shared Entity Direction Movement
|
|
;
|
|
; Local:
|
|
; Applies the signed step in $05 to either byte $00 or $02 of the entity
|
|
; structure referenced by $02/$03.
|
|
;
|
|
; Performs coordinate wrapping/bounds handling, updates a per-entity flag
|
|
; stored in $39+, checks tile/grid alignment, and when the entity reaches a
|
|
; specific location ($60,$70) changes the entity primary state to $02.
|
|
;
|
|
; Global:
|
|
; Shared movement implementation for the four handlers above.
|
|
;
|
|
; Notes:
|
|
; This section eventually rejoins the earlier movement arithmetic at $D5EB
|
|
; when the entity is not aligned to the grid.
|
|
;==============================================================================
|
|
|
|
EntityDirectionMove:
|
|
lda ($02),y ; CPU:$D623 PRG:1623 B1 02
|
|
clc ; CPU:$D625 PRG:1625 18
|
|
adc $05 ; CPU:$D626 PRG:1626 65 05
|
|
sta ($02),y ; CPU:$D628 PRG:1628 91 02
|
|
|
|
ldy #$00 ; CPU:$D62A PRG:162A A0 00
|
|
|
|
lda ($02),y ; CPU:$D62C PRG:162C B1 02
|
|
cmp #$0A ; CPU:$D62E PRG:162E C9 0A
|
|
bne @D637 ; CPU:$D630 PRG:1630 D0 06
|
|
|
|
lda #$BF ; CPU:$D632 PRG:1632 A9 BF
|
|
sta ($02),y ; CPU:$D634 PRG:1634 91 02
|
|
bne @D64B ; CPU:$D636 PRG:1636 D0 12
|
|
|
|
|
|
@D637:
|
|
cmp #$C0 ; CPU:$D638 PRG:1638 C9 C0
|
|
bne @D641 ; CPU:$D63A PRG:163A D0 06
|
|
|
|
lda #$0B ; CPU:$D63C PRG:163C A9 0B
|
|
sta ($02),y ; CPU:$D63E PRG:163E 91 02
|
|
bne @D64B ; CPU:$D640 PRG:1640 D0 08
|
|
|
|
|
|
@D641:
|
|
cmp #$18 ; CPU:$D642 PRG:1642 C9 18
|
|
bcc @D64B ; CPU:$D644 PRG:1644 90 04
|
|
|
|
cmp #$A9 ; CPU:$D646 PRG:1646 C9 A9
|
|
bcc @D64F ; CPU:$D648 PRG:1648 90 04
|
|
|
|
|
|
@D64B:
|
|
lda #$20 ; CPU:$D64A PRG:164A A9 20
|
|
bne @D651 ; CPU:$D64C PRG:164C D0 02
|
|
|
|
|
|
@D64F:
|
|
lda #$00 ; CPU:$D64E PRG:164E A9 00
|
|
|
|
|
|
@D651:
|
|
sta $05 ; CPU:$D650 PRG:1650 85 05
|
|
|
|
txa ; CPU:$D652 PRG:1652 8A
|
|
lsr ; CPU:$D653 PRG:1653 4A
|
|
tay ; CPU:$D654 PRG:1654 A8
|
|
|
|
lda $39,y ; CPU:$D655 PRG:1655 B9 39
|
|
and #$DF ; CPU:$D657 PRG:1657 00 29
|
|
ora $05 ; CPU:$D659 PRG:1659 DF 05
|
|
sta $39,y ; CPU:$D65B PRG:165B 05 99
|
|
|
|
ldy #$00 ; CPU:$D65D PRG:165D 39 00
|
|
lda ($02),y ; CPU:$D65F PRG:165F A0 00
|
|
|
|
ldy #$02 ; CPU:$D661 PRG:1661 B1 02
|
|
ora ($02),y ; CPU:$D663 PRG:1663 A0 02
|
|
and #$07 ; CPU:$D665 PRG:1665 11 02
|
|
beq @D66E ; CPU:$D667 PRG:1667 29 07
|
|
|
|
jmp EntitySecondaryApplyResult ; CPU:$D669 PRG:1669 F0 03 4C
|
|
|
|
@D66E:
|
|
ldy #$00 ; CPU:$D66C PRG:166C EB D5
|
|
|
|
lda ($02),y ; CPU:$D66E PRG:166E A0 00
|
|
cmp #$60 ; CPU:$D670 PRG:1670 B1 02
|
|
bne $D69B ; CPU:$D672 PRG:1672 C9 60
|
|
|
|
ldy #$02 ; CPU:$D674 PRG:1674 D0 25
|
|
|
|
lda ($02),y ; CPU:$D676 PRG:1676 A0 02
|
|
cmp #$70 ; CPU:$D678 PRG:1678 B1 02
|
|
bne $D69B ; CPU:$D67A PRG:167A C9 70
|
|
|
|
lda #$02 ; CPU:$D67C PRG:167C D0 1D
|
|
sta $B8,x ; CPU:$D67E PRG:167E A9 02
|
|
|
|
lda #$00 ; CPU:$D680 PRG:1680 95 B8
|
|
clc ; CPU:$D682 PRG:1682 A9
|
|
sbc $04 ; CPU:$D683 PRG:1683 00 18
|
|
and $88 ; CPU:$D685 PRG:1685 E5 04
|
|
sta $88 ; CPU:$D687 PRG:1687 25 88
|
|
|
|
txa ; CPU:$D689 PRG:1689 85
|
|
lsr ; CPU:$D68A PRG:168A 88
|
|
tay ; CPU:$D68B PRG:168B 8A
|
|
sta $05 ; CPU:$D68C PRG:168C 4A A8
|
|
|
|
lda $39,y ; CPU:$D68E PRG:168E 85 05
|
|
and #$FC ; CPU:$D690 PRG:1690 B9 39
|
|
ora $05 ; CPU:$D692 PRG:1692 00 29
|
|
sta $39,y ; CPU:$D694 PRG:1694 FC 05
|
|
|
|
rts ; CPU:$D696 PRG:1696 05
|
|
|
|
;==============================================================================
|
|
; $D69B-$D6C6: Entity Movement Continuation / Target Selection
|
|
;
|
|
; Local:
|
|
; Continues entity processing after direction movement.
|
|
;
|
|
; Primary entity state $06 selects the fixed value $6F60 in $CD/$CE.
|
|
; Otherwise entity bitmasks in $04 are tested against $88 and $87.
|
|
;
|
|
; ($04 & $88) != 0 transfers to $D70A.
|
|
; ($04 & $87) != 0 transfers to $D6CF.
|
|
;
|
|
; If neither mask matches, the current entity index X selects a 16-bit value
|
|
; from EntityTargetTable and processing continues at $D778.
|
|
;
|
|
; Global:
|
|
; Chooses the next entity target/path-processing mode based on entity state
|
|
; and per-entity bitmasks.
|
|
;
|
|
; Notes:
|
|
; Cross-region branch targets remain raw until the destination blocks are
|
|
; decoded.
|
|
;==============================================================================
|
|
|
|
EntityMovementContinuation:
|
|
lda $B8,x ; CPU:$D69B PRG:169B B5 B8
|
|
cmp #$06 ; CPU:$D69D PRG:169D C9 06
|
|
bne @CheckEntityMasks ; CPU:$D69F PRG:169F D0 0B
|
|
|
|
lda #$60 ; CPU:$D6A1 PRG:16A1 A9 60
|
|
sta $CD ; CPU:$D6A3 PRG:16A3 85 CD
|
|
|
|
lda #$6F ; CPU:$D6A5 PRG:16A5 A9 6F
|
|
sta $CE ; CPU:$D6A7 PRG:16A7 85 CE
|
|
|
|
jmp $D778 ; CPU:$D6A9 PRG:16A9 4C 78 D7
|
|
|
|
|
|
@CheckEntityMasks:
|
|
lda $04 ; CPU:$D6AC PRG:16AC A5 04
|
|
and $88 ; CPU:$D6AE PRG:16AE 25 88
|
|
bne $D70A ; CPU:$D6B0 PRG:16B0 D0 58
|
|
|
|
lda $04 ; CPU:$D6B2 PRG:16B2 A5 04
|
|
and $87 ; CPU:$D6B4 PRG:16B4 25 87
|
|
bne $D6CF ; CPU:$D6B6 PRG:16B6 D0 17
|
|
|
|
txa ; CPU:$D6B8 PRG:16B8 8A
|
|
tay ; CPU:$D6B9 PRG:16B9 A8
|
|
|
|
lda EntityTargetTable,y ; CPU:$D6BA PRG:16BA B9 C7 D6
|
|
sta $CD ; CPU:$D6BD PRG:16BD 85 CD
|
|
|
|
lda EntityTargetTable+1,y ; CPU:$D6BF PRG:16BF B9 C8 D6
|
|
sta $CE ; CPU:$D6C2 PRG:16C2 85 CE
|
|
|
|
jmp $D778 ; CPU:$D6C4 PRG:16C4 4C 78 D7
|
|
|
|
;==============================================================================
|
|
; $D6C7-$D6CE: Entity Target Table
|
|
;
|
|
; Local:
|
|
; Four 16-bit values indexed directly by the even entity offset X.
|
|
;
|
|
; Global:
|
|
; Supplies the $CD/$CE working target used by EntityMovementContinuation.
|
|
;
|
|
; Notes:
|
|
; Values are retained numerically until the consumer at $D778 is decoded.
|
|
;==============================================================================
|
|
|
|
EntityTargetTable:
|
|
.word $08A8 ; CPU:$D6C7 PRG:16C7 A8 08
|
|
.word $0818 ; CPU:$D6C9 PRG:16C9 18 08
|
|
.word $D0A8 ; CPU:$D6CB PRG:16CB A8 D0
|
|
.word $D018 ; CPU:$D6CD PRG:16CD 18 D0
|
|
|
|
;==============================================================================
|
|
; $D6CF-$D6DD: Entity Target-Selection Dispatcher
|
|
;
|
|
; Local:
|
|
; Uses the current even entity index X directly as a byte offset into the
|
|
; four-entry pointer table at $D6DE.
|
|
;
|
|
; The selected handler address is stored in $10/$11 and execution transfers
|
|
; through an indirect JMP.
|
|
;
|
|
; Global:
|
|
; Entered from EntityMovementContinuation when the current entity's bit in
|
|
; $87 is set. Selects entity-specific target/path behavior.
|
|
;
|
|
; Notes:
|
|
; X is already constrained by the calling code to the even entity offsets:
|
|
;
|
|
; $00,$02,$04,$06
|
|
;
|
|
; Therefore no multiply-by-two is required here.
|
|
;==============================================================================
|
|
|
|
DispatchEntityTargetBehavior:
|
|
txa ; CPU:$D6CF PRG:16CF 8A
|
|
tay ; CPU:$D6D0 PRG:16D0 A8
|
|
|
|
lda EntityTargetBehaviorTable,y ; CPU:$D6D1 PRG:16D1 B9 DE D6
|
|
sta $10 ; CPU:$D6D4 PRG:16D4 85 10
|
|
|
|
lda EntityTargetBehaviorTable+1,y ; CPU:$D6D6 PRG:16D6 B9 DF D6
|
|
sta $11 ; CPU:$D6D9 PRG:16D9 85 11
|
|
|
|
jmp ($0010) ; CPU:$D6DB PRG:16DB 6C 10 00 3B D7
|
|
|
|
;==============================================================================
|
|
; $D6DE-$D6E5: Entity Target-Behavior Dispatch Table
|
|
;
|
|
; Local:
|
|
; Four 16-bit handlers indexed directly by the even entity index X.
|
|
;
|
|
; Global:
|
|
; Selects different target/path calculations for each of the four gameplay
|
|
; entities.
|
|
;
|
|
; Notes:
|
|
; The fourth entry deliberately points backward to $D6E6, immediately after
|
|
; this table.
|
|
;==============================================================================
|
|
|
|
EntityTargetBehaviorTable:
|
|
.word EntityTargetBehaviorD73B ; X = $00 ; CPU:$D6DE PRG:16DE 3B D7
|
|
.word EntityTargetBehaviorD745 ; X = $02 ; CPU:$D6E0 PRG:16E0 45 D7
|
|
.word EntityTargetBehaviorD764 ; X = $04 ; CPU:$D6E2 PRG:16E2 64 D7
|
|
.word EntityTargetBehaviorD6E6 ; X = $06 ; CPU:$D6E4 PRG:16E4 E6 D6
|
|
|
|
;==============================================================================
|
|
; $D6E6-$D73A: Entity Target Behavior - Proximity/Direction Selection
|
|
;
|
|
; Local:
|
|
; Computes absolute differences between $1A/$2A and $1C/$2C.
|
|
; If either difference is at least $20, transfers to EntityTargetBehaviorD73B.
|
|
;
|
|
; Otherwise attempts up to five candidate directions. Each candidate is
|
|
; checked against the data addressed by $00/$01 and against the current
|
|
; entity direction/state at $B9,X.
|
|
;
|
|
; The selected value is stored into $B9,X before returning to the common
|
|
; entity movement result handler at $D5EB.
|
|
;
|
|
; Global:
|
|
; Fourth entry in EntityTargetBehaviorTable, selected for entity X=$06.
|
|
;
|
|
; Notes:
|
|
; Cross-block target $D73B remains raw until that handler is decoded.
|
|
;==============================================================================
|
|
|
|
EntityTargetBehaviorD6E6:
|
|
lda $1A ; CPU:$D6E6 PRG:16E6 A5 1A
|
|
sec ; CPU:$D6E8 PRG:16E8 38
|
|
sbc $2A ; CPU:$D6E9 PRG:16E9 E5 2A
|
|
bcs @D6F4 ; CPU:$D6EB PRG:16EB B0 07
|
|
|
|
sta $05 ; CPU:$D6ED PRG:16ED 85 05
|
|
|
|
lda #$00 ; CPU:$D6EF PRG:16EF A9 00
|
|
sec ; CPU:$D6F1 PRG:16F1 38
|
|
sbc $05 ; CPU:$D6F2 PRG:16F2 E5 05
|
|
|
|
@D6F4:
|
|
cmp #$20 ; CPU:$D6F4 PRG:16F4 C9 20
|
|
bcs $D73B ; CPU:$D6F6 PRG:16F6 B0 43
|
|
|
|
lda $1C ; CPU:$D6F8 PRG:16F8 A5 1C
|
|
sec ; CPU:$D6FA PRG:16FA 38
|
|
sbc $2C ; CPU:$D6FB PRG:16FB E5 2C
|
|
bcs @D703 ; CPU:$D6FD PRG:16FD B0 07
|
|
|
|
sta $05 ; CPU:$D6FF PRG:16FF 85 05
|
|
|
|
lda #$00 ; CPU:$D701 PRG:1701 A9 00
|
|
sec ; CPU:$D703 PRG:1703 38
|
|
sbc $05 ; CPU:$D704 PRG:1704 E5 05
|
|
|
|
@D703:
|
|
cmp #$20 ; CPU:$D706 PRG:1706 C9 20
|
|
bcs $D73B ; CPU:$D708 PRG:1708 B0 31
|
|
|
|
lda $4B ; CPU:$D70A PRG:170A A5 4B
|
|
sta $05 ; CPU:$D70C PRG:170C 85 05
|
|
|
|
lda #$05 ; CPU:$D70E PRG:170E A9 05
|
|
sta $06 ; CPU:$D710 PRG:1710 85 06
|
|
|
|
|
|
@D712:
|
|
dec $06 ; CPU:$D712 PRG:1712 C6 06
|
|
bne @D71A ; CPU:$D714 PRG:1714 D0 04
|
|
|
|
lda #$02 ; CPU:$D716 PRG:1716 A9 02
|
|
bne @D736 ; CPU:$D718 PRG:1718 D0 1C
|
|
|
|
|
|
@D71A:
|
|
inc $05 ; CPU:$D71A PRG:171A E6 05
|
|
|
|
lda $05 ; CPU:$D71C PRG:171C A5 05
|
|
and #$03 ; CPU:$D71E PRG:171E 29 03
|
|
tay ; CPU:$D720 PRG:1720 A8
|
|
|
|
lda ($00),y ; CPU:$D721 PRG:1721 B1 00
|
|
and #$F8 ; CPU:$D723 PRG:1723 29 F8
|
|
bne @D712 ; CPU:$D725 PRG:1725 D0 EB
|
|
|
|
lda $05 ; CPU:$D727 PRG:1727 A5 05
|
|
clc ; CPU:$D729 PRG:1729 18
|
|
adc #$02 ; CPU:$D72A PRG:172A 69 02
|
|
and #$03 ; CPU:$D72C PRG:172C 29 03
|
|
cmp $B9,x ; CPU:$D72E PRG:172E D5 B9
|
|
beq @D712 ; CPU:$D730 PRG:1730 F0 E0
|
|
|
|
lda $05 ; CPU:$D732 PRG:1732 A5 05
|
|
and #$03 ; CPU:$D734 PRG:1734 29 03
|
|
|
|
|
|
@D736:
|
|
sta $B9,x ; CPU:$D736 PRG:1736 95 B9
|
|
|
|
jmp EntitySecondaryApplyResult ; CPU:$D738 PRG:1738 4C EB D5
|
|
|
|
;==============================================================================
|
|
; $D73B-$D777: Entity Target Calculation Handlers
|
|
;
|
|
; Local:
|
|
; Three handlers selected by EntityTargetBehaviorTable.
|
|
;
|
|
; $D73B:
|
|
; Uses the current $1A/$1C coordinate pair directly as the target.
|
|
;
|
|
; $D745:
|
|
; Uses $51 to select a signed coordinate offset from the table at $D75C,
|
|
; then adds that offset to $1A/$1C.
|
|
;
|
|
; $D764:
|
|
; Reflects/extrapolates the current coordinate pair relative to
|
|
; $1E/$20.
|
|
;
|
|
; All three produce the target coordinate in $CD/$CE and converge on the
|
|
; still-undecoded common processing at $D778.
|
|
;
|
|
; Global:
|
|
; Three of the four target strategies selected by
|
|
; EntityTargetBehaviorTable.
|
|
;
|
|
; Notes:
|
|
; Cross-block destination $D778 remains raw until the common handler is
|
|
; decoded separately.
|
|
;==============================================================================
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D73B: direct target
|
|
;------------------------------------------------------------------------------
|
|
|
|
EntityTargetBehaviorD73B:
|
|
lda $1A ; CPU:$D73B PRG:173B A5 1A
|
|
sta $CD ; CPU:$D73D PRG:173D 85 CD
|
|
|
|
lda $1C ; CPU:$D73F PRG:173F A5 1C
|
|
sta $CE ; CPU:$D741 PRG:1741 85 CE
|
|
|
|
bne $D778 ; CPU:$D743 PRG:1743 D0 33
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D745: direction-offset target
|
|
;------------------------------------------------------------------------------
|
|
|
|
EntityTargetBehaviorD745:
|
|
lda $51 ; CPU:$D745 PRG:1745 A5 51
|
|
asl ; CPU:$D747 PRG:1747 0A
|
|
tay ; CPU:$D748 PRG:1748 A8
|
|
|
|
lda EntityDirectionTargetOffsets,y ; CPU:$D749 PRG:1749 B9 5C D7
|
|
clc ; CPU:$D74C PRG:174C 18
|
|
adc $1A ; CPU:$D74D PRG:174D 65 1A
|
|
sta $CD ; CPU:$D74F PRG:174F 85 CD
|
|
|
|
lda EntityDirectionTargetOffsets+1,y ; CPU:$D751 PRG:1751 B9 5D D7
|
|
clc ; CPU:$D754 PRG:1754 18
|
|
adc $1C ; CPU:$D755 PRG:1755 65 1C
|
|
sta $CE ; CPU:$D757 PRG:1757 85 CE
|
|
|
|
jmp $D778 ; CPU:$D759 PRG:1759 4C 78 D7
|
|
|
|
;==============================================================================
|
|
; $D75C-$D763: Direction Target Offset Table
|
|
;
|
|
; Local:
|
|
; Four signed coordinate offset pairs selected by ($51 * 2).
|
|
;
|
|
; As signed 8-bit values:
|
|
;
|
|
; 0 -> ( 0, -24 )
|
|
; 1 -> (-24, 0 )
|
|
; 2 -> ( 0, +24 )
|
|
; 3 -> (+24, 0 )
|
|
;
|
|
; Global:
|
|
; Used by EntityTargetBehaviorD745 to project a target position in the
|
|
; entity's current direction.
|
|
;==============================================================================
|
|
|
|
EntityDirectionTargetOffsets:
|
|
.byte $00,$E8 ; CPU:$D75C PRG:175C 00 E8
|
|
.byte $E8,$00 ; CPU:$D75E PRG:175E E8 00
|
|
.byte $00,$18 ; CPU:$D760 PRG:1760 00 18
|
|
.byte $18,$00 ; CPU:$D762 PRG:1762 18 00
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D764: relative/reflected target
|
|
;
|
|
; Computes:
|
|
;
|
|
; $CD = $1A + ($1A - $1E)
|
|
; $CE = $1C + ($1C - $20)
|
|
;
|
|
; which algebraically corresponds to:
|
|
;
|
|
; $CD = 2*$1A - $1E
|
|
; $CE = 2*$1C - $20
|
|
;
|
|
; using 8-bit arithmetic.
|
|
;------------------------------------------------------------------------------
|
|
|
|
EntityTargetBehaviorD764:
|
|
lda $1A ; CPU:$D764 PRG:1764 A5 1A
|
|
sec ; CPU:$D766 PRG:1766 38
|
|
sbc $1E ; CPU:$D767 PRG:1767 E5 1E
|
|
|
|
clc ; CPU:$D769 PRG:1769 18
|
|
adc $1A ; CPU:$D76A PRG:176A 65 1A
|
|
sta $CD ; CPU:$D76C PRG:176C 85 CD
|
|
|
|
lda $1C ; CPU:$D76E PRG:176E A5 1C
|
|
sec ; CPU:$D770 PRG:1770 38
|
|
sbc $20 ; CPU:$D771 PRG:1771 E5 20
|
|
|
|
clc ; CPU:$D773 PRG:1773 18
|
|
adc $1C ; CPU:$D774 PRG:1774 65 1C
|
|
sta $CE ; CPU:$D776 PRG:1776 85 CE
|
|
|
|
;==============================================================================
|
|
; $D778-$D79F: Common Entity Target Processing
|
|
;
|
|
; Local:
|
|
; Shared continuation used after an entity target coordinate has been
|
|
; calculated in $CD/$CE.
|
|
;
|
|
; Uses the entity primary state at $B8,X, minus $04, as a byte offset into
|
|
; a packed pointer table beginning at $D881. The selected pointer is stored
|
|
; in $0A/$0B and passed to BuildLegalDirectionList.
|
|
;
|
|
; The results returned in $0C/$0D determine the entity's next secondary
|
|
; state at $B9,X:
|
|
;
|
|
; $0C == $FF
|
|
; -> force state $02
|
|
;
|
|
; $0C != $FF and $0D == $FF
|
|
; -> store $0C into $B9,X and return
|
|
;
|
|
; $0C != $FF and $0D != $FF
|
|
; -> continue at $D7A0 for additional selection logic
|
|
;
|
|
; Global:
|
|
; Common target-evaluation stage reached by the entity target strategies
|
|
; at $D73B, $D745 and $D764, as well as fixed-target paths from earlier
|
|
; entity processing.
|
|
;
|
|
; Notes:
|
|
; $D881 remains undecoded and is therefore referenced by address.
|
|
;
|
|
; The branch to $D7A0 is intentionally kept raw because $D7A0 belongs to
|
|
; the next block and is an explicit continuation rather than an RTS.
|
|
;==============================================================================
|
|
|
|
EntityTargetCommon:
|
|
lda $B8,x ; CPU:$D778 PRG:1778 B5 B8
|
|
sec ; CPU:$D77A PRG:177A 38
|
|
sbc #$04 ; CPU:$D77B PRG:177B E9 04
|
|
tay ; CPU:$D77D PRG:177D A8
|
|
|
|
lda $D881,y ; CPU:$D77E PRG:177E B9 81 D8
|
|
sta $0A ; CPU:$D781 PRG:1781 85 0A
|
|
|
|
lda $D882,y ; CPU:$D783 PRG:1783 B9 82 D8
|
|
sta $0B ; CPU:$D786 PRG:1786 85 0B
|
|
|
|
jsr BuildLegalDirectionList ; CPU:$D788 PRG:1788 20 B1 E4
|
|
|
|
lda $0C ; CPU:$D78B PRG:178B A5 0C
|
|
cmp #$FF ; CPU:$D78D PRG:178D C9 FF
|
|
bne @D795 ; CPU:$D78F PRG:178F D0 04
|
|
|
|
lda #$02 ; CPU:$D791 PRG:1791 A9 02
|
|
bne @D79D ; CPU:$D793 PRG:1793 D0 08
|
|
|
|
|
|
@D795:
|
|
lda $0D ; CPU:$D795 PRG:1795 A5 0D
|
|
cmp #$FF ; CPU:$D797 PRG:1797 C9 FF
|
|
bne $D7A0 ; CPU:$D799 PRG:1799 D0 05
|
|
|
|
lda $0C ; CPU:$D79B PRG:179B A5 0C
|
|
|
|
|
|
@D79D:
|
|
sta $B9,x ; CPU:$D79D PRG:179D 95 B9
|
|
|
|
rts ; CPU:$D79F PRG:179F 60
|
|
|
|
;==============================================================================
|
|
; $D7A0-$D820: Select Entity Direction Toward Target
|
|
;
|
|
; Local:
|
|
; Entered from EntityTargetCommon when both $0C and $0D returned by
|
|
; BuildLegalDirectionList are valid.
|
|
;
|
|
; Computes absolute coordinate distances between target $CD/$CE and the
|
|
; current entity coordinates addressed through $02/$03.
|
|
;
|
|
; $05 accumulates direction-order information according to:
|
|
; - sign of the horizontal/vertical difference
|
|
; - which axis has the larger absolute distance
|
|
;
|
|
; The result is used to index a direction-priority table at $D871.
|
|
; Candidate directions are compared against the four values at $0C-$0F.
|
|
; When a candidate matches, execution branches back to the common direction
|
|
; store at $D79D.
|
|
;
|
|
; If the preferred candidates fail, the routine tests directions adjacent
|
|
; to the current secondary state $B9,X before eventually returning.
|
|
;
|
|
; Global:
|
|
; Alternate continuation of EntityTargetCommon. Selects the next movement
|
|
; direction for an entity based on its current position and target.
|
|
;
|
|
; Notes:
|
|
; $05 is a temporary direction-priority index.
|
|
; $06/$07 hold absolute coordinate differences.
|
|
; $08 is temporary storage during absolute-value calculations.
|
|
;
|
|
; $D871 is not decoded yet and remains a raw table reference.
|
|
;==============================================================================
|
|
|
|
SelectEntityDirectionTowardTarget:
|
|
ldy #$00 ; CPU:$D7A0 PRG:17A0 A0 00
|
|
sty $05 ; CPU:$D7A2 PRG:17A2 84 05
|
|
|
|
lda $CD ; CPU:$D7A4 PRG:17A4 A5 CD
|
|
sec ; CPU:$D7A6 PRG:17A6 38
|
|
sbc ($02),y ; CPU:$D7A7 PRG:17A7 F1 02
|
|
bcs @D7B9 ; CPU:$D7A9 PRG:17A9 B0 0F
|
|
|
|
sta $08 ; CPU:$D7AB PRG:17AB 85 08
|
|
|
|
lda #$00 ; CPU:$D7AD PRG:17AD A9 00
|
|
sec ; CPU:$D7AF PRG:17AF 38
|
|
sbc $08 ; CPU:$D7B0 PRG:17B0 E5 08
|
|
|
|
inc $05 ; CPU:$D7B2 PRG:17B2 E6 05
|
|
inc $05 ; CPU:$D7B4 PRG:17B4 E6 05
|
|
inc $05 ; CPU:$D7B6 PRG:17B6 E6 05
|
|
inc $05 ; CPU:$D7B8 PRG:17B8 E6 05
|
|
|
|
@D7B9:
|
|
sta $06 ; CPU:$D7BA PRG:17BA 85 06
|
|
|
|
lda $CE ; CPU:$D7BC PRG:17BC A5 CE
|
|
|
|
ldy #$02 ; CPU:$D7BE PRG:17BE A0 02
|
|
|
|
sec ; CPU:$D7C0 PRG:17C0 38
|
|
sbc ($02),y ; CPU:$D7C1 PRG:17C1 F1 02
|
|
bcs @D7D2 ; CPU:$D7C3 PRG:17C3 B0 0B
|
|
|
|
sta $08 ; CPU:$D7C5 PRG:17C5 85 08
|
|
|
|
lda #$00 ; CPU:$D7C7 PRG:17C7 A9 00
|
|
sec ; CPU:$D7C9 PRG:17C9 38
|
|
sbc $08 ; CPU:$D7CA PRG:17CA E5 08
|
|
|
|
inc $05 ; CPU:$D7CC PRG:17CC E6 05
|
|
inc $05 ; CPU:$D7CE PRG:17CE E6 05
|
|
|
|
@D7D2:
|
|
sta $07 ; CPU:$D7D0 PRG:17D0 85 07
|
|
|
|
lda $06 ; CPU:$D7D2 PRG:17D2 A5 06
|
|
cmp $07 ; CPU:$D7D4 PRG:17D4 C5 07
|
|
bcs @D7DB ; CPU:$D7D6 PRG:17D6 B0 02
|
|
|
|
inc $05 ; CPU:$D7D8 PRG:17D8 E6 05
|
|
|
|
@D7DB:
|
|
lda $05 ; CPU:$D7DA PRG:17DA A5 05
|
|
asl ; CPU:$D7DC PRG:17DC 0A
|
|
sta $05 ; CPU:$D7DD PRG:17DD 85 05
|
|
|
|
lda #$02 ; CPU:$D7DF PRG:17DF A9 02
|
|
sta $06 ; CPU:$D7E1 PRG:17E1 85 06
|
|
|
|
|
|
@D7E3:
|
|
ldy $05 ; CPU:$D7E3 PRG:17E3 A4 05
|
|
|
|
lda $D871,y ; CPU:$D7E5 PRG:17E5 B9 71 D8
|
|
|
|
ldy #$00 ; CPU:$D7E8 PRG:17E8 A0 00
|
|
|
|
@D7EA:
|
|
cmp $000C,y ; CPU:$D7EA PRG:17EA D9 0C 00
|
|
beq $D79D ; CPU:$D7ED PRG:17ED F0 AE
|
|
|
|
iny ; CPU:$D7EF PRG:17EF C8
|
|
cpy #$04 ; CPU:$D7F0 PRG:17F0 C0 04
|
|
bne @D7EA ; CPU:$D7F2 PRG:17F2 D0 F6
|
|
|
|
inc $05 ; CPU:$D7F4 PRG:17F4 E6 05
|
|
|
|
dec $06 ; CPU:$D7F6 PRG:17F6 C6 06
|
|
bne @D7E3 ; CPU:$D7F8 PRG:17F8 D0 E9
|
|
|
|
lda $B9,x ; CPU:$D7FA PRG:17FA B5 B9
|
|
sec ; CPU:$D7FC PRG:17FC 38
|
|
sbc #$01 ; CPU:$D7FD PRG:17FD E9 01
|
|
and #$03 ; CPU:$D7FF PRG:17FF 29 03
|
|
|
|
ldy #$00 ; CPU:$D801 PRG:1801 A0 00
|
|
|
|
@D802:
|
|
cmp $000C,y ; CPU:$D803 PRG:1803 D9 0C 00
|
|
beq $D79D ; CPU:$D806 PRG:1806 F0 95
|
|
|
|
iny ; CPU:$D808 PRG:1808 C8
|
|
cpy #$04 ; CPU:$D809 PRG:1809 C0 04
|
|
bne @D802 ; CPU:$D80B PRG:180B D0 F6
|
|
|
|
lda $B9,x ; CPU:$D80D PRG:180D B5 B9
|
|
clc ; CPU:$D80F PRG:180F 18
|
|
adc #$01 ; CPU:$D810 PRG:1810 69 01
|
|
and #$03 ; CPU:$D812 PRG:1812 29 03
|
|
|
|
ldy #$00 ; CPU:$D814 PRG:1814 A0 00
|
|
|
|
@D814:
|
|
cmp $000C,y ; CPU:$D816 PRG:1816 D9 0C 00
|
|
beq $D79D ; CPU:$D819 PRG:1819 F0 82
|
|
|
|
iny ; CPU:$D81B PRG:181B C8
|
|
cpy #$04 ; CPU:$D81C PRG:181C C0 04
|
|
bne @D814 ; CPU:$D81E PRG:181E D0 F6
|
|
|
|
rts ; CPU:$D820 PRG:1820 60
|
|
|
|
;==============================================================================
|
|
; $D821-$D870: Select Entity Movement Parameters
|
|
;
|
|
; Local:
|
|
; Chooses the two-byte movement/step value stored at:
|
|
;
|
|
; $C2,X
|
|
; $C3,X
|
|
;
|
|
; for the current gameplay entity.
|
|
;
|
|
; Selection depends on:
|
|
;
|
|
; - primary entity state $B8,X
|
|
; - current entity coordinates through ($02)
|
|
; - entity bitmask $04 against $88
|
|
; - whether X is zero or identifies another entity
|
|
;
|
|
; Parameter pairs are copied from several global values:
|
|
;
|
|
; $B3/$B4
|
|
; $CA/$CB
|
|
; $AF/$B0
|
|
; $B1/$B2
|
|
;
|
|
; Primary state $06 instead installs the fixed pair:
|
|
;
|
|
; $00,$02
|
|
;
|
|
; Global:
|
|
; Called before the $B9,X secondary-state dispatcher at $D5A1. This chooses
|
|
; the movement increment used by the entity movement arithmetic.
|
|
;
|
|
; Notes:
|
|
; The coordinate pointer $02/$03 identifies the current entity's structure.
|
|
; X is the even entity slot index.
|
|
;==============================================================================
|
|
|
|
SelectEntityMovementSpeed:
|
|
lda $B8,x ; CPU:$D821 PRG:1821 B5 B8
|
|
cmp #$06 ; CPU:$D823 PRG:1823 C9 06
|
|
beq @D864 ; CPU:$D825 PRG:1825 F0 41
|
|
|
|
ldy #$02 ; CPU:$D827 PRG:1827 A0 02
|
|
|
|
lda ($02),y ; CPU:$D829 PRG:1829 B1 02
|
|
cmp #$70 ; CPU:$D82B PRG:182B C9 70
|
|
bne @D843 ; CPU:$D82D PRG:182D D0 15
|
|
|
|
ldy #$00 ; CPU:$D82F PRG:182F A0 00
|
|
|
|
lda ($02),y ; CPU:$D831 PRG:1831 B1 02
|
|
cmp #$90 ; CPU:$D833 PRG:1833 C9 90
|
|
bcs @D83D ; CPU:$D835 PRG:1835 B0 04
|
|
|
|
cmp #$30 ; CPU:$D837 PRG:1837 C9 30
|
|
bcs @D843 ; CPU:$D839 PRG:1839 B0 09
|
|
|
|
@D83D:
|
|
lda $B3 ; CPU:$D83B PRG:183B A5 B3
|
|
sta $C2,x ; CPU:$D83D PRG:183D 95 C2
|
|
|
|
lda $B4 ; CPU:$D83F PRG:183F A5 B4
|
|
sta $C3,x ; CPU:$D841 PRG:1841 95 C3
|
|
|
|
rts ; CPU:$D843 PRG:1843 60
|
|
|
|
|
|
@D843:
|
|
lda $04 ; CPU:$D844 PRG:1844 A5 04
|
|
and $88 ; CPU:$D846 PRG:1846 25 88
|
|
bne @D85A ; CPU:$D848 PRG:1848 D0 15
|
|
|
|
txa ; CPU:$D84A PRG:184A 8A
|
|
bne @D854 ; CPU:$D84B PRG:184B D0 09
|
|
|
|
lda $CA ; CPU:$D84D PRG:184D A5 CA
|
|
sta $C2 ; CPU:$D84F PRG:184F 85 C2
|
|
|
|
lda $CB ; CPU:$D851 PRG:1851 A5 CB
|
|
sta $C3 ; CPU:$D853 PRG:1853 85 C3
|
|
|
|
rts ; CPU:$D855 PRG:1855 60
|
|
|
|
|
|
@D854:
|
|
lda $AF ; CPU:$D856 PRG:1856 A5 AF
|
|
sta $C2,x ; CPU:$D858 PRG:1858 95 C2
|
|
|
|
lda $B0 ; CPU:$D85A PRG:185A A5 B0
|
|
sta $C3,x ; CPU:$D85C PRG:185C 95 C3
|
|
|
|
rts ; CPU:$D85E PRG:185E 60
|
|
|
|
|
|
@D85A:
|
|
lda $B1 ; CPU:$D85F PRG:185F A5 B1
|
|
sta $C2,x ; CPU:$D861 PRG:1861 95 C2
|
|
|
|
lda $B2 ; CPU:$D863 PRG:1863 A5 B2
|
|
sta $C3,x ; CPU:$D865 PRG:1865 95 C3
|
|
|
|
rts ; CPU:$D867 PRG:1867 60
|
|
|
|
|
|
@D864:
|
|
lda #$00 ; CPU:$D868 PRG:1868 A9 00
|
|
sta $C2,x ; CPU:$D86A PRG:186A 95 C2
|
|
|
|
lda #$02 ; CPU:$D86C PRG:186C A9 02
|
|
sta $C3,x ; CPU:$D86E PRG:186E 95 C3
|
|
|
|
rts ; CPU:$D870 PRG:1870 60
|
|
|
|
;==============================================================================
|
|
; $D871-$D880: Entity Direction Priority Table
|
|
;
|
|
; Local:
|
|
; Sixteen direction values used by SelectEntityDirectionTowardTarget.
|
|
;
|
|
; $05 is derived from:
|
|
; - the sign of each target-coordinate difference,
|
|
; - which axis has the greater absolute distance.
|
|
;
|
|
; $05 is doubled before indexing this table, and the routine may examine
|
|
; the following entry as its second preferred candidate.
|
|
;
|
|
; Global:
|
|
; Defines the preferred entity movement directions for the different
|
|
; relative target-position quadrants/axis priorities.
|
|
;
|
|
; Notes:
|
|
; Values are internal direction numbers 0-3. Concrete direction names remain
|
|
; deferred until the internal direction numbering is fully mapped.
|
|
;
|
|
; The natural layout is eight pairs of preferred directions.
|
|
;==============================================================================
|
|
|
|
EntityDirectionPriorityTable:
|
|
.byte $03,$02 ; CPU:$D871 PRG:1871 03 02
|
|
.byte $02,$03 ; CPU:$D873 PRG:1873 02 03
|
|
.byte $03,$00 ; CPU:$D875 PRG:1875 03 00
|
|
.byte $00,$03 ; CPU:$D877 PRG:1877 00 03
|
|
.byte $01,$02 ; CPU:$D879 PRG:1879 01 02
|
|
.byte $02,$01 ; CPU:$D87B PRG:187B 02 01
|
|
.byte $01,$00 ; CPU:$D87D PRG:187D 01 00
|
|
.byte $00,$01 ; CPU:$D87F PRG:187F 00 01
|
|
|
|
;==============================================================================
|
|
; $D881-$D884: Entity Path/Map Pointer Table
|
|
;
|
|
; Local:
|
|
; Two 16-bit values selected according to entity primary state:
|
|
;
|
|
; state $04 -> $0000
|
|
; state $06 -> $082C
|
|
;
|
|
; The selected value is placed in $0A/$0B and passed to the helper at
|
|
; BuildLegalDirectionList.
|
|
;
|
|
; Global:
|
|
; Supplies state-dependent path/map parameters used by EntityTargetCommon.
|
|
;
|
|
; Notes:
|
|
; Keep the entries as literal 16-bit values until BuildLegalDirectionList
|
|
; is decoded and the semantic meaning of $0A/$0B is established.
|
|
;==============================================================================
|
|
|
|
EntityPathParameterTable:
|
|
.word $0000 ; CPU:$D881 PRG:1881 00 00
|
|
.word $082C ; CPU:$D883 PRG:1883 2C 08
|
|
|
|
;==============================================================================
|
|
; $D885-$D8D4: Entity Primary State $02 Handler
|
|
;==============================================================================
|
|
|
|
UpdateEntityState02:
|
|
lda #$00 ; CPU:$D885 PRG:1885 A9 00
|
|
tay ; CPU:$D887 PRG:1887 A8
|
|
sta $05 ; CPU:$D888 PRG:1888 85 05
|
|
|
|
lda #$80 ; CPU:$D88A PRG:188A A9 80
|
|
sta $06 ; CPU:$D88C PRG:188C 85 06
|
|
|
|
lda ($02),y ; CPU:$D88E PRG:188E B1 02
|
|
cmp #$60 ; CPU:$D890 PRG:1890 C9 60
|
|
beq UpdateEntityState02SecondaryPhase ; CPU:$D892 PRG:1892 F0 1E
|
|
|
|
bcc @D89C ; CPU:$D894 PRG:1894 90 06
|
|
|
|
dec $05 ; CPU:$D896 PRG:1896 C6 05
|
|
|
|
lda #$01 ; CPU:$D898 PRG:1898 A9 01
|
|
bne @D89E ; CPU:$D89A PRG:189A D0 02
|
|
|
|
@D89C:
|
|
lda #$03 ; CPU:$D89C PRG:189C A9 03
|
|
|
|
@D89E:
|
|
sta $B9,x ; CPU:$D89E PRG:189E 95 B9
|
|
|
|
ldy #$01 ; CPU:$D8A0 PRG:18A0 A0 01
|
|
|
|
lda ($02),y ; CPU:$D8A2 PRG:18A2 B1 02
|
|
clc ; CPU:$D8A4 PRG:18A4 18
|
|
adc $06 ; CPU:$D8A5 PRG:18A5 65 06
|
|
sta ($02),y ; CPU:$D8A7 PRG:18A7 91 02
|
|
|
|
ldy #$00 ; CPU:$D8A9 PRG:18A9 A0 00
|
|
|
|
lda ($02),y ; CPU:$D8AB PRG:18AB B1 02
|
|
adc $05 ; CPU:$D8AD PRG:18AD 65 05
|
|
sta ($02),y ; CPU:$D8AF PRG:18AF 91 02
|
|
|
|
rts ; CPU:$D8B1 PRG:18B1 60
|
|
|
|
|
|
;==============================================================================
|
|
; $D8B2-$D8D4: Entity State $02 Secondary Movement Phase
|
|
;==============================================================================
|
|
|
|
UpdateEntityState02SecondaryPhase:
|
|
lda #$00 ; CPU:$D8B2 PRG:18B2 A9 00
|
|
sta $B9,x ; CPU:$D8B4 PRG:18B4 95 B9
|
|
|
|
ldy #$03 ; CPU:$D8B6 PRG:18B6 A0 03
|
|
|
|
lda ($02),y ; CPU:$D8B8 PRG:18B8 B1 02
|
|
sec ; CPU:$D8BA PRG:18BA 38
|
|
sbc #$80 ; CPU:$D8BB PRG:18BB E9 80
|
|
sta ($02),y ; CPU:$D8BD PRG:18BD 91 02
|
|
|
|
ldy #$02 ; CPU:$D8BF PRG:18BF A0 02
|
|
|
|
lda ($02),y ; CPU:$D8C1 PRG:18C1 B1 02
|
|
sbc #$00 ; CPU:$D8C3 PRG:18C3 E9 00
|
|
sta ($02),y ; CPU:$D8C5 PRG:18C5 91 02
|
|
|
|
cmp #$58 ; CPU:$D8C7 PRG:18C7 C9 58
|
|
beq @D8CC ; CPU:$D8C9 PRG:18C9 F0 01
|
|
|
|
rts ; CPU:$D8CB PRG:18CB 60
|
|
|
|
@D8CC:
|
|
lda #$01 ; CPU:$D8CC PRG:18CC A9 01
|
|
sta $B9,x ; CPU:$D8CE PRG:18CE 95 B9
|
|
|
|
lda #$04 ; CPU:$D8D0 PRG:18D0 A9 04
|
|
sta $B8,x ; CPU:$D8D2 PRG:18D2 95 B8
|
|
|
|
rts ; CPU:$D8D4 PRG:18D4 60
|
|
|
|
|
|
;==============================================================================
|
|
; $D8D5-$D913: Entity Primary State $00 Handler
|
|
;
|
|
; Local:
|
|
; Initializes working movement values:
|
|
;
|
|
; $05 = $00
|
|
; $06 = $80
|
|
;
|
|
; Then uses the entity secondary state at $B9,X as a byte offset into a
|
|
; two-entry table at $D8EC.
|
|
;
|
|
; The selected subhandler adjusts bytes 3/2 of the current entity structure
|
|
; through $02/$03. When the resulting high byte crosses defined thresholds,
|
|
; $B9,X advances to secondary state $02 or resets to $00.
|
|
;
|
|
; Global:
|
|
; Handler selected by EntityStateTable for primary entity state $00.
|
|
;
|
|
; Notes:
|
|
; Unlike the $D5A1 secondary dispatcher, $B9,X is already treated as a byte
|
|
; offset here. Valid values are $00 and $02.
|
|
;==============================================================================
|
|
|
|
EntityState00:
|
|
lda #$00 ; CPU:$D8D5 PRG:18D5 A9 00
|
|
sta $05 ; CPU:$D8D7 PRG:18D7 85 05
|
|
|
|
lda #$80 ; CPU:$D8D9 PRG:18D9 A9 80
|
|
sta $06 ; CPU:$D8DB PRG:18DB 85 06
|
|
|
|
ldy $B9,x ; CPU:$D8DD PRG:18DD B4 B9
|
|
|
|
lda EntityState00SubstateTable,y ; CPU:$D8DF PRG:18DF B9 EC D8
|
|
sta $10 ; CPU:$D8E2 PRG:18E2 85 10
|
|
|
|
lda EntityState00SubstateTable+1,y ; CPU:$D8E4 PRG:18E4 B9 ED D8
|
|
sta $11 ; CPU:$D8E7 PRG:18E7 85 11
|
|
|
|
jmp ($0010) ; CPU:$D8E9 PRG:18E9 6C 10 00 F0 D8
|
|
|
|
|
|
;==============================================================================
|
|
; $D8EC-$D8EF: Entity State $00 Secondary Table
|
|
;==============================================================================
|
|
|
|
EntityState00SubstateTable:
|
|
.word UpdateEntityState00MovingNegative ; CPU:$D8EC PRG:18EC F0 D8
|
|
.word UpdateEntityState00MovingPositive ; CPU:$D8EE PRG:18EE F2 D8
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D8F0: secondary state $00
|
|
;------------------------------------------------------------------------------
|
|
|
|
UpdateEntityState00MovingNegative:
|
|
dec $05 ; CPU:$D8F0 PRG:18F0 C6 05
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $D8F2: secondary state $02
|
|
;------------------------------------------------------------------------------
|
|
|
|
UpdateEntityState00MovingPositive:
|
|
ldy #$03 ; CPU:$D8F2 PRG:18F2 A0 03
|
|
|
|
lda ($02),y ; CPU:$D8F4 PRG:18F4 B1 02
|
|
clc ; CPU:$D8F6 PRG:18F6 18
|
|
adc $06 ; CPU:$D8F7 PRG:18F7 65 06
|
|
sta ($02),y ; CPU:$D8F9 PRG:18F9 91 02
|
|
|
|
ldy #$02 ; CPU:$D8FB PRG:18FB A0 02
|
|
|
|
lda ($02),y ; CPU:$D8FD PRG:18FD B1 02
|
|
adc $05 ; CPU:$D8FF PRG:18FF 65 05
|
|
sta ($02),y ; CPU:$D901 PRG:1901 91 02
|
|
|
|
cmp #$69 ; CPU:$D903 PRG:1903 C9 69
|
|
bcs @D90B ; CPU:$D905 PRG:1905 B0 04
|
|
|
|
lda #$02 ; CPU:$D907 PRG:1907 A9 02
|
|
bne @D911 ; CPU:$D909 PRG:1909 D0 06
|
|
|
|
|
|
@D90B:
|
|
cmp #$70 ; CPU:$D90B PRG:190B C9 70
|
|
bcc @D913 ; CPU:$D90D PRG:190D 90 04
|
|
|
|
lda #$00 ; CPU:$D90F PRG:190F A9 00
|
|
|
|
@D911:
|
|
sta $B9,x ; CPU:$D911 PRG:1911 95 B9
|
|
|
|
@D913:
|
|
rts ; CPU:$D913 PRG:1913 60
|
|
;==============================================================================
|
|
; $D914-$D943: Update Four Gameplay Entity States
|
|
;
|
|
; Local:
|
|
; Iterates the four gameplay entity slots using even X offsets:
|
|
;
|
|
; $00,$02,$04,$06
|
|
;
|
|
; Initializes the same per-entity working values used by the other entity
|
|
; update coordinator:
|
|
;
|
|
; $00 = $2F
|
|
; $01 = $02
|
|
; $02 = $1E
|
|
; $03 = $00
|
|
; $04 = $01
|
|
;
|
|
; Calls the entity dispatcher at $D944 for each slot.
|
|
;
|
|
; After each call:
|
|
;
|
|
; $00 += 4
|
|
; $02 += 4
|
|
; $04 <<= 1
|
|
; X += 2
|
|
;
|
|
; Global:
|
|
; Called from GameModeState06 during its per-frame update sequence.
|
|
; Processes a second entity-state machine for all four gameplay entities.
|
|
;
|
|
; Notes:
|
|
; The layout closely parallels UpdateGameplayEntities at $D557, but uses
|
|
; a different dispatcher and therefore a different behavior set.
|
|
;==============================================================================
|
|
|
|
UpdateEntityMovementStates:
|
|
ldx #$00 ; CPU:$D914 PRG:1914 A2 00
|
|
|
|
lda #$2F ; CPU:$D916 PRG:1916 A9 2F
|
|
sta $00 ; CPU:$D918 PRG:1918 85 00
|
|
|
|
lda #$02 ; CPU:$D91A PRG:191A A9 02
|
|
sta $01 ; CPU:$D91C PRG:191C 85 01
|
|
|
|
lda #$1E ; CPU:$D91E PRG:191E A9 1E
|
|
sta $02 ; CPU:$D920 PRG:1920 85 02
|
|
|
|
lda #$00 ; CPU:$D922 PRG:1922 A9 00
|
|
sta $03 ; CPU:$D924 PRG:1924 85 03
|
|
|
|
lda #$01 ; CPU:$D926 PRG:1926 A9 01
|
|
sta $04 ; CPU:$D928 PRG:1928 85 04
|
|
|
|
@D92A:
|
|
jsr $D944 ; CPU:$D92A PRG:192A 20 44 D9
|
|
|
|
lda $00 ; CPU:$D92D PRG:192D A5 00
|
|
clc ; CPU:$D92F PRG:192F 18
|
|
adc #$04 ; CPU:$D930 PRG:1930 69 04
|
|
sta $00 ; CPU:$D932 PRG:1932 85 00
|
|
|
|
lda $02 ; CPU:$D934 PRG:1934 A5 02
|
|
clc ; CPU:$D936 PRG:1936 18
|
|
adc #$04 ; CPU:$D937 PRG:1937 69 04
|
|
sta $02 ; CPU:$D939 PRG:1939 85 02
|
|
|
|
asl $04 ; CPU:$D93B PRG:193B 06
|
|
|
|
inx ; CPU:$D93C PRG:193C 04
|
|
inx ; CPU:$D93D PRG:193D E8
|
|
|
|
cpx #$08 ; CPU:$D93E PRG:193E E8 E0
|
|
bne @D92A ; CPU:$D940 PRG:1940 08 D0
|
|
|
|
rts ; CPU:$D942 PRG:1942 E7
|
|
|
|
;==============================================================================
|
|
; $D944-$D952: Gameplay Entity Transition-State Dispatcher
|
|
;
|
|
; Local:
|
|
; Reads the current entity primary state from $B8,X and uses it directly as
|
|
; a byte offset into the packed pointer table at $D953.
|
|
;
|
|
; The selected 16-bit address is stored in $10/$11 and execution transfers
|
|
; to it through an indirect JMP.
|
|
;
|
|
; Global:
|
|
; Called by UpdateEntityMovementStates once for each of the four
|
|
; gameplay entity slots.
|
|
;
|
|
; Notes:
|
|
; X identifies the entity using even offsets:
|
|
;
|
|
; $00,$02,$04,$06
|
|
;
|
|
; $B8,X is itself an even byte offset into the pointer table:
|
|
;
|
|
; $00,$02,$04,$06,$08
|
|
;==============================================================================
|
|
|
|
DispatchEntityMovementState:
|
|
ldy $B8,x ; CPU:$D944 PRG:1944 B4 B8
|
|
|
|
lda EntityMovementStateHandlerTable,y ; CPU:$D946 PRG:1946 B9 53 D9
|
|
sta $10 ; CPU:$D949 PRG:1949 85 10
|
|
|
|
lda EntityMovementStateHandlerTable+1,y ; CPU:$D94B PRG:194B B9 54 D9
|
|
sta $11 ; CPU:$D94E PRG:194E 85 11
|
|
|
|
jmp ($0010) ; CPU:$D950 PRG:1950 6C 10 00 5D D9
|
|
|
|
|
|
;==============================================================================
|
|
; $D953-$D95C: Gameplay Entity Transition-State Table
|
|
;
|
|
; Local:
|
|
; Five 16-bit handlers indexed directly by the entity primary state stored
|
|
; in $B8,X.
|
|
;
|
|
; Global:
|
|
; Defines the per-entity behavior used by
|
|
; DispatchEntityMovementState.
|
|
;
|
|
; Notes:
|
|
; States $00, $02, $04 and $08 all use the same handler at $D95D.
|
|
;
|
|
; State $06 reuses DispatchEntitySecondaryState at $D5A1.
|
|
;==============================================================================
|
|
|
|
EntityMovementStateHandlerTable:
|
|
.word EntityMovementStateNoOp ; state $00 ; CPU:$D953 PRG:1953 5D D9
|
|
.word EntityMovementStateNoOp ; state $02 ; CPU:$D955 PRG:1955 5D D9
|
|
.word EntityMovementStateNoOp ; state $04 ; CPU:$D957 PRG:1957 5D D9
|
|
.word DispatchEntitySecondaryState ; state $06 ; CPU:$D959 PRG:1959 A1 D5
|
|
.word EntityMovementStateNoOp ; state $08 ; CPU:$D95B PRG:195B 5D D9
|
|
|
|
;==============================================================================
|
|
; $D95D: No-Op Entity Transition Handler
|
|
;
|
|
; Local:
|
|
; Returns immediately.
|
|
;
|
|
; Global:
|
|
; Used by EntityMovementStateHandlerTable for primary entity states
|
|
; $00, $02, $04 and $08.
|
|
;==============================================================================
|
|
EntityMovementStateNoOp:
|
|
rts ; CPU:$D95D PRG:195D 60
|
|
|
|
;==============================================================================
|
|
; $D95E-$D979: Check Entity Transition State
|
|
;
|
|
; Local:
|
|
; Scans the four primary entity-state entries at:
|
|
;
|
|
; $B8,$BA,$BC,$BE
|
|
;
|
|
; If any entity is in primary state $06, stores the current A value
|
|
; ($06 from the CMP) into $0608 and returns.
|
|
;
|
|
; If no entity is in state $06, tests $88. When $88 is nonzero, stores that
|
|
; value into $0609 before returning.
|
|
;
|
|
; Global:
|
|
; Called during normal gameplay processing. Exports entity/state conditions
|
|
; to RAM $0608/$0609 for use by other gameplay systems.
|
|
;
|
|
; Notes:
|
|
; $00 is initialized but not subsequently used inside this routine in the
|
|
; decoded path. Preserve the write because another overlapping entry or
|
|
; external expectation may depend on it.
|
|
;==============================================================================
|
|
|
|
UpdateEntityStatusFlags:
|
|
ldx #$00 ; CPU:$D95E PRG:195E A2 00
|
|
stx $00 ; CPU:$D960 PRG:1960 86 00
|
|
|
|
@D962:
|
|
lda $B8,x ; CPU:$D962 PRG:1962 B5 B8
|
|
cmp #$06 ; CPU:$D964 PRG:1964 C9 06
|
|
bne @D96C ; CPU:$D966 PRG:1966 D0 04
|
|
|
|
sta $0608 ; CPU:$D968 PRG:1968 8D 08 06
|
|
rts ; CPU:$D96B PRG:196B 60
|
|
|
|
@D96C:
|
|
inx ; CPU:$D96C PRG:196C E8
|
|
inx ; CPU:$D96D PRG:196D E8
|
|
|
|
cpx #$08 ; CPU:$D96E PRG:196E E0 08
|
|
bne @D962 ; CPU:$D970 PRG:1970 D0 F0
|
|
|
|
lda $88 ; CPU:$D972 PRG:1972 A5 88
|
|
beq UpdatePlayerVerticalRegionFlag ; CPU:$D974 PRG:1974 F0 04
|
|
|
|
sta $0609 ; CPU:$D976 PRG:1976 8D 09 06
|
|
|
|
rts ; CPU:$D979 PRG:1979 60
|
|
|
|
;==============================================================================
|
|
; $D97A-$D98D: Update Gameplay Range Flag
|
|
;==============================================================================
|
|
UpdatePlayerVerticalRegionFlag:
|
|
ldy #$00 ; CPU:$D97A PRG:197A A0 00
|
|
|
|
lda $6A ; CPU:$D97C PRG:197C A5 6A
|
|
cmp #$88 ; CPU:$D97E PRG:197E C9 88
|
|
bcs @D988 ; CPU:$D980 PRG:1980 B0 06
|
|
|
|
iny ; CPU:$D982 PRG:1982 C8
|
|
|
|
cmp #$42 ; CPU:$D983 PRG:1983 C9 42
|
|
bcs @D988 ; CPU:$D985 PRG:1985 B0 01
|
|
|
|
iny ; CPU:$D987 PRG:1987 C8
|
|
|
|
@D988:
|
|
lda #$01 ; CPU:$D988 PRG:1988 A9 01
|
|
sta $060A,y ; CPU:$D98A PRG:198A 99 0A 06
|
|
|
|
rts ; CPU:$D98D PRG:198D 60
|
|
|
|
;==============================================================================
|
|
; $D98E-$D9C5: Update Direction-Dependent Gameplay Value
|
|
;
|
|
; Local:
|
|
; Builds a base value from the current direction $51, then selects an
|
|
; additional offset based on coordinate alignment, tile state, and $B7.
|
|
;
|
|
; The resulting value is stored in $32.
|
|
;
|
|
; Notes:
|
|
; Address-derived labels preserve the original compact control flow.
|
|
;==============================================================================
|
|
|
|
UpdatePlayerDirectionAnimation:
|
|
lda $51 ; CPU:$D98E PRG:198E A5 51
|
|
asl ; CPU:$D990 PRG:1990 0A
|
|
clc ; CPU:$D991 PRG:1991 18
|
|
adc #$02 ; CPU:$D992 PRG:1992 69 02
|
|
sta $00 ; CPU:$D994 PRG:1994 85 00
|
|
|
|
lda $1A ; CPU:$D996 PRG:1996 A5 1A
|
|
ora $1C ; CPU:$D998 PRG:1998 05 1C
|
|
and #$07 ; CPU:$D99A PRG:199A 29 07
|
|
bne @D9AE ; CPU:$D99C PRG:199C D0 10
|
|
|
|
ldy $51 ; CPU:$D99E PRG:199E A4 51
|
|
|
|
lda $022B,y ; CPU:$D9A0 PRG:19A0 B9 2B 02
|
|
and #$F0 ; CPU:$D9A3 PRG:19A3 29 F0
|
|
beq @D9AE ; CPU:$D9A5 PRG:19A5 F0 07
|
|
|
|
lda $B7 ; CPU:$D9A7 PRG:19A7 A5 B7
|
|
and #$03 ; CPU:$D9A9 PRG:19A9 29 03
|
|
jmp @D9B2 ; CPU:$D9AB PRG:19AB 4C B2 D9
|
|
|
|
|
|
@D9AE:
|
|
inc $B7 ; CPU:$D9AE PRG:19AE E6 B7
|
|
|
|
lda $B7 ; CPU:$D9B0 PRG:19B0 A5 B7
|
|
|
|
@D9B2:
|
|
and #$07 ; CPU:$D9B2 PRG:19B2 29 07
|
|
cmp #$06 ; CPU:$D9B4 PRG:19B4 C9 06
|
|
bcc @D9BC ; CPU:$D9B6 PRG:19B6 90 04
|
|
|
|
lda #$01 ; CPU:$D9B8 PRG:19B8 A9 01
|
|
bne @D9C3 ; CPU:$D9BA PRG:19BA D0 07
|
|
|
|
|
|
@D9BC:
|
|
tay ; CPU:$D9BC PRG:19BC A8
|
|
|
|
lda PlayerDirectionAnimationOffsets,y ; CPU:$D9BD PRG:19BD B9 C6 D9
|
|
clc ; CPU:$D9C0 PRG:19C0 18
|
|
adc $00 ; CPU:$D9C1 PRG:19C1 65 00
|
|
|
|
|
|
@D9C3:
|
|
sta $32 ; CPU:$D9C3 PRG:19C3 85 32
|
|
|
|
rts ; CPU:$D9C5 PRG:19C5 60
|
|
|
|
;==============================================================================
|
|
; $D9C6-$D9CB: Direction-Value Offset Table
|
|
;
|
|
; Local:
|
|
; Six values indexed by $B7 & $07 when that result is less than six.
|
|
;
|
|
; Global:
|
|
; Provides the small offset added to the direction-derived base before the
|
|
; result is stored in $32.
|
|
;==============================================================================
|
|
|
|
PlayerDirectionAnimationOffsets:
|
|
.byte $00,$00,$00,$01,$01,$00 ; CPU:$D9C6 PRG:19C6 00 00 00 01 01 00
|
|
|
|
;==============================================================================
|
|
; $D9CC-$D9EA: Update Four Entity Display/State Values
|
|
;
|
|
; Local:
|
|
; Initializes:
|
|
;
|
|
; X = $00
|
|
; $00 = $00 or $01 depending on frame-counter bit 3
|
|
; $01 = $01
|
|
;
|
|
; Then iterates the four entity slots:
|
|
;
|
|
; X = $00,$02,$04,$06
|
|
;
|
|
; For each entity:
|
|
; - Calls the dispatcher at $D9EB.
|
|
; - Shifts $01 left once, producing per-entity masks:
|
|
;
|
|
; $01,$02,$04,$08
|
|
;
|
|
; - Advances X by two.
|
|
;
|
|
; Global:
|
|
; Called from several game-mode states and during normal gameplay. Provides
|
|
; per-frame updates for all four gameplay entities, with an alternating
|
|
; phase selected from frame-counter bit 3.
|
|
;
|
|
; Notes:
|
|
; $4B is the NMI-driven frame counter.
|
|
; $00 is a two-phase animation/control value.
|
|
; $01 is the current entity bitmask.
|
|
;==============================================================================
|
|
|
|
UpdateEntitySpriteStates:
|
|
lda #$00 ; CPU:$D9CC PRG:19CC A9 00
|
|
tax ; CPU:$D9CE PRG:19CE AA
|
|
sta $00 ; CPU:$D9CF PRG:19CF 85 00
|
|
|
|
lda $4B ; CPU:$D9D1 PRG:19D1 A5 4B
|
|
and #$08 ; CPU:$D9D3 PRG:19D3 29 08
|
|
beq @D9DC ; CPU:$D9D5 PRG:19D5 F0 04
|
|
|
|
lda #$01 ; CPU:$D9D7 PRG:19D7 A9 01
|
|
sta $00 ; CPU:$D9D9 PRG:19D9 85 00
|
|
|
|
|
|
@D9DC:
|
|
lda #$01 ; CPU:$D9DB PRG:19DB A9 01
|
|
sta $01 ; CPU:$D9DD PRG:19DD 85 01
|
|
|
|
|
|
@D9E0:
|
|
jsr $D9EB ; CPU:$D9DF PRG:19DF 20 EB D9
|
|
|
|
asl $01 ; CPU:$D9E2 PRG:19E2 06
|
|
|
|
inx ; CPU:$D9E3 PRG:19E3 01
|
|
inx ; CPU:$D9E4 PRG:19E4 E8
|
|
|
|
cpx #$08 ; CPU:$D9E5 PRG:19E5 E8 E0
|
|
bne @D9E0 ; CPU:$D9E7 PRG:19E7 08 D0
|
|
|
|
rts ; CPU:$D9E9 PRG:19E9 F5
|
|
|
|
|
|
;==============================================================================
|
|
; $D9EB-$D9F9: Per-Entity Display/State Dispatcher
|
|
;==============================================================================
|
|
|
|
DispatchEntitySpriteState:
|
|
ldy $B8,x ; CPU:$D9EB PRG:19EB B4 B8
|
|
|
|
lda EntitySpriteStateHandlerTable,y ; CPU:$D9ED PRG:19ED B9 FA D9
|
|
sta $10 ; CPU:$D9F0 PRG:19F0 85 10
|
|
|
|
lda EntitySpriteStateHandlerTable+1,y ; CPU:$D9F2 PRG:19F2 B9 FB D9
|
|
sta $11 ; CPU:$D9F5 PRG:19F5 85 11
|
|
|
|
jmp ($0010) ; CPU:$D9F7 PRG:19F7 6C 10 00 21 DA
|
|
|
|
|
|
;==============================================================================
|
|
; $D9FA-$DA03: Entity Display/State Table
|
|
;==============================================================================
|
|
EntitySpriteStateHandlerTable:
|
|
.word UpdateNormalEntitySprite ; state $00 ; CPU:$D9FA PRG:19FA 21 DA
|
|
.word UpdateNormalEntitySprite ; state $02 ; CPU:$D9FC PRG:19FC 21 DA
|
|
.word UpdateNormalEntitySprite ; state $04 ; CPU:$D9FE PRG:19FE 21 DA
|
|
.word UpdateSpecialEntitySprite ; state $06 ; CPU:$DA00 PRG:1A00 2D DA
|
|
.word $D9EA ; state $08 -> shared RTS ; CPU:$DA02 PRG:1A02 EA D9
|
|
|
|
;==============================================================================
|
|
; $DA04-$DA3F: Entity Display/State Value Handlers
|
|
;
|
|
; Local:
|
|
; Three entry points used by EntitySpriteStateHandlerTable:
|
|
;
|
|
; $DA21 primary states $00/$02/$04
|
|
; $DA2D primary state $06
|
|
;
|
|
; $DA04 is shared calculation code entered by those handlers.
|
|
;
|
|
; Each path computes a value from the entity secondary state $B9,X, combines
|
|
; it with a base value, and stores the final result into one of $33-$36
|
|
; according to the current entity index X.
|
|
;
|
|
; Global:
|
|
; Produces per-entity display/state values during UpdateEntitySpriteStates.
|
|
;
|
|
; Notes:
|
|
; X is an even entity index ($00,$02,$04,$06). TXA/LSR converts this into
|
|
; the ordinal entity index 0-3 for the final store at $33,Y.
|
|
;==============================================================================
|
|
|
|
;==============================================================================
|
|
; $DA04-$DA3F: Entity Display/State Value Handlers
|
|
;
|
|
; Local:
|
|
; Shared calculations used by the per-entity display/state dispatcher.
|
|
;
|
|
; Global:
|
|
; UpdateNormalEntitySprite handles primary states $00/$02/$04.
|
|
; UpdateSpecialEntitySprite handles primary state $06.
|
|
;
|
|
; Notes:
|
|
; Non-local labels are intentional because multiple handler entry points
|
|
; branch backward into shared code.
|
|
;==============================================================================
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DA04
|
|
;------------------------------------------------------------------------------
|
|
|
|
CalculateEntitySpriteValue:
|
|
lda $B9,x ; CPU:$DA04 PRG:1A04 B5 B9
|
|
sta $03 ; CPU:$DA06 PRG:1A06 85 03
|
|
|
|
lda #$0A ; CPU:$DA08 PRG:1A08 A9 0A
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DA0A
|
|
;------------------------------------------------------------------------------
|
|
|
|
CalculateEntitySpriteValueLoop:
|
|
dec $03 ; CPU:$DA0A PRG:1A0A C6 03
|
|
bmi AddEntitySpriteBase ; CPU:$DA0C PRG:1A0C 30 05
|
|
|
|
clc ; CPU:$DA0E PRG:1A0E 18
|
|
adc #$02 ; CPU:$DA0F PRG:1A0F 69 02
|
|
bne CalculateEntitySpriteValueLoop ; CPU:$DA11 PRG:1A11 D0 F7
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DA13
|
|
;------------------------------------------------------------------------------
|
|
|
|
AddEntitySpriteBase:
|
|
clc ; CPU:$DA13 PRG:1A13 18
|
|
adc $00 ; CPU:$DA14 PRG:1A14 65 00
|
|
sta $02 ; CPU:$DA16 PRG:1A16 85 02
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DA18
|
|
;------------------------------------------------------------------------------
|
|
|
|
StoreEntitySpriteValue:
|
|
txa ; CPU:$DA18 PRG:1A18 8A
|
|
lsr ; CPU:$DA19 PRG:1A19 4A
|
|
tay ; CPU:$DA1A PRG:1A1A A8
|
|
|
|
lda $02 ; CPU:$DA1B PRG:1A1B A5 02
|
|
sta $0033,y ; CPU:$DA1D PRG:1A1D 99 33 00
|
|
|
|
rts ; CPU:$DA20 PRG:1A20 60
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DA21
|
|
; Primary entity states $00/$02/$04.
|
|
;------------------------------------------------------------------------------
|
|
|
|
UpdateNormalEntitySprite:
|
|
lda $01 ; CPU:$DA21 PRG:1A21 A5 01
|
|
and $88 ; CPU:$DA23 PRG:1A23 25 88
|
|
beq CalculateEntitySpriteValue ; CPU:$DA25 PRG:1A25 F0 DD
|
|
|
|
lda #$1E ; CPU:$DA27 PRG:1A27 A9 1E
|
|
sta $02 ; CPU:$DA29 PRG:1A29 85 02
|
|
|
|
bne AddEntitySpriteBase ; CPU:$DA2B PRG:1A2B D0 E6
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DA2D
|
|
; Primary entity state $06.
|
|
;------------------------------------------------------------------------------
|
|
|
|
UpdateSpecialEntitySprite:
|
|
lda $B9,x ; CPU:$DA2D PRG:1A2D B5 B9
|
|
sta $03 ; CPU:$DA2F PRG:1A2F 85 03
|
|
|
|
lda #$20 ; CPU:$DA31 PRG:1A31 A9 20
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DA33
|
|
;------------------------------------------------------------------------------
|
|
|
|
UpdateSpecialEntitySpriteLoop:
|
|
dec $03 ; CPU:$DA33 PRG:1A33 C6 03
|
|
bmi UpdateSpecialEntitySpriteDone ; CPU:$DA35 PRG:1A35 30 05
|
|
|
|
clc ; CPU:$DA37 PRG:1A37 18
|
|
adc #$01 ; CPU:$DA38 PRG:1A38 69 01
|
|
bne UpdateSpecialEntitySpriteLoop ; CPU:$DA3A PRG:1A3A D0 F7
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DA3C
|
|
;------------------------------------------------------------------------------
|
|
|
|
UpdateSpecialEntitySpriteDone:
|
|
sta $02 ; CPU:$DA3C PRG:1A3C 85 02
|
|
|
|
bmi StoreEntitySpriteValue ; CPU:$DA3E PRG:1A3E 30 D8
|
|
|
|
;==============================================================================
|
|
; $DA40-$DAF0: Gameplay Entity Collision / Slot Exchange
|
|
;
|
|
; Local:
|
|
; Copies $24 bytes from zero-page $1A-$3D to RAM $0274-$0297.
|
|
;
|
|
; Then initializes an indirect pointer to $0284 and scans entity structures
|
|
; while testing them against the primary coordinate pair at $0274/$0276.
|
|
;
|
|
; For each enabled entity, computes absolute coordinate differences. If both
|
|
; axes are within $19 and their combined distance is below $10, exchanges
|
|
; coordinate and associated state fields between the primary slot and the
|
|
; selected entity slot.
|
|
;
|
|
; If no qualifying overlap is found, advances the structure pointer backward
|
|
; by four bytes, shifts the per-entity mask, and continues.
|
|
;
|
|
; Global:
|
|
; Called in several game-mode states and during normal gameplay. Maintains
|
|
; the mirrored gameplay/object state in $0274+ and handles close-overlap
|
|
; exchanges between entity slots.
|
|
;
|
|
; Notes:
|
|
; $00/$01 form a temporary pointer, initially $0284.
|
|
; $02 counts entity slots.
|
|
; $03 is a bitmask, initially $08.
|
|
; $04-$06 are temporary coordinate/state values during a swap.
|
|
;
|
|
; $DAF1 is a separate routine and is not included in this block.
|
|
;==============================================================================
|
|
|
|
CheckEntityCollisions:
|
|
ldx #$23 ; CPU:$DA40 PRG:1A40 A2 23
|
|
|
|
@CopyWorkingState:
|
|
lda $1A,x ; CPU:$DA42 PRG:1A42 B5 1A
|
|
sta $0274,x ; CPU:$DA44 PRG:1A44 9D 74 02
|
|
|
|
dex ; CPU:$DA47 PRG:1A47 CA
|
|
bpl @CopyWorkingState ; CPU:$DA48 PRG:1A48 10 F8
|
|
|
|
lda #$84 ; CPU:$DA4A PRG:1A4A A9 84
|
|
sta $00 ; CPU:$DA4C PRG:1A4C 85 00
|
|
|
|
lda #$02 ; CPU:$DA4E PRG:1A4E A9 02
|
|
sta $01 ; CPU:$DA50 PRG:1A50 85 01
|
|
|
|
lda #$08 ; CPU:$DA52 PRG:1A52 A9 08
|
|
sta $03 ; CPU:$DA54 PRG:1A54 85 03
|
|
|
|
lda #$03 ; CPU:$DA56 PRG:1A56 A9 03
|
|
sta $02 ; CPU:$DA58 PRG:1A58 85 02
|
|
|
|
|
|
@CheckNextEntity:
|
|
lda $03 ; CPU:$DA5A PRG:1A5A A5 03
|
|
and $88 ; CPU:$DA5C PRG:1A5C 25 88
|
|
bne @AdvanceEntity ; CPU:$DA5E PRG:1A5E D0 7B
|
|
|
|
ldy #$00 ; CPU:$DA60 PRG:1A60 A0 00
|
|
|
|
lda $0274 ; CPU:$DA62 PRG:1A62 AD 74 02
|
|
cmp ($00),y ; CPU:$DA65 PRG:1A65 D1 00
|
|
bcs @FirstAxisReverse ; CPU:$DA67 PRG:1A67 B0 08
|
|
|
|
lda ($00),y ; CPU:$DA69 PRG:1A69 B1 00
|
|
sec ; CPU:$DA6B PRG:1A6B 38
|
|
sbc $0274 ; CPU:$DA6C PRG:1A6C ED 74 02
|
|
bcs @CheckFirstAxis ; CPU:$DA6F PRG:1A6F B0 02
|
|
|
|
@FirstAxisReverse:
|
|
sbc ($00),y ; CPU:$DA71 PRG:1A71 F1 00
|
|
|
|
@CheckFirstAxis:
|
|
cmp #$19 ; CPU:$DA73 PRG:1A73 C9 19
|
|
bcs @AdvanceEntity ; CPU:$DA75 PRG:1A75 B0 64
|
|
|
|
sta $04 ; CPU:$DA77 PRG:1A77 85 04
|
|
|
|
ldy #$02 ; CPU:$DA79 PRG:1A79 A0 02
|
|
|
|
lda $0276 ; CPU:$DA7B PRG:1A7B AD 76 02
|
|
cmp ($00),y ; CPU:$DA7E PRG:1A7E D1 00
|
|
bcs @SecondAxisReverse ; CPU:$DA80 PRG:1A80 B0 08
|
|
|
|
lda ($00),y ; CPU:$DA82 PRG:1A82 B1 00
|
|
sec ; CPU:$DA84 PRG:1A84 38
|
|
sbc $0276 ; CPU:$DA85 PRG:1A85 ED 76 02
|
|
bcs @CheckSecondAxis ; CPU:$DA88 PRG:1A88 B0 02
|
|
|
|
@SecondAxisReverse:
|
|
sbc ($00),y ; CPU:$DA8A PRG:1A8A F1 00
|
|
|
|
@CheckSecondAxis:
|
|
cmp #$19 ; CPU:$DA8C PRG:1A8C C9 19
|
|
bcs @AdvanceEntity ; CPU:$DA8E PRG:1A8E B0 4B
|
|
|
|
adc $04 ; CPU:$DA90 PRG:1A90 65 04
|
|
cmp #$10 ; CPU:$DA92 PRG:1A92 C9 10
|
|
bcs @AdvanceEntity ; CPU:$DA94 PRG:1A94 B0 45
|
|
|
|
; Save the primary slot coordinates/state.
|
|
lda $0274 ; CPU:$DA96 PRG:1A96 AD 74 02
|
|
sta $03 ; CPU:$DA99 PRG:1A99 85 03
|
|
|
|
lda $0276 ; CPU:$DA9B PRG:1A9B AD 76 02
|
|
sta $04 ; CPU:$DA9E PRG:1A9E 85 04
|
|
|
|
lda $028C ; CPU:$DAA0 PRG:1AA0 AD 8C 02
|
|
sta $05 ; CPU:$DAA3 PRG:1AA3 85 05
|
|
|
|
lda $0292 ; CPU:$DAA5 PRG:1AA5 AD 92 02
|
|
sta $06 ; CPU:$DAA8 PRG:1AA8 85 06
|
|
|
|
; Copy selected entity coordinates into the primary slot.
|
|
ldy #$00 ; CPU:$DAAA PRG:1AAA A0 00
|
|
lda ($00),y ; CPU:$DAAC PRG:1AAC B1 00
|
|
sta $0274 ; CPU:$DAAE PRG:1AAE 8D 74 02
|
|
|
|
lda $03 ; CPU:$DAB1 PRG:1AB1 A5 03
|
|
sta ($00),y ; CPU:$DAB3 PRG:1AB3 91 00
|
|
|
|
ldy #$02 ; CPU:$DAB5 PRG:1AB5 A0 02
|
|
lda ($00),y ; CPU:$DAB7 PRG:1AB7 B1 00
|
|
sta $0276 ; CPU:$DAB9 PRG:1AB9 8D 76 02
|
|
|
|
lda $04 ; CPU:$DABC PRG:1ABC A5 04
|
|
sta ($00),y ; CPU:$DABE PRG:1ABE 91 00
|
|
|
|
; Exchange the parallel status values.
|
|
ldx $02 ; CPU:$DAC0 PRG:1AC0 A6 02
|
|
|
|
lda $028D,x ; CPU:$DAC2 PRG:1AC2 BD 8D 02
|
|
sta $028C ; CPU:$DAC5 PRG:1AC5 8D 8C 02
|
|
|
|
lda $05 ; CPU:$DAC8 PRG:1AC8 A5 05
|
|
sta $028D,x ; CPU:$DACA PRG:1ACA 9D 8D 02
|
|
|
|
lda $0293,x ; CPU:$DACD PRG:1ACD BD 93 02
|
|
sta $0292 ; CPU:$DAD0 PRG:1AD0 8D 92 02
|
|
|
|
lda $06 ; CPU:$DAD3 PRG:1AD3 A5 06
|
|
sta $0293,x ; CPU:$DAD5 PRG:1AD5 9D 93 02
|
|
|
|
jmp $DAEB ; CPU:$DAD8 PRG:1AD8 4C EB DA
|
|
|
|
|
|
@AdvanceEntity:
|
|
lda $00 ; CPU:$DADB PRG:1ADB A5 00
|
|
sec ; CPU:$DADD PRG:1ADD 38
|
|
sbc #$04 ; CPU:$DADE PRG:1ADE E9 04
|
|
sta $00 ; CPU:$DAE0 PRG:1AE0 85 00
|
|
|
|
lsr $03 ; CPU:$DAE2 PRG:1AE2 46
|
|
|
|
dec $02 ; CPU:$DAE3 PRG:1AE3 03 C6
|
|
bmi @NoCollision ; CPU:$DAE5 PRG:1AE5 02 30
|
|
|
|
jmp @CheckNextEntity ; CPU:$DAE7 PRG:1AE7 03 4C 5A
|
|
|
|
|
|
@NoCollision:
|
|
jsr $E1DA ; CPU:$DAEA PRG:1AEA DA 20 DA
|
|
|
|
jmp $DAF1 ; CPU:$DAED PRG:1AED E1 4C F1
|
|
|
|
;==============================================================================
|
|
; $DAF1-$DBEE: Rebuild Gameplay Entity Render Data
|
|
;
|
|
; Local:
|
|
; Builds four-byte render/object records in page $07 from mirrored gameplay
|
|
; state beginning at $0274.
|
|
;
|
|
; Working variables:
|
|
;
|
|
; $00/$01 = source pointer, initially $0274
|
|
; $02/$03 = destination pointer, initially $0700
|
|
; $04 = source-group index
|
|
; $05 = record/lookup index
|
|
; $06 = temporary lookup index
|
|
;
|
|
; X advances through even entity offsets $00,$02,$04,$06.
|
|
;
|
|
; Encoded state values at $028C+ determine which lookup-table path is used
|
|
; to construct bytes 1 and 2 of each four-byte output record.
|
|
;
|
|
; Global:
|
|
; Called by several gameplay paths to rebuild the page-$07 representation
|
|
; used by the rendering/object pipeline.
|
|
;
|
|
; Notes:
|
|
; Several ROM tables referenced here remain undecoded:
|
|
;
|
|
; $DBEE
|
|
; $DCEE
|
|
; $DD22
|
|
; EntitySpriteAttributeTable0
|
|
; EntitySpriteCoordinateOffsets
|
|
; $DE57
|
|
;
|
|
; $DBEE is particularly interesting because it is also the RTS terminating
|
|
; this routine. The ROM intentionally uses that address as both executable
|
|
; code and the base of a later indexed lookup.
|
|
;==============================================================================
|
|
BuildEntitySpriteBuffer:
|
|
lda #$74 ; CPU:$DAF1 PRG:1AF1 A9 74
|
|
sta $00 ; CPU:$DAF3 PRG:1AF3 85 00
|
|
|
|
lda #$02 ; CPU:$DAF5 PRG:1AF5 A9 02
|
|
sta $01 ; CPU:$DAF7 PRG:1AF7 85 01
|
|
|
|
lda #$00 ; CPU:$DAF9 PRG:1AF9 A9 00
|
|
sta $02 ; CPU:$DAFB PRG:1AFB 85 02
|
|
|
|
lda #$07 ; CPU:$DAFD PRG:1AFD A9 07
|
|
sta $03 ; CPU:$DAFF PRG:1AFF 85 03
|
|
|
|
lda #$00 ; CPU:$DB01 PRG:1B01 A9 00
|
|
sta $04 ; CPU:$DB03 PRG:1B03 85 04
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DB05
|
|
; Start/restart one source group.
|
|
;------------------------------------------------------------------------------
|
|
|
|
BuildSpriteBufferNextGroup:
|
|
lda #$00 ; CPU:$DB05 PRG:1B05 A9 00
|
|
sta $05 ; CPU:$DB07 PRG:1B07 85 05
|
|
|
|
tax ; CPU:$DB09 PRG:1B09 AA
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DB0A
|
|
; Build one four-byte render record.
|
|
;------------------------------------------------------------------------------
|
|
|
|
BuildSpriteBufferNextSprite:
|
|
ldy #$02 ; CPU:$DB0A PRG:1B0A A0 02
|
|
|
|
lda ($00),y ; CPU:$DB0C PRG:1B0C B1 00
|
|
bne AdjustSpriteY ; CPU:$DB0E PRG:1B0E D0 04
|
|
|
|
lda #$FF ; CPU:$DB10 PRG:1B10 A9 FF
|
|
bne StoreSpriteY ; CPU:$DB12 PRG:1B12 D0 04
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DB14
|
|
;------------------------------------------------------------------------------
|
|
|
|
AdjustSpriteY:
|
|
clc ; CPU:$DB14 PRG:1B14 18
|
|
adc EntitySpriteCoordinateOffsets,x ; CPU:$DB15 PRG:1B15 7D 56 DE
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DB18
|
|
;------------------------------------------------------------------------------
|
|
|
|
StoreSpriteY:
|
|
ldy #$00 ; CPU:$DB18 PRG:1B18 A0 00
|
|
sta ($02),y ; CPU:$DB1A PRG:1B1A 91 02
|
|
|
|
ldy $04 ; CPU:$DB1C PRG:1B1C A4 04
|
|
|
|
lda $028C,y ; CPU:$DB1E PRG:1B1E B9 8C 02
|
|
asl ; CPU:$DB21 PRG:1B21 0A
|
|
rol ; CPU:$DB22 PRG:1B22 2A
|
|
rol ; CPU:$DB23 PRG:1B23 2A
|
|
and #$03 ; CPU:$DB24 PRG:1B24 29 03
|
|
|
|
beq BuildSpriteClass0 ; CPU:$DB26 PRG:1B26 F0 29
|
|
|
|
cmp #$02 ; CPU:$DB28 PRG:1B28 C9 02
|
|
beq BuildSpriteClass2 ; CPU:$DB2A PRG:1B2A F0 6B
|
|
|
|
bcc BuildSpriteClass1 ; CPU:$DB2C PRG:1B2C 90 46
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DB2E
|
|
; Status-class path.
|
|
;------------------------------------------------------------------------------
|
|
|
|
lda $028C,y ; CPU:$DB2E PRG:1B2E B9 8C 02
|
|
asl ; CPU:$DB31 PRG:1B31 0A
|
|
asl ; CPU:$DB32 PRG:1B32 0A
|
|
clc ; CPU:$DB33 PRG:1B33 18
|
|
adc $05 ; CPU:$DB34 PRG:1B34 65 05
|
|
tay ; CPU:$DB36 PRG:1B36 A8
|
|
|
|
sta $06 ; CPU:$DB37 PRG:1B37 85 06
|
|
|
|
lda $DD22,y ; CPU:$DB39 PRG:1B39 B9 22 DD
|
|
|
|
ldy #$01 ; CPU:$DB3C PRG:1B3C A0 01
|
|
sta ($02),y ; CPU:$DB3E PRG:1B3E 91 02
|
|
|
|
ldy $04 ; CPU:$DB40 PRG:1B40 A4 04
|
|
lda $0292,y ; CPU:$DB42 PRG:1B42 B9 92 02
|
|
|
|
ldy $06 ; CPU:$DB45 PRG:1B45 A4 06
|
|
ora EntitySpriteCoordinateOffsets,y ; CPU:$DB47 PRG:1B47 19 56 DE
|
|
|
|
ldy #$02 ; CPU:$DB4A PRG:1B4A A0 02
|
|
sta ($02),y ; CPU:$DB4C PRG:1B4C 91 02
|
|
|
|
jmp BuildSpriteX ; CPU:$DB4E PRG:1B4E 4C B7 DB
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DB51
|
|
;------------------------------------------------------------------------------
|
|
|
|
BuildSpriteClass0:
|
|
lda $028C,y ; CPU:$DB51 PRG:1B51 B9 8C 02
|
|
asl ; CPU:$DB54 PRG:1B54 0A
|
|
asl ; CPU:$DB55 PRG:1B55 0A
|
|
clc ; CPU:$DB56 PRG:1B56 18
|
|
adc $05 ; CPU:$DB57 PRG:1B57 65 05
|
|
tay ; CPU:$DB59 PRG:1B59 A8
|
|
|
|
sta $06 ; CPU:$DB5A PRG:1B5A 85 06
|
|
|
|
lda $DBEE,y ; CPU:$DB5C PRG:1B5C B9 EE DB
|
|
|
|
ldy #$01 ; CPU:$DB5F PRG:1B5F A0 01
|
|
sta ($02),y ; CPU:$DB61 PRG:1B61 91 02
|
|
|
|
ldy $04 ; CPU:$DB63 PRG:1B63 A4 04
|
|
lda $0292,y ; CPU:$DB65 PRG:1B65 B9 92 02
|
|
|
|
ldy $06 ; CPU:$DB68 PRG:1B68 A4 06
|
|
ora $DD22,y ; CPU:$DB6A PRG:1B6A 19 22 DD
|
|
|
|
ldy #$02 ; CPU:$DB6D PRG:1B6D A0 02
|
|
sta ($02),y ; CPU:$DB6F PRG:1B6F 91 02
|
|
|
|
jmp BuildSpriteX ; CPU:$DB71 PRG:1B71 4C B7 DB
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DB74
|
|
;------------------------------------------------------------------------------
|
|
|
|
BuildSpriteClass1:
|
|
lda $028C,y ; CPU:$DB74 PRG:1B74 B9 8C 02
|
|
asl ; CPU:$DB77 PRG:1B77 0A
|
|
asl ; CPU:$DB78 PRG:1B78 0A
|
|
clc ; CPU:$DB79 PRG:1B79 18
|
|
adc $05 ; CPU:$DB7A PRG:1B7A 65 05
|
|
tay ; CPU:$DB7C PRG:1B7C A8
|
|
|
|
sta $06 ; CPU:$DB7D PRG:1B7D 85 06
|
|
|
|
lda $DCEE,y ; CPU:$DB7F PRG:1B7F B9 EE DC
|
|
|
|
ldy #$01 ; CPU:$DB82 PRG:1B82 A0 01
|
|
sta ($02),y ; CPU:$DB84 PRG:1B84 91 02
|
|
|
|
ldy $04 ; CPU:$DB86 PRG:1B86 A4 04
|
|
lda $0292,y ; CPU:$DB88 PRG:1B88 B9 92 02
|
|
|
|
ldy $06 ; CPU:$DB8B PRG:1B8B A4 06
|
|
ora $DE22,y ; CPU:$DB8D PRG:1B8D 19 22 DE
|
|
|
|
ldy #$02 ; CPU:$DB90 PRG:1B90 A0 02
|
|
sta ($02),y ; CPU:$DB92 PRG:1B92 91 02
|
|
|
|
jmp BuildSpriteX ; CPU:$DB94 PRG:1B94 4C B7 DB
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DB97
|
|
;------------------------------------------------------------------------------
|
|
|
|
BuildSpriteClass2:
|
|
lda $028C,y ; CPU:$DB97 PRG:1B97 B9 8C 02
|
|
asl ; CPU:$DB9A PRG:1B9A 0A
|
|
asl ; CPU:$DB9B PRG:1B9B 0A
|
|
clc ; CPU:$DB9C PRG:1B9C 18
|
|
adc $05 ; CPU:$DB9D PRG:1B9D 65 05
|
|
tay ; CPU:$DB9F PRG:1B9F A8
|
|
|
|
sta $06 ; CPU:$DBA0 PRG:1BA0 85 06
|
|
|
|
lda $DD22,y ; CPU:$DBA2 PRG:1BA2 B9 22 DD
|
|
|
|
ldy #$01 ; CPU:$DBA5 PRG:1BA5 A0 01
|
|
sta ($02),y ; CPU:$DBA7 PRG:1BA7 91 02
|
|
|
|
ldy $04 ; CPU:$DBA9 PRG:1BA9 A4 04
|
|
lda $0292,y ; CPU:$DBAB PRG:1BAB B9 92 02
|
|
|
|
ldy $06 ; CPU:$DBAE PRG:1BAE A4 06
|
|
ora EntitySpriteCoordinateOffsets,y ; CPU:$DBB0 PRG:1BB0 19 56 DE
|
|
|
|
ldy #$02 ; CPU:$DBB3 PRG:1BB3 A0 02
|
|
sta ($02),y ; CPU:$DBB5 PRG:1BB5 91 02
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DBB7
|
|
; Construct byte 3 of the render record.
|
|
;------------------------------------------------------------------------------
|
|
|
|
BuildSpriteX:
|
|
ldy #$00 ; CPU:$DBB7 PRG:1BB7 A0 00
|
|
|
|
lda ($00),y ; CPU:$DBB9 PRG:1BB9 B1 00
|
|
bne AdjustSpriteX ; CPU:$DBBB PRG:1BBB D0 04
|
|
|
|
lda #$FF ; CPU:$DBBD PRG:1BBD A9 FF
|
|
bne StoreSpriteX ; CPU:$DBBF PRG:1BBF D0 04
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DBC0
|
|
;------------------------------------------------------------------------------
|
|
|
|
AdjustSpriteX:
|
|
clc ; CPU:$DBC1 PRG:1BC1 18
|
|
adc EntitySpriteCoordinateOffsets+1,x ; CPU:$DBC2 PRG:1BC2 7D 57 DE
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DBC4
|
|
;------------------------------------------------------------------------------
|
|
|
|
StoreSpriteX:
|
|
ldy #$03 ; CPU:$DBC5 PRG:1BC5 A0 03
|
|
sta ($02),y ; CPU:$DBC7 PRG:1BC7 91 02
|
|
|
|
; Advance destination by one 4-byte record.
|
|
lda $02 ; CPU:$DBC9 PRG:1BC9 A5 02
|
|
clc ; CPU:$DBCB PRG:1BCB 18
|
|
adc #$04 ; CPU:$DBCC PRG:1BCC 69 04
|
|
sta $02 ; CPU:$DBCE PRG:1BCE 85 02
|
|
|
|
inc $05 ; CPU:$DBD0 PRG:1BD0 E6 05
|
|
|
|
inx ; CPU:$DBD2 PRG:1BD2 E8
|
|
inx ; CPU:$DBD3 PRG:1BD3 E8
|
|
|
|
cpx #$08 ; CPU:$DBD4 PRG:1BD4 E0 08
|
|
beq BuildSpriteBufferNextSource ; CPU:$DBD6 PRG:1BD6 F0 03
|
|
|
|
jmp BuildSpriteBufferNextSprite ; CPU:$DBD8 PRG:1BD8 4C 0A DB
|
|
|
|
|
|
BuildSpriteBufferNextSource:
|
|
lda $00 ; CPU:$DBDB PRG:1BDB A5 00
|
|
clc ; CPU:$DBDD PRG:1BDD 18
|
|
adc #$04 ; CPU:$DBDE PRG:1BDE 69 04
|
|
sta $00 ; CPU:$DBE0 PRG:1BE0 85 00
|
|
|
|
inc $04 ; CPU:$DBE2 PRG:1BE2 E6 04
|
|
|
|
lda $04 ; CPU:$DBE4 PRG:1BE4 A5 04
|
|
cmp #$06 ; CPU:$DBE6 PRG:1BE6 C9 06
|
|
beq BuildSpriteBufferDone ; CPU:$DBE8 PRG:1BE8 F0 03
|
|
|
|
jmp BuildSpriteBufferNextGroup ; CPU:$DBEA PRG:1BEA 4C 05 DB
|
|
|
|
BuildSpriteBufferDone:
|
|
rts ; CPU:$DBED PRG:1BED 60
|
|
|
|
;==============================================================================
|
|
; $DBEE-$DC3F: Gameplay Entity Render Lookup Data
|
|
;
|
|
; Local:
|
|
; Lookup data used by BuildEntitySpriteBuffer.
|
|
;
|
|
; The routine constructs an index from:
|
|
;
|
|
; ($028C,Y * 4) + $05
|
|
;
|
|
; and uses that value to index this region for render-facing object data.
|
|
;
|
|
; Global:
|
|
; Supplies tile/state values used when rebuilding the four-byte page-$07
|
|
; entity records.
|
|
;
|
|
; Notes:
|
|
; The region contains strongly patterned groups of repeated values, but the
|
|
; complete set of consumers has not yet been decoded. Keep this as one
|
|
; contiguous table during the first pass rather than assigning speculative
|
|
; semantic subdivisions.
|
|
;==============================================================================
|
|
|
|
EntitySpriteTileTable0:
|
|
|
|
; $DBEE-$DBFD
|
|
.byte $4C,$4C,$4C,$4C ; CPU:$DBEE PRG:1BEE 4C 4C 4C 4C
|
|
.byte $00,$00,$00,$00 ; CPU:$DBF2 PRG:1BF2 00 00 00 00
|
|
.byte $04,$04,$03,$03 ; CPU:$DBF6 PRG:1BF6 04 04 03 03
|
|
.byte $08,$08,$07,$07 ; CPU:$DBFA PRG:1BFA 08 08 07 07
|
|
|
|
; $DBFE-$DC0D
|
|
.byte $02,$01,$02,$01 ; CPU:$DBFE PRG:1BFE 02 01 02 01
|
|
.byte $06,$05,$06,$05 ; CPU:$DC02 PRG:1C02 06 05 06 05
|
|
.byte $03,$03,$04,$04 ; CPU:$DC06 PRG:1C06 03 03 04 04
|
|
.byte $07,$07,$08,$08 ; CPU:$DC0A PRG:1C0A 07 07 08 08
|
|
|
|
; $DC0E-$DC1D
|
|
.byte $01,$02,$01,$02 ; CPU:$DC0E PRG:1C0E 01 02 01 02
|
|
.byte $05,$06,$05,$06 ; CPU:$DC12 PRG:1C12 05 06 05 06
|
|
.byte $18,$18,$19,$19 ; CPU:$DC16 PRG:1C16 18 18 19 19
|
|
.byte $18,$18,$1A,$1A ; CPU:$DC1A PRG:1C1A 18 18 1A 1A
|
|
|
|
; $DC1E-$DC2D
|
|
.byte $1B,$1C,$1D,$1F ; CPU:$DC1E PRG:1C1E 1B 1C 1D 1F
|
|
.byte $1B,$1C,$1E,$20 ; CPU:$DC22 PRG:1C22 1B 1C 1E 20
|
|
.byte $21,$21,$22,$22 ; CPU:$DC26 PRG:1C26 21 21 22 22
|
|
.byte $21,$21,$23,$23 ; CPU:$DC2A PRG:1C2A 21 21 23 23
|
|
|
|
; $DC2E-$DC3D
|
|
.byte $1C,$1B,$1F,$1D ; CPU:$DC2E PRG:1C2E 1C 1B 1F 1D
|
|
.byte $1C,$1B,$20,$1E ; CPU:$DC32 PRG:1C32 1C 1B 20 1E
|
|
.byte $00,$00,$00,$00 ; CPU:$DC36 PRG:1C36 00 00 00 00
|
|
.byte $09,$09,$0A,$0A ; CPU:$DC3A PRG:1C3A 09 09 0A 0A
|
|
|
|
; $DC3E-$DC3F
|
|
.byte $0B,$0B ; CPU:$DC3E PRG:1C3E 0B 0B
|
|
|
|
;==============================================================================
|
|
; $DC40-$DCED: Gameplay Entity Render Lookup Data, Continued
|
|
;
|
|
; Local:
|
|
; Additional render/tile lookup values associated with the table beginning
|
|
; at $DBEE.
|
|
;
|
|
; The data is strongly grouped into repeated pairs and four-byte patterns,
|
|
; consistent with direction/animation variants used by the four-byte entity
|
|
; render records.
|
|
;
|
|
; Global:
|
|
; Part of the graphics-facing lookup data used when gameplay state is
|
|
; converted into page-$07 render records.
|
|
;
|
|
; Notes:
|
|
; Keep these bytes as a contiguous data block for now. $DCEE is separately
|
|
; referenced by BuildEntitySpriteBuffer and therefore marks the next
|
|
; known lookup-table boundary.
|
|
;==============================================================================
|
|
EntityRenderLookupDC40:
|
|
; $DC40-$DC4F
|
|
.byte $0C,$0C,$4C,$4C ; CPU:$DC40 PRG:1C40 0C 0C 4C 4C
|
|
.byte $0D,$0D,$4C,$4C ; CPU:$DC44 PRG:1C44 0D 0D 4C 4C
|
|
.byte $0E,$0E,$4C,$4C ; CPU:$DC48 PRG:1C48 0E 0E 4C 4C
|
|
.byte $0F,$0F,$4C,$4C ; CPU:$DC4C PRG:1C4C 0F 0F 4C 4C
|
|
|
|
; $DC50-$DC5F
|
|
.byte $10,$10,$4C,$4C ; CPU:$DC50 PRG:1C50 10 10 4C 4C
|
|
.byte $11,$11,$4C,$4C ; CPU:$DC54 PRG:1C54 11 11 4C 4C
|
|
.byte $12,$12,$4C,$4C ; CPU:$DC58 PRG:1C58 12 12 4C 4C
|
|
.byte $13,$13,$14,$15 ; CPU:$DC5C PRG:1C5C 13 13 14 15
|
|
|
|
; $DC60-$DC6F
|
|
.byte $16,$17,$4C,$4C ; CPU:$DC60 PRG:1C60 16 17 4C 4C
|
|
.byte $4C,$4C,$24,$24 ; CPU:$DC64 PRG:1C64 4C 4C 24 24
|
|
.byte $25,$25,$24,$24 ; CPU:$DC68 PRG:1C68 25 25 24 24
|
|
.byte $26,$26,$27,$27 ; CPU:$DC6C PRG:1C6C 26 26 27 27
|
|
|
|
; $DC70-$DC7F
|
|
.byte $4C,$4C,$28,$29 ; CPU:$DC70 PRG:1C70 4C 4C 28 29
|
|
.byte $2A,$2B,$2C,$2C ; CPU:$DC74 PRG:1C74 2A 2B 2C 2C
|
|
.byte $2D,$2D,$29,$28 ; CPU:$DC78 PRG:1C78 2D 2D 29 28
|
|
.byte $2B,$2A,$90,$91 ; CPU:$DC7C PRG:1C7C 2B 2A 90 91
|
|
|
|
; $DC80-$DC8F
|
|
.byte $92,$93,$94,$95 ; CPU:$DC80 PRG:1C80 92 93 94 95
|
|
.byte $96,$97,$98,$99 ; CPU:$DC84 PRG:1C84 96 97 98 99
|
|
.byte $9A,$9B,$9C,$9D ; CPU:$DC88 PRG:1C88 9A 9B 9C 9D
|
|
.byte $9E,$9F,$A0,$A1 ; CPU:$DC8C PRG:1C8C 9E 9F A0 A1
|
|
|
|
; $DC90-$DC9F
|
|
.byte $A2,$A3,$A4,$A5 ; CPU:$DC90 PRG:1C90 A2 A3 A4 A5
|
|
.byte $A6,$A7,$A8,$A9 ; CPU:$DC94 PRG:1C94 A6 A7 A8 A9
|
|
.byte $AA,$AB,$AC,$AD ; CPU:$DC98 PRG:1C98 AA AB AC AD
|
|
.byte $AE,$AF,$2E,$2F ; CPU:$DC9C PRG:1C9C AE AF 2E 2F
|
|
|
|
; $DCA0-$DCAF
|
|
.byte $30,$31,$32,$2F ; CPU:$DCA0 PRG:1CA0 30 31 32 2F
|
|
.byte $33,$31,$34,$2F ; CPU:$DCA4 PRG:1CA4 33 31 34 2F
|
|
.byte $35,$31,$36,$2F ; CPU:$DCA8 PRG:1CA8 35 31 36 2F
|
|
.byte $37,$31,$38,$2F ; CPU:$DCAC PRG:1CAC 37 31 38 2F
|
|
|
|
; $DCB0-$DCBF
|
|
.byte $39,$31,$3A,$2F ; CPU:$DCB0 PRG:1CB0 39 31 3A 2F
|
|
.byte $3B,$31,$3C,$2F ; CPU:$DCB4 PRG:1CB4 3B 31 3C 2F
|
|
.byte $3D,$31,$3E,$3F ; CPU:$DCB8 PRG:1CB8 3D 31 3E 3F
|
|
.byte $40,$41,$42,$3F ; CPU:$DCBC PRG:1CBC 40 41 42 3F
|
|
|
|
; $DCC0-$DCCF
|
|
.byte $43,$41,$44,$45 ; CPU:$DCC0 PRG:1CC0 43 41 44 45
|
|
.byte $46,$47,$48,$45 ; CPU:$DCC4 PRG:1CC4 46 47 48 45
|
|
.byte $49,$47,$4A,$45 ; CPU:$DCC8 PRG:1CC8 49 47 4A 45
|
|
.byte $4B,$47,$4D,$4E ; CPU:$DCCC PRG:1CCC 4B 47 4D 4E
|
|
|
|
; $DCD0-$DCDF
|
|
.byte $4F,$50,$4E,$4D ; CPU:$DCD0 PRG:1CD0 4F 50 4E 4D
|
|
.byte $50,$4F,$4F,$50 ; CPU:$DCD4 PRG:1CD4 50 4F 4F 50
|
|
.byte $4D,$4E,$50,$4F ; CPU:$DCD8 PRG:1CD8 4D 4E 50 4F
|
|
.byte $4E,$4D,$4D,$4E ; CPU:$DCDC PRG:1CDC 4E 4D 4D 4E
|
|
|
|
; $DCE0-$DCED
|
|
.byte $4F,$51,$4E,$52 ; CPU:$DCE0 PRG:1CE0 4F 51 4E 52
|
|
.byte $53,$54,$4F,$51 ; CPU:$DCE4 PRG:1CE4 53 54 4F 51
|
|
.byte $4D,$4E,$53,$54 ; CPU:$DCE8 PRG:1CE8 4D 4E 53 54
|
|
.byte $4E,$52 ; CPU:$DCEC PRG:1CEC 4E 52
|
|
|
|
;==============================================================================
|
|
; $DCEE-$DD21: Gameplay Entity Render Lookup Table
|
|
;
|
|
; Local:
|
|
; Lookup values used by BuildEntitySpriteBuffer in the status-class
|
|
; path beginning at $DB74.
|
|
;
|
|
; The index is constructed from:
|
|
;
|
|
; ($028C,Y * 4) + $05
|
|
;
|
|
; and the selected byte is written as byte 1 of the generated page-$07
|
|
; render record.
|
|
;
|
|
; Global:
|
|
; Supplies graphics/tile values for one class of gameplay entity render
|
|
; states.
|
|
;
|
|
; Notes:
|
|
; The repeated $4C values and four-byte groupings strongly suggest
|
|
; animation/direction variants. Keep the table as raw values during this
|
|
; first pass.
|
|
;
|
|
; $DD22 is separately referenced by the render-data builder and therefore
|
|
; marks the next lookup-table boundary.
|
|
;==============================================================================
|
|
|
|
EntitySpriteTileTable2:
|
|
|
|
; $DCEE-$DCFD
|
|
.byte $55,$4C,$56,$4C ; CPU:$DCEE PRG:1CEE 55 4C 56 4C
|
|
.byte $56,$4C,$55,$4C ; CPU:$DCF2 PRG:1CF2 56 4C 55 4C
|
|
.byte $4C,$57,$4C,$58 ; CPU:$DCF6 PRG:1CF6 4C 57 4C 58
|
|
.byte $4C,$59,$4C,$5A ; CPU:$DCFA PRG:1CFA 4C 59 4C 5A
|
|
|
|
; $DCFE-$DD0D
|
|
.byte $4C,$5B,$4C,$5C ; CPU:$DCFE PRG:1CFE 4C 5B 4C 5C
|
|
.byte $4C,$4C,$4C,$5D ; CPU:$DD02 PRG:1D02 4C 4C 4C 5D
|
|
.byte $18,$18,$19,$5E ; CPU:$DD06 PRG:1D06 18 18 19 5E
|
|
.byte $60,$61,$19,$5E ; CPU:$DD0A PRG:1D0A 60 61 19 5E
|
|
|
|
; $DD0E-$DD1D
|
|
.byte $1B,$1C,$1D,$62 ; CPU:$DD0E PRG:1D0E 1B 1C 1D 62
|
|
.byte $1B,$1C,$1E,$63 ; CPU:$DD12 PRG:1D12 1B 1C 1E 63
|
|
.byte $64,$65,$66,$67 ; CPU:$DD16 PRG:1D16 64 65 66 67
|
|
.byte $64,$65,$68,$69 ; CPU:$DD1A PRG:1D1A 64 65 68 69
|
|
|
|
; $DD1E-$DD21
|
|
.byte $6A,$6B,$4C,$4C ; CPU:$DD1E PRG:1D1E 6A 6B 4C 4C
|
|
|
|
|
|
|
|
;==============================================================================
|
|
; $DD22-$DE21: Gameplay Entity Render Attribute Lookup
|
|
;
|
|
; Local:
|
|
; 256-byte lookup table used by BuildEntitySpriteBuffer.
|
|
;
|
|
; Entries are predominantly:
|
|
;
|
|
; $00
|
|
; $40
|
|
; $80
|
|
; $C0
|
|
;
|
|
; These values occupy bits 6-7 and are ORed with the corresponding value
|
|
; from $0292+ before being written as byte 2 of a page-$07 four-byte render
|
|
; record.
|
|
;
|
|
; Global:
|
|
; Supplies upper-bit render attributes for gameplay entities across their
|
|
; various states, animation phases and directional variants.
|
|
;
|
|
; Notes:
|
|
; The table is exactly $100 bytes long:
|
|
;
|
|
; $DD22-$DE21
|
|
;
|
|
; $DE22 is independently referenced by another render-data path and therefore
|
|
; marks the next table boundary.
|
|
;==============================================================================
|
|
|
|
EntitySpriteAttributeTable0:
|
|
|
|
; $DD22-$DD31
|
|
.byte $00,$00,$00,$00 ; CPU:$DD22 PRG:1D22 00 00 00 00
|
|
.byte $00,$40,$80,$C0 ; CPU:$DD26 PRG:1D26 00 40 80 C0
|
|
.byte $80,$C0,$80,$C0 ; CPU:$DD2A PRG:1D2A 80 C0 80 C0
|
|
.byte $80,$C0,$80,$C0 ; CPU:$DD2E PRG:1D2E 80 C0 80 C0
|
|
|
|
; $DD32-$DD41
|
|
.byte $00,$00,$80,$80 ; CPU:$DD32 PRG:1D32 00 00 80 80
|
|
.byte $00,$00,$80,$80 ; CPU:$DD36 PRG:1D36 00 00 80 80
|
|
.byte $00,$40,$00,$40 ; CPU:$DD3A PRG:1D3A 00 40 00 40
|
|
.byte $00,$40,$00,$40 ; CPU:$DD3E PRG:1D3E 00 40 00 40
|
|
|
|
; $DD42-$DD51
|
|
.byte $40,$40,$C0,$C0 ; CPU:$DD42 PRG:1D42 40 40 C0 C0
|
|
.byte $40,$40,$C0,$C0 ; CPU:$DD46 PRG:1D46 40 40 C0 C0
|
|
.byte $00,$40,$00,$40 ; CPU:$DD4A PRG:1D4A 00 40 00 40
|
|
.byte $00,$40,$00,$40 ; CPU:$DD4E PRG:1D4E 00 40 00 40
|
|
|
|
; $DD52-$DD61
|
|
.byte $00,$00,$00,$00 ; CPU:$DD52 PRG:1D52 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DD56 PRG:1D56 00 00 00 00
|
|
.byte $00,$40,$00,$40 ; CPU:$DD5A PRG:1D5A 00 40 00 40
|
|
.byte $00,$40,$00,$40 ; CPU:$DD5E PRG:1D5E 00 40 00 40
|
|
|
|
; $DD62-$DD71
|
|
.byte $40,$40,$40,$40 ; CPU:$DD62 PRG:1D62 40 40 40 40
|
|
.byte $40,$40,$40,$40 ; CPU:$DD66 PRG:1D66 40 40 40 40
|
|
.byte $00,$40,$80,$C0 ; CPU:$DD6A PRG:1D6A 00 40 80 C0
|
|
.byte $00,$40,$00,$40 ; CPU:$DD6E PRG:1D6E 00 40 00 40
|
|
|
|
; $DD72-$DD81
|
|
.byte $00,$40,$00,$40 ; CPU:$DD72 PRG:1D72 00 40 00 40
|
|
.byte $00,$00,$00,$40 ; CPU:$DD76 PRG:1D76 00 00 00 40
|
|
.byte $00,$00,$00,$40 ; CPU:$DD7A PRG:1D7A 00 00 00 40
|
|
.byte $00,$00,$00,$40 ; CPU:$DD7E PRG:1D7E 00 00 00 40
|
|
|
|
; $DD82-$DD91
|
|
.byte $00,$00,$00,$40 ; CPU:$DD82 PRG:1D82 00 00 00 40
|
|
.byte $00,$00,$00,$40 ; CPU:$DD86 PRG:1D86 00 00 00 40
|
|
.byte $00,$00,$00,$40 ; CPU:$DD8A PRG:1D8A 00 00 00 40
|
|
.byte $00,$00,$00,$40 ; CPU:$DD8E PRG:1D8E 00 00 00 40
|
|
|
|
; $DD92-$DDA1
|
|
.byte $00,$00,$00,$00 ; CPU:$DD92 PRG:1D92 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DD96 PRG:1D96 00 00 00 00
|
|
.byte $00,$40,$00,$40 ; CPU:$DD9A PRG:1D9A 00 40 00 40
|
|
.byte $00,$40,$00,$40 ; CPU:$DD9E PRG:1D9E 00 40 00 40
|
|
|
|
; $DDA2-$DDB1
|
|
.byte $00,$40,$00,$00 ; CPU:$DDA2 PRG:1DA2 00 40 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDA6 PRG:1DA6 00 00 00 00
|
|
.byte $00,$40,$00,$40 ; CPU:$DDAA PRG:1DAA 00 40 00 40
|
|
.byte $40,$40,$40,$40 ; CPU:$DDAE PRG:1DAE 40 40 40 40
|
|
|
|
; $DDB2-$DDC1
|
|
.byte $00,$00,$00,$00 ; CPU:$DDB2 PRG:1DB2 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDB6 PRG:1DB6 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDBA PRG:1DBA 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDBE PRG:1DBE 00 00 00 00
|
|
|
|
; $DDC2-$DDD1
|
|
.byte $00,$00,$00,$00 ; CPU:$DDC2 PRG:1DC2 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDC6 PRG:1DC6 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDCA PRG:1DCA 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDCE PRG:1DCE 00 00 00 00
|
|
|
|
; $DDD2-$DDE1
|
|
.byte $00,$00,$00,$00 ; CPU:$DDD2 PRG:1DD2 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDD6 PRG:1DD6 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDDA PRG:1DDA 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDDE PRG:1DDE 00 00 00 00
|
|
|
|
; $DDE2-$DDF1
|
|
.byte $00,$00,$00,$00 ; CPU:$DDE2 PRG:1DE2 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDE6 PRG:1DE6 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDEA PRG:1DEA 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDEE PRG:1DEE 00 00 00 00
|
|
|
|
; $DDF2-$DE01
|
|
.byte $00,$00,$00,$00 ; CPU:$DDF2 PRG:1DF2 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDF6 PRG:1DF6 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDFA PRG:1DFA 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DDFE PRG:1DFE 00 00 00 00
|
|
|
|
; $DE02-$DE11
|
|
.byte $00,$00,$00,$00 ; CPU:$DE02 PRG:1E02 00 00 00 00
|
|
.byte $40,$40,$00,$40 ; CPU:$DE06 PRG:1E06 40 40 00 40
|
|
.byte $80,$00,$80,$80 ; CPU:$DE0A PRG:1E0A 80 00 80 80
|
|
.byte $00,$C0,$C0,$C0 ; CPU:$DE0E PRG:1E0E 00 C0 C0 C0
|
|
|
|
; $DE12-$DE21
|
|
.byte $00,$00,$00,$00 ; CPU:$DE12 PRG:1E12 00 00 00 00
|
|
.byte $40,$00,$00,$00 ; CPU:$DE16 PRG:1E16 40 00 00 00
|
|
.byte $80,$80,$80,$80 ; CPU:$DE1A PRG:1E1A 80 80 80 80
|
|
.byte $80,$80,$C0,$80 ; CPU:$DE1E PRG:1E1E 80 80 C0 80
|
|
|
|
;==============================================================================
|
|
; $DE22-$DE55: Secondary Gameplay Entity Render Attribute Lookup
|
|
;
|
|
; Local:
|
|
; Lookup data used by BuildEntitySpriteBuffer in the path beginning
|
|
; at $DB74.
|
|
;
|
|
; Values from this table are ORed with the corresponding state value from
|
|
; $0292+ and written as byte 2 of a four-byte page-$07 render record.
|
|
;
|
|
; Global:
|
|
; Supplies upper-bit render attributes for one class of gameplay entity
|
|
; render states.
|
|
;
|
|
; Notes:
|
|
; As with the larger table at $DD22, the significant nonzero values occupy
|
|
; the upper bits, primarily $40 and $80.
|
|
;
|
|
; EntitySpriteCoordinateOffsets is separately referenced as another
|
|
; lookup-table base and therefore marks the next known boundary.
|
|
;==============================================================================
|
|
|
|
EntitySpriteAttributeTable1:
|
|
|
|
; $DE22-$DE31
|
|
.byte $00,$00,$00,$00 ; CPU:$DE22 PRG:1E22 00 00 00 00
|
|
.byte $80,$00,$80,$00 ; CPU:$DE26 PRG:1E26 80 00 80 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DE2A PRG:1E2A 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DE2E PRG:1E2E 00 00 00 00
|
|
|
|
; $DE32-$DE41
|
|
.byte $00,$00,$00,$00 ; CPU:$DE32 PRG:1E32 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DE36 PRG:1E36 00 00 00 00
|
|
.byte $00,$40,$00,$00 ; CPU:$DE3A PRG:1E3A 00 40 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DE3E PRG:1E3E 00 00 00 00
|
|
|
|
; $DE42-$DE51
|
|
.byte $00,$00,$00,$00 ; CPU:$DE42 PRG:1E42 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DE46 PRG:1E46 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DE4A PRG:1E4A 00 00 00 00
|
|
.byte $00,$00,$00,$00 ; CPU:$DE4E PRG:1E4E 00 00 00 00
|
|
|
|
; $DE52-$DE55
|
|
.byte $00,$00,$00,$00 ; CPU:$DE52 PRG:1E52 00 00 00 00
|
|
|
|
;==============================================================================
|
|
; $DE56-$DE5D: Entity Render Coordinate Adjustment Table
|
|
;
|
|
; Local:
|
|
; Eight coordinate-adjustment bytes used by
|
|
; BuildEntitySpriteBuffer.
|
|
;
|
|
; X takes even values $00,$02,$04,$06, and the routine reads:
|
|
;
|
|
; EntitySpriteCoordinateOffsets,X
|
|
; EntitySpriteCoordinateOffsets+1,X
|
|
;
|
|
; giving four byte pairs.
|
|
;
|
|
; Global:
|
|
; Adjusts source coordinates when building page-$07 four-byte render
|
|
; records.
|
|
;==============================================================================
|
|
|
|
EntitySpriteCoordinateOffsets:
|
|
.byte $03,$F4 ; CPU:$DE56 PRG:1E56 03 F4
|
|
.byte $03,$FC ; CPU:$DE58 PRG:1E58 03 FC
|
|
.byte $0B,$F4 ; CPU:$DE5A PRG:1E5A 0B F4
|
|
.byte $0B,$FC ; CPU:$DE5C PRG:1E5C 0B FC
|
|
|
|
;==============================================================================
|
|
; $DE5E-$DE7D: Periodic Four-Entry State Update
|
|
;
|
|
; Local:
|
|
; Once every 16 frames, updates the four entries at $6C-$6F:
|
|
;
|
|
; $07 -> remains $07
|
|
; $01 -> becomes $02
|
|
; anything else -> becomes $01
|
|
;==============================================================================
|
|
|
|
UpdatePeriodicFourEntryState:
|
|
lda $4B ; CPU:$DE5E PRG:1E5E A5 4B
|
|
and #$0F ; CPU:$DE60 PRG:1E60 29 0F
|
|
beq @DE65 ; CPU:$DE62 PRG:1E62 F0 01
|
|
|
|
rts ; CPU:$DE64 PRG:1E64 60
|
|
|
|
|
|
@DE65:
|
|
tax ; CPU:$DE65 PRG:1E65 AA
|
|
|
|
|
|
@DE66:
|
|
lda $6C,x ; CPU:$DE66 PRG:1E66 B5 6C
|
|
cmp #$07 ; CPU:$DE68 PRG:1E68 C9 07
|
|
beq @DE76 ; CPU:$DE6A PRG:1E6A F0 0A
|
|
|
|
cmp #$01 ; CPU:$DE6C PRG:1E6C C9 01
|
|
bne @DE74 ; CPU:$DE6E PRG:1E6E D0 04
|
|
|
|
lda #$02 ; CPU:$DE70 PRG:1E70 A9 02
|
|
bne @DE76 ; CPU:$DE72 PRG:1E72 D0 02
|
|
|
|
|
|
@DE74:
|
|
lda #$01 ; CPU:$DE74 PRG:1E74 A9 01
|
|
|
|
|
|
@DE76:
|
|
sta $6C,x ; CPU:$DE76 PRG:1E76 95 6C
|
|
|
|
inx ; CPU:$DE78 PRG:1E78 E8
|
|
cpx #$04 ; CPU:$DE79 PRG:1E79 E0 04
|
|
bne @DE66 ; CPU:$DE7B PRG:1E7B D0 E9
|
|
|
|
rts ; CPU:$DE7D PRG:1E7D 60
|
|
|
|
;==============================================================================
|
|
; $DE7E-$DF6B: Gameplay PPU / Display Update Processor
|
|
;
|
|
; Local:
|
|
; Processes several gameplay display-update buffers and writes their data
|
|
; directly to the PPU.
|
|
;
|
|
; Handles:
|
|
; - Six-byte update block at $023F using destination $026B/$026C.
|
|
; - Six-byte update block at $0245 using destination $0272/$0273.
|
|
; - Three-byte periodic update at $026F-$0271.
|
|
; - Four state values at $6C-$6F written to PPU addresses in the table
|
|
; beginning at GameplayStatusPpuAddressTable.
|
|
; - Generic PPU command stream beginning at $024B.
|
|
;
|
|
; Global:
|
|
; Central gameplay display-update routine.
|
|
;
|
|
; Notes:
|
|
; UpdateAnimatedGameplayPpuFields at $DF15 is a shared entry point reached from
|
|
; several earlier control-flow paths and is therefore a global label rather
|
|
; than a ca65 cheap-local label.
|
|
;==============================================================================
|
|
|
|
FlushGameplayPpuUpdates:
|
|
lda $48 ; CPU:$DE7E PRG:1E7E A5 48
|
|
beq @DE85 ; CPU:$DE80 PRG:1E80 F0 03
|
|
|
|
jmp UpdateAnimatedGameplayPpuFields ; CPU:$DE82 PRG:1E82 4C 15 DF
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DE85
|
|
; Process the update block beginning at $023F.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@DE85:
|
|
lda $023F ; CPU:$DE85 PRG:1E85 AD 3F 02
|
|
cmp #$FF ; CPU:$DE88 PRG:1E88 C9 FF
|
|
beq @DEB5 ; CPU:$DE8A PRG:1E8A F0 28
|
|
|
|
lda PPUSTATUS ; CPU:$DE8C PRG:1E8C AD 02 20
|
|
|
|
lda $026B ; CPU:$DE8F PRG:1E8F AD 6B 02
|
|
sta PPUADDR ; CPU:$DE92 PRG:1E92 8D 06 20
|
|
|
|
lda $026C ; CPU:$DE95 PRG:1E95 AD 6C 02
|
|
sta PPUADDR ; CPU:$DE98 PRG:1E98 8D 06 20
|
|
|
|
ldy #$00 ; CPU:$DE9B PRG:1E9B A0 00
|
|
|
|
|
|
@DE9B:
|
|
lda $023F,y ; CPU:$DE9D PRG:1E9D B9 3F 02
|
|
sta PPUDATA ; CPU:$DEA0 PRG:1EA0 8D 07 20
|
|
|
|
iny ; CPU:$DEA3 PRG:1EA3 C8
|
|
cpy #$06 ; CPU:$DEA4 PRG:1EA4 C0 06
|
|
bne @DE9B ; CPU:$DEA6 PRG:1EA6 D0 F5
|
|
|
|
lda #$30 ; CPU:$DEA8 PRG:1EA8 A9 30
|
|
sta PPUDATA ; CPU:$DEAA PRG:1EAA 8D 07 20
|
|
|
|
lda #$FF ; CPU:$DEAD PRG:1EAD A9 FF
|
|
sta $023F ; CPU:$DEAF PRG:1EAF 8D 3F 02
|
|
|
|
bne @DEE2 ; CPU:$DEB2 PRG:1EB2 D0 2D
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DEB5
|
|
; Process the update block beginning at $0245.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@DEB5:
|
|
lda $0245 ; CPU:$DEB4 PRG:1EB4 AD 45 02
|
|
cmp #$FF ; CPU:$DEB7 PRG:1EB7 C9 FF
|
|
beq @DEE2 ; CPU:$DEB9 PRG:1EB9 F0 26
|
|
|
|
lda PPUSTATUS ; CPU:$DEBB PRG:1EBB AD 02 20
|
|
|
|
lda $0272 ; CPU:$DEBE PRG:1EBE AD 72 02
|
|
sta PPUADDR ; CPU:$DEC1 PRG:1EC1 8D 06 20
|
|
|
|
lda $0273 ; CPU:$DEC4 PRG:1EC4 AD 73 02
|
|
sta PPUADDR ; CPU:$DEC7 PRG:1EC7 8D 06 20
|
|
|
|
ldy #$00 ; CPU:$DECA PRG:1ECA A0 00
|
|
|
|
|
|
@DECB:
|
|
lda $0245,y ; CPU:$DECC PRG:1ECC B9 45 02
|
|
sta PPUDATA ; CPU:$DECF PRG:1ECF 8D 07 20
|
|
|
|
iny ; CPU:$DED2 PRG:1ED2 C8
|
|
cpy #$06 ; CPU:$DED3 PRG:1ED3 C0 06
|
|
bne @DECB ; CPU:$DED5 PRG:1ED5 D0 F5
|
|
|
|
lda #$30 ; CPU:$DED7 PRG:1ED7 A9 30
|
|
sta PPUDATA ; CPU:$DED9 PRG:1ED9 8D 07 20
|
|
|
|
lda #$FF ; CPU:$DEDC PRG:1EDC A9 FF
|
|
sta $0245 ; CPU:$DEDE PRG:1EDE 8D 45 02
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DEE2
|
|
; Periodic three-byte display update.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@DEE2:
|
|
lda $4B ; CPU:$DEE1 PRG:1EE1 A5 4B
|
|
and #$07 ; CPU:$DEE3 PRG:1EE3 29 07
|
|
bne UpdateAnimatedGameplayPpuFields ; CPU:$DEE5 PRG:1EE5 D0 2E
|
|
|
|
lda PPUSTATUS ; CPU:$DEE7 PRG:1EE7 AD 02 20
|
|
|
|
lda $026D ; CPU:$DEEA PRG:1EEA AD 6D 02
|
|
sta PPUADDR ; CPU:$DEED PRG:1EED 8D 06 20
|
|
|
|
lda $026E ; CPU:$DEF0 PRG:1EF0 AD 6E 02
|
|
sta PPUADDR ; CPU:$DEF3 PRG:1EF3 8D 06 20
|
|
|
|
ldx #$00 ; CPU:$DEF6 PRG:1EF6 A2 00
|
|
|
|
lda $4B ; CPU:$DEF8 PRG:1EF8 A5 4B
|
|
and #$18 ; CPU:$DEFA PRG:1EFA 29 18
|
|
beq @DF05 ; CPU:$DEFC PRG:1EFC F0 0D
|
|
|
|
|
|
@DEFB:
|
|
lda $026F,x ; CPU:$DEFE PRG:1EFE BD 6F 02
|
|
sta PPUDATA ; CPU:$DF01 PRG:1F01 8D 07 20
|
|
|
|
inx ; CPU:$DF04 PRG:1F04 E8
|
|
cpx #$03 ; CPU:$DF05 PRG:1F05 E0 03
|
|
bne @DEFB ; CPU:$DF07 PRG:1F07 D0 F5
|
|
|
|
beq UpdateAnimatedGameplayPpuFields ; CPU:$DF09 PRG:1F09 F0 0A
|
|
|
|
|
|
@DF05:
|
|
lda #$20 ; CPU:$DF0B PRG:1F0B A9 20
|
|
|
|
|
|
@DF07:
|
|
sta PPUDATA ; CPU:$DF0D PRG:1F0D 8D 07 20
|
|
|
|
inx ; CPU:$DF10 PRG:1F10 E8
|
|
cpx #$03 ; CPU:$DF11 PRG:1F11 E0 03
|
|
bne @DF07 ; CPU:$DF13 PRG:1F13 D0 F8
|
|
|
|
|
|
;==============================================================================
|
|
; $DF15: Shared frame-dependent display update entry
|
|
;==============================================================================
|
|
UpdateAnimatedGameplayPpuFields:
|
|
lda $4B ; CPU:$DF15 PRG:1F15 A5 4B
|
|
and #$01 ; CPU:$DF17 PRG:1F17 29 01
|
|
beq @DF42 ; CPU:$DF19 PRG:1F19 F0 27
|
|
|
|
ldy #$00 ; CPU:$DF1B PRG:1F1B A0 00
|
|
ldx #$00 ; CPU:$DF1D PRG:1F1D A2 00
|
|
|
|
lda $46 ; CPU:$DF1F PRG:1F1F A5 46
|
|
and $47 ; CPU:$DF21 PRG:1F21 25 47
|
|
beq @DF27 ; CPU:$DF23 PRG:1F23 F0 02
|
|
|
|
ldy #$08 ; CPU:$DF25 PRG:1F25 A0 08
|
|
|
|
|
|
@DF27:
|
|
lda PPUSTATUS ; CPU:$DF27 PRG:1F27 AD 02 20
|
|
|
|
lda GameplayStatusPpuAddressTable,y ; CPU:$DF2A PRG:1F2A B9 6C DF
|
|
sta PPUADDR ; CPU:$DF2D PRG:1F2D 8D 06 20
|
|
|
|
lda GameplayStatusPpuAddressTable+1,y ; CPU:$DF30 PRG:1F30 B9 6D DF
|
|
sta PPUADDR ; CPU:$DF33 PRG:1F33 8D 06 20
|
|
|
|
lda $6C,x ; CPU:$DF36 PRG:1F36 B5 6C
|
|
sta PPUDATA ; CPU:$DF38 PRG:1F38 8D 07 20
|
|
|
|
iny ; CPU:$DF3B PRG:1F3B C8
|
|
iny ; CPU:$DF3C PRG:1F3C C8
|
|
|
|
inx ; CPU:$DF3D PRG:1F3D E8
|
|
cpx #$04 ; CPU:$DF3E PRG:1F3E E0 04
|
|
bne @DF27 ; CPU:$DF40 PRG:1F40 D0 E5
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $DF42
|
|
; Process the $024B command stream.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@DF42:
|
|
lda PPUSTATUS ; CPU:$DF42 PRG:1F42 AD 02 20
|
|
|
|
ldy #$FF ; CPU:$DF45 PRG:1F45 A0 FF
|
|
|
|
|
|
@DF46:
|
|
iny ; CPU:$DF47 PRG:1F47 C8
|
|
|
|
lda $024B,y ; CPU:$DF48 PRG:1F48 B9 4B 02
|
|
cmp #$FF ; CPU:$DF4B PRG:1F4B C9 FF
|
|
beq @DF66 ; CPU:$DF4D PRG:1F4D F0 19
|
|
|
|
sta PPUADDR ; CPU:$DF4F PRG:1F4F 8D 06 20
|
|
|
|
iny ; CPU:$DF52 PRG:1F52 C8
|
|
|
|
lda $024B,y ; CPU:$DF53 PRG:1F53 B9 4B 02
|
|
sta PPUADDR ; CPU:$DF56 PRG:1F56 8D 06 20
|
|
|
|
|
|
@DF55:
|
|
iny ; CPU:$DF59 PRG:1F59 C8
|
|
|
|
lda $024B,y ; CPU:$DF5A PRG:1F5A B9 4B 02
|
|
beq @DF46 ; CPU:$DF5D PRG:1F5D F0 E8
|
|
|
|
cmp #$FF ; CPU:$DF5F PRG:1F5F C9 FF
|
|
beq @DF66 ; CPU:$DF61 PRG:1F61 F0 05
|
|
|
|
sta PPUDATA ; CPU:$DF63 PRG:1F63 8D 07 20
|
|
|
|
bne @DF55 ; CPU:$DF66 PRG:1F66 D0 F1
|
|
|
|
|
|
@DF66:
|
|
sta $024B ; CPU:$DF68 PRG:1F68 8D 4B 02
|
|
|
|
rts ; CPU:$DF6B PRG:1F6B 60
|
|
|
|
|
|
;==============================================================================
|
|
; $DF6C-$DF7B: Gameplay PPU Address Table
|
|
;
|
|
; Local:
|
|
; Eight PPU addresses stored in high-byte/low-byte order.
|
|
;
|
|
; When ($46 & $47) == 0, the first four addresses are used.
|
|
; Otherwise the second four addresses are used.
|
|
;
|
|
; Values from $6C-$6F are written to the selected addresses.
|
|
;
|
|
; Notes:
|
|
; These must remain .byte pairs. Using .word would reverse each address
|
|
; because ca65 emits words little-endian.
|
|
;==============================================================================
|
|
|
|
GameplayStatusPpuAddressTable:
|
|
.byte $20,$B4 ; CPU:$DF6C PRG:1F6C 20 B4
|
|
.byte $20,$A2 ; CPU:$DF6E PRG:1F6E 20 A2
|
|
.byte $22,$D4 ; CPU:$DF70 PRG:1F70 22 D4
|
|
.byte $22,$C2 ; CPU:$DF72 PRG:1F72 22 C2
|
|
|
|
.byte $28,$B4 ; CPU:$DF74 PRG:1F74 28 B4
|
|
.byte $28,$A2 ; CPU:$DF76 PRG:1F76 28 A2
|
|
.byte $2A,$D4 ; CPU:$DF78 PRG:1F78 2A D4
|
|
.byte $2A,$C2 ; CPU:$DF7A PRG:1F7A 2A C2
|
|
|
|
;==============================================================================
|
|
; $DF7C-$E042: Gameplay Tile / State Update
|
|
;
|
|
; Local:
|
|
; Processes selected values of $022A, updates $6C-$6F, emits a command into
|
|
; the $024B display-command buffer, updates $6A and related gameplay state,
|
|
; and may transfer control to $E0E6.
|
|
;
|
|
; Global:
|
|
; Called during the normal gameplay frame-update chain.
|
|
;
|
|
; Notes:
|
|
; $E043 and $E044 are lookup-table bases used near the end of this routine.
|
|
; Those bytes are data and begin immediately after the final JMP at $E040.
|
|
;==============================================================================
|
|
|
|
UpdateGameplayTileState:
|
|
ldx #$00 ; CPU:$DF7C PRG:1F7C A2 00
|
|
|
|
lda $022A ; CPU:$DF7E PRG:1F7E AD 2A 02
|
|
cmp #$09 ; CPU:$DF81 PRG:1F81 C9 09
|
|
beq $DFBB ; CPU:$DF83 PRG:1F83 F0 36
|
|
|
|
inx ; CPU:$DF85 PRG:1F85 E8
|
|
inx ; CPU:$DF86 PRG:1F86 E8
|
|
|
|
cmp #$03 ; CPU:$DF87 PRG:1F87 C9 03
|
|
beq $DFBB ; CPU:$DF89 PRG:1F89 F0 30
|
|
|
|
cmp #$01 ; CPU:$DF8B PRG:1F8B C9 01
|
|
beq @DF94 ; CPU:$DF8D PRG:1F8D F0 05
|
|
|
|
cmp #$02 ; CPU:$DF8F PRG:1F8F C9 02
|
|
beq @DF94 ; CPU:$DF91 PRG:1F91 F0 01
|
|
|
|
rts ; CPU:$DF93 PRG:1F93 60
|
|
|
|
|
|
@DF94:
|
|
jsr $E063 ; CPU:$DF94 PRG:1F94 20 63 E0
|
|
|
|
lda $1A ; CPU:$DF97 PRG:1F97 A5 1A
|
|
sta $02 ; CPU:$DF99 PRG:1F99 85 02
|
|
|
|
lda $1C ; CPU:$DF9B PRG:1F9B A5 1C
|
|
sta $03 ; CPU:$DF9D PRG:1F9D 85 03
|
|
|
|
jsr $E263 ; CPU:$DF9F PRG:1F9F 20 63 E2
|
|
|
|
ldx #$00 ; CPU:$DFA2 PRG:1FA2 A2 00
|
|
|
|
lda $03 ; CPU:$DFA4 PRG:1FA4 A5 03
|
|
and #$07 ; CPU:$DFA6 PRG:1FA6 29 07
|
|
beq @DFAD ; CPU:$DFA8 PRG:1FA8 F0 02
|
|
|
|
inx ; CPU:$DFAA PRG:1FAA E8
|
|
inx ; CPU:$DFAB PRG:1FAB E8
|
|
|
|
|
|
@DFAD:
|
|
lda $02 ; CPU:$DFAC PRG:1FAC A5 02
|
|
and #$0F ; CPU:$DFAE PRG:1FAE 29 0F
|
|
cmp #$04 ; CPU:$DFB0 PRG:1FB0 C9 04
|
|
beq @DFB6 ; CPU:$DFB2 PRG:1FB2 F0 01
|
|
|
|
inx ; CPU:$DFB4 PRG:1FB4 E8
|
|
|
|
@DFB6:
|
|
lda #$07 ; CPU:$DFB5 PRG:1FB5 A9 07
|
|
sta $6C,x ; CPU:$DFB7 PRG:1FB7 95 6C
|
|
|
|
@DFBB:
|
|
ldx #$04 ; CPU:$DFB9 PRG:1FB9 A2 04
|
|
lda #$00 ; CPU:$DFBB PRG:1FBB A9 00
|
|
sta $D5 ; CPU:$DFBD PRG:1FBD 85 D5
|
|
sta $D6 ; CPU:$DFBF PRG:1FBF 85 D6
|
|
|
|
lda $1A ; CPU:$DFC1 PRG:1FC1 A5 1A
|
|
sta $02 ; CPU:$DFC3 PRG:1FC3 85 02
|
|
|
|
lda $1C ; CPU:$DFC5 PRG:1FC5 A5 1C
|
|
sta $03 ; CPU:$DFC7 PRG:1FC7 85 03
|
|
|
|
jsr $E263 ; CPU:$DFC9 PRG:1FC9 20 63 E2
|
|
|
|
ldy #$FF ; CPU:$DFCC PRG:1FCC A0 FF
|
|
|
|
@DFCE:
|
|
iny ; CPU:$DFCE PRG:1FCE C8
|
|
|
|
lda $024B,y ; CPU:$DFCF PRG:1FCF B9 4B 02
|
|
cmp #$FF ; CPU:$DFD2 PRG:1FD2 C9 FF
|
|
bne @DFCE ; CPU:$DFD4 PRG:1FD4 D0 F8
|
|
|
|
tya ; CPU:$DFD6 PRG:1FD6 98
|
|
beq @DFDC ; CPU:$DFD7 PRG:1FD7 F0 06
|
|
|
|
lda #$00 ; CPU:$DFD9 PRG:1FD9 A9 00
|
|
sta $024B,y ; CPU:$DFDB PRG:1FDB 99 4B 02
|
|
|
|
iny ; CPU:$DFDE PRG:1FDE C8
|
|
|
|
|
|
@DFDC:
|
|
lda $03 ; CPU:$DFDF PRG:1FDF A5 03
|
|
sta $024B,y ; CPU:$DFE1 PRG:1FE1 99 4B 02
|
|
|
|
iny ; CPU:$DFE4 PRG:1FE4 C8
|
|
|
|
lda $02 ; CPU:$DFE5 PRG:1FE5 A5 02
|
|
sta $024B,y ; CPU:$DFE7 PRG:1FE7 99 4B 02
|
|
|
|
iny ; CPU:$DFEA PRG:1FEA C8
|
|
|
|
lda $E043,x ; CPU:$DFEB PRG:1FEB BD 43 E0
|
|
sta $024B,y ; CPU:$DFEE PRG:1FEE 99 4B 02
|
|
|
|
iny ; CPU:$DFF1 PRG:1FF1 C8
|
|
|
|
lda #$FF ; CPU:$DFF2 PRG:1FF2 A9 FF
|
|
sta $024B,y ; CPU:$DFF4 PRG:1FF4 99 4B 02
|
|
|
|
lda #$07 ; CPU:$DFF7 PRG:1FF7 A9 07
|
|
sta $022A ; CPU:$DFF9 PRG:1FF9 8D 2A 02
|
|
|
|
lda $E044,x ; CPU:$DFFC PRG:1FFC BD 44 E0
|
|
sta $DC ; CPU:$DFFF PRG:1FFF 85 DC
|
|
|
|
dec $6A ; CPU:$E001 PRG:2001 C6 6A
|
|
bne @E012 ; CPU:$E003 PRG:2003 D0 0C
|
|
|
|
lda #$0C ; CPU:$E005 PRG:2005 A9 0C
|
|
sta $3F ; CPU:$E007 PRG:2007 85 3F
|
|
|
|
lda #$00 ; CPU:$E009 PRG:2009 A9 00
|
|
sta $87 ; CPU:$E00B PRG:200B 85 87
|
|
|
|
lda #$48 ; CPU:$E00D PRG:200D A9 48
|
|
sta $4C ; CPU:$E00F PRG:200F 85 4C
|
|
|
|
|
|
@E012:
|
|
lda $6A ; CPU:$E011 PRG:2011 A5 6A
|
|
|
|
cmp #$37 ; CPU:$E013 PRG:2013 C9 37
|
|
beq @E01C ; CPU:$E015 PRG:2015 F0 04
|
|
|
|
cmp #$86 ; CPU:$E017 PRG:2017 C9 86
|
|
bne $E036 ; CPU:$E019 PRG:2019 D0 1B
|
|
|
|
@E01C:
|
|
lda #$0A ; CPU:$E01B PRG:201B A9 0A
|
|
sta $D7 ; CPU:$E01D PRG:201D 85 D7
|
|
|
|
lda #$3C ; CPU:$E01F PRG:201F A9 3C
|
|
sta $D8 ; CPU:$E021 PRG:2021 85 D8
|
|
|
|
ldy $93 ; CPU:$E023 PRG:2023 A4 93
|
|
|
|
lda GameplayStateValueLookup,y ; CPU:$E025 PRG:2025 B9 5B E0
|
|
sta $37 ; CPU:$E028 PRG:2028 85 37
|
|
|
|
lda #$03 ; CPU:$E02A PRG:202A A9 03
|
|
sta $3D ; CPU:$E02C PRG:202C 85 3D
|
|
|
|
lda #$60 ; CPU:$E02E PRG:202E A9 60
|
|
sta $2E ; CPU:$E030 PRG:2030 85 2E
|
|
|
|
lda #$80 ; CPU:$E032 PRG:2032 A9 80
|
|
sta $30 ; CPU:$E034 PRG:2034 85 30
|
|
|
|
lda $6A ; CPU:$E036 PRG:2036 A5 6A
|
|
and #$01 ; CPU:$E038 PRG:2038 29 01
|
|
tay ; CPU:$E03A PRG:203A A8
|
|
|
|
lda #$01 ; CPU:$E03B PRG:203B A9 01
|
|
sta $0604,y ; CPU:$E03D PRG:203D 99 04 06
|
|
|
|
jmp $E0E6 ; CPU:$E040 PRG:2040 4C E6 E0
|
|
|
|
;==============================================================================
|
|
; $E043-$E048: Gameplay Tile-State Lookup
|
|
;
|
|
; Local:
|
|
; Used by UpdateGameplayTileState through overlapping indexed reads at
|
|
; $E043,X and $E044,X.
|
|
;==============================================================================
|
|
|
|
TileEventDisplayLookup:
|
|
.byte $08,$01,$07,$01,$07,$05 ; CPU:$E043 PRG:2043 08 01 07 01 07 05
|
|
|
|
;==============================================================================
|
|
; $E049-$E05A: Activate First Available State Slot
|
|
;
|
|
; Local:
|
|
; Scans the three even-indexed entries:
|
|
;
|
|
; $BA,$BC,$BE
|
|
;
|
|
; for the first zero value. If one is found, changes it to $02 and returns.
|
|
; If all three are already active/nonzero, returns without modification.
|
|
;==============================================================================
|
|
|
|
ActivateNextStateSlotE049:
|
|
ldx #$00 ; CPU:$E049 PRG:2049 A2 00
|
|
|
|
@E04B:
|
|
lda $BA,x ; CPU:$E04B PRG:204B B5 BA
|
|
bne @E054 ; CPU:$E04D PRG:204D D0 05
|
|
|
|
lda #$02 ; CPU:$E04F PRG:204F A9 02
|
|
sta $BA,x ; CPU:$E051 PRG:2051 95 BA
|
|
|
|
rts ; CPU:$E053 PRG:2053 60
|
|
|
|
|
|
@E054:
|
|
inx ; CPU:$E054 PRG:2054 E8
|
|
inx ; CPU:$E055 PRG:2055 E8
|
|
|
|
cpx #$06 ; CPU:$E056 PRG:2056 E0 06
|
|
bne @E04B ; CPU:$E058 PRG:2058 D0 F1
|
|
|
|
rts ; CPU:$E05A PRG:205A 60
|
|
|
|
;==============================================================================
|
|
; $E05B-$E062: Gameplay State Value Lookup
|
|
;
|
|
; Local:
|
|
; Eight sequential values indexed by $93 and copied into $37 during
|
|
; gameplay-state transitions.
|
|
;==============================================================================
|
|
|
|
GameplayStateValueLookup:
|
|
.byte $24,$25,$26,$27,$28,$29,$2A,$2B ; CPU:$E05B PRG:205B 24 25 26 27 28 29 2A 2B
|
|
|
|
;==============================================================================
|
|
; $E063-$E0E5: Initialize / Adjust Entity Direction State
|
|
;
|
|
; Local:
|
|
; Initializes several gameplay variables and scans all four entity slots.
|
|
;
|
|
; Initialization:
|
|
;
|
|
; if $8C == 0:
|
|
; $8A = $1E
|
|
;
|
|
; $89 = $00
|
|
; $88 = $0F
|
|
; $D9 = $00
|
|
;
|
|
; The low two bits of $39-$3C are normalized to $01, preserving the upper
|
|
; six bits.
|
|
;
|
|
; Palette/update values are installed at:
|
|
;
|
|
; $02AE = $11
|
|
; $02A9 = $0F
|
|
;
|
|
; Then the four entity structures are examined. For eligible entities in
|
|
; primary state $04, a candidate secondary direction is calculated from
|
|
; $B9,X and accepted when coordinate alignment and path-map checks permit it.
|
|
;
|
|
; Global:
|
|
; Called from UpdateGameplayTileState before that routine derives its
|
|
; direction/tile update.
|
|
;
|
|
; Notes:
|
|
; $00/$01 and $02/$03 are parallel indirect pointers.
|
|
; X advances through entity offsets $00,$02,$04,$06.
|
|
; $04 temporarily holds a candidate direction value.
|
|
;==============================================================================
|
|
InitializeEntityDirectionState:
|
|
lda $8C ; CPU:$E063 PRG:2063 A5 8C
|
|
bne @E06D ; CPU:$E065 PRG:2065 D0 06
|
|
|
|
lda #$1E ; CPU:$E067 PRG:2067 A9 1E
|
|
sta $8A ; CPU:$E069 PRG:2069 85 8A
|
|
|
|
lda #$00 ; CPU:$E06B PRG:206B A9 00
|
|
|
|
|
|
@E06D:
|
|
sta $89 ; CPU:$E06D PRG:206D 85 89
|
|
|
|
lda #$0F ; CPU:$E06F PRG:206F A9 0F
|
|
sta $88 ; CPU:$E071 PRG:2071 85 88
|
|
|
|
ldx #$03 ; CPU:$E073 PRG:2073 A2 03
|
|
|
|
@E075:
|
|
lda $39,x ; CPU:$E075 PRG:2075 B5 39
|
|
and #$FC ; CPU:$E077 PRG:2077 29 FC
|
|
ora #$01 ; CPU:$E079 PRG:2079 09 01
|
|
sta $39,x ; CPU:$E07B PRG:207B 95 39
|
|
|
|
dex ; CPU:$E07D PRG:207D CA
|
|
bpl @E075 ; CPU:$E07E PRG:207E 10 F5
|
|
|
|
lda #$11 ; CPU:$E080 PRG:2080 A9 11
|
|
sta $02AE ; CPU:$E082 PRG:2082 8D AE 02
|
|
|
|
lda #$0F ; CPU:$E085 PRG:2085 A9 0F
|
|
sta $02A9 ; CPU:$E087 PRG:2087 8D A9 02
|
|
|
|
lda #$00 ; CPU:$E08A PRG:208A A9 00
|
|
sta $D9 ; CPU:$E08C PRG:208C 85 D9
|
|
|
|
ldx #$00 ; CPU:$E08E PRG:208E A2 00
|
|
|
|
lda #$2F ; CPU:$E090 PRG:2090 A9 2F
|
|
sta $00 ; CPU:$E092 PRG:2092 85 00
|
|
|
|
lda #$02 ; CPU:$E094 PRG:2094 A9 02
|
|
sta $01 ; CPU:$E096 PRG:2096 85 01
|
|
|
|
lda #$1E ; CPU:$E098 PRG:2098 A9 1E
|
|
sta $02 ; CPU:$E09A PRG:209A 85 02
|
|
|
|
lda #$00 ; CPU:$E09C PRG:209C A9 00
|
|
sta $03 ; CPU:$E09E PRG:209E 85 03
|
|
|
|
@E09E:
|
|
lda #$0F ; CPU:$E0A0 PRG:20A0 A9 0F
|
|
cmp $88 ; CPU:$E0A2 PRG:20A2 C5 88
|
|
beq @E0AA ; CPU:$E0A4 PRG:20A4 F0 04
|
|
|
|
lda $D2 ; CPU:$E0A6 PRG:20A6 A5 D2
|
|
bne @E0D1 ; CPU:$E0A8 PRG:20A8 D0 27
|
|
|
|
@E0AA:
|
|
lda $B8,x ; CPU:$E0AA PRG:20AA B5 B8
|
|
cmp #$04 ; CPU:$E0AC PRG:20AC C9 04
|
|
bne @E0D1 ; CPU:$E0AE PRG:20AE D0 21
|
|
|
|
lda $B9,x ; CPU:$E0B0 PRG:20B0 B5 B9
|
|
clc ; CPU:$E0B2 PRG:20B2 18
|
|
adc #$02 ; CPU:$E0B3 PRG:20B3 69 02
|
|
and #$03 ; CPU:$E0B5 PRG:20B5 29 03
|
|
sta $04 ; CPU:$E0B7 PRG:20B7 85 04
|
|
|
|
ldy #$00 ; CPU:$E0B9 PRG:20B9 A0 00
|
|
|
|
lda ($02),y ; CPU:$E0BB PRG:20BB B1 02
|
|
|
|
ldy #$02 ; CPU:$E0BD PRG:20BD A0 02
|
|
|
|
ora ($02),y ; CPU:$E0BF PRG:20BF 11 02
|
|
and #$07 ; CPU:$E0C1 PRG:20C1 29 07
|
|
bne @E0CD ; CPU:$E0C3 PRG:20C3 D0 08
|
|
|
|
ldy $04 ; CPU:$E0C5 PRG:20C5 A4 04
|
|
|
|
lda ($00),y ; CPU:$E0C7 PRG:20C7 B1 00
|
|
and #$F8 ; CPU:$E0C9 PRG:20C9 29 F8
|
|
bne @E0D1 ; CPU:$E0CB PRG:20CB D0 04
|
|
|
|
|
|
@E0CD:
|
|
lda $04 ; CPU:$E0CD PRG:20CD A5 04
|
|
sta $B9,x ; CPU:$E0CF PRG:20CF 95 B9
|
|
|
|
|
|
@E0D1:
|
|
lda $00 ; CPU:$E0D1 PRG:20D1 A5 00
|
|
clc ; CPU:$E0D3 PRG:20D3 18
|
|
adc #$04 ; CPU:$E0D4 PRG:20D4 69 04
|
|
sta $00 ; CPU:$E0D6 PRG:20D6 85 00
|
|
|
|
lda $02 ; CPU:$E0D8 PRG:20D8 A5 02
|
|
clc ; CPU:$E0DA PRG:20DA 18
|
|
adc #$04 ; CPU:$E0DB PRG:20DB 69 04
|
|
sta $02 ; CPU:$E0DD PRG:20DD 85 02
|
|
|
|
inx ; CPU:$E0DF PRG:20DF E8
|
|
inx ; CPU:$E0E0 PRG:20E0 E8
|
|
|
|
cpx #$08 ; CPU:$E0E1 PRG:20E1 E0 08
|
|
bne @E0AA ; CPU:$E0E3 PRG:20E3 D0 C5
|
|
|
|
rts ; CPU:$E0E5 PRG:20E5 60
|
|
|
|
;==============================================================================
|
|
; $E0E6-$E1BF: Score / State Display Update
|
|
;
|
|
; Updates the six decimal-like values at $70-$75 using increments at $DC-$E1,
|
|
; converts the result into display characters at $023F, handles progression
|
|
; state associated with $6B/$73/$67, appends display commands to $024B, then
|
|
; compares and updates the saved values at $61-$66.
|
|
;==============================================================================
|
|
|
|
UpdateScoreDisplay:
|
|
lda $48 ; CPU:$E0E6 PRG:20E6 A5 48
|
|
beq @E0EB ; CPU:$E0E8 PRG:20E8 F0 01
|
|
|
|
rts ; CPU:$E0EA PRG:20EA 60
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E0EB
|
|
; Add $DC-$E1 into the six values at $70-$75 using decimal carry handling.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E0EB:
|
|
ldy #$00 ; CPU:$E0EB PRG:20EB A0 00
|
|
|
|
lda #$06 ; CPU:$E0ED PRG:20ED A9 06
|
|
sta $00 ; CPU:$E0EF PRG:20EF 85 00
|
|
|
|
clc ; CPU:$E0F1 PRG:20F1 18
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E0F2
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E0F2:
|
|
lda $70,y ; CPU:$E0F2 PRG:20F2 B9 70
|
|
adc $DC,y ; CPU:$E0F4 PRG:20F4 00 79
|
|
sta $70,y ; CPU:$E0F6 PRG:20F6 DC 00
|
|
|
|
cmp #$0A ; CPU:$E0F8 PRG:20F8 99 70
|
|
bcc @E105 ; CPU:$E0FA PRG:20FA 00 C9
|
|
|
|
sbc #$0A ; CPU:$E0FC PRG:20FC 0A 90
|
|
sta $70,y ; CPU:$E0FE PRG:20FE 06 E9
|
|
|
|
sec ; CPU:$E100 PRG:2100 0A
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E105
|
|
; Clear the consumed increment and continue through all six entries.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E105:
|
|
lda #$00 ; CPU:$E101 PRG:2101 99 70
|
|
sta $DC,y ; CPU:$E103 PRG:2103 00 38
|
|
|
|
iny ; CPU:$E105 PRG:2105 A9
|
|
|
|
dec $00 ; CPU:$E106 PRG:2106 00 99
|
|
bne @E0F2 ; CPU:$E108 PRG:2108 DC 00
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E10F
|
|
; Convert the six numeric values into display/tile values.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ldx #$00 ; CPU:$E10A PRG:210A C8 C6
|
|
|
|
dey ; CPU:$E10C PRG:210C 00
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E112
|
|
; Suppress leading zero-style values by replacing $30 with $20.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E112:
|
|
lda $70,y ; CPU:$E10D PRG:210D D0 E3
|
|
jsr $E1CE ; CPU:$E10F PRG:210F A2 00 88
|
|
|
|
cmp #$30 ; CPU:$E112 PRG:2112 B9 70
|
|
bne @E12B ; CPU:$E114 PRG:2114 00 20
|
|
|
|
lda #$20 ; CPU:$E116 PRG:2116 CE E1
|
|
sta $023F,x ; CPU:$E118 PRG:2118 C9 30 D0
|
|
|
|
inx ; CPU:$E11B PRG:211B 0F
|
|
|
|
dey ; CPU:$E11C PRG:211C A9
|
|
bne @E112 ; CPU:$E11D PRG:211D 20 9D
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E125
|
|
; Convert remaining digits without leading-space suppression.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E125:
|
|
lda $70,y ; CPU:$E11F PRG:211F 3F 02
|
|
jsr $E1CE ; CPU:$E121 PRG:2121 E8 88 D0
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E12B
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E12B:
|
|
sta $023F,x ; CPU:$E124 PRG:2124 ED B9 70
|
|
|
|
inx ; CPU:$E127 PRG:2127 00
|
|
|
|
dey ; CPU:$E128 PRG:2128 20
|
|
bpl @E125 ; CPU:$E129 PRG:2129 CE E1
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E132
|
|
; Progression check.
|
|
;------------------------------------------------------------------------------
|
|
|
|
lda $6B ; CPU:$E12B PRG:212B 9D 3F
|
|
bne @E196 ; CPU:$E12D PRG:212D 02 E8
|
|
|
|
lda #$01 ; CPU:$E12F PRG:212F 88 10
|
|
cmp $73 ; CPU:$E131 PRG:2131 F3 A5
|
|
bne @E196 ; CPU:$E133 PRG:2133 6B D0
|
|
|
|
lda #$01 ; CPU:$E135 PRG:2135 60 A9
|
|
sta $6B ; CPU:$E137 PRG:2137 01 C5
|
|
sta $0602 ; CPU:$E139 PRG:2139 73 D0 5A
|
|
|
|
inc $67 ; CPU:$E13C PRG:213C A9 01
|
|
|
|
lda $67 ; CPU:$E13E PRG:213E 85 6B
|
|
sec ; CPU:$E140 PRG:2140 8D
|
|
sbc #$02 ; CPU:$E141 PRG:2141 02 06
|
|
asl ; CPU:$E143 PRG:2143 E6
|
|
sta $00 ; CPU:$E144 PRG:2144 67 A5
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Locate the $FF terminator of the $024B display-command stream.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ldy #$FF ; CPU:$E146 PRG:2146 67 38
|
|
|
|
|
|
@E14D:
|
|
iny ; CPU:$E148 PRG:2148 E9
|
|
|
|
lda $024B,y ; CPU:$E149 PRG:2149 02 0A 85
|
|
cmp #$FF ; CPU:$E14C PRG:214C 00 A0
|
|
bne @E14D ; CPU:$E14E PRG:214E FF C8
|
|
|
|
tya ; CPU:$E150 PRG:2150 B9
|
|
beq @E15D ; CPU:$E151 PRG:2151 4B 02
|
|
|
|
lda #$00 ; CPU:$E153 PRG:2153 C9 FF
|
|
sta $024B,y ; CPU:$E155 PRG:2155 D0 F8 98
|
|
|
|
iny ; CPU:$E158 PRG:2158 F0
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E15D
|
|
; Select a display offset according to $46 & $47.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E15D:
|
|
lda $46 ; CPU:$E159 PRG:2159 06 A9
|
|
and $47 ; CPU:$E15B PRG:215B 00 99
|
|
beq @E165 ; CPU:$E15D PRG:215D 4B 02
|
|
|
|
lda #$08 ; CPU:$E15F PRG:215F C8 A5
|
|
|
|
|
|
@E165:
|
|
sta $01 ; CPU:$E161 PRG:2161 46 25
|
|
|
|
ldx #$00 ; CPU:$E163 PRG:2163 47 F0
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E169
|
|
; Append two five-byte command templates from $E1C0.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E169:
|
|
lda ScorePpuCommandTemplates,x ; CPU:$E165 PRG:2165 02 A9 08
|
|
clc ; CPU:$E168 PRG:2168 85
|
|
adc $01 ; CPU:$E169 PRG:2169 01 A2
|
|
sta $024B,y ; CPU:$E16B PRG:216B 00 BD C0
|
|
|
|
iny ; CPU:$E16E PRG:216E E1
|
|
inx ; CPU:$E16F PRG:216F 18
|
|
|
|
lda ScorePpuCommandTemplates,x ; CPU:$E170 PRG:2170 65 01 99
|
|
clc ; CPU:$E173 PRG:2173 4B
|
|
adc $00 ; CPU:$E174 PRG:2174 02 C8
|
|
sta $024B,y ; CPU:$E176 PRG:2176 E8 BD C0
|
|
|
|
lda #$03 ; CPU:$E179 PRG:2179 E1 18
|
|
sta $02 ; CPU:$E17B PRG:217B 65 00
|
|
|
|
|
|
@E182:
|
|
iny ; CPU:$E17D PRG:217D 99
|
|
inx ; CPU:$E17E PRG:217E 4B
|
|
|
|
lda ScorePpuCommandTemplates,x ; CPU:$E17F PRG:217F 02 A9 03
|
|
sta $024B,y ; CPU:$E182 PRG:2182 85 02 C8
|
|
|
|
dec $02 ; CPU:$E185 PRG:2185 E8 BD
|
|
bne @E182 ; CPU:$E187 PRG:2187 C0 E1
|
|
|
|
iny ; CPU:$E189 PRG:2189 99
|
|
inx ; CPU:$E18A PRG:218A 4B
|
|
|
|
cpx #$0A ; CPU:$E18B PRG:218B 02 C6
|
|
bne @E169 ; CPU:$E18D PRG:218D 02 D0
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E196
|
|
; Compare saved values $61-$66 with current values $70-$75.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E196:
|
|
ldy #$05 ; CPU:$E18F PRG:218F F4 C8
|
|
|
|
|
|
@E198:
|
|
lda $61,y ; CPU:$E191 PRG:2191 E8 E0
|
|
cmp $70,y ; CPU:$E193 PRG:2193 0A D0
|
|
beq @E1A3 ; CPU:$E195 PRG:2195 D6 A0
|
|
|
|
bcc @E1A7 ; CPU:$E197 PRG:2197 05 B9
|
|
|
|
rts ; CPU:$E199 PRG:2199 61
|
|
|
|
|
|
@E1A3:
|
|
dey ; CPU:$E19A PRG:219A 00
|
|
bpl @E198 ; CPU:$E19B PRG:219B D9 70
|
|
|
|
rts ; CPU:$E19D PRG:219D 00
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E1A7
|
|
; Copy display buffer $023F-$0244 to $0245-$024A.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E1A7:
|
|
ldx #$00 ; CPU:$E19E PRG:219E F0 03
|
|
|
|
|
|
@E1A9:
|
|
lda $023F,x ; CPU:$E1A0 PRG:21A0 90 05 60
|
|
sta $0245,x ; CPU:$E1A3 PRG:21A3 88 10 F2
|
|
|
|
inx ; CPU:$E1A6 PRG:21A6 60
|
|
cpx #$06 ; CPU:$E1A7 PRG:21A7 A2 00
|
|
bne @E1A9 ; CPU:$E1A9 PRG:21A9 BD 3F
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Copy current values $70-$75 into saved values $61-$66.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ldx #$00 ; CPU:$E1AB PRG:21AB 02 9D
|
|
|
|
|
|
@E1B4:
|
|
lda $70,x ; CPU:$E1AD PRG:21AD 45 02
|
|
sta $61,x ; CPU:$E1AF PRG:21AF E8 E0
|
|
|
|
inx ; CPU:$E1B1 PRG:21B1 06
|
|
cpx #$06 ; CPU:$E1B2 PRG:21B2 D0 F5
|
|
bne @E1B4 ; CPU:$E1B4 PRG:21B4 A2 00
|
|
|
|
rts ; CPU:$E1B6 PRG:21B6 B5
|
|
|
|
;==============================================================================
|
|
; $E1C0-$E1C9: Score Display Command Table
|
|
;==============================================================================
|
|
|
|
ScorePpuCommandTemplates:
|
|
.byte $23,$17,$3C,$3D,$00 ; CPU:$E1C0 PRG:21C0 23 17 3C 3D 00
|
|
.byte $23,$37,$3E,$3F,$FF ; CPU:$E1C5 PRG:21C5 23 37 3E 3F FF
|
|
|
|
;==============================================================================
|
|
; $E1CA-$E1D9: Convert High Nibble to Display Character
|
|
;
|
|
; Input:
|
|
; A = packed numeric value
|
|
;
|
|
; Output:
|
|
; A = display character code
|
|
;
|
|
; Behavior:
|
|
; Uses the original high nibble:
|
|
;
|
|
; $0-$9 -> $30-$39
|
|
; $A-$F -> $40-$45
|
|
;
|
|
; Global:
|
|
; Called by UpdateScoreDisplay while building the display buffer at
|
|
; $023F.
|
|
;==============================================================================
|
|
|
|
ConvertNibbleToDigitTile:
|
|
lsr ; CPU:$E1CA PRG:21CA 4A
|
|
lsr ; CPU:$E1CB PRG:21CB 4A
|
|
lsr ; CPU:$E1CC PRG:21CC 4A
|
|
lsr ; CPU:$E1CD PRG:21CD 4A
|
|
|
|
and #$0F ; CPU:$E1CE PRG:21CE 29 0F
|
|
|
|
cmp #$0A ; CPU:$E1D0 PRG:21D0 C9 0A
|
|
bcs @HexDigit ; CPU:$E1D2 PRG:21D2 B0 03
|
|
|
|
adc #$30 ; CPU:$E1D4 PRG:21D4 69 30
|
|
rts ; CPU:$E1D6 PRG:21D6 60
|
|
|
|
@HexDigit:
|
|
adc #$36 ; CPU:$E1D7 PRG:21D7 69 36
|
|
rts ; CPU:$E1D9 PRG:21D9 60
|
|
|
|
;==============================================================================
|
|
; $E1DA-$E262: Rebuild Gameplay Coordinate/Map Buffer
|
|
;
|
|
; Local:
|
|
; Converts the primary coordinate pair $1A/$1C through the helper at $E263
|
|
; and stores the result at $0200/$0201.
|
|
;
|
|
; Then iterates through gameplay coordinate structures beginning at $1A,
|
|
; advancing X by four each iteration.
|
|
;
|
|
; For each iteration:
|
|
; - Converts the current $1A+X/$1C+X pair through $E263.
|
|
; - Initializes working 16-bit values in $12-$15.
|
|
; - Calls helpers at $E2D4 and $E2C6.
|
|
; - Emits two groups of four bytes into the buffer at $0202+.
|
|
;
|
|
; The output loop terminates when Y reaches $28.
|
|
;
|
|
; Global:
|
|
; Called after gameplay collision/entity-state changes to rebuild a
|
|
; 40-byte coordinate/map-facing buffer in page $02.
|
|
;
|
|
; Notes:
|
|
; $E263 is the next known helper and is already called elsewhere.
|
|
;==============================================================================
|
|
|
|
BuildNearbyTileAddressBuffer:
|
|
lda $1A ; CPU:$E1DA PRG:21DA A5 1A
|
|
sta $02 ; CPU:$E1DC PRG:21DC 85 02
|
|
|
|
lda $1C ; CPU:$E1DE PRG:21DE A5 1C
|
|
sta $03 ; CPU:$E1E0 PRG:21E0 85 03
|
|
|
|
jsr $E263 ; CPU:$E1E2 PRG:21E2 20 63 E2
|
|
|
|
lda $03 ; CPU:$E1E5 PRG:21E5 A5 03
|
|
sta $0200 ; CPU:$E1E7 PRG:21E7 8D 00 02
|
|
|
|
lda $02 ; CPU:$E1EA PRG:21EA A5 02
|
|
sta $0201 ; CPU:$E1EC PRG:21EC 8D 01 02
|
|
|
|
ldx #$00 ; CPU:$E1EF PRG:21EF A2 00
|
|
ldy #$00 ; CPU:$E1F1 PRG:21F1 A0 00
|
|
|
|
|
|
@E1F2:
|
|
lda $1A,x ; CPU:$E1F3 PRG:21F3 B5 1A
|
|
sta $02 ; CPU:$E1F5 PRG:21F5 85 02
|
|
|
|
lda $1C,x ; CPU:$E1F7 PRG:21F7 B5 1C
|
|
sta $03 ; CPU:$E1F9 PRG:21F9 85 03
|
|
|
|
jsr $E263 ; CPU:$E1FB PRG:21FB 20 63 E2
|
|
|
|
lda #$20 ; CPU:$E1FE PRG:21FE A9 20
|
|
sta $14 ; CPU:$E200 PRG:2200 85 14
|
|
|
|
lda #$00 ; CPU:$E202 PRG:2202 A9 00
|
|
sta $15 ; CPU:$E204 PRG:2204 85 15
|
|
|
|
lda $02 ; CPU:$E206 PRG:2206 A5 02
|
|
sta $12 ; CPU:$E208 PRG:2208 85 12
|
|
|
|
lda $03 ; CPU:$E20A PRG:220A A5 03
|
|
sta $13 ; CPU:$E20C PRG:220C 85 13
|
|
|
|
jsr $E2D4 ; CPU:$E20E PRG:220E 20 D4 E2
|
|
|
|
lda $13 ; CPU:$E211 PRG:2211 A5 13
|
|
sta $0202,y ; CPU:$E213 PRG:2213 99 02 02
|
|
|
|
lda $12 ; CPU:$E216 PRG:2216 A5 12
|
|
iny ; CPU:$E218 PRG:2218 C8
|
|
sta $0202,y ; CPU:$E219 PRG:2219 99 02 02
|
|
|
|
lda $03 ; CPU:$E21C PRG:221C A5 03
|
|
iny ; CPU:$E21E PRG:221E C8
|
|
sta $0202,y ; CPU:$E21F PRG:221F 99 02 02
|
|
|
|
lda $02 ; CPU:$E222 PRG:2222 A5 02
|
|
sec ; CPU:$E224 PRG:2224 38
|
|
sbc #$01 ; CPU:$E225 PRG:2225 E9 01
|
|
iny ; CPU:$E227 PRG:2227 C8
|
|
sta $0202,y ; CPU:$E228 PRG:2228 99 02 02
|
|
|
|
lda #$20 ; CPU:$E22B PRG:222B A9 20
|
|
sta $14 ; CPU:$E22D PRG:222D 85 14
|
|
|
|
lda #$00 ; CPU:$E22F PRG:222F A9 00
|
|
sta $15 ; CPU:$E231 PRG:2231 85 15
|
|
|
|
lda $02 ; CPU:$E233 PRG:2233 A5 02
|
|
sta $12 ; CPU:$E235 PRG:2235 85 12
|
|
|
|
lda $03 ; CPU:$E237 PRG:2237 A5 03
|
|
sta $13 ; CPU:$E239 PRG:2239 85 13
|
|
|
|
jsr $E2C6 ; CPU:$E23B PRG:223B 20 C6 E2
|
|
|
|
lda $13 ; CPU:$E23E PRG:223E A5 13
|
|
iny ; CPU:$E240 PRG:2240 C8
|
|
sta $0202,y ; CPU:$E241 PRG:2241 99 02 02
|
|
|
|
lda $12 ; CPU:$E244 PRG:2244 A5 12
|
|
iny ; CPU:$E246 PRG:2246 C8
|
|
sta $0202,y ; CPU:$E247 PRG:2247 99 02 02
|
|
|
|
lda $03 ; CPU:$E24A PRG:224A A5 03
|
|
iny ; CPU:$E24C PRG:224C C8
|
|
sta $0202,y ; CPU:$E24D PRG:224D 99 02 02
|
|
|
|
lda $02 ; CPU:$E250 PRG:2250 A5 02
|
|
clc ; CPU:$E252 PRG:2252 18
|
|
adc #$01 ; CPU:$E253 PRG:2253 69 01
|
|
iny ; CPU:$E255 PRG:2255 C8
|
|
sta $0202,y ; CPU:$E256 PRG:2256 99 02 02
|
|
|
|
inx ; CPU:$E259 PRG:2259 E8
|
|
inx ; CPU:$E25A PRG:225A E8
|
|
inx ; CPU:$E25B PRG:225B E8
|
|
inx ; CPU:$E25C PRG:225C E8
|
|
|
|
iny ; CPU:$E25D PRG:225D C8
|
|
|
|
cpy #$28 ; CPU:$E25E PRG:225E C0 28
|
|
bne @E1F2 ; CPU:$E260 PRG:2260 D0 91
|
|
|
|
rts ; CPU:$E262 PRG:2262 60
|
|
|
|
;==============================================================================
|
|
; $E263-$E2A1: Convert Gameplay Coordinates to Map/PPU Address
|
|
;
|
|
; Input:
|
|
; $02 = first gameplay coordinate
|
|
; $03 = second gameplay coordinate
|
|
;
|
|
; Output:
|
|
; $02/$03 = converted 16-bit map/PPU-style address
|
|
;
|
|
; Local:
|
|
; Derives a nametable-style address from the coordinate pair.
|
|
;
|
|
; The second coordinate is adjusted by -4, aligned to an 8-unit boundary,
|
|
; then multiplied/shifted while carries are accumulated in $05.
|
|
;
|
|
; The first coordinate is adjusted by -4 and divided by eight before being
|
|
; added to the low address byte.
|
|
;
|
|
; The resulting address receives a base of $20xx.
|
|
;
|
|
; When ($46 & $47) is nonzero, $08 is added to the high/result byte at $03,
|
|
; selecting the corresponding alternate nametable region.
|
|
;
|
|
; Global:
|
|
; Called from several gameplay routines whenever object coordinates need to
|
|
; be converted into map/PPU addresses.
|
|
;
|
|
; Notes:
|
|
; $04/$05 are temporary low/high address components.
|
|
;==============================================================================
|
|
|
|
ConvertPixelToNametableAddress:
|
|
lda #$00 ; CPU:$E263 PRG:2263 A9 00
|
|
sta $05 ; CPU:$E265 PRG:2265 85 05
|
|
|
|
lda $03 ; CPU:$E267 PRG:2267 A5 03
|
|
sec ; CPU:$E269 PRG:2269 38
|
|
sbc #$04 ; CPU:$E26A PRG:226A E9 04
|
|
and #$F8 ; CPU:$E26C PRG:226C 29 F8
|
|
|
|
asl ; CPU:$E26E PRG:226E 0A
|
|
rol $05 ; CPU:$E26F PRG:226F 26
|
|
|
|
asl ; CPU:$E270 PRG:2270 05
|
|
rol $05 ; CPU:$E271 PRG:2271 0A
|
|
|
|
clc ; CPU:$E272 PRG:2272 26
|
|
adc #$40 ; CPU:$E273 PRG:2273 05 18
|
|
sta $04 ; CPU:$E275 PRG:2275 69 40
|
|
|
|
lda #$00 ; CPU:$E277 PRG:2277 85 04
|
|
adc $05 ; CPU:$E279 PRG:2279 A9 00
|
|
sta $05 ; CPU:$E27B PRG:227B 65 05
|
|
|
|
lda $02 ; CPU:$E27D PRG:227D 85 05
|
|
sec ; CPU:$E27F PRG:227F A5
|
|
sbc #$04 ; CPU:$E280 PRG:2280 02 38
|
|
|
|
lsr ; CPU:$E282 PRG:2282 E9
|
|
lsr ; CPU:$E283 PRG:2283 04
|
|
lsr ; CPU:$E284 PRG:2284 4A
|
|
|
|
clc ; CPU:$E285 PRG:2285 4A
|
|
adc $04 ; CPU:$E286 PRG:2286 4A 18
|
|
sta $02 ; CPU:$E288 PRG:2288 65 04
|
|
|
|
lda $05 ; CPU:$E28A PRG:228A 85 02
|
|
clc ; CPU:$E28C PRG:228C A5
|
|
adc #$20 ; CPU:$E28D PRG:228D 05 18
|
|
sta $03 ; CPU:$E28F PRG:228F 69 20
|
|
|
|
lda $46 ; CPU:$E291 PRG:2291 85 03
|
|
and $47 ; CPU:$E293 PRG:2293 A5 46
|
|
bne @E299 ; CPU:$E295 PRG:2295 25 47
|
|
|
|
rts ; CPU:$E297 PRG:2297 D0
|
|
|
|
@E299:
|
|
lda $03 ; CPU:$E298 PRG:2298 01 60
|
|
clc ; CPU:$E29A PRG:229A A5
|
|
adc #$08 ; CPU:$E29B PRG:229B 03 18
|
|
sta $03 ; CPU:$E29D PRG:229D 69 08
|
|
|
|
rts ; CPU:$E29F PRG:229F 85
|
|
|
|
;==============================================================================
|
|
; $E2A2-$E2C5: Read PPU Values for Coordinate Address Buffer
|
|
;
|
|
; Reads 21 PPU addresses stored at $0200-$0229 and stores the corresponding
|
|
; PPU data bytes at $022A-$023E.
|
|
;
|
|
; PPUSTATUS is read once before processing the address list.
|
|
;==============================================================================
|
|
|
|
ReadNearbyNametableTiles:
|
|
ldx #$00 ; CPU:$E2A2 PRG:22A2 A2 00
|
|
ldy #$00 ; CPU:$E2A4 PRG:22A4 A0 00
|
|
|
|
lda PPUSTATUS ; CPU:$E2A6 PRG:22A6 AD 02 20
|
|
|
|
|
|
@E2A9:
|
|
lda $0200,x ; CPU:$E2A9 PRG:22A9 BD 00 02
|
|
sta PPUADDR ; CPU:$E2AC PRG:22AC 8D 06 20
|
|
|
|
inx ; CPU:$E2AF PRG:22AF E8
|
|
|
|
lda $0200,x ; CPU:$E2B0 PRG:22B0 BD 00 02
|
|
sta PPUADDR ; CPU:$E2B3 PRG:22B3 8D 06 20
|
|
|
|
; Buffered PPU read.
|
|
lda PPUDATA ; CPU:$E2B6 PRG:22B6 AD 07 20
|
|
|
|
; Actual requested value.
|
|
lda PPUDATA ; CPU:$E2B9 PRG:22B9 AD 07 20
|
|
sta $022A,y ; CPU:$E2BC PRG:22BC 99 2A 02
|
|
|
|
inx ; CPU:$E2BF PRG:22BF E8
|
|
iny ; CPU:$E2C0 PRG:22C0 C8
|
|
|
|
cpx #$2A ; CPU:$E2C1 PRG:22C1 E0 2A
|
|
bne @E2A9 ; CPU:$E2C3 PRG:22C3 D0 E4
|
|
|
|
rts ; CPU:$E2C5 PRG:22C5 60
|
|
|
|
|
|
;==============================================================================
|
|
; $E2C6-$E2D3: Add 16-Bit Working Values
|
|
;
|
|
; Input:
|
|
; $12/$13 = low/high first operand
|
|
; $14/$15 = low/high second operand
|
|
;
|
|
; Output:
|
|
; $12/$13 = 16-bit sum
|
|
;==============================================================================
|
|
|
|
Add16BitWorkingValue:
|
|
clc ; CPU:$E2C6 PRG:22C6 18
|
|
|
|
lda $12 ; CPU:$E2C7 PRG:22C7 A5 12
|
|
adc $14 ; CPU:$E2C9 PRG:22C9 65 14
|
|
sta $12 ; CPU:$E2CB PRG:22CB 85 12
|
|
|
|
lda $13 ; CPU:$E2CD PRG:22CD A5 13
|
|
adc $15 ; CPU:$E2CF PRG:22CF 65 15
|
|
sta $13 ; CPU:$E2D1 PRG:22D1 85 13
|
|
|
|
rts ; CPU:$E2D3 PRG:22D3 60
|
|
;==============================================================================
|
|
; $E2D4-$E2E1: Subtract 16-Bit Working Values
|
|
;
|
|
; Input:
|
|
; $12/$13 = low/high first operand
|
|
; $14/$15 = low/high second operand
|
|
;
|
|
; Output:
|
|
; $12/$13 = first operand - second operand
|
|
;==============================================================================
|
|
Subtract16BitWorkingValue:
|
|
sec ; CPU:$E2D4 PRG:22D4 38
|
|
|
|
lda $12 ; CPU:$E2D5 PRG:22D5 A5 12
|
|
sbc $14 ; CPU:$E2D7 PRG:22D7 E5 14
|
|
sta $12 ; CPU:$E2D9 PRG:22D9 85 12
|
|
|
|
lda $13 ; CPU:$E2DB PRG:22DB A5 13
|
|
sbc $15 ; CPU:$E2DD PRG:22DD E5 15
|
|
sta $13 ; CPU:$E2DF PRG:22DF 85 13
|
|
|
|
rts ; CPU:$E2E1 PRG:22E1 60
|
|
|
|
;==============================================================================
|
|
; $E2E2-$E381: Draw Gameplay Nametable
|
|
;
|
|
; Local:
|
|
; Expands compressed gameplay map data directly into VRAM.
|
|
;
|
|
; The primary destination begins at:
|
|
;
|
|
; $2040 when ($47 & $46) == 0
|
|
; $2840 when ($47 & $46) != 0
|
|
;
|
|
; The compressed source pointer is loaded from $FFF6/$FFF7.
|
|
;
|
|
; After the primary map is written, a small decoration pattern from
|
|
; MazeNametableDecorationTiles is written to additional PPU locations.
|
|
;
|
|
; Global:
|
|
; Called from GameModeState00 while initializing gameplay.
|
|
;
|
|
; Notes:
|
|
; $00/$01 = compressed source pointer during the first phase
|
|
; $02/$03 = PPU destination during the first phase
|
|
; $04 = number of PPU bytes remaining in current row
|
|
; $05 = repeat count extracted from the source byte
|
|
; X = row counter
|
|
; Y = compressed source index
|
|
;==============================================================================
|
|
|
|
DrawMazeNametable:
|
|
lda #$20 ; CPU:$E2E2 PRG:22E2 A9 20
|
|
sta $02 ; CPU:$E2E4 PRG:22E4 85 02
|
|
|
|
lda #$40 ; CPU:$E2E6 PRG:22E6 A9 40
|
|
sta $03 ; CPU:$E2E8 PRG:22E8 85 03
|
|
|
|
lda $47 ; CPU:$E2EA PRG:22EA A5 47
|
|
and $46 ; CPU:$E2EC PRG:22EC 25 46
|
|
beq @E2F4 ; CPU:$E2EE PRG:22EE F0 04
|
|
|
|
lda #$28 ; CPU:$E2F0 PRG:22F0 A9 28
|
|
sta $02 ; CPU:$E2F2 PRG:22F2 85 02
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E2F4
|
|
; Load compressed-map source pointer.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E2F4:
|
|
lda MazeDataPointerBytes+1 ; CPU:$E2F4 PRG:22F4 AD F7 FF
|
|
sta $01 ; CPU:$E2F7 PRG:22F7 85 01
|
|
|
|
lda MazeDataPointerBytes ; CPU:$E2F9 PRG:22F9 AD F6 FF
|
|
sta $00 ; CPU:$E2FC PRG:22FC 85 00
|
|
|
|
ldx #$1B ; CPU:$E2FE PRG:22FE A2 1B
|
|
ldy #$00 ; CPU:$E300 PRG:2300 A0 00
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E302
|
|
; Set PPU destination for the next row.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E302:
|
|
lda PPUSTATUS ; CPU:$E302 PRG:2302 AD 02 20
|
|
|
|
lda $02 ; CPU:$E305 PRG:2305 A5 02
|
|
sta PPUADDR ; CPU:$E307 PRG:2307 8D 06 20
|
|
|
|
lda $03 ; CPU:$E30A PRG:230A A5 03
|
|
sta PPUADDR ; CPU:$E30C PRG:230C 8D 06 20
|
|
|
|
lda #$16 ; CPU:$E30F PRG:230F A9 16
|
|
sta $04 ; CPU:$E311 PRG:2311 85 04
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E313
|
|
; Start decoding the next compressed source byte.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E313:
|
|
lda #$00 ; CPU:$E313 PRG:2313 A9 00
|
|
sta $05 ; CPU:$E315 PRG:2315 85 05
|
|
|
|
lda ($00),y ; CPU:$E317 PRG:2317 B1 00
|
|
|
|
asl ; CPU:$E319 PRG:2319 0A
|
|
rol $05 ; CPU:$E31A PRG:231A 26
|
|
|
|
asl ; CPU:$E31B PRG:231B 05
|
|
rol $05 ; CPU:$E31C PRG:231C 0A
|
|
|
|
lda ($00),y ; CPU:$E31D PRG:231D 26 05
|
|
and #$3F ; CPU:$E31F PRG:231F B1 00
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E321
|
|
; Repeat the decoded value according to the repeat count in $05.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E321:
|
|
sta PPUDATA ; CPU:$E321 PRG:2321 29 3F 8D
|
|
|
|
dec $04 ; CPU:$E324 PRG:2324 07 20
|
|
dec $05 ; CPU:$E326 PRG:2326 C6 04
|
|
bpl @E321 ; CPU:$E328 PRG:2328 C6 05
|
|
|
|
iny ; CPU:$E32A PRG:232A 10
|
|
bne @E32F ; CPU:$E32B PRG:232B F7 C8
|
|
|
|
inc $01 ; CPU:$E32D PRG:232D D0 02
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E32F
|
|
; Continue until the current row contains $16 output bytes.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E32F:
|
|
lda $04 ; CPU:$E32F PRG:232F E6 01
|
|
bne @E313 ; CPU:$E331 PRG:2331 A5 04
|
|
|
|
lda $03 ; CPU:$E333 PRG:2333 D0 DE
|
|
clc ; CPU:$E335 PRG:2335 A5
|
|
adc #$20 ; CPU:$E336 PRG:2336 03 18
|
|
sta $03 ; CPU:$E338 PRG:2338 69 20
|
|
|
|
lda $02 ; CPU:$E33A PRG:233A 85 03
|
|
adc #$00 ; CPU:$E33C PRG:233C A5 02
|
|
sta $02 ; CPU:$E33E PRG:233E 69 00
|
|
|
|
dex ; CPU:$E340 PRG:2340 85
|
|
bne @E302 ; CPU:$E341 PRG:2341 02 CA
|
|
|
|
|
|
;==============================================================================
|
|
; $E345-$E381: Draw additional nametable decoration strips.
|
|
;==============================================================================
|
|
|
|
ldy #$02 ; CPU:$E343 PRG:2343 D0 BD
|
|
|
|
lda #$21 ; CPU:$E345 PRG:2345 A0 02
|
|
sta $00 ; CPU:$E347 PRG:2347 A9 21
|
|
|
|
lda #$D6 ; CPU:$E349 PRG:2349 85 00
|
|
sta $01 ; CPU:$E34B PRG:234B A9 D6
|
|
|
|
lda $47 ; CPU:$E34D PRG:234D 85 01
|
|
and $46 ; CPU:$E34F PRG:234F A5 47
|
|
beq @E359 ; CPU:$E351 PRG:2351 25 46
|
|
|
|
lda #$29 ; CPU:$E353 PRG:2353 F0 04
|
|
sta $00 ; CPU:$E355 PRG:2355 A9 29
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E359
|
|
; Start one decoration strip.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E359:
|
|
ldx #$07 ; CPU:$E357 PRG:2357 85 00
|
|
|
|
lda PPUSTATUS ; CPU:$E359 PRG:2359 A2 07 AD
|
|
|
|
lda $00 ; CPU:$E35C PRG:235C 02 20
|
|
sta PPUADDR ; CPU:$E35E PRG:235E A5 00 8D
|
|
|
|
lda $01 ; CPU:$E361 PRG:2361 06 20
|
|
sta PPUADDR ; CPU:$E363 PRG:2363 A5 01 8D
|
|
|
|
lda MazeNametableDecorationTiles,y ; CPU:$E366 PRG:2366 06 20 B9
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E36B
|
|
; Write the selected table value eight times.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E36B:
|
|
sta PPUDATA ; CPU:$E369 PRG:2369 82 E3 8D
|
|
|
|
dex ; CPU:$E36C PRG:236C 07
|
|
bpl @E36B ; CPU:$E36D PRG:236D 20 CA
|
|
|
|
lda $01 ; CPU:$E36F PRG:236F 10 FA
|
|
clc ; CPU:$E371 PRG:2371 A5
|
|
adc #$20 ; CPU:$E372 PRG:2372 01 18
|
|
sta $01 ; CPU:$E374 PRG:2374 69 20
|
|
|
|
lda #$00 ; CPU:$E376 PRG:2376 85 01
|
|
adc $00 ; CPU:$E378 PRG:2378 A9 00
|
|
sta $00 ; CPU:$E37A PRG:237A 65 00
|
|
|
|
dey ; CPU:$E37C PRG:237C 85
|
|
bpl @E359 ; CPU:$E37D PRG:237D 00 88
|
|
|
|
rts ; CPU:$E37F PRG:237F 10
|
|
|
|
;==============================================================================
|
|
; $E382-$E385: Gameplay Nametable Decoration Table
|
|
;==============================================================================
|
|
|
|
MazeNametableDecorationTiles:
|
|
.byte $2D,$04,$2D ; CPU:$E382 PRG:2382 2D 04 2D
|
|
;==============================================================================
|
|
; $E385-$E3FE: Initialize Gameplay Nametable Regions
|
|
;
|
|
; Fills gameplay nametable regions with tile $2D, then clears the corresponding
|
|
; attribute-table regions.
|
|
;
|
|
; Address-based global labels are used for shared entry points to avoid ca65
|
|
; cheap-local scope issues and collisions with previously defined symbols.
|
|
;==============================================================================
|
|
|
|
ClearGameplayNametables:
|
|
lda PPUSTATUS ; CPU:$E385 PRG:2385 AD 02 20
|
|
|
|
lda #$20 ; CPU:$E388 PRG:2388 A9 20
|
|
sta PPUADDR ; CPU:$E38A PRG:238A 8D 06 20
|
|
|
|
lda #$00 ; CPU:$E38D PRG:238D A9 00
|
|
sta PPUADDR ; CPU:$E38F PRG:238F 8D 06 20
|
|
|
|
lda #$01 ; CPU:$E392 PRG:2392 A9 01
|
|
sta $02 ; CPU:$E394 PRG:2394 85 02
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E396
|
|
; Shared entry used for another nametable pass.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ClearGameplayNametablesSecondPass:
|
|
lda #$01 ; CPU:$E396 PRG:2396 A9 01
|
|
sta $03 ; CPU:$E398 PRG:2398 85 03
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E39A
|
|
; Initialize fill counters.
|
|
;------------------------------------------------------------------------------
|
|
|
|
InitializeNametableFillCounters:
|
|
lda #$03 ; CPU:$E39A PRG:239A A9 03
|
|
sta $00 ; CPU:$E39C PRG:239C 85 00
|
|
|
|
lda #$C0 ; CPU:$E39E PRG:239E A9 C0
|
|
sta $01 ; CPU:$E3A0 PRG:23A0 85 01
|
|
|
|
lda #$2D ; CPU:$E3A2 PRG:23A2 A9 2D
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E3A4
|
|
; Shared fill loop.
|
|
;------------------------------------------------------------------------------
|
|
|
|
FillNametableByte:
|
|
sta PPUDATA ; CPU:$E3A4 PRG:23A4 8D 07 20
|
|
|
|
dec $01 ; CPU:$E3A7 PRG:23A7 C6 01
|
|
bne FillNametableByte ; CPU:$E3A9 PRG:23A9 D0 F9
|
|
|
|
dec $00 ; CPU:$E3AB PRG:23AB C6 00
|
|
bpl FillNametableByte ; CPU:$E3AD PRG:23AD 10 F5
|
|
|
|
dec $03 ; CPU:$E3AF PRG:23AF C6 03
|
|
bne AdvanceNametableFillPass ; CPU:$E3B1 PRG:23B1 D0 08
|
|
|
|
lda #$40 ; CPU:$E3B3 PRG:23B3 A9 40
|
|
sta $01 ; CPU:$E3B5 PRG:23B5 85 01
|
|
|
|
lda #$00 ; CPU:$E3B7 PRG:23B7 A9 00
|
|
beq FillNametableByte ; CPU:$E3B9 PRG:23B9 F0 E9
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E3BB
|
|
; Advance to alternate nametable / next phase.
|
|
;------------------------------------------------------------------------------
|
|
|
|
AdvanceNametableFillPass:
|
|
dec $02 ; CPU:$E3BB PRG:23BB C6 02
|
|
bne ClearGameplayAttributeTables ; CPU:$E3BD PRG:23BD D0 10
|
|
|
|
lda PPUSTATUS ; CPU:$E3BF PRG:23BF AD 02 20
|
|
|
|
lda #$28 ; CPU:$E3C2 PRG:23C2 A9 28
|
|
sta PPUADDR ; CPU:$E3C4 PRG:23C4 8D 06 20
|
|
|
|
lda #$00 ; CPU:$E3C7 PRG:23C7 A9 00
|
|
sta PPUADDR ; CPU:$E3C9 PRG:23C9 8D 06 20
|
|
|
|
jmp ClearGameplayNametablesSecondPass ; CPU:$E3CC PRG:23CC 4C 96 E3
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E3CF
|
|
; Begin clearing attribute-table regions.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ClearGameplayAttributeTables:
|
|
lda #$01 ; CPU:$E3CF PRG:23CF A9 01
|
|
sta $00 ; CPU:$E3D1 PRG:23D1 85 00
|
|
|
|
lda PPUSTATUS ; CPU:$E3D3 PRG:23D3 AD 02 20
|
|
|
|
lda #$23 ; CPU:$E3D6 PRG:23D6 A9 23
|
|
sta PPUADDR ; CPU:$E3D8 PRG:23D8 8D 06 20
|
|
|
|
lda #$C0 ; CPU:$E3DB PRG:23DB A9 C0
|
|
sta PPUADDR ; CPU:$E3DD PRG:23DD 8D 06 20
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E3E0
|
|
; Shared attribute-clear setup.
|
|
;------------------------------------------------------------------------------
|
|
|
|
BeginAttributeTableClear:
|
|
lda #$00 ; CPU:$E3E0 PRG:23E0 A9 00
|
|
tay ; CPU:$E3E2 PRG:23E2 A8
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E3E3
|
|
; Write $20 zero bytes to PPUDATA.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ClearAttributeTableLoop:
|
|
sta PPUDATA ; CPU:$E3E3 PRG:23E3 8D 07 20
|
|
|
|
iny ; CPU:$E3E6 PRG:23E6 C8
|
|
cpy #$20 ; CPU:$E3E7 PRG:23E7 C0 20
|
|
bne ClearAttributeTableLoop ; CPU:$E3E9 PRG:23E9 D0 F8
|
|
|
|
dec $00 ; CPU:$E3EB PRG:23EB C6 00
|
|
bne ClearSecondAttributeTable ; CPU:$E3ED PRG:23ED D0 01
|
|
|
|
rts ; CPU:$E3EF PRG:23EF 60
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E3F0
|
|
; Set destination to the second attribute table, $2BC0.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ClearSecondAttributeTable:
|
|
lda PPUSTATUS ; CPU:$E3F0 PRG:23F0 AD 02 20
|
|
|
|
lda #$2B ; CPU:$E3F3 PRG:23F3 A9 2B
|
|
sta PPUADDR ; CPU:$E3F5 PRG:23F5 8D 06 20
|
|
|
|
lda #$C0 ; CPU:$E3F8 PRG:23F8 A9 C0
|
|
sta PPUADDR ; CPU:$E3FA PRG:23FA 8D 06 20
|
|
|
|
bne BeginAttributeTableClear ; CPU:$E3FD PRG:23FD D0 E1
|
|
|
|
;==============================================================================
|
|
; $E3FF-$E473: Draw Gameplay Numeric / Status Fields
|
|
;
|
|
; Local:
|
|
; Configures a PPU destination and repeatedly draws numeric fields through
|
|
; the helper at DrawSixDigitScore.
|
|
;
|
|
; Initial destination/configuration:
|
|
;
|
|
; $00/$01 = PPU destination
|
|
; $04 = destination stride
|
|
; X = index into a pointer table at ScoreFieldSourcePointerTable
|
|
;
|
|
; The destination and table index vary depending on $47 & $46.
|
|
;
|
|
; Three fields are drawn per pass. The routine may perform another pass
|
|
; according to $47 and the current field counter.
|
|
;
|
|
; Global:
|
|
; Called by GameModeState00 as part of gameplay initialization.
|
|
;
|
|
; Notes:
|
|
; DrawSixDigitScore renders one numeric field using the source pointer
|
|
; loaded from the table at ScoreFieldSourcePointerTable.
|
|
;==============================================================================
|
|
|
|
DrawGameplayScoreFields:
|
|
lda #$20 ; CPU:$E3FF PRG:23FF A9 20
|
|
sta $00 ; CPU:$E401 PRG:2401 85 00
|
|
|
|
lda #$B6 ; CPU:$E403 PRG:2403 A9 B6
|
|
sta $01 ; CPU:$E405 PRG:2405 85 01
|
|
|
|
lda #$80 ; CPU:$E407 PRG:2407 A9 80
|
|
sta $04 ; CPU:$E409 PRG:2409 85 04
|
|
|
|
ldx #$00 ; CPU:$E40B PRG:240B A2 00
|
|
|
|
lda $47 ; CPU:$E40D PRG:240D A5 47
|
|
and $46 ; CPU:$E40F PRG:240F 25 46
|
|
beq @E429 ; CPU:$E411 PRG:2411 F0 18
|
|
|
|
lda #$28 ; CPU:$E413 PRG:2413 A9 28
|
|
sta $00 ; CPU:$E415 PRG:2415 85 00
|
|
|
|
bne @E429 ; CPU:$E417 PRG:2417 D0 12
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; Alternate setup path.
|
|
;------------------------------------------------------------------------------
|
|
|
|
lda #$20 ; CPU:$E419 PRG:2419 A9 20
|
|
sta $00 ; CPU:$E41B PRG:241B 85 00
|
|
|
|
lda #$83 ; CPU:$E41D PRG:241D A9 83
|
|
sta $01 ; CPU:$E41F PRG:241F 85 01
|
|
|
|
lda #$09 ; CPU:$E421 PRG:2421 A9 09
|
|
sta $04 ; CPU:$E423 PRG:2423 85 04
|
|
|
|
lda #$01 ; CPU:$E425 PRG:2425 A9 01
|
|
sta $47 ; CPU:$E427 PRG:2427 85 47
|
|
|
|
ldx #$0C ; CPU:$E429 PRG:2429 A2 0C
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E429
|
|
; Adjust lookup-table index for alternate player/mode state.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E429:
|
|
lda $47 ; CPU:$E42B PRG:242B A5 47
|
|
and $46 ; CPU:$E42D PRG:242D 25 46
|
|
beq @E436 ; CPU:$E42F PRG:242F F0 05
|
|
|
|
txa ; CPU:$E431 PRG:2431 8A
|
|
clc ; CPU:$E432 PRG:2432 18
|
|
adc #$06 ; CPU:$E433 PRG:2433 69 06
|
|
tax ; CPU:$E435 PRG:2435 AA
|
|
|
|
|
|
@E436:
|
|
lda #$03 ; CPU:$E436 PRG:2436 A9 03
|
|
sta $05 ; CPU:$E438 PRG:2438 85 05
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E43A: render one status field.
|
|
;------------------------------------------------------------------------------
|
|
|
|
@E43A:
|
|
lda PPUSTATUS ; CPU:$E43A PRG:243A AD 02 20
|
|
|
|
lda $00 ; CPU:$E43D PRG:243D A5 00
|
|
sta PPUADDR ; CPU:$E43F PRG:243F 8D 06 20
|
|
|
|
lda $01 ; CPU:$E442 PRG:2442 A5 01
|
|
sta PPUADDR ; CPU:$E444 PRG:2444 8D 06 20
|
|
|
|
lda ScoreFieldSourcePointerTable,x ; CPU:$E447 PRG:2447 BD 9F E4
|
|
sta $02 ; CPU:$E44A PRG:244A 85 02
|
|
|
|
lda ScoreFieldSourcePointerTable+1,x ; CPU:$E44C PRG:244C BD A0 E4
|
|
sta $03 ; CPU:$E44F PRG:244F 85 03
|
|
|
|
jsr DrawSixDigitScore ; CPU:$E451 PRG:2451 20 74 E4
|
|
|
|
inx ; CPU:$E454 PRG:2454 E8
|
|
inx ; CPU:$E455 PRG:2455 E8
|
|
|
|
lda $01 ; CPU:$E456 PRG:2456 A5 01
|
|
clc ; CPU:$E458 PRG:2458 18
|
|
adc $04 ; CPU:$E459 PRG:2459 65 04
|
|
sta $01 ; CPU:$E45B PRG:245B 85 01
|
|
|
|
lda #$00 ; CPU:$E45D PRG:245D A9 00
|
|
adc $00 ; CPU:$E45F PRG:245F 65 00
|
|
sta $00 ; CPU:$E461 PRG:2461 85 00
|
|
|
|
dec $05 ; CPU:$E463 PRG:2463 C6 05
|
|
|
|
lda $05 ; CPU:$E465 PRG:2465 A5 05
|
|
cmp #$01 ; CPU:$E467 PRG:2467 C9 01
|
|
bne @E46D ; CPU:$E469 PRG:2469 D0 04
|
|
|
|
lda $47 ; CPU:$E46B PRG:246B A5 47
|
|
beq @E473 ; CPU:$E46D PRG:246D F0 04
|
|
|
|
|
|
@E46D:
|
|
lda $05 ; CPU:$E46F PRG:246F A5 05
|
|
bne @E43A ; CPU:$E471 PRG:2471 D0 C7
|
|
|
|
|
|
@E473:
|
|
rts ; CPU:$E473 PRG:2473 60
|
|
|
|
;==============================================================================
|
|
; $E474-$E49E: Draw Six-Digit Numeric Field
|
|
;
|
|
; Input:
|
|
; $02/$03 = pointer to packed numeric values
|
|
;
|
|
; Local:
|
|
; Processes six source values from index 5 down to 0.
|
|
;
|
|
; Leading values whose low nibble is zero are rendered as spaces ($20).
|
|
; Once a nonzero low nibble is encountered, remaining values are converted
|
|
; through the shared conversion entry at $E1CE and written to PPUDATA.
|
|
;
|
|
; The final value at Y=0 is always converted, after which a trailing $30
|
|
; character is written.
|
|
;
|
|
; Notes:
|
|
; The conversion calls MUST target $E1CE, not $E1CA. $E1CE is the shared
|
|
; entry that begins with AND #$0F, while $E1CA additionally shifts A right
|
|
; four times.
|
|
;==============================================================================
|
|
DrawSixDigitScore:
|
|
ldy #$05 ; CPU:$E474 PRG:2474 A0 05
|
|
|
|
|
|
SkipLeadingZeroDigits:
|
|
lda ($02),y ; CPU:$E476 PRG:2476 B1 02
|
|
and #$0F ; CPU:$E478 PRG:2478 29 0F
|
|
bne ConvertCurrentScoreDigit ; CPU:$E47A PRG:247A D0 0C
|
|
|
|
lda #$20 ; CPU:$E47C PRG:247C A9 20
|
|
sta PPUDATA ; CPU:$E47E PRG:247E 8D 07 20
|
|
|
|
dey ; CPU:$E481 PRG:2481 88
|
|
bne SkipLeadingZeroDigits ; CPU:$E482 PRG:2482 D0 F2
|
|
|
|
beq DrawFinalScoreDigit ; CPU:$E484 PRG:2484 F0 0B
|
|
|
|
|
|
LoadNextScoreDigit:
|
|
lda ($02),y ; CPU:$E486 PRG:2486 B1 02
|
|
|
|
|
|
ConvertCurrentScoreDigit:
|
|
jsr $E1CE ; CPU:$E488 PRG:2488 20 CE E1
|
|
|
|
sta PPUDATA ; CPU:$E48B PRG:248B 8D 07 20
|
|
|
|
dey ; CPU:$E48E PRG:248E 88
|
|
bne LoadNextScoreDigit ; CPU:$E48F PRG:248F D0 F5
|
|
|
|
|
|
DrawFinalScoreDigit:
|
|
lda ($02),y ; CPU:$E491 PRG:2491 B1 02
|
|
|
|
jsr $E1CE ; CPU:$E493 PRG:2493 20 CE E1
|
|
|
|
sta PPUDATA ; CPU:$E496 PRG:2496 8D 07 20
|
|
|
|
lda #$30 ; CPU:$E499 PRG:2499 A9 30
|
|
sta PPUDATA ; CPU:$E49B PRG:249B 8D 07 20
|
|
|
|
rts ; CPU:$E49E PRG:249E 60
|
|
;==============================================================================
|
|
; $E49F-$E4B0: Gameplay Status Field Source Pointer Table
|
|
;
|
|
; Local:
|
|
; Nine little-endian zero-page/RAM pointers used by the gameplay status-field
|
|
; drawing routine beginning at $E3FF.
|
|
;
|
|
; X indexes this table in steps of two. Each selected address is loaded into
|
|
; $02/$03 and passed to DrawSixDigitScore.
|
|
;
|
|
; Global:
|
|
; Selects the numeric/state arrays rendered into the different gameplay
|
|
; status display fields.
|
|
;==============================================================================
|
|
|
|
ScoreFieldSourcePointerTable:
|
|
.word $0061 ; CPU:$E49F PRG:249F 61 00
|
|
.word $0070 ; CPU:$E4A1 PRG:24A1 70 00
|
|
.word $0080 ; CPU:$E4A3 PRG:24A3 80 00
|
|
|
|
.word $0061 ; CPU:$E4A5 PRG:24A5 61 00
|
|
.word $0080 ; CPU:$E4A7 PRG:24A7 80 00
|
|
.word $0070 ; CPU:$E4A9 PRG:24A9 70 00
|
|
|
|
.word $0070 ; CPU:$E4AB PRG:24AB 70 00
|
|
.word $0061 ; CPU:$E4AD PRG:24AD 61 00
|
|
.word $0080 ; CPU:$E4AF PRG:24AF 80 00
|
|
|
|
;==============================================================================
|
|
; $E4B1-$E501: Build Entity Direction Candidate List
|
|
;
|
|
; Input:
|
|
; $00/$01 = pointer to direction/path data
|
|
; $0A/$0B = comparison values prepared by the caller
|
|
; X = current entity slot index
|
|
;
|
|
; Output:
|
|
; $0C-$0F = candidate direction values, with invalid entries marked $FF
|
|
;
|
|
; Local:
|
|
; First clears all four candidate entries to $FF.
|
|
;
|
|
; Then examines four values through ($00),Y. A candidate is accepted when
|
|
; either:
|
|
;
|
|
; value == $0A
|
|
;
|
|
; or:
|
|
;
|
|
; (value & $F8) != 0
|
|
; and value == $0B
|
|
;
|
|
; Accepted entries store their Y index into $0C-$0F.
|
|
;
|
|
; The entity's reverse/current-excluded direction is then calculated from
|
|
; $B9,X and explicitly removed from the candidate list.
|
|
;
|
|
; Finally performs up to three passes compacting $FF holes by shifting the
|
|
; following entry left.
|
|
;
|
|
; Global:
|
|
; Called by EntityTargetCommon at $D778 before entity direction selection.
|
|
;
|
|
; Notes:
|
|
; $0C-$0F therefore form a filtered list of legal direction indices.
|
|
;==============================================================================
|
|
|
|
BuildLegalDirectionList:
|
|
ldy #$FF ; CPU:$E4B1 PRG:24B1 A0 FF
|
|
|
|
sty $0C ; CPU:$E4B3 PRG:24B3 84 0C
|
|
sty $0D ; CPU:$E4B5 PRG:24B5 84 0D
|
|
sty $0E ; CPU:$E4B7 PRG:24B7 84 0E
|
|
sty $0F ; CPU:$E4B9 PRG:24B9 84 0F
|
|
|
|
iny ; CPU:$E4BB PRG:24BB C8
|
|
|
|
|
|
ScanDirectionCandidate:
|
|
lda ($00),y ; CPU:$E4BC PRG:24BC B1 00
|
|
cmp $0A ; CPU:$E4BE PRG:24BE C5 0A
|
|
beq AcceptDirectionCandidate ; CPU:$E4C0 PRG:24C0 F0 08
|
|
|
|
and #$F8 ; CPU:$E4C2 PRG:24C2 29 F8
|
|
beq AcceptDirectionCandidate ; CPU:$E4C4 PRG:24C4 F0 04
|
|
|
|
cmp $0B ; CPU:$E4C6 PRG:24C6 C5 0B
|
|
bne NextDirectionCandidate ; CPU:$E4C8 PRG:24C8 D0 04
|
|
|
|
|
|
AcceptDirectionCandidate:
|
|
tya ; CPU:$E4CA PRG:24CA 98
|
|
sta $000C,y ; CPU:$E4CB PRG:24CB 99 0C 00
|
|
|
|
|
|
NextDirectionCandidate:
|
|
iny ; CPU:$E4CE PRG:24CE C8
|
|
cpy #$04 ; CPU:$E4CF PRG:24CF C0 04
|
|
bne ScanDirectionCandidate ; CPU:$E4D1 PRG:24D1 D0 E9
|
|
|
|
lda $B9,x ; CPU:$E4D3 PRG:24D3 B5 B9
|
|
clc ; CPU:$E4D5 PRG:24D5 18
|
|
adc #$02 ; CPU:$E4D6 PRG:24D6 69 02
|
|
and #$03 ; CPU:$E4D8 PRG:24D8 29 03
|
|
tay ; CPU:$E4DA PRG:24DA A8
|
|
|
|
lda #$FF ; CPU:$E4DB PRG:24DB A9 FF
|
|
sta $000C,y ; CPU:$E4DD PRG:24DD 99 0C 00
|
|
|
|
lda #$03 ; CPU:$E4E0 PRG:24E0 A9 03
|
|
sta $0B ; CPU:$E4E2 PRG:24E2 85 0B
|
|
|
|
|
|
CompactDirectionListPass:
|
|
ldy #$00 ; CPU:$E4E4 PRG:24E4 A0 00
|
|
|
|
|
|
CompactDirectionListEntry:
|
|
lda $000C,y ; CPU:$E4E6 PRG:24E6 B9 0C 00
|
|
cmp #$FF ; CPU:$E4E9 PRG:24E9 C9 FF
|
|
bne NextDirectionListEntry ; CPU:$E4EB PRG:24EB D0 0B
|
|
|
|
lda $000D,y ; CPU:$E4ED PRG:24ED B9 0D 00
|
|
sta $000C,y ; CPU:$E4F0 PRG:24F0 99 0C 00
|
|
|
|
lda #$FF ; CPU:$E4F3 PRG:24F3 A9 FF
|
|
sta $000D,y ; CPU:$E4F5 PRG:24F5 99 0D 00
|
|
|
|
|
|
NextDirectionListEntry:
|
|
iny ; CPU:$E4F8 PRG:24F8 C8
|
|
cpy #$03 ; CPU:$E4F9 PRG:24F9 C0 03
|
|
bne CompactDirectionListEntry ; CPU:$E4FB PRG:24FB D0 E9
|
|
|
|
dec $0B ; CPU:$E4FD PRG:24FD C6 0B
|
|
bne CompactDirectionListPass ; CPU:$E4FF PRG:24FF D0 E3
|
|
|
|
rts ; CPU:$E501 PRG:2501 60
|
|
|
|
;==============================================================================
|
|
; $E502-$E53B: Draw Gameplay Initialization Data
|
|
;
|
|
; Local:
|
|
; Reads compact PPU command data beginning at $E53C and writes the payloads
|
|
; directly to PPUDATA.
|
|
;
|
|
; X selects between two passes/variants.
|
|
; Y indexes the command stream.
|
|
; $00 holds the number of bytes remaining in the current payload.
|
|
;
|
|
; Global:
|
|
; Called from GameModeState00 during gameplay initialization.
|
|
;==============================================================================
|
|
|
|
DrawGameplayHudLabels:
|
|
ldx #$01 ; CPU:$E502 PRG:2502 A2 01
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E504
|
|
; Reset command-stream index for a pass.
|
|
;------------------------------------------------------------------------------
|
|
|
|
InitData_E504:
|
|
ldy #$00 ; CPU:$E504 PRG:2504 A0 00
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E506
|
|
; Start one command record.
|
|
;------------------------------------------------------------------------------
|
|
|
|
InitData_E506:
|
|
lda $E53C,y ; CPU:$E506 PRG:2506 B9 3C E5
|
|
|
|
cpx #$00 ; CPU:$E509 PRG:2509 E0 00
|
|
bne InitData_E50F ; CPU:$E50B PRG:250B D0 02
|
|
|
|
adc #$07 ; CPU:$E50D PRG:250D 69 07
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E50F
|
|
; Write PPU destination address.
|
|
;------------------------------------------------------------------------------
|
|
|
|
InitData_E50F:
|
|
sta PPUADDR ; CPU:$E50F PRG:250F 8D 06 20
|
|
|
|
iny ; CPU:$E512 PRG:2512 C8
|
|
|
|
lda $E53C,y ; CPU:$E513 PRG:2513 B9 3C E5
|
|
sta PPUADDR ; CPU:$E516 PRG:2516 8D 06 20
|
|
|
|
iny ; CPU:$E519 PRG:2519 C8
|
|
|
|
lda $E53C,y ; CPU:$E51A PRG:251A B9 3C E5
|
|
sta $00 ; CPU:$E51D PRG:251D 85 00
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E51F
|
|
; Write record payload.
|
|
;------------------------------------------------------------------------------
|
|
|
|
InitData_E51F:
|
|
iny ; CPU:$E51F PRG:251F C8
|
|
|
|
lda $E53C,y ; CPU:$E520 PRG:2520 B9 3C E5
|
|
sta PPUDATA ; CPU:$E523 PRG:2523 8D 07 20
|
|
|
|
dec $00 ; CPU:$E526 PRG:2526 C6 00
|
|
bne InitData_E51F ; CPU:$E528 PRG:2528 D0 F5
|
|
|
|
iny ; CPU:$E52A PRG:252A C8
|
|
|
|
cpy #$11 ; CPU:$E52B PRG:252B C0 11
|
|
bne InitData_E534 ; CPU:$E52D PRG:252D D0 05
|
|
|
|
lda $47 ; CPU:$E52F PRG:252F A5 47
|
|
bne InitData_E534 ; CPU:$E531 PRG:2531 D0 01
|
|
|
|
rts ; CPU:$E533 PRG:2533 60
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E534
|
|
; Continue through the first/second stream section.
|
|
;------------------------------------------------------------------------------
|
|
|
|
InitData_E534:
|
|
cpy #$17 ; CPU:$E534 PRG:2534 C0 17
|
|
bne InitData_E506 ; CPU:$E536 PRG:2536 D0 CE
|
|
|
|
dex ; CPU:$E538 PRG:2538 CA
|
|
beq InitData_E504 ; CPU:$E539 PRG:2539 F0 C9
|
|
|
|
rts ; CPU:$E53B PRG:253B 60
|
|
|
|
;==============================================================================
|
|
; $E53C-$E552: Gameplay Initialization PPU Command Data
|
|
;
|
|
; Record format:
|
|
; byte 0 = PPU address high
|
|
; byte 1 = PPU address low
|
|
; byte 2 = payload length
|
|
; remaining bytes = payload written to PPUDATA
|
|
;==============================================================================
|
|
|
|
GameplayHudInitializationData:
|
|
|
|
; $E53C: PPU $2076, 8-byte payload
|
|
.byte $20,$76,$08 ; CPU:$E53C PRG:253C 20 76 08
|
|
.byte $B4,$B5,$B6,$B7,$B8,$B9,$BA,$BB ; CPU:$E53F PRG:253F B4 B5 B6 B7 B8 B9 BA BB
|
|
|
|
; $E547: PPU $20F7, 3-byte payload
|
|
.byte $20,$F7,$03 ; CPU:$E547 PRG:2547 20 F7 03
|
|
.byte $B0,$B3,$B2 ; CPU:$E54A PRG:254A B0 B3 B2
|
|
|
|
; $E54D: PPU $2177, 3-byte payload
|
|
.byte $21,$77,$03 ; CPU:$E54D PRG:254D 21 77 03
|
|
.byte $B1,$B3,$B2 ; CPU:$E550 PRG:2550 B1 B3 B2
|
|
|
|
;==============================================================================
|
|
; $E553-$E5C0: Draw Progression / Status Markers
|
|
;
|
|
; Local:
|
|
; Returns immediately when $67 is zero.
|
|
;
|
|
; Otherwise computes:
|
|
;
|
|
; count = min($67 + 1, $07)
|
|
;
|
|
; and stores that in $02.
|
|
;
|
|
; Initializes:
|
|
;
|
|
; $03 = $04
|
|
; $00/$01 = $2317
|
|
;
|
|
; If ($46 & $47) != 0, the high destination byte is adjusted by $08.
|
|
;
|
|
; The routine then performs nested loops, calling the helper at $E59A with
|
|
; Y=$3C. The helper writes a 2x2-style pattern at the current PPU position.
|
|
;
|
|
; Global:
|
|
; Called during gameplay initialization to draw a progression/status display.
|
|
;
|
|
; Notes:
|
|
; $E59A is a valid internal helper entry point within this routine.
|
|
;==============================================================================
|
|
|
|
DrawLevelProgressMarkers:
|
|
lda $67 ; CPU:$E553 PRG:2553 A5 67
|
|
bne Progression_E558 ; CPU:$E555 PRG:2555 D0 01
|
|
|
|
rts ; CPU:$E557 PRG:2557 60
|
|
|
|
|
|
Progression_E558:
|
|
clc ; CPU:$E558 PRG:2558 18
|
|
adc #$01 ; CPU:$E559 PRG:2559 69 01
|
|
|
|
cmp #$07 ; CPU:$E55B PRG:255B C9 07
|
|
bcc Progression_E55F ; CPU:$E55D PRG:255D 90 02
|
|
|
|
lda #$07 ; CPU:$E55F PRG:255F A9 07
|
|
|
|
|
|
Progression_E55F:
|
|
sta $02 ; CPU:$E561 PRG:2561 85 02
|
|
|
|
lda #$04 ; CPU:$E563 PRG:2563 A9 04
|
|
sta $03 ; CPU:$E565 PRG:2565 85 03
|
|
|
|
lda #$23 ; CPU:$E567 PRG:2567 A9 23
|
|
sta $00 ; CPU:$E569 PRG:2569 85 00
|
|
|
|
lda #$17 ; CPU:$E56B PRG:256B A9 17
|
|
sta $01 ; CPU:$E56D PRG:256D 85 01
|
|
|
|
lda $46 ; CPU:$E56F PRG:256F A5 46
|
|
and $47 ; CPU:$E571 PRG:2571 25 47
|
|
beq Progression_E57C ; CPU:$E573 PRG:2573 F0 07
|
|
|
|
lda $00 ; CPU:$E575 PRG:2575 A5 00
|
|
clc ; CPU:$E577 PRG:2577 18
|
|
adc #$08 ; CPU:$E578 PRG:2578 69 08
|
|
sta $00 ; CPU:$E57A PRG:257A 85 00
|
|
|
|
|
|
Progression_E57C:
|
|
dec $02 ; CPU:$E57C PRG:257C C6 02
|
|
bne Progression_E581 ; CPU:$E57E PRG:257E D0 01
|
|
|
|
rts ; CPU:$E580 PRG:2580 60
|
|
|
|
|
|
Progression_E581:
|
|
dec $03 ; CPU:$E581 PRG:2581 C6 03
|
|
bne Progression_E58A ; CPU:$E583 PRG:2583 D0 07
|
|
|
|
lda $01 ; CPU:$E585 PRG:2585 A5 01
|
|
clc ; CPU:$E587 PRG:2587 18
|
|
adc #$3A ; CPU:$E588 PRG:2588 69 3A
|
|
sta $01 ; CPU:$E58A PRG:258A 85 01
|
|
|
|
|
|
Progression_E58A:
|
|
ldy #$3C ; CPU:$E58C PRG:258C A0 3C
|
|
|
|
jsr Draw2x2Marker ; CPU:$E58E PRG:258E 20 9A E5
|
|
|
|
lda $01 ; CPU:$E591 PRG:2591 A5 01
|
|
clc ; CPU:$E593 PRG:2593 18
|
|
adc #$02 ; CPU:$E594 PRG:2594 69 02
|
|
sta $01 ; CPU:$E596 PRG:2596 85 01
|
|
|
|
bne Progression_E57C ; CPU:$E598 PRG:2598 D0 E2
|
|
|
|
;==============================================================================
|
|
; $E59A-$E5C0: Draw 2x2 Progression Marker
|
|
;
|
|
; Input:
|
|
; $00/$01 = first PPU destination
|
|
; Y = first tile value
|
|
;
|
|
; Effect:
|
|
; Writes Y and Y+1 horizontally, then Y+2 and Y+3 one row ($20 bytes)
|
|
; below the initial destination.
|
|
;==============================================================================
|
|
|
|
Draw2x2Marker:
|
|
lda $00 ; CPU:$E59A PRG:259A A5 00
|
|
sta PPUADDR ; CPU:$E59C PRG:259C 8D 06 20
|
|
|
|
lda $01 ; CPU:$E59F PRG:259F A5 01
|
|
sta PPUADDR ; CPU:$E5A1 PRG:25A1 8D 06 20
|
|
|
|
sty PPUDATA ; CPU:$E5A4 PRG:25A4 8C 07 20
|
|
|
|
iny ; CPU:$E5A7 PRG:25A7 C8
|
|
sty PPUDATA ; CPU:$E5A8 PRG:25A8 8C 07 20
|
|
|
|
lda $00 ; CPU:$E5AB PRG:25AB A5 00
|
|
sta PPUADDR ; CPU:$E5AD PRG:25AD 8D 06 20
|
|
|
|
lda $01 ; CPU:$E5B0 PRG:25B0 A5 01
|
|
clc ; CPU:$E5B2 PRG:25B2 18
|
|
adc #$20 ; CPU:$E5B3 PRG:25B3 69 20
|
|
sta PPUADDR ; CPU:$E5B5 PRG:25B5 8D 06 20
|
|
|
|
iny ; CPU:$E5B8 PRG:25B8 C8
|
|
sty PPUDATA ; CPU:$E5B9 PRG:25B9 8C 07 20
|
|
|
|
iny ; CPU:$E5BC PRG:25BC C8
|
|
sty PPUDATA ; CPU:$E5BD PRG:25BD 8C 07 20
|
|
|
|
rts ; CPU:$E5C0 PRG:25C0 60
|
|
|
|
;==============================================================================
|
|
; $-$E699: Initialize Gameplay State / Markers
|
|
;
|
|
; Local:
|
|
; Builds several gameplay marker/display values using the current value at
|
|
; $68 and a collection of lookup tables beginning at LevelProgressMarkerIndexTable
|
|
;
|
|
; The routine:
|
|
; - Initializes working values at $0A-$0F.
|
|
; - Derives an index/count from $68.
|
|
; - Selects PPU coordinates according to $46/$47.
|
|
; - Draws repeated 2x2 marker blocks using Draw2x2Marker.
|
|
; - Combines several lookup-table values into $0A+ working state.
|
|
; - Writes the resulting values directly into PPU attribute/display areas.
|
|
; - Selects final values for $02B6 and $02A9.
|
|
;
|
|
; Global:
|
|
; Called from GameModeState00 during initial gameplay setup.
|
|
;
|
|
; Notes:
|
|
; Address-oriented labels are used for the larger loops to preserve the
|
|
; original compact branch structure.
|
|
;==============================================================================
|
|
|
|
InitializeLevelProgressDisplay:
|
|
lda #$00 ; CPU:$E5C1 PRG:25C1 A9 00
|
|
sta $03 ; CPU:$E5C3 PRG:25C3 85 03
|
|
sta $0E ; CPU:$E5C5 PRG:25C5 85 0E
|
|
sta $0F ; CPU:$E5C7 PRG:25C7 85 0F
|
|
|
|
lda #$15 ; CPU:$E5C9 PRG:25C9 A9 15
|
|
sta $0A ; CPU:$E5CB PRG:25CB 85 0A
|
|
|
|
lda #$11 ; CPU:$E5CD PRG:25CD A9 11
|
|
sta $0D ; CPU:$E5CF PRG:25CF 85 0D
|
|
|
|
lda #$05 ; CPU:$E5D1 PRG:25D1 A9 05
|
|
sta $0B ; CPU:$E5D3 PRG:25D3 85 0B
|
|
sta $0C ; CPU:$E5D5 PRG:25D5 85 0C
|
|
|
|
lda $68 ; CPU:$E5D7 PRG:25D7 A5 68
|
|
sta $02 ; CPU:$E5D9 PRG:25D9 85 02
|
|
|
|
sec ; CPU:$E5DB PRG:25DB 38
|
|
sbc #$07 ; CPU:$E5DC PRG:25DC E9 07
|
|
bcc UseFirstLevelProgressIndex ; CPU:$E5DE PRG:25DE 90 0D
|
|
|
|
cmp #$0C ; CPU:$E5E0 PRG:25E0 C9 0C
|
|
bcc ClampLevelProgressIndex ; CPU:$E5E2 PRG:25E2 90 02
|
|
|
|
lda #$0C ; CPU:$E5E4 PRG:25E4 A9 0C
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E5E9
|
|
;------------------------------------------------------------------------------
|
|
|
|
ClampLevelProgressIndex:
|
|
tax ; CPU:$E5E6 PRG:25E6 AA
|
|
|
|
lda #$07 ; CPU:$E5E7 PRG:25E7 A9 07
|
|
sta $02 ; CPU:$E5E9 PRG:25E9 85 02
|
|
|
|
bne InitializeLevelProgressPosition ; CPU:$E5EB PRG:25EB D0 02
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E5F0
|
|
;------------------------------------------------------------------------------
|
|
|
|
UseFirstLevelProgressIndex:
|
|
ldx #$00 ; CPU:$E5ED PRG:25ED A2 00
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E5F2
|
|
; Initial PPU destination.
|
|
;------------------------------------------------------------------------------
|
|
|
|
InitializeLevelProgressPosition:
|
|
lda #$22 ; CPU:$E5EF PRG:25EF A9 22
|
|
sta $00 ; CPU:$E5F1 PRG:25F1 85 00
|
|
|
|
lda #$56 ; CPU:$E5F3 PRG:25F3 A9 56
|
|
sta $01 ; CPU:$E5F5 PRG:25F5 85 01
|
|
|
|
lda $46 ; CPU:$E5F7 PRG:25F7 A5 46
|
|
and $47 ; CPU:$E5F9 PRG:25F9 25 47
|
|
beq InitializeLevelProgressRowCounter ; CPU:$E5FB PRG:25FB F0 07
|
|
|
|
lda $00 ; CPU:$E5FD PRG:25FD A5 00
|
|
clc ; CPU:$E5FF PRG:25FF 18
|
|
adc #$08 ; CPU:$E600 PRG:2600 69 08
|
|
sta $00 ; CPU:$E602 PRG:2602 85 00
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E605
|
|
;------------------------------------------------------------------------------
|
|
|
|
InitializeLevelProgressRowCounter:
|
|
lda #$05 ; CPU:$E604 PRG:2604 A9 05
|
|
sta $04 ; CPU:$E606 PRG:2606 85 04
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E609
|
|
; Main marker loop.
|
|
;------------------------------------------------------------------------------
|
|
|
|
DrawNextLevelProgressMarker:
|
|
dec $04 ; CPU:$E608 PRG:2608 C6 04
|
|
bne SelectLevelProgressMarker ; CPU:$E60A PRG:260A D0 07
|
|
|
|
lda $01 ; CPU:$E60C PRG:260C A5 01
|
|
clc ; CPU:$E60E PRG:260E 18
|
|
adc #$38 ; CPU:$E60F PRG:260F 69 38
|
|
sta $01 ; CPU:$E611 PRG:2611 85 01
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E612
|
|
; Select marker information.
|
|
;------------------------------------------------------------------------------
|
|
|
|
SelectLevelProgressMarker:
|
|
lda LevelProgressMarkerIndexTable,x ; CPU:$E613 PRG:2613 BD 9A E6
|
|
sta $05 ; CPU:$E616 PRG:2616 85 05
|
|
|
|
asl ; CPU:$E618 PRG:2618 0A
|
|
asl ; CPU:$E619 PRG:2619 0A
|
|
adc #$60 ; CPU:$E61A PRG:261A 69 60
|
|
tay ; CPU:$E61C PRG:261C A8
|
|
|
|
jsr Draw2x2Marker ; CPU:$E61D PRG:261D 20 9A E5
|
|
|
|
ldy $03 ; CPU:$E620 PRG:2620 A4 03
|
|
|
|
lda LevelProgressAttributeIndexTable,y ; CPU:$E622 PRG:2622 B9 AE E6
|
|
sta $06 ; CPU:$E625 PRG:2625 85 06
|
|
|
|
lda LevelProgressAttributeIndexTable+1,y ; CPU:$E627 PRG:2627 B9 AF E6
|
|
sta $07 ; CPU:$E62A PRG:262A 85 07
|
|
|
|
ldy $05 ; CPU:$E62C PRG:262C A4 05
|
|
|
|
lda LevelProgressAttributeBits,y ; CPU:$E62E PRG:262E B9 BE E6
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E633
|
|
; Shift selected marker bits.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ShiftLevelProgressAttributeBits:
|
|
dec $07 ; CPU:$E631 PRG:2631 C6 07
|
|
bmi StoreLevelProgressAttributeBits ; CPU:$E633 PRG:2633 30 04
|
|
|
|
asl ; CPU:$E635 PRG:2635 0A
|
|
asl ; CPU:$E636 PRG:2636 0A
|
|
bcc ShiftLevelProgressAttributeBits ; CPU:$E637 PRG:2637 90 F8
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E63B
|
|
; Combine marker bits into working values.
|
|
;------------------------------------------------------------------------------
|
|
|
|
StoreLevelProgressAttributeBits:
|
|
ldy $06 ; CPU:$E639 PRG:2639 A4 06
|
|
|
|
ora $0A,y ; CPU:$E63B PRG:263B 19 0A
|
|
sta $0A,y ; CPU:$E63D PRG:263D 00 99
|
|
|
|
lda $01 ; CPU:$E63F PRG:263F 0A 00
|
|
clc ; CPU:$E641 PRG:2641 A5
|
|
adc #$02 ; CPU:$E642 PRG:2642 01 18
|
|
sta $01 ; CPU:$E644 PRG:2644 69 02
|
|
|
|
inc $03 ; CPU:$E646 PRG:2646 85 01
|
|
inc $03 ; CPU:$E648 PRG:2648 E6 03
|
|
|
|
inx ; CPU:$E64A PRG:264A E6
|
|
|
|
dec $02 ; CPU:$E64B PRG:264B 03 E8
|
|
bpl DrawNextLevelProgressMarker ; CPU:$E64D PRG:264D C6 02
|
|
|
|
|
|
;==============================================================================
|
|
; Write generated marker-state values into PPU memory.
|
|
;==============================================================================
|
|
|
|
ldx #$23 ; CPU:$E64F PRG:264F 10 B7
|
|
|
|
lda $47 ; CPU:$E651 PRG:2651 A2 23
|
|
and $46 ; CPU:$E653 PRG:2653 A5 47
|
|
beq SetLevelProgressAttributeAddress ; CPU:$E655 PRG:2655 25 46
|
|
|
|
ldx #$2B ; CPU:$E657 PRG:2657 F0 02
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E65D
|
|
; Set first PPU destination.
|
|
;------------------------------------------------------------------------------
|
|
|
|
SetLevelProgressAttributeAddress:
|
|
stx PPUADDR ; CPU:$E65B PRG:265B 8E 06 20
|
|
stx $00 ; CPU:$E65E PRG:265E 86 00
|
|
|
|
lda #$E5 ; CPU:$E660 PRG:2660 A9 E5
|
|
sta PPUADDR ; CPU:$E662 PRG:2662 8D 06 20
|
|
|
|
ldx #$00 ; CPU:$E665 PRG:2665 A2 00
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E667
|
|
; Reset count for one three-byte PPU group.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ResetAttributeWriteCount:
|
|
lda #$03 ; CPU:$E667 PRG:2667 A9 03
|
|
sta $01 ; CPU:$E669 PRG:2669 85 01
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E66B
|
|
; Write three values from $0A+.
|
|
;------------------------------------------------------------------------------
|
|
|
|
WriteLevelProgressAttribute:
|
|
lda $0A,x ; CPU:$E66B PRG:266B B5 0A
|
|
sta PPUDATA ; CPU:$E66D PRG:266D 8D 07 20
|
|
|
|
inx ; CPU:$E670 PRG:2670 E8
|
|
|
|
dec $01 ; CPU:$E671 PRG:2671 C6 01
|
|
bne WriteLevelProgressAttribute ; CPU:$E673 PRG:2673 D0 F6
|
|
|
|
inc $02 ; CPU:$E675 PRG:2675 E6 02
|
|
bne SelectLevelProgressPalette ; CPU:$E677 PRG:2677 D0 0C
|
|
|
|
lda $00 ; CPU:$E679 PRG:2679 A5 00
|
|
sta PPUADDR ; CPU:$E67B PRG:267B 8D 06 20
|
|
|
|
lda #$ED ; CPU:$E67E PRG:267E A9 ED
|
|
sta PPUADDR ; CPU:$E680 PRG:2680 8D 06 20
|
|
|
|
bne ResetAttributeWriteCount ; CPU:$E683 PRG:2683 D0 E2
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E685
|
|
; Select final marker/display value.
|
|
;------------------------------------------------------------------------------
|
|
|
|
SelectLevelProgressPalette:
|
|
lda $68 ; CPU:$E685 PRG:2685 A5 68
|
|
|
|
cmp #$10 ; CPU:$E687 PRG:2687 C9 10
|
|
bcc StoreLevelProgressPalette ; CPU:$E689 PRG:2689 90 02
|
|
|
|
lda #$0F ; CPU:$E68B PRG:268B A9 0F
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E68D
|
|
;------------------------------------------------------------------------------
|
|
|
|
StoreLevelProgressPalette:
|
|
tay ; CPU:$E68D PRG:268D A8
|
|
|
|
lda LevelProgressPaletteTable,y ; CPU:$E68E PRG:268E B9 C6 E6
|
|
sta $02B6 ; CPU:$E691 PRG:2691 8D B6 02
|
|
|
|
lda #$0F ; CPU:$E694 PRG:2694 A9 0F
|
|
sta $02A9 ; CPU:$E696 PRG:2696 8D A9 02
|
|
|
|
rts ; CPU:$E699 PRG:2699 60
|
|
|
|
|
|
;==============================================================================
|
|
; $E69A-$E6AD: Gameplay Marker Level Index Table
|
|
;==============================================================================
|
|
|
|
LevelProgressMarkerIndexTable:
|
|
.byte $00,$01,$02,$02 ; CPU:$E69A PRG:269A 00 01 02 02
|
|
.byte $03,$03,$04,$04 ; CPU:$E69E PRG:269E 03 03 04 04
|
|
.byte $05,$05,$06,$06 ; CPU:$E6A2 PRG:26A2 05 05 06 06
|
|
.byte $07,$07,$07,$07 ; CPU:$E6A6 PRG:26A6 07 07 07 07
|
|
.byte $07,$07,$07,$07 ; CPU:$E6AA PRG:26AA 07 07 07 07
|
|
|
|
;==============================================================================
|
|
; $E6AE-$E6BD: Gameplay Marker Working-Value Table
|
|
;
|
|
; Used as byte pairs through $03.
|
|
;==============================================================================
|
|
|
|
LevelProgressAttributeIndexTable:
|
|
.byte $00,$03 ; CPU:$E6AE PRG:26AE 00 03
|
|
.byte $01,$02 ; CPU:$E6B0 PRG:26B0 01 02
|
|
.byte $01,$03 ; CPU:$E6B2 PRG:26B2 01 03
|
|
.byte $02,$02 ; CPU:$E6B4 PRG:26B4 02 02
|
|
.byte $03,$01 ; CPU:$E6B6 PRG:26B6 03 01
|
|
.byte $04,$00 ; CPU:$E6B8 PRG:26B8 04 00
|
|
.byte $04,$01 ; CPU:$E6BA PRG:26BA 04 01
|
|
.byte $05,$00 ; CPU:$E6BC PRG:26BC 05 00
|
|
|
|
;==============================================================================
|
|
; $E6BE-$E6C5: Gameplay Marker Bit/Pattern Table
|
|
;==============================================================================
|
|
|
|
LevelProgressAttributeBits:
|
|
.byte $02,$02,$02,$02 ; CPU:$E6BE PRG:26BE 02 02 02 02
|
|
.byte $03,$03,$03,$03 ; CPU:$E6C2 PRG:26C2 03 03 03 03
|
|
|
|
;==============================================================================
|
|
; $E6C6-$E6D5: Gameplay Marker Final Value Table
|
|
;
|
|
; Indexed by min($68,$0F). Selected value is stored at $02B6.
|
|
;==============================================================================
|
|
|
|
LevelProgressPaletteTable:
|
|
.byte $16,$16,$26,$26 ; CPU:$E6C6 PRG:26C6 16 16 26 26
|
|
.byte $06,$06,$19,$19 ; CPU:$E6CA PRG:26CA 06 06 19 19
|
|
.byte $17,$17,$17,$17 ; CPU:$E6CE PRG:26CE 17 17 17 17
|
|
.byte $12,$12,$12,$12 ; CPU:$E6D2 PRG:26D2 12 12 12 12
|
|
|
|
|
|
;==============================================================================
|
|
; $E6D6-$E737: Initialize Gameplay Transition State
|
|
;==============================================================================
|
|
|
|
InitializeGameplayTransitionState:
|
|
lda #$08 ; CPU:$E6D6 PRG:26D6 A9 08
|
|
sta $43 ; CPU:$E6D8 PRG:26D8 85 43
|
|
sta PPUCTRL ; CPU:$E6DA PRG:26DA 8D 00 20
|
|
|
|
|
|
TransitionInit_E6DD:
|
|
lda PPUSTATUS ; CPU:$E6DD PRG:26DD AD 02 20
|
|
bpl TransitionInit_E6DD ; CPU:$E6E0 PRG:26E0 10 FB
|
|
|
|
lda #$01 ; CPU:$E6E2 PRG:26E2 A9 01
|
|
sta $060D ; CPU:$E6E4 PRG:26E4 8D 0D 06
|
|
sta $060E ; CPU:$E6E7 PRG:26E7 8D 0E 06
|
|
|
|
lda #$00 ; CPU:$E6EA PRG:26EA A9 00
|
|
sta PPUMASK ; CPU:$E6EC PRG:26EC 8D 01 20
|
|
|
|
jsr ClearPlayfieldNametable ; CPU:$E6EF PRG:26EF 20 38 E7
|
|
|
|
lda #$01 ; CPU:$E6F2 PRG:26F2 A9 01
|
|
sta $028D ; CPU:$E6F4 PRG:26F4 8D 8D 02
|
|
|
|
lda #$01 ; CPU:$E6F7 PRG:26F7 A9 01
|
|
sta $0293 ; CPU:$E6F9 PRG:26F9 8D 93 02
|
|
|
|
lda #$F7 ; CPU:$E6FC PRG:26FC A9 F7
|
|
sta $0278 ; CPU:$E6FE PRG:26FE 8D 78 02
|
|
|
|
lda #$7C ; CPU:$E701 PRG:2701 A9 7C
|
|
sta $027A ; CPU:$E703 PRG:2703 8D 7A 02
|
|
|
|
lda #$FF ; CPU:$E706 PRG:2706 A9 FF
|
|
sta $1E ; CPU:$E708 PRG:2708 85 1E
|
|
|
|
lda #$00 ; CPU:$E70A PRG:270A A9 00
|
|
sta $1F ; CPU:$E70C PRG:270C 85 1F
|
|
|
|
lda #$00 ; CPU:$E70E PRG:270E A9 00
|
|
sta $88 ; CPU:$E710 PRG:2710 85 88
|
|
|
|
ldy #$00 ; CPU:$E712 PRG:2712 A0 00
|
|
|
|
|
|
TransitionInit_CopyPalette:
|
|
lda GameplayTransitionPalette,y ; CPU:$E714 PRG:2714 B9 AF E7
|
|
sta $02A9,y ; CPU:$E717 PRG:2717 99 A9 02
|
|
|
|
iny ; CPU:$E71A PRG:271A C8
|
|
cpy #$10 ; CPU:$E71B PRG:271B C0 10
|
|
bne TransitionInit_CopyPalette ; CPU:$E71D PRG:271D D0 F5
|
|
|
|
lda #$20 ; CPU:$E71F PRG:271F A9 20
|
|
sta $026F ; CPU:$E721 PRG:2721 8D 6F 02
|
|
sta $0270 ; CPU:$E724 PRG:2724 8D 70 02
|
|
sta $0271 ; CPU:$E727 PRG:2727 8D 71 02
|
|
|
|
lda #$10 ; CPU:$E72A PRG:272A A9 10
|
|
sta $3F ; CPU:$E72C PRG:272C 85 3F
|
|
|
|
lda #$88 ; CPU:$E72E PRG:272E A9 88
|
|
sta PPUCTRL ; CPU:$E730 PRG:2730 8D 00 20
|
|
sta $43 ; CPU:$E733 PRG:2733 85 43
|
|
|
|
jmp $CAA7 ; CPU:$E735 PRG:2735 4C A7 CA
|
|
|
|
|
|
;==============================================================================
|
|
; $E738-$E7AE: Initialize Gameplay PPU Region
|
|
;
|
|
; Selects $2000/$2800 according to $47 & $46, performs a patterned fill,
|
|
; clears $40 PPU bytes, and conditionally writes tile $5E at $2230/$2A30.
|
|
;
|
|
; Several branches deliberately re-enter the counter setup at $E751.
|
|
;==============================================================================
|
|
|
|
ClearPlayfieldNametable:
|
|
ldx #$20 ; CPU:$E738 PRG:2738 A2 20
|
|
|
|
lda $47 ; CPU:$E73A PRG:273A A5 47
|
|
and $46 ; CPU:$E73C PRG:273C 25 46
|
|
beq SetPlayfieldPpuAddress ; CPU:$E73E PRG:273E F0 02
|
|
|
|
ldx #$28 ; CPU:$E740 PRG:2740 A2 28
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E742
|
|
; Initialize selected nametable address.
|
|
;------------------------------------------------------------------------------
|
|
|
|
SetPlayfieldPpuAddress:
|
|
lda PPUSTATUS ; CPU:$E742 PRG:2742 AD 02 20
|
|
|
|
stx PPUADDR ; CPU:$E745 PRG:2745 8E 06 20
|
|
|
|
lda #$00 ; CPU:$E748 PRG:2748 A9 00
|
|
sta PPUADDR ; CPU:$E74A PRG:274A 8D 06 20
|
|
|
|
lda #$1C ; CPU:$E74D PRG:274D A9 1C
|
|
sta $00 ; CPU:$E74F PRG:274F 85 00
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E751
|
|
; Shared counter-setup entry.
|
|
;
|
|
; The outer $00 loop deliberately jumps back here rather than rebuilding $00.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ResetPlayfieldFillCounters:
|
|
lda #$02 ; CPU:$E751 PRG:2751 A9 02
|
|
sta $01 ; CPU:$E753 PRG:2753 85 01
|
|
|
|
lda #$1C ; CPU:$E755 PRG:2755 A9 1C
|
|
sta $02 ; CPU:$E757 PRG:2757 85 02
|
|
|
|
lda #$02 ; CPU:$E759 PRG:2759 A9 02
|
|
sta $03 ; CPU:$E75B PRG:275B 85 03
|
|
|
|
lda #$2D ; CPU:$E75D PRG:275D A9 2D
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E75F
|
|
; Shared PPUDATA write point.
|
|
;------------------------------------------------------------------------------
|
|
|
|
WritePlayfieldFillByte:
|
|
sta PPUDATA ; CPU:$E75F PRG:275F 8D 07 20
|
|
|
|
ldx $01 ; CPU:$E762 PRG:2762 A6 01
|
|
beq AdvancePlayfieldInnerRun ; CPU:$E764 PRG:2764 F0 08
|
|
|
|
dec $01 ; CPU:$E766 PRG:2766 C6 01
|
|
bne WritePlayfieldFillByte ; CPU:$E768 PRG:2768 D0 F5
|
|
|
|
lda #$20 ; CPU:$E76A PRG:276A A9 20
|
|
bne WritePlayfieldFillByte ; CPU:$E76C PRG:276C D0 F1
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E76E
|
|
; Process the second run counter.
|
|
;------------------------------------------------------------------------------
|
|
|
|
AdvancePlayfieldInnerRun:
|
|
ldx $02 ; CPU:$E76E PRG:276E A6 02
|
|
beq AdvancePlayfieldOuterRun ; CPU:$E770 PRG:2770 F0 08
|
|
|
|
dec $02 ; CPU:$E772 PRG:2772 C6 02
|
|
bne WritePlayfieldFillByte ; CPU:$E774 PRG:2774 D0 E9
|
|
|
|
lda #$2D ; CPU:$E776 PRG:2776 A9 2D
|
|
bne WritePlayfieldFillByte ; CPU:$E778 PRG:2778 D0 E5
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E77A
|
|
; Process outer fill counters.
|
|
;------------------------------------------------------------------------------
|
|
|
|
AdvancePlayfieldOuterRun:
|
|
dec $03 ; CPU:$E77A PRG:277A C6 03
|
|
bne WritePlayfieldFillByte ; CPU:$E77C PRG:277C D0 E1
|
|
|
|
dec $00 ; CPU:$E77E PRG:277E C6 00
|
|
bne ResetPlayfieldFillCounters ; CPU:$E780 PRG:2780 D0 CF
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E782
|
|
; Clear $40 PPU bytes.
|
|
;------------------------------------------------------------------------------
|
|
|
|
lda #$00 ; CPU:$E782 PRG:2782 A9 00
|
|
tax ; CPU:$E784 PRG:2784 AA
|
|
|
|
|
|
ClearPlayfieldTail:
|
|
sta PPUDATA ; CPU:$E785 PRG:2785 8D 07 20
|
|
|
|
inx ; CPU:$E788 PRG:2788 E8
|
|
cpx #$40 ; CPU:$E789 PRG:2789 E0 40
|
|
bne ClearPlayfieldTail ; CPU:$E78B PRG:278B D0 F8
|
|
|
|
lda $87 ; CPU:$E78D PRG:278D A5 87
|
|
cmp #$02 ; CPU:$E78F PRG:278F C9 02
|
|
beq DrawPlayfieldSpecialTile ; CPU:$E791 PRG:2791 F0 01
|
|
|
|
rts ; CPU:$E793 PRG:2793 60
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $E794
|
|
; Optional special tile at PPU $2230 or $2A30.
|
|
;------------------------------------------------------------------------------
|
|
|
|
DrawPlayfieldSpecialTile:
|
|
ldx #$22 ; CPU:$E794 PRG:2794 A2 22
|
|
|
|
lda $47 ; CPU:$E796 PRG:2796 A5 47
|
|
and $46 ; CPU:$E798 PRG:2798 25 46
|
|
beq SetSpecialTilePpuAddress ; CPU:$E79A PRG:279A F0 02
|
|
|
|
ldx #$2A ; CPU:$E79C PRG:279C A2 2A
|
|
|
|
|
|
SetSpecialTilePpuAddress:
|
|
lda PPUSTATUS ; CPU:$E79E PRG:279E AD 02 20
|
|
|
|
stx PPUADDR ; CPU:$E7A1 PRG:27A1 8E 06 20
|
|
|
|
lda #$30 ; CPU:$E7A4 PRG:27A4 A9 30
|
|
sta PPUADDR ; CPU:$E7A6 PRG:27A6 8D 06 20
|
|
|
|
lda #$5E ; CPU:$E7A9 PRG:27A9 A9 5E
|
|
sta PPUDATA ; CPU:$E7AB PRG:27AB 8D 07 20
|
|
|
|
rts ; CPU:$E7AE PRG:27AE 60
|
|
|
|
|
|
;==============================================================================
|
|
; $E7AF-$E7BE: Gameplay Transition Palette
|
|
;==============================================================================
|
|
|
|
GameplayTransitionPalette:
|
|
.byte $0F,$36,$20,$06 ; CPU:$E7AF PRG:27AF 0F 36 20 06
|
|
.byte $0F,$27,$20,$06 ; CPU:$E7B3 PRG:27B3 0F 27 20 06
|
|
.byte $0F,$11,$20,$33 ; CPU:$E7B7 PRG:27B7 0F 11 20 33
|
|
.byte $0F,$36,$20,$11 ; CPU:$E7BB PRG:27BB 0F 36 20 11
|
|
|
|
;==============================================================================
|
|
; $E7BF-$E7CD: Gameplay Transition Update Coordinator
|
|
;
|
|
; Runs several already-known gameplay/render helpers, then dispatches through
|
|
; the state machine at $E7CE before returning to the main game-mode dispatcher.
|
|
;==============================================================================
|
|
|
|
UpdateIntermissionTransition:
|
|
jsr $EA19 ; CPU:$E7BF PRG:27BF 20 19 EA
|
|
jsr $EA94 ; CPU:$E7C2 PRG:27C2 20 94 EA
|
|
jsr BuildEntitySpriteBuffer ; CPU:$E7C5 PRG:27C5 20 F1 DA
|
|
jsr DispatchIntermissionState ; CPU:$E7C8 PRG:27C8 20 CE E7
|
|
|
|
jmp $CAA7 ; CPU:$E7CB PRG:27CB 4C A7 CA
|
|
|
|
|
|
;==============================================================================
|
|
; $E7CE-$E7DC: Transition state dispatcher
|
|
;
|
|
; $87 is an even state value used directly as a byte offset into the table.
|
|
;==============================================================================
|
|
|
|
DispatchIntermissionState:
|
|
ldy $87 ; CPU:$E7CE PRG:27CE A4 87
|
|
|
|
lda IntermissionStateHandlerTable,y ; CPU:$E7D0 PRG:27D0 B9 DD E7
|
|
sta $10 ; CPU:$E7D3 PRG:27D3 85 10
|
|
|
|
lda IntermissionStateHandlerTable+1,y ; CPU:$E7D5 PRG:27D5 B9 DE E7
|
|
sta $11 ; CPU:$E7D8 PRG:27D8 85 11
|
|
|
|
jmp ($0010) ; CPU:$E7DA PRG:27DA 6C 10 00 E3 E7
|
|
|
|
|
|
;==============================================================================
|
|
; $E7DD-$E7E2: Transition state pointer table
|
|
;==============================================================================
|
|
|
|
IntermissionStateHandlerTable:
|
|
.word DispatchIntermissionPhase ; CPU:$E7DD PRG:27DD E3 E7
|
|
.word DispatchIntermissionState2Phase ; CPU:$E7DF PRG:27DF C7 E8
|
|
.word DispatchIntermissionState4Phase ; CPU:$E7E1 PRG:27E1 6E E9
|
|
|
|
|
|
;==============================================================================
|
|
; $E7E3-$E7F1: Secondary transition-state dispatcher
|
|
;
|
|
; $88 is used directly as a byte offset into another pointer table.
|
|
;==============================================================================
|
|
|
|
DispatchIntermissionPhase:
|
|
ldy $88 ; CPU:$E7E3 PRG:27E3 A4 88
|
|
|
|
lda IntermissionPhaseHandlerTable,y ; CPU:$E7E5 PRG:27E5 B9 F2 E7
|
|
sta $10 ; CPU:$E7E8 PRG:27E8 85 10
|
|
|
|
lda IntermissionPhaseHandlerTable+1,y ; CPU:$E7EA PRG:27EA B9 F3 E7
|
|
sta $11 ; CPU:$E7ED PRG:27ED 85 11
|
|
|
|
jmp ($0010) ; CPU:$E7EF PRG:27EF 6C 10 00 FA E7
|
|
|
|
|
|
;==============================================================================
|
|
; $E7F2-$E7F9: Transition substate pointer table
|
|
;==============================================================================
|
|
|
|
IntermissionPhaseHandlerTable:
|
|
.word UpdateIntermissionPhase0 ; CPU:$E7F2 PRG:27F2 FA E7
|
|
.word UpdateIntermissionPhase1 ; CPU:$E7F4 PRG:27F4 23 E8
|
|
.word UpdateIntermissionPhase2 ; CPU:$E7F6 PRG:27F6 4E E8
|
|
.word UpdateIntermissionPhase3 ; CPU:$E7F8 PRG:27F8 BA E8
|
|
|
|
|
|
;==============================================================================
|
|
; $E7FA-$E822: Transition substate 0
|
|
;
|
|
; Waits until $0278 reaches at least $D0, then advances $88 by two and
|
|
; initializes several mirrored object/state values.
|
|
;==============================================================================
|
|
|
|
UpdateIntermissionPhase0:
|
|
lda $0278 ; CPU:$E7FA PRG:27FA AD 78 02
|
|
cmp #$D0 ; CPU:$E7FD PRG:27FD C9 D0
|
|
bcc TransitionSubstate_E802 ; CPU:$E7FF PRG:27FF 90 01
|
|
|
|
rts ; CPU:$E801 PRG:2801 60
|
|
|
|
|
|
TransitionSubstate_E802:
|
|
inc $88 ; CPU:$E802 PRG:2802 E6 88
|
|
inc $88 ; CPU:$E804 PRG:2804 E6 88
|
|
|
|
lda #$0C ; CPU:$E806 PRG:2806 A9 0C
|
|
sta $028C ; CPU:$E808 PRG:2808 8D 8C 02
|
|
|
|
lda #$20 ; CPU:$E80B PRG:280B A9 20
|
|
sta $0292 ; CPU:$E80D PRG:280D 8D 92 02
|
|
|
|
lda #$F7 ; CPU:$E810 PRG:2810 A9 F7
|
|
sta $0274 ; CPU:$E812 PRG:2812 8D 74 02
|
|
|
|
lda #$7C ; CPU:$E815 PRG:2815 A9 7C
|
|
sta $0276 ; CPU:$E817 PRG:2817 8D 76 02
|
|
|
|
lda #$FE ; CPU:$E81A PRG:281A A9 FE
|
|
sta $1A ; CPU:$E81C PRG:281C 85 1A
|
|
|
|
lda #$E0 ; CPU:$E81E PRG:281E A9 E0
|
|
sta $1B ; CPU:$E820 PRG:2820 85 1B
|
|
|
|
rts ; CPU:$E822 PRG:2822 60
|
|
|
|
|
|
;==============================================================================
|
|
; $E823-$E84D: Transition substate 1
|
|
;
|
|
; Waits for $0274 to become zero, then advances $88 and initializes a
|
|
; different object/state configuration.
|
|
;==============================================================================
|
|
|
|
UpdateIntermissionPhase1:
|
|
lda $0274 ; CPU:$E823 PRG:2823 AD 74 02
|
|
beq TransitionSubstate_E829 ; CPU:$E826 PRG:2826 F0 01
|
|
|
|
rts ; CPU:$E828 PRG:2828 60
|
|
|
|
|
|
TransitionSubstate_E829:
|
|
inc $88 ; CPU:$E829 PRG:2829 E6 88
|
|
inc $88 ; CPU:$E82B PRG:282B E6 88
|
|
|
|
lda #$40 ; CPU:$E82D PRG:282D A9 40
|
|
sta $4C ; CPU:$E82F PRG:282F 85 4C
|
|
|
|
lda #$1E ; CPU:$E831 PRG:2831 A9 1E
|
|
sta $028C ; CPU:$E833 PRG:2833 8D 8C 02
|
|
|
|
lda #$22 ; CPU:$E836 PRG:2836 A9 22
|
|
sta $0292 ; CPU:$E838 PRG:2838 8D 92 02
|
|
|
|
lda #$09 ; CPU:$E83B PRG:283B A9 09
|
|
sta $0274 ; CPU:$E83D PRG:283D 8D 74 02
|
|
|
|
lda #$7C ; CPU:$E840 PRG:2840 A9 7C
|
|
sta $0276 ; CPU:$E842 PRG:2842 8D 76 02
|
|
|
|
lda #$01 ; CPU:$E845 PRG:2845 A9 01
|
|
sta $1A ; CPU:$E847 PRG:2847 85 1A
|
|
|
|
lda #$00 ; CPU:$E849 PRG:2849 A9 00
|
|
sta $1B ; CPU:$E84B PRG:284B 85 1B
|
|
|
|
rts ; CPU:$E84D PRG:284D 60
|
|
|
|
|
|
;==============================================================================
|
|
; $E84E-$E8B9: Transition substate 2
|
|
;
|
|
; Waits until $0274 reaches at least $80, then advances $88 and initializes
|
|
; four related coordinate/state structures and their mirrored render values.
|
|
;==============================================================================
|
|
|
|
UpdateIntermissionPhase2:
|
|
lda #$01 ; CPU:$E84E PRG:284E A9 01
|
|
sta $060D ; CPU:$E850 PRG:2850 8D 0D 06
|
|
sta $060E ; CPU:$E853 PRG:2853 8D 0E 06
|
|
|
|
lda $0274 ; CPU:$E856 PRG:2856 AD 74 02
|
|
cmp #$80 ; CPU:$E859 PRG:2859 C9 80
|
|
bcs TransitionSubstate_E85D ; CPU:$E85B PRG:285B B0 01
|
|
|
|
rts ; CPU:$E85D PRG:285D 60
|
|
|
|
|
|
TransitionSubstate_E85D:
|
|
inc $88 ; CPU:$E85E PRG:285E E6 88
|
|
inc $88 ; CPU:$E860 PRG:2860 E6 88
|
|
|
|
lda #$01 ; CPU:$E862 PRG:2862 A9 01
|
|
sta $1E ; CPU:$E864 PRG:2864 85 1E
|
|
sta $22 ; CPU:$E866 PRG:2866 85 22
|
|
sta $26 ; CPU:$E868 PRG:2868 85 26
|
|
sta $2A ; CPU:$E86A PRG:286A 85 2A
|
|
|
|
lda #$C0 ; CPU:$E86C PRG:286C A9 C0
|
|
sta $1F ; CPU:$E86E PRG:286E 85 1F
|
|
sta $23 ; CPU:$E870 PRG:2870 85 23
|
|
sta $27 ; CPU:$E872 PRG:2872 85 27
|
|
sta $2B ; CPU:$E874 PRG:2874 85 2B
|
|
|
|
clc ; CPU:$E876 PRG:2876 18
|
|
|
|
lda #$38 ; CPU:$E877 PRG:2877 A9 38
|
|
sta $028D ; CPU:$E879 PRG:2879 8D 8D 02
|
|
|
|
adc #$01 ; CPU:$E87C PRG:287C 69 01
|
|
sta $028E ; CPU:$E87E PRG:287E 8D 8E 02
|
|
|
|
adc #$01 ; CPU:$E881 PRG:2881 69 01
|
|
sta $028F ; CPU:$E883 PRG:2883 8D 8F 02
|
|
|
|
adc #$01 ; CPU:$E886 PRG:2886 69 01
|
|
sta $0290 ; CPU:$E888 PRG:2888 8D 90 02
|
|
|
|
lda #$21 ; CPU:$E88B PRG:288B A9 21
|
|
sta $0293 ; CPU:$E88D PRG:288D 8D 93 02
|
|
sta $0294 ; CPU:$E890 PRG:2890 8D 94 02
|
|
sta $0295 ; CPU:$E893 PRG:2893 8D 95 02
|
|
sta $0296 ; CPU:$E896 PRG:2896 8D 96 02
|
|
|
|
lda #$09 ; CPU:$E899 PRG:2899 A9 09
|
|
sta $0278 ; CPU:$E89B PRG:289B 8D 78 02
|
|
sta $0280 ; CPU:$E89E PRG:289E 8D 80 02
|
|
|
|
lda #$19 ; CPU:$E8A1 PRG:28A1 A9 19
|
|
sta $027C ; CPU:$E8A3 PRG:28A3 8D 7C 02
|
|
sta $0284 ; CPU:$E8A6 PRG:28A6 8D 84 02
|
|
|
|
lda #$6C ; CPU:$E8A9 PRG:28A9 A9 6C
|
|
sta $027A ; CPU:$E8AB PRG:28AB 8D 7A 02
|
|
sta $027E ; CPU:$E8AE PRG:28AE 8D 7E 02
|
|
|
|
lda #$7C ; CPU:$E8B1 PRG:28B1 A9 7C
|
|
sta $0282 ; CPU:$E8B3 PRG:28B3 8D 82 02
|
|
sta $0286 ; CPU:$E8B6 PRG:28B6 8D 86 02
|
|
|
|
rts ; CPU:$E8B9 PRG:28B9 60
|
|
|
|
|
|
;==============================================================================
|
|
; $E8BA-$E8C6: Transition substate 3
|
|
;
|
|
; Waits for $0278 to become zero, then primes delay $4C and transfers to the
|
|
; routine at $EA14.
|
|
;==============================================================================
|
|
|
|
UpdateIntermissionPhase3:
|
|
lda $0278 ; CPU:$E8BA PRG:28BA AD 78 02
|
|
beq TransitionSubstate_E8C0 ; CPU:$E8BD PRG:28BD F0 01
|
|
|
|
rts ; CPU:$E8BF PRG:28BF 60
|
|
|
|
|
|
TransitionSubstate_E8C0:
|
|
lda #$40 ; CPU:$E8C0 PRG:28C0 A9 40
|
|
sta $4C ; CPU:$E8C2 PRG:28C2 85 4C
|
|
|
|
jmp $EA14 ; CPU:$E8C4 PRG:28C4 4C 14 EA
|
|
|
|
|
|
;==============================================================================
|
|
; $E8C7-$E8D5: Transition State $02 Substate Dispatcher
|
|
;
|
|
; Local:
|
|
; Uses $88 as an even byte offset into IntermissionState2PhaseTable.
|
|
;==============================================================================
|
|
|
|
DispatchIntermissionState2Phase:
|
|
ldy $88 ; CPU:$E8C7 PRG:28C7 A4 88
|
|
|
|
lda IntermissionState2PhaseTable,y ; CPU:$E8C9 PRG:28C9 B9 D6 E8
|
|
sta $10 ; CPU:$E8CC PRG:28CC 85 10
|
|
|
|
lda IntermissionState2PhaseTable+1,y ; CPU:$E8CE PRG:28CE B9 D7 E8
|
|
sta $11 ; CPU:$E8D1 PRG:28D1 85 11
|
|
|
|
jmp ($0010) ; CPU:$E8D3 PRG:28D3 6C 10 00 DC E8
|
|
|
|
|
|
;==============================================================================
|
|
; $E8D6-$E8DB: Transition phase table
|
|
;==============================================================================
|
|
|
|
IntermissionState2PhaseTable:
|
|
.word UpdateIntermissionState2Phase0 ; CPU:$E8D6 PRG:28D6 DC E8
|
|
.word UpdateIntermissionState2Phase1 ; CPU:$E8D8 PRG:28D8 05 E9
|
|
.word UpdateIntermissionState2Phase2 ; CPU:$E8DA PRG:28DA 3F E9
|
|
|
|
|
|
;==============================================================================
|
|
; $E8DC-$E904: Transition phase 0
|
|
;
|
|
; Waits until $0278 reaches $A0, then advances the $88 state and initializes
|
|
; the primary mirrored object/state values.
|
|
;==============================================================================
|
|
|
|
UpdateIntermissionState2Phase0:
|
|
lda $0278 ; CPU:$E8DC PRG:28DC AD 78 02
|
|
cmp #$A0 ; CPU:$E8DF PRG:28DF C9 A0
|
|
bcc TransitionPhase_E8E4 ; CPU:$E8E1 PRG:28E1 90 01
|
|
|
|
rts ; CPU:$E8E3 PRG:28E3 60
|
|
|
|
|
|
TransitionPhase_E8E4:
|
|
inc $88 ; CPU:$E8E4 PRG:28E4 E6 88
|
|
inc $88 ; CPU:$E8E6 PRG:28E6 E6 88
|
|
|
|
lda #$0C ; CPU:$E8E8 PRG:28E8 A9 0C
|
|
sta $028C ; CPU:$E8EA PRG:28EA 8D 8C 02
|
|
|
|
lda #$20 ; CPU:$E8ED PRG:28ED A9 20
|
|
sta $0292 ; CPU:$E8EF PRG:28EF 8D 92 02
|
|
|
|
lda #$F7 ; CPU:$E8F2 PRG:28F2 A9 F7
|
|
sta $0274 ; CPU:$E8F4 PRG:28F4 8D 74 02
|
|
|
|
lda #$7C ; CPU:$E8F7 PRG:28F7 A9 7C
|
|
sta $0276 ; CPU:$E8F9 PRG:28F9 8D 76 02
|
|
|
|
lda #$FF ; CPU:$E8FC PRG:28FC A9 FF
|
|
sta $1A ; CPU:$E8FE PRG:28FE 85 1A
|
|
|
|
lda #$00 ; CPU:$E900 PRG:2900 A9 00
|
|
sta $1B ; CPU:$E902 PRG:2902 85 1B
|
|
|
|
rts ; CPU:$E904 PRG:2904 60
|
|
|
|
|
|
;==============================================================================
|
|
; $E905-$E93E: Transition phase 1
|
|
;
|
|
; Watches $0274. At $80 it installs one object configuration. At $78 it
|
|
; clears the position pair and advances to the next phase.
|
|
;==============================================================================
|
|
|
|
UpdateIntermissionState2Phase1:
|
|
lda $0274 ; CPU:$E905 PRG:2905 AD 74 02
|
|
|
|
cmp #$80 ; CPU:$E908 PRG:2908 C9 80
|
|
bne TransitionPhase_E92D ; CPU:$E90A PRG:290A D0 23
|
|
|
|
lda #$FF ; CPU:$E90C PRG:290C A9 FF
|
|
sta $1A ; CPU:$E90E PRG:290E 85 1A
|
|
|
|
lda #$C0 ; CPU:$E910 PRG:2910 A9 C0
|
|
sta $1B ; CPU:$E912 PRG:2912 85 1B
|
|
|
|
lda #$42 ; CPU:$E914 PRG:2914 A9 42
|
|
sta $028E ; CPU:$E916 PRG:2916 8D 8E 02
|
|
|
|
lda #$00 ; CPU:$E919 PRG:2919 A9 00
|
|
sta $0294 ; CPU:$E91B PRG:291B 8D 94 02
|
|
|
|
lda #$80 ; CPU:$E91E PRG:291E A9 80
|
|
sta $027C ; CPU:$E920 PRG:2920 8D 7C 02
|
|
|
|
lda #$7C ; CPU:$E923 PRG:2923 A9 7C
|
|
sta $027E ; CPU:$E925 PRG:2925 8D 7E 02
|
|
|
|
lda #$00 ; CPU:$E928 PRG:2928 A9 00
|
|
sta $22 ; CPU:$E92A PRG:292A 85 22
|
|
sta $23 ; CPU:$E92C PRG:292C 85 23
|
|
|
|
rts ; CPU:$E92E PRG:292E 60
|
|
|
|
|
|
TransitionPhase_E92D:
|
|
cmp #$78 ; CPU:$E92F PRG:292F C9 78
|
|
beq TransitionPhase_E933 ; CPU:$E931 PRG:2931 F0 01
|
|
|
|
rts ; CPU:$E933 PRG:2933 60
|
|
|
|
|
|
TransitionPhase_E933:
|
|
lda #$00 ; CPU:$E934 PRG:2934 A9 00
|
|
sta $1A ; CPU:$E936 PRG:2936 85 1A
|
|
sta $1B ; CPU:$E938 PRG:2938 85 1B
|
|
|
|
inc $88 ; CPU:$E93A PRG:293A E6 88
|
|
inc $88 ; CPU:$E93C PRG:293C E6 88
|
|
|
|
rts ; CPU:$E93E PRG:293E 60
|
|
|
|
|
|
;==============================================================================
|
|
; $E93F-$E96D: Transition phase 2
|
|
;
|
|
; Uses bit $40 of $028C and timer/state value $89 to alternate the object
|
|
; state between values $46 and $47. Eventually transfers to $EA14.
|
|
;==============================================================================
|
|
|
|
UpdateIntermissionState2Phase2:
|
|
lda $028C ; CPU:$E93F PRG:293F AD 8C 02
|
|
and #$40 ; CPU:$E942 PRG:2942 29 40
|
|
bne TransitionPhase_E953 ; CPU:$E944 PRG:2944 D0 0F
|
|
|
|
lda #$46 ; CPU:$E946 PRG:2946 A9 46
|
|
sta $028C ; CPU:$E948 PRG:2948 8D 8C 02
|
|
|
|
lda #$45 ; CPU:$E94B PRG:294B A9 45
|
|
sta $028E ; CPU:$E94D PRG:294D 8D 8E 02
|
|
|
|
lda #$40 ; CPU:$E950 PRG:2950 A9 40
|
|
sta $89 ; CPU:$E952 PRG:2952 85 89
|
|
|
|
rts ; CPU:$E954 PRG:2954 60
|
|
|
|
|
|
TransitionPhase_E953:
|
|
dec $89 ; CPU:$E955 PRG:2955 C6 89
|
|
beq TransitionPhase_E958 ; CPU:$E957 PRG:2957 F0 01
|
|
|
|
rts ; CPU:$E959 PRG:2959 60
|
|
|
|
|
|
TransitionPhase_E958:
|
|
lda $028C ; CPU:$E95A PRG:295A AD 8C 02
|
|
cmp #$47 ; CPU:$E95D PRG:295D C9 47
|
|
bne TransitionPhase_E963 ; CPU:$E95F PRG:295F D0 03
|
|
|
|
jmp $EA14 ; CPU:$E961 PRG:2961 4C 14 EA
|
|
|
|
|
|
TransitionPhase_E963:
|
|
lda #$47 ; CPU:$E964 PRG:2964 A9 47
|
|
sta $028C ; CPU:$E966 PRG:2966 8D 8C 02
|
|
|
|
lda #$40 ; CPU:$E969 PRG:2969 A9 40
|
|
sta $89 ; CPU:$E96B PRG:296B 85 89
|
|
|
|
rts ; CPU:$E96D PRG:296D 60
|
|
|
|
|
|
;==============================================================================
|
|
; $E96E-$E97C: Transition State $04 Dispatcher
|
|
;
|
|
; $88 is an even byte offset into the four-entry phase table.
|
|
;==============================================================================
|
|
DispatchIntermissionState4Phase:
|
|
ldy $88 ; CPU:$E96E PRG:296E A4 88
|
|
|
|
lda IntermissionState4PhaseTable,y ; CPU:$E970 PRG:2970 B9 7D E9
|
|
sta $10 ; CPU:$E973 PRG:2973 85 10
|
|
|
|
lda IntermissionState4PhaseTable+1,y ; CPU:$E975 PRG:2975 B9 7E E9
|
|
sta $11 ; CPU:$E978 PRG:2978 85 11
|
|
|
|
jmp ($0010) ; CPU:$E97A PRG:297A 6C 10 00 85 E9
|
|
|
|
;==============================================================================
|
|
; $E97D-$E984: Transition State $04 Phase Table
|
|
;==============================================================================
|
|
IntermissionState4PhaseTable:
|
|
.word UpdateIntermissionState4Phase0 ; CPU:$E97D PRG:297D 85 E9
|
|
.word UpdateIntermissionState4Phase1 ; CPU:$E97F PRG:297F AE E9
|
|
.word UpdateIntermissionState4Phase2 ; CPU:$E981 PRG:2981 D9 E9
|
|
.word UpdateIntermissionState4Phase3 ; CPU:$E983 PRG:2983 0A EA
|
|
|
|
;==============================================================================
|
|
; $E985-$E9AD: Phase 0
|
|
;
|
|
; Waits until $0278 reaches $D8, advances $88, then installs the initial
|
|
; mirrored object/state configuration.
|
|
;==============================================================================
|
|
|
|
UpdateIntermissionState4Phase0:
|
|
lda $0278 ; CPU:$E985 PRG:2985 AD 78 02
|
|
cmp #$D8 ; CPU:$E988 PRG:2988 C9 D8
|
|
bcc TransitionPhase_E98D ; CPU:$E98A PRG:298A 90 01
|
|
|
|
rts ; CPU:$E98C PRG:298C 60
|
|
|
|
TransitionPhase_E98D:
|
|
inc $88 ; CPU:$E98D PRG:298D E6 88
|
|
inc $88 ; CPU:$E98F PRG:298F E6 88
|
|
|
|
lda #$4C ; CPU:$E991 PRG:2991 A9 4C
|
|
sta $028C ; CPU:$E993 PRG:2993 8D 8C 02
|
|
|
|
lda #$20 ; CPU:$E996 PRG:2996 A9 20
|
|
sta $0292 ; CPU:$E998 PRG:2998 8D 92 02
|
|
|
|
lda #$F7 ; CPU:$E99B PRG:299B A9 F7
|
|
sta $0274 ; CPU:$E99D PRG:299D 8D 74 02
|
|
|
|
lda #$7C ; CPU:$E9A0 PRG:29A0 A9 7C
|
|
sta $0276 ; CPU:$E9A2 PRG:29A2 8D 76 02
|
|
|
|
lda #$FF ; CPU:$E9A5 PRG:29A5 A9 FF
|
|
sta $1A ; CPU:$E9A7 PRG:29A7 85 1A
|
|
|
|
lda #$00 ; CPU:$E9A9 PRG:29A9 A9 00
|
|
sta $1B ; CPU:$E9AB PRG:29AB 85 1B
|
|
|
|
rts ; CPU:$E9AD PRG:29AD 60
|
|
|
|
;==============================================================================
|
|
; $E9AE-$E9D8: Phase 1
|
|
;
|
|
; Waits for $0274 to reach zero, advances $88 and installs the next object
|
|
; configuration.
|
|
;==============================================================================
|
|
|
|
UpdateIntermissionState4Phase1:
|
|
lda $0274 ; CPU:$E9AE PRG:29AE AD 74 02
|
|
beq TransitionPhase_E9B4 ; CPU:$E9B1 PRG:29B1 F0 01
|
|
|
|
rts ; CPU:$E9B3 PRG:29B3 60
|
|
|
|
TransitionPhase_E9B4:
|
|
inc $88 ; CPU:$E9B4 PRG:29B4 E6 88
|
|
inc $88 ; CPU:$E9B6 PRG:29B6 E6 88
|
|
|
|
lda #$28 ; CPU:$E9B8 PRG:29B8 A9 28
|
|
sta $4C ; CPU:$E9BA PRG:29BA 85 4C
|
|
|
|
lda #$4A ; CPU:$E9BC PRG:29BC A9 4A
|
|
sta $028C ; CPU:$E9BE PRG:29BE 8D 8C 02
|
|
|
|
lda #$23 ; CPU:$E9C1 PRG:29C1 A9 23
|
|
sta $0292 ; CPU:$E9C3 PRG:29C3 8D 92 02
|
|
|
|
lda #$09 ; CPU:$E9C6 PRG:29C6 A9 09
|
|
sta $0274 ; CPU:$E9C8 PRG:29C8 8D 74 02
|
|
|
|
lda #$7C ; CPU:$E9CB PRG:29CB A9 7C
|
|
sta $0276 ; CPU:$E9CD PRG:29CD 8D 76 02
|
|
|
|
lda #$01 ; CPU:$E9D0 PRG:29D0 A9 01
|
|
sta $1A ; CPU:$E9D2 PRG:29D2 85 1A
|
|
|
|
lda #$00 ; CPU:$E9D4 PRG:29D4 A9 00
|
|
sta $1B ; CPU:$E9D6 PRG:29D6 85 1B
|
|
|
|
rts ; CPU:$E9D8 PRG:29D8 60
|
|
|
|
;==============================================================================
|
|
; $E9D9-$EA09: Phase 2
|
|
;
|
|
; Enables transition flags, waits until $0274 reaches $19, then advances $88
|
|
; and sets the next mirrored-state values.
|
|
;==============================================================================
|
|
UpdateIntermissionState4Phase2:
|
|
lda #$01 ; CPU:$E9D9 PRG:29D9 A9 01
|
|
sta $060D ; CPU:$E9DB PRG:29DB 8D 0D 06
|
|
sta $060E ; CPU:$E9DE PRG:29DE 8D 0E 06
|
|
|
|
lda $0274 ; CPU:$E9E1 PRG:29E1 AD 74 02
|
|
cmp #$19 ; CPU:$E9E4 PRG:29E4 C9 19
|
|
bcs TransitionPhase_E9E8 ; CPU:$E9E6 PRG:29E6 B0 01
|
|
|
|
rts ; CPU:$E9E8 PRG:29E8 60
|
|
|
|
TransitionPhase_E9E8:
|
|
inc $88 ; CPU:$E9E9 PRG:29E9 E6 88
|
|
inc $88 ; CPU:$E9EB PRG:29EB E6 88
|
|
|
|
lda #$4C ; CPU:$E9ED PRG:29ED A9 4C
|
|
sta $028D ; CPU:$E9EF PRG:29EF 8D 8D 02
|
|
|
|
lda #$21 ; CPU:$E9F2 PRG:29F2 A9 21
|
|
sta $0293 ; CPU:$E9F4 PRG:29F4 8D 93 02
|
|
|
|
lda #$11 ; CPU:$E9F7 PRG:29F7 A9 11
|
|
sta $0278 ; CPU:$E9F9 PRG:29F9 8D 78 02
|
|
|
|
lda #$84 ; CPU:$E9FC PRG:29FC A9 84
|
|
sta $027A ; CPU:$E9FE PRG:29FE 8D 7A 02
|
|
|
|
lda #$01 ; CPU:$EA01 PRG:2A01 A9 01
|
|
sta $1E ; CPU:$EA03 PRG:2A03 85 1E
|
|
|
|
lda #$00 ; CPU:$EA05 PRG:2A05 A9 00
|
|
sta $1F ; CPU:$EA07 PRG:2A07 85 1F
|
|
|
|
rts ; CPU:$EA09 PRG:2A09 60
|
|
|
|
;==============================================================================
|
|
; $EA0A-$EA18: Phase 3
|
|
;
|
|
; Waits for $0278 to reach zero, then primes the next game-mode/state
|
|
; transition.
|
|
;==============================================================================
|
|
UpdateIntermissionState4Phase3:
|
|
lda $0278 ; CPU:$EA0A PRG:2A0A AD 78 02
|
|
beq TransitionPhase_EA10 ; CPU:$EA0D PRG:2A0D F0 01
|
|
|
|
rts ; CPU:$EA0F PRG:2A0F 60
|
|
|
|
TransitionPhase_EA10:
|
|
lda #$40 ; CPU:$EA10 PRG:2A10 A9 40
|
|
sta $4C ; CPU:$EA12 PRG:2A12 85 4C
|
|
|
|
lda #$00 ; CPU:$EA14 PRG:2A14 A9 00
|
|
sta $3F ; CPU:$EA16 PRG:2A16 85 3F
|
|
|
|
rts ; CPU:$EA18 PRG:2A18 60
|
|
|
|
;==============================================================================
|
|
; $EA19-$EA93: Update Mirrored Gameplay Object Positions
|
|
;
|
|
; Local:
|
|
; Walks five four-byte structures in parallel:
|
|
;
|
|
; $00/$01 -> source gameplay structures beginning at $001A
|
|
; $02/$03 -> mirrored structures beginning at $0274
|
|
;
|
|
; Movement increments from the source structures are added into mirrored
|
|
; coordinates. Attribute bit $20 in $0292+ is adjusted according to the
|
|
; resulting coordinate, and coordinate reset/wrap handling is performed.
|
|
;
|
|
; Global:
|
|
; Called from gameplay transition processing before render data is rebuilt.
|
|
;
|
|
; Notes:
|
|
; Several branches deliberately re-enter shared code, so global address-style
|
|
; labels are used throughout.
|
|
;==============================================================================
|
|
UpdateTransitionObjectPositions:
|
|
lda #$1A ; CPU:$EA19 PRG:2A19 A9 1A
|
|
sta $00 ; CPU:$EA1B PRG:2A1B 85 00
|
|
|
|
lda #$00 ; CPU:$EA1D PRG:2A1D A9 00
|
|
sta $01 ; CPU:$EA1F PRG:2A1F 85 01
|
|
|
|
lda #$74 ; CPU:$EA21 PRG:2A21 A9 74
|
|
sta $02 ; CPU:$EA23 PRG:2A23 85 02
|
|
|
|
lda #$02 ; CPU:$EA25 PRG:2A25 A9 02
|
|
sta $03 ; CPU:$EA27 PRG:2A27 85 03
|
|
|
|
ldx #$00 ; CPU:$EA29 PRG:2A29 A2 00
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EA2B
|
|
; Process one structure.
|
|
;------------------------------------------------------------------------------
|
|
UpdateNextTransitionObject:
|
|
ldy #$00 ; CPU:$EA2B PRG:2A2B A0 00
|
|
|
|
lda ($02),y ; CPU:$EA2D PRG:2A2D B1 02
|
|
beq AdvanceTransitionObjectPointers ; CPU:$EA2F PRG:2A2F F0 43
|
|
|
|
iny ; CPU:$EA31 PRG:2A31 C8
|
|
|
|
lda ($00),y ; CPU:$EA32 PRG:2A32 B1 00
|
|
clc ; CPU:$EA34 PRG:2A34 18
|
|
adc ($02),y ; CPU:$EA35 PRG:2A35 71 02
|
|
sta ($02),y ; CPU:$EA37 PRG:2A37 91 02
|
|
|
|
dey ; CPU:$EA39 PRG:2A39 88
|
|
|
|
lda ($00),y ; CPU:$EA3A PRG:2A3A B1 00
|
|
adc ($02),y ; CPU:$EA3C PRG:2A3C 71 02
|
|
sta ($02),y ; CPU:$EA3E PRG:2A3E 91 02
|
|
|
|
cmp #$C0 ; CPU:$EA40 PRG:2A40 C9 C0
|
|
bcc UpdateTransitionObjectAttribute ; CPU:$EA42 PRG:2A42 90 0A
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EA44
|
|
; Set attribute bit $20.
|
|
;------------------------------------------------------------------------------
|
|
SetTransitionObjectAttributeBit:
|
|
lda #$20 ; CPU:$EA44 PRG:2A44 A9 20
|
|
ora $0292,x ; CPU:$EA46 PRG:2A46 1D 92 02
|
|
sta $0292,x ; CPU:$EA49 PRG:2A49 9D 92 02
|
|
|
|
bne CheckTransitionObjectWrap ; CPU:$EA4C PRG:2A4C D0 0C
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EA4E
|
|
; Clear/set attribute according to coordinate range.
|
|
;
|
|
; If value < $40, branch backward to $EA44 and set bit $20.
|
|
; Otherwise clear bit $20 with mask $DF.
|
|
;------------------------------------------------------------------------------
|
|
|
|
UpdateTransitionObjectAttribute:
|
|
cmp #$40 ; CPU:$EA4E PRG:2A4E C9 40
|
|
bcc SetTransitionObjectAttributeBit ; CPU:$EA50 PRG:2A50 90 F2
|
|
|
|
lda #$DF ; CPU:$EA52 PRG:2A52 A9 DF
|
|
and $0292,x ; CPU:$EA54 PRG:2A54 3D 92 02
|
|
sta $0292,x ; CPU:$EA57 PRG:2A57 9D 92 02
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EA5A
|
|
; Coordinate wrap/reset test.
|
|
;------------------------------------------------------------------------------
|
|
|
|
CheckTransitionObjectWrap:
|
|
ldy #$00 ; CPU:$EA5A PRG:2A5A A0 00
|
|
|
|
lda ($02),y ; CPU:$EA5C PRG:2A5C B1 02
|
|
cmp #$FC ; CPU:$EA5E PRG:2A5E C9 FC
|
|
bcc CheckTransitionObjectLowBoundary ; CPU:$EA60 PRG:2A60 90 0E
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EA62
|
|
; Reset coordinate/movement state.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ResetTransitionObjectPosition:
|
|
lda #$00 ; CPU:$EA62 PRG:2A62 A9 00
|
|
sta ($02),y ; CPU:$EA64 PRG:2A64 91 02
|
|
sta ($00),y ; CPU:$EA66 PRG:2A66 91 00
|
|
|
|
iny ; CPU:$EA68 PRG:2A68 C8
|
|
sta ($00),y ; CPU:$EA69 PRG:2A69 91 00
|
|
|
|
iny ; CPU:$EA6B PRG:2A6B C8
|
|
sta ($02),y ; CPU:$EA6C PRG:2A6C 91 02
|
|
|
|
bne AdvanceTransitionObjectPointers ; CPU:$EA6E PRG:2A6E D0 04
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EA70
|
|
; Values below $04 also take the reset path.
|
|
;------------------------------------------------------------------------------
|
|
|
|
CheckTransitionObjectLowBoundary:
|
|
cmp #$04 ; CPU:$EA70 PRG:2A70 C9 04
|
|
bcc ResetTransitionObjectPosition ; CPU:$EA72 PRG:2A72 90 EE
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EA74
|
|
; Advance both source and mirrored pointers.
|
|
;------------------------------------------------------------------------------
|
|
|
|
AdvanceTransitionObjectPointers:
|
|
lda $00 ; CPU:$EA74 PRG:2A74 A5 00
|
|
clc ; CPU:$EA76 PRG:2A76 18
|
|
adc #$04 ; CPU:$EA77 PRG:2A77 69 04
|
|
sta $00 ; CPU:$EA79 PRG:2A79 85 00
|
|
|
|
lda $01 ; CPU:$EA7B PRG:2A7B A5 01
|
|
adc #$00 ; CPU:$EA7D PRG:2A7D 69 00
|
|
sta $01 ; CPU:$EA7F PRG:2A7F 85 01
|
|
|
|
lda $02 ; CPU:$EA81 PRG:2A81 A5 02
|
|
clc ; CPU:$EA83 PRG:2A83 18
|
|
adc #$04 ; CPU:$EA84 PRG:2A84 69 04
|
|
sta $02 ; CPU:$EA86 PRG:2A86 85 02
|
|
|
|
lda $03 ; CPU:$EA88 PRG:2A88 A5 03
|
|
adc #$00 ; CPU:$EA8A PRG:2A8A 69 00
|
|
sta $03 ; CPU:$EA8C PRG:2A8C 85 03
|
|
|
|
inx ; CPU:$EA8E PRG:2A8E E8
|
|
|
|
cpx #$05 ; CPU:$EA8F PRG:2A8F E0 05
|
|
bne UpdateNextTransitionObject ; CPU:$EA91 PRG:2A91 D0 98
|
|
|
|
rts ; CPU:$EA93 PRG:2A93 60
|
|
|
|
|
|
;==============================================================================
|
|
; $EA94-$EAA2: Gameplay Animation State Dispatcher
|
|
;
|
|
; $87 is an even state value used directly as an offset into the pointer table
|
|
; at $EAA3.
|
|
;==============================================================================
|
|
|
|
DispatchTransitionAnimation:
|
|
ldy $87 ; CPU:$EA94 PRG:2A94 A4 87
|
|
|
|
lda TransitionAnimationHandlerTable,y ; CPU:$EA96 PRG:2A96 B9 A3 EA
|
|
sta $10 ; CPU:$EA99 PRG:2A99 85 10
|
|
|
|
lda TransitionAnimationHandlerTable+1,y ; CPU:$EA9B PRG:2A9B B9 A4 EA
|
|
sta $11 ; CPU:$EA9E PRG:2A9E 85 11
|
|
|
|
jmp ($0010) ; CPU:$EAA0 PRG:2AA0 6C 10 00 A9 EA
|
|
|
|
;==============================================================================
|
|
; $EAA3-$EAA8: Gameplay Animation State Table
|
|
;==============================================================================
|
|
|
|
TransitionAnimationHandlerTable:
|
|
.word DispatchTransitionAnimationPhase ; CPU:$EAA3 PRG:2AA3 A9 EA
|
|
.word DispatchTransitionAnimationState2 ; CPU:$EAA5 PRG:2AA5 3D EB
|
|
.word DispatchTransitionAnimationState4 ; CPU:$EAA7 PRG:2AA7 6D EB
|
|
|
|
;==============================================================================
|
|
; $EAA9-$EAB7: Animation Substate Dispatcher
|
|
;
|
|
; $88 is an even state value used directly as an offset into this table.
|
|
;==============================================================================
|
|
|
|
DispatchTransitionAnimationPhase:
|
|
ldy $88 ; CPU:$EAA9 PRG:2AA9 A4 88
|
|
|
|
lda TransitionAnimationPhaseTable,y ; CPU:$EAAB PRG:2AAB B9 B8 EA
|
|
sta $10 ; CPU:$EAAE PRG:2AAE 85 10
|
|
|
|
lda TransitionAnimationPhaseTable+1,y ; CPU:$EAB0 PRG:2AB0 B9 B9 EA
|
|
sta $11 ; CPU:$EAB3 PRG:2AB3 85 11
|
|
|
|
jmp ($0010) ; CPU:$EAB5 PRG:2AB5 6C 10 00 C0 EA
|
|
|
|
|
|
;==============================================================================
|
|
; $EAB8-$EABF: Animation Substate Table
|
|
;==============================================================================
|
|
|
|
TransitionAnimationPhaseTable:
|
|
.word UpdateTransitionAnimationFrame ; CPU:$EAB8 PRG:2AB8 C0 EA
|
|
.word UpdateTransitionAnimationType1 ; CPU:$EABA PRG:2ABA D6 EA
|
|
.word UpdateTransitionAnimationType2 ; CPU:$EABC PRG:2ABC ED EA
|
|
.word UpdateTransitionAnimationPattern ; CPU:$EABE PRG:2ABE 04 EB
|
|
|
|
|
|
;==============================================================================
|
|
; $EAC0-$EACD: Animation Substate 0
|
|
;
|
|
; Advances $B7 modulo eight and uses it to select a value for $028D.
|
|
;==============================================================================
|
|
|
|
UpdateTransitionAnimationFrame:
|
|
inc $B7 ; CPU:$EAC0 PRG:2AC0 E6 B7
|
|
|
|
lda $B7 ; CPU:$EAC2 PRG:2AC2 A5 B7
|
|
and #$07 ; CPU:$EAC4 PRG:2AC4 29 07
|
|
tay ; CPU:$EAC6 PRG:2AC6 A8
|
|
|
|
lda TransitionAnimationFrameTable,y ; CPU:$EAC7 PRG:2AC7 B9 CE EA
|
|
sta $028D ; CPU:$EACA PRG:2ACA 8D 8D 02
|
|
|
|
rts ; CPU:$EACD PRG:2ACD 60
|
|
|
|
|
|
;==============================================================================
|
|
; $EACE-$EAD5: Animation frame table
|
|
;==============================================================================
|
|
|
|
TransitionAnimationFrameTable:
|
|
.byte $04,$04,$04,$05 ; CPU:$EACE PRG:2ACE 04 04 04 05
|
|
.byte $05,$04,$01,$01 ; CPU:$EAD2 PRG:2AD2 05 04 01 01
|
|
|
|
|
|
;==============================================================================
|
|
; $EAD6-$EAEC: Animation Substate 1
|
|
;
|
|
; Runs only when ($4B & 7) == 0. Alternates $028C between $0C and $0D
|
|
; according to frame-counter bit 3, then falls back into the common animation
|
|
; update path beginning at $EAC0.
|
|
;==============================================================================
|
|
|
|
UpdateTransitionAnimationType1:
|
|
lda $4B ; CPU:$EAD6 PRG:2AD6 A5 4B
|
|
and #$07 ; CPU:$EAD8 PRG:2AD8 29 07
|
|
bne UpdateTransitionAnimationFrame ; CPU:$EADA PRG:2ADA D0 E4
|
|
|
|
lda $4B ; CPU:$EADC PRG:2ADC A5 4B
|
|
and #$08 ; CPU:$EADE PRG:2ADE 29 08
|
|
bne AnimationSubstate_EAE7 ; CPU:$EAE0 PRG:2AE0 D0 04
|
|
|
|
lda #$0C ; CPU:$EAE2 PRG:2AE2 A9 0C
|
|
bne AnimationSubstate_EAE9 ; CPU:$EAE4 PRG:2AE4 D0 02
|
|
|
|
|
|
AnimationSubstate_EAE7:
|
|
lda #$0D ; CPU:$EAE6 PRG:2AE6 A9 0D
|
|
|
|
|
|
AnimationSubstate_EAE9:
|
|
sta $028C ; CPU:$EAE8 PRG:2AE8 8D 8C 02
|
|
|
|
bne UpdateTransitionAnimationFrame ; CPU:$EAEB PRG:2AEB D0 D3
|
|
|
|
|
|
;==============================================================================
|
|
; $EAED-$EB03: Animation Substate 2
|
|
;
|
|
; Updates only once every eight frames and alternates $028C between $1E/$1F
|
|
; according to frame-counter bit 3.
|
|
;==============================================================================
|
|
|
|
UpdateTransitionAnimationType2:
|
|
lda $4B ; CPU:$EAED PRG:2AED A5 4B
|
|
and #$07 ; CPU:$EAEF PRG:2AEF 29 07
|
|
beq AnimationSubstate_EAF5 ; CPU:$EAF1 PRG:2AF1 F0 01
|
|
|
|
rts ; CPU:$EAF3 PRG:2AF3 60
|
|
|
|
|
|
AnimationSubstate_EAF5:
|
|
lda $4B ; CPU:$EAF4 PRG:2AF4 A5 4B
|
|
and #$08 ; CPU:$EAF6 PRG:2AF6 29 08
|
|
bne AnimationSubstate_EB00 ; CPU:$EAF8 PRG:2AF8 D0 04
|
|
|
|
lda #$1E ; CPU:$EAFA PRG:2AFA A9 1E
|
|
bne AnimationSubstate_EB02 ; CPU:$EAFC PRG:2AFC D0 02
|
|
|
|
|
|
AnimationSubstate_EB00:
|
|
lda #$1F ; CPU:$EAFE PRG:2AFE A9 1F
|
|
|
|
|
|
AnimationSubstate_EB02:
|
|
sta $028C ; CPU:$EB00 PRG:2B00 8D 8C 02
|
|
|
|
rts ; CPU:$EB03 PRG:2B03 60
|
|
|
|
|
|
;==============================================================================
|
|
; $EB04-$EB28: Animation Substate 3
|
|
;
|
|
; Advances $B7 modulo eight, maps the result through a small index table, and
|
|
; uses the selected entry to load four consecutive animation values into
|
|
; $028D-$0290.
|
|
;
|
|
; The final BNE intentionally branches backward into the common update path.
|
|
;==============================================================================
|
|
|
|
UpdateTransitionAnimationPattern:
|
|
inc $B7 ; CPU:$EB04 PRG:2B04 E6 B7
|
|
|
|
lda $B7 ; CPU:$EB06 PRG:2B06 A5 B7
|
|
and #$07 ; CPU:$EB08 PRG:2B08 29 07
|
|
tay ; CPU:$EB0A PRG:2B0A A8
|
|
|
|
lda TransitionAnimationPatternIndex,y ; CPU:$EB0B PRG:2B0B B9 29 EB
|
|
tay ; CPU:$EB0E PRG:2B0E A8
|
|
|
|
lda TransitionAnimationPatternTiles,y ; CPU:$EB0F PRG:2B0F B9 31 EB
|
|
sta $028D ; CPU:$EB12 PRG:2B12 8D 8D 02
|
|
|
|
lda TransitionAnimationPatternTiles+1,y ; CPU:$EB15 PRG:2B15 B9 32 EB
|
|
sta $028E ; CPU:$EB18 PRG:2B18 8D 8E 02
|
|
|
|
lda TransitionAnimationPatternTiles+2,y ; CPU:$EB1B PRG:2B1B B9 33 EB
|
|
sta $028F ; CPU:$EB1E PRG:2B1E 8D 8F 02
|
|
|
|
lda TransitionAnimationPatternTiles+3,y ; CPU:$EB21 PRG:2B21 B9 34 EB
|
|
sta $0290 ; CPU:$EB24 PRG:2B24 8D 90 02
|
|
|
|
bne UpdateTransitionAnimationType2 ; CPU:$EB27 PRG:2B27 D0 C4
|
|
|
|
|
|
;==============================================================================
|
|
; $EB29-$EB30: Animation pattern index table
|
|
;==============================================================================
|
|
|
|
TransitionAnimationPatternIndex:
|
|
.byte $00,$00,$00,$04 ; CPU:$EB29 PRG:2B29 00 00 00 04
|
|
.byte $04,$00,$08,$08 ; CPU:$EB2D PRG:2B2D 04 00 08 08
|
|
|
|
|
|
;==============================================================================
|
|
; $EB31-$EB3C: Animation pattern data
|
|
;
|
|
; Indexed using offsets 0, 4 and 8. The final logical group continues beyond
|
|
; this initial range, so preserve the next code/data boundary carefully.
|
|
;==============================================================================
|
|
TransitionAnimationPatternTiles:
|
|
.byte $3C,$3D,$3E,$3F ; CPU:$EB31 PRG:2B31 3C 3D 3E 3F
|
|
.byte $3C,$40,$3E,$41 ; CPU:$EB35 PRG:2B35 3C 40 3E 41
|
|
.byte $38,$39,$3A,$3B ; CPU:$EB39 PRG:2B39 38 39 3A 3B
|
|
|
|
;==============================================================================
|
|
; $EB3D-$EB4B: Gameplay Animation State $02 Dispatcher
|
|
;==============================================================================
|
|
|
|
DispatchTransitionAnimationState2:
|
|
ldy $88 ; CPU:$EB3D PRG:2B3D A4 88
|
|
|
|
lda TransitionAnimationState2Table,y ; CPU:$EB3F PRG:2B3F B9 4C EB
|
|
sta $10 ; CPU:$EB42 PRG:2B42 85 10
|
|
|
|
lda TransitionAnimationState2Table+1,y ; CPU:$EB44 PRG:2B44 B9 4D EB
|
|
sta $11 ; CPU:$EB47 PRG:2B47 85 11
|
|
|
|
jmp ($0010) ; CPU:$EB49 PRG:2B49 6C 10 00 C0 EA
|
|
|
|
|
|
;==============================================================================
|
|
; $EB4C-$EB51: Gameplay Animation State $02 Pointer Table
|
|
;==============================================================================
|
|
|
|
TransitionAnimationState2Table:
|
|
.word UpdateTransitionAnimationFrame ; CPU:$EB4C PRG:2B4C C0 EA
|
|
.word UpdateTransitionAnimationState2 ; CPU:$EB4E PRG:2B4E 52 EB
|
|
.word UpdateTransitionAnimationFrame ; CPU:$EB50 PRG:2B50 C0 EA
|
|
|
|
|
|
;==============================================================================
|
|
; $EB52-$EB6C: Animation State $02 Handler
|
|
;==============================================================================
|
|
|
|
UpdateTransitionAnimationState2:
|
|
jsr UpdateTransitionAnimationType1 ; CPU:$EB52 PRG:2B52 20 D6 EA
|
|
|
|
lda $0274 ; CPU:$EB55 PRG:2B55 AD 74 02
|
|
cmp #$7D ; CPU:$EB58 PRG:2B58 C9 7D
|
|
bne AnimationState2_EB62 ; CPU:$EB5A PRG:2B5A D0 06
|
|
|
|
lda #$43 ; CPU:$EB5C PRG:2B5C A9 43
|
|
sta $028E ; CPU:$EB5E PRG:2B5E 8D 8E 02
|
|
|
|
rts ; CPU:$EB61 PRG:2B61 60
|
|
|
|
|
|
AnimationState2_EB62:
|
|
cmp #$7B ; CPU:$EB62 PRG:2B62 C9 7B
|
|
beq AnimationState2_EB68 ; CPU:$EB64 PRG:2B64 F0 01
|
|
|
|
rts ; CPU:$EB66 PRG:2B66 60
|
|
|
|
|
|
AnimationState2_EB68:
|
|
lda #$44 ; CPU:$EB67 PRG:2B67 A9 44
|
|
sta $028E ; CPU:$EB69 PRG:2B69 8D 8E 02
|
|
|
|
rts ; CPU:$EB6C PRG:2B6C 60
|
|
|
|
|
|
;==============================================================================
|
|
; $EB6D-$EB7B: Gameplay Animation State $04 Dispatcher
|
|
;==============================================================================
|
|
DispatchTransitionAnimationState4:
|
|
ldy $88 ; CPU:$EB6D PRG:2B6D A4 88
|
|
|
|
lda TransitionAnimationState4Table,y ; CPU:$EB6F PRG:2B6F B9 7C EB
|
|
sta $10 ; CPU:$EB72 PRG:2B72 85 10
|
|
|
|
lda TransitionAnimationState4Table+1,y ; CPU:$EB74 PRG:2B74 B9 7D EB
|
|
sta $11 ; CPU:$EB77 PRG:2B77 85 11
|
|
|
|
jmp ($0010) ; CPU:$EB79 PRG:2B79 6C 10 00 C0 EA
|
|
|
|
;==============================================================================
|
|
; $EB7C-$EB83: Gameplay Animation State $04 Pointer Table
|
|
;==============================================================================
|
|
|
|
TransitionAnimationState4Table:
|
|
.word UpdateTransitionAnimationFrame ; CPU:$EB7C PRG:2B7C C0 EA
|
|
.word UpdateTransitionAnimationState4Type1 ; CPU:$EB7E PRG:2B7E 84 EB
|
|
.word UpdateTransitionAnimationState4Type2 ; CPU:$EB80 PRG:2B80 9F EB
|
|
.word UpdateTransitionAnimationState4Type2 ; CPU:$EB82 PRG:2B82 9F EB
|
|
|
|
;==============================================================================
|
|
; $EB84-$EB9E: Animation State $04 Handler 1
|
|
;
|
|
; Alternates $028C between $48/$49 every eight frames, while non-update
|
|
; frames tail-jump into the common $EAC0 animation updater.
|
|
;==============================================================================
|
|
UpdateTransitionAnimationState4Type1:
|
|
lda $4B ; CPU:$EB84 PRG:2B84 A5 4B
|
|
and #$07 ; CPU:$EB86 PRG:2B86 29 07
|
|
beq AnimationState4_EB8E ; CPU:$EB88 PRG:2B88 F0 03
|
|
|
|
jmp UpdateTransitionAnimationFrame ; CPU:$EB8A PRG:2B8A 4C C0 EA
|
|
|
|
AnimationState4_EB8E:
|
|
lda $4B ; CPU:$EB8D PRG:2B8D A5 4B
|
|
and #$08 ; CPU:$EB8F PRG:2B8F 29 08
|
|
bne AnimationState4_EB97 ; CPU:$EB91 PRG:2B91 D0 04
|
|
|
|
lda #$48 ; CPU:$EB93 PRG:2B93 A9 48
|
|
bne AnimationState4_EB99 ; CPU:$EB95 PRG:2B95 D0 02
|
|
|
|
AnimationState4_EB97:
|
|
lda #$49 ; CPU:$EB97 PRG:2B97 A9 49
|
|
|
|
AnimationState4_EB99:
|
|
sta $028C ; CPU:$EB99 PRG:2B99 8D 8C 02
|
|
|
|
jmp UpdateTransitionAnimationFrame ; CPU:$EB9C PRG:2B9C 4C C0 EA
|
|
|
|
;==============================================================================
|
|
; $EB9F-$EBB5: Animation State $04 Handler 2/3
|
|
;
|
|
; Alternates $028C between $4A and $4B every eight frames.
|
|
;==============================================================================
|
|
|
|
UpdateTransitionAnimationState4Type2:
|
|
lda $4B ; CPU:$EB9F PRG:2B9F A5 4B
|
|
and #$07 ; CPU:$EBA1 PRG:2BA1 29 07
|
|
beq AnimationState4_EBA6 ; CPU:$EBA3 PRG:2BA3 F0 01
|
|
|
|
rts ; CPU:$EBA5 PRG:2BA5 60
|
|
|
|
AnimationState4_EBA6:
|
|
lda $4B ; CPU:$EBA6 PRG:2BA6 A5 4B
|
|
and #$08 ; CPU:$EBA8 PRG:2BA8 29 08
|
|
bne AnimationState4_EBB0 ; CPU:$EBAA PRG:2BAA D0 04
|
|
|
|
lda #$4A ; CPU:$EBAC PRG:2BAC A9 4A
|
|
bne AnimationState4_EBB2 ; CPU:$EBAE PRG:2BAE D0 02
|
|
|
|
AnimationState4_EBB0:
|
|
lda #$4B ; CPU:$EBB0 PRG:2BB0 A9 4B
|
|
|
|
AnimationState4_EBB2:
|
|
sta $028C ; CPU:$EBB2 PRG:2BB2 8D 8C 02
|
|
|
|
rts ; CPU:$EBB5 PRG:2BB5 60
|
|
|
|
;==============================================================================
|
|
; $EBB6-$EC3F: Gameplay Lookup Data
|
|
;
|
|
; Raw lookup data preserved byte-for-byte.
|
|
; Semantic subdivision is deferred until the consuming routines are decoded.
|
|
;==============================================================================
|
|
|
|
MazeGameplayData_EBB6:
|
|
|
|
; $EBB6-$EBC5
|
|
.byte $00,$07,$00,$00,$00,$04,$01,$06 ; CPU:$EBB6 PRG:2BB6 00 07 00 00 00 04 01 06
|
|
.byte $01,$01,$01,$04,$01,$04,$02,$02 ; CPU:$EBBE PRG:2BBE 01 01 01 04 01 04 02 02
|
|
|
|
; $EBC6-$EBD5
|
|
.byte $02,$03,$02,$03,$02,$02,$02,$03 ; CPU:$EBC6 PRG:2BC6 02 03 02 03 02 02 02 03
|
|
.byte $02,$02,$02,$02,$03,$03,$03,$05 ; CPU:$EBCE PRG:2BCE 02 02 02 02 03 03 03 05
|
|
|
|
; $EBD6-$EBE5
|
|
.byte $03,$02,$03,$03,$03,$02,$03,$02 ; CPU:$EBD6 PRG:2BD6 03 02 03 03 03 02 03 02
|
|
.byte $04,$03,$03,$02,$03,$02,$04,$03 ; CPU:$EBDE PRG:2BDE 04 03 03 02 03 02 04 03
|
|
|
|
; $EBE6-$EBF5
|
|
.byte $03,$01,$04,$02,$05,$03,$03,$05 ; CPU:$EBE6 PRG:2BE6 03 01 04 02 05 03 03 05
|
|
.byte $04,$02,$05,$03,$03,$02,$04,$02 ; CPU:$EBEE PRG:2BEE 04 02 05 03 03 02 04 02
|
|
|
|
; $EBF6-$EC05
|
|
.byte $06,$03,$03,$01,$05,$02,$06,$03 ; CPU:$EBF6 PRG:2BF6 06 03 03 01 05 02 06 03
|
|
.byte $03,$01,$05,$02,$07,$03,$03,$03 ; CPU:$EBFE PRG:2BFE 03 01 05 02 07 03 03 03
|
|
|
|
; $EC06-$EC15
|
|
.byte $05,$02,$07,$03,$03,$01,$06,$02 ; CPU:$EC06 PRG:2C06 05 02 07 03 03 01 06 02
|
|
.byte $07,$03,$03,$01,$06,$02,$07,$03 ; CPU:$EC0E PRG:2C0E 07 03 03 01 06 02 07 03
|
|
|
|
; $EC16-$EC25
|
|
.byte $03,$00,$06,$02,$07,$03,$03,$01 ; CPU:$EC16 PRG:2C16 03 00 06 02 07 03 03 01
|
|
.byte $06,$02,$07,$03,$03,$00,$06,$02 ; CPU:$EC1E PRG:2C1E 06 02 07 03 03 00 06 02
|
|
|
|
; $EC26-$EC35
|
|
.byte $07,$03,$03,$00,$06,$02,$07,$03 ; CPU:$EC26 PRG:2C26 07 03 03 00 06 02 07 03
|
|
.byte $03,$00,$06,$02,$07,$03,$04,$00 ; CPU:$EC2E PRG:2C2E 03 00 06 02 07 03 04 00
|
|
|
|
; $EC36-$EC3F
|
|
.byte $06,$02,$07,$03,$04,$00,$06,$02 ; CPU:$EC36 PRG:2C36 06 02 07 03 04 00 06 02
|
|
.byte $07,$03 ; CPU:$EC3E PRG:2C3E 07 03
|
|
|
|
|
|
;==============================================================================
|
|
; $EC40-$ECAB: Gameplay Parameter Lookup Data
|
|
;
|
|
; Raw lookup data preserved byte-for-byte.
|
|
;
|
|
; The byte pattern strongly resembles little-endian 16-bit quantities, but
|
|
; semantic grouping is intentionally deferred until the consuming routines
|
|
; have been identified.
|
|
;==============================================================================
|
|
MazeGameplayData_EC40:
|
|
; $EC40-$EC4F
|
|
.byte $D0,$00,$C0,$00,$A0,$00,$B0,$00 ; CPU:$EC40 PRG:2C40 D0 00 C0 00 A0 00 B0 00
|
|
.byte $A0,$00,$80,$00,$A0,$00,$B0,$00 ; CPU:$EC48 PRG:2C48 A0 00 80 00 A0 00 B0 00
|
|
|
|
; $EC50-$EC5F
|
|
.byte $90,$00,$50,$00,$50,$00,$D0,$00 ; CPU:$EC50 PRG:2C50 90 00 50 00 50 00 D0 00
|
|
.byte $C0,$00,$A0,$00,$B0,$00,$A0,$00 ; CPU:$EC58 PRG:2C58 C0 00 A0 00 B0 00 A0 00
|
|
|
|
; $EC60-$EC6F
|
|
.byte $80,$00,$B0,$00,$C0,$00,$A0,$00 ; CPU:$EC60 PRG:2C60 80 00 B0 00 C0 00 A0 00
|
|
.byte $50,$00,$50,$00,$F0,$00,$E0,$00 ; CPU:$EC68 PRG:2C68 50 00 50 00 F0 00 E0 00
|
|
|
|
; $EC70-$EC7F
|
|
.byte $C0,$00,$E0,$00,$D0,$00,$B0,$00 ; CPU:$EC70 PRG:2C70 C0 00 E0 00 D0 00 B0 00
|
|
.byte $E0,$00,$F0,$00,$D0,$00,$70,$00 ; CPU:$EC78 PRG:2C78 E0 00 F0 00 D0 00 70 00
|
|
|
|
; $EC80-$EC8F
|
|
.byte $70,$00,$00,$01,$F0,$00,$D0,$00 ; CPU:$EC80 PRG:2C80 70 00 00 01 F0 00 D0 00
|
|
.byte $00,$01,$F0,$00,$D0,$00,$00,$01 ; CPU:$EC88 PRG:2C88 00 01 F0 00 D0 00 00 01
|
|
|
|
; $EC90-$EC9F
|
|
.byte $10,$01,$F0,$00,$80,$00,$80,$00 ; CPU:$EC90 PRG:2C90 10 01 F0 00 80 00 80 00
|
|
.byte $00,$01,$F0,$00,$D0,$00,$00,$01 ; CPU:$EC98 PRG:2C98 00 01 F0 00 D0 00 00 01
|
|
|
|
; $ECA0-$ECAB
|
|
.byte $F0,$00,$D0,$00,$20,$01,$30,$01 ; CPU:$ECA0 PRG:2CA0 F0 00 D0 00 20 01 30 01
|
|
.byte $10,$01,$80,$00 ; CPU:$ECA8 PRG:2CA8 10 01 80 00
|
|
|
|
|
|
|
|
;==============================================================================
|
|
; $ECAC-$ECFF: Gameplay Lookup / Parameter Data
|
|
;
|
|
; Raw data preserved byte-for-byte. Semantic subdivision is intentionally
|
|
; deferred until the consuming routines are decoded.
|
|
;==============================================================================
|
|
|
|
MazeGameplayData_ECAC:
|
|
|
|
; $ECAC-$ECBB
|
|
.byte $80,$00,$07,$14,$07,$14,$05,$14 ; CPU:$ECAC PRG:2CAC 80 00 07 14 07 14 05 14
|
|
.byte $05,$FF,$07,$14,$07,$14,$05,$FF ; CPU:$ECB4 PRG:2CB4 05 FF 07 14 07 14 05 FF
|
|
|
|
; $ECBC-$ECCB
|
|
.byte $00,$00,$05,$14,$05,$14,$05,$FF ; CPU:$ECBC PRG:2CBC 00 00 05 14 05 14 05 FF
|
|
.byte $00,$00,$05,$14,$05,$14,$05,$FF ; CPU:$ECC4 PRG:2CC4 00 00 05 14 05 14 05 FF
|
|
|
|
; $ECCC-$ECDB
|
|
.byte $00,$00,$14,$0A,$1E,$0F,$28,$14 ; CPU:$ECCC PRG:2CCC 00 00 14 0A 1E 0F 28 14
|
|
.byte $32,$19,$3C,$1E,$50,$28,$64,$32 ; CPU:$ECD4 PRG:2CD4 32 19 3C 1E 50 28 64 32
|
|
|
|
; $ECDC-$ECEB
|
|
.byte $02,$1E,$5A,$00,$03,$32,$00,$00 ; CPU:$ECDC PRG:2CDC 02 1E 5A 00 03 32 00 00
|
|
.byte $04,$00,$00,$00,$01,$07,$11,$20 ; CPU:$ECE4 PRG:2CE4 04 00 00 00 01 07 11 20
|
|
|
|
; $ECEC-$ECFB
|
|
.byte $2D,$1F,$D0,$D0,$10,$13,$D0,$D0 ; CPU:$ECEC PRG:2CEC 2D 1F D0 D0 10 13 D0 D0
|
|
.byte $10,$1D,$2D,$11,$C3,$C3,$03,$11 ; CPU:$ECF4 PRG:2CF4 10 1D 2D 11 C3 C3 03 11
|
|
|
|
; $ECFC-$ECFF
|
|
.byte $C3,$C3,$03,$11 ; CPU:$ECFC PRG:2CFC C3 C3 03 11
|
|
|
|
;==============================================================================
|
|
; $ED00-$EDFF: Gameplay Lookup / Pattern Data
|
|
;
|
|
; Raw data preserved byte-for-byte. This region contains highly structured
|
|
; repeated values and bit-pattern-like fields, but semantic subdivisions are
|
|
; deferred until the routines that consume this region are identified.
|
|
;==============================================================================
|
|
|
|
MazeLayoutData_ED00:
|
|
|
|
; $ED00-$ED0F
|
|
.byte $2D,$11,$03,$1F,$10,$1D,$03,$1F ; CPU:$ED00 PRG:2D00 2D 11 03 1F 10 1D 03 1F
|
|
.byte $10,$1D,$03,$11,$03,$1F,$10,$1D ; CPU:$ED08 PRG:2D08 10 1D 03 11 03 1F 10 1D
|
|
|
|
; $ED10-$ED1F
|
|
.byte $03,$1F,$10,$1D,$03,$11,$2D,$11 ; CPU:$ED10 PRG:2D10 03 1F 10 1D 03 11 2D 11
|
|
.byte $01,$11,$20,$11,$03,$11,$20,$11 ; CPU:$ED18 PRG:2D18 01 11 20 11 03 11 20 11
|
|
|
|
; $ED20-$ED2F
|
|
.byte $03,$11,$03,$11,$20,$11,$03,$11 ; CPU:$ED20 PRG:2D20 03 11 03 11 20 11 03 11
|
|
.byte $20,$11,$01,$11,$2D,$11,$03,$1E ; CPU:$ED28 PRG:2D28 20 11 01 11 2D 11 03 1E
|
|
|
|
; $ED30-$ED3F
|
|
.byte $10,$1C,$03,$1E,$10,$1C,$03,$1A ; CPU:$ED30 PRG:2D30 10 1C 03 1E 10 1C 03 1A
|
|
.byte $03,$1E,$10,$1C,$03,$1E,$10,$1C ; CPU:$ED38 PRG:2D38 03 1E 10 1C 03 1E 10 1C
|
|
|
|
; $ED40-$ED4F
|
|
.byte $03,$11,$2D,$11,$C3,$C3,$C3,$C3 ; CPU:$ED40 PRG:2D40 03 11 2D 11 C3 C3 C3 C3
|
|
.byte $83,$11,$2D,$11,$03,$1F,$10,$1D ; CPU:$ED48 PRG:2D48 83 11 2D 11 03 1F 10 1D
|
|
|
|
; $ED50-$ED5F
|
|
.byte $03,$1B,$03,$1F,$10,$10,$10,$1D ; CPU:$ED50 PRG:2D50 03 1B 03 1F 10 10 10 1D
|
|
.byte $03,$1B,$03,$1F,$10,$1D,$03,$11 ; CPU:$ED58 PRG:2D58 03 1B 03 1F 10 1D 03 11
|
|
|
|
; $ED60-$ED6F
|
|
.byte $2D,$11,$03,$1E,$10,$1C,$03,$11 ; CPU:$ED60 PRG:2D60 2D 11 03 1E 10 1C 03 11
|
|
.byte $03,$1E,$10,$13,$10,$1C,$03,$11 ; CPU:$ED68 PRG:2D68 03 1E 10 13 10 1C 03 11
|
|
|
|
; $ED70-$ED7F
|
|
.byte $03,$1E,$10,$1C,$03,$11,$2D,$11 ; CPU:$ED70 PRG:2D70 03 1E 10 1C 03 11 2D 11
|
|
.byte $C3,$03,$11,$83,$11,$83,$11,$C3 ; CPU:$ED78 PRG:2D78 C3 03 11 83 11 83 11 C3
|
|
|
|
; $ED80-$ED8F
|
|
.byte $03,$11,$2D,$1E,$90,$1D,$03,$15 ; CPU:$ED80 PRG:2D80 03 11 2D 1E 90 1D 03 15
|
|
.byte $10,$18,$08,$1A,$08,$19,$10,$14 ; CPU:$ED88 PRG:2D88 10 18 08 1A 08 19 10 14
|
|
|
|
; $ED90-$ED9F
|
|
.byte $03,$1F,$90,$1C,$2D,$E0,$11,$03 ; CPU:$ED90 PRG:2D90 03 1F 90 1C 2D E0 11 03
|
|
.byte $11,$C0,$80,$11,$03,$11,$E0,$2D ; CPU:$ED98 PRG:2D98 11 C0 80 11 03 11 E0 2D
|
|
|
|
; $EDA0-$EDAF
|
|
.byte $E0,$11,$03,$11,$00,$1F,$17,$2C ; CPU:$EDA0 PRG:2DA0 E0 11 03 11 00 1F 17 2C
|
|
.byte $16,$1D,$00,$11,$03,$11,$E0,$2D ; CPU:$EDA8 PRG:2DA8 16 1D 00 11 03 11 E0 2D
|
|
|
|
; $EDB0-$EDBF
|
|
.byte $22,$90,$1C,$03,$1A,$00,$11,$80 ; CPU:$EDB0 PRG:2DB0 22 90 1C 03 1A 00 11 80
|
|
.byte $11,$00,$1A,$03,$1E,$90,$21,$04 ; CPU:$EDB8 PRG:2DB8 11 00 1A 03 1E 90 21 04
|
|
|
|
; $EDC0-$EDCF
|
|
.byte $06,$C0,$03,$40,$11,$80,$11,$40 ; CPU:$EDC0 PRG:2DC0 06 C0 03 40 11 80 11 40
|
|
.byte $03,$C0,$05,$2D,$22,$90,$1D,$03 ; CPU:$EDC8 PRG:2DC8 03 C0 05 2D 22 90 1D 03
|
|
|
|
; $EDD0-$EDDF
|
|
.byte $1B,$00,$1E,$90,$1C,$00,$1B,$03 ; CPU:$EDD0 PRG:2DD0 1B 00 1E 90 1C 00 1B 03
|
|
.byte $1F,$90,$21,$2D,$E0,$11,$03,$11 ; CPU:$EDD8 PRG:2DD8 1F 90 21 2D E0 11 03 11
|
|
|
|
; $EDE0-$EDEF
|
|
.byte $C0,$80,$11,$03,$11,$E0,$2D,$E0 ; CPU:$EDE0 PRG:2DE0 C0 80 11 03 11 E0 2D E0
|
|
.byte $11,$03,$11,$00,$1F,$90,$1D,$00 ; CPU:$EDE8 PRG:2DE8 11 03 11 00 1F 90 1D 00
|
|
|
|
; $EDF0-$EDFF
|
|
.byte $11,$03,$11,$E0,$2D,$1F,$90,$1C ; CPU:$EDF0 PRG:2DF0 11 03 11 E0 2D 1F 90 1C
|
|
.byte $03,$1A,$00,$1E,$10,$13,$10,$1C ; CPU:$EDF8 PRG:2DF8 03 1A 00 1E 10 13 10 1C
|
|
|
|
;==============================================================================
|
|
; $EE00-$EE8B: Gameplay Lookup / Pattern Data
|
|
;
|
|
; Raw data preserved byte-for-byte.
|
|
;==============================================================================
|
|
|
|
MazeLayoutData_EE00:
|
|
|
|
; $EE00-$EE0F
|
|
.byte $00,$1A,$03,$1E,$90,$1D,$2D,$11 ; CPU:$EE00 PRG:2E00 00 1A 03 1E 90 1D 2D 11
|
|
.byte $C3,$C3,$03,$11,$C3,$C3,$03,$11 ; CPU:$EE08 PRG:2E08 C3 C3 03 11 C3 C3 03 11
|
|
|
|
; $EE10-$EE1F
|
|
.byte $2D,$11,$03,$19,$10,$1D,$03,$19 ; CPU:$EE10 PRG:2E10 2D 11 03 19 10 1D 03 19
|
|
.byte $10,$18,$09,$1A,$09,$19,$10,$18 ; CPU:$EE18 PRG:2E18 10 18 09 1A 09 19 10 18
|
|
|
|
; $EE20-$EE2F
|
|
.byte $03,$1F,$10,$18,$03,$11,$2D,$11 ; CPU:$EE20 PRG:2E20 03 1F 10 18 03 11 2D 11
|
|
.byte $01,$43,$11,$C3,$03,$00,$C3,$03 ; CPU:$EE28 PRG:2E28 01 43 11 C3 03 00 C3 03
|
|
|
|
; $EE30-$EE3F
|
|
.byte $11,$43,$01,$11,$2D,$15,$10,$1D ; CPU:$EE30 PRG:2E30 11 43 01 11 2D 15 10 1D
|
|
.byte $03,$11,$03,$1B,$03,$1F,$90,$1D ; CPU:$EE38 PRG:2E38 03 11 03 1B 03 1F 90 1D
|
|
|
|
; $EE40-$EE4F
|
|
.byte $03,$1B,$03,$11,$03,$1F,$10,$14 ; CPU:$EE40 PRG:2E40 03 1B 03 11 03 1F 10 14
|
|
.byte $2D,$15,$10,$1C,$03,$1A,$03,$11 ; CPU:$EE48 PRG:2E48 2D 15 10 1C 03 1A 03 11
|
|
|
|
; $EE50-$EE5F
|
|
.byte $03,$1E,$10,$13,$10,$1C,$03,$11 ; CPU:$EE50 PRG:2E50 03 1E 10 13 10 1C 03 11
|
|
.byte $03,$1A,$03,$1E,$10,$14,$2D,$11 ; CPU:$EE58 PRG:2E58 03 1A 03 1E 10 14 2D 11
|
|
|
|
; $EE60-$EE6F
|
|
.byte $C3,$03,$11,$83,$11,$83,$11,$C3 ; CPU:$EE60 PRG:2E60 C3 03 11 83 11 83 11 C3
|
|
.byte $03,$11,$2D,$11,$03,$19,$90,$12 ; CPU:$EE68 PRG:2E68 03 11 2D 11 03 19 90 12
|
|
|
|
; $EE70-$EE7F
|
|
.byte $10,$18,$03,$1A,$03,$19,$10,$12 ; CPU:$EE70 PRG:2E70 10 18 03 1A 03 19 10 12
|
|
.byte $90,$18,$03,$11,$2D,$11,$C3,$C3 ; CPU:$EE78 PRG:2E78 90 18 03 11 2D 11 C3 C3
|
|
|
|
; $EE80-$EE8B
|
|
.byte $C3,$C3,$83,$11,$2D,$1E,$D0,$D0 ; CPU:$EE80 PRG:2E80 C3 C3 83 11 2D 1E D0 D0
|
|
.byte $D0,$D0,$90,$1C ; CPU:$EE88 PRG:2E88 D0 D0 90 1C
|
|
|
|
|
|
;==============================================================================
|
|
; $EE8C-$EECF: Initialize Runtime Work Buffers
|
|
;
|
|
; Initializes zero-page runtime pointers and hardware state, clears $0600-$060F,
|
|
; then clears sixteen locations at eight-byte intervals beginning at $0620.
|
|
;==============================================================================
|
|
|
|
InitializeAudioEngine:
|
|
lda #$00 ; CPU:$EE8C PRG:2E8C A9 00
|
|
sta audioRequestPtr ; CPU:$EE8E PRG:2E8E 85 F0
|
|
|
|
lda #$06 ; CPU:$EE90 PRG:2E90 A9 06
|
|
sta audioRequestPtr+1 ; CPU:$EE92 PRG:2E92 85 F1 A9
|
|
|
|
lda #$20 ; CPU:$EE95 PRG:2E95 20 85
|
|
sta audioChannelTablePtr ; CPU:$EE97 PRG:2E97 F2 A9
|
|
|
|
lda #$06 ; CPU:$EE99 PRG:2E99 06 85
|
|
sta audioChannelTablePtr+1 ; CPU:$EE9B PRG:2E9B F3 AD 00
|
|
|
|
lda $F100 ; CPU:$EE9E PRG:2E9E F1 85 F4
|
|
sta audioSequenceTablePtr ; CPU:$EEA1 PRG:2EA1 AD 01
|
|
|
|
lda $F101 ; CPU:$EEA3 PRG:2EA3 F1 85 F5
|
|
sta audioSequenceTablePtr+1 ; CPU:$EEA6 PRG:2EA6 A9 40 85
|
|
|
|
lda #$40 ; CPU:$EEA9 PRG:2EA9 F7 A9
|
|
sta audioWorkValue ; CPU:$EEAB PRG:2EAB 1F 8D
|
|
|
|
lda #$1F ; CPU:$EEAD PRG:2EAD 15 40
|
|
sta APUSTATUS ; CPU:$EEAF PRG:2EAF A9 C0 8D
|
|
|
|
lda #$C0 ; CPU:$EEB2 PRG:2EB2 17 40
|
|
sta APUFRAMECNT ; CPU:$EEB4 PRG:2EB4 A0 00 A9
|
|
|
|
ldy #$00 ; CPU:$EEB7 PRG:2EB7 00 91
|
|
|
|
lda #$00 ; CPU:$EEB9 PRG:2EB9 F0 C8
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EEB8
|
|
; Clear sixteen contiguous bytes through ($F0).
|
|
;------------------------------------------------------------------------------
|
|
|
|
RuntimeInit_Clear0600:
|
|
sta (audioRequestPtr),y ; CPU:$EEB8 PRG:2EB8 91 F0
|
|
|
|
iny ; CPU:$EEBA PRG:2EBA C8
|
|
cpy #$10 ; CPU:$EEBB PRG:2EBB C0 10
|
|
bne RuntimeInit_Clear0600 ; CPU:$EEBD PRG:2EBD D0 F9
|
|
|
|
ldy #$00 ; CPU:$EEBF PRG:2EBF A0 00
|
|
ldx #$10 ; CPU:$EEC1 PRG:2EC1 A2 10
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EEC3
|
|
; Clear sixteen entries at an eight-byte stride.
|
|
;
|
|
; LDA #$00 is intentionally executed on every iteration.
|
|
;------------------------------------------------------------------------------
|
|
RuntimeInit_Clear0620Stride:
|
|
lda #$00 ; CPU:$EEC3 PRG:2EC3 A9 00
|
|
sta (audioChannelTablePtr),y ; CPU:$EEC5 PRG:2EC5 91 F2
|
|
|
|
tya ; CPU:$EEC7 PRG:2EC7 98
|
|
clc ; CPU:$EEC8 PRG:2EC8 18
|
|
adc #$08 ; CPU:$EEC9 PRG:2EC9 69 08
|
|
tay ; CPU:$EECB PRG:2ECB A8
|
|
|
|
dex ; CPU:$EECC PRG:2ECC CA
|
|
bne RuntimeInit_Clear0620Stride ; CPU:$EECD PRG:2ECD D0 F4
|
|
|
|
rts ; CPU:$EECF PRG:2ECF 60
|
|
|
|
|
|
;==============================================================================
|
|
; $EED0-$EF2C: Initialize and Scan Runtime Command Slots
|
|
;
|
|
; Clears runtime work values, then scans sixteen 8-byte entries addressed
|
|
; through $F2/$F3. Occupied entries update flags through $FE/$FF, while newly
|
|
; activated entries copy four bytes through the pointer selected in $F6.
|
|
;
|
|
; Execution falls through at $EF2D into the next processing phase.
|
|
;==============================================================================
|
|
|
|
InitializeAudioChannels:
|
|
lda #$00 ; CPU:$EED0 PRG:2ED0 A9 00
|
|
sta audioChannelFlags ; CPU:$EED2 PRG:2ED2 85 F8
|
|
sta $F9 ; CPU:$EED4 PRG:2ED4 85 F9
|
|
sta $FA ; CPU:$EED6 PRG:2ED6 85 FA
|
|
sta $FB ; CPU:$EED8 PRG:2ED8 85 FB
|
|
sta audioChannelOffset ; CPU:$EEDA PRG:2EDA 85 FD
|
|
sta $FF ; CPU:$EEDC PRG:2EDC 85 FF
|
|
|
|
lda #$F8 ; CPU:$EEDE PRG:2EDE A9 F8
|
|
sta audioIndirectPtr ; CPU:$EEE0 PRG:2EE0 85 FE
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EEE2
|
|
; Examine one eight-byte slot.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ScanAudioChannelSlot:
|
|
ldy $FD ; CPU:$EEE2 PRG:2EE2 A4 FD
|
|
|
|
lda (audioChannelTablePtr),y ; CPU:$EEE4 PRG:2EE4 B1 F2
|
|
beq AdvanceAudioChannelSlot ; CPU:$EEE6 PRG:2EE6 F0 3A
|
|
|
|
cmp #$05 ; CPU:$EEE8 PRG:2EE8 C9 05
|
|
bcc ActivateAudioChannelSlot ; CPU:$EEEA PRG:2EEA 90 0B
|
|
|
|
sec ; CPU:$EEEC PRG:2EEC 38
|
|
sbc #$05 ; CPU:$EEED PRG:2EED E9 05
|
|
tay ; CPU:$EEEF PRG:2EEF A8
|
|
|
|
lda #$01 ; CPU:$EEF0 PRG:2EF0 A9 01
|
|
sta ($FE),y ; CPU:$EEF2 PRG:2EF2 91 FE
|
|
|
|
jmp AdvanceAudioChannelSlot ; CPU:$EEF4 PRG:2EF4 4C 22 EF
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EEF5
|
|
; Process slot values $01-$04.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ActivateAudioChannelSlot:
|
|
sec ; CPU:$EEF7 PRG:2EF7 38
|
|
sbc #$01 ; CPU:$EEF8 PRG:2EF8 E9 01
|
|
tay ; CPU:$EEFA PRG:2EFA A8
|
|
|
|
lda ($FE),y ; CPU:$EEFB PRG:2EFB B1 FE
|
|
bne AdvanceAudioChannelSlot ; CPU:$EEFD PRG:2EFD D0 23
|
|
|
|
lda #$01 ; CPU:$EEFF PRG:2EFF A9 01
|
|
sta ($FE),y ; CPU:$EF01 PRG:2F01 91 FE
|
|
|
|
tya ; CPU:$EF03 PRG:2F03 98
|
|
tax ; CPU:$EF04 PRG:2F04 AA
|
|
|
|
adc #$04 ; CPU:$EF05 PRG:2F05 69 04
|
|
|
|
ldy $FD ; CPU:$EF07 PRG:2F07 A4 FD
|
|
sta ($F2),y ; CPU:$EF09 PRG:2F09 91 F2
|
|
|
|
txa ; CPU:$EF0B PRG:2F0B 8A
|
|
asl ; CPU:$EF0C PRG:2F0C 0A
|
|
asl ; CPU:$EF0D PRG:2F0D 0A
|
|
sta $F6 ; CPU:$EF0E PRG:2F0E 85 F6
|
|
|
|
ldx #$00 ; CPU:$EF10 PRG:2F10 A2 00
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EF12
|
|
; Set initial four-byte copy count.
|
|
;------------------------------------------------------------------------------
|
|
|
|
BeginAudioChannelParameterCopy:
|
|
lda #$04 ; CPU:$EF12 PRG:2F12 A9 04
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EF14
|
|
; Push the current copy count.
|
|
;
|
|
; The loop at $EF20 deliberately returns here, so PHA is repeated on every
|
|
; iteration.
|
|
;------------------------------------------------------------------------------
|
|
|
|
CopyAudioChannelParameter:
|
|
pha ; CPU:$EF14 PRG:2F14 48
|
|
|
|
iny ; CPU:$EF15 PRG:2F15 C8
|
|
|
|
lda ($F2),y ; CPU:$EF16 PRG:2F16 B1 F2
|
|
sta ($F6,x) ; CPU:$EF18 PRG:2F18 81 F6 E6 F6 68
|
|
|
|
inc $F6 ; CPU:$EF1D PRG:2F1D 38 E9
|
|
|
|
pla ; CPU:$EF1F PRG:2F1F 01
|
|
|
|
sec ; CPU:$EF20 PRG:2F20 D0
|
|
sbc #$01 ; CPU:$EF21 PRG:2F21 F2 A5
|
|
bne CopyAudioChannelParameter ; CPU:$EF23 PRG:2F23 FD 18
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EF22
|
|
; Advance to the next eight-byte slot.
|
|
;------------------------------------------------------------------------------
|
|
|
|
AdvanceAudioChannelSlot:
|
|
lda $FD ; CPU:$EF22 PRG:2F22 A5 FD
|
|
clc ; CPU:$EF24 PRG:2F24 18
|
|
adc #$08 ; CPU:$EF25 PRG:2F25 69 08
|
|
sta $FD ; CPU:$EF27 PRG:2F27 85 FD
|
|
|
|
cmp #$80 ; CPU:$EF29 PRG:2F29 C9 80
|
|
bcc ScanAudioChannelSlot ; CPU:$EF2B PRG:2F2B 90 B5
|
|
|
|
; Fall through to $EF2D.
|
|
|
|
|
|
;==============================================================================
|
|
; $EF2D-$F006: Process Runtime Command Entries
|
|
;
|
|
; Continuation of the runtime command-slot scan.
|
|
;
|
|
; $FC indexes source commands through ($F0).
|
|
; $FD indexes eight-byte runtime records through ($F2).
|
|
;
|
|
; Empty runtime records are initialized from tables through $F4/$F5 and
|
|
; command bytes fetched through the helper at $F0C3. Active records update
|
|
; countdowns and command parameters before both indices advance.
|
|
;==============================================================================
|
|
|
|
UpdateAudioChannels:
|
|
ldy #$00 ; CPU:$EF2D PRG:2F2D A0 00
|
|
sty $FC ; CPU:$EF2F PRG:2F2F 84 FC
|
|
sty $FD ; CPU:$EF31 PRG:2F31 84 FD
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EF33
|
|
; Process one source entry.
|
|
;------------------------------------------------------------------------------
|
|
|
|
UpdateNextAudioSequence:
|
|
ldy $FC ; CPU:$EF33 PRG:2F33 A4 FC
|
|
|
|
lda ($F0),y ; CPU:$EF35 PRG:2F35 B1 F0
|
|
bne CheckAudioChannelActive ; CPU:$EF37 PRG:2F37 D0 03
|
|
|
|
jmp AdvanceAudioSequence ; CPU:$EF39 PRG:2F39 4C F8 EF
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EF3B
|
|
; Check the corresponding runtime record.
|
|
;------------------------------------------------------------------------------
|
|
|
|
CheckAudioChannelActive:
|
|
ldy $FD ; CPU:$EF3C PRG:2F3C A4 FD
|
|
|
|
lda ($F2),y ; CPU:$EF3E PRG:2F3E B1 F2
|
|
bne TickAudioChannelDelay ; CPU:$EF40 PRG:2F40 D0 51
|
|
|
|
lda $FC ; CPU:$EF42 PRG:2F42 A5 FC
|
|
asl ; CPU:$EF44 PRG:2F44 0A
|
|
tay ; CPU:$EF45 PRG:2F45 A8
|
|
|
|
lda ($F4),y ; CPU:$EF46 PRG:2F46 B1 F4
|
|
pha ; CPU:$EF48 PRG:2F48 48
|
|
|
|
lda $FD ; CPU:$EF49 PRG:2F49 A5 FD
|
|
adc #$05 ; CPU:$EF4B PRG:2F4B 69 05
|
|
tay ; CPU:$EF4D PRG:2F4D A8
|
|
|
|
pla ; CPU:$EF4E PRG:2F4E 68
|
|
sta ($F2),y ; CPU:$EF4F PRG:2F4F 91 F2
|
|
|
|
lda $FC ; CPU:$EF51 PRG:2F51 A5 FC
|
|
asl ; CPU:$EF53 PRG:2F53 0A
|
|
adc #$01 ; CPU:$EF54 PRG:2F54 69 01
|
|
tay ; CPU:$EF56 PRG:2F56 A8
|
|
|
|
lda ($F4),y ; CPU:$EF57 PRG:2F57 B1 F4
|
|
pha ; CPU:$EF59 PRG:2F59 48
|
|
|
|
lda $FD ; CPU:$EF5A PRG:2F5A A5 FD
|
|
adc #$06 ; CPU:$EF5C PRG:2F5C 69 06
|
|
tay ; CPU:$EF5E PRG:2F5E A8
|
|
|
|
pla ; CPU:$EF5F PRG:2F5F 68
|
|
sta ($F2),y ; CPU:$EF60 PRG:2F60 91 F2
|
|
|
|
jsr $F0C3 ; CPU:$EF62 PRG:2F62 20 C3 F0
|
|
|
|
ldy $FD ; CPU:$EF65 PRG:2F65 A4 FD
|
|
sta ($F2),y ; CPU:$EF67 PRG:2F67 91 F2
|
|
|
|
jsr $F0C3 ; CPU:$EF69 PRG:2F69 20 C3 F0
|
|
tax ; CPU:$EF6C PRG:2F6C AA
|
|
|
|
lda $FD ; CPU:$EF6D PRG:2F6D A5 FD
|
|
clc ; CPU:$EF6F PRG:2F6F 18
|
|
adc #$01 ; CPU:$EF70 PRG:2F70 69 01
|
|
tay ; CPU:$EF72 PRG:2F72 A8
|
|
|
|
txa ; CPU:$EF73 PRG:2F73 8A
|
|
sta ($F2),y ; CPU:$EF74 PRG:2F74 91 F2
|
|
|
|
jsr $F0C3 ; CPU:$EF76 PRG:2F76 20 C3 F0
|
|
tax ; CPU:$EF79 PRG:2F79 AA
|
|
|
|
lda $FD ; CPU:$EF7A PRG:2F7A A5 FD
|
|
clc ; CPU:$EF7C PRG:2F7C 18
|
|
adc #$02 ; CPU:$EF7D PRG:2F7D 69 02
|
|
tay ; CPU:$EF7F PRG:2F7F A8
|
|
|
|
txa ; CPU:$EF80 PRG:2F80 8A
|
|
sta ($F2),y ; CPU:$EF81 PRG:2F81 91 F2
|
|
|
|
jsr $F0C3 ; CPU:$EF83 PRG:2F83 20 C3 F0
|
|
tax ; CPU:$EF86 PRG:2F86 AA
|
|
|
|
lda $FD ; CPU:$EF87 PRG:2F87 A5 FD
|
|
clc ; CPU:$EF89 PRG:2F89 18
|
|
adc #$04 ; CPU:$EF8A PRG:2F8A 69 04
|
|
tay ; CPU:$EF8C PRG:2F8C A8
|
|
|
|
txa ; CPU:$EF8D PRG:2F8D 8A
|
|
sta ($F2),y ; CPU:$EF8E PRG:2F8E 91 F2
|
|
|
|
jmp DecodeAudioCommand ; CPU:$EF90 PRG:2F90 4C A2 EF
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EF94
|
|
; Decrement the active record countdown at offset 7.
|
|
;------------------------------------------------------------------------------
|
|
|
|
TickAudioChannelDelay:
|
|
lda $FD ; CPU:$EF93 PRG:2F93 A5 FD
|
|
clc ; CPU:$EF95 PRG:2F95 18
|
|
adc #$07 ; CPU:$EF96 PRG:2F96 69 07
|
|
tay ; CPU:$EF98 PRG:2F98 A8
|
|
|
|
lda ($F2),y ; CPU:$EF99 PRG:2F99 B1 F2
|
|
sec ; CPU:$EF9B PRG:2F9B 38
|
|
sbc #$01 ; CPU:$EF9C PRG:2F9C E9 01
|
|
sta ($F2),y ; CPU:$EF9E PRG:2F9E 91 F2
|
|
|
|
bne AdvanceAudioSequence ; CPU:$EFA0 PRG:2FA0 D0 56
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EFA2
|
|
; Fetch and decode the next runtime command byte.
|
|
;------------------------------------------------------------------------------
|
|
|
|
DecodeAudioCommand:
|
|
jsr $F0C3 ; CPU:$EFA2 PRG:2FA2 20 C3 F0
|
|
|
|
cmp #$F0 ; CPU:$EFA5 PRG:2FA5 C9 F0
|
|
bcs $F00D ; CPU:$EFA7 PRG:2FA7 B0 64
|
|
|
|
cmp #$C0 ; CPU:$EFA9 PRG:2FA9 C9 C0
|
|
bcs LoadAudioCommandDelay ; CPU:$EFAB PRG:2FAB B0 3E
|
|
|
|
pha ; CPU:$EFAD PRG:2FAD 48
|
|
|
|
and #$F0 ; CPU:$EFAE PRG:2FAE 29 F0
|
|
lsr ; CPU:$EFB0 PRG:2FB0 4A
|
|
lsr ; CPU:$EFB1 PRG:2FB1 4A
|
|
lsr ; CPU:$EFB2 PRG:2FB2 4A
|
|
tax ; CPU:$EFB3 PRG:2FB3 AA
|
|
|
|
lda AudioFrequencyLookupTable,x ; CPU:$EFB4 PRG:2FB4 BD E8 F0
|
|
sta $FE ; CPU:$EFB7 PRG:2FB7 85 FE
|
|
|
|
lda AudioFrequencyLookupTable+1,x ; CPU:$EFB9 PRG:2FB9 BD E9 F0
|
|
sta $FF ; CPU:$EFBC PRG:2FBC 85 FF
|
|
|
|
pla ; CPU:$EFBE PRG:2FBE 68
|
|
|
|
and #$0F ; CPU:$EFBF PRG:2FBF 29 0F
|
|
beq ApplyAudioFrequencyMask ; CPU:$EFC1 PRG:2FC1 F0 08
|
|
|
|
tax ; CPU:$EFC3 PRG:2FC3 AA
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EFC4
|
|
; Shift the selected mask by the command low nibble.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ShiftAudioFrequencyMask:
|
|
lsr $FE ; CPU:$EFC4 PRG:2FC4 46
|
|
ror $FF ; CPU:$EFC5 PRG:2FC5 FE
|
|
|
|
dex ; CPU:$EFC6 PRG:2FC6 66
|
|
bne ShiftAudioFrequencyMask ; CPU:$EFC7 PRG:2FC7 FF CA
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EFCB
|
|
; Merge the generated mask into the runtime record.
|
|
;------------------------------------------------------------------------------
|
|
|
|
ApplyAudioFrequencyMask:
|
|
lda $FD ; CPU:$EFCB PRG:2FCB A5 FD
|
|
clc ; CPU:$EFCD PRG:2FCD 18
|
|
adc #$04 ; CPU:$EFCE PRG:2FCE 69 04
|
|
tay ; CPU:$EFD0 PRG:2FD0 A8
|
|
|
|
lda ($F2),y ; CPU:$EFD1 PRG:2FD1 B1 F2
|
|
and #$F8 ; CPU:$EFD3 PRG:2FD3 29 F8
|
|
ora $FE ; CPU:$EFD5 PRG:2FD5 05 FE
|
|
sta ($F2),y ; CPU:$EFD7 PRG:2FD7 91 F2
|
|
|
|
lda $FF ; CPU:$EFD9 PRG:2FD9 A5 FF
|
|
dey ; CPU:$EFDB PRG:2FDB 88
|
|
sta ($F2),y ; CPU:$EFDC PRG:2FDC 91 F2
|
|
|
|
ldy $FD ; CPU:$EFDE PRG:2FDE A4 FD
|
|
|
|
lda ($F2),y ; CPU:$EFE0 PRG:2FE0 B1 F2
|
|
cmp #$05 ; CPU:$EFE2 PRG:2FE2 C9 05
|
|
bcc LoadAudioCommandDelay ; CPU:$EFE4 PRG:2FE4 90 05
|
|
|
|
sec ; CPU:$EFE6 PRG:2FE6 38
|
|
sbc #$04 ; CPU:$EFE7 PRG:2FE7 E9 04
|
|
sta ($F2),y ; CPU:$EFE9 PRG:2FE9 91 F2
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EFEB
|
|
; Load the new runtime countdown.
|
|
;------------------------------------------------------------------------------
|
|
|
|
LoadAudioCommandDelay:
|
|
jsr $F0C3 ; CPU:$EFEB PRG:2FEB 20 C3 F0
|
|
pha ; CPU:$EFEE PRG:2FEE 48
|
|
|
|
lda $FD ; CPU:$EFEF PRG:2FEF A5 FD
|
|
clc ; CPU:$EFF1 PRG:2FF1 18
|
|
adc #$07 ; CPU:$EFF2 PRG:2FF2 69 07
|
|
tay ; CPU:$EFF4 PRG:2FF4 A8
|
|
|
|
pla ; CPU:$EFF5 PRG:2FF5 68
|
|
sta ($F2),y ; CPU:$EFF6 PRG:2FF6 91 F2
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; $EFF8
|
|
; Advance to the next runtime/source entry.
|
|
;------------------------------------------------------------------------------
|
|
|
|
AdvanceAudioSequence:
|
|
lda $FD ; CPU:$EFF8 PRG:2FF8 A5 FD
|
|
clc ; CPU:$EFFA PRG:2FFA 18
|
|
adc #$08 ; CPU:$EFFB PRG:2FFB 69 08
|
|
sta $FD ; CPU:$EFFD PRG:2FFD 85 FD
|
|
|
|
lda $FC ; CPU:$EFFF PRG:2FFF A5 FC
|
|
adc #$01 ; CPU:$F001 PRG:3001 69 01
|
|
sta $FC ; CPU:$F003 PRG:3003 85 FC
|
|
|
|
cmp #$10 ; CPU:$F005 PRG:3005 C9 10
|
|
|
|
; Fall through at $F007 to the next control-flow block.
|
|
|
|
;==============================================================================
|
|
; $F007-$F00C: Runtime command-loop termination / continuation
|
|
;
|
|
; Entry is the fall-through from the CMP #$10 at $F005.
|
|
;==============================================================================
|
|
|
|
FinishAudioSequenceScan:
|
|
bcs AudioSequenceUpdateDone ; CPU:$F007 PRG:3007 B0 03
|
|
|
|
jmp UpdateNextAudioSequence ; CPU:$F009 PRG:3009 4C 33 EF
|
|
|
|
|
|
AudioSequenceUpdateDone:
|
|
rts ; CPU:$F00C PRG:300C 60
|
|
|
|
|
|
;==============================================================================
|
|
; $F00D-$F01D: Runtime Command Dispatcher
|
|
;
|
|
; Input:
|
|
; A = command byte >= $F0
|
|
;
|
|
; Uses the low nibble to select a handler through the pointer table at $F01E.
|
|
;==============================================================================
|
|
|
|
DispatchAudioCommand:
|
|
and #$0F ; CPU:$F00D PRG:300D 29 0F
|
|
asl ; CPU:$F00F PRG:300F 0A
|
|
tax ; CPU:$F010 PRG:3010 AA
|
|
|
|
lda AudioCommandHandlerTable,x ; CPU:$F011 PRG:3011 BD 1E F0
|
|
sta $FE ; CPU:$F014 PRG:3014 85 FE
|
|
|
|
lda AudioCommandHandlerTable+1,x ; CPU:$F016 PRG:3016 BD 1F F0
|
|
sta $FF ; CPU:$F019 PRG:3019 85 FF
|
|
|
|
jmp ($00FE) ; CPU:$F01B PRG:301B 6C FE 00 3E F0
|
|
|
|
|
|
;==============================================================================
|
|
; $F01E-$F03D: Runtime Command Handler Table
|
|
;
|
|
; Sixteen 16-bit handlers. Unsupported command values use the no-op handler
|
|
; at $F03E.
|
|
;==============================================================================
|
|
|
|
AudioCommandHandlerTable:
|
|
.word StopAudioSequence ; $F0 ; CPU:$F01E PRG:301E 3E F0
|
|
.word AudioCommandF1 ; $F1 ; CPU:$F020 PRG:3020 4B F0
|
|
.word AudioCommandF2 ; $F2 ; CPU:$F022 PRG:3022 63 F0
|
|
.word AudioCommandF3 ; $F3 ; CPU:$F024 PRG:3024 7B F0
|
|
.word AudioCommandF4 ; $F4 ; CPU:$F026 PRG:3026 93 F0
|
|
.word AudioCommandF5 ; $F5 ; CPU:$F028 PRG:3028 A3 F0
|
|
.word AudioCommandF6 ; $F6 ; CPU:$F02A PRG:302A B3 F0
|
|
.word StopAudioSequence ; $F7 ; CPU:$F02C PRG:302C 3E F0
|
|
.word StopAudioSequence ; $F8 ; CPU:$F02E PRG:302E 3E F0
|
|
.word StopAudioSequence ; $F9 ; CPU:$F030 PRG:3030 3E F0
|
|
.word StopAudioSequence ; $FA ; CPU:$F032 PRG:3032 3E F0
|
|
.word StopAudioSequence ; $FB ; CPU:$F034 PRG:3034 3E F0
|
|
.word StopAudioSequence ; $FC ; CPU:$F036 PRG:3036 3E F0
|
|
.word StopAudioSequence ; $FD ; CPU:$F038 PRG:3038 3E F0
|
|
.word StopAudioSequence ; $FE ; CPU:$F03A PRG:303A 3E F0
|
|
.word StopAudioSequence ; $FF ; CPU:$F03C PRG:303C 3E F0
|
|
|
|
|
|
;==============================================================================
|
|
; $F03E-$F04A: Runtime command no-op/terminate handler
|
|
;
|
|
; Clears the current source entry and current runtime record, then advances
|
|
; through the common continuation at $EFF8.
|
|
;==============================================================================
|
|
|
|
StopAudioSequence:
|
|
ldy $FC ; CPU:$F03E PRG:303E A4 FC
|
|
|
|
lda #$00 ; CPU:$F040 PRG:3040 A9 00
|
|
sta ($F0),y ; CPU:$F042 PRG:3042 91 F0
|
|
|
|
ldy $FD ; CPU:$F044 PRG:3044 A4 FD
|
|
sta ($F2),y ; CPU:$F046 PRG:3046 91 F2
|
|
|
|
jmp AdvanceAudioSequence ; CPU:$F048 PRG:3048 4C F8 EF
|
|
|
|
|
|
;==============================================================================
|
|
; $F04B-$F062: Runtime command $F1
|
|
;
|
|
; Fetches one command byte and merges its bits into runtime-record byte 0/1.
|
|
;==============================================================================
|
|
|
|
AudioCommandF1:
|
|
jsr FetchAudioSequenceByte ; CPU:$F04B PRG:304B 20 C3 F0
|
|
pha ; CPU:$F04E PRG:304E 48
|
|
|
|
lda $FD ; CPU:$F04F PRG:304F A5 FD
|
|
clc ; CPU:$F051 PRG:3051 18
|
|
adc #$01 ; CPU:$F052 PRG:3052 69 01
|
|
tay ; CPU:$F054 PRG:3054 A8
|
|
|
|
lda ($F2),y ; CPU:$F055 PRG:3055 B1 F2
|
|
and #$3F ; CPU:$F057 PRG:3057 29 3F
|
|
sta ($F2),y ; CPU:$F059 PRG:3059 91 F2
|
|
|
|
pla ; CPU:$F05B PRG:305B 68
|
|
ora ($F2),y ; CPU:$F05C PRG:305C 11 F2
|
|
sta ($F2),y ; CPU:$F05E PRG:305E 91 F2
|
|
|
|
jmp DecodeAudioCommand ; CPU:$F060 PRG:3060 4C A2 EF
|
|
|
|
;==============================================================================
|
|
; $F063-$F07A: Runtime command $F2
|
|
;==============================================================================
|
|
|
|
AudioCommandF2:
|
|
jsr FetchAudioSequenceByte ; CPU:$F063 PRG:3063 20 C3 F0
|
|
pha ; CPU:$F066 PRG:3066 48
|
|
|
|
lda $FD ; CPU:$F067 PRG:3067 A5 FD
|
|
clc ; CPU:$F069 PRG:3069 18
|
|
adc #$01 ; CPU:$F06A PRG:306A 69 01
|
|
tay ; CPU:$F06C PRG:306C A8
|
|
|
|
lda ($F2),y ; CPU:$F06D PRG:306D B1 F2
|
|
and #$CF ; CPU:$F06F PRG:306F 29 CF
|
|
sta ($F2),y ; CPU:$F071 PRG:3071 91 F2
|
|
|
|
pla ; CPU:$F073 PRG:3073 68
|
|
ora ($F2),y ; CPU:$F074 PRG:3074 11 F2
|
|
sta ($F2),y ; CPU:$F076 PRG:3076 91 F2
|
|
|
|
jmp DecodeAudioCommand ; CPU:$F078 PRG:3078 4C A2 EF
|
|
|
|
;==============================================================================
|
|
; $F07B-$F092: Runtime command $F3
|
|
;==============================================================================
|
|
|
|
AudioCommandF3:
|
|
jsr FetchAudioSequenceByte ; CPU:$F07B PRG:307B 20 C3 F0
|
|
pha ; CPU:$F07E PRG:307E 48
|
|
|
|
lda $FD ; CPU:$F07F PRG:307F A5 FD
|
|
clc ; CPU:$F081 PRG:3081 18
|
|
adc #$01 ; CPU:$F082 PRG:3082 69 01
|
|
tay ; CPU:$F084 PRG:3084 A8
|
|
|
|
lda ($F2),y ; CPU:$F085 PRG:3085 B1 F2
|
|
and #$F0 ; CPU:$F087 PRG:3087 29 F0
|
|
sta ($F2),y ; CPU:$F089 PRG:3089 91 F2
|
|
|
|
pla ; CPU:$F08B PRG:308B 68
|
|
ora ($F2),y ; CPU:$F08C PRG:308C 11 F2
|
|
sta ($F2),y ; CPU:$F08E PRG:308E 91 F2
|
|
|
|
jmp DecodeAudioCommand ; CPU:$F090 PRG:3090 4C A2 EF
|
|
|
|
;==============================================================================
|
|
; $F093-$F0A2: Runtime command $F4
|
|
;==============================================================================
|
|
|
|
AudioCommandF4:
|
|
jsr FetchAudioSequenceByte ; CPU:$F093 PRG:3093 20 C3 F0
|
|
pha ; CPU:$F096 PRG:3096 48
|
|
|
|
lda $FD ; CPU:$F097 PRG:3097 A5 FD
|
|
clc ; CPU:$F099 PRG:3099 18
|
|
adc #$02 ; CPU:$F09A PRG:309A 69 02
|
|
tay ; CPU:$F09C PRG:309C A8
|
|
|
|
pla ; CPU:$F09D PRG:309D 68
|
|
sta ($F2),y ; CPU:$F09E PRG:309E 91 F2
|
|
|
|
jmp DecodeAudioCommand ; CPU:$F0A0 PRG:30A0 4C A2 EF
|
|
|
|
;==============================================================================
|
|
; $F0A3-$F0B2: Runtime command $F5
|
|
;==============================================================================
|
|
|
|
AudioCommandF5:
|
|
jsr FetchAudioSequenceByte ; CPU:$F0A3 PRG:30A3 20 C3 F0
|
|
pha ; CPU:$F0A6 PRG:30A6 48
|
|
|
|
lda $FD ; CPU:$F0A7 PRG:30A7 A5 FD
|
|
clc ; CPU:$F0A9 PRG:30A9 18
|
|
adc #$04 ; CPU:$F0AA PRG:30AA 69 04
|
|
tay ; CPU:$F0AC PRG:30AC A8
|
|
|
|
pla ; CPU:$F0AD PRG:30AD 68
|
|
sta ($F2),y ; CPU:$F0AE PRG:30AE 91 F2
|
|
|
|
jmp DecodeAudioCommand ; CPU:$F0B0 PRG:30B0 4C A2 EF
|
|
|
|
;==============================================================================
|
|
; $F0B3-$F0C2: Runtime command $F6
|
|
;==============================================================================
|
|
|
|
AudioCommandF6:
|
|
jsr FetchAudioSequenceByte ; CPU:$F0B3 PRG:30B3 20 C3 F0
|
|
pha ; CPU:$F0B6 PRG:30B6 48
|
|
|
|
lda $FD ; CPU:$F0B7 PRG:30B7 A5 FD
|
|
clc ; CPU:$F0B9 PRG:30B9 18
|
|
adc #$01 ; CPU:$F0BA PRG:30BA 69 01
|
|
tay ; CPU:$F0BC PRG:30BC A8
|
|
|
|
pla ; CPU:$F0BD PRG:30BD 68
|
|
sta ($F2),y ; CPU:$F0BE PRG:30BE 91 F2
|
|
|
|
jmp DecodeAudioCommand ; CPU:$F0C0 PRG:30C0 4C A2 EF
|
|
|
|
;==============================================================================
|
|
; $F0C3-$F0E7: Fetch Runtime Command Byte
|
|
;
|
|
; Uses the 16-bit source pointer stored in runtime-record bytes +5/+6.
|
|
;
|
|
; Output:
|
|
; A = byte read from the command stream
|
|
;
|
|
; Side effect:
|
|
; Advances the source pointer by one and writes it back into bytes +5/+6.
|
|
;==============================================================================
|
|
|
|
FetchAudioSequenceByte:
|
|
lda $FD ; CPU:$F0C3 PRG:30C3 A5 FD
|
|
clc ; CPU:$F0C5 PRG:30C5 18
|
|
adc #$05 ; CPU:$F0C6 PRG:30C6 69 05
|
|
tay ; CPU:$F0C8 PRG:30C8 A8
|
|
|
|
lda ($F2),y ; CPU:$F0C9 PRG:30C9 B1 F2
|
|
sta $FE ; CPU:$F0CB PRG:30CB 85 FE
|
|
|
|
iny ; CPU:$F0CD PRG:30CD C8
|
|
|
|
lda ($F2),y ; CPU:$F0CE PRG:30CE B1 F2
|
|
sta $FF ; CPU:$F0D0 PRG:30D0 85 FF
|
|
|
|
ldx #$00 ; CPU:$F0D2 PRG:30D2 A2 00
|
|
|
|
lda ($FE,x) ; CPU:$F0D4 PRG:30D4 A1 FE 48 A5 FE
|
|
pha ; CPU:$F0D9 PRG:30D9 88
|
|
|
|
lda $FE ; CPU:$F0DA PRG:30DA 18 69
|
|
|
|
dey ; CPU:$F0DC PRG:30DC 01
|
|
clc ; CPU:$F0DD PRG:30DD 91
|
|
adc #$01 ; CPU:$F0DE PRG:30DE F2 A5
|
|
sta ($F2),y ; CPU:$F0E0 PRG:30E0 FF 69
|
|
|
|
lda $FF ; CPU:$F0E2 PRG:30E2 00 C8
|
|
adc #$00 ; CPU:$F0E4 PRG:30E4 91 F2
|
|
|
|
iny ; CPU:$F0E6 PRG:30E6 68
|
|
sta ($F2),y ; CPU:$F0E7 PRG:30E7 60 03
|
|
|
|
pla ; CPU:$F0E9 PRG:30E9 F9
|
|
|
|
rts ; CPU:$F0EA PRG:30EA 03
|
|
|
|
;==============================================================================
|
|
; $F0E8-$F14F: Runtime / Audio Lookup Data
|
|
;
|
|
; Raw data preserved byte-for-byte.
|
|
;
|
|
; The first portion is referenced by UpdateAudioChannels through
|
|
; $F0E8,X / $F0E9,X as paired mask values. Later portions appear to contain
|
|
; additional pointers and command/parameter data.
|
|
;
|
|
; Semantic subdivision is deferred until all consumers are decoded.
|
|
;==============================================================================
|
|
AudioFrequencyLookupTable:
|
|
; $F0E8-$F0F7
|
|
.byte $03,$F9,$03,$C0,$03,$8A,$03,$57 ; CPU:$F0E8 PRG:30E8 03 F9 03 C0 03 8A 03 57
|
|
.byte $03,$27,$02,$FA,$02,$CF,$02,$A7 ; CPU:$F0F0 PRG:30F0 03 27 02 FA 02 CF 02 A7
|
|
|
|
; $F0F8-$F107
|
|
.byte $02,$81,$02,$5D,$02,$3B,$02,$1B ; CPU:$F0F8 PRG:30F8 02 81 02 5D 02 3B 02 1B
|
|
.byte $02,$F1,$CB,$F3,$14,$F4,$22,$F1 ; CPU:$F100 PRG:3100 02 F1 CB F3 14 F4 22 F1
|
|
|
|
; $F108-$F117
|
|
.byte $3C,$F3,$3F,$F4,$50,$F4,$37,$F1 ; CPU:$F108 PRG:3108 3C F3 3F F4 50 F4 37 F1
|
|
.byte $E4,$F1,$1D,$F3,$CF,$F1,$62,$F1 ; CPU:$F110 PRG:3110 E4 F1 1D F3 CF F1 62 F1
|
|
|
|
; $F118-$F127
|
|
.byte $8D,$F1,$B0,$F1,$07,$F2,$7A,$F2 ; CPU:$F118 PRG:3118 8D F1 B0 F1 07 F2 7A F2
|
|
.byte $61,$F4,$01,$03,$7F,$08,$A2,$0C ; CPU:$F120 PRG:3120 61 F4 01 03 7F 08 A2 0C
|
|
|
|
; $F128-$F137
|
|
.byte $A2,$0C,$A2,$0C,$A2,$0C,$A2,$0C ; CPU:$F128 PRG:3128 A2 0C A2 0C A2 0C A2 0C
|
|
.byte $A2,$0C,$A2,$0C,$A2,$0C,$F0,$03 ; CPU:$F130 PRG:3130 A2 0C A2 0C A2 0C F0 03
|
|
|
|
; $F138-$F147
|
|
.byte $04,$7F,$08,$33,$01,$23,$01,$03 ; CPU:$F138 PRG:3138 04 7F 08 33 01 23 01 03
|
|
.byte $01,$A2,$01,$92,$01,$72,$01,$52 ; CPU:$F140 PRG:3140 01 A2 01 92 01 72 01 52
|
|
|
|
; $F148-$F14F
|
|
.byte $01,$32,$01,$22,$01,$02,$01,$A1 ; CPU:$F148 PRG:3148 01 32 01 22 01 02 01 A1
|
|
|
|
|
|
|
|
;==============================================================================
|
|
; $F150-$F24F: Runtime / Audio Command Data
|
|
;
|
|
; Raw data preserved byte-for-byte.
|
|
;
|
|
; The region contains strongly patterned pairs and command-like values used
|
|
; by the late-PRG runtime/audio interpreter. Semantic subdivision is deferred
|
|
; until its individual consumers are mapped.
|
|
;==============================================================================
|
|
AudioSequenceData_F150:
|
|
; $F150-$F15F
|
|
.byte $01,$91,$01,$C0,$08,$91,$01,$A1 ; CPU:$F150 PRG:3150 01 91 01 C0 08 91 01 A1
|
|
.byte $01,$02,$01,$22,$01,$32,$01,$52 ; CPU:$F158 PRG:3158 01 02 01 22 01 32 01 52
|
|
|
|
; $F160-$F16F
|
|
.byte $01,$F0,$01,$96,$7F,$28,$82,$01 ; CPU:$F160 PRG:3160 01 F0 01 96 7F 28 82 01
|
|
.byte $92,$01,$A2,$01,$B2,$01,$03,$01 ; CPU:$F168 PRG:3168 92 01 A2 01 B2 01 03 01
|
|
|
|
; $F170-$F17F
|
|
.byte $13,$01,$23,$01,$33,$01,$43,$01 ; CPU:$F170 PRG:3170 13 01 23 01 33 01 43 01
|
|
.byte $53,$01,$33,$01,$23,$01,$13,$01 ; CPU:$F178 PRG:3178 53 01 33 01 23 01 13 01
|
|
|
|
; $F180-$F18F
|
|
.byte $03,$01,$B2,$01,$A2,$01,$92,$01 ; CPU:$F180 PRG:3180 03 01 B2 01 A2 01 92 01
|
|
.byte $82,$01,$72,$01,$F0,$01,$96,$7F ; CPU:$F188 PRG:3188 82 01 72 01 F0 01 96 7F
|
|
|
|
; $F190-$F19F
|
|
.byte $28,$A2,$01,$B2,$01,$03,$01,$13 ; CPU:$F190 PRG:3190 28 A2 01 B2 01 03 01 13
|
|
.byte $01,$23,$01,$33,$01,$43,$01,$53 ; CPU:$F198 PRG:3198 01 23 01 33 01 43 01 53
|
|
|
|
; $F1A0-$F1AF
|
|
.byte $01,$33,$01,$23,$01,$13,$01,$03 ; CPU:$F1A0 PRG:31A0 01 33 01 23 01 13 01 03
|
|
.byte $01,$B2,$01,$A2,$01,$92,$01,$F0 ; CPU:$F1A8 PRG:31A8 01 B2 01 A2 01 92 01 F0
|
|
|
|
; $F1B0-$F1BF
|
|
.byte $01,$96,$7F,$28,$B2,$01,$03,$01 ; CPU:$F1B0 PRG:31B0 01 96 7F 28 B2 01 03 01
|
|
.byte $13,$01,$23,$01,$33,$01,$43,$01 ; CPU:$F1B8 PRG:31B8 13 01 23 01 33 01 43 01
|
|
|
|
; $F1C0-$F1CF
|
|
.byte $53,$01,$33,$01,$23,$01,$13,$01 ; CPU:$F1C0 PRG:31C0 53 01 33 01 23 01 13 01
|
|
.byte $03,$01,$B2,$01,$A2,$01,$F0,$02 ; CPU:$F1C8 PRG:31C8 03 01 B2 01 A2 01 F0 02
|
|
|
|
; $F1D0-$F1DF
|
|
.byte $9C,$7F,$28,$31,$01,$71,$01,$A1 ; CPU:$F1D0 PRG:31D0 9C 7F 28 31 01 71 01 A1
|
|
.byte $01,$12,$01,$32,$01,$72,$01,$A2 ; CPU:$F1D8 PRG:31D8 01 12 01 32 01 72 01 A2
|
|
|
|
; $F1E0-$F1EF
|
|
.byte $01,$13,$01,$F0,$02,$00,$7F,$10 ; CPU:$F1E0 PRG:31E0 01 13 01 F0 02 00 7F 10
|
|
.byte $20,$03,$50,$03,$80,$02,$A0,$02 ; CPU:$F1E8 PRG:31E8 20 03 50 03 80 02 A0 02
|
|
|
|
; $F1F0-$F1FF
|
|
.byte $21,$02,$51,$02,$81,$01,$A1,$01 ; CPU:$F1F0 PRG:31F0 21 02 51 02 81 01 A1 01
|
|
.byte $02,$01,$22,$01,$32,$01,$52,$01 ; CPU:$F1F8 PRG:31F8 02 01 22 01 32 01 52 01
|
|
|
|
; $F200-$F20F
|
|
.byte $F5,$18,$73,$01,$C0,$08,$F0,$01 ; CPU:$F200 PRG:3200 F5 18 73 01 C0 08 F0 01
|
|
.byte $03,$7F,$08,$72,$02,$82,$08,$72 ; CPU:$F208 PRG:3208 03 7F 08 72 02 82 08 72
|
|
|
|
; $F210-$F21F
|
|
.byte $02,$82,$08,$72,$02,$82,$08,$42 ; CPU:$F210 PRG:3210 02 82 08 72 02 82 08 42
|
|
.byte $02,$52,$04,$32,$04,$82,$06,$82 ; CPU:$F218 PRG:3218 02 52 04 32 04 82 06 82
|
|
|
|
; $F220-$F22F
|
|
.byte $08,$B2,$02,$03,$10,$C0,$08,$72 ; CPU:$F220 PRG:3220 08 B2 02 03 10 C0 08 72
|
|
.byte $02,$82,$08,$72,$02,$82,$08,$72 ; CPU:$F228 PRG:3228 02 82 08 72 02 82 08 72
|
|
|
|
; $F230-$F23F
|
|
.byte $02,$82,$08,$42,$02,$52,$04,$32 ; CPU:$F230 PRG:3230 02 82 08 42 02 52 04 32
|
|
.byte $04,$82,$06,$82,$08,$42,$02,$52 ; CPU:$F238 PRG:3238 04 82 06 82 08 42 02 52
|
|
|
|
; $F240-$F24F
|
|
.byte $10,$C0,$08,$72,$02,$82,$08,$72 ; CPU:$F240 PRG:3240 10 C0 08 72 02 82 08 72
|
|
.byte $02,$82,$08,$72,$02,$82,$08,$42 ; CPU:$F248 PRG:3248 02 82 08 72 02 82 08 42
|
|
|
|
;==============================================================================
|
|
; $F250-$F34F: Runtime / Audio Command Data
|
|
;
|
|
; Raw data preserved byte-for-byte.
|
|
; Semantic subdivision is deferred until the individual stream consumers are
|
|
; fully mapped.
|
|
;==============================================================================
|
|
|
|
AudioSequenceData_F250:
|
|
|
|
; $F250-$F25F
|
|
.byte $02,$52,$04,$32,$04,$82,$06,$82 ; CPU:$F250 PRG:3250 02 52 04 32 04 82 06 82
|
|
.byte $08,$A2,$02,$B2,$08,$03,$02,$13 ; CPU:$F258 PRG:3258 08 A2 02 B2 08 03 02 13
|
|
|
|
; $F260-$F26F
|
|
.byte $0A,$13,$02,$23,$0C,$03,$02,$13 ; CPU:$F260 PRG:3260 0A 13 02 23 0C 03 02 13
|
|
.byte $08,$A2,$02,$B2,$08,$82,$0A,$A2 ; CPU:$F268 PRG:3268 08 A2 02 B2 08 82 0A A2
|
|
|
|
; $F270-$F27F
|
|
.byte $02,$B2,$0A,$72,$02,$82,$10,$C0 ; CPU:$F270 PRG:3270 02 B2 0A 72 02 82 10 C0
|
|
.byte $08,$F0,$02,$81,$7F,$40,$80,$08 ; CPU:$F278 PRG:3278 08 F0 02 81 7F 40 80 08
|
|
|
|
; $F280-$F28F
|
|
.byte $C0,$06,$80,$04,$C0,$02,$80,$08 ; CPU:$F280 PRG:3280 C0 06 80 04 C0 02 80 08
|
|
.byte $C0,$06,$80,$04,$C0,$02,$80,$08 ; CPU:$F288 PRG:3288 C0 06 80 04 C0 02 80 08
|
|
|
|
; $F290-$F29F
|
|
.byte $C0,$06,$80,$04,$C0,$02,$01,$04 ; CPU:$F290 PRG:3290 C0 06 80 04 C0 02 01 04
|
|
.byte $C0,$01,$11,$04,$C0,$01,$21,$04 ; CPU:$F298 PRG:3298 C0 01 11 04 C0 01 21 04
|
|
|
|
; $F2A0-$F2AF
|
|
.byte $C0,$01,$31,$04,$C0,$01,$80,$08 ; CPU:$F2A0 PRG:32A0 C0 01 31 04 C0 01 80 08
|
|
.byte $C0,$06,$80,$04,$C0,$02,$80,$08 ; CPU:$F2A8 PRG:32A8 C0 06 80 04 C0 02 80 08
|
|
|
|
; $F2B0-$F2BF
|
|
.byte $C0,$06,$80,$04,$C0,$02,$80,$08 ; CPU:$F2B0 PRG:32B0 C0 06 80 04 C0 02 80 08
|
|
.byte $C0,$06,$80,$04,$C0,$02,$01,$04 ; CPU:$F2B8 PRG:32B8 C0 06 80 04 C0 02 01 04
|
|
|
|
; $F2C0-$F2CF
|
|
.byte $C0,$01,$11,$04,$C0,$01,$21,$04 ; CPU:$F2C0 PRG:32C0 C0 01 11 04 C0 01 21 04
|
|
.byte $C0,$01,$31,$04,$C0,$01,$80,$08 ; CPU:$F2C8 PRG:32C8 C0 01 31 04 C0 01 80 08
|
|
|
|
; $F2D0-$F2DF
|
|
.byte $C0,$06,$80,$04,$C0,$02,$80,$08 ; CPU:$F2D0 PRG:32D0 C0 06 80 04 C0 02 80 08
|
|
.byte $C0,$06,$80,$04,$C0,$02,$80,$08 ; CPU:$F2D8 PRG:32D8 C0 06 80 04 C0 02 80 08
|
|
|
|
; $F2E0-$F2EF
|
|
.byte $C0,$06,$80,$04,$C0,$02,$01,$04 ; CPU:$F2E0 PRG:32E0 C0 06 80 04 C0 02 01 04
|
|
.byte $C0,$01,$11,$04,$C0,$01,$21,$04 ; CPU:$F2E8 PRG:32E8 C0 01 11 04 C0 01 21 04
|
|
|
|
; $F2F0-$F2FF
|
|
.byte $C0,$01,$31,$04,$C0,$01,$81,$0A ; CPU:$F2F0 PRG:32F0 C0 01 31 04 C0 01 81 0A
|
|
.byte $31,$04,$C0,$01,$21,$04,$C0,$01 ; CPU:$F2F8 PRG:32F8 31 04 C0 01 21 04 C0 01
|
|
|
|
; $F300-$F30F
|
|
.byte $11,$04,$C0,$01,$B0,$04,$C0,$01 ; CPU:$F300 PRG:3300 11 04 C0 01 B0 04 C0 01
|
|
.byte $80,$04,$C0,$01,$70,$04,$C0,$01 ; CPU:$F308 PRG:3308 80 04 C0 01 70 04 C0 01
|
|
|
|
; $F310-$F31F
|
|
.byte $60,$08,$C0,$02,$70,$08,$C0,$02 ; CPU:$F310 PRG:3310 60 08 C0 02 70 08 C0 02
|
|
.byte $80,$0C,$C0,$06,$F0,$02,$98,$7F ; CPU:$F318 PRG:3318 80 0C C0 06 F0 02 98 7F
|
|
|
|
; $F320-$F32F
|
|
.byte $28,$33,$01,$23,$01,$13,$01,$03 ; CPU:$F320 PRG:3320 28 33 01 23 01 13 01 03
|
|
.byte $01,$A2,$01,$82,$01,$72,$01,$52 ; CPU:$F328 PRG:3328 01 A2 01 82 01 72 01 52
|
|
|
|
; $F330-$F33F
|
|
.byte $01,$32,$01,$12,$01,$A1,$01,$71 ; CPU:$F330 PRG:3330 01 32 01 12 01 A1 01 71
|
|
.byte $01,$31,$01,$F0,$01,$42,$7F,$38 ; CPU:$F338 PRG:3338 01 31 01 F0 01 42 7F 38
|
|
|
|
; $F340-$F34F
|
|
.byte $23,$02,$33,$02,$43,$02,$53,$02 ; CPU:$F340 PRG:3340 23 02 33 02 43 02 53 02
|
|
.byte $43,$02,$33,$02,$23,$02,$13,$02 ; CPU:$F348 PRG:3348 43 02 33 02 23 02 13 02
|
|
|
|
;==============================================================================
|
|
; $F350-$F44F: Runtime / Audio Command Data
|
|
;
|
|
; Raw command/parameter stream preserved byte-for-byte.
|
|
; Semantic subdivision is deferred until all stream consumers are mapped.
|
|
;==============================================================================
|
|
|
|
AudioSequenceData_F350:
|
|
|
|
; $F350-$F35F
|
|
.byte $23,$02,$33,$02,$43,$02,$33,$02 ; CPU:$F350 PRG:3350 23 02 33 02 43 02 33 02
|
|
.byte $23,$02,$13,$02,$03,$02,$13,$02 ; CPU:$F358 PRG:3358 23 02 13 02 03 02 13 02
|
|
|
|
; $F360-$F36F
|
|
.byte $23,$02,$33,$02,$23,$02,$13,$02 ; CPU:$F360 PRG:3360 23 02 33 02 23 02 13 02
|
|
.byte $03,$02,$B2,$02,$03,$02,$13,$02 ; CPU:$F368 PRG:3368 03 02 B2 02 03 02 13 02
|
|
|
|
; $F370-$F37F
|
|
.byte $23,$02,$13,$02,$03,$02,$B2,$02 ; CPU:$F370 PRG:3370 23 02 13 02 03 02 B2 02
|
|
.byte $A2,$02,$B2,$02,$03,$02,$23,$02 ; CPU:$F378 PRG:3378 A2 02 B2 02 03 02 23 02
|
|
|
|
; $F380-$F38F
|
|
.byte $03,$02,$B2,$02,$A2,$02,$92,$02 ; CPU:$F380 PRG:3380 03 02 B2 02 A2 02 92 02
|
|
.byte $A2,$02,$B2,$02,$03,$02,$B2,$02 ; CPU:$F388 PRG:3388 A2 02 B2 02 03 02 B2 02
|
|
|
|
; $F390-$F39F
|
|
.byte $A2,$02,$92,$02,$82,$02,$92,$02 ; CPU:$F390 PRG:3390 A2 02 92 02 82 02 92 02
|
|
.byte $A2,$02,$03,$02,$A2,$02,$92,$02 ; CPU:$F398 PRG:3398 A2 02 03 02 A2 02 92 02
|
|
|
|
; $F3A0-$F3AF
|
|
.byte $82,$02,$F2,$00,$F3,$00,$F5,$18 ; CPU:$F3A0 PRG:33A0 82 02 F2 00 F3 00 F5 18
|
|
.byte $31,$01,$71,$01,$B1,$01,$32,$01 ; CPU:$F3A8 PRG:33A8 31 01 71 01 B1 01 32 01
|
|
|
|
; $F3B0-$F3BF
|
|
.byte $72,$01,$B2,$01,$33,$01,$73,$01 ; CPU:$F3B0 PRG:33B0 72 01 B2 01 33 01 73 01
|
|
.byte $C0,$02,$31,$01,$71,$01,$B1,$01 ; CPU:$F3B8 PRG:33B8 C0 02 31 01 71 01 B1 01
|
|
|
|
; $F3C0-$F3CF
|
|
.byte $32,$01,$72,$01,$B2,$01,$33,$01 ; CPU:$F3C0 PRG:33C0 32 01 72 01 B2 01 33 01
|
|
.byte $73,$01,$F0,$01,$81,$7F,$40,$31 ; CPU:$F3C8 PRG:33C8 73 01 F0 01 81 7F 40 31
|
|
|
|
; $F3D0-$F3DF
|
|
.byte $08,$32,$08,$A1,$08,$71,$08,$32 ; CPU:$F3D0 PRG:33D0 08 32 08 A1 08 71 08 32
|
|
.byte $07,$A1,$07,$71,$0C,$C0,$06,$41 ; CPU:$F3D8 PRG:33D8 07 A1 07 71 0C C0 06 41
|
|
|
|
; $F3E0-$F3EF
|
|
.byte $08,$42,$08,$B1,$08,$81,$08,$42 ; CPU:$F3E0 PRG:33E0 08 42 08 B1 08 81 08 42
|
|
.byte $07,$B1,$07,$81,$0C,$C0,$06,$31 ; CPU:$F3E8 PRG:33E8 07 B1 07 81 0C C0 06 31
|
|
|
|
; $F3F0-$F3FF
|
|
.byte $08,$32,$08,$A1,$08,$71,$08,$32 ; CPU:$F3F0 PRG:33F0 08 32 08 A1 08 71 08 32
|
|
.byte $07,$A1,$07,$71,$0C,$C0,$06,$61 ; CPU:$F3F8 PRG:33F8 07 A1 07 71 0C C0 06 61
|
|
|
|
; $F400-$F40F
|
|
.byte $05,$71,$05,$81,$05,$81,$05,$91 ; CPU:$F400 PRG:3400 05 71 05 81 05 81 05 91
|
|
.byte $05,$A1,$05,$A1,$05,$B1,$05,$02 ; CPU:$F408 PRG:3408 05 A1 05 A1 05 B1 05 02
|
|
|
|
; $F410-$F41F
|
|
.byte $05,$32,$0C,$F0,$02,$82,$7F,$40 ; CPU:$F410 PRG:3410 05 32 0C F0 02 82 7F 40
|
|
.byte $30,$18,$A0,$08,$30,$0E,$A0,$0C ; CPU:$F418 PRG:3418 30 18 A0 08 30 0E A0 0C
|
|
|
|
; $F420-$F42F
|
|
.byte $C0,$06,$40,$18,$B0,$08,$40,$0E ; CPU:$F420 PRG:3420 C0 06 40 18 B0 08 40 0E
|
|
.byte $B0,$0C,$C0,$06,$30,$18,$A0,$08 ; CPU:$F428 PRG:3428 B0 0C C0 06 30 18 A0 08
|
|
|
|
; $F430-$F43F
|
|
.byte $30,$0E,$A0,$0C,$C0,$06,$A0,$0F ; CPU:$F430 PRG:3430 30 0E A0 0C C0 06 A0 0F
|
|
.byte $01,$0F,$21,$0F,$31,$0C,$F0,$01 ; CPU:$F438 PRG:3438 01 0F 21 0F 31 0C F0 01
|
|
|
|
; $F440-$F44F
|
|
.byte $9F,$7F,$28,$01,$01,$41,$01,$71 ; CPU:$F440 PRG:3440 9F 7F 28 01 01 41 01 71
|
|
.byte $01,$A1,$01,$02,$01,$F5,$18,$F0 ; CPU:$F448 PRG:3448 01 A1 01 02 01 F5 18 F0
|
|
|
|
|
|
;==============================================================================
|
|
; $F450-$F49A: Runtime / Audio Command Data
|
|
;
|
|
; Raw command data preserved byte-for-byte.
|
|
;==============================================================================
|
|
|
|
AudioSequenceData_F450:
|
|
|
|
; $F450-$F45F
|
|
.byte $01,$9F,$7F,$28,$02,$01,$A1,$01 ; CPU:$F450 PRG:3450 01 9F 7F 28 02 01 A1 01
|
|
.byte $71,$01,$41,$01,$F5,$18,$01,$01 ; CPU:$F458 PRG:3458 71 01 41 01 F5 18 01 01
|
|
|
|
; $F460-$F46F
|
|
.byte $F0,$01,$9F,$7F,$28,$52,$01,$92 ; CPU:$F460 PRG:3460 F0 01 9F 7F 28 52 01 92
|
|
.byte $01,$03,$01,$33,$01,$F5,$18,$53 ; CPU:$F468 PRG:3468 01 03 01 33 01 F5 18 53
|
|
|
|
; $F470-$F47F
|
|
.byte $03,$F5,$28,$53,$01,$33,$01,$03 ; CPU:$F470 PRG:3470 03 F5 28 53 01 33 01 03
|
|
.byte $01,$92,$01,$F5,$18,$52,$03,$92 ; CPU:$F478 PRG:3478 01 92 01 F5 18 52 03 92
|
|
|
|
; $F480-$F48F
|
|
.byte $01,$13,$01,$43,$01,$73,$01,$F5 ; CPU:$F480 PRG:3480 01 13 01 43 01 73 01 F5
|
|
.byte $18,$93,$0A,$F5,$28,$93,$01,$73 ; CPU:$F488 PRG:3488 18 93 0A F5 28 93 01 73
|
|
|
|
; $F490-$F49A
|
|
.byte $01,$43,$01,$13,$01,$F5,$18,$92 ; CPU:$F490 PRG:3490 01 43 01 13 01 F5 18 92
|
|
.byte $03,$F0,$FF ; CPU:$F498 PRG:3498 03 F0 FF
|
|
|
|
;==============================================================================
|
|
; $F49B-$F64F: PRG Padding
|
|
;==============================================================================
|
|
.res $0B5B, $FF ; CPU:$F49B PRG:349B FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
|
|
|
|
|
|
;==============================================================================
|
|
; $FFF6-$FFF9: Final ROM Data
|
|
;
|
|
; Notes:
|
|
; $FFF6/$FFF7 are read directly by DrawMazeNametable:
|
|
;
|
|
; lda $FFF7
|
|
; sta $01
|
|
; lda $FFF6
|
|
; sta $00
|
|
;
|
|
; Therefore the first two bytes form the little-endian value $ECEC.
|
|
;
|
|
; $FFF8/$FFF9 form the little-endian value $C10E.
|
|
;==============================================================================
|
|
|
|
MazeDataPointerBytes:
|
|
.byte $EC,$EC ; CPU:$FFF6 PRG:3FF6 EC EC
|
|
.byte $0E,$C1 ; CPU:$FFF8 PRG:3FF8 0E C1
|
|
|
|
;==============================================================================
|
|
; $FFFA-$FFFF: Interrupt Vectors
|
|
;==============================================================================
|
|
.org $FFFA
|
|
CpuInterruptVectors:
|
|
.word NmiHandler ; NMI ; CPU:$FFFA PRG:3FFA 0E C1
|
|
.word Reset ; Reset ; CPU:$FFFC PRG:3FFC 33 C0
|
|
.word IrqHandler ; IRQ/BRK ; CPU:$FFFE PRG:3FFE 7E C1
|