RustyNES v2.9.9 — "Ballast" (the release candidate: the audits re-run, MMC3 and MMC5 by their documentation, audio exact across save states, and the MiSTer core moved onto it)
LatestRustyNES v2.9.9 — "Ballast"
The release candidate for v3.0.0. It re-audits the whole project, fixes what that found, corrects the MMC3 interrupt timing and the MMC5's graphics banking from their documentation, makes audio exact across save states, and moves the MiSTer core onto this emulator so the two agree again. It also cuts the release-candidate bitstream pair. Read the breaking changes before upgrading.
Breaking changes
v2.9.9 follows v2.9.8's rule: a file that cannot be read correctly is refused with a message, not read on a guess. v3.0.0's notes will list these again with v2.9.8's.
- Save states from v2.9.8 are refused. Three sections changed:
- the APU section now carries the audio resampler's state;
- the MMC3 section, because its interrupt timing changed;
- the MMC5 section, because it now records the sprite size it reads from the PPU.
- Movies older than this release are refused. A movie and a netplay session check that both sides run the same machine, and that check now covers the PRG and CHR sizes and two header bits.
- On phones, your saves move once. Android and iOS now find saves by the game's identity, as the desktop has since v2.9.8. Existing battery saves, suspend states, library entries and per-game settings are moved to it the first time a game is opened. Each copy is checked before the original is removed. Cloud copies are not moved: the next upload makes new ones.
- For developers:
- the
mmc3-m2-phase-irqfeature is removed, because its behaviour is now the default; BoardDescription::captureis no longerconst;CartridgeandBoardDescriptionhave new fields.
- the
Accuracy
- MMC3 interrupts arrive on the right scanline. In blargg's
4-scanline_timingtest the emulator raised the MMC3 interrupt a scanline late. The cause was a condition the NESdev page does not have. The emulator now follows the page's rule, and the interrupt is raised at the next per-cycle step after the counter fires, so a rise that lands after the CPU's access is seen a cycle later, as the chip's registered output is. The MiSTer core and the emulator now agree on every bus cycle of its MMC3 interrupt test. The test now gets to sub-test 9, against 3 before, andmmc3_test/5-MMC3passes. Sixteen commercial MMC3 baselines moved, by their audio and at most three cycles; each one was attributed. - MMC5 picks its graphics banks the way the chip does. It now reads the sprite size from the PPU itself. With 8x8 sprites it uses one register set for everything. With 8x16 sprites the background uses the other set while drawing, and
$2007uses the set written last. The 8, 4 and 2 KiB modes also select the right bank now. This fixes Uchuu Keibitai SDF's intro, which reads its data through$2007and had drawn garbage. The other local MMC5 games are unchanged. - Audio is exact across a save state. Loading a state used to drop about 17 samples and click, and the sound never quite matched a run that had not loaded. A load now resumes exactly, so rollback and run-ahead also stay bit-for-bit.
$4017's interrupt inhibit takes effect on the write, in both directions.
Re-audit
All four scopes were audited again: the core, the frontends, the libretro core and the MiSTer core's RTL. No earlier fix had regressed. The findings that were new are fixed or decided:
- Desktop:
- Reset, Power Cycle, disk swaps and state loads are refused on every route while a movie or netplay runs, including the hotkeys.
- Loading a ROM ends a movie session, and offers to save a recording in progress.
- Exporting a movie keeps the recording going.
- FDS:
- A movie, TAStudio or netplay session no longer writes your disk save.
- A game keeps its identity after its first disk save, so its save states and cheats are found again.
- Files the emulator reads: a corrupt save state can no longer turn the audio to noise or make later saves unloadable. A movie cannot overclock past the core's maximum.
- libretro: a refused state load says why in the log, and the Vs. coin pulse lasts three frames under run-ahead and rollback.
- Speed: restoring a state on a flash board (GTROM, UNROM 512) is about 11% faster, with the same result, which matters under run-ahead. The release's other performance leads were measured and not adopted.
- Smaller fixes:
- history-viewer clips;
- TAStudio and cheats;
- netplay spectators;
- the browser's save messages;
- a Vs. cabinet's live settings;
- the per-game settings on a command-line load.
- Provenance: four more files are recorded as derived from Mesen2 or TriCNES. They are the APU's DMC-DMA state, the frame counter's
$4015clear, the Vs. DualSystem orchestration and the Namco 163 level. Nothing was reworded or removed, and the licence is unchanged.
The MiSTer core
- It now agrees with this emulator's v2.9.9. Its reference moved from v2.9.2. Every difference that showed up was traced to an emulator change before the references were regenerated.
- Four fixes, each written from the emulator's documentation:
$4017's inhibit on the write;- one length-counter clock when a mode-1 write meets the sequencer's own step;
- the sequencer keeps running until a reset lands (it had stopped, and only blargg's
apu_test_9and_10could see it); - the first sprite pixel at X=0 on odd frames.
- New gates: blargg's
apu_test1-10, and the MMC3 interrupt test that had been held back until the emulator's fix. It now matches on every bus cycle. - A NES 2.0 header naming a board variant the core does not build is refused, with a message on screen. The bus-conflict variants load as the base board, a stated inaccuracy.
- A
$4017inhibit write landing exactly on a frame-IRQ point now clears last, as the emulator does. No ROM reaches that cycle, so four directed stimuli gate it. - The co-simulation ladder is 199 passed, 0 failed, 1 expected failure on-die and 200 passed, 0 failed, 1 expected failure off-die, each from one run of a frozen tree.
- The release-candidate bitstreams. Both builds are compiled at fitter seed 6, chosen from eight seeds swept on one build date (261005), and each one was compiled twice to the same bytes:
- on-die md5
10c2b2cee45737cc57c15daa3af1f862(timing margin +0.474 ns setup, +0.092 ns hold); - off-die md5
909e91c2a555348089aac22cb54aea18(+0.377 / +0.080 ns; the SDRAM read +0.451 / +1.183 ns, assuming zero board delay). - A first pair, compiled at seed 8 on 261004, was withdrawn because the
$4017fix changed the RTL after it.
- on-die md5
- No hardware has run either bitstream.
Verification
--features test-roms: 3,201 passed, 0 failed, 13 ignored.- The local commercial suites:
external_real_games60/0,external_extended137/0,external_coverage6/0 over every staged ROM. - AccuracyCoin 144/144, nestest 0-diff.
- Every moved baseline attributed; every fix has a test that failed before it.