Search › A-Z › N › Neo Geo Pocket Color
Neo Geo Pocket Color
This is the SNK Neo Geo Pocket Color running in your browser: the RACE core (a portable C emulator for the Neo Geo Pocket and Pocket Color) compiled to WebAssembly with Emscripten and self-hosted, no CDN. It boots with RACE's built-in HLE BIOS replacement, so no proprietary SNK BIOS is needed, and plugs into the shared in-frame debugger for the Toshiba TLCS-900/H CPU.
Runs on: Web browser
Neo Geo Pocket Color Online Emulator
Play Neo Geo Pocket Color using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| Fractal | Neo Geo Pocket Color | SNK Neo Geo Pocket Color | open | Open ⛶ | |
| Snake | Neo Geo Pocket Color | SNK Neo Geo Pocket Color | open | Open ⛶ |
Machines emulated
Chips
Notes
Embedding
RACE is a C emulator for the Neo Geo Pocket / Pocket Color. We compile its core to WebAssembly with Emscripten and vendor race.js + race.wasm - no CDN. A small C shim (race_wrap.c) exports a handful of EMSCRIPTEN_KEEPALIVE entry points that a short boot script drives.
Boot and load a ROM. Instantiate the module, copy the ROM into its heap, and call ngpc_load:
const mod = await RaceModule({ locateFile: f => base + f });
const load = mod.cwrap('ngpc_load', 'number', ['number', 'number']);
const rom = new Uint8Array(await (await fetch(url)).arrayBuffer());
const p = mod._malloc(rom.length); mod.HEAPU8.set(rom, p);
load(p, rom.length); // -> handleInputFile -> boots the HLE BIOS + cart
Run and inspect. The shim exposes the whole machine so a host page can do far more than render:
| Export | What it does |
|---|---|
ngpc_run_frame() | Emulate one video frame (TLCS-900/H for 6144000/60 cycles, VDP + Z80 sound in lockstep). |
ngpc_step_insn() | Execute a single CPU instruction and return its cycle count, the debugger's step button. |
ngpc_pc() | The current program counter. |
ngpc_reg(i) / ngpc_set_reg(i,v) | Read / write the banked register file (XWA0..XHL3, XIX/XIY/XIZ, XSP, PC, SR, XSSP, XNSP). |
ngpc_read(a) | Side-effect-free byte read of the 24-bit address space (skips sound/flash I/O) for the memory views. |
ngpc_write(a,v) | Poke a byte through the normal write path. |
ngpc_set_input(mask) | Set the gamepad latch (bit0 Up, 1 Down, 2 Left, 3 Right, 4 A, 5 B, 6 Option). |
ngpc_fb() | Pointer to the 160×152 RGB565 framebuffer inside the wasm heap. |
ngpc_reset() | Re-seed the machine from the loaded ROM. |
The boot script owns the requestAnimationFrame loop, so pausing simply stops calling ngpc_run_frame; when breakpoints or watchpoints are armed it switches to ngpc_step_insn and checks the PC / watched addresses after every instruction.
Debugger integration
The machine plug-in (ngpc-debug.js) reads the live core from window.EMU_BOOT and calls EmuKit.defineMachine. It binds the Toshiba TLCS-900/H register file, three side-effect-free memory chips (CPU RAM, cartridge ROM, video/IO RAM), and an on-screen NGPC gamepad.
New CPU decoder. The TLCS-900/H is not a 6502/Z80, so a new disassembler lives at /debugger/src/cpus/tlcs900.js. It reproduces the CPU's two-level opcode map: a 256-entry first-byte table (control, immediate loads, relative branches, register push/pop) plus eight addressing-prefix families (0x80–0xF7) that select a source/destination operand and then read a second opcode byte from one of seven operation tables. Those seven tables and the per-opcode immediate sizes were generated directly from the RACE core's own dispatch tables so instruction lengths match the real PC advance, which keeps the overlapping-column disassembly in sync. Undefined encodings fall back to .byte.
Breakpoints and watchpoints. Execution breakpoints are a set of PC values the step loop checks before each instruction; watchpoints snapshot the watched byte and pause the moment it changes. Both are wired through the shared transport.
Architecture
The Neo Geo Pocket Color (1999) is SNK's 16-bit colour handheld. Its CPU is a Toshiba TLCS-900/H running at about 6.144 MHz, with a secondary Z80 for sound and a tile/sprite VDP driving a 160×152 LCD.
- TLCS-900/H - a 32-bit-internal CPU with a banked general-register file (four banks of XWA/XBC/XDE/XHL), index registers XIX/XIY/XIZ, and a system/normal stack pair. RACE interprets it in
tlcs900h.c. - VDP - two scrolling tile planes plus sprites, an 8-bit-internal colour palette; the renderer walks scanlines into a 160×152 RGB565 framebuffer.
- Z80 + sound - a T6W28 (SN76489-like) tone/noise chip plus a DAC, clocked by the main CPU through shared registers.
- BIOS - this build boots with RACE's built-in HLE BIOS replacement (the "koyote" snapshot embedded in the core), so no proprietary SNK BIOS image is needed.
Because the core is ordinary C compiled to wasm, the whole machine state, registers, RAM, ROM, VDP memory, is inspectable live from the host page, which is what the debugger plugs into.