ZX81
The Sinclair ZX81 running in the browser. This build vendors JtyOne, Simon Holdsworth's JavaScript port of Mike Wynne's EightyOne, and drives its interpreted Z80 core from a pausable, instruction-steppable loop, so the shared debugger can single-step the CPU, read and write registers and memory, and set breakpoints. It boots straight to the ZX81 BASIC "K" cursor.
Runs on: Web browser
ZX81 Online Emulator
Play ZX81 using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| ZX81 BASIC | ZX81 | Sinclair ZX81 | grey | Open ⛶ |
Machines emulated
Chips
Notes
Embedding
JtyOne is plain-global JavaScript with no bundler: three constructors (Z80, ZX81, ZX81Display) hang off the window. The stock ZX81EmulatorUI/JtyOne wrappers install a self-scheduling setTimeout loop that cannot be paused or single-stepped, so instead we wire the parts by hand and drive our own loop.
Boot. Build a keyboard, a display and the machine, then let the machine load its ROM (asynchronously) and call us back:
var kbd = new ZX81Keyboard();
var display = new ZX81Display(statusSpan, canvas);
var machine = new ZX81('', 0, 0, kbd.zxKeyboard); // no tape
machine.start(function(){ startOurLoop(); }); // fires once the 8K ROM has loaded + CPU reset
The machine is plain objects - there is no wasm heap. Everything the debugger needs is a live handle we exposed on the vendored core:
| Member | Kind | What it does |
|---|---|---|
machine.z80.doOpcode() | method | Execute exactly one Z80 instruction and return its T-state cost. This is our single-step primitive. |
machine.doScanLine(display) | method | Run a scanline's worth of CPU + raster the ZX81's software-generated picture into the display buffer. Our free-run loop calls this until a frame's vertical sync completes, then blits. |
machine.z80.get/set* | method | Live register access. The stock core exposed PC SP DE I R; we added AF BC HL IX IY AF' IM IFF as one-line accessors over its register array. |
machine.readByte(a) / writeByte(a,v) | method | The 64K bus. Reads are side-effect-free (safe for the auto-polling hex view); writes honour ROM protection below $2000. |
display.blit() | method | Copy the finished frame to the visible canvas (we exposed the core's private blit). |
The ZX81 has no display hardware. The ROM builds the picture by racing the beam with the CPU, which is why the frame runner is doScanLine rather than a separate video chip.
Debugger integration
The plug-in (zx81-debug.js) reads the live machine from window.EMU_BOOT and calls EmuKit.defineMachine with a transport, the full Z80 register set and the memory bus, reusing the shared z80 disassembler (/debugger/src/cpus/z80.js).
Single-step is machine.z80.doOpcode() - one instruction, registers update live. Free run calls doScanLine until the frame's vertical-sync completes, then display.blit().
Breakpoints are a Set of PC values. To avoid slowing the hot path when the debugger is idle, the vendored doScanLine only consults a hook when one is installed:
if (window.__ZX81BP && window.__ZX81BP(p.getPC())) { this._brk = true; break }
window.__ZX81BP is null whenever there are no breakpoints or watchpoints, so the per-instruction cost is a single truthy test only while you are actually using them. Watchpoints wrap machine.writeByte and raise the same halt flag when a watched address is written.
Architecture
The ZX81 is a Z80 with 8K of ROM and (here) 16K of RAM, and almost no dedicated hardware:
Z80- a readable interpreted core.doOpcode()fetches and executes one instruction (base page plus the CB/ED/DD/FD prefixes) and returns its T-states;interrupt()raises the 50Hz maskable interrupt andnmi()the display NMI.ZX81- the machine: the 64K bus ($0000ROM, RAM from$4000), the port handlers (keyboard on even ports, NMI generator control), anddoScanLine, which interleaves CPU execution with rastering the character picture the ROM paints by manipulating the R register and the video address.ZX81Display- turns the emulated beam into ARGB pixels and blits them to the canvas.ZX81Keyboard- an 8×5 key matrix; the stock core maps physical keys by character, so symbols land correctly.roms/zx81.rom- the 8K Sinclair/Nine Tiles system ROM, loaded at boot into the bottom of the bus.