Skip to content

Build a CHIP-8 emulator from scratch

C++23 · SDL3 · macOS

In 1977, Joseph Weisbecker wrote an interpreter for the RCA COSMAC VIP, a 2 KB desk-sized computer. The interpreter gave the machine a tiny instruction set, a 64×32 display, a 16-key keypad, and two timers. Programs written for it were just bytes — and because the bytes were interpreted, they ran on any machine with the same interpreter. The virtual machine was called CHIP-8. It never had a CPU of its own.

This tutorial builds that machine again, from an empty main.cpp, in modern C++ on a Mac. You will write the CPU loop, the memory, the display, the keypad, and the buzzer yourself. No emulator library, no game engine, no copied ROM listing: just 4,096 bytes of state and a while loop that advances it.

By the final chapter you will have:

  • a working CHIP-8 and SUPER-CHIP emulator, with the historical quirks selectable;
  • a test suite that proves it — golden traces, exhaustive decode, sanitizers;
  • an optional XO-CHIP extension, an assembler, and a rewind debugger;
  • a mental model that transfers to the Game Boy, the NES, and anything else with a fetch–decode–execute loop.

Start Chapter 1: A Computer in 4,096 Bytes See the roadmap

Why CHIP-8?

Most "write an emulator" advice points at the NES or the Game Boy, then abandons you somewhere around the PPU. CHIP-8 is different in a way that matters for learning:

  • The whole machine fits on one page. Sixteen registers, 4 KB of memory, 35 instructions, one display, sixteen keys.
  • The hard parts are still there. Fetch–decode–execute, timing, sprite collision, input, sound, compatibility, testing.
  • Failure is visible immediately. A wrong flag shows up in a test ROM in seconds, not after a week of black screens.
  • The platform is alive. People still write CHIP-8 games, and a mature test suite exists to tell you exactly what you got wrong.

Who this is for

You have written C++ before — variables, functions, classes, std::vector — but you have never emulated anything. You are on macOS, you can run cmake and clang++, and you want to understand the code rather than paste it.

You do not need to know SDL, assembly, or how a CPU works. This tutorial starts with a data sheet and a blank file.

How to use this tutorial

  1. Type the code. Every chapter shows the new pieces in small chunks, then the complete file so you can check yourself. Typing is where the learning happens.
  2. Build and run at each checkpoint. Every chapter ends with a program that works; nothing is left broken for "later".
  3. Run the checkpoint. It lists the exact things you should see. If they are not there, the troubleshooting table is the first place to look.
  4. Do at least one exercise. The stretch exercise is where the chapter's idea becomes yours.
  5. Say "next" when you are ready for the following chapter.

The machine comes first

Chapters 1–8 never open a window. You will see the CHIP-8 logo in your terminal before you see it on screen, and that is deliberate: when the window arrives in Chapter 9, you will know that the CPU was already correct.

The shape of the course

Part Chapters What it covers
I — The Machine 1–8 Memory, decode, the CPU loop, flags, timing, sprites
II — The Frontend 9–12 SDL3 window, keypad, sound, playable games
III — Getting It Right 13–14 Historical quirks, golden traces, sanitizers, fuzzing
IV — Bigger Machines 15–16 SUPER-CHIP, then optionally XO-CHIP
V — Tools of the Trade 17–19 Assembler, rewind debugger, performance
VI — Beyond 20 The design doc for your next emulator

The full chapter list, with prerequisites and status, is on the roadmap.

Before you start

You need Homebrew LLVM, CMake, and Ninja:

brew install llvm cmake ninja

SDL3 joins in Chapter 9, when there is something worth drawing:

brew install sdl3

Check that the compiler is the Homebrew one, not Apple's:

"$(brew --prefix llvm)/bin/clang++" --version

You should see Homebrew clang version 23 or newer. The project's CMakeLists.txt selects it for you; this command is just a sanity check.

The repository also contains the course's design notes, the CHIP-8 reference, and the verification log in references/. You do not need them to follow the tutorial, but they are there when you want to know why a chapter is shaped the way it is.