Roadmap
Last updated:
This chapter is a list of milestones to aim for while building the emulator. The rest of the book follows the order you'd actually build things in, while still working as reference.
Especially if it's your first emulator, I think momentum increases the chances of finishing it.
Every milestone ends in something you can verify. The concepts get explained, but each one closes with concrete work that proves your code actually does what it should.
Here's the milestones:
Draw the graphics stored in a cartridge. Pull the art straight out of the ROM and onto the screen, before implementing any chips — so you see something early.
Diff against
nestest. Build the CPU and check it againstnestest, a test ROM with a reference log — so you add opcodes incrementally instead of all at once.Diff against Mesen. This is pretty much the same as nestest, except we can pick any ROM we want, and we compare our log to that of Mesen (a mature, well-tested NES emulator), while both run, line by line.
Render one of the nametables in real time, in grayscale. A nametable (also called the name table) is the grid of tiles that makes up a background screen. Instead of dumping one frame to a file like in milestone 1, put it in a window and redraw it every frame as the game runs — still grayscale, no palette. This is where the emulator starts to feel live.
Render the background, for real. The same screen as milestone 4, but built the way the console builds it: color from the palettes, horizontal and vertical scrolling, and the frame produced one pixel at a time by the background pipeline instead of read straight off the nametable. Still no sprites — just the world, in color and in motion.
Sprites. The up-to-64 movable tiles the PPU calls objects: sprite evaluation and the 8-per-scanline limit, then getting them on screen in the right place, palette, and flip. Drawn over the backdrop on their own, so you can check the sprite system without the background tangled in.
Composite the background and sprites. Run both pipelines together and pick one pixel per dot — the front-or-behind priority that lets a sprite pass behind the scenery. Now sprites and the background share one screen the way they do in the game.
Sprite 0 hit. The flag the CPU polls to learn the beam has reached a known sprite — the classic mid-frame split, a static status bar over a scrolling playfield. The flag itself is a few lines; the real work is that the PPU and CPU now have to keep close enough time for a game to trust it. This is the first place rendering drives game logic.