Skip to content

Commit 0bfa871

Browse files
doublegateclaude
andcommitted
docs(audits): record the RTL audit's v2.8.2 verdicts and the Solder plan
The RTL ledger's eleven v2.8.2 rows now carry verdicts with evidence. Five are FIXED on the sibling, each by a co-simulation or module gate that failed first and catches its mutant: R-3.5b (MMC3 acknowledge vs a same-edge counter clock, cart-mmc3-gate), R-3.5d (SNROM's CHR-A16 PRG-RAM enable, mapper1snrom067, 3,924 cycles diverged before), R-3.2b (the $2002 data-bus latch, ppulatch072, 2 cycles before) and R-3.3c (triangle/noise reload drop, aputrireload070/apunoisereload071, per-channel mutants). The pulse-1 sweep row (R-3.3b, refuted earlier) gains its promised gate, apusweepneg069. Three are NOT A DEFECT as written. R-3.5c: the RTL implements the "normal" Sharp revision and the report names the wrong one. R-3.2a: unreachable, because it needs $2002 reads on dot 0 and dot 1 of one frame and CPU accesses are three dots apart. R-3.1a/b stay PARTIAL: no gate shows an effect, so nothing changed, and the v2.9.0 re-audit revisits them. R-3.5a is a new verdict, INVERTED, added to docs/audits/README.md: the two implementations disagreed as the report says, but the documentation shows the audited side (the RTL) was right. The oracle's MMC1 was the defect and was fixed in dae2053. Recording it as FIXED or REFUTED would each have been false: the finding was real, and it was about the other repository. The sibling commit ids are in the rows; the PR column fills when the sibling PR opens. Also: to-dos/plans/v2.8.2-solder-plan.md (codename checked unused across CHANGELOG, VERSION-PLAN, release notes and plans), the CHANGELOG [Unreleased] RTL bullets, and two docs/agents/mister-cosim.md notes (an audit's disagreement does not say which side is wrong; a drifting loop reaches a dot only if its period is coprime with the frame, which is why ppulatch072 carries a NOP). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014qfTKi2M3swo7qnwvYCkDj
1 parent dae2053 commit 0bfa871

5 files changed

Lines changed: 111 additions & 10 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,33 @@ cycle-accurate core later replaced.
3434
*Shinsenden* (a reset on a read-modify-write's second write) needs not to
3535
do. The MiSTer core already had it right.
3636

37+
The rest of this section is the MiSTer core (`RustyNES_MiSTer`). Each fix
38+
failed a new co-simulation gate first, and that gate catches the fix's mutant.
39+
The RTL was written from the nesdev wiki and first-divergence reads of this
40+
emulator's traces; no reference HDL was opened (ADR 0037).
41+
42+
- **An MMC3 IRQ acknowledge is not lost to a counter clock on the same
43+
edge.** When a `$E000` write and the A12 rise that took the counter to zero
44+
landed on one master clock, the counter's "pending" won, leaving an IRQ
45+
pending with IRQs disabled until the next `$E000`. A module gate places the
46+
two on one clock.
47+
- **SNROM's PRG-RAM follows its CHR-bank enable.** SNROM boards (*The Legend
48+
of Zelda* and other battery MMC1 games) wire CHR A16 to a second PRG-RAM
49+
enable; the core ignored it, so RAM the game had disabled stayed writable.
50+
- **The triangle and noise drop a length reload that lands on a length
51+
clock**, as the pulse channels already did and as this emulator does.
52+
- **A `$2002` read on the vertical-blank dot leaves the value it returned on
53+
the data bus.** The latch was rebuilt from the registers, which had not yet
54+
set, so a following read of a write-only register saw `$00` where the
55+
console sees `$80`.
56+
- **Pulse 1's sweep with negate and shift 0 (`$4001 = $08`) is now under a
57+
gate.** The core was already right; the gate guards the emulator's v2.7.0
58+
fix.
59+
- **The RTL audit's v2.8.2 rows are closed** in
60+
`docs/audits/rtl-disposition.md`. Three were not defects as written, and one
61+
(MMC1) was the emulator's defect, not the core's; the ledger gains an
62+
INVERTED verdict for that case.
63+
3764
## [2.8.1] - 2026-09-25 - "Gasket" (the libretro core fits the frontends around it)
3865

