# Chubby Cherub (U) ## Status **Pass 1 + Pass 2 + Pass 3 complete.** The project builds and verifies byte-identical to the original ROM. `prg.s` is a traced disassembly classifying bytes as reachable code or data, with every instruction carrying a trailing audit comment. Unreached bytes remain as explicit `.byte` blocks; no ROM byte is deleted or reformatted. `make` assembles `header.s`, `prg.s`, `chr.s`, links them with `ld65` and compares the result against `rom.nes`: ``` Byte-identical ROM verified. ``` ### The split The Pass 1 split was redone from a Mesen Code Data Logger capture of a real session. The capture's jump-target flag names the addresses the CPU actually branched to, and re-tracing with those seeds reaches the code behind the game's computed dispatch. | | | |---|---| | Instructions | 6,630 | | Code bytes | 13,553 of 32,768 (41.4%) | | Data blocks | 48 | | Named data structures | 58 | ### The character encoding The HUD and message text is 8x8 nametable tiles, and the code that draws it is a table of tile codes. The mapping was recovered by running the ROM in Mesen and matching the live nametable against the title, gameplay and game-over screens: | Code | Meaning | Code | Meaning | |------|---------|------|---------| | `$00-$09` | digits `0`-`9` | `$26` | `™` | | `$0A-$23` | `A`-`Z` | `$2D` | heart | | `$24` | `-` | `$2E` | `!` | | `$25` | `.` | `$2F` | `©` | | `$30` | space | `$33` | blank | That turns opaque byte blobs into readable strings - "TM AND © BANDAI 1986", "LICENSED BY NINTENDO", "1-PLAYER GAME", "1P-SCORE", "1P READY", "1P GAME OVER", "1P CONGRATULATIONS!", "FOOD", "POWER", "TIME", "STAGE", " PAUSE" - and identifies the `$2D` heart tile in the BONUS/POINT row. The letter glyphs themselves are *not* in the CHR, which holds only the graphics for those tile codes, so the letter identities rest on the on-screen comparison rather than on the tile art. `make` assembles `header.s`, `prg.s`, `chr.s`, links them with `ld65` and compares the result against `rom.nes`: ``` Byte-identical ROM verified. ``` ## ROM | Property | Value | |----------|-------| | Format | iNES | | Mapper | 0 | | Board | NROM-256 | | Mirroring | Vertical | | Four-screen VRAM | no | | Battery | no | | PRG | 32 KB (2 x 16 KB), mapped at CPU $8000-$FFFF | | CHR | 8 KB (1 x 8 KB) | | Trainer | none | | Footer | none | | NMI vector | $82B7 | | RESET vector | $8000 | | IRQ vector | $8331 | | ROM file | `Chubby Cherub (U).nes` | | SHA-256 | `4283bdf7efdac14d5c940716d791f8a2de1bce3291c17c1b650a80097bc1bc3b` | ### Header notes - none ## Address-derived entry points (residue) `PROMPTS.md` asks every `jsr`/`jmp` entry point to carry a semantic name and accepts the address-derived `SubCXXXX` form **only where the dump does not reveal a better one**. Of the 223 address-derived entry points this project started with, **205 now carry a semantic name** - for example `LoadPlayerInitialValues` at `$8283`, `UploadOamToPpu` at `$84CF`, `SetScrollPosition` at `$84FB`, `LatchControllerButtons` at `$8487`, `TurnOffRendering` at `$8611`, `UpdateSprites`/`DrawSprites` at `$CA033`, `DispatchStageHandler` at `$CB640`, `DispatchScreenState` at `$CB2DA`, `ResetSoundEngine` at `$CCF09` and `StartStageMusic` at `$CC89A`. **18 entry points remain address-derived**, in two groups: | Group | Count | Addresses | Why the dump does not settle it | |-------|-------|-----------|--------------------------------| | Individual sound-effect selectors | 12 | `$CC900`, `$CC90D`, `$CC927`, `$CC93E`, `$CC94B`, `$CC96B`, `$CC978`, `$CC985`, `$CC9D3`, `$CC9E0`, `$CC9ED`, `$CC9FA` | Each of these sets a pair of 16-bit pointers into the `$CA07-$CF08` region - the one block whose layout the inventory above records as *not established*. They differ only in which of those pointers they select, so the ROM reveals *where* the sound data lives but never *what the sound is*: the game's sound vocabulary (the "eat", "hit", "power up", "time up" cues) is not derivable from a pointer value. The three selectors whose role the callers do reveal are named: `StartStageMusic` (`$CC89A`, called when a stage begins), `StartAllStagesClearedMusic` (`$CC8BB`, called with the stage number set to `$0F`) and `StartGameOverMusic` (`$CC8D2`, called with the stage number set to `$10`). | | Game-state reset variants and sprite helpers | 6 | `$8231`, `$8257`, `$87E5`, `$8CB1`, `$CA123`, `$CA63D` | `$8231` and `$8257` are the two halves of the state machine's "leave the screen" path; they differ only in the two flag bytes `$4C`/`$4D` they set, and nothing in the ROM says which screen each pair selects. `$87E5`, `$8CB1`, `$CA123` and `$CA63D` are the small steps that decide whether a sprite or the player may be drawn this frame; the flags they test are named nowhere in the ROM. | These are left as they are rather than guessed: a plausible-sounding name the ROM does not support would be worse than the honest `SubCXXXX` form that `PROMPTS.md` explicitly allows. ## Open work - The **zero-page aliases** in `locals.inc` are the generated `ZpXX` names with no behavioural alias applied: the roles are not proven from the code alone. - The **routine names**: 205 of the 223 address-derived `SubC` entry points now carry a semantic name; the 18 that are left are listed in [Address-derived entry points (residue)](#address-derived-entry-points-residue) with the reason the dump does not settle them. - The layout of the **`$CA07-$CF08` block (1,282 bytes)** is not established. It is recorded as such in the inventory below rather than being given a speculative name. - Nine of the unreferenced blocks decode as long runs of instructions - code the tracer could not reach rather than data. They stay `.byte`. ## Power-on flow analysis Derived from the disassembly by `_tools/derive_poweron.py`; the call graph is walked from the reset entry. **RESET** is at `$8000` (`Reset`). The CPU comes here out of reset with the PPU and APU in their power-on state and the zero page and RAM uninitialised. The reset path calls: | Address | Routine | |---------|---------| | `$8007` | `SubC8007` (falls through) | | `$8012` | `SubC8012` (falls through) | | `$8032` | `SubC8032` (falls through) | | `$8049` | `SubC8049` (falls through) | | `$8757` | `ResetPlayerPosition` | **NMI** is at `$82B7` (`NmiHandler`). It is the per-frame handler; what it calls: | Address | Routine | |---------|---------| | `$8462` | `ReadControllerButtons` | | `$84CF` | `UploadOamToPpu` | **IRQ** is at `$8331` (`IrqHandler`) - a different address from RESET. ## Pass 3 data-table inventory Every `; ---- data $XXXX-$YYYY ----` region in `prg.s` is listed here. A region that is only partly table and partly code says so: the tracer's data blocks are contiguous runs of bytes it never reached, so a block can hold a table, a table *and* unreached code, or code alone. ### How the game's text was decoded Chubby Cherub draws its HUD and message screens as 8x8 nametable tiles, so the "text" tables below are streams of CHR tile indices that the game writes to `$2007`. The code-to-letter mapping was recovered from the running game (Mesen) by matching the nametable contents of the title, gameplay and game-over screens against what is on screen: | Tile code | Meaning | |-----------|---------| | `$00`-`$09` | digits `0`-`9` | | `$0A`-`$23` | letters `A`-`Z` (`$0A`=A ... `$23`=Z) | | `$24` | `-` | | `$25` | `.` | | `$26` | `TM` | | `$2D` | heart (the bonus-point counter) | | `$2E` | `!` | | `$2F` | `(c)` | | `$30` | space | | `$33` | blank tile (the nametable background) | Decoded examples: `$AD97` is `"TM AND (c) BANDAI 1986"`, `"LICENSED BY NINTENDO"`, `"OF AMERICA INC."`, `"1-UP"`, `"HI-SCORE"`, `"2-UP"`; `$B58A` is `"1P CONGRATULATIONS!"`; `$B4D1` is `"1P GAME OVER "`; `$AE36`/`$AE23` are `"-PLAYER"` and `" GAME"`. The CHR itself holds only graphics for these codes, so the letter identities come from the on-screen comparison, not from the tile art. ### Inventory | Address | Size | Name | Structure | Read by | |---------|------|------|-----------|---------| | `$8290-$82A0` | 17 | `PlayerStateInitialValues` | 17 x 8-bit initial values for the 17-byte player/game-state block at `$4F-$5F` (stage number, 16-bit world position, timers) | `lda $8290,x` at `$8285` (copied to `$4F` by `sta Zp4F,x` at `$8288`) | | `$8613-$8613` | 1 | - | single byte `$AE` sitting between the two PPU-register setup routines at `$8611` and `$8614`; not an instruction start | not referenced by any instruction | | `$861E-$861E` | 1 | - | single byte `$AE` between the PPUCTRL setup at `$861C` and the routine at `$861F` | not referenced by any instruction | | `$8877-$8999` | 291 | `StageSceneryAttributeRuns` (`$889A`) | `$8877-$8899` is unreached code; `$889A-$8999` is 51 x (8-bit sprite attribute, 8-bit run length) pairs covering 1019 stage columns | `lda $889A,y` at `$84B7`, `lda $889B,y` at `$84BC` | | `$8CC4-$8CF3` | 48 | `CameraColumnStepFlags` | 48 x 8-bit flags, `0` = hold the column, `1` = advance one pixel; the per-column fractional step of the camera/scenery position. The index is a counter masked to `$3F`, so the ROM can in principle address 64 entries | `lda $8CC4,x` at `$8A59`, `lda $8CC4,x` at `$8A9B`, `sbc $8CC4,y` at `$9AC9`, `adc $8CC4,y` at `$9AF9`, `adc $8CC4,x` at `$DB45`, `sbc $8CC4,x` at `$DB50` | | `$8EF1-$8F0B` | 27 | `EnemyPointValueTable` (`$8EF1`), `EnemyWalkSpeedTable` (`$8EFA`), `EnemyAltitudeTable` (`$8F03`) | three parallel 9-byte tables, one entry per enemy type: score value, movement speed, altitude. The index is the enemy's type byte masked to `$0F`, so the ROM can in principle address 16 entries per table | `lda $8EF1,x` at `$8E3C`, `lda $8F03,y` at `$8E61`, `lda $8EFA,y` at `$8E73` | | `$8F96-$8FA1` | 12 | `StageMarkerTileTable` | 12 x 8-bit CHR tile indices, one per stage, for the stage's fixed marker sprite (written to the OAM shadow at `$0705`) | `lda $8F96,x` at `$8F4E` | | `$9335-$938D` | 89 | `HudLabelTextTable` (`$9335`), `HudLabelPointerTable` (`$9355`), `HudLabelRecordTable` (`$936D`), `StageLabelText` (`$9389`) | `$9335-$9354` = four inline HUD label records `[nametable high][nametable low][length][text]` = `"P-SCORE"`, `"POWER"`, `"TIME"`, `"GAU-"`; `$9355-$936C` = 10 x 16-bit LE pointers into `$936D`; `$936D-$9388` = four more records = `"FOOD"`, `"TIME"`, `"GAU"`, `"JEWEL"`; `$9389-$938D` = `"STAGE"` | `lda $9355,x` at `$9293`, `lda $9356,x` at `$9298`, `lda $9389,y` at `$92B8`, `lda $9389,y` at `$B146` | | `$95BC-$95D0` | 21 | `SpriteRepeatCountTable` | 21 x 8-bit repeat counts, one per sprite type; the count says how many copies of that sprite the stage layout asks for | `lda $95BC,y` at `$9540` | | `$9703-$97A6` | 164 | `ObjectBehaviourPointerTable` (`$9703`) | `$9703-$9732` = 24 x 16-bit LE dispatch pointers, one per object type, reached through `jmp ($10)` at `$96F5`; `$9733-$97A6` is unreached code | `lda $9703,y` at `$96E5`, `lda $9704,y` at `$96EA` | | `$97F9-$988E` | 150 | - | unreferenced; decodes as 73 consecutive instructions, so it is code the tracer could not reach, not data | not referenced by any instruction | | `$9899-$98B2` | 26 | - | unreferenced; decodes as 12 consecutive instructions - code the tracer could not reach | not referenced by any instruction | | `$98CD-$99EB` | 287 | - | unreferenced; decodes as 134 consecutive instructions - code the tracer could not reach | not referenced by any instruction | | `$9BE3-$9C2D` | 75 | `ObjectTypeBaseTileTable` (`$9BE3`), `ObjectTypeAttributeTable` (`$9BFC`) | `$9BE3-$9BFB` = 25 x 8-bit base tile per object type (the sprite routine adds 2 to it); `$9BFC-$9C2D` = 25 x 16-bit LE sprite attribute per object type (`$40`/`$80`/`$C0` are the flip bits) | `lda $9BE3,y` at `$9A00`, `lda $9BFC,y` at `$9A09`, `lda $9BFD,y` at `$9A0E`, `lda $9BE3,y` at `$9AA5` | | `$9D39-$9E96` | 350 | - | unreferenced; decodes as 153 consecutive instructions - code the tracer could not reach | not referenced by any instruction | | `$A1C7-$A63C` | 1142 | `StageSpriteSetPointerTable` (`$A1C7`), `StageSpriteParameterPointerTable` (`$A2C7`), `StageSpriteParameterTable` (`$A2E7`), `StageObjectCoordinateTable` (`$A567`), `StageSpriteCoordinateTable` (`$A5DD`) | `$A1C7-$A2C6` = 128 x 16-bit LE pointers, one per stage; `$A2C7-$A2E6` = 16 x 16-bit LE pointers to the 40-byte sub-tables at `$A2E7`; `$A2E7-$A566` = those 16 sub-tables of 16-bit values; `$A567-$A5DC` and `$A5DD-$A63C` = 16-bit (X,Y) screen-coordinate pairs | `lda $A1C7,x` at `$9F40`, `lda $A1C8,x` at `$9F45`, `lda $A2C7,x` at `$9F51`, `lda $A2C8,x` at `$9F56`, `lda $A5DD,y` at `$9F9F`, `lda $A5DE,y` at `$9FA7` | | `$A776-$A795` | 32 | `MetaspriteYPositionTable` (`$A776`), `MetaspriteAttributeTable` (`$A786`) | two parallel 16-byte tables: the Y position of a 16-row object and its attribute (all zero) | `lda $A786,x` at `$A760`, `lda $A776,x` at `$A765` | | `$A7C3-$A7C8` | 6 | `PauseLabelText` | 6 font codes, `" PAUSE"`, copied into the 6-byte text buffer at `$024D` | `lda $A7C3,x` at `$A7B9` | | `$A96B-$A974` | 10 | `SpriteCountPerTypeTable` | 10 x 8-bit sprite counts, one per sprite type, indexing the pointer table at `$BCFF` | `lda $A96B,x` at `$A929` | | `$AA01-$AA01` | 1 | - | single byte `$AC` between two instructions | not referenced by any instruction | | `$AC3A-$AC3C` | 3 | `ObjectPaletteTable` | 3 x 8-bit sprite attribute/palette selectors (`$70`, `$60`, `$50`), picked by the object's attribute bits | `lda $AC3A,y` at `$ABC4` | | `$AD97-$ADE5` | 79 | `TitleScreenTextTiles` (`$AD97`), `OneUpLabelText` (`$ADCE`) | `$AD97` = one stream of title/copyright-screen font codes (`"TM AND (c) BANDAI 1986"`, `"LICENSED BY NINTENDO"`, `"OF AMERICA INC."`, `"1-UP"`, `"HI-SCORE"`, `"2-UP"`), written to the nametable in 20-, 40- and 55-tile runs; `$ADCE-$ADD2` = `"1-UP "` | `lda $ADCE,y` at `$ACB9`, `lda $AD97,x` at `$AD61`, `lda $AD97,x` at `$AD76`, `lda $AD97,x` at `$AD8B` | | `$AE23-$AE27` | 5 | `GameLabelText` | 5 font codes, `" GAME"` (the space is the blank tile `$33`) | `lda $AE23,x` at `$AE17` | | `$AE36-$AE3C` | 7 | `PlayerLabelText` | 7 font codes, `"-PLAYER"` | `lda $AE36,x` at `$AE2A` | | `$AF0B-$AF0E` | 4 | `MarkerSpriteYTable` | 4 x 8-bit sprite Y positions written to the OAM shadow at `$0704` | `lda $AF0B,x` at `$AF01` | | `$AF2F-$B0D6` | 424 | `TitleLogoTileData` (`$AFAF`), `OnePlayerScoreRowText` (`$B0C7`) | `$AF2F-$AF4E` = 32 unreferenced bytes in 16 two-byte pairs; `$AF4F-$AF8E` = 64 bytes of nametable tile data (mostly blank) written to `$2007`; `$AF8F-$AFAE` = 32 more unreferenced bytes; `$AFAF-$AFE2` = the 52 tiles of the two-row `"CHUBBY CHERUB"` title logo, drawn at `$2104` and `$2124`; `$AFE3-$B0C6` = unreached code; `$B0C7-$B0D6` = the 16-tile `"1P-SCORE"` + 7 blanks + `"0"` HUD row | `lda $AF4F,x` at `$AD34`, `lda $AFAF,x` at `$AE5A`, `lda $B0C7,y` at `$B190` | | `$B258-$B270` | 25 | `BonusPointRowText` | 25 font codes: 5 blanks, 8 heart tiles (`$2D`), `"BONUS"`, 2 blanks, `"POINT"` | `lda $B265,y` at `$B1DE`, `lda $B258,x` at `$B24D` | | `$B2D2-$B2D9` | 8 | `ReadyRowText` | 8 font codes, `"1P READY"` | `lda $B2D2,y` at `$B279` | | `$B2ED-$B3D5` | 233 | `ScreenStatePointerTable` (`$B2ED`) | `$B2ED-$B304` = 12 x 16-bit LE dispatch pointers (four distinct targets, three entries each) reached through `jmp ($10)` at `$B2EA`; `$B305-$B3D5` is unreached code | `lda $B2ED,y` at `$B2E0`, `lda $B2EE,y` at `$B2E5` | | `$B4D1-$B4DE` | 14 | `GameOverRowText` | 14 font codes, `"1P GAME OVER "` | `lda $B4D1,y` at `$B41A`, `lda $B4D3,y` at `$B497` | | `$B58A-$B63F` | 182 | `CongratulationsRowText` (`$B58A`) | `$B58A-$B59B` = 18 font codes, `"1P CONGRATULATIONS!"`; `$B59C-$B63F` is unreached code | `lda $B58A,y` at `$B4F7` | | `$B653-$B758` | 262 | `StageHandlerPointerTable` (`$B653`) | `$B653-$B666` = 10 x 16-bit LE dispatch pointers, one per stage, reached through `jmp ($10)` at `$B650` (the index is the stage number masked to `$0F`); `$B667-$B758` is unreached code | `lda $B653,y` at `$B646`, `lda $B654,y` at `$B64B` | | `$B7A5-$B8AD` | 265 | `FrameHandlerPointerTable` (`$B7A5`) | `$B7A5-$B7AC` = 4 x 16-bit LE dispatch pointers picked by the frame counter `Zp1D & 3`, reached through `jmp ($10)` at `$B7A2`; `$B7AD-$B8AD` is unreached code | `lda $B7A5,x` at `$B798`, `lda $B7A6,x` at `$B79D` | | `$B8BD-$C818` | 3932 | `StageBackgroundTileData` (`$B8BD`), `StageParameterPointerTable` (`$BAA1`), `StageParameterRecords` (`$BAC3`), `ObjectBaseAddressTable` (`$BB79`), `SpriteTilePointerTable` (`$BC03`), `SpriteTileListPointerTable` (`$BCFF`), `StageObjectVariantTable` (`$BD13`), `StageObjectGroupPointerTable` (`$BD25`), `StageObjectGroupTable` (`$BD3D`), `StageSpriteBaseAddressTable` (`$BDFD`), `StageObjectAttributeList` (`$BE22`) | the stage's graphics and layout data: `$B8BD-$BAA0` = nametable tile indices for the stage; `$BAA1-$BAC2` = 17 x 16-bit LE pointers to the 13-byte stage parameter records at `$BAC3`; `$BAC3-$BB5E` = 12 contiguous 13-byte parameter records (plus two more at `$BB5F` and `$BB6C`); `$BB79-$BBBA` = 33 x 16-bit LE base addresses `$DBEB + $100 * n`; `$BC03-$BC2C` = 21 x 16-bit LE tile pointers, one per sprite type; `$BCFF-$BD12` = 10 x 16-bit LE pointers to the sprite tile lists; `$BD13-$BD24` = 9 x 16-bit LE values; `$BD25-$BD3C` = 12 x 16-bit LE pointers to 8-byte tile-group records; `$BD3D-$BD9C` = 12 records of four 2-byte (tile, second-byte) pairs; `$BDFD-$BE20` = 18 x 16-bit LE base addresses; `$BE22-$C818` = a stream of 16-bit LE (small ascending index, sprite attribute) pairs describing the stage's object list | `lda $BBBB,x` at `$8C82`, `lda $BAA1,x` at `$9104`, `lda $BAA2,x` at `$9109`, `lda $BB79,x` at `$9115`, `lda $BB7A,x` at `$911C`, `lda $BDFD,x` at `$93D8` | | `$C8F3-$C8FF` | 13 | - | unreferenced; decodes as 7 consecutive instructions - code the tracer could not reach | not referenced by any instruction | | `$C91A-$C926` | 13 | - | unreferenced; decodes as 7 consecutive instructions - code the tracer could not reach | not referenced by any instruction | | `$C958-$C96A` | 19 | - | unreferenced; decodes as 10 consecutive instructions - code the tracer could not reach | not referenced by any instruction | | `$C992-$C9D2` | 65 | - | unreferenced; decodes as 35 consecutive instructions - code the tracer could not reach | not referenced by any instruction | | `$CA07-$CF08` | 1282 | - | unreferenced and not decodable as a single structure: a 1282-byte region whose layout was not established from this dump. ROM provenance: it sits between the unreached code at `$C9D3` and the code at `$CF09` | not referenced by any instruction | | `$CF1D-$CF20` | 4 | - | unreferenced; four bytes between the code at `$CF1C` and `$CF21` | not referenced by any instruction | | `$D037-$D04B` | 21 | - | unreferenced; 21 bytes sitting between the code at `$D036` and `$D04C` | not referenced by any instruction | | `$D070-$D07F` | 16 | `StepValueTable` | 16 x 8-bit step sizes: the index is the object's velocity byte masked to four bits, or the byte minus `$F0` when it is `$F0`-`$FF`; the value is stored as the object's step and doubled when the object's flag bit 0 is set | `lda $D070,y` at `$D058` | | `$D0A5-$D0AE` | 10 | `FlagMaskTable` | 10 x 8-bit bit masks OR-ed into an object's flag byte | `ora $D0A5,x` at `$D082`, `ora $D0AA,x` at `$D09F` | | `$D489-$D4A4` | 28 | `ObjectSpeedTable` (`$D489`), `ObjectHeightTable` (`$D497`) | two parallel 14-byte tables indexed by the object's type: movement speed and altitude/height | `lda $D489,y` at `$D47B`, `lda $D497,y` at `$D480` | | `$D716-$D719` | 4 | `ObjectVariantPointerTable` | 2 x 16-bit LE pointers to the two object variants at `$B898` and `$B8B8` | `lda $D716,y` at `$D625` | | `$D744-$D865` | 290 | `EnemyBehaviourPointerTable` | 145 x 16-bit LE dispatch pointers, indexed by the enemy's type byte, reached through `jmp ($10)` at `$D736` | `lda $D744,y` at `$D726`, `lda $D745,y` at `$D72B` | | `$D8F7-$D90A` | 20 | `SpritePlacementTable` | 16-bit LE coordinate/delta values used to place an enemy sprite: `$D8F7-$D8FA` (2 entries), `$D8FB-$D8FE` and `$D903-$D906` (two more offset tables read one entry apart), `$D907-$D90A` (the tail) | `lda $D8F7,y` at `$D8D1`, `lda $D8FB,y` at `$D5DF`, `lda $D8FC,y` at `$D5E5`, `adc $D903,y` at `$D5EE`, `adc $D904,y` at `$D5F6` | | `$DBEB-$FFFF` | 9237 | `ObjectDefinitionRecords` | the stage's object-definition records: a run of variable-length records, each beginning with an object-type byte followed by the 2-byte marker `$67 $68` and the object's parameter bytes. The block is reached indirectly - the base-address table at `$BB79` points into it 256 bytes at a time - so no instruction names an address inside it | not referenced by any instruction (reached indirectly through `ObjectBaseAddressTable` at `$BB79`) | ### Notes on the blocks that are not tables - The nine blocks that "decodes as N consecutive instructions" are code, not data: the tracer never reached them, so they are still emitted as `.byte` rows, but their contents are instructions. They are left unnamed here on purpose; seeding the tracer at the first byte of each would turn them back into routines. - The three one-byte regions at `$8613`, `$861E` and `$AA01` hold `$AE`, `$AE` and `$AC`. They sit between two instructions each and are not the start of any instruction in this dump, so they are stray bytes rather than a table. - `$AF2F-$AF4E` and `$AF8F-$AFAE` are unreferenced byte groups inside a block that also holds the 64-byte nametable row at `$AF4F` and the `"1P-SCORE"` row at `$B0C7`. They may be reached through an indirect address the tracer cannot follow. - `$CA07-$CF08` is the only large region whose layout could not be established from this dump; it is recorded here with its ROM provenance rather than given a speculative name. ## Files | File | Purpose | |------|---------| | `prg.s` | Pass 0 PRG include (replaced by the Pass 1 disassembly) | | `header.s` | iNES header include | | `chr.s` | CHR include | | `prg.bin` | 32768 bytes (32 KB) PRG image | | `chr.bin` | 8192 bytes (8 KB) CHR image | | `rom.nes` | byte-identical copy of the original ROM | | `linker.cfg` | HEADER / PRG / CHR memory areas | | `symbols.inc` | NES hardware register names | | `locals.inc` | zero-page aliases (empty at Pass 0) | | `Makefile` | build and byte-identity check |