SearchA-ZA › Luxor ABC80

Luxor ABC80

1978 Open source · MIT System ROMs · grey Online

The Luxor ABC80 (1978) is the Swedish Z80 home computer that taught a generation of Scandinavian schoolchildren to program, with its BASIC held entirely in ROM. This build runs in the browser and boots straight to the ABC80 BASIC screen — the "ABC80" herald and a blinking cursor. The Zilog Z80 CPU is a compact pure-JavaScript core (Molly Howell's Z80.js, MIT); around it, an original JavaScript machine adds the ABC80 memory map, the 40×24 text video drawn through the machine's character generator, a 50 Hz NMI real-time clock, and the interrupt-mode-2 keyboard with the Swedish Å Ä Ö. The BASIC and character ROMs are grey ABC80 system firmware, self-hosted and cited. Because the CPU, ROM and RAM are ordinary JavaScript, the whole machine can be single-stepped, breakpointed and inspected live.

Visit the Z80.js CPU core on GitHub ↗

Visit the official site ↗

Runs on: Web browser

Luxor ABC80 Online Emulator

Play Luxor ABC80 using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
ABC80 BASICLuxor ABC80Luxor ABC80greyOpen ⛶
HEJ demoLuxor ABC80Luxor ABC80openOpen ⛶
Kvadrat (squares)Luxor ABC80Luxor ABC80openOpen ⛶
Mönster (pattern)Luxor ABC80Luxor ABC80openOpen ⛶

Chips

Notes

Embedding

The emulator is three vendored pieces: a Z80 CPU core (Z80.js, MIT), the ABC80 system ROMs + character generator (abc80-roms.js, grey firmware from abc80sim), and an original JavaScript ABC80 machine (abc80-machine.js). The machine owns its own run loop rather than free-running, so the debugger can pause, single-step and breakpoint it.

Boot. Build the machine on a <canvas>; it installs the ROMs, wires the Z80 to an ABC80 memory map and I/O ports, and runs a 50 Hz frame loop. Each frame runs a frame's worth of Z80 instructions, then fires the vertical-retrace NMI that drives the real-time clock and the cursor blink; a pending key is offered to the CPU as an interrupt-mode-2 interrupt after each instruction:

var m = ABC80.boot(canvas);          // installs ROMs, returns the machine
// inside the machine's own frame loop:
while (tstates < target) {
  tstates += z80.run_instruction();    // one Z80 instruction
  if (keyPending) serviceKeyIRQ();     // IM2 keyboard interrupt
}
z80.interrupt(true, 0);              // 50 Hz NMI: clock + vsync + cursor

Everything the debugger needs is a plain object — there is no wasm heap to reach into:

MemberKindWhat it does
z80.run_instruction()methodExecute exactly one Z80 instruction; returns its T-cycle count. The single-step primitive.
z80.getState() / setState()methodRead/write the whole register file (AF BC DE HL IX IY SP PC I R and the flags).
z80.interrupt(nmi, vec)methodRaise an NMI (clock) or, in IM2, a maskable interrupt with a data-bus vector (keyboard).
readByte(a) / writeByte(a,v)methodSide-effect-free view of the 64 KB map (ROM shadow + RAM) for the hex/disasm panes.
pressKey(code) / releaseKey()methodPush a 7-bit ABC80 key code; the loop delivers it as an IM2 interrupt.

Because the CPU, ROM and RAM are ordinary JavaScript, the debugger single-steps with run_instruction(), reads and writes registers through getState/setState, and implements breakpoints and watchpoints as host-side checks in the loop — no changes to the CPU core.

Debugger integration

The plug-in (abc80-debug.js) describes the machine to the shared debugger and nothing more:

  • Registers are read live from the Z80 core each refresh (A B C D E H L, IX IY SP PC, I R and the S Z H P/V N C flags) and written back through setState.
  • Disassembly uses the shared z80 decoder over the full 64 KB: BASIC and the monitor at 0x0000-0x3FFF, the device ROM at 0x4000-0x7BFF, the video RAM at 0x7C00-0x7FFF, and work RAM above.
  • Memory is read side-effect-free from the ROM shadow / RAM arrays, so opening a hex or disassembly window never disturbs the running machine.
  • Single step is one run_instruction(); breakpoints are a PC set checked before each instruction; watchpoints wrap the memory-write path and pause the loop the moment a watched address changes. At the READY prompt the ROM sits in a keyboard-poll loop, so stepping there walks that poll — set a breakpoint inside a running program, or step after RUN, to watch real BASIC interpreter code.
  • Keyboard — the on-screen ABC80 keyboard (and the physical one) feed 7-bit key codes straight into the machine, raising the same interrupt-mode-2 interrupt the real PIO-A did; the Swedish Å Ä Ö sit where the ABC80 character ROM keeps them.

Architecture

The Luxor ABC80 (1978) is the Swedish Z80 home computer that taught a generation of Scandinavian schoolchildren to program; its BASIC lives entirely in ROM. This build models the 40-column machine:

  • Zilog Z80 at ~3 MHz, run one instruction at a time by a compact pure-JavaScript core. It uses interrupt mode 2 for the keyboard and a 50 Hz NMI for the real-time clock and cursor.
  • Memory — 16 KB BASIC/monitor ROM at 0x0000, the device (DOS) ROM at 0x4000, 1 KB of video RAM at 0x7C00, and work RAM above 0x8000.
  • Video — a 40×24 text screen of 6×10 characters, drawn from the ABC80 character generator through the machine's interleaved address map, with the inline colour/graphics control codes and the software cursor (a blinking inverse-video cell) that the ROM itself maintains.
  • Keyboard — the ABC80's intelligent keyboard delivered a 7-bit code per key over PIO-A; here host key presses become those codes, complete with the Swedish letters.

The BASIC and character ROMs are grey system firmware — long out of production, universally redistributed for the ABC80 — self-hosted here and cited. The Z80 core is MIT-licensed.