Game Boy (DMG) emulator written in TypeScript: full CPU, PPU, APU, timers, interrupts, MBC1/MBC3 cartridges, and Joypad — playable in the browser or in the terminal.
yarn installyarn web:build
yarn web:serveOpen http://localhost:8000/web/index.html, then drop a .gb/.gbc file
anywhere on the page (or use the file picker). No game is bundled — bring
your own ROM dump.
The browser frontend is also deployed automatically to GitHub Pages after
pushes to main. Enable Settings → Pages → Source: GitHub Actions once in
the repository settings.
- Canvas at 2x by default (fit / 3x / 4x available), 4 palettes, scanlines, fullscreen, touch-friendly buttons.
- Sound via Web Audio (starts on first key/click,
Mmutes). - Battery saves persist in localStorage; Reset/ROM-switch/tab-close all
persist first. Saves can also be downloaded as
.savor wiped. - Keyboard: arrows/WASD d-pad,
X/KB,Z/JA,Enterstart,Shiftselect,Ppause,Mmute.
yarn play <rom.gb> [ascii|hires]ASCII (80×36) or hires quadrant (80×72, auto-selected on tall terminals)
rendering at the original ~59.7 fps. Keys: arrows, X A, Z B, Enter
start, Backspace select, P pause, Q quit. Battery saves are written
next to the ROM as <rom>.sav.
yarn test # vitest, 190 testsCovers CPU registers/flags, 8/16-bit ALU, shifts/bits, memory bus, timer, interrupts, cartridge/MBC, PPU layers, APU channels (including a measured 440 Hz pitch test), joypad, SRAM save round-trip, and renderers.
src/cpu/— registers, instruction set +step(), 64 KiB bus, timer, interrupts, joypad, MBC1/MBC3 cartridgessrc/ppu/— scanline renderer (background, window, sprites), 160×144src/apu/— 4 sound channels (pulse+sweep, pulse, wave, noise), mixersrc/emulator.ts— platform-agnostic core: boot, frame loop (17556 M-cycles @ 59.7 Hz), save handlingsrc/web/— browser frontend (canvas, Web Audio, localStorage saves)src/terminal/— ASCII/hires terminal frontendsrc/main.ts— terminal entry point
- CPU passes its opcode/flag unit tests; timings follow gb-opcodes in M-cycles.
- APU sequencer runs off DIV bit 12 (512 Hz); DAC curve, HPF, and mixer follow PanDocs; pitch verified by measurement.
- No CGB/SGB features, no RTC ticking (stubbed), no link cable, no boot ROM (DMG post-boot state is set directly).
https://gbdev.io/pandocs/Specifications.html