Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions docs/accuracy-ledger.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
<https://www.nesdev.org/wiki/Open_bus_behavior>): *"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
Comment thread
coderabbitai[bot] marked this conversation as resolved.
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
Expand Down
37 changes: 36 additions & 1 deletion to-dos/mister/TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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: <https://www.nesdev.org/wiki/NROM>),
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

Expand Down
Loading