update of Circus WIP
start of Pyramid wip
This commit is contained in:
1 parent
9aef410424
commit
3877214637
8 files changed
+17570
-28
No files matched your search
@@ -32,5 +32,6 @@ cd "<Project>/copilot" && make # builds reconstructed.nes, then cmp vs rom.nes
|
||||
- Zero pages are reused across modes; aliases may be required in `locals.inc` (e.g. `RandomStateAlt = $E4` beside `RandomState0 = $54`).
|
||||
- Donkey Kong Jr. is architecturally different: reset entry is $C66E, the reset path idles forever in an LFSR loop, and the entire frame state machine runs inside NMI. Its `DeferredTaskHandlerTable` entry 0 deliberately mirrors the IRQ vector word at $BFFE.
|
||||
- IRQ vectors often point at unused/data targets in these games — verify before assuming a handler is broken.
|
||||
- Unlicensed titles break static-trace assumptions: Pyramid (U) pokes a mapper unlock at `$4100` (beyond the register space) despite a mapper-0 header, and dispatches through `jmp ($0002)` built from RAM — trace via its two queue tables (`$C3A6`, `$CCD5`), and do NOT fall-through-seed gaps that follow `rts`/`jmp`/`brk` (that misclassifies data as code).
|
||||
- ROM filenames contain spaces; builds `incbin` a space-free `rom.nes` inside `copilot/`. Keep that copy/symlink working and don't rename it.
|
||||
- `.gitignore` contains `ROMS/*` but the actual directory is `_ROMS` — the pattern matches nothing, so ROM binaries stay tracked. Check before committing large blobs.
|
||||
+43
-1
@@ -136,7 +136,47 @@ This document provides a consolidated overview of all NES disassembly projects i
|
||||
|
||||
---
|
||||
|
||||
## Skeleton Projects (under `_wip/`)
|
||||
|
||||
25 additional ROMs awaiting full disassembly. Each is set up as a Pass-0 skeleton (`default_project.tar.gz`): `copilot/` contains the split `prg.bin`/`header.bin`/`chr.bin`, a symbolic skeleton `prg.s`, and builds **BYTE-IDENTICAL** at the PRG level. Mapper 0 / 16 KB PRG / 8 KB CHR for all.
|
||||
|
||||
| Project | Vectors (NMI/RESET/IRQ) | Mir. | Status |
|
||||
|---------|--------------------------|------|--------|
|
||||
| `CIRCUS` | $C05A / $C000 / $C4B7 | H | BYTE-IDENTICAL |
|
||||
| `Donkey Kong (JU)` | $C85F / $C79E / $FFF0 | V | BYTE-IDENTICAL |
|
||||
| `Donkey Kong Jr. Math (U)` | $C4A9 / $C41E / $FFF0 | H | BYTE-IDENTICAL |
|
||||
| `Duck Hunt (JUE)` | $C086 / $C000 / $C000 | H | BYTE-IDENTICAL |
|
||||
| `Golf (JU)` | $C0A6 / $C000 / $C0C4 | H | BYTE-IDENTICAL |
|
||||
| `Hogan's Alley (JU)` | $C088 / $C000 / $C000 | H | BYTE-IDENTICAL |
|
||||
| `Ice Climber (JE)` | $C076 / $C014 / $FFF0 | V | BYTE-IDENTICAL |
|
||||
| `Ice Climber (U)` | $C076 / $C014 / $FFF0 | V | BYTE-IDENTICAL |
|
||||
| `Joypad Test Cartridge (U)` | $CCF7 / $C000 / $C000 | H | BYTE-IDENTICAL |
|
||||
| `Lode Runner (U)` | $C02C / $C000 / $FFF9 | H | BYTE-IDENTICAL |
|
||||
| `Lunar Pool (U)` | $FF65 / $E80C / $FF64 | H | BYTE-IDENTICAL |
|
||||
| `MUSCLE (U)` | $86CB / $8000 / $8764 | H | BYTE-IDENTICAL |
|
||||
| `Mario Bros (JU)` | $C07D / $C000 / $C000 | H | BYTE-IDENTICAL |
|
||||
| `Millipede (U)` | $C7F1 / $C735 / $FFF0 | H | BYTE-IDENTICAL |
|
||||
| `NES PowerPad Test Card (U)` | $E06E / $E000 / $E000 | H | BYTE-IDENTICAL |
|
||||
| `Pac-Man (Tengen) (U)` | $C0FA / $C033 / $C16A | V | BYTE-IDENTICAL |
|
||||
| `Pac-Man (U)` | $C0FA / $FF00 / $C16A | V | BYTE-IDENTICAL |
|
||||
| `Pinball (JU)` | $C1ED / $C000 / $C1ED | H | BYTE-IDENTICAL |
|
||||
| `Popeye (JU) (PRG 0)` | $C701 / $C649 / $FFF0 | H | BYTE-IDENTICAL |
|
||||
| `Popeye (JU) (PRG 1)` | $C701 / $C649 / $FFF0 | V | BYTE-IDENTICAL |
|
||||
| `Pyramid (U)` | $D72E / $FF00 / $FF00 | H | **Pass 1 done** — classified code/data, byte-identical; see `_wip/Pyramid (U)/OVERVIEW.md` |
|
||||
| `Raid on Bungeling Bay (U)` | $C04C / $C000 / $C2C0 | H | BYTE-IDENTICAL |
|
||||
| `Raid on Bungeling Bay (U) [a2]` | $C04C / $C000 / $C2C0 | V | BYTE-IDENTICAL |
|
||||
| `Urban Champion (JU)` | $CA91 / $CA00 / $CA00 | H | BYTE-IDENTICAL |
|
||||
| `Wild Gunman (U)` | $C086 / $C000 / $C000 | H | BYTE-IDENTICAL |
|
||||
|
||||
Notable vector/header observations for Pass 1 work:
|
||||
- **Pac-Man (U)** RESET at `$FF00` (vector-page tail), while the Tengen variant RESETs at `$C033` — different builds confirmed (PRG bytes differ).
|
||||
- **MUSCLE (U)** vectors sit in the `$8000-EFFF` window — inconsistent with the `prg.s` skeleton's expected `$C000-$FFFF` mapping; verify the header/image match before Pass 1.
|
||||
- **Lunar Pool (U)** NMI `$FF65` / IRQ `$FF64` are adjacent in the vector page; RESET `$E80C`.
|
||||
- **NES PowerPad Test Card (U)** RESET/IRQ both at `$E000`, far from the usual `$C000`-page entries.
|
||||
- **Ice Climber (JE) vs (U)**: byte-identical PRG *and* header — only the CHR differs (~regional title graphic).
|
||||
- **Popeye (JU) PRG 0 vs PRG 1**: different PRG binaries (and mirroring); same vectors.
|
||||
- **Raid on Bungeling Bay (U) vs [a2]**: `[a2]` differs in mirroring only per header, but PRGs differ — separate builds.
|
||||
- **Pyramid (U)** — *already at Pass 1*: interesting unlicensed Sachen boot ($4100 mapper pokes, "AV" stack-byte check, two queued-event dispatchers). See its `OVERVIEW.md`.
|
||||
|
||||
## Common Patterns Across All Projects
|
||||
|
||||
@@ -206,4 +246,6 @@ All 11 projects in this repository rebuild **byte-identical** to their original
|
||||
| 10 | Donkey Kong 3 (JUE) | BYTE-IDENTICAL |
|
||||
| 11 | Donkey Kong Jr. (JU) | BYTE-IDENTICAL (Pass 1) |
|
||||
|
||||
Every project builds successfully with `make` in the `copilot/` folder, and every reconstructed ROM matches the original byte-for-byte. Donkey Kong Jr. shares the same byte-identical build guarantee; its remaining Pass 2/3 work is semantic renaming and table decoding, not build-correctness.
|
||||
Every project builds successfully with `make` in the `copilot/` folder, and every reconstructed ROM matches the original byte-for-byte. Donkey Kong Jr. shares the same byte-identical build guarantee; its remaining Pass 2/3 work is semantic renaming and table decoding, not build-correctness.
|
||||
|
||||
The 25 `_wip/` skeleton projects above also all rebuild byte-identical (PRG level); all Pass 1 work and promotion to this index's numbered inventory is future work.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
Donkey Kong Jr disassembly project.
|
||||
CIRCUS disassembly project.
|
||||
you will disassemble a NES rom. I will provide you with the skeleton project as a tar.gz file renamed to txt. build the byte identical rom. once you have completed a first pass to identify the code vs the data blocks, stop and provide me with the code. The goal is a byte-identical disassembly. Identify code and data sections. After the first pass, take a second pass and replace the known labels. Pass a third time to better identify use of code and data tables naming more appropriately.
|
||||
|
||||
with code blocks that are generated, each method will have a local and global description, the parameters and the return value(s). for each instruction, include a comment at the end of the line with the offset followed by the actual bytes that are expected to be encoded. during building the byte exact source, include the remaining incbin line so we can cycle through builds quickly and efficently.
|
||||
|
||||
@@ -1,2 +1,161 @@
|
||||
; CIRCUS zero-page aliases (declared during Pass 2).
|
||||
; These intentionally conservative names will be refined in Passes 2 and 3.
|
||||
; CIRCUS application-specific RAM aliases - Pass 2
|
||||
; Generated from a complete static trace of direct zero-page accesses.
|
||||
; ZpXX names indicate confirmed storage with a role not yet unique enough for a behavioral name.
|
||||
|
||||
Zp00 = $00 ; 24 refs; reads=13; writes=14; ClearInternalRamLoop, InitializeVramQueue, RunMainStateDispatcher
|
||||
StateSubstage = $01 ; 14 refs; reads=12; writes=6; SecondaryStateHandlerPointerTable, ContinueStateInitialization, UpdateMenuState_OnNonzero_C237
|
||||
Zp01 = $01 ; indexed structure-field alias
|
||||
StateTimer = $02 ; 21 refs; reads=13; writes=15; InitializeCurrentScreen, UpdateMenuState, FinishStateHandler
|
||||
Zp02 = $02 ; indexed structure-field alias
|
||||
Zp03 = $03 ; 25 refs; reads=18; writes=7; FinishStateHandler_OnZero_C2D2, FinishStateHandler_OnNonnegative_C2EB, FinishStateHandler_OnNonzero_C32D
|
||||
Zp04 = $04 ; 11 refs; reads=7; writes=8; NmiHandler, FinishNmiPpuUpdates, ResetPpuScroll
|
||||
Zp05 = $05 ; 6 refs; reads=4; writes=2; AdvanceRoundTransition_OnZero_C34B, ReadControllers_OnNonzero_C40D, ReadControllers_StoreAndContinue_C444
|
||||
Zp06 = $06 ; 2 refs; reads=1; writes=1; ProcessAudioFrame_JoinBranchPaths_F8AD, DecodeAudioStream_OnNotEqualFD_F902
|
||||
Zp07 = $07 ; 4 refs; reads=2; writes=2; ReadControllers_StoreAndContinue_C444, ProcessAudioFrame_JoinBranchPaths_F8AD, DecodeAudioStream_OnNotEqualFD_F902
|
||||
Zp08 = $08 ; 4 refs; reads=1; writes=3; RequestAudioSequence_OnNonzero_F835, DecodeAudioStream_IncrementAndContinue_F8E1, ExecuteAudioCommand_OnEqual04_FA80
|
||||
ControllerEdgeFlags = $09 ; 22 refs; reads=17; writes=6; RunMainStateDispatcher, UpdateMenuState, ReadControllers_CallNext_C64B
|
||||
Zp09 = $09 ; indexed structure-field alias
|
||||
Zp0A = $0A ; 11 refs; reads=5; writes=6; FinishStateHandler_OnZero_C28F, FinishStateHandler_LoadAndContinue_C2AB, FinishStateHandler_OnNonnegative_C2EB
|
||||
Zp0B = $0B ; 4 refs; reads=2; writes=2; FinishStateHandler_OnNonnegative_C2EB, AdvanceRoundTransition_OnZero_C39A, ExecuteAudioCommand_JoinBranchPaths_FA12
|
||||
Zp0C = $0C ; 16 refs; reads=12; writes=4; DispatchVariantObjectUpdate_OnZero_D82E, DispatchVariantObjectUpdate_JoinBranchPaths_D88A, DispatchVariantObjectUpdate_OnBelow40_D8B7
|
||||
Zp0D = $0D ; 6 refs; reads=5; writes=1; DispatchVariantObjectUpdate_OnZero_DA20, ObjectStateLookupTables_OnNonnegative_F34D, ExecuteAudioCommand_OnZero_F9D1
|
||||
Zp0E = $0E ; 7 refs; reads=2; writes=5; UpdateMenuState_OnZero_C22B, FinishStateHandler_OnNonzero_C31B, ReadControllers_OnNonzero_C40D
|
||||
Zp0F = $0F ; 18 refs; reads=11; writes=9; ReadControllers_JoinBranchPaths_C8E2, DispatchVariantObjectUpdate_JoinBranchPaths_D971, DispatchVariantObjectUpdate_OnEqualF0_D9E6
|
||||
Zp10 = $10 ; 2 refs; reads=1; writes=1; ExecuteAudioCommand_OnNonzero_F99B, ExecuteAudioCommand_OnZero_F9D1
|
||||
Zp12 = $12 ; 1 refs; reads=1; writes=0; SetPaletteRamAddress_OnZero_CA29
|
||||
Zp1E = $1E ; 2 refs; reads=1; writes=1; RequestAudioSequence, RequestAudioSequence_OnZero_F85D
|
||||
Zp23 = $23 ; 1 refs; reads=1; writes=0; SetPaletteRamAddress_LoadAndContinue_CA31
|
||||
Zp2F = $2F ; 4 refs; reads=2; writes=2; RequestAudioSequence, RequestAudioSequence_OnNonzero_F835, RequestAudioSequence_OnEqual08_F867
|
||||
Zp34 = $34 ; 1 refs; reads=1; writes=0; SetPaletteRamAddress_LoadAndContinue_CA31
|
||||
Zp40 = $40 ; 2 refs; reads=1; writes=1; RequestAudioSequence, RequestAudioSequence_JoinBranchPaths_F873
|
||||
Zp45 = $45 ; 1 refs; reads=1; writes=0; SetPaletteRamAddress_LoadAndContinue_CA25
|
||||
Zp4F = $4F ; 2 refs; reads=1; writes=1; RequestAudioSequence, RequestAudioSequence_JoinBranchPaths_F873
|
||||
Zp50 = $50 ; 6 refs; reads=5; writes=2; ReadControllers_LoadAndContinue_C470, ReadControllers_OnNonzero_C480, ReadControllers_OnNonnegative_C591
|
||||
Zp51 = $51 ; 5 refs; reads=2; writes=3; SetupScreenPaletteTransfer_LoadIndexAndContinue_CF58, SetupScreenPaletteTransfer_OnZero_D1DC, SetupScreenPaletteTransfer_LoadIndexAndContinue_D1E4
|
||||
Zp52 = $52 ; 5 refs; reads=5; writes=0; ObjectStateLookupTables_OnCarrySet_E548, ObjectStateLookupTables_JoinBranchPaths_E581, ObjectStateLookupTables_OnNonnegative_EC68
|
||||
PpuCtrlShadow = $53 ; 11 refs; reads=8; writes=3; WriteMaskedPpuControl, InitializeApuAndPpu_LoadAndContinue_C3C1, SetPaletteRamAddress_LoadAndContinue_CA4B
|
||||
PpuMaskShadow = $54 ; 3 refs; reads=1; writes=2; ApplyPpuMaskShadow, SetVisiblePpuMask, ConfigurePpuForScreenTransfer
|
||||
Zp56 = $56 ; 11 refs; reads=6; writes=5; DispatchVariantObjectUpdate_OnNotEqual02_D84A, DispatchVariantObjectUpdate_OnNotEqual03_D86F, DispatchVariantObjectUpdate_OnNonzero_D987
|
||||
Zp59 = $59 ; 1 refs; reads=0; writes=1; ClearInternalRamLoop
|
||||
Zp5F = $5F ; 2 refs; reads=1; writes=1; FinishStateHandler_OnNonzero_C32D
|
||||
Zp60 = $60 ; 3 refs; reads=3; writes=1; FinishStateHandler_OnZero_C28F, AdvanceRoundTransition_OnZero_C34B, ReadControllers_LoadAndContinue_C67B
|
||||
Zp61 = $61 ; 6 refs; reads=4; writes=2; FinishStateHandler_OnZero_C2B2, AdvanceRoundTransition_OnZero_C39A, ReadControllers_LoadAndContinue_C62D
|
||||
CurrentGameVariant = $63 ; 11 refs; reads=10; writes=1; ReadControllers_LoadIndexAndContinue_C835, ReadControllers_OnEqual06_C8C1, SetupScreenPaletteTransfer_LoadAndContinue_CD28
|
||||
Zp64 = $64 ; 13 refs; reads=12; writes=1; ReadControllers_LoadIndexAndContinue_C835, ReadControllers_OnZero_C897, SetupScreenPaletteTransfer_LoadAndContinue_CF0D
|
||||
Zp65 = $65 ; 1 refs; reads=0; writes=1; ReadControllers_JoinBranchPaths_C845
|
||||
Zp66 = $66 ; 8 refs; reads=6; writes=4; AdvanceRoundTransition_OnZero_C34B, ReadControllers_OnZero_C897, ReadControllers_OnOverflowClear_C8B3
|
||||
Zp67 = $67 ; 2 refs; reads=1; writes=2; AdvanceRoundTransition_OnZero_C34B
|
||||
Zp68 = $68 ; 5 refs; reads=4; writes=1; SetupScreenPaletteTransfer_LoadAndContinue_CF0D, DispatchVariantObjectUpdate_LoadAndContinue_DA05, ObjectStateLookupTables_OnZero_E685
|
||||
Zp69 = $69 ; 7 refs; reads=6; writes=1; ReadControllers_OnEqual06_C8C1, SetupScreenPaletteTransfer_LoadAndContinue_CF0D, DispatchVariantObjectUpdate_LoadAndContinue_DA05
|
||||
Zp6A = $6A ; 20 refs; reads=16; writes=4; ReadControllers_JoinBranchPaths_C8E2, SetPaletteRamAddress_LoadAndContinue_CC20, SetPaletteRamAddress_OnNonzero_CC40
|
||||
Zp6B = $6B ; 17 refs; reads=12; writes=7; ReadControllers_JoinBranchPaths_C8B5, ReadControllers_OnEqual06_C8C1, ReadControllers_OnAtLeast02_C8D7
|
||||
Zp6C = $6C ; 4 refs; reads=1; writes=4; ObjectStateLookupTables_LoadAndContinue_E5B0, ObjectStateLookupTables_OnNonnegative_EC68, ObjectStateLookupTables_OnNonnegative_EC89
|
||||
Zp6D = $6D ; 9 refs; reads=7; writes=8; ReadControllers_JoinBranchPaths_C8B5, InitializeRoundParameters, ObjectStateLookupTables_OnZero_E659
|
||||
Zp6E = $6E ; 4 refs; reads=1; writes=3; FinishStateHandler_OnNonnegative_C2EB, AdvanceRoundTransition_OnZero_C34B, AdvanceRoundTransition_OnZero_C382
|
||||
Zp6F = $6F ; 2 refs; reads=1; writes=1; ReadControllers_LoadAndContinue_C889
|
||||
Zp70 = $70 ; 28 refs; reads=18; writes=10; ObjectStateLookupTables_JoinBranchPaths_E64C, ObjectStateLookupTables_OnBelow08_E667, ObjectStateLookupTables_OnNonzero_E7A9
|
||||
Zp71 = $71 ; 7 refs; reads=5; writes=2; ObjectStateLookupTables_OnZero_E685, ObjectStateLookupTables_OnZero_E814, ObjectStateLookupTables_LoadAndContinue_E82C
|
||||
Zp72 = $72 ; 4 refs; reads=1; writes=3; ObjectStateLookupTables_OnZero_E693, ObjectStateLookupTables_OnZero_EA68, ObjectStateLookupTables_LoadIndexAndContinue_F2DB
|
||||
Zp73 = $73 ; 34 refs; reads=21; writes=13; SetPaletteRamAddress_LoadAndContinue_CC6C, DispatchVariantObjectUpdate_OnZero_DA3E, DispatchVariantObjectUpdate_OnNonzero_DA76
|
||||
Zp74 = $74 ; 56 refs; reads=41; writes=23; SetPaletteRamAddress_LoadAndContinue_CC6C, DispatchVariantObjectUpdate_OnNotEqual02_D84A, DispatchVariantObjectUpdate_OnNotEqual03_D86F
|
||||
Zp75 = $75 ; 6 refs; reads=3; writes=3; ObjectStateLookupTables_JoinBranchPaths_E823, ObjectStateLookupTables_OnNonzero_E8A8, ObjectStateLookupTables_OnAtLeast04_EB7B
|
||||
Zp76 = $76 ; 30 refs; reads=9; writes=21; DispatchVariantObjectUpdate_JoinBranchPaths_DAB3, DispatchVariantObjectUpdate_StoreAndContinue_DADA, DispatchVariantObjectUpdate_OnCarrySet_DAE4
|
||||
Zp77 = $77 ; 69 refs; reads=33; writes=37; SetPaletteRamAddress_LoadAndContinue_CC16, SetPaletteRamAddress_LoadAndContinue_CC20, SetPaletteRamAddress_OnNonzero_CC40
|
||||
Zp78 = $78 ; 22 refs; reads=9; writes=13; SetPaletteRamAddress_LoadAndContinue_CC16, SetPaletteRamAddress_LoadAndContinue_CC20, SetupScreenPaletteTransfer_LoadAndContinue_CEE5
|
||||
Zp79 = $79 ; 28 refs; reads=17; writes=18; ReadControllers_JoinBranchPaths_C845, ReadControllers_OnNonzero_C861, SetupScreenPaletteTransfer_LoadAndContinue_D1E8
|
||||
Zp7A = $7A ; 17 refs; reads=8; writes=9; SetPaletteRamAddress_LoadAndContinue_CC20, SetupScreenPaletteTransfer_LoadAndContinue_D1E8, SetupScreenPaletteTransfer_OnNonzero_D206
|
||||
Zp7B = $7B ; 27 refs; reads=14; writes=15; SetupScreenPaletteTransfer_OnZero_D21D, SetupScreenPaletteTransfer_OnZero_D255, SetupScreenPaletteTransfer_OnNonzero_D270
|
||||
WorkPointer0Lo = $7C ; 24 refs; reads=14; writes=10; ReadControllers_OnNonzero_C861, SetupScreenPaletteTransfer_CallNext_CEB7, SetupScreenPaletteTransfer_CallNext_D1C4
|
||||
Zp7C = $7C ; indexed structure-field alias
|
||||
WorkPointer0Hi = $7D ; 10 refs; reads=2; writes=9; ReadControllers_OnNonzero_C861, ReadControllers_OnNonzero_C87C, SetupScreenPaletteTransfer_CallNext_CEB7
|
||||
Zp7D = $7D ; indexed structure-field alias
|
||||
WorkPointer1Lo = $7E ; 12 refs; reads=4; writes=8; SetPaletteRamAddress_LoadAndContinue_CBE4, SetupScreenPaletteTransfer_LoadAndContinue_D1E8, SetupScreenPaletteTransfer_OnNonzero_D206
|
||||
Zp7E = $7E ; indexed structure-field alias
|
||||
WorkPointer1Hi = $7F ; 17 refs; reads=10; writes=11; SetPaletteRamAddress_LoadAndContinue_CBE4, SetupScreenPaletteTransfer_LoadAndContinue_D1E8, SetupScreenPaletteTransfer_OnNonzero_D206
|
||||
Zp7F = $7F ; indexed structure-field alias
|
||||
Zp80 = $80 ; 9 refs; reads=2; writes=7; ReadControllers_OnNonzero_C861, DispatchVariantObjectUpdate_OnCarrySet_D9AB, DispatchVariantObjectUpdate_OnNonzero_D9C4
|
||||
Zp81 = $81 ; 2 refs; reads=0; writes=2; ObjectStateLookupTables_OnZero_E685, ObjectStateLookupTables_LoadIndexAndContinue_F2DB
|
||||
Zp82 = $82 ; 2 refs; reads=0; writes=2; ObjectStateLookupTables_OnZero_E693, ObjectStateLookupTables_LoadIndexAndContinue_F2DB
|
||||
Zp83 = $83 ; 7 refs; reads=3; writes=4; DispatchVariantObjectUpdate_OnZero_DA3E, DispatchVariantObjectUpdate_JoinBranchPaths_DAB3, DispatchVariantObjectUpdate_OnCarrySet_DAE4
|
||||
Zp84 = $84 ; 17 refs; reads=13; writes=10; DispatchVariantObjectUpdate_OnNotEqual03_D91A, DispatchVariantObjectUpdate_OnNotEqual03_D93D, DispatchVariantObjectUpdate_OnCarrySet_D9AB
|
||||
Zp86 = $86 ; 5 refs; reads=0; writes=5; DispatchVariantObjectUpdate_JoinBranchPaths_DAB3, DispatchVariantObjectUpdate_OnEqual00_DC1B, DispatchVariantObjectUpdate_OnEqual03_DC21
|
||||
Zp87 = $87 ; 9 refs; reads=5; writes=4; ObjectStateLookupTables_LoadAndContinue_EE5F, ObjectStateLookupTables_OnNonzero_EEBB, ObjectStateLookupTables_LoadAndContinue_F342
|
||||
Zp88 = $88 ; 1 refs; reads=1; writes=0; ObjectStateLookupTables_OnZero_F356
|
||||
Zp89 = $89 ; 2 refs; reads=1; writes=1; ProcessQueuedVramUpdates_LoadAndContinue_D2FD, ExecuteVramDescriptorStream
|
||||
Zp8A = $8A ; 2 refs; reads=1; writes=1; ExecuteVramDescriptorStream, ExecuteVramDescriptorStream_OnNonzero_D35F
|
||||
Zp8B = $8B ; 2 refs; reads=1; writes=1; SetupScreenPaletteTransfer_OnZero_D255, ObjectStateLookupTables_StoreIndexAndContinue_ED26
|
||||
Zp8C = $8C ; 22 refs; reads=9; writes=13; SetPaletteRamAddress_LoadAndContinue_CBE4, SetPaletteRamAddress_LoadAndContinue_CC6C, SetupScreenPaletteTransfer_LoadAndContinue_D1E8
|
||||
Zp8D = $8D ; 3 refs; reads=2; writes=1; SetPaletteRamAddress_LoadAndContinue_CBE4, SetPaletteRamAddress_LoadAndContinue_CC62, ObjectStateLookupTables_OnNonzero_F5D8
|
||||
Zp8E = $8E ; 11 refs; reads=5; writes=6; SetPaletteRamAddress_LoadAndContinue_CBE4, SetPaletteRamAddress_LoadAndContinue_CC6C, SetupScreenPaletteTransfer_LoadAndContinue_D1E8
|
||||
Zp8F = $8F ; 4 refs; reads=2; writes=2; SetPaletteRamAddress_LoadAndContinue_CC62, SetupScreenPaletteTransfer_CallNext_D1C4, ObjectStateLookupTables_OnNonnegative_E905
|
||||
Zp90 = $90 ; 4 refs; reads=3; writes=2; ObjectStateLookupTables_LoadAndContinue_E61D, ObjectStateLookupTables_LoadAndContinue_F08C, ObjectStateLookupTables_OnZero_F09E
|
||||
Zp91 = $91 ; 2 refs; reads=1; writes=1; ObjectStateLookupTables_LoadIndexAndContinue_F0A8, ObjectStateLookupTables_OnNonzero_F155
|
||||
Zp92 = $92 ; 3 refs; reads=3; writes=2; ObjectStateLookupTables_LoadAndContinue_EFC7, ObjectStateLookupTables_OnEqual02_EFDC
|
||||
Zp94 = $94 ; 3 refs; reads=2; writes=1; ObjectStateLookupTables_LoadAndContinue_EFC7, ObjectStateLookupTables_OnEqual02_EFDC
|
||||
Zp98 = $98 ; 3 refs; reads=2; writes=2; ObjectStateLookupTables_OnZero_E5D1, ObjectStateLookupTables_JoinBranchPaths_E618
|
||||
Zp9A = $9A ; 2 refs; reads=1; writes=1; ObjectStateLookupTables_LoadAndContinue_E7BA
|
||||
Zp9B = $9B ; 6 refs; reads=3; writes=4; ReadControllers_JoinBranchPaths_C8E2, ObjectStateLookupTables_LoadIndexAndContinue_E484, ObjectStateLookupTables_JoinBranchPaths_E4AA
|
||||
Zp9C = $9C ; 2 refs; reads=1; writes=1; ObjectStateLookupTables_LoadIndexAndContinue_E521, ObjectStateLookupTables_OnNonzero_E86C
|
||||
Zp9D = $9D ; 2 refs; reads=2; writes=1; ObjectStateLookupTables_LoadAndContinue_E509
|
||||
ZpA7 = $A7 ; 3 refs; reads=1; writes=3; ObjectStateLookupTables_OnNonzero_EEBB, ObjectStateLookupTables_LoadAndContinue_F08C, ObjectStateLookupTables_OnZero_F09E
|
||||
ZpA8 = $A8 ; 4 refs; reads=2; writes=2; ObjectStateLookupTables_LoadAndContinue_F08C, ObjectStateLookupTables_OnZero_F09E, ObjectStateLookupTables_OnCarryClear_F141
|
||||
ZpAA = $AA ; 3 refs; reads=3; writes=1; ObjectStateLookupTables_OnBelow08_F672, ObjectStateLookupTables_OnCarryClear_F693, ObjectStateLookupTables_OnEqualFF_F6B6
|
||||
ZpAB = $AB ; 3 refs; reads=2; writes=2; ReadControllers_JoinBranchPaths_C8B5, ReadControllers_JoinBranchPaths_C8D9, ObjectStateLookupTables_OnCarrySet_F44E
|
||||
ZpAD = $AD ; 5 refs; reads=4; writes=3; ReadControllers_JoinBranchPaths_C8B5, ObjectStateLookupTables_OnBelow08_F672, ObjectStateLookupTables_JoinBranchPaths_F6E3
|
||||
ZpAE = $AE ; 2 refs; reads=1; writes=1; ObjectStateLookupTables_JoinBranchPaths_F4F5, ObjectStateLookupTables_LoadAndContinue_F540
|
||||
ZpAF = $AF ; 5 refs; reads=2; writes=3; DispatchVariantObjectUpdate_JoinBranchPaths_D971, ObjectStateLookupTables_OnCarrySet_F131, ObjectStateLookupTables_JoinBranchPaths_F495
|
||||
ZpB0 = $B0 ; 2 refs; reads=1; writes=1; ObjectStateLookupTables_OnNotEqual40_E62D, ObjectStateLookupTables_OnBelow01_F6DD
|
||||
ZpB3 = $B3 ; 3 refs; reads=1; writes=2; ObjectStateLookupTables_LoadIndexAndContinue_EED9, ObjectStateLookupTables_OnZero_EEFF, ObjectStateLookupTables_OnAtLeastA4_EF3D
|
||||
ZpB8 = $B8 ; 6 refs; reads=2; writes=4; ReadControllers_JoinBranchPaths_C8E2, DispatchVariantObjectUpdate_JoinBranchPaths_D971, DispatchVariantObjectUpdate_OnEqualF0_D9E6
|
||||
ZpBE = $BE ; 5 refs; reads=3; writes=3; DispatchVariantObjectUpdate_OnNonzero_DA76, ObjectStateLookupTables_LoadAndContinue_EE5F, ObjectStateLookupTables_JoinBranchPaths_EE86
|
||||
ZpBF = $BF ; 5 refs; reads=5; writes=2; DispatchVariantObjectUpdate_OnZero_D912, DispatchVariantObjectUpdate_OnNotEqual02_D935, ObjectStateLookupTables_LoadAndContinue_EE0A
|
||||
ZpC0 = $C0 ; 1 refs; reads=0; writes=1; ObjectStateLookupTables_OnBelow01_F6DD
|
||||
ZpC5 = $C5 ; 1 refs; reads=1; writes=0; ReadControllers_CallNext_C64B
|
||||
ZpC6 = $C6 ; 1 refs; reads=1; writes=1; ReadControllers_CallNext_C64B
|
||||
ZpC7 = $C7 ; 3 refs; reads=2; writes=1; ObjectStateLookupTables_OnCarrySet_F44E, ObjectStateLookupTables_OnZero_F4BE, ObjectStateLookupTables_OnNonnegative_F5CD
|
||||
ZpC9 = $C9 ; 6 refs; reads=3; writes=3; DispatchVariantObjectUpdate_OnZero_D887, DispatchVariantObjectUpdate_OnNonzero_D945, DispatchVariantObjectUpdate_OnCarryClear_D959
|
||||
ZpCA = $CA ; 13 refs; reads=7; writes=6; DispatchVariantObjectUpdate_JoinBranchPaths_D885, DispatchVariantObjectUpdate_OnCarryClear_D8AF, DispatchVariantObjectUpdate_OnCarryClear_D8D7
|
||||
ZpCB = $CB ; 4 refs; reads=2; writes=3; DispatchVariantObjectUpdate_OnNonzero_DA60, DispatchVariantObjectUpdate_OnNonzero_DA76, ObjectStateLookupTables_OnNonnegative_F0BD
|
||||
ZpCC = $CC ; 2 refs; reads=1; writes=1; UpdateMenuSelection_LoadAndContinue_D5DF, ObjectStateLookupTables_JoinBranchPaths_DCE6
|
||||
ZpCD = $CD ; 6 refs; reads=3; writes=4; ReadControllers_JoinBranchPaths_C8E2, DispatchVariantObjectUpdate_OnCarryClear_D959, DispatchVariantObjectUpdate_OnZero_DA19
|
||||
ZpCE = $CE ; 6 refs; reads=2; writes=4; DispatchVariantObjectUpdate_JoinBranchPaths_D839, DispatchVariantObjectUpdate_OnZero_D858, DispatchVariantObjectUpdate_OnZero_D87F
|
||||
ZpCF = $CF ; 2 refs; reads=1; writes=2; ReadControllers_JoinBranchPaths_C8E2, ObjectStateLookupTables_LoadAndContinue_F601
|
||||
ZpD0 = $D0 ; 5 refs; reads=3; writes=2; ObjectStateLookupTables_OnNonzero_E86C, ObjectStateLookupTables_OnZero_E8E9, ObjectStateLookupTables_OnZero_E9B3
|
||||
ZpD1 = $D1 ; 1 refs; reads=0; writes=1; ObjectStateLookupTables_OnNonnegative_E980
|
||||
ZpD2 = $D2 ; 3 refs; reads=3; writes=2; ObjectStateLookupTables_JoinBranchPaths_F267, ObjectStateLookupTables_JoinBranchPaths_F2A0, ObjectStateLookupTables_OnZero_F356
|
||||
ZpD3 = $D3 ; 5 refs; reads=4; writes=3; ObjectStateLookupTables_JoinBranchPaths_F474, ObjectStateLookupTables_LoadIndexAndContinue_F479, ObjectStateLookupTables_OnCarrySet_F4BB
|
||||
ZpD4 = $D4 ; 1 refs; reads=0; writes=1; ObjectStateLookupTables_OnEqualFE_E9A9
|
||||
ZpD5 = $D5 ; 4 refs; reads=3; writes=2; ObjectStateLookupTables_OnCarrySet_F44E, ObjectStateLookupTables_CallNext_F5C6, ObjectStateLookupTables_OnNonnegative_F5CD
|
||||
ZpD6 = $D6 ; 3 refs; reads=1; writes=2; ObjectStateLookupTables_OnCarrySet_F44E, ObjectStateLookupTables_LoadIndexAndContinue_F479, ObjectStateLookupTables_JoinBranchPaths_F495
|
||||
ZpD7 = $D7 ; 2 refs; reads=1; writes=1; ObjectStateLookupTables_LoadAndContinue_F540
|
||||
ZpD9 = $D9 ; 4 refs; reads=0; writes=4; ReadControllers_OnNonnegative_C900, ObjectStateLookupTables_OnEqual20_E8CD, ObjectStateLookupTables_OnNonzero_EBE7
|
||||
ZpDB = $DB ; 1 refs; reads=0; writes=1; ObjectStateLookupTables_OnNonzero_E849
|
||||
ZpDE = $DE ; 10 refs; reads=5; writes=5; ReadControllers_JoinBranchPaths_C8E2, DispatchVariantObjectUpdate_LoadIndexAndContinue_D824, DispatchVariantObjectUpdate_OnNonzero_D8E4
|
||||
ZpDF = $DF ; 18 refs; reads=15; writes=4; ReadControllers_JoinBranchPaths_C8E2, DispatchVariantObjectUpdate_OnCarrySet_D820, DispatchVariantObjectUpdate_JoinBranchPaths_D88A
|
||||
IndirectPointerLo = $E0 ; 13 refs; reads=1; writes=12; ClearUpperRamPages, SelectNametableClearPage_OnNonzero_C3E2, ReadControllers_LoadIndexAndContinue_C4BA
|
||||
IndirectPointerHi = $E1 ; 14 refs; reads=3; writes=13; ClearUpperRamPages, ClearUpperRamPageLoop, SelectNametableClearPage_OnNonzero_C3E2
|
||||
TransferByteCount = $E2 ; 7 refs; reads=3; writes=7; SelectNametableClearPage_OnNonzero_C3E2, ClearPpuPage_OnNonzero_C3FA, ReadControllers_OnNonzero_C4AF
|
||||
ZpE3 = $E3 ; 3 refs; reads=1; writes=3; ReadControllers_OnCarryClear_C4EA, ReadControllers_LoadAndContinue_C67B, ReadControllers_OnNonnegative_C68D
|
||||
Controller1Shift = $E4 ; 10 refs; reads=6; writes=5; ReadControllers_OnNonzero_C40D, ReadControllers_StoreAndContinue_C444, ReadControllers_OnNonzero_C454
|
||||
ZpE4 = $E4 ; indexed structure-field alias
|
||||
Controller2Shift = $E5 ; 4 refs; reads=2; writes=3; ReadControllers_OnNonzero_C40D, ReadControllers_OnNonzero_C454, ReadControllers_OnCarryClear_C4EA
|
||||
ControllerReadScratch = $E7 ; 4 refs; reads=2; writes=2; ReadControllers_OnNonzero_C40D
|
||||
ZpE8 = $E8 ; 3 refs; reads=2; writes=1; ReadControllers_StoreIndexAndContinue_C6F3, ReadControllers_OnBelow0A_C70D
|
||||
ZpEE = $EE ; 4 refs; reads=2; writes=2; ReadControllers_StoreIndexAndContinue_C6F3, ReadControllers_OnBelow0A_C70D
|
||||
ZpEF = $EF ; 7 refs; reads=4; writes=4; ReadControllers_LoadAndContinue_C5B2, ReadControllers_OnNonnegative_C5B6, ReadControllers_StoreIndexAndContinue_C6F3
|
||||
ZpF0 = $F0 ; 8 refs; reads=4; writes=6; DecodeAudioStream_OnZero_F962, ExecuteAudioCommand_OnNotEqualE0_FA23, ExecuteAudioCommand_OnNonzero_FA32
|
||||
ZpF1 = $F1 ; 4 refs; reads=2; writes=3; DecodeAudioStream_OnZero_F962, ExecuteAudioCommand_OnNotEqual0C_FA62, ExecuteAudioCommand_JumpNext_FA73
|
||||
ZpF2 = $F2 ; 1 refs; reads=0; writes=1; RequestAudioSequence_OnNonzero_F835
|
||||
ZpF3 = $F3 ; 1 refs; reads=0; writes=1; RequestAudioSequence_OnNonzero_F835
|
||||
AudioChannelStructOffset = $F4 ; 8 refs; reads=7; writes=1; ProcessAudioFrame_OnCarryClear_F880, ProcessAudioFrame_OnZero_F88B, DecodeAudioStream_OnZero_F921
|
||||
AudioApuRegisterOffset = $F5 ; 14 refs; reads=13; writes=1; ProcessAudioFrame_OnCarryClear_F880, ProcessAudioFrame_OnNotEqual54_F895, ProcessAudioFrame_OnNonnegative_F89E
|
||||
AudioSequencePointerLo = $F6 ; 5 refs; reads=4; writes=2; ProcessAudioFrame_JoinBranchPaths_F8AD, DecodeAudioStream, ExecuteAudioCommand_OnNotEqual08_F981
|
||||
AudioSequencePointerHi = $F7 ; 4 refs; reads=3; writes=2; ProcessAudioFrame_JoinBranchPaths_F8AD, DecodeAudioStream, ExecuteAudioCommand_OnNotEqual08_F981
|
||||
SavedObjectIndex = $F8 ; 7 refs; reads=4; writes=3; SetPaletteRamAddress_StoreIndexAndContinue_CC7E, SetPaletteRamAddress_OnCarryClear_CC8C, SetPaletteRamAddress_StoreIndexAndContinue_CC8F
|
||||
SavedObjectSlot = $F9 ; 21 refs; reads=14; writes=7; SetPaletteRamAddress_StoreIndexAndContinue_CB2D, SetPaletteRamAddress_JoinBranchPaths_CB4B, ObjectStateLookupTables_OnNonzero_E601
|
||||
SavedTransferIndex = $FA ; 8 refs; reads=4; writes=4; UpdateMenuSelection_OnZero_D627, UpdateMenuSelection_OnNonzero_D62B, ObjectStateLookupTables_LoadAndContinue_E562
|
||||
NmiDelayCounter = $FB ; 3 refs; reads=2; writes=2; NmiHandler, ReadControllers_LoadAndContinue_C4C8
|
||||
ZpFF = $FF ; 2 refs; reads=1; writes=1; FinishStateHandler_OnNonzero_C32D
|
||||
|
||||
MenuSelectionIndex = $0302
|
||||
VariantSequenceCounter = $03B0
|
||||
+12748
-5
File diff suppressed because it is too large.
Load diff
@@ -1,7 +1,6 @@
|
||||
# Pyramid (U) — Skeleton Project
|
||||
|
||||
ROM: `_wip/Pyramid (U)/Pyramid (U) (Sachen).nes` (24,592 bytes, iNES). Status: **SKELETON — not yet disassembled.** The entire 16 KB PRG bank is a single unclassified block; `copilot/prg.s` is the default-project skeleton (`default_project.tar.gz`) that reproduces it as one `.incbin`. The skeleton build is **byte-identical** at the PRG level.
|
||||
# Pyramid (U) — Pass 1
|
||||
|
||||
ROM: `_wip/Pyramid (U)/Pyramid (U) (Sachen).nes` (24,592 bytes, iNES). Status: **PASS 1 — code/data split complete, byte-identical.** 5,834 of 16,384 PRG bytes (35.6%) are classified as traced 6502 code (396 labels, 70 distinct `jsr` targets); everything else is explicit `.byte` data with per-line PRG-offset annotations. `make` → `cmp reconstructed_prg.bin prg.bin` → **BYTE-IDENTICAL**.
|
||||
|
||||
## ROM Facts
|
||||
|
||||
@@ -19,9 +18,68 @@ ROM: `_wip/Pyramid (U)/Pyramid (U) (Sachen).nes` (24,592 bytes, iNES). Status: *
|
||||
|
||||
| Vector | Target | Note |
|
||||
|--------|--------|------|
|
||||
| NMI | `$D72E` | per-frame heartbeat |
|
||||
| RESET | `$FF00` | initial execution at $FF00, inside the last PRG page — unusual; PASS 1 should confirm the true cold-start path |
|
||||
| IRQ | `$FF00` | redirects to RESET — unused placeholder |
|
||||
| NMI | `$D72E` | normal per-frame engine entry (waits PPU, runs frame state, drives APU silence/queue) |
|
||||
| RESET | `$FF00` | real cold-start code — see boot chain below |
|
||||
| IRQ | `$FF00` | redirects to RESET target; `sei` at boot, no `cli` seen on the traced path — IRQ likely never fires |
|
||||
|
||||
## Boot chain (all statically traced from `$FF00`)
|
||||
|
||||
1. `ldx #$FF / txs / sei / cld`, clear PPUCTRL/PPUMASK.
|
||||
2. Repeated `LDA #<val> / JSR $FF49` — `$FF49` does **`STA $4100`** (write beyond the NES register space, $4000–$4017) followed by a long delay loop ($CE×256-ish iterations ×4 outer). The header claims mapper 0, but on the real Sachen cart these `$4100` pokes are an mapper-unlock/protection sequence. Boot pokes `$30`, `$10/$30/$10+$30` (via `$FF4C` delay variant twice) or `$20/$30/$20` depending on a check.
|
||||
3. `JSR $FF57` — reads stack page bytes `$0120`/`$0121` and compares against `$41`/`$56` ("A","V"). `SEC` ⇒ proceeds to the `$4100` poke sequence above; `CLC` ⇒ alternate poke sequence, then falls into:
|
||||
4. `JSR $FF69` — seeds `$0120`/`$0121` with `$41`/`$56`.
|
||||
5. `JMP $C800` — real init: waits two `$2002` vblank phases, clears `$0000-$07FF`, builds ZP pointer `$D7/$D8 = $C8xx`, zeroes `$00`, writes `$98` to PPUCTRL / `$1A` to PPUMASK.
|
||||
|
||||
`$FF74-$FF7C` (`LDA #$00 / STA $0120 / STA $0121 / RTS`) clears the checker bytes; never called from static paths — emitted as data in the tail block.
|
||||
|
||||
## Dispatcher architecture (two queue + `jmp ($0002)` dispatchers)
|
||||
|
||||
The engine is the classic *queued-task* pattern (same family as the repo's Burger Time / DK Jr. analysis):
|
||||
|
||||
| Dispatcher | Site | Pointer | Vector table | Entries |
|
||||
|-----------|------|---------|--------------|---------|
|
||||
| 1 | `$C3A3` | `$0002/$0003` | `$C3A6` | 9: `$C3B6 $C3C7 $C3FD $C35F $C3E3 $C3E7 $C3EB $C3EF $D820` |
|
||||
| 2 | `$CCCA` | `$0002/$0003` | `$CCD5` | 8: `$CCEE $CD27 $CC90 $CD75 $CD43 $CDA4 $CE1A $CE5E` |
|
||||
|
||||
Both build the pointer with the `TXA / ASL / TAX / LDA $tbl,X / STA $02 / LDA $tbl+1,X / STA $03 / LDX $45 / LDY $46 / jmp ($0002)` idiom; dispatcher 2 additionally copies an 8-byte low-value table from `$CCCD,X` into `$04EA,X` and syncs `$0430/$0431` (X/Y "cursor" state) before the jump. The `jmp ($0002)` sites terminate static traces; the tail at `$CCEB` (`jsr $D2BF / jsr $D476 / jmp $CC90`) re-queues into dispatcher 2.
|
||||
|
||||
**Pass-1 candidates not statically resolvable** (emitted as code where entered only via runtime dispatch, documented for Pass 2 review): `$D7EB` (`EA EA A2 FF 9A / jmp $D655` — alternate cold-start stub, caller unknown), `$C201` (PPUCTRL/PPUMASK setup helper + OAM-buffer splitters, fall-through of the `$2002` wait loop at `$C1F6-$C200`), `$C43E` (division/multiply-style arithmetic helper entered after `rts` at `$C43D`).
|
||||
|
||||
## Code coverage summary (final Pass-1 state)
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Code bytes traced | 5,834 / 16,384 (35.6%) |
|
||||
| Labels | 396 |
|
||||
| Distinct `jsr` targets | 70 |
|
||||
| Data/gap bytes | 10,550 (64.4%) |
|
||||
| Indirect `jmp ($0002)` sites | 2 (both queue dispatchers) |
|
||||
|
||||
Regions entered only via runtime dispatch (queue-table targets) are traced; remaining unreached bytes sit in the data map below.
|
||||
|
||||
## Data map (unreached bytes, all provenance-checked)
|
||||
|
||||
| Region | Size | Content evidence |
|
||||
|--------|------|------------------|
|
||||
| `$C201-$C2FF` tail ($C225-$C2FF) | 219 | zero padding after the PPU-setup helpers |
|
||||
| `$C34A-$C35E` | 21 | data after the dispatcher-1 `jmp ($0002)` tail |
|
||||
| `$C3A6-$C3B7` | 18 | dispatcher-1 vector table (9 words) |
|
||||
| `$C585-$C7FF` | 635 | text/marker tables (tile-index values `$88 $20 $88 $C1`; zero-padded from `$C714`) |
|
||||
| `$C95A-$C9A6`, `$CAAA-$CAF2`, `$CBC1-$CBDB` | 177 | tile-index/lookup tables read via `lda $tbl,X` |
|
||||
| `$CCCD-$CCE4` | 24 | dispatcher-2 low-byte table (8) + vector table (8 words) |
|
||||
| `$D021-$D029` | 9 | brightness ramp `$0F $14 $28 $3C $50 $64` |
|
||||
| `$D1AA-$D1B1`, `$D2AB-$D2BE` | 28 | small pointer/value tables |
|
||||
| `$D320-$D3A0` | 129 | per-level byte tables (`$01 $02 $01 $02 ... $00 $08`) |
|
||||
| `$D467-$D475`, `$D4EE-$D509`, `$D556-$D56A`, `$D5D5-$D631` | 146 | pointer/value pools read via `lda $tbl,X` / `adc` arithmetic |
|
||||
| `$D69C-$D6AB` | 16 | value ramp `$27 $29 $2B $2D ...` |
|
||||
| `$D79D-$D7E2` | 37 | small tables flanking the NMI handler |
|
||||
| `$D7F3-$DE99` | 1,703 | packed level data (`$22 $2F`-patterned runs after the `$D7EB` stub) |
|
||||
| `$DEBB-$DECA` | 16 | table |
|
||||
| `$DF3E-$DF7F` | 80 | music frequency table (`$C3 $EC $6A $ED ...`) |
|
||||
| `$E276-$ED6D` | 2,808 | audio pool: instrument/envelope ramps (`$FA $A8 $80 $3C ...` declining) + APU-register data |
|
||||
| `$EDBF-$F890` | 2,770 | audio/graphics bulk tables + large `$00` runs (incl. `$F07F-$F890` padding) |
|
||||
| `$F942-$FEFF` | 1,470 | mostly zeros — padding, save for small tables near `$FA00` |
|
||||
| `$FF74-$FFF9` | 134 | tail: clear-checker bytes + pure zeros up to the vector page |
|
||||
|
||||
## `copilot/` Contents
|
||||
|
||||
@@ -29,14 +87,15 @@ ROM: `_wip/Pyramid (U)/Pyramid (U) (Sachen).nes` (24,592 bytes, iNES). Status: *
|
||||
|------|---------|
|
||||
| `Pyramid (U) (Sachen).nes` | original ROM image (reference) |
|
||||
| `prg.bin` / `header.bin` / `chr.bin` | split image, produced by `_tools/splitnes.py` |
|
||||
| `prg.s` | Pass-1 skeleton: `.incbin "prg.bin", $0000, $4000` (whole PRG) |
|
||||
| `symbols.inc` | shared NES hardware constants (PPU/APU/controller, from the skeleton) |
|
||||
| `locals.inc` | project-local zero-page aliases — empty for now (filled in Pass 2) |
|
||||
| `prg.s` | Pass-1 classified source: traced code + explicit `.byte` data, `; PRG:$xxxx AA BB` per line |
|
||||
| `symbols.inc` | shared NES hardware constants (PPU/APU/controller) |
|
||||
| `locals.inc` | project-local zero-page aliases — still empty (filled in Pass 2) |
|
||||
| `linker.cfg` | PRG at $C000, 16 KB, `fill = yes` |
|
||||
| `Makefile` | links `reconstructed_prg.bin` and `cmp`s it against `prg.bin` |
|
||||
| `reconstructed_prg.bin` | build output from the last verified build |
|
||||
| `prg.s.skeleton` | backup of the pre-classification skeleton (`.incbin`-only) source |
|
||||
|
||||
Header/CHR are reproduced verbatim from `header.bin`/`chr.bin` (not linked): `make` verifies **PRG bytes only** at this stage, which is exactly what a skeleton proves. When this project is promoted to a full disassembly, `header.s` / `chr.s` (as e.g. `Burger Time (U)`) and a full-ROM `make` target get added.
|
||||
Header/CHR are reproduced verbatim from `header.bin`/`chr.bin` (not linked): `make` verifies **PRG bytes only** at this stage, exactly like every other `_wip/` skeleton. When this project is promoted to a top-level full disassembly, `header.s` / `chr.s` and a full-ROM `make` target (cf. `Burger Time (U)`) get added.
|
||||
|
||||
## Build
|
||||
|
||||
@@ -47,7 +106,7 @@ make # → cmp reconstructed_prg.bin prg.bin → "BYTE-IDENTICAL"
|
||||
|
||||
## Next Steps (per `PROMPTS.md`)
|
||||
|
||||
1. **Pass 1** — replace the blanket `.incbin` with classified code/data: trace reachability from RESET ($FF00) and NMI ($D72E), emit per-instruction `; PRG:$xxxx AA BB` annotations, keep unreached bytes as explicit `.byte` blocks.
|
||||
2. **Pass 2** — replace `Label_`/`Sub_` names with semantic routine names; fill `locals.inc`.
|
||||
3. **Pass 3** — name data tables/structures; release provisional flags.
|
||||
4. **Promotion** — move to a top-level `<name>/copilot/` folder, add full-ROM build (header.s + chr.s + vectors), and write the power-on flow `OVERVIEW.md` in the established style; then it joins the root index's numbered inventory.
|
||||
1. **Pass 1 — DONE.** Code/data split, `; PRG:$xxxx AA BB` audit annotations on every line, byte-identical build.
|
||||
2. **Pass 2** — semantic names: `BootUnlock`, `StackByteCheck`, `QueueDispatch1/2`, NMI/IRQ frame handlers, audio routines; fill `locals.inc` with zero-page aliases (`$02/$03` pointer, `$45/$46` X/Y state, `$04EA` dispatcher copy, `$0120/$0121` "AV" checker).
|
||||
3. **Pass 3** — name the data tables (level data at `$D7F3+`, envelope pool at `$E276+`, frequency table at `$DF3E`, ramps).
|
||||
4. **Promotion** — move to a top-level `<name>/copilot/` folder, add `header.s`/`chr.s` + full-ROM `make`, write the power-on flow `OVERVIEW.md` in the established style; then it joins the root index's numbered inventory.
|
||||
+4531
-5
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,12 @@
|
||||
; Pyramid (U) NES disassembly - Pass 1 (skeleton)
|
||||
; Generated from the supplied 16 KiB PRG image.
|
||||
; Pass 1 classifies recursively reachable code, inline address tables, vectors,
|
||||
; and untraced/data regions. All PRG data bytes are emitted explicitly with .byte directives.
|
||||
|
||||
.setcpu "6502"
|
||||
|
||||
.include "symbols.inc"
|
||||
.include "locals.inc"
|
||||
|
||||
.segment "PRG"
|
||||
.incbin "prg.bin", $0000, $4000
|
||||
Reference in new issue
Block a user