diff --git a/docs/accuracy-ledger.md b/docs/accuracy-ledger.md index babb88f2..59c049c3 100644 --- a/docs/accuracy-ledger.md +++ b/docs/accuracy-ledger.md @@ -104,6 +104,44 @@ disposition under the v2.1.0 "Fathom" accuracy-remediation line `palette_ram`, work RAM) is already serialized, and the selections themselves are config re-applied on load like `region`. +- **NROM provides PRG-RAM at `$6000-$7FFF` where the board has none, and the + MiSTer co-simulation DUT found it (2026-08-25, v2.6.3 rung 5).** + `crates/rustynes-mappers/src/m000_nrom.rs` allocates 8 KiB of PRG-RAM + unconditionally so accesses "don't fall off the edge". `cpu_read` returns + `self.prg_ram[addr - 0x6000]` and `cpu_write` stores into it, so the window + behaves as **real, writable RAM**: an *unwritten* location reads `$00` + (the array is zero-filled at construction) and a written one reads back what + was stored. On hardware an NROM board decodes nothing there and the read + floats — it returns **open bus**, the last value the data bus held, whether + or not the program has written to that address. + + This is the emulator default `nesdev_wiki/Open_bus_behavior.xhtml` names as a + problem in its own words (public source: + ): *"A few games read the region $6000-7FFF but have no + WRAM present here. This can be a problem for emulators, as the original iNES + file format had no way to specify a lack of WRAM, leaving the emulator to + provide WRAM behavior in that region by default. The NES 2.0 format corrects + this with a WRAM size field."* The page then names titles that break on the + WRAM answer — **Low G Man** (a crash in Chapter 1 Scene 3B, or boomerang + graphical glitches) and **Battletoads & Double Dragon** (a `$00` read at the + end of level 1 crashes it). + + **Not fixed here, and the reason is scope rather than doubt.** The fix is a + behaviour change to the shipped emulator on every iNES-header NROM cartridge, + so it needs the NES 2.0 WRAM-size field honoured where present, a decision + about iNES-header defaults, the per-game database consulted, and the full + accuracy battery plus the commercial-ROM oracle re-run — the same shape as the + header-override hazard that froze *Wizards & Warriors* (ADR 0031). It is a + correctness item with a citation and named symptoms, recorded rather than + quietly carried. + + **How it was found is the point.** The v2.6.3 co-simulation step wrote a + `cpu_bus` module from the wiki and ran it against this emulator; the DUT and + the oracle agreed on `$4016`, `$4017`, `$5000` and `$5C34` and disagreed only + in `$6000-$7FFF`. This is the first time the verification ladder has found the + **oracle** wrong rather than the DUT, which the v2.5.0 plan listed in advance + as risk 6: *"the oracle can be wrong. 141/141 is not 'matches silicon'."* + ## Ignored-test dispositions (all 20) Every `#[ignore]`'d test in the workspace, with its disposition. **None is an diff --git a/to-dos/mister/TASKS.md b/to-dos/mister/TASKS.md index 2ad78a3d..2cd154e7 100644 --- a/to-dos/mister/TASKS.md +++ b/to-dos/mister/TASKS.md @@ -61,7 +61,42 @@ Legend: `[ ]` open · `[~]` in progress · `[x]` done ## v2.6.3 – v2.6.4 — rung 5, NROM + AccuracyCoin -- [ ] v2.6.3 NROM cartridge; first end-to-end AccuracyCoin run +- [~] v2.6.3 NROM cartridge; first end-to-end AccuracyCoin run + - [x] `rtl/cart/cart_nrom.sv` — written from `nesdev_wiki/NROM.xhtml` + (public source: ), + instantiated beneath the existing gates and cross-checked per access + rather than trusted. Runtime write port, not `$readmemh`: on MiSTer the + image arrives from `hps_io` at runtime, so the port that ships is the + port that is tested + - [x] `rtl/wram.sv` — 2 KiB and the `$0000-$1FFF` decode. **50 gates green**, + 5 mutations CAUGHT. Its mirroring was invisible to the entire prior + corpus: all 48 ROMs stay inside `$0000-$07FF`, so three mirror-only + mutations came back **NOT CAUGHT** against `blargg03`'s 893,410 cycles + and CAUGHT against the new `wrammirror044`. A stimulus NOT CAUGHT — the + fourth distinct meaning that verdict has had here + - [x] The harness's own memory model was wrong first: it wrote `mem[addr]` + unmirrored, so a correctly-mirrored RAM would have been reported as the + defect. Fixed before the RTL was trusted + - [x] `rtl/cpu_bus.sv` — the address decode, read mux and open-bus latch. + **The flat 64 KiB array no longer answers the CPU**; the RTL bus does, + and the harness's array survives only as a model scoped to the windows + it can independently speak for. The testbench's hardcoded `$40` for a + `$4016` read is now DERIVED from the latch + - [x] `rtl/controller.sv` — the standard pad's shift register. `cpu_bus` + first returned a bare 0 in D0, which is not a model of "no controller" + but a model of nothing, and diverged from the oracle on the NINTH read + - [x] **Found the ORACLE wrong, not the DUT** — NROM provides PRG-RAM at + `$6000-$7FFF` where the board has none. Recorded in + `docs/accuracy-ledger.md` with the wiki citation and the games the wiki + names as breaking on it. First time the ladder has caught the oracle; + risk 6 in the v2.5.0 plan + - [ ] **DMA is still `tb/cpu_main.cpp`.** On stalled cycles the bus mux is + not the requester, which is also why two mutations are provably inert + today and should flip to CAUGHT when it moves + - [ ] **`rtl/nes_top.sv` is still a shell.** The chips are tied together by + the co-simulation wrapper rather than by the core's own top level + - [ ] First end-to-end AccuracyCoin run — blocked on the above, and NOT + attempted. Producing a status vector is v2.6.3; matching it is v2.6.4 - [ ] v2.6.4 status vector identical **entry-for-entry**, including `Skipped` and `NotRun` — **rung 5 closes**. State a floor, not a target