- Decoded the VramWrite ($E1CC) stream format: <addr hi> <addr lo> <count> <bytes>, $00 terminator - Named all 9 payload streams ($E4CC-$E7C2, no gaps/overlaps) plus VramWriteSourcePointerTable at $F000 - Split PadBitTableLives into Player1TileTable ($E4B4) and Player2TileTable ($E4C0), 12 entries each (Y=0..11) - Decoded CHR font (digits $30-$39, letters $3A-$52, space $5F; 'W' missing from the A-Z run) and recovered on-screen text including 'PRESS A TO TEST SIDE-A' / 'SIDE-B' - Documented that the 16 KiB PRG is two byte-identical 8 KiB halves; $C000 copy is dead - Documented 7 unreached subroutines inside the live code region (kept as .byte per Pass-1 policy) - Fixed a stray duplicate sentence and stale _wip paths in root OVERVIEW.md Byte-identical ROM verified.
7.5 KiB
7.5 KiB
| 1 | # MUSCLE (U) zero-page names - Pass 2 | |||
|---|---|---|---|---|
| 2 | # kind<TAB>old<TAB>new<TAB>note | |||
| 3 | zp | Zp10 | SourcePointerLo | Lo byte of the compressed VRAM/attribute stream pointer |
| 4 | zp | Zp11 | SourcePointerHi | Hi byte of the compressed VRAM/attribute stream pointer |
| 5 | zp | Zp12 | DestinationPointerLo | Lo byte of the VRAM destination pointer |
| 6 | zp | Zp13 | DestinationPointerHi | Hi byte of the VRAM destination pointer |
| 7 | zp | Zp1A | BytecodeStreamPointerLo | Lo byte of the token-stream pointer, loaded from the $8CEF table |
| 8 | zp | Zp1B | BytecodeStreamPointerHi | Hi byte of the token-stream pointer |
| 9 | zp | Zp1C | BytecodeHandlerPointerLo | Lo byte of the handler address consumed by jmp ($001C) |
| 10 | zp | Zp1D | BytecodeHandlerPointerHi | Hi byte of the handler address consumed by jmp ($001C) |
| 11 | zp | Zp1E | ActorIndex | Active player/actor slot (0 or 1) used as an array index |
| 12 | zp | Zp21 | ActorSlotOffset | ActorIndex*4; byte offset into the per-actor record arrays |
| 13 | zp | Zp22 | ActorSlotOffsetHi | High half of the per-actor record offset |
| 14 | zp | Zp23 | ActorFieldOffset | Second per-actor offset used by the bytecode handlers |
| 15 | zp | Zp24 | FrameCounterLo | Low byte of the 16-bit frame counter, incremented once per NMI |
| 16 | zp | Zp25 | FrameCounterHi | High byte of the 16-bit frame counter |
| 17 | zp | Zp26 | PlayerSpriteIndex1 | Per-player sprite slot table, first plane |
| 18 | zp | Zp27 | PlayerSpriteIndex2 | Per-player sprite slot table, second plane |
| 19 | zp | Zp28 | PlayerSpriteIndex3 | Per-player sprite slot table, third plane |
| 20 | zp | Zp29 | PlayerSpriteIndex4 | Per-player sprite slot table, fourth plane |
| 21 | zp | Zp2A | PlayerPaletteIndex | Per-player palette slot table |
| 22 | zp | Zp2B | PlayerTileIndex | Per-player tile slot table |
| 23 | zp | Zp34 | ActorPosXLo | Per-actor 16-bit X scratch, written by the bytecode handlers |
| 24 | zp | Zp35 | ActorPosXHi | Per-actor 16-bit X scratch, high byte |
| 25 | zp | Zp36 | ActorPosY | Per-actor Y scratch |
| 26 | zp | Zp3A | PlayerPosXLo1 | Player 1 X position, low byte |
| 27 | zp | Zp3C | PlayerPosYLo1 | Player 1 Y position, low byte |
| 28 | zp | Zp3E | PlayerPosXLo2 | Player 2 X position, low byte |
| 29 | zp | Zp40 | PlayerPosYLo2 | Player 2 Y position, low byte |
| 30 | zp | Zp41 | ScriptFlags | Script state byte selected by the bytecode SelectActorSlot handlers |
| 31 | zp | Zp43 | ScriptCounterA | Per-actor bytecode counter A |
| 32 | zp | Zp44 | ScriptCounterB | Per-actor bytecode counter B |
| 33 | zp | Zp45 | ScriptCounterC | Per-actor bytecode counter C |
| 34 | zp | Zp47 | ScriptArgLo | Per-actor bytecode argument, low byte |
| 35 | zp | Zp48 | ScriptArgHi | Per-actor bytecode argument, high byte |
| 36 | zp | Zp4D | ScriptFlagsLo | Low byte of the 16-bit script flag pair |
| 37 | zp | Zp4E | ScriptFlagsHi | High byte; tested non-zero to gate several bytecode handlers |
| 38 | zp | Zp65 | ActionCooldown | Frames to wait before the main loop resumes object updates |
| 39 | zp | Zp68 | ScreenTransitionState | 0 = idle, negative = entering, positive = leaving |
| 40 | zp | Zp6E | PlayerBoxOriginX | Player 1 hitbox origin used by the overlap test |
| 41 | zp | Zp70 | PlayerBoxOriginY | Player 1 hitbox origin used by the overlap test |
| 42 | zp | Zp80 | SoundVolume1 | APU channel 1 volume |
| 43 | zp | Zp81 | SoundVolume2 | APU channel 2 volume |
| 44 | zp | Zp82 | SoundVolume3 | APU channel 3 volume |
| 45 | zp | Zp83 | SoundVolume4 | APU channel 4 volume |
| 46 | zp | Zp8B | PlayerFlashTimer | Per-player damage-flash countdown |
| 47 | zp | Zp8C | PlayerFlashTimer2 | Per-player damage-flash countdown, second half |
| 48 | zp | Zp8D | RoundTransitionTimer | Decremented by the round-transition state |
| 49 | zp | Zp91 | PlayerPaletteIndexLo | Low byte of the player palette index pair |
| 50 | zp | Zp92 | PlayerPaletteIndexHi | High byte of the player palette index pair |
| 51 | zp | Zp94 | PlayerCount | 0 = one player, 1 = two players |
| 52 | zp | Zp96 | SubModeFlag | $FF entering a sub-mode, $01 leaving it, 0 idle |
| 53 | zp | ZpC4 | SoundEnvelopeMode1 | APU channel 1 envelope/tone mode nibble |
| 54 | zp | ZpC5 | SoundEnvelopeMode2 | APU channel 2 envelope/tone mode nibble |
| 55 | zp | ZpC6 | SoundEnvelopeMode3 | APU channel 3 envelope/tone mode nibble |
| 56 | zp | ZpC7 | SoundEnvelopeMode4 | APU channel 4 envelope/tone mode nibble |
| 57 | zp | ZpC8 | SoundNoteTimer1 | APU channel 1 note duration countdown |
| 58 | zp | ZpC9 | SoundNoteTimer2 | APU channel 2 note duration countdown |
| 59 | zp | ZpCA | SoundNoteTimer3 | APU channel 3 note duration countdown |
| 60 | zp | ZpCB | SoundNoteTimer4 | APU channel 4 note duration countdown |
| 61 | zp | ZpCC | SoundEnvelopeValue1 | APU channel 1 envelope byte read from the sequence |
| 62 | zp | ZpCD | SoundEnvelopeValue2 | APU channel 2 envelope byte read from the sequence |
| 63 | zp | ZpCE | SoundEnvelopeValue3 | APU channel 3 envelope byte read from the sequence |
| 64 | zp | ZpCF | SoundEnvelopeValue4 | APU channel 4 envelope byte read from the sequence |
| 65 | zp | ZpD0 | SoundChannelStep1 | APU channel 1 step index into its note table |
| 66 | zp | ZpD1 | SoundChannelStep2 | APU channel 2 step index into its note table |
| 67 | zp | ZpD2 | SoundChannelStep3 | APU channel 3 step index into its note table |
| 68 | zp | ZpD3 | SoundChannelStep4 | APU channel 4 step index into its note table |
| 69 | zp | ZpD4 | SoundSequencePtrLo1 | APU channel 1 sequence pointer, low byte |
| 70 | zp | ZpD5 | SoundSequencePtrLo2 | APU channel 2 sequence pointer, low byte |
| 71 | zp | ZpD6 | SoundSequencePtrLo3 | APU channel 3 sequence pointer, low byte |
| 72 | zp | ZpD7 | SoundSequencePtrLo4 | APU channel 4 sequence pointer, low byte |
| 73 | zp | ZpD8 | SoundSequencePtrHi1 | APU channel 1 sequence pointer, high byte |
| 74 | zp | ZpD9 | SoundSequencePtrHi2 | APU channel 2 sequence pointer, high byte |
| 75 | zp | ZpDA | SoundSequencePtrHi3 | APU channel 3 sequence pointer, high byte |
| 76 | zp | ZpDB | SoundSequencePtrHi4 | APU channel 4 sequence pointer, high byte |
| 77 | zp | ZpDC | SoundSustainCounter1 | APU channel 1 sustain/release counter |
| 78 | zp | ZpDD | SoundSustainCounter2 | APU channel 2 sustain/release counter |
| 79 | zp | ZpDE | SoundSustainCounter3 | APU channel 3 sustain/release counter |
| 80 | zp | ZpDF | SoundSustainCounter4 | APU channel 4 sustain/release counter |
| 81 | zp | ZpE0 | SoundLastCtrlWrite1 | Last value written to $4000+4*channel, channel 1 |
| 82 | zp | ZpE1 | SoundLastCtrlWrite2 | Last value written to $4000+4*channel, channel 2 |
| 83 | zp | ZpE2 | SoundLastCtrlWrite3 | Last value written to $4000+4*channel, channel 3 |
| 84 | zp | ZpE3 | SoundLastCtrlWrite4 | Last value written to $4000+4*channel, channel 4 |
| 85 | zp | ZpE4 | ApuRegisterOffset | Channel*4, the offset added to $4000/$4001/$4002/$4003 |
| 86 | zp | ZpE8 | ApuEnableMask | Bit mask of currently enabled APU channels |
| 87 | zp | ZpE9 | SoundMuted | Bit 7 set suppresses writes to $4015 (write during rendering) |
| 88 | zp | ZpEA | SoundTonePeriodLo | Computed tone period, low byte |
| 89 | zp | ZpEB | SoundTonePeriodHi | Computed tone period, high byte |
| 90 | zp | ZpEC | SoundEnvelopeMaskLo | Computed envelope bits OR-ed into $4000, low part |
| 91 | zp | ZpED | SoundEnvelopeMaskHi | Computed envelope bits OR-ed into $4000, high part |
| 92 | zp | ZpEE | SoundReadPointerLo | Lo byte of the sound sequence read cursor |
| 93 | zp | ZpEF | SoundReadPointerHi | Hi byte of the sound sequence read cursor |
| 94 | zp | ZpF0 | PlayerActionState | Per-player action/animation state byte ($80..$FF) |
| 95 | zp | ZpF1 | PlayerActionState2 | Per-player second action state byte |
| 96 | zp | ZpF2 | ControllerButtonMask | Filtered button bits for this read, per player |
| 97 | zp | ZpF3 | ControllerButtonMask2 | Filtered button bits, second player |
| 98 | zp | ZpF4 | ControllerButtonsPrev | Previous read's button byte, for edge detection |
| 99 | zp | ZpF5 | ControllerButtonsPrev2 | Previous read's button byte, second player |
| 100 | zp | ZpF6 | ControllerDPad1 | Directional bits derived from the button byte |
| 101 | zp | ZpF7 | ControllerDPad2 | Directional bits derived from the button byte |
| 102 | zp | ZpF8 | ControllerFaceButtons1 | Face-button bits derived from the button byte |
| 103 | zp | ZpF9 | ControllerFaceButtons2 | Face-button bits derived from the button byte |
| 104 | zp | ZpFA | ControllerButtons1 | Raw button byte for player 1 (shadows $4010/$4011 at reset) |
| 105 | zp | ZpFB | ControllerButtons2 | Raw button byte for player 2 (shadows $4010/$4011 at reset) |
| 106 | zp | ZpFC | PpuCtrlShadow | Shadow of the last value written to $2000 |
| 107 | zp | ZpFD | PpuMaskShadow | Shadow of the last value written to $2001 |
| 108 | zp | ZpFE | PpuScrollX | Shadow of the first $2005 write |
| 109 | zp | ZpFF | PpuScrollY | Shadow of the second $2005 write |
| 110 | zp | Zp14 | VramBlockCountLo | Low byte of the 16-bit block counter advanced by AdvanceCountWord |
| 111 | zp | Zp15 | CollisionFlagBits | Accumulator for the overlap bit flags OR-ed together by ComputePlayerOverlapBits |