SearchA-ZN › NEC PC-6001

NEC PC-6001

1981 Online · runs in your browser Open source · MIT

The NEC PC-6001 (1981), sold in North America as the "NEC Trek", was NEC's entry-level Z80 home computer: a cartridge slot, cassette storage and an MC6847-based colour display, booting to N60-BASIC. This is a compact, from-scratch in-browser emulator: a hand-written PC-6001 machine driving the MIT Z80.js core, booting the freely-redistributable compatible N60-BASIC ROM to its "Ok" prompt. It plugs into the shared in-frame debugger, so you can single-step the Z80, set breakpoints and watchpoints, and inspect memory live.

Visit the official site ↗

Runs on: any modern browser — nothing to install.

NEC PC-6001 Online Emulator

Play NEC PC-6001 using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
N60-BASICNEC PC-6001NEC PC-6001greyOpen ⛶
Hello demoNEC PC-6001NEC PC-6001openOpen ⛶
Sine plot demoNEC PC-6001NEC PC-6001openOpen ⛶

Machines emulated

Chips

Notes

Embedding

There is no off-the-shelf browser core for the PC-6001, so this build is a small hand-written machine, pc6001.js, wrapped around the MIT Z80.js interpreter core. We own the run-loop instead of any upstream one, so the debugger can pause, single-step and breakpoint it.

Boot. Create the machine on a <canvas>, fetch the two ROM images (the LGPL compatible N60-BASIC ROM at $0000-$3FFF and the CG ROM font), reset, then run your own loop over cpu.run_instruction() (one Z80 instruction) while asserting one IM-2 interrupt per frame:

var m = new PC6001(canvas);
m.loadRoms(basicBytes, cgBytes);   // $0000-$3FFF ROM + 4K CG font
m.reset();                        // di; jp COLD  (PC <- $0000)
(function frame(){
  m.serviceInterrupt();             // one IM2 int: key ($02) > strig (6) > timer ($06)
  var used = 0;
  while (used < PER_FRAME) used += m.cpu.run_instruction();
  m.renderFrame();                 // paint the 32x16 text page from CG ROM
  requestAnimationFrame(frame);
})();

The machine is plain objects. Everything the debugger needs is a field or method — there is no wasm heap:

MemberKindWhat it does
m.cpu.run_instruction()methodExecute exactly one Z80 instruction; returns its T-cycle count. The single-step primitive.
m.cpu.getState() / setState()methodRead / write the full Z80 register file (a b c d e h l, the primes, ix iy sp pc i r and the S Z H P N C flags).
m.cpu.get_pc()methodCheap PC read (added to the core) so the loop can check breakpoints without allocating a state object each instruction.
m.memfieldThe raw 64 KB address space (Uint8Array). Read it for a side-effect-free hex / disasm view; the text page is at $C200.
m.pushKey(ascii)methodQueue a key: the sub-CPU hands the ROM an ASCII byte through the i8255 and asserts the key interrupt.
m.wps / m.wpHitfieldThe write-watchpoint address set and its "hit" flag, checked inside the memory-write path.

Because the CPU, bus and key latch are ordinary JavaScript, the debugger single-steps with run_instruction(), reads and writes registers straight through getState()/setState(), and implements breakpoints (on get_pc()) and watchpoints (inside mem_write) as host-side checks in the loop — no changes to the interpreter.

Debugger integration

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

  • Registers are read live from the Z80 core each refresh — the 16-bit pairs AF BC DE HL IX IY SP PC, the I/R bytes and the S Z H P N C flags — and written back through setState().
  • Disassembly uses the shared z80 decoder over the full 64 KB, so the BASIC ROM and anything you type read back as Z80 mnemonics.
  • Memory is read straight from m.mem, side-effect-free (no I/O ports live in the address space), so the auto-polling hex view never disturbs the machine.
  • Single step is one run_instruction(); breakpoints (on PC) and watchpoints (on a memory write) are host-side checks in the boot loop, added with no change to the core.
  • Keyboard. The physical keyboard is mapped character-accurately to the PC-6001's ASCII key codes; an on-screen keyboard coloured like the real machine feeds the same path for touch.

Architecture

The NEC PC-6001 (1981; sold in the US as the "NEC Trek") is an entry-level Z80 home computer with a cartridge slot, cassette storage and an MC6847-based colour display. This build emulates just the parts the N60-BASIC boot exercises, each kept visible:

  • Z80 CPU (the NEC µPD780) at ~3.99 MHz. The MIT Z80.js core interprets one instruction per run_instruction(); the shared z80 decoder disassembles it.
  • Memory — 16 KB BASIC ROM at $0000-$3FFF, a 16 KB-RAM machine at $C000-$FFFF ($4000-$BFFF is left unmapped, which is how the ROM auto-detects the RAM size). The MC6847 text page sits at $C200.
  • Interrupts are Z80 IM 2 with I=$FA and a vector table at $FA00; the device supplies the low byte — $02 key, $06 the 2 ms timer, 6 the joystick/STRIG reply.
  • Keyboard — a µPD8049 sub-CPU normally scans the keys and hands the main CPU an ASCII code through an i8255 (port $90 data, port $92 status). We emulate that link directly: latch a code, raise the key interrupt, and the ROM's INTKEY handler collects it.
  • Video — the 32×16 character screen is drawn from the bundled CG ROM font (8×12 cells) exactly as the MC6847 scanned it.

System software. NEC's own ROM is copyrighted, so this ships the freely-redistributable compatible N60-BASIC ROM (Akikawa Hisashi, LGPL v2.1) that the iP6 emulator bundles, together with its public-domain CG ROM (shinonome / misaki fonts). It prints "BASIC Ver.0.7.2" and behaves like N60-BASIC — hence the grey (not open) classification of the whole machine.