Repository navigation
RustyNES v3.6.2 — "Latchkey" (the latest AccuracyCoin, 147 of 147, and Rad Racer's stray tiles corrected)
RustyNES v3.6.2 — "Latchkey"
A patch release on v3.6.1 "Threshold". It brings the latest AccuracyCoin, passed in full, and hides Rad Racer's stray tiles at the right of the road and the horizon with a switchable per-game correction. Movies and netplay peers from v3.6.1 are refused (emulation epoch 10, .rnm format 8), with a message naming both epochs. Save states from v3.6.1 load, and netplay protocol 9 is unchanged.
Fixed
- Rad Racer's stray tiles at the right of the road and the horizon.
- The glitch. While the car is driving, a wrong 8-pixel tile appears in the sand right of the road, just below the middle of the screen, on about one frame in eleven. On most frames there is also a wrong tile at the right of the band where the ground meets the horizon.
- The cause. The game writes the PPU's address register (
$2006) in the middle of those scanlines, from loops timed off a sprite-0 hit. Their timing varies by a few dots from frame to frame. When the PPU's delayed copy of the new address lands inside an 8-dot tile fetch, that tile is fetched from two addresses: half from the old one and half from the new. - A real NES draws this too. In a 2012 nesdev thread, a player on a console describes "a very noticable glitch" on the right at that line.
- The correction. v3.6.2 adds a per-game correction, on by default for Rad Racer's three dumps (USA, Europe, and the Japanese Highway Star) and for no other game. It holds such a copy to the next tile boundary, so every tile is fetched from one address.
- It is a deliberate departure from the hardware. ADR 0051 records the decision.
- To see the console's own picture, tick Settings > Enhancements > Turn off per-game picture corrections (
[enhancements] disable_game_corrections), or set the RetroArch core optionrustynes_game_correctionsto Off.
- Measured over two scripted 800-frame races:
- The dash in the sand appeared on 73 and 68 frames without the correction, and on none with it.
- With it, the picture differs from the hardware's only in tiles at the right of lines 107-139.
- The MiSTer core does not implement the correction; it draws what the hardware draws.
- A movie or netplay session started while paused used an option's previous setting. The CPU overclock, the sprite limit (both since v3.1.0) and the per-game corrections reached the console only when the next frame ran. A recording started before then captured, and replayed, the old value, and a netplay handshake announced it to the peer. Power-on and branch recordings and every netplay session, on the desktop and in the browser, now apply the configured options first. A branch from a playing movie keeps that movie's options, and a movie played from pause gives back the configured setting when it stops.
Withdrawn
- The attribute-read change this release first carried. It gave a tile's attribute fetch the address that fetch started with, to remove the same dash.
- Why it failed. The diagnosis was wrong: the dash comes from the tile-number (nametable) fetch's mixed address. With the change, the dash was still drawn on 68 to 73 of 800 frames, only grey instead of sky-coloured. The first measurement counted sky-coloured pixels only, so it missed that.
- What happens instead. The change is withdrawn in both cores, and every game's PPU behaves as in v3.6.1 (ADR 0030, "Withdrawal — 2026-11-06"). The per-game correction above is what removes the tiles.
AccuracyCoin
- Re-synced to upstream
66e87112, 147 of 147.- What changed upstream. Twelve commits since v3.1.0's
f5f41dc2:- one new test, DMC Playback Rate;
- revisions to DMA Sync Pretest and DMA Landing on Write;
- a stack fix in Misaligned OAM Behavior;
- further checks in the DMC DMA tests.
- The result. The catalog has 152 rows, 147 of them scored, and every scored test passes, read from the ROM's own result bytes. The new ROM passed on its first run, with no emulator change.
- The mirror ROM. It runs the same tests on the MiSTer core and was rebuilt from the same commit. The emulator runs all 147 of its tests.
- What changed upstream. Twelve commits since v3.1.0's
- The emulation-epoch fingerprint records each probe ROM's hash, so a re-synced ROM shows up as a new probe rather than as moved emulation.
What changes in recorded play
- The emulation epoch rises to 10, and the movie format to 8.
- Rad Racer draws differently from the same inputs, and a movie or a netplay peer records whether the correction was on.
- So a v3.6.1 movie is refused with the reason instead of replaying to a different picture.
- Re-record v3.6.1 movies under v3.6.2, and keep both netplay peers on the same release and the same correction setting.
- No other golden, snapshot or commercial-ROM frame moved. The full suite with the test ROMs and the local commercial corpus passes: 4,067 tests in 202 binaries, none failing, 20 ignored by design. The correction is off for every test ROM.
The MiSTer core
- The attribute-read change is withdrawn here too.
- The stimulus written for it,
ppuatale494, stays. It walks a$2006copy one dot per line through 200 lines, so the copy lands inside attribute fetches at every phase, and its goldens come from the reverted oracle.
- The stimulus written for it,
- An older quadrant bug, found by that stimulus.
- On the dot a delayed
$2006copy took effect, the core picked the attribute's quadrant from the old address while the fetch already used the new one. That drew 74 pixels in the wrong palette. - The bug predates this release. The quadrant now follows the fetch address, and its mutant is caught.
- On the dot a delayed
- AccuracyCoin's new ROM: the core's 30 AccuracyCoin entry gates, each comparing one test's result with the oracle's, all pass on the release tree. The 147 of 147 above is the oracle's own run: the core's ladder has no gate that runs the whole ROM.
- The save engine on a region change. v3.6.1's notes listed three possible races, reported in review, when the Region option changes at the moment of a save, a load or a rewind capture. A stimulus for each confirmed all three, and all three are fixed, along with a fourth found later:
- A save during a clock switch. The save engine's hold did not wait for the clock switch, so the CPU chain moved 1,079 clocks during the reset (1,077 off the die). The hold now waits for the engine to go idle and the clock switch to finish, and a claimed save takes the hold.
- A PAL to Dendy change. The console kept running while the hold was up: 53 clocks moved over 300 region changes (54 off the die). The hold is now a term of the console reset, and none move.
- A request on the hold's own edge got no completion pulse. It now does.
- A request under way on the region change's own clock (found in the MiSTer core's review, 2026-11-07, after this release was published). The engine only noticed the change a clock later, so a save interrupted before its first word could empty its slot instead of keeping it. The change now abandons on its own clock (sibling
6e824e8); a new stimulus catches the old wiring, and the bitstreams below include the fix.
- Save-state layout fingerprints:
BEE10697on the die (4,098 chain bits) andB72EFC82off the die (4,737), the same as v3.6.1's. The withdrawn change had added 6 bits to the save chain, and the withdrawal removes them. - Co-simulation ladders against this release's oracle (its goldens re-exported from the withdrawal commit, where
VERIFY=1moved onlyppuatale494's two artifacts): 355 passed, 0 failed, 4 expected failures on the die, one run with nothing skipped, with all 30 AccuracyCoin entry gates passing. The off-die run (USE_SDRAM=1), which was still running when this release was cut, finished at 413 passed, 0 failed, 10 expected failures, also one run with nothing skipped. Both ladders were run again on the MiSTer core's release RTL, after the fourth race was fixed, against this release's merge64eaa051(whereVERIFY=1reproduces all 285 stems, 1,311 artifacts, byte for byte): the same 355 / 0 / 4 and 413 / 0 / 10 (added 2026-11-07). - New bitstreams, compiled from the MiSTer core's release tree, which pins this release's merge commit, and attached here and to the MiSTer core's v3.6.2 release (added 2026-11-07, after this release was published):
RustyNES_MiSTer-v3.6.2.rbf(off-die, md597310724549c187e1c6be7aeeae9989d) andRustyNES_MiSTer-v3.6.2-lite.rbf(on-die, md5052ba6f9f2f6f5ae59a22f6e54c4bc84). v3.6.1's seed failed both builds at this release's date, so they use a new seed, 7, the only one of 1-8 closing both. The MiSTer core's review also found and fixed a fourth save-state race on a region change, so a first pair attached here earlier on 2026-11-07 was replaced the same day. Their margins and the seed table are in its notes. - Release candidate, not hardware-verified: no hardware has run any bitstream.
Tools
rad_racer_movierecords a scripted race as an.rnmmovie.rad_racer_provgains--rect(print every pixel's provenance in a screen rectangle) and--events(list a frame's PPU register writes with their scanline and dot).- Both need the commercial-ROM feature and your own dump.
Verification
- The correction.
- Two PPU unit tests: a copy due inside a tile fetch is held and lands at the boundary with the same address the hardware path reaches there, and one due on a boundary lands at once. A mutant that never holds and one that drops the boundary's address increment each fail them. A third test switches rendering off, and off and back on, on every dot around a copy due on any dot of a tile fetch, at the middle of the line and at its last held group, and requires the same address as the hardware path from the landing on; a mutant that holds under the live rendering bit, and one that holds past the last group, each fail it.
tests/rad_racer_coherent_copy.rs, run against a local dump, counts the dash on 0 frames with the correction and 56 without it (frames 700-1100), so the count can see a dash.
- The withdrawal.
an_attribute_read_takes_the_live_bus_hybridpins the restored rule; the full withdrawn change fails it. - AccuracyCoin: 147 of 147 on the RAM decoder.
- The full suite with test ROMs and the local commercial corpus: 4,067 passed, 0 failed, 20 ignored, in 202 binaries.
- Lint and builds: clippy is clean for the workspace, every frontend feature set and both WebAssembly builds. The
no_stdcore build and the documentation build pass.
Install
- Download the pre-built binaries for Linux, macOS, and Windows below.
- The MiSTer bitstreams, a release candidate and not hardware-verified, are attached below: copy
RustyNES_MiSTer-v3.6.2.rbf(off-die, needs the SDRAM add-on) orRustyNES_MiSTer-v3.6.2-lite.rbf(on-die) to the MiSTer's_Consolefolder. - The WebAssembly build is live at doublegate.github.io/RustyNES.
- The RetroArch core is in RetroArch's Online Updater on the platforms the libretro buildbot publishes to.
- Licensed under GPL-3.0-or-later.