3966
The second release of the v2.8.x line, and the last of its libretro work:

‎docs/agents/mister-cosim.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,5 @@
4040
- **THE ELEVEN-VARIANT SWEEP CLOSED (v2.6.23): `chrram-live` GREEN, 32,861 -> 0 PIXELS.** The axis the sweep missed (recorded above) was what a `$2007` access during rendering COMPUTES FROM, not what it computes. On silicon the access pulses the rendering pipeline's existing load rather than performing its own increment. Three changes, each exposing the next: `v_pipeline` (increment the value *this dot's* pipeline load produced, 21,941 -> 2,646 diverging fetches), `v_acc_addr` (RESOLVE the access against that same value, -> 18, which stopped 33 nametable cells being written one coarse-X cell early), and `chr_wr_addr` sourced from it too (-> 0 pixels). `chr_wr` asserts 4,389 times before and after — same stimulus. The `chr_wr_addr` step is a MAINTAINER DECISION (ADR 0037 territory: the write address the oracle now follows is a case the wiki declares undefined), taken knowingly and kept in the RTL comment marked resolved-by-decision rather than deleted, so it governs the next case like it. `chrram-fetch` stays `run_xfail` at 18 of 185,725 — all garbage sprite-window nametable fetches (dots 257-320) whose data is discarded, which is why the picture is byte-perfect while the trace is not.
4141
- **GOLDEN RECIPES: 97 OF 110 MANIFESTS, GENERATED NOT TRANSCRIBED, AND 472 ARTIFACTS BYTE-FOR-BYTE (v2.6.23).** `tb/gen_golden_recipes.py` derives each recipe row from fields the manifest already carries (`frames_req`, `ckpt_interval`, `obs_count` sizing `--irq-trace`, `press_start`), because 110 hand-transcribed caps is 110 silent ways to under-cover a golden. `VERIFY=1 tb/fetch-goldens.sh` regenerates into scratch and diffs against `goldens/` WITHOUT writing to it — **472 artifacts byte-for-byte** across goldens recorded as rustynes 2.5.1 through 2.6.22, fifteen releases. **Every apparent difference across four diff passes was a recipe defect, never oracle drift**: a `.irq.csv` diagnostic nothing reads; a guessed `--apu-trace` cap the exporter correctly REFUSED rather than silently under-covering; eleven blargg stems producing nothing because the exporter names artifacts after the ROM FILE's stem, not the target stem; and AccuracyCoin differing in 11.4% of its framebuffer with a MATCHING rom hash — actually a missing `--press-start`, caught by `accuracycoin_status` refusing to score a vacuous run ("every one of the 144 SCORED entries is NotRun"). The ROM is located by `rom_sha256` (content), never the manifest's unusable `rom` path (relative / `../../../`-relative / absolute-under-$HOME / pointing into deleted `/tmp/blargg-apu/` depending on the stem).
4242
- **FITTER SEED 4 PINNED ON BEST-OVERALL, NOT STRICT BINDING-MARGIN (v2.6.23).** RTL changed, so by `RustyNES.qsf`'s own rule the prior sweep described a design that no longer exists. Re-swept, 5 seeds, all closing; hold binds at every seed (0.078-0.115ns vs setup's 0.247-0.421ns), so the established rule mechanically selects seed 1 (+0.115 hold). Maintainer decision pinned seed 4 instead (+0.112 hold, +0.421 setup) on BEST OVERALL — within 3ps of seed 1 on hold while beating it by 174ps on setup — with the reasoning AND the falsifying experiment (re-fit one seed repeatedly, measure run-to-run variance; not yet done) written into the `.qsf` alongside the pinned seed, not left implicit. Marked `<- pinned`, not `<- published`, since no bitstream had been built from it yet at write time. Seed 5 — the PREVIOUS release's outright winner — is joint-worst on this RTL: a sweep result belongs to one specific RTL, never carries forward.
43+
- **AN AUDIT'S "THE RTL DISAGREES WITH THE ORACLE" DOES NOT SAY WHICH SIDE IS WRONG (v2.8.2).** RTL audit R-3.5a said `cart.sv` checked MMC1's reset bit before the consecutive-write filter "while the oracle filters first", and called the RTL the defect. nesdev MMC1 says a reset is never ignored and only a DATA write on the cycle after a write is, so the ORACLE was wrong (`m001_mmc1.rs`, fixed red-first in v2.8.2) and the RTL was left alone. The v2.7.0 pulse-1 sweep finding had the same shape. Before fixing either side of a disagreement, read the wiki for the rule itself; the audit ledger now has an INVERTED verdict for this case (`docs/audits/README.md`).
44+
- **A DRIFTING LOOP REACHES A DOT ONLY IF ITS PERIOD IS COPRIME WITH THE FRAME (v2.8.2).** The first `ppulatch072` draft, an 11-cycle `$2002`/`$2000` loop, is 33 dots, and 11 divides the 89,342-dot NTSC frame (2·11·31·131), so the loop reaches only 3 of 33 landing residues and could miss the VBL set dot forever. A `NOP` makes it 13 cycles (39 dots, coprime), and 39 frames cover every dot. Coverage was then read from the oracle's `irq.csv` (reads at scanline 241 dots 0-4, dot 1 twice), not assumed. The reverse case is `apureload042`'s: a walk resolves a residue class, not a cycle, so a one-cycle target inside a long period needs a PLACED write instead.

‎docs/audits/README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,6 @@ ADR 0037 reference firewall.
8383
| REFUTED | The code does not do what the finding says; evidence given. Closed. |
8484
| NOT A DEFECT | Accurate description, but the behaviour is deliberate or correct. Closed. |
8585
| REJECTED FIX | The defect is real but the recommended fix breaks a project rule; a different fix is recorded. |
86+
| INVERTED | The two implementations disagree as the finding says, but the documentation shows the audited side is right and the other one wrong, so the fix lands on the other side (first used for R-3.5a, v2.8.2). |
8687
| UNTRIAGED | Not yet read against the code. Nothing is planned on an untriaged finding. |
8788
| FIXED | Closed by the PR in the ledger row, with the red-first test named. |

‎docs/audits/rtl-disposition.md‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,21 @@ accurate: the build targets the DE10-Nano's 5CSEBA6U23I7 (`sys/sys.tcl`).
2222
| Id | Finding (report §) | Verdict | Evidence | Release | PR |
2323
| --- | --- | --- | --- | --- | --- |
2424
| R-2.4 | Resource utilisation table (§2.4) | REFUTED | `output_files/RustyNES.fit.summary` (2026-09-20): 23,013 / 41,910 ALMs (55%), 468 / 553 RAM blocks (85%), 33 / 112 DSP (29%). The report says 21,865 ALMs, 394 M10K, 0 DSP | — | |
25-
| R-3.1a | Spurious `last_cycle` at `tcyc == 0` for `AM_REL` (§3.1, Fix 11) | PARTIAL | `cpu6502.sv:1285-1286` matches the description, but the only consumer not gated by `ST_EXEC` is the `sh_rdy_low` clear (`:921`), which the SH instruction re-arms. No functional effect found. Fixed only if a gate can show one | v2.8.2 | |
26-
| R-3.1b | Second NMI edge swallowed during NMI entry (§3.1) | PARTIAL | `cpu6502.sv:1860-1862` has no `!int_is_nmi` guard, as described; losing a second edge before the vector fetch may be hardware behaviour. Not a proven defect | v2.8.2 | |
27-
| R-3.2a | `vblank_now` ignores `suppress_vbl` (§3.2, Fix 12) | UNTRIAGED | | v2.8.2 | |
28-
| R-3.2b | `$2002` read latches register state, not the driven bus, into open bus (§3.2) | UNTRIAGED | | v2.8.2 | |
25+
| R-3.1a | Spurious `last_cycle` at `tcyc == 0` for `AM_REL` (§3.1, Fix 11) | PARTIAL | `cpu6502.sv:1285-1286` matches the description, but the only consumer not gated by `ST_EXEC` is the `sh_rdy_low` clear (`:921`), which the SH instruction re-arms. No functional effect found, and v2.8.2 found no gate that shows one; left unchanged. Revisited at the v2.9.0 re-audit | v2.8.2 | |
26+
| R-3.1b | Second NMI edge swallowed during NMI entry (§3.1) | PARTIAL | `cpu6502.sv:1860-1862` has no `!int_is_nmi` guard, as described; losing a second edge before the vector fetch may be hardware behaviour. Not a proven defect, and v2.8.2 found no gate that shows an effect; left unchanged. Revisited at the v2.9.0 re-audit | v2.8.2 | |
27+
| R-3.2a | `vblank_now` ignores `suppress_vbl` (§3.2, Fix 12) | NOT A DEFECT | True as written and unreachable: the failure needs a `$2002` read on dot 0 (setting `suppress_vbl`) AND another on dot 1 of the same frame, and CPU accesses are three dots apart. Left unchanged | — | |
28+
| R-3.2b | `$2002` read latches register state, not the driven bus, into open bus (§3.2) | FIXED | On the VBL set dot bit 7 comes from the combinational `vblank_now`; the latch was rebuilt from the registers and kept 0. Stimulus `ppulatch072` (a 13-cycle `$2002`/`$2000` loop that walks every landing dot): 2 of 1,429,465 cycles diverged before, 0 after (349 checkpoints). Fix `open_bus <= cpu_dout`. Sibling `b09ee32` | v2.8.2 | |
2929
| R-3.3a | `audio_dc_block.sv` 32-bit overflow (§3.3, Fix 1) | REFUTED | `W = 32`, `FRAC = 15`, `mix` is 16-bit unsigned. Worst case `65535<<15 = 2^31-2^15` fits; for unipolar input the high-pass output stays within ±M·2^15 and the ±(32767<<15) clamp (`:120-123`) fires first | — | |
30-
| R-3.3b | Pulse-1 sweep with negate not muted (§3.3, Fix 7) | REFUTED | `apu2a03.sv:230-231` gates overflow behind `!neg`, which is correct: `nesdev_wiki/APU_Sweep.xhtml` says a negative target clamps and negate is the documented way to disable the sweep. The RTL is right; see core ledger T-01 for the oracle side | — | |
31-
| R-3.3c | Triangle / noise length reload overrides a coinciding decrement (§3.3) | UNTRIAGED | | v2.8.2 | |
30+
| R-3.3b | Pulse-1 sweep with negate not muted (§3.3, Fix 7) | REFUTED | `apu2a03.sv:230-231` gates overflow behind `!neg`, which is correct: `nesdev_wiki/APU_Sweep.xhtml` says a negative target clamps and negate is the documented way to disable the sweep. The RTL is right; see core ledger T-01 for the oracle side. v2.8.2 adds the co-simulation gate `apusweepneg069` (pulse 1 `$4001=$08` sounds, pulse 2 `$00` mutes; a mute mutant diverges on 163,968 cycles), sibling `6e343b2` | — | |
31+
| R-3.3c | Triangle / noise length reload overrides a coinciding decrement (§3.3) | FIXED | CONFIRMED by first divergence against the oracle, which drops a reload landing on a half-frame length clock when the counter was non-zero (as the pulses already did in the RTL). Stimuli `aputrireload070` / `apunoisereload071`; each channel's mutant is caught only by its own gate. Sibling `b8610c9` | v2.8.2 | |
3232
| R-3.4a | CKE raised on the same edge as the first PRECHARGE (§3.4, Fix 2) | CONFIRMED | `sdram.sv:481-482` `sdram_cke <= 1'b1; cmd <= C_PRECHARGE;`. Off-die build only | v2.8.4 | |
3333
| R-3.4b | DQM held high through the read wait, floating the bus at CL3 (§3.4, Fix 3) | REFUTED | `CAS_LATENCY` is 2 at `CLK_PS = 11640` (`sdram.sv:198`) and READ is issued with DQM low (`:666`); at CL2 that covers the data beat | — | |
3434
| R-3.4c | Arbiter byte-lane select read from `*_hold[0]` at ack time (§3.4, Fix 4) | CONFIRMED | `sdram_arbiter.sv:353` slices on `chr_hold[0]` at ack; `chr_hold <= chr_addr` (`:317`) reloads on a new strobe, and a re-strobe in flight sets no overrun. Latent: the shipped cart path does not use it | v2.8.4 | |
3535
| R-3.4d | Write handshake: `wr_busy` omits `wr_stb` (§3.4) | UNTRIAGED | Off-die build only | v2.8.4 | |
36-
| R-3.5a | MMC1 bit-7 reset checked before the consecutive-write filter (§3.5, Fix 5) | CONFIRMED | `cart.sv:389` tests `cpu_din[7]` before `!mmc1_wrote_last_cycle`; the oracle filters first (`m001_mmc1.rs:315-321`). The report misstates the impact: "resets twice" is harmless; the case that matters is a bit7=0 write followed by a bit7=1 write | v2.8.2 | |
37-
| R-3.5b | MMC3 `$E000` acknowledge vs counter decrement race (§3.5, Fix 6) | UNTRIAGED | Verify against nesdev before any fix | v2.8.2 | |
38-
| R-3.5c | MMC3 Sharp reload-to-zero (§3.5) | UNTRIAGED | As R-3.5b | v2.8.2 | |
39-
| R-3.5d | SNROM PRG-RAM `/CE2` protection missing (§3.5) | UNTRIAGED | | v2.8.2 | |
36+
| R-3.5a | MMC1 bit-7 reset checked before the consecutive-write filter (§3.5, Fix 5) | INVERTED | The RTL is right and the ORACLE was wrong: `nesdev_wiki` MMC1 says a reset write is never ignored, only a data write on the cycle after another write (the RMW idiom of *Bill & Ted*). Oracle fixed (`m001_mmc1.rs`, red test first, mutation caught); sibling gate `mapper1rmw068` pins the RTL against it. RTL unchanged. Sibling `6531830` | v2.8.2 | |
37+
| R-3.5b | MMC3 `$E000` acknowledge vs counter decrement race (§3.5, Fix 6) | FIXED | CONFIRMED. On the same edge the counter's `pending <= 1` came after the acknowledge's `pending <= 0` and won. "Permanently stuck" is overstated: it lasts until the next `$E000`. Module gate `cart-mmc3-gate` (control / coincide / after / reload-to-zero), red first. Sibling `60a2aab` | v2.8.2 | |
38+
| R-3.5c | MMC3 Sharp reload-to-zero (§3.5) | NOT A DEFECT | The RTL raises the IRQ when a reload yields zero, which is the "normal" (Sharp) behaviour on nesdev; the report attributes the wrong revision. Covered by the `reload-to-zero` case of `cart-mmc3-gate` | — | |
39+
| R-3.5d | SNROM PRG-RAM `/CE2` protection missing (§3.5) | FIXED | CONFIRMED. SNROM gates PRG-RAM on CHR A16 (`E` bit 4 of the selected CHR bank) as well as MMC1 `E` bit 4. Stimulus `mapper1snrom067`: 3,924 cycles diverged before, 0 after. Sibling `5461730` | v2.8.2 | |
4040
| R-4.1 | Timing table and per-domain slack figures (§4.1) | UNTRIAGED | The binding figures (+0.421 ns setup, +0.112 ns hold) match the pinned seed 4; the per-domain Fmax values and domain attribution are unverified | v2.8.3 | |
4141
| R-4.2 | Runtime `%` bank dividers in `cart.sv` (§4.2, Fix 10) | NOT A DEFECT | Confirmed present (`cart.sv:679,681,698`; `lpm_divide:Mod0` in the fit report) and deliberate: documented, and timing closed by registering the crossing (`:760-775`). The "~480 ALMs" has no source. Revisited only on a measured need | — | |
4242
| R-4.3 | `dec_rom[din]` 256:1 mux in the fetch path (§4.3) | UNTRIAGED | The "978 LEs" figure is to be measured in Quartus, not quoted | v2.8.3 | |

‎to-dos/plans/v2.8.2-solder-plan.md‎

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
2+
# v2.8.2 "Solder" — the MiSTer core's on-die RTL, corrected against the oracle and the wiki
3+
4+
The third release of the v2.8.x line
5+
([ADR 0041](../../docs/adr/0041-hardware-release-is-v3.0.0.md);
6+
[line plan](v2.8.x-libretro-rtl-audit-plan.md)). It works from
7+
[`rtl-audit-report.md`](../../docs/audits/rtl-audit-report.md) §3.1 to §3.5
8+
and the [RTL ledger](../../docs/audits/rtl-disposition.md) rows targeted at
9+
v2.8.2. Both repositories change: the sibling's RTL and co-simulation ladder,
10+
and one oracle mapper found wrong while triaging.
11+
12+
## What v2.8.1 closed and did not
13+
14+
v2.8.1 "Gasket" closed the libretro ledger. The RTL ledger had eleven rows
15+
targeted at v2.8.2, nine of them UNTRIAGED; the audit's RTL report is the one
16+
its own calibration trusts least.
17+
18+
## The deliverable
19+
20+
Every v2.8.2 row triaged against the nesdev wiki and a first divergence
21+
against the oracle, and every CONFIRMED row fixed with a gate that fails
22+
first and catches its mutant. Written from documentation under the ADR 0037
23+
firewall; no reference HDL or emulator source was opened. The provenance
24+
headers were checked before any oracle source was read for this work
25+
(`m001_mmc1.rs`, `pulse.rs`, the triangle and noise channels carry none).
26+
27+
## The gate
28+
29+
- Each fix: its gate red on the unfixed RTL, green after, and the fix's
30+
mutant caught by that gate (a value mutant where a deleted signal would be
31+
a Verilator build failure rather than a result).
32+
- The whole ladder (`tb/regress.sh`) green from the sibling tree, with the
33+
`TOTAL:` line recorded; `make -C tb lint` clean.
34+
- A Quartus compile of the changed RTL at the pinned seed 4 whose timing
35+
closes (`scripts/check_timing.py`), since any RTL change makes the
36+
published `.rbf`'s timing report stale.
37+
- Oracle: `--features test-roms` suite, AccuracyCoin 144/144, nestest 0-diff
38+
re-run for the MMC1 change.
39+
- After the oracle merges, the sibling's `tb/ORACLE_COMMIT` moves to the
40+
merge commit and `VERIFY=1 tb/fetch-goldens.sh` re-verifies every golden
41+
against it.
42+
43+
## What was found and done
44+
45+
| Row | Verdict | How it was shown |
46+
| --- | --- | --- |
47+
| R-3.5a MMC1 reset vs the consecutive-write filter | INVERTED | nesdev MMC1: a reset is never ignored, only a data write on the cycle after a write. The RTL was right; the ORACLE ignored the reset. Oracle fixed (red unit test, mutation caught); sibling stimulus `mapper1rmw068` (an `INC` on the serial port) pins the RTL against the corrected oracle |
48+
| R-3.5b MMC3 `$E000` vs a same-edge counter clock | FIXED | `cart-mmc3-gate`, a module gate placing both on one master clock: pending stayed set with IRQs disabled. "Permanently stuck" overstated: it lasts until the next `$E000` |
49+
| R-3.5c MMC3 Sharp reload-to-zero | NOT A DEFECT | the RTL implements the "normal" (Sharp) revision; the report attributes the wrong one. Covered by the gate's `reload-to-zero` case |
50+
| R-3.5d SNROM PRG-RAM protection | FIXED | `mapper1snrom067`: 3,924 cycles diverged before, 0 after |
51+
| R-3.2a `vblank_now` vs `suppress_vbl` | NOT A DEFECT | needs `$2002` reads on dot 0 and dot 1 of one frame; CPU accesses are three dots apart |
52+
| R-3.2b `$2002` open-bus latch | FIXED | `ppulatch072` (a 13-cycle loop, coprime with the frame, so every landing dot is reached): 2 cycles diverged before, 0 after |
53+
| R-3.3c triangle / noise reload vs a length clock | FIXED | first-divergence read against the oracle; `aputrireload070` / `apunoisereload071`, each channel's mutant caught only by its own gate |
54+
| pulse-1 sweep negate | GATE ADDED | `apusweepneg069` guards the v2.7.0 oracle fix; a mute mutant diverges on 163,968 cycles |
55+
| R-3.1a / R-3.1b CPU `last_cycle`, NMI entry | PARTIAL, unchanged | no gate shows an effect; revisited at the v2.9.0 re-audit |
56+
57+
## Risks
58+
59+
- The oracle's MMC1 change is an emulation behaviour change. Its reach is
60+
the reset-after-write case only; the test-roms suite and AccuracyCoin are
61+
re-run on it.
62+
- The sibling's goldens are pinned at an oracle older than every fix here.
63+
Until the pin moves, the new stems' goldens come from the release branch;
64+
the pin bump re-derives all of them.
65+
66+
## Out of scope
67+
68+
- RTL robustness (reset synchronisers, the `dec_rom` mux, `rmw_addr`,
69+
tabs): v2.8.3.
70+
- The off-die SDRAM build: v2.8.4.
71+
- Anything on hardware: v2.9.2. **No hardware has run any bitstream.**

0 commit comments

Comments
 (0)