retro-silicon

Nintendo Entertainment System · build log

The NES is complete

The NES is finished. Commercial games play at the desk on the Tang Nano 20K and the PYNQ-Z2, with picture and sound over HDMI and a USB gamepad, and they look and behave the same on both boards.

The checks are the same ones the test ROMs get. For 29 games from Chris’s own cartridges, MesenCE gives the frame at power-up and a frame after pressing Start twice, and each board must produce those frames exactly, as a CRC-32 of the palette values: 63 checks, all passing on both boards. The five games with battery saves, among them both Zeldas and Final Fantasy, start from a save made playing on the board, and their save memory must end up the same as MesenCE’s too. Behind the games, all 190 test ROMs in the golden list still pass on the Tang Nano 20K and the PYNQ-Z2, and all but two on the Tang Console 138K, whose block RAM can’t hold those two.

The last fix was pacing. The NES keeps time with the 60 Hz display it drives, but at the NES’s exact rate a frame had only 0.16% of a display frame to spare. Kirby’s Adventure, which reads a lot from the PYNQ-Z2’s DDR3, sometimes ran past that and waited a whole display frame, so busy scenes stuttered at half speed. Running the NES’s clock 2% fast, and letting it wait at the end of each frame, fixed it: Kirby now slows down only where the original console does.

The pictures and the music below come from the PYNQ-Z2. The music is Thwaite, a free homebrew game by Damian Yerrick, as the commercial games’ music isn’t ours to share.

The NES runs eight mappers: NROM, UxROM, CNROM, AxROM, MMC1, MMC2, MMC3 and MMC6. Save states work on the Tang Console 138K and the PYNQ-Z2; the Tang Nano 20K’s chip has no room for them alongside sound and HDMI.

Super Mario Bros.: Mario standing at the start of World 1-1, under a blue sky, with the score, coins, world and time along the top.
Super Mario Bros. at the start of World 1-1: frame 1,199 after two presses of Start, drawn by retro-silicon's NES on the PYNQ-Z2 and read back through its test shell, identical to MesenCE's pixel for pixel. © Nintendo; captured from retro-silicon on the PYNQ-Z2, Used under fair use; not covered by the site's licence.
Kirby's Adventure: Kirby on a grassy path in the first level, with a message box reading 'Right or Left makes Kirby walk or dash!'
Kirby's Adventure in its first level: frame 1,199 after two presses of Start, drawn by retro-silicon's NES on the PYNQ-Z2, with its 768 KB of program ROM in the board's DDR3, and identical to MesenCE's pixel for pixel. © HAL Laboratory / Nintendo; captured from retro-silicon on the PYNQ-Z2, Used under fair use; not covered by the site's licence.
The Legend of Zelda: Link on a sand path between green trees in the overworld, with the map, item slots and hearts along the top.
The Legend of Zelda in the overworld, started from a save made playing on the board: frame 1,199 after two presses of Start, drawn by retro-silicon's NES on the PYNQ-Z2 with that save in its battery RAM, and identical to MesenCE's pixel for pixel. © Nintendo; captured from retro-silicon on the PYNQ-Z2, Used under fair use; not covered by the site's licence.
Thwaite's music at the start of a game: the PYNQ-Z2's HDMI output, recorded at 48 kHz by a USB capture device. retro-silicon on the PYNQ-Z2; Thwaite by Damian Yerrick, GPL-3.0-or-later (source).