Projects/Build a Game Boy Emulator

Build a Game Boy Emulator

Bring the Sharp LR35902 back to life. Each opcode, flag, and pixel comes with a spec checked against known-good values, so bugs surface the day you write them - not hours into a game. You finish with a working core that boots a real ROM into its main loop and draws the screen.

60 lessonsLarge~20 min / lessonOpcodesPPU
The project

What you'll build over the next 60 lessons

Over the next 60 lessons you'll build a working Game Boy core in the language of your choice, one small piece at a time. You start with the CPU's registers and memory, teach it arithmetic and the flags that make games behave, then layer on control flow, bit operations, and the cartridge, then interrupts, timing, and the picture-processing unit that draws a frame, filling in enough of the instruction set that a real cartridge boots and reaches its main loop, and finally wiring the picture and input through their hardware registers so the ROM's own graphics and controls come alive.

Every lesson is a single ~20-minute session anchored to a concrete spec with known-good values, and each lesson's code runs. What you end with is a genuine, runnable DMG core that executes nearly the full instruction set, boots a real cartridge, renders the background it chooses (scrolled, palettised) with its sprites, and responds to the buttons, not a polished emulator that plays any commercial game front to back. The “Scope & extensions” section below is honest about where it stops and what to build next.

build-a-game-boy-emulator / lesson-01.md
Lesson 01 · CPU registers & memory

The register file

Today you build the CPU's register file, the eight one-byte slots that hold every value the processor works with. Every instruction you write for the rest of the project reads from and writes to these registers, so getting the container right first makes everything after it trivial.

The goal

Build a register file that stores and returns a single byte in any of the CPU's eight registers.

Start here - the target
TO DO
Scenario: Storing a byte in register A
Givena fresh CPU with registers A, B, C, D, E, F, H, and L
WhenA is set to 0x12
Thenreading A returns 0x12
Andreading B still returns 0x00
Background

The heart of the Game Boy is the Sharp LR35902, an 8-bit CPU. Everything it does flows through eight one-byte registers named A, B, C, D, E, F, H, and L. A is the accumulator - most arithmetic lands there - and F holds status flags we will meet on lesson 5. The rest are general scratch space.

A register is just a byte of storage: you write a value in and read the same value back. Start here because every instruction you write for the rest of the project will move data into and out of these eight slots. Getting the container right first makes all of that trivial.

Make it work
// eight 8-bit registers, all starting at zero
type Registers struct {
A, B, C, D, E, F, H, L uint8
}
r := &Registers{}
r.A = 0x12
Further Reading

The DMG CPU has eight 8-bit registers. Any "Game Boy CPU manual" register summary covers them.

CheckpointDONE
The spec now works and your CPU can hold a byte in any of its eight registers. Commit and stop here.
Scope & extensions

Where this project stops - and where to go next

Far more than a boot-loop core: the CPU opcode table is essentially complete, and the picture now scrolls and palettises with live sprites while the controller answers input and the timer and joypad raise their interrupts. It still stops short of a general-purpose Game Boy, there is no LCD STAT or window layer, no sprite priority or 8x16 mode, no OAM DMA, only MBC1, and no sound. Those are the next climb, not the core.

Extend it next
  • Add LCD STAT (the mode flag, the LYC=LY coincidence, and its interrupt), which many games rely on for raster effects and safe VRAM/OAM access.
  • Add the window layer, the sprite background-priority bit, and 8x16 sprite mode.
  • Implement OAM DMA (0xFF46) so ROMs can refresh sprites the usual way instead of writing OAM by hand.
  • Support more cartridge mappers (MBC1 RAM banking, MBC3 with a real-time clock, MBC5) plus battery-backed saves.
  • Move toward cycle-accurate PPU mode timing (OAM scan / draw / HBlank) instead of an end-of-frame sync.
  • Add sound - the APU.
Recommended reading

Books & references that go deeper

  • The community-maintained technical reference for Game Boy hardware - the closest thing to an official spec.

  • Every opcode with its operands, flag effects, and cycle counts laid out on a single page.

  • A 33c3 conference talk covering the CPU, PPU, and memory map end to end, the best single overview of the hardware.

  • Cycle-accurate test ROMs used to verify CPU and timing correctness against real hardware behavior.

  • The long-standing test suite for CPU instruction and timing correctness that most emulator projects validate against.