dcpu16
dcpu16 is mappum's pure-JavaScript emulator for the DCPU-16, the fictional 16-bit processor from Notch's 0x10c. It implements the CPU (spec 1.7) together with an assembler and the LEM1802 32×12 character monitor, so a program can be assembled straight into memory and run in the browser. On emulators.org it boots to a small demo that writes text to the monitor, wires the DCPU generic keyboard, and plugs into the shared debugger for single-stepping, breakpoints and live register and memory views.
Runs on: Web browser
dcpu16 Online Emulator
Play dcpu16 using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| Hello world (LEM1802) | dcpu16 | open | Open ⛶ | ||
| Keyboard echo | dcpu16 | open | Open ⛶ |
Chips
Notes
Embedding
dcpu16 is mappum's plain-global JavaScript DCPU-16 (Notch's 0x10c, spec 1.7). Vendor the core three files and load them in order - cpu.js, assembler.js, LEM1802.js - then build the machine and drive it yourself rather than calling the upstream run loop, which cannot be paused or stepped from outside.
Boot. Create the CPU, attach the LEM1802 (pointed at a <canvas>) and a keyboard, assemble a program into RAM, then run your own loop built on cpu.step() (execute one instruction):
var cpu = new DCPU16.CPU();
var lem = new LEM1802(canvas);
cpu.addDevice(lem); // device 0
cpu.addDevice(keyboard); // device 1
new DCPU16.Assembler(cpu).compile(source); // writes words into cpu.mem[]
cpu.running = true;
(function loop(){
for (var i = 0; i < 2000; i++) cpu.step(); // ~one 60fps frame at 100kHz
requestAnimationFrame(loop);
})();
The machine is plain objects. Everything the debugger needs is live on the CPU:
| Member | Kind | What it does |
|---|---|---|
cpu.step() | method | Execute exactly one DCPU-16 instruction. The single-step primitive. |
cpu.mem | field | The 0x10000-word RAM array, which also carries the registers as named properties: mem.a…mem.j, mem.pc, mem.sp, mem.ex, mem.ia. |
cpu.get(a) / cpu.set(a, v) | method | The memory bus, with onGet / onSet listeners: how the LEM1802 watches video RAM and how we hook write watchpoints. |
cpu.addDevice(d) | method | Attach a spec hardware device (indexed for HWN / HWQ / HWI). |
LEM1802 | device | The 32×12 monitor; on its own draw loop it rasters video RAM to the canvas and honours the HWI memory-map / font / palette / border commands. |
Because the CPU and RAM are ordinary JavaScript, the debugger single-steps with cpu.step(), reads and writes registers straight off cpu.mem, and implements breakpoints and watchpoints as host-side checks around step() and set() - no changes to the emulator core.
Debugger integration
The boot script publishes window.EMU_BOOT with a transport the shared debugger drives: pause / resume / isPaused, stepInsn (one instruction), step (one frame), reset, and breakpoints / watchpoints sets. With no breakpoints the loop runs a whole frame of instructions fast; with breakpoints it checks cpu.mem.pc before each cpu.step() and pauses on a match. Write watchpoints wrap cpu.set() and pause the moment a watched word is written.
Memory addressing. DCPU-16 RAM is 0x10000 sixteen-bit words, but the shared hex / disassembly / bits views read memory as bytes. So the machine plug-in exposes RAM as 0x20000 little-endian bytes and the dcpu16 decoder (in /debugger/src/cpus/dcpu16.js) reassembles each word from a byte pair, returning instruction lengths in bytes (2, 4 or 6). The disassembler decodes the real encoding, a 6-bit a, 5-bit b and 5-bit opcode in the first word, plus the "next word" operand forms.
Architecture
The DCPU-16 is Notch's fictional 16-bit processor for the (cancelled) game 0x10c. It is deliberately tiny and fully documented, which makes it an unusually clean debugging target:
- Sixteen-bit words throughout: 0x10000 words of RAM, 8 general registers (A, B, C, X, Y, Z, I, J) plus PC, SP, EX and the interrupt address IA.
- One instruction per word: a 5-bit opcode with a 6-bit
aand 5-bitboperand, each of which may pull one extra "next word". Special (one-operand) ops encode the opcode 0. - Hardware is enumerated with
HWN/HWQand messaged withHWI. Here device 0 is the LEM1802 32×12 monitor and device 1 is the generic keyboard. - The LEM1802 reads a screen of
fg<<12 | bg<<8 | blink<<7 | charcells from video RAM (mapped to 0x8000 by the demos) and draws each 4×8 glyph from its built-in font.
mappum's emulator implements the CPU and the LEM1802 faithfully; this integration adds the controllable loop, the disassembler and the keyboard wiring the debugger needs.