Search › A-Z › S › Watara Supervision
Watara Supervision
The Watara Supervision (1992), also sold as the QuickShot Supervision, is an 8-bit handheld game console and one of the many Game Boy rivals of its era. This is the Potator emulator, whose portable C core is compiled to WebAssembly so it runs the machine directly in the browser. It is wired into the in-page debugger, where you can single-step the 65C02 CPU, set breakpoints and watchpoints, and inspect the whole memory map. The 65C02 core it reuses is a compact portable 6502/65C02 emulator, credited in the notes below.
Runs on: Web browser
Watara Supervision Online Emulator
Play Watara Supervision using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| Chimera | Watara Supervision | Watara Supervision | grey | Open ⛶ | |
| Super Pang | Watara Supervision | Watara Supervision | grey | Open ⛶ | |
| SSSnake | Watara Supervision | Watara Supervision | grey | Open ⛶ | |
| Journey to the West | Watara Supervision | Watara Supervision | grey | Open ⛶ | |
| Tennis Pro ’92 | Watara Supervision | Watara Supervision | grey | Open ⛶ | |
| Crystball | Watara Supervision | Watara Supervision | grey | Open ⛶ | |
| Plasma (65C02 demo) | Watara Supervision | Watara Supervision | open | Open ⛶ |
Machines emulated
Chips
Notes
Embedding
The online build is Potator, a Watara Supervision emulator (originally by Normmatt, this fork by infval), whose emulation core is portable C with no SDL dependency. We compile only that core to WebAssembly with Emscripten and reach it through a small hand-written shim (sv_shim.c) that exposes a handful of EMSCRIPTEN_KEEPALIVE entry points — there is never a per-cycle callback across the JS/wasm boundary.
Boot and load a ROM. The module is built with MODULARIZE, so loading supervision_core.js defines a SupervisionModule() factory. Instantiate it, cwrap the shim, copy the ROM image into the wasm heap and hand it over:
const Mod = await SupervisionModule();
const sv_init = Mod.cwrap('sv_init', null, []);
const sv_load = Mod.cwrap('sv_load', 'number', ['number', 'number']);
const sv_frame = Mod.cwrap('sv_frame', null, []);
sv_init(); // gpu_init + memorymap_init, 65C02 IPeriod = 256
const rom = new Uint8Array(await (await fetch(romUrl)).arrayBuffer());
const p = Mod._malloc(rom.length);
Mod.HEAPU8.set(rom, p);
sv_load(p, rom.length); // memorymap_load + hard reset
The shim surface. Everything the debugger needs is a plain C function; the wasm holds all machine state:
| Export | What it does |
|---|---|
sv_frame() | Run one whole video frame (256 CPU slices + timer + the vblank NMI) and blit the 160×160 LCD into an RGBA buffer. |
sv_step() | Execute exactly one 65C02 instruction (Exec6502). The single-step primitive. |
sv_render() | Re-scan the LCD out of video RAM without advancing the CPU, so a stepped state shows on screen. |
sv_fb() | Pointer to the 160×160 RGBA framebuffer inside the wasm heap, painted to a 2D canvas. |
sv_read(a) / sv_write(a,v) | Bus access over RAM / I/O / video RAM / ROM. sv_read is side-effect-free (reads the register file directly, never clearing a latch). |
sv_pc() | The 16-bit program counter. |
sv_getreg(i) / sv_setreg(i,v) | Read / write the register file: A, P, X, Y, S, PC. |
sv_key(bit,down) | Press or release a button (D-pad, A, B, Start, Select) on the controls latch. |
Debugger integration
Wiring the wasm core into the shared in-browser debugger needed one boot shim that owns the loop, plus a new 65C02 disassembler.
A host-owned loop. Rather than call any built-in frontend, the boot drives the core itself so pause / step / breakpoints work. With no breakpoints or watchpoints it runs a whole frame at once; otherwise it steps one instruction at a time and checks state between instructions:
function stepFrame(){
for (let i = 0; i < INSNS_PER_FRAME; i++) {
if (bps.has(sv.pc())) { running = false; return; } // execution breakpoint
const before = snapshotWatched();
sv.step(); // one 65C02 instruction
if (watchedChanged(before)) { running = false; return; }
}
sv.render();
}
Techniques for deeper access.
- A single-instruction primitive. The stock core only ran to a cycle boundary, so
Exec6502was added to the 65C02: a one-line step flag makesRun6502return right after one instruction, giving the debugger an exact step. - Side-effect-free reads. The hex and disassembly views read through
sv_read, which indexes the register file, RAM and ROM directly instead of routing through the hardware read path, so auto-polling a view never clears the timer or DMA latches. - Direct register state.
sv_getreg/sv_setregread and write the liveM6502struct; the status byte is surfaced as clickable N/V/B/D/I/Z/C flag chips. - Execution breakpoints. Because the loop is host-owned, a breakpoint is a JavaScript
Setof PC values compared againstsv_pc()before each instruction. - Write watchpoints. With no per-write hook across the wasm boundary, watched addresses are snapshotted before each instruction and compared after; a change pauses the loop — the same visible behaviour as a store watchpoint.
A new 65C02 decoder. debugger/src/cpus/w65c02.js was added: the shared NMOS 6502 table plus the 65C02 additions the Supervision runs (STZ, BRA, the stack ops PHX/PHY/PLX/PLY, TSB/TRB, BIT immediate, the (zp) indirect mode, JMP (abs,X)) and the Rockwell bit ops, with a .byte fall-back for raw data.
Architecture
The Watara Supervision (1992), also sold as the QuickShot Supervision, is an 8-bit handheld game console and one of the many Game Boy rivals of its era. It is built around a 65C02 (a CMOS 6502) running at about 4 MHz, with a 160×160 monochrome LCD showing four shades of grey.
- 65C02 CPU — the CMOS 6502: the accumulator A, index registers X and Y, stack pointer S, 16-bit PC and the N/V/B/D/I/Z/C status flags, plus the 65C02 instruction additions.
- Memory map — 8 KB system RAM at
$0000, the I/O register block at$2000, 8 KB video RAM at$4000that the LCD scans, and the cartridge ROM banked into$8000–$FFFF. - Video — a scanline is read straight out of video RAM using the
XPOS/YPOS/XSIZEregisters; each byte packs four 2-bit pixels. - Timer & interrupts — a programmable timer and a vertical-blank NMI drive the machine; two bytes at
$2024/$2025latch the timer and DMA interrupt sources.
The 65C02 core the machine runs is a compact portable 6502/65C02 emulator (the M6502 / M65C02 by Marat Fayzullin and contributors), reused unchanged inside Potator; only a single-instruction step entry point was added for the debugger. The whole machine lives inside the WebAssembly module, and the debugger reads it each refresh through the shim.