SearchA-ZC › cpm-z80

cpm-z80

2012 Open source · GPL-2 System ROMs · grey Online

cpm-z80 is a complete CP/M 2.2 system that runs in the browser and boots straight to the A> console prompt. The Intel 8080 CPU is a compact pure-JavaScript core (Alexander Demin's i8080.js); on top of it, an original JavaScript BDOS and BIOS host the genuine Digital Research Console Command Processor over a small RAM disk, with the console drawn to an 80×24 canvas text grid like a real CP/M terminal. Because the CCP runs as real 8080 code and calls the BDOS through CALL 5, the whole operating system can be single-stepped and inspected live.

Visit the i8080-js CPU core on GitHub ↗

Visit the official site ↗

Runs on: Web browser

cpm-z80 Online Emulator

Play cpm-z80 using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
CP/M 2.2 consolecpm-z80Digital Research CP/MgreyOpen ⛶

Operating system

Chips

Notes

Embedding

The emulator is two independent pieces: a vendored Intel 8080 CPU core (i8080.js) and an original JavaScript CP/M environment (cpm-machine.js). CP/M itself is the genuine Digital Research Console Command Processor, loaded as an 8080 binary at 0xF400; the BDOS and BIOS are emulated in JavaScript, RunCPM-style, by trapping the well-known CP/M entry addresses. Because the CCP is real 8080 code and calls the BDOS through the CALL 5 vector, the whole operating system is visible to the debugger.

Boot. Install the page-zero vectors, the BDOS serial number the CCP validates, and the BIOS jump table; load the CCP; then run your own loop over cpu.instruction() (one 8080 instruction) that intercepts the trap addresses:

var cpu = new I8080(memoryBus, ioBus);       // vendored 8080 core
installLow();                              // 0x0005 JMP BDOS, serial @0xFC00, BIOS @0xFE00
loadCCP(0xF400);                         // genuine DR CCP
cpu.pc = 0xF400;
(function frame(){
  for (var i = 0; i < BUDGET; i++) {
    var pc = cpu.pc;
    if (pc === BDOS_TRAP) { bdos(); continue; }   // handle in JS, then RET
    if (isBiosTrap(pc)) { bios(pc); continue; }
    cpu.instruction();                       // one 8080 instruction
  }
  requestAnimationFrame(frame);
})();

The machine is plain objects. Everything the debugger needs is a field or method on the core. There is no wasm heap to reach into:

MemberKindWhat it does
cpu.instruction()methodExecute exactly one 8080 instruction; returns its cycle count. The single-step primitive.
cpu.pc / cpu.spfieldLive program counter and stack pointer (plain, writable numbers).
cpu.a()cpu.l() / cpu.set_reg(r,v)methodThe 8080 register file (A B C D E H L); flags are cpu.sf .zf .hf .pf .cf.
memoryBus.read(a) / .write(a,v)methodThe 64 KB address space the CPU sees - poke memory live.
bdos() / bios(n)trapJavaScript implementations of the CP/M system calls, reached by intercepting the CCP's CALL 5 and BIOS-vector addresses.

Because the CPU and memory are ordinary JavaScript, the debugger single-steps with cpu.instruction(), reads and writes registers straight off the core, and implements breakpoints and watchpoints as host-side checks around the loop. No changes to the emulator.

Debugger integration

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

  • Registers are read live from the 8080 core each refresh (A, B, C, D, E, H, L, SP, PC and the S Z H P C flags) and written back through set_reg.
  • Disassembly uses the shared z80 decoder: the Z80 is a superset of the 8080, so it renders CP/M's 8080 code correctly, mnemonics and all.
  • Memory is the full 64 KB, read side-effect-free straight from the RAM array - you can watch the CCP, the TPA and a running .COM at once.
  • Single step is one cpu.instruction(); breakpoints and watchpoints are host-side checks in the boot loop. Because console input parks the CPU at the BDOS trap, stepping at the A> prompt does nothing until you type; step through a transient program instead.

Architecture

CP/M 2.2 is Digital Research's operating system for 8080 and Z80 computers, the direct ancestor of MS-DOS. It has three layers, and this build keeps each one honest:

  • CCP - the Console Command Processor: prints A>, reads a line, runs its built-ins (DIR, TYPE, ERA, REN…) or loads a .COM transient into the TPA at 0x0100. This is the genuine Digital Research CCP, running as 8080 code.
  • BDOS - the Basic Disk Operating System: the machine-independent system calls (console I/O, the file system) reached through CALL 5. Emulated in JavaScript over a small read-only RAM disk.
  • BIOS - the hardware layer: character I/O and disk vectors. Emulated in JavaScript; the console is a glass-TTY rendered to an 80×24 canvas text grid, the way a real CP/M terminal drew characters.

The disk boots with two freely-distributed 8080 diagnostics - TEST.COM (Microcosm Associates' 8080/8085 CPU diagnostic) and 8080PRE.COM (the 8080 preliminary test) - so DIR shows files and you can run and single-step a real transient program.