Skip to content
Mustafa Tarhan

NES Emulator on a Raspberry Pi

A plug-in retro console: the 6502 CPU, picture and sound chips of the NES, written from scratch in C++.

Embedded systems · course project2024 – 2025Complete

Super Mario Bros. and Donkey Kong display correctly. The scanline-timing test ROM doesn't yet.

Role
Course project at HTW Berlin: the emulator (CPU, PPU, APU, cartridge loading, ROM menu) and the full systems-engineering documentation.
CPU opcodes
150 of 151
Mapper
NROM
Output
SDL2, 16:15, with sound
Stack
C++17, SDL2, Raspberry Pi, Linux, Make, Mermaid / PlantUML

The idea

Original NES consoles have turned into collector's items. The goal was a cheap plug-and-play replacement: a Raspberry Pi that boots straight into a ROM menu, plays games from a USB stick with a wired USB gamepad, and goes back to the menu when you hold A + B + Start + Select for five seconds.

Requirements first

The project mixed V-model phases with short iterations, and every document lives in the repository: problem statement, stakeholders and their needs, operational concept, system requirements, architecture and design, test cases. Traceability matrices link each stakeholder need through requirements and architecture down to the tests that check it. I wrote those documents and the emulator itself.

A wired controller instead of Bluetooth (weighted trade-off)

Why
It scored 2.9 against 2.2: cheaper and half the programming work, at the price of some comfort.
Cost
A cable to the console.

Architecture

  1. User interface
    • ROM menulists the ROMs on the USB stick
    • ControllerUSB gamepad via SDL2
  2. Emulation
    • CPU150 opcode handlers, interrupts
    • PPUbackground and sprites, 64-colour palette
    • APU2 square, triangle, noise
  3. Memory
    • RAM and memory mapPPU, APU and controller registers
    • VRAM and OAM
    • ROM loaderiNES header, NROM mapper
  4. Platform
    • SDL2 rendererfull screen, 16:15 with black bars
    • Raspberry Pi, Linux
From the system design and the C++ sources. Components talk to each other only through the emulated memory map, as on the real hardware.

Inside the emulator

  • CPU: 150 of the 151 official 6502 opcodes, each with its addressing mode and flag behaviour, plus reset, NMI and IRQ.
  • Memory map: the RAM class mirrors memory and routes reads and writes to the PPU, APU and controller registers, the way the real board is wired.
  • PPU: draws background tiles and up to 8 sprites per scanline from OAM, like the hardware, then turns palette indices into RGB frames that SDL2 scales to the screen in the original 16:15 aspect ratio.
  • APU: two square-wave channels, a triangle and a noise channel, mixed and streamed to SDL2 audio.
  • Cartridges: a ROM loader behind a format interface that can take more mappers. NROM is the one that exists.

Testing and what's missing

Three test ROMs map to the requirements: nestest for the CPU (logged and compared with the reference output), a scanline ROM for PPU timing, and a small game for sprites and input. Commercial games such as Super Mario Bros. and Donkey Kong display correctly.

Still open: the scanline-timing test ROM doesn't produce the right picture yet, and only the NROM mapper exists, so games that need another mapper won't run.