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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ cycle-accurate core later replaced.

### Changed

- **MiSTer co-simulation, rung 5 (sibling repository).** The NROM cartridge, the
work RAM, the console's CPU bus, the controller ports and DMC DMA are landed
and gated at **50 gates green**. The DUT's CPU is driven by the RTL bus and a
DMC fetch is a real bus cycle by a second requester — no flat testbench array
in either path. Assembling `nes_top` is what remains, and because that top
level must divide the master clock — the apparatus rung 3's phase calibration
was built on — it is a change to the timing substrate rather than a rewiring,
and is named as its own step.

**The ladder caught the oracle for the first time**, which is what the
accuracy-ledger entry below records. No `rustynes-*` crate changes, so
AccuracyCoin and nestest are untouched by construction.

- **Dependency and toolchain-adjacent refresh.** 17 crates moved to their newest
semver-compatible versions (including `cc` 1.4.3 → 1.4.4 and `log` 0.4.33 →
0.4.34), `directories` 5 → 6, and four GitHub Actions advanced —
Expand Down
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -892,11 +892,22 @@ testbench links, plus a `nes_golden_export` CLI emitting golden traces.
Progress is a **rung ladder**, and a rung may not open until the one below is
green: rung 0 the compare surface, rung 1 the 6502, rung 2 the bus and
interrupts, rung 3 the 2C02, rung 4 the 2A03, rung 5 AccuracyCoin parity, rung 6
hardware bring-up, rung 7 mappers. Rungs 0-3 are closed; rung 4 is the current
work. Every rung is labelled in [`docs/mister.md`](docs/mister.md) by whether it
has an **independent** oracle — because 141/141 on AccuracyCoin is not the same
as "matches silicon", and a rung verified only against this emulator inherits
whatever this emulator has wrong.
hardware bring-up, rung 7 mappers. **Rungs 0-4 are closed; rung 5 is the current
work** — the NROM cartridge, the work RAM, the CPU bus, the controller ports and
DMC DMA are all landed and gated (50 gates green), and assembling the core's own
top level is what remains. Every rung is labelled in
[`docs/mister.md`](docs/mister.md) by whether it has an **independent** oracle —
because 141/141 on AccuracyCoin is not the same as "matches silicon", and a rung
verified only against this emulator inherits whatever this emulator has wrong.

**Rung 5 has already shown why that caveat is not decorative.** A `cpu_bus`
module written from the wiki disagreed with this emulator at `$6000-$7FFF`: an
NROM board decodes nothing there and reads open bus, while RustyNES allocates
8 KiB of PRG-RAM unconditionally. The wiki names that emulator default as a
problem and lists games that crash on it. **The DUT is the more accurate of the
two**, and the finding is recorded in
[`docs/accuracy-ledger.md`](docs/accuracy-ledger.md) rather than fixed inside a
co-simulation step — it changes shipped behaviour on every iNES NROM cartridge.

**The emulation core is unchanged by this line.** Releases in it touch the
co-simulation apparatus and the DUT, not the shipped emulator, so AccuracyCoin
Expand Down
30 changes: 30 additions & 0 deletions docs/mister.md
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,36 @@ Every rung is therefore labelled by whether it has an **independent** oracle:
nestest (Nintendulator) and the blargg ROMs do; trace fields with no Mesen2
counterpart do not, and are advisory only.

### It happened, at rung 5 (2026-08-25)

This stopped being a stated risk and became a measurement.

`rtl/cpu_bus.sv` was written from `nesdev_wiki/CPU_memory_map.xhtml` and
`Open_bus_behavior.xhtml` and run against this emulator. The two agreed on
`$4016`, `$4017`, `$5000` and `$5C34` — including the open-bus value, which the
DUT *derives* from a latch where the testbench had hardcoded `$40` — and
disagreed only in `$6000-$7FFF`.

**The DUT was right.** An NROM board decodes nothing there, so the window reads
open bus. `crates/rustynes-mappers/src/m000_nrom.rs` allocates 8 KiB of PRG-RAM
unconditionally so accesses "don't fall off the edge", which is the iNES-era
emulator default the wiki names as a problem in its own words — and it lists
games that break on the WRAM answer, *Low G Man* and *Battletoads & Double
Dragon* among them.

Three things this establishes, in order of how much they matter:

1. **The ladder can catch the oracle.** That was asserted when the programme was
planned and is now demonstrated, which is a different kind of claim.
2. **The correct response was to record, not to fix.** Changing it alters
shipped behaviour on every iNES-header NROM cartridge and needs the NES 2.0
WRAM-size field, the per-game database and the full accuracy battery. It is
in [`accuracy-ledger.md`](accuracy-ledger.md) with its citation.
3. **The gate ROM was narrowed rather than the DUT bent.** `busopen045` reads
`$4020-$5FFF` and not `$6000-$7FFF`, because a gate that fails for the
oracle's limitation rather than the DUT's teaches the wrong lesson and
eventually gets switched off.

## The two risks that had to be settled before any RTL

Both were settled in v2.4.3, and **both were answered by evidence that
Expand Down
23 changes: 18 additions & 5 deletions to-dos/mister/TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,24 @@ Legend: `[ ]` open · `[~]` in progress · `[x]` done
`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
- [x] `rtl/dma.sv` — the documented four-phase DMC sequence, load-bearing.
The byte comes off `cpu_bus` at the DMA's own address, so a DMC fetch is
a real bus cycle by a **second requester**. Two ordering defects found
by side-by-side comparison, in opposite directions: the load delay one
cycle late (non-blocking assignment), then one cycle early (a `$4015`
write landing on an APU phase edge must be armed AND decremented by it)
- [x] `rtl/controller.sv` — and the address mux placed at the CONSOLE level,
not inside the read mux, so the memories see the DMA's address
- [x] **Prediction recorded as WRONG.** The previous step predicted in writing
that two inert open-bus mutations would flip to CAUGHT once DMA drove
the bus. They did not, and a third joined them. The cause is stimulus:
no ROM in the corpus both runs DMC fetches and reads open bus
- [ ] **`rtl/nes_top.sv` is still a shell** — the one remaining piece. Every
part exists and is gated, but they are tied together by the
co-simulation wrapper rather than by the core's own top level, and that
top level must also divide the master clock. That is the apparatus rung
3's phase calibration was built on, so it is a change to the timing
substrate rather than a rewiring — named as its own step for that reason
- [ ] 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
Expand Down
Loading