SearchA-ZN › Neo Geo Pocket Color

Neo Geo Pocket Color

2006 Open source · GPL-2.0 Online

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.

Visit the source repository ↗

Visit the official site ↗

Runs on: Web browser

Neo Geo Pocket Color Online Emulator

Play Neo Geo Pocket Color using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
FractalNeo Geo Pocket ColorSNK Neo Geo Pocket ColoropenOpen ⛶
SnakeNeo Geo Pocket ColorSNK Neo Geo Pocket ColoropenOpen ⛶

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:

ExportWhat 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.