SearchA-ZE › Elektronika BK-0010

Elektronika BK-0010

2021 Open source · GPL-3.0 Online

A pure-JavaScript emulator of the Elektronika BK-0010 (Электроника БК-0010, 1985) and the later BK-0011M — Soviet 16-bit home computers built around the K1801VM1, a single-chip clone of the DEC PDP-11 instruction set. Refactored and maintained by Ivan "VDM" Kalininskiy from an earlier JavaScript port, it runs in the browser, rendering the 512×256 bit-mapped screen to an HTML5 canvas and bundling the system ROMs so it boots straight to BASIC, FOCAL or the machine-code Monitor with no downloads.

Because the K1801VM1 is a PDP-11, its code disassembles with the debugger's shared PDP-11 decoder; the CPU, memory and I/O are plain JavaScript objects, so the whole machine can be single-stepped and inspected live.

Visit the project on GitHub ↗

Visit the official site ↗

Runs on: Web browser

Elektronika BK-0010 Online Emulator

Play Elektronika BK-0010 using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
БК-0010 · Vilnius BASICElektronika BK-0010Elektronika BK-0010greyOpen ⛶
БК-0010 · FOCALElektronika BK-0010Elektronika BK-0010greyOpen ⛶
БК-0010 · MonitorElektronika BK-0010Elektronika BK-0010greyOpen ⛶
БК-0010 · floppy systemElektronika BK-0010Elektronika BK-0010greyOpen ⛶
БК-0011М · floppy systemElektronika BK-0010Elektronika BK-0010greyOpen ⛶

Machines emulated

Chips

Notes

Embedding

The emulator is a set of plain-global JavaScript modules (no bundler). Vendor src/** and load them in dependency order; loading app.js last auto-runs Emulator.init(), which builds the machine and wires the physical keyboard. The whole computer is then two globals: cpu (the K1801VM1) and base (memory, video, I/O).

Own the loop. The stock app.js drives itself with a self-rescheduling setTimeout(FPSloop, …) that cannot be paused or single-stepped, so we never call loaded(). We run our own frame built on cpu.exec_insn() — one PDP-11 instruction — and reuse the shipped per-frame helpers for input, sound and video:

base.setBASIC10Model();        // pick a ROM set…
cpu.reset();                    // …PC loads from the reset vector (0100000)
base.setVideoMode(2);           // 0 B/W · 1 grey · 2 colour
(function frame(){
  var target = cpu.Cycles + BK_speed.cyc;   // ~1 video frame of cycles
  while (cpu.Cycles < target) {
    cpu.exec_insn();                          // one K1801VM1 / PDP-11 instruction
    if (breakpoints.has(cpu.regs[7])) break;    // R7 = PC
  }
  base.DRAW();                              // blit BK video RAM to the canvas
  setTimeout(frame, 1000 / BK_speed.fps);
})();

The machine is plain objects. Everything the debugger needs is a live field or method:

MemberKindWhat it does
cpu.exec_insn()methodExecute exactly one PDP-11 instruction. The single-step primitive.
cpu.reset()methodReset the CPU; reloads R7 (PC) from the reset vector.
cpu.regsfieldThe live 8-word register file R0…R7 (R6 = SP, R7 = PC); writes land immediately.
cpu.getPSW() / setPSW(v)methodThe processor status word (flags T N Z V C, priority I).
base.peekByte(a) / peekWord(a)methodAdded. Side-effect-free read of the mapped bus — no device latches touched.
base.pokeByte(a,v) / pokeWord(a,v)methodAdded. Write straight to RAM and refresh the video buffer.
base.keyboard_punch(code)methodDeliver one BK key code (KOI-7) to the keyboard controller.

Debugger integration

The plug-in (bk0010-debug.js) reads window.EMU_BOOT and calls EmuKit.defineMachine. The disassembler is the shared 'pdp11' decoder — the K1801VM1 is a PDP-11, so no machine-specific decoder was written; only a byte view onto BK memory is supplied.

Two small core extensions were added to the vendored engine so the debugger is fully faithful:

  • Side-effect-free memory. The normal readWord routes I/O-page addresses through device plug-ins — reading the keyboard data register clears its key-ready flag, which would eat keystrokes under an auto-refreshing hex view. New base.peekWord/peekByte (and pokeWord/pokeByte) translate an address through the same 8×8 KB page map the CPU sees and touch the raw memory[] store only.
  • Write watchpoints. The boot shim wraps base.writeWord and base.writeByteAsWord (every byte write funnels through the latter); when a written address is in the watch set it halts the loop after that instruction.

Breakpoints are a Set of PC values the frame checks against cpu.regs[7] after each instruction; single-step calls cpu.exec_insn() once. Registers read and write straight off cpu.regs / cpu.getPSW(), with the T N Z V C flags unpacked from the PSW bits. Numbers are shown in PDP-11 octal where natural.

Architecture

The Elektronika BK-0010 (Электроника БК-0010, 1985) is a Soviet 16-bit home computer built around the K1801VM1 — a single-chip processor implementing the DEC PDP-11 (LSI-11) instruction set. This core emulates it and the later BK-0011M:

  • K1801VM1 — the CPU interpreter. exec_insn() decodes one 16-bit word by instruction class (double-operand, single-operand, branch, JSR/RTS/SOB, EMT/TRAP…) and runs it; registers are R0-R7 with a PSW carrying the N Z V C flags.
  • BaseBK001x — memory, the 8×8 KB page map (RAM in pages 0-3, ROM/disk in 4-7), the 512×256 bit-mapped video (mono, 4-grey and 16-palette colour), and the Q-Bus I/O page (keyboard, timer, system register).
  • SystemROMs — the grey system ROMs as byte arrays: the BK-0010 Monitor, BASIC (Вильнюс) and FOCAL, the BK-0011M OS + BASIC, and the 4 KB floppy controller ROM.
  • Keyboard / KeyMapper / BKkeys — the KOI-7 key matrix at 0177660, with РУС/ЛАТ (Cyrillic/Latin) layout switching and AR2 graphics characters.

Because the CPU, bus and RAM are ordinary interpreted JavaScript, the debugger single-steps real PDP-11 instructions and reads and writes registers and memory with no changes to the decode logic.