SearchA-ZJ › Jupiter Ace

Jupiter Ace

2020 Open source · GPL-3.0 Online

The Jupiter Ace (Jupiter Cantab, 1982) was the rare British home computer that ran FORTH in ROM instead of BASIC. This build pairs the reused JtyOne interpreted Z80 core with a compact, hand-written Ace machine (the 8K FORTH ROM, the mirrored bus, the keyboard matrix and the monochrome 32×24 display) and drives it from a pausable, instruction-steppable loop, so the shared debugger can single-step the Z80, read and write registers and memory, and set breakpoints. It boots straight to the FORTH prompt.

Visit the official site ↗

Runs on: Web browser

Jupiter Ace Online Emulator

Play Jupiter Ace using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
Jupiter Ace FORTHJupiter Acejupiter-acegreyOpen ⛶

Machines emulated

Jupiter Ace

Chips

Notes

Embedding

The Jupiter Ace has no ready-made JavaScript core with debugger access, so this build pairs the reused JtyOne interpreted Z80 (ace-z80.js, one instruction per doOpcode()) with a small hand-written machine (ace-machine.js). The machine is deliberately plain objects, so every part is a live handle for the debugger.

Boot. Construct the machine, fetch the 8K ROM, reset and run your own loop:

var ace = new AceMachine(canvas);
fetch('roms/ace.rom').then(r => r.arrayBuffer()).then(function(buf){
  ace.loadROM(new Uint8Array(buf));
  ace.reset();
  loop();                    // our 50Hz requestAnimationFrame loop
});

The machine map (matches the real Ace, cross-checked against EightyOne's ace.cpp): $0000 8K FORTH ROM, $2400 1K video RAM (32×24), $2C00 1K programmable character RAM (128 glyphs), $3C00 standard RAM, expansion above. Reads mirror several low pages and the character RAM reads back as $FF, exactly like the hardware; the display reads the raw arrays.

MemberKindWhat it does
ace.z80.doOpcode()methodExecute one Z80 instruction, return its T-states. The single-step primitive.
ace.runFrame(fast)methodRun one 50Hz frame then raise the IM1 interrupt and render. With breakpoints set it steps instruction-by-instruction and returns true on a hit.
ace.z80.get/set*methodLive Z80 registers (AF BC DE HL IX IY SP PC I R AF' IM).
ace.peek(a) / poke(a,v)methodRaw, side-effect-free 64K access for the debugger's hex/disasm views.
ace.readByte / writeByte / readPortmethodThe Z80 host interface: mirrored bus + the active-low keyboard port.

Debugger integration

The plug-in (jupiter-ace-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 ace.z80.doOpcode(). Breakpoints and watchpoints are host-side Sets: when either is non-empty runFrame switches from running a whole frame at once to stepping one instruction at a time, comparing getPC() before each and honouring a write-watch flag raised inside writeByte. When both are empty the frame runs in a single tight loop, so the debugger costs nothing while idle.

Architecture

The Jupiter Ace is an unusual 8-bit machine: it runs FORTH in ROM instead of BASIC. Hardware-wise it is close to a ZX81 done properly:

  • Z80A at 3.25MHz, the reused JtyOne interpreted core. A 50Hz maskable interrupt (IM1 / RST $38) drives the cursor flash and keyboard scan.
  • ace-machine.js - the bus (8K ROM, video RAM at $2400, character RAM at $2C00, RAM at $3C00 + expansion), the keyboard matrix (8 rows read active-low through even I/O ports, high address byte selecting the row) and the monochrome 32×24 display (a set pixel is white).
  • roms/ace.rom - the 8K Jupiter Cantab FORTH ROM.