Emulator Project

Crumb
CHIP-8 Emulator

A CHIP-8 interpreter built from scratch in C — modeling the virtual machine directly, with registers, memory, a stack, timers, and a function-pointer opcode table driving the fetch-decode-execute cycle at the center of every emulator.

v1.0.0CCMakeSDL2MIT License
github.com/carson-js/crumb

Overview

The core of an emulator

Crumb models the CHIP-8 virtual machine directly in C — 16 general-purpose registers, 4KB of memory, a 16-level stack, an index register, and a program counter — and executes original CHIP-8 ROMs instruction by instruction.

The goal was to understand emulation at a low level: how opcodes get decoded, how fonts get memory-mapped, and how the interpreter pattern underneath CHIP-8 generalizes to most virtual machines.

CPU core
16 registers, 4KB memory, 16-level stack, PC & index register
Full instruction set
All 35 CHIP-8 opcodes (0x0–0xF) implemented
Opcode table
Dispatched through a function-pointer table
ROM loading
Loaded into memory starting at 0x200
Fontset
Built-in font mapped at 0x50 for the FX29 opcode
Timers
Delay and sound timers decrement each cycle

How It Works

Fetch, decode, execute

Once a ROM is loaded, main.c drives the emulation loop: poll input, run a CPU cycle, render the frame, repeat until the window is closed.

Each cycle, cpuCycle() fetches the next 2-byte opcode from memory at pc, advances the program counter, dispatches to the matching handler via op_table — indexed by the opcode's top nibble — and ticks the delay/sound timers.


Structure

Modular by design

The codebase splits CPU emulation from the platform layer, so the opcode logic stays independent of SDL2.

crumb/
├─main.centry point, CLI args, main loop
├─cpu.c / .hCPU state, opcode table, handlers
├─platform.c / .hSDL2 window, rendering, input
├─CMakeLists.txtbuild config

What's Next

Planned features

Crumb is actively being developed. These two are next on the list.

Audio beepPlay a tone while the sound timer is active
Debug modeStep through opcodes and inspect registers