← All projects

01 / Computer architecture

NESmulator

My NES emulator in Rust. It has a 6502 CPU, a picture processing unit, and a memory bus, with SDL2 handling the window and input.

Rust · SDL2Personal project
View repository

The problem

An emulator has to reproduce the relationships between components, not just their individual operations. Executing an instruction changes registers and memory, advances time, and can affect what appears on screen.

How it is structured

The code separates the CPU, PPU, bus, ROM loader, rendering, and controller input. That separation gives hardware behavior a clear place in the implementation and makes individual edge cases easier to isolate.

CPU

Decode instructions and update execution state.

Bus

Map memory and coordinate component timing.

PPU

Turn graphics state into a rendered frame.

The memory bus

The bus contains memory mapping and tick coordination. CPU execution and graphics behavior meet through that shared boundary, rather than living in one large game loop.

CPU and PPU tests

The CPU tests include the indirect-JMP page-wrap behavior: two possible high-byte addresses hold different values, then the test asserts the resulting program counter. PPU tests cover memory mirroring and register behavior.

Current capabilities

  • 6502 instruction execution, including documented support for common unofficial opcodes.
  • Background and sprite rendering, nametable and palette mirroring, OAM DMA, and VBlank NMI.
  • NROM cartridge mapping and one standard controller through SDL2.

Scope & limitations

Audio, cartridge mappers beyond NROM, a second controller, and save states are still missing. The regression tests cover specific CPU and PPU behavior; they don’t establish compatibility with every game.

A detail worth looking at

The indirect-JMP test is a good example of the details involved. It checks a particular address-wrap behavior of the original CPU, rather than just whether an instruction produces the usual result.

Explore the source