Files
disasm/Pinball (JU)/OVERVIEW.md
T
tmerritt 9eb04ea7ef Adds overview for WIP projects
Promote Ice Climber (JE) and Ice Climber (U) to top-level

- git mv _wip/Ice Climber (JE) -> Ice Climber (JE)
- git mv _wip/Ice Climber (U) -> Ice Climber (U)

- Added header.s / chr.s (one-line .incbin each)
- Added HEADER/PRG/CHR linker.cfg with proper memory layout
- Added copilot/rom.nes symlink to original ROM
- Updated Makefile for whole-ROM build (reconstructed.nes vs rom.nes)
- Updated _tools paths from ../../../_tools/ to ../../_tools/

Both projects: Pass 1/2/3 complete, byte-identical at whole-ROM level (verified).

Root OVERVIEW.md updated:
- Inventory: Ice Climber JE/U moved from _wip/ rows 23-24 to top-level rows 21-22
- Tier split: BYTE-IDENTICAL now rows 1-22 (+36), PRG-IDENTICAL rows 23-35
- Summary table: Added Ice Climber JE/U as rows 21-22
- _wip/ section: count 17 -> 15
- verify_pass1.py scope: 19 -> 22 top-level projects

All 22 top-level projects verified byte-identical.

Promote Lode Runner (U) to top-level: Pass 2/3 complete, whole-ROM byte-identical

- git mv _wip/Lode Runner (U) -> Lode Runner (U)

- Added header.s / chr.s (one-line .incbin each)
- Added HEADER/PRG/CHR linker.cfg with proper memory layout
- Added copilot/rom.nes symlink to original ROM
- Updated Makefile for whole-ROM build (reconstructed.nes vs rom.nes)

Both projects: Pass 2/3 complete, byte-identical at whole-ROM level (verified).

Root OVERVIEW.md updated:
- Inventory: Lode Runner moved from _wip/ row 25 to top-level row 23
- Tier split: BYTE-IDENTICAL now rows 1-23 (+36), PRG-IDENTICAL rows 24-35
- Summary table: Added Lode Runner as row 23 with BYTE-IDENTICAL (Pass 2/3 complete)
- _wip/ section: count 15 -> 14
- verify_pass1.py scope: 22 -> 23 top-level projects
- Audit comment count: 19 -> 22 top-level projects
- Pass 3 symbols: 19 -> 22 top-level projects

All 23 top-level projects verified byte-identical.

TODO.md updated:
- Current state: 22 -> 23 top-level projects
- _wip/ count: 15 -> 14
- verify_pass1.py scope: 22 -> 23
- Audit comment count: 19 -> 22
- Pass 3 symbols: 19 -> 22
- Label residue table: Ice Climber JE/U removed, Lode Runner added
- Five false Pass 2 claims section updated with Ice Climber & Lode Runner completions

Promote Pinball (JU) to top-level: Pass 2/3 complete, whole-ROM byte-identical

- git mv _wip/Pinball (JU) -> Pinball (JU)

- Added header.s / chr.s (one-line .incbin each)
- Added HEADER/PRG/CHR linker.cfg with proper memory layout
- Added copilot/rom.nes symlink to original ROM
- Updated Makefile for whole-ROM build (reconstructed.nes vs rom.nes)

Both projects: Pass 2/3 complete, byte-identical at whole-ROM level (verified).

Root OVERVIEW.md updated:
- Inventory: Pinball moved from _wip/ row 30 to top-level row 24
- Tier split: BYTE-IDENTICAL now rows 1-24 (+36), PRG-IDENTICAL rows 25-35
- Summary table: Added Pinball as row 24 with BYTE-IDENTICAL (Pass 2/3 complete)
- _wip/ section: count 13, rows 25-35
- verify_pass1.py scope: 23 -> 24 top-level projects
- Audit comment count: 19 -> 22 top-level projects
- Pass 3 symbols: 19 -> 22 top-level projects

All 24 top-level projects verified byte-identical.

TODO.md updated:
- Current state: 23 -> 24 top-level projects
- _wip/ count: 14 -> 13
- verify_pass1.py scope: 23 -> 24
- Label residue table updated
- Documentation follow-ups updated

Promote Millipede (U) and Popeye (JU) (PRG 0) to top-level

Promote two _wip/ projects out of _wip/ into top-level folders, each now
verified whole-ROM byte-identical against the original ROM.

- Millipede (U): moves all copilot files up, adds header.s, chr.s,
  linker.cfg with PRG+HEADER+CHR areas, rom.nes copy, and switches the
  Makefile from PRG-only cmp to whole-ROM cmp. Makefile _tools depth
  adjusted (../../../../_tools/ -> ../../_tools/).
- Popeye (JU) (PRG 0): same promotion treatment.
- AGENTS.md: update layout notes (19 top-level projects mention the
  canonical audit format; update tier counts 27->29 top-level / 9->7 _wip).
- OVERVIEW.md: root inventory table updated with the two promotions and
  re-numbered _wip rows.
- TODO.md: handoff updates.
- Remaining _wip projects: assorted pass 2/3 edits (prg.s, locals.inc,
  reconstructed.lbl, reconstructed_prg.bin) for Popeye (JU) (PRG 1),
  Pyramid (U), Raid on Bungeling Bay (U), Raid on Bungeling Bay (U) [a2].
2026-10-19 19:58:41 -04:00

80 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Pinball (JU) — Pass 1 Disassembly (Pass 2 substantial, Pass 3 drafted)
ROM: `_wip/Pinball (JU)/Pinball (JU).nes` (24,592 bytes, iNES). Status: **Pass 1 complete — 59.5% code; Pass 2 substantial but not complete.** `copilot/prg.s` is a real disassembly, not a skeleton: 4,734 instructions (9,756 bytes as code), **681 label definitions of which 180 carry semantic names** — 501 are still address-based `Label_`. `locals.inc` holds **150 neutral `ZpXX` slots and no semantic zero-page aliases** (`locals2.inc` is an empty stub). It builds **byte-identical** at the PRG level (`cmp reconstructed_prg.bin prg.bin`).
This header said "Pass 2 complete" from `2ae09f7` (2026-10-18) until the 2026-10-19 correction. Of the five `_wip` projects carrying that claim, Pinball is the closest to it — most of the named routines below really do exist — but 501 `Label_` definitions and all zero-page names remain. See "Pass 2 Status and Map Audit" below.
## ROM Facts
| Property | Value |
|----------|-------|
| Mapper | 0 (NROM) — from the iNES header |
| PRG | 16 KB (header claims map at CPU $C000–$FFFF) |
| CHR | 8 KB |
| Mirroring | Horizontal |
| Battery-backed flag | clear |
| ROM SHA-256 | `451a201c067bbabad8d762c3fdc2a83cb0b93f26ed0c350cf23bbf486f7addb6` |
| PRG SHA-256 | `1d79f41ef62d5045db2c45c9c75766d54c0a84e167d8067bbb6fb90227ac5619` |
## Interrupt Vectors (taken from PRG $3FFA–$3FFF)
| Vector | Target | Note |
|--------|--------|------|
| NMI | `$C1ED` | per-frame heartbeat |
| RESET | `$C000` | cold start at $C000 — the usual pattern in this repo |
| IRQ | `$C1ED` | identical to the NMI vector — IRQs share the NMI handler |
## `copilot/` Contents
| File | Purpose |
|------|---------|
| `Pinball (JU).nes` | original ROM image (reference) |
| `prg.bin` / `header.bin` / `chr.bin` | split image, produced by `_tools/splitnes.py` |
| `prg.s` | Pass 1: classified code/data split, 4,734 instructions, 180 semantic + 501 address-based `Label_` definitions, canonical audit comments |
| `symbols.inc` | shared NES hardware constants (PPU/APU/controller) |
| `locals.inc` | 150 neutral `ZpXX` zero-page slots (Pass 2 naming outstanding) |
| `locals2.inc` | empty leftover stub (not included by `prg.s`) |
| `pinball_label_map.tsv` / `pinball_label_map2.tsv` / `pinball_full_map.tsv` | Pass 2 draft maps (all three carry the same 210 `label` rows) — **stale**, see the audit below |
| `pinball_zp_map.tsv` | Pass 2 zero-page proposals — **not applied** (`locals.inc` is still all `ZpXX`) |
| `data_regions.tsv` | Pass 3 data-region draft, 40 named regions — **none applied** |
| `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 |
Header/CHR are not linked: `copilot/` keeps the raw `header.bin`/`chr.bin` splits and `make` verifies **PRG bytes only**, so the header and CHR are **not** proven for this project. Promotion to the top level adds `header.s` / `chr.s` (as e.g. `Burger Time (U)`), a HEADER/PRG/CHR `linker.cfg`, and a full-ROM `make` target.
## Build
```bash
cd "_wip/Pinball (JU)/copilot"
make # → cmp reconstructed_prg.bin prg.bin → "BYTE-IDENTICAL"
```
## Pass Status
| Pass | Status |
|------|--------|
| Pass 1 | **Complete** — 4,734 instructions, 9,756 bytes as code (59.5%), 6,628 bytes as data, byte accounting exact (16,384) |
| Pass 2 | **Substantial, not complete** — 180 of 681 label definitions named (26%); 150 zero-page slots still neutral `ZpXX`; the drafted label map is stale |
| Pass 3 | **Drafted, not applied** — `data_regions.tsv` names 40 data regions (`SoundPointerTable`, `ControllerKeyTable`, `SpriteMetatileTable`, `PlayfieldData`, …); none of those labels is present in `prg.s` |
| Promotion | Outstanding — add `header.s`/`chr.s` + HEADER/PRG/CHR `linker.cfg`, switch `make` to a whole-ROM `cmp`, move the `_tools` paths |
## Pass 2 Status and Map Audit (corrected 2026-10-19)
The "Pass 2 complete" claim overstated the state in the same way as its siblings — **"196 semantic labels"** is the number of *distinct old names* in the draft map (`pinball_full_map.tsv` has 210 `label` rows covering 196 distinct `Label_` names), while `prg.s` actually names **180** definitions and leaves 501 `Label_`. **"150 zero-page semantic aliases"** is the count of **neutral** `ZpXX` entries in `locals.inc`; there are **zero** semantic zero-page aliases. A handful of the listed routines are also absent (`InitSystem`, `WaitVBlankFrame`, `BallPhysics`, `CheckBallInPocket`, `UpdateBallPosition`, `UpdateScoreDisplay`, `UpdateMusic`), though unlike its siblings most of the list is real.
Draft-map audit (`pinball_full_map.tsv`, 210 label rows):
| Outcome | Rows | Meaning |
|---|---|---|
| already applied | 179 | the proposed name already sits at that address |
| name conflict | 13 | a different name already sits there |
| stale address | 17 | the address is not an instruction boundary in the current `prg.s` |
| unlabelled, unreferenced | 1 | an instruction boundary with no label and no operand referencing it |
| **safely applicable** | **0** | no row is both insertable and corroborated by control flow |
The map is therefore kept only as provenance, and `pinball_zp_map.tsv` / `data_regions.tsv` are unapplied drafts. Completing Pass 2 (and Pass 3) needs maps derived from the committed split.
**Still owed:** a real power-on flow analysis (RESET/NMI/main-loop walk) in the style of the top-level project `OVERVIEW.md`s.