multi-cpu-emu

A browser-based IDE and emulator for six classic microprocessors. Write assembly, assemble, step, and debug — all in one page.

MIT License Rust → WASM 6 ISAs v0.1.0

Quick Start

  1. Open the emulator in your browser.
  2. Select an ISA from the dropdown (default: Intel 8086).
  3. Write assembly in the editor, or click Example to load a sample.
  4. Press F7 or click Assemble to compile and load into memory.
  5. Press F8 or Step to execute one instruction at a time.
  6. Press F5 or Run to execute continuously until HLT/BRK.
  7. Watch registers, flags, memory, and output update in the tabs on the right.
Tip: Source is auto-saved to localStorage. Press Ctrl+S to save. Share copies a URL with your code encoded in it.

IDE Guide

8086 emulator screenshot
The IDE: source editor with gutter (left), registers/flags/disassembly/memory/output tabs (right)

Toolbar

ButtonKeyDescription
AssembleF7Compile source and load into memory at the ISA's entry point
StepF8Execute one instruction
OverF10Step over a CALL — executes the entire subroutine in one step
Back—Undo last step (time-travel via snapshot restore, up to 200 steps)
RunF5Run continuously until HLT/BRK or Stop
StopEscHalt continuous execution
ResetF4Reset CPU to initial state
Save—Download a binary snapshot of the full CPU state
Load—Restore a previously saved snapshot
Share—Copy a shareable URL with code + breakpoints + watches

Disassembly Interactions

Editor Autocomplete

Type in the editor to get ISA-aware autocomplete for registers, mnemonics, and labels. Navigate with ↑↓, accept with Tab or Enter, dismiss with Esc.

Languages

Switch language from the Lang dropdown: English, Spanish, German, French, Hindi.

Intel 8086

16-bit x86 processor with segmented memory. The foundation of the x86 architecture that powers most modern PCs. This emulator implements the 8086 instruction set with DOS INT 21h and BIOS INT 10h service subsets.

8086 stepping demo
8086 — registers change (amber highlight), gutter + editor show current PC in green

Registers

AX
0000
AH=00 AL=00
BX
0000
BH=00 BL=00
CX
0000
CH=00 CL=00
DX
0000
DH=00 DL=00
SI
0000
DI
0000
BP
0000
SP
FFFE
CS
0000
DS
0000
ES
0000
SS
0000
IP
0100
FLAGS
0000

General (blue): AX/BX/CX/DX are 16-bit, each split into high/low 8-bit halves (AH/AL, etc). Used for arithmetic, data, pointers.
Index (gray): SI/DI for string operations, BP for stack frames, SP for the stack pointer.
Segment (teal): CS/DS/ES/SS — physical address = segment×16 + offset.
Special (amber): IP = instruction pointer, FLAGS = condition codes.

Flags

FlagNameDescription
CFCarryUnsigned overflow / borrow
ZFZeroResult is zero
SFSignResult is negative (bit 15 set)
PFParityLow byte has even parity
AFAuxiliary CarryBCD carry from bit 3 to 4
OFOverflowSigned overflow
DFDirectionString ops direction (CLD/STD)
IFInterrupt EnableEnables maskable INTR (CLI/STI)
TFTrapSingle-step mode (INT 1 after each instruction)

Memory Model

00000h
Interrupt Vector Table (1 KB)
00400h
BIOS Data Area (256 B)
00500h
Conventional Memory
00100h
COM Program Area (entry point)
A0000h
Video Memory
FFFF0h
BIOS ROM

1 MiB flat address space. Physical address = segment × 16 + offset. COM programs load at CS:0100h. Programs in this emulator use ORG 100h (COM format).

I/O Model

PortDeviceRead/Write
01hCharacter output (AL → Output tab)Write
10hTraffic light (bits 0/1/2 = R/Y/G)Write
11h/12h7-segment display (low/high digit)Write
13hStepper motor (4-bit coil pattern)Write
14h/15hPrinter (data / status)Write/Read
16h/17hRobot grid (X / Y position)Write
20h–27h8×8 LED matrix (one row per port)Write

Text output via INT 21h: AH=01h (read with echo), AH=02h (print char in DL), AH=07h (read no echo), AH=09h (print $-terminated string at DS:DX), AH=4Ch (exit).
Graphics via INT 10h: AH=0Eh (teletype), AH=00h (set video mode, e.g. 13h for 320×200×256).

Interrupts

NMI (non-maskable, vector 02h) and INTR (maskable via IF, device-supplied vector) are available from the header bar. Set up IVT entries at 4×vector with a far pointer (offset + segment).

Instruction Set

Data Movement
MOVPUSHPOPXCHGLEALAHFSAHF
Arithmetic
ADDADCSUBSBBINCDECNEGMULIMULDIVIDIVCMP
Logic
ANDORXORNOTTESTSHLSHRSARROLRORRCLRCR
String
MOVSBMOVSWLODSBLODSWSTOSBSTOSWCMPSBCMPSWSCASBSCASWREPREPEREPNE
Control Flow
JMPCALLRETRETFJccLOOPLOOPZLOOPNZJCXZINTINT3INTOIRET
Flag / Control
CLCSTCCMCCLISTICLDSTDCBWCWDNOPHLT
Stack / Pseudo
PUSHAPOPA

Example: Hello World

ORG 100h
MOV DX, OFFSET msg
MOV AH, 09h
INT 21h
MOV AH, 4Ch
INT 21h
msg DB 'Hello, 8086!$'

Intel 8085

8-bit microprocessor with accumulator-centric architecture. The predecessor to the 8086, widely used in embedded systems and education.

8085 stepping demo
8085 — A=43 (41h + 02h), B=02, PC advanced through instructions

Registers

A (Accumulator)
00
B
00
C
00
D
00
E
00
H
00
L
00
SP
FFFF
PC
0000

A: 8-bit accumulator — all arithmetic/logic results go here.
B–L: 6 general-purpose 8-bit registers, pairable as BC, DE, HL (16-bit). HL is the primary memory pointer.
SP: Stack pointer. PC: Program counter.

Flags (PSW — A + Flags in one pair)

FlagNameDescription
SSignBit 7 of result set
ZZeroResult is zero
ACAuxiliary CarryCarry from bit 3 to 4 (BCD)
PParityEven parity of result
CYCarryUnsigned overflow / borrow

Memory Model

0000h
Program Code (64 KiB)
FFFFh
Top of Stack

64 KiB flat address space. Entry at 0000h. Stack grows downward from FFFFh.

I/O Model

Character output via OUT 01h (writes A to the Output tab). All 256 ports are addressable via IN/OUT.

Instruction Set

Data Movement
MOVMVILXILDASTALDAXSTAXLHLDSHLDXCHG
Arithmetic
ADDADCSUBSBBINRDCRINXDCXDADDAA
Logic
ANAXRAORACMPRLCRRCRALRARCMACMCSTC
Control Flow
JMPJccCALLCccRETRccRST
Stack / I/O
PUSHPOPXTHLSPHLPCHLINOUTEIDISIMRIMNOPHLT

Interrupts

Hardware interrupts from the header bar:

ButtonVectorPriorityNotes
TRAP0024h1 (highest)Non-maskable, keeps IE
7.5003Ch2Edge-latched, maskable via SIM
6.50034h3Maskable via SIM
5.5002Ch4Maskable via SIM
INTRvector5 (lowest)Maskable via EI/DI

SID input pin: toggleable from the header. Read via RIM instruction (bit 7 of A).

Example: Output Loop

MVI A, '1'        ; A = 31h
MVI C, 9          ; counter
LOOP: OUT 01h      ; print A
      INR A        ; A++
      DCR C        ; C--
      JNZ LOOP     ; repeat until C=0
HLT

Intel 8051 (MCS-51)

8-bit microcontroller with Special Function Registers (SFRs), bit-addressable RAM, timers, and serial port. Widely used in embedded systems.

8051 stepping demo
8051 — A=43 (41h + 02h), R0=02, PC=0005

Registers

ACC
00
B
00
R0
00
R1
00
R2
00
R3
00
R4
00
R5
00
R6
00
R7
00
DPL
00
DPH
00
SP
07
PC
0000
PSW
00
CY AC F0 RS1 RS0 OV — P
IE
00
EA — ET2 ES ET1 EX1 ET0 EX0
IP
00
— — PT2 PS PT1 PX1 PT0 PX0

ACC: Accumulator. B: Multiply/divide helper. R0–R7: Register bank (4 banks of 8, selected by PSW.RS0/RS1).
DPTR: 16-bit data pointer (DPH:DPL) for MOVX. SP: Stack pointer (starts at 07h).PC: Program counter.

Memory Map

0000h
Internal RAM (128 B)
0020h
Bit-addressable (20h–2Fh)
0030h
General RAM
0080h
SFR Space (80h–FFh)
0000h
Code Memory (64 KiB)

Key SFRs

AddressNameDescription
80hP0Port 0 (quasi-bidirectional)
90hP1Port 1 (quasi-bidirectional)
A0hP2Port 2 (quasi-bidirectional)
B0hP3Port 3 (alt functions: RXD, TXD, INT0, INT1, T0, T1, WR, RD)
99hSBUFSerial data buffer — writing emits a char to Output
98hSCONSerial control
88hTCONTimer control (TF1, TR1, TF0, TR0, IE1, IT1, IE0, IT0)
89hTMODTimer mode
8Ch/8AhTH0/TL0Timer 0 high/low byte
8Dh/8BhTH1/TL1Timer 1 high/low byte

Instruction Set

Data Movement
MOVMOVCMOVXPUSHPOPXCHXCHDSWAP
Arithmetic
ADDADDCSUBBINCDECMULDIVDA
Logic
ANLORLXRLCLRCPLRLRRRLCRRC
Bit Operations
SETBCLRCPLANL C,ORL C,MOV C,
Control Flow
SJMPAJMPLJMPJZJNZJCJNCJBJNBJBCCJNEDJNZACALLLCALLRETRETINOP

Interrupts

SourceVectorPriority (IP)Notes
INT00003hPX0 (highest)External INT0, edge/level via IT0
Timer 0000BhPT0TF0 flag, cleared on service
INT10013hPX1External INT1, edge/level via IT1
Timer 1001BhPT1TF1 flag
Serial0023hPS (lowest)RI | TI (software-cleared)

Use the INT0/INT1 header buttons to trigger external interrupts. Type a character in the RX field and click send to inject serial data.

Example: Hello via Serial

MOV A, #'H'
MOV SBUF, A       ; transmit 'H'
JNB TI, $          ; wait for TX complete
CLR TI
MOV A, #'i'
MOV SBUF, A
JNB TI, $
CLR TI
SJMP $

MOS 6502

8-bit processor famous for powering the Apple II, Commodore 64, and NES. Features zero-page fast access, a hardware stack, and decimal mode.

6502 stepping demo
6502 — A=41, X=02, SP=FD (stack starts at 01FF)

Registers

A (Accumulator)
00
X
00
Y
00
SP
FD
PC
0000
P (Status)
00
N V — B D I Z C

A: 8-bit accumulator. X, Y: Index registers for addressing and counting.
SP: Stack pointer (8-bit, offset from 0100h — stack page is always 01xxh).
PC: 16-bit program counter. P: Processor status (NV-BDIZC).

Flags (P register)

BitFlagDescription
7NNegative (bit 7 of result)
6VOverflow (signed)
5—Unused (always 1 after PHP/PLP)
4BBreak (set on BRK)
3DDecimal mode (BCD arithmetic)
2IInterrupt disable
1ZZero
0CCarry

Memory Map

0000h
Zero Page (256 B — fast addressing)
0100h
Stack Page (256 B, SP is offset)
0200h
General RAM
FFFEh
IRQ/BRK Vector

64 KiB flat address space. Entry at 0000h. Zero page (00–FF) enables faster addressing modes. Stack is fixed at page 1 (0100–01FF).

Addressing Modes

ModeSyntaxExampleDescription
Immediate#nLDA #42Load constant value
Zero PageaddrLDA $20Access zero page (1-byte address)
AbsoluteaddrLDA $0200Full 16-bit address
Indexed Xaddr,XLDA $20,XAddress + X offset
Indexed Yaddr,YLDX $20,YAddress + Y offset
Indirect,X(addr,X)LDA ($20,X)Zero-page pointer + X
Indirect,Y(addr),YLDA ($20),YZero-page pointer + Y
Implied—NOPNo operand
AccumulatorAASL AOperate on accumulator

Instruction Set

Data Transfer
LDALDXLDYSTASTXSTYTAXTAYTXATYATXSTSXPHAPLAPHPPLP
Arithmetic
ADCSBCINCDECINXINYDEXDEY
Logic / Shift
ANDORAEORBITASLLSRROLROR
Comparison
CMPCPXCPY
Control Flow
JMPJSRRTSRTIBCCBCSBEQBNEBMIBPLBVCBVS
System
BRKNOPCLCSECCLISEICLVCLDSED

Interrupts

IRQ (maskable via I flag, vector at FFFEh) and NMI (non-maskable, vector at FFFAh) from the header bar. BRK software interrupt vectors through FFFEh with B flag set.

Example: Sum 1..10

LDA #0              ; accumulator = 0
LDX #10             ; counter
LOOP: CLC
      ADC #X         ; A += X (immediate not valid for ADC, use zero page)
      DEX
      BNE LOOP
BRK                 ; done: A = sum(1..10) = 55

Zilog Z80

8-bit processor, superset of the Intel 8080. Adds IX/IY index registers, shadow registers (A'F'/BC'/DE'/HL'), block transfers, bit manipulation, and multiple interrupt modes.

Z80 stepping demo
Z80 — A=30 (10h + 20h), PC=0005

Registers

A
00
F (Flags)
00
S Z H P/V N C
B
00
C
00
D
00
E
00
H
00
L
00
IX
0000
Index X
IY
0000
Index Y
SP
FFFF
PC
0000
I
00
Interrupt vector (IM2)
R
00
Memory refresh

Main set: A, F, B, C, D, E, H, L — same as 8080. AF/BC/DE/HL are 16-bit pairs.
IX/IY (purple): 16-bit index registers with displacement addressing (e.g. LD A, (IX+5)).
I: High byte of IM2 interrupt vector table. R: Auto-incrementing memory refresh counter.
SP: Stack pointer. PC: Program counter.

Flags (F register)

BitFlagDescription
7SSign (bit 7 of result)
6ZZero
5HHalf-carry (BCD, bit 3→4)
4P/VParity / Overflow
3NSubtract (set by SUB, SBC; cleared by ADD, ADC)
0CCarry

Instruction Set

Load
LD r,r'LD r,nLD r,(HL)LD (HL),rLD rr,nnLD A,(BC)LD A,(DE)LD A,(nn)LD (nn),ALDILDIRLDDLDDR
Arithmetic
ADDADCSUBSBCINCDECNEGDAAADD HL,rrADC HL,rrSBC HL,rr
Logic / Bit
ANDORXORCPBITRESSETRLCRRCRLRRSLASRASRLRLDRRD
Block / Search
CPICPIRCPDCPDR
Control Flow
JPJRDJNZCALLRETRET ccCALL ccRST n
I/O
IN r,(C)OUT (C),rIN A,(n)OUT (n),AINIOUTIINDOUTD
Exchange / Stack
EXEXXPUSHPOP
System
EIDIIM 0IM 1IM 2HALTNOPSCFCCFCPLRETIRETN

Interrupts

NMI (non-maskable, jumps to 0066h) and INT (maskable via IFF1). Interrupt mode selector in the header:

ModeBehavior
IM 0External device places instruction on data bus
IM 1Always RST 38h (vector 0038h)
IM 2Vector table at I×100h, device supplies low byte

Example: Hello via OUT

LD A, 'H'
OUT (1), A         ; print 'H'
LD A, 'i'
OUT (1), A         ; print 'i'
HALT

RISC-V RV32I

32-bit RISC processor implementing the base integer ISA (RV32I) with M extension (multiply/divide) and CSR instructions. Uses ECALL semihosting for I/O.

RV32 stepping demo
RV32 — x1=10 (ADDI), x2=14, x3=24 (ADD x3,x1,x2)

Registers

x0 (zero)
00000000
Hardwired zero
x1 (ra)
00000000
Return address
x2 (sp)
00000000
Stack pointer
x3 (gp)
00000000
Global pointer
x4 (tp)
00000000
Thread pointer
x5–x7
00000000
Temporaries (t0–t2)
x8–x9
00000000
Saved (s0–s1)
x10–x17
00000000
Args/returns (a0–a7)
x18–x27
00000000
Saved (s2–s11)
x28–x31
00000000
Temporaries (t3–t6)
PC
00000000

x0: Always zero. x1–x31: 32 general-purpose 32-bit registers (ABI names in parentheses).
PC: 32-bit program counter. All instructions are 32-bit (4-byte aligned).

Memory Model

00000000
Code + Data (1 MiB, little-endian)

Flat 32-bit address space (1 MiB implemented). Little-endian byte ordering. All instructions are exactly 4 bytes (no compressed).

Instruction Formats

FormatFunct7Rs2Rs1Funct3RdOpcode
R-type7 bits5 bits5 bits3 bits5 bits7 bits
I-typeimm[11:0]5 bits3 bits5 bits7 bits
S-typeimm[11:5]5 bits3 bitsimm[4:0]
B-typeimm[12|10:5]5 bits3 bitsimm[4:1|11]
U-typeimm[31:12]5 bits7 bits
J-typeimm[20|10:1|11|19:12]5 bits7 bits

Instruction Set

Upper Immediate
LUIAUIPC
Jumps
JALJALR
Branches
BEQBNEBLTBGEBLTUBGEU
Loads / Stores
LBLHLWLBULHUSBSHSW
Register-Immediate
ADDISLTISLTIUXORIORIANDISLLISRLISRAI
Register-Register
ADDSUBSLLSLTSLTUXORSRLSRAORAND
M Extension
MULMULHMULHSUMULHUDIVDIVUREMREMU
System
ECALLEBREAKFENCE
CSR
CSRRWCSRRSCSRRCCSRRWICSRRSICSRRCI

I/O via ECALL Semihosting

a7SyscallArgumentsDescription
64writea0=fd, a1=buf_ptr, a2=lenWrite bytes to Output tab
93exita0=codeHalt the CPU

Example: Hello World

.text
  LA   a0, msg        ; load address of string
  LI   a7, 64         ; syscall: write
  LI   a0, 1          ; fd = stdout
  LA   a1, msg        ; buffer
  LI   a2, 3          ; length
  ECALL
  LI   a7, 93         ; syscall: exit
  ECALL
msg: .byte 'H','i','\n'

Devices & I/O Peripherals

Simulated hardware accessible via I/O ports. View them in the Devices tab, or pop them out as floating windows.

DevicePort(s)OperationDescription
Traffic Light0x10WriteBit 0 = Red, Bit 1 = Yellow, Bit 2 = Green
7-Segment0x11/0x12WriteLow/high digit hex display (0–F per digit)
Stepper Motor0x13Write4-bit coil pattern → 8 rotor positions (45° steps)
Printer0x14/0x15Write/ReadData accumulates in text buffer; status 0x80 = ready
Robot Grid0x16/0x17Write16×16 grid; X/Y position with visited trail
LED Matrix0x20–0x27Write8×8 monochrome; one port per row (bit 7 = left)

Debugging Features

Time-Travel Debugging

Every step saves a snapshot. Click Back to undo and restore the previous CPU state (up to 200 steps of history).

Breakpoints

Conditional Breakpoint Expressions

ExpressionDescription
CX==0Break when CX equals 0
AX>10Break when AX is greater than 10
mem[0x200]==5Break when memory at 0x200 equals 5
IP==0x100Break when IP/PC reaches a specific address

Watch Expressions

In the Watch tab, add register names (e.g. AX) or memory expressions (e.g. [0x200]). Values that change between steps are highlighted in amber.

Snapshot Save/Load

Save downloads a binary snapshot of the entire CPU state (registers, flags, memory, breakpoints, watches). Load restores it deterministically.

Share Links

Share encodes your source code, breakpoints, and watches into a URL. Anyone with the link can open the same program.

Assembly Syntax

All assemblers share: line-oriented, case-insensitive, ; comments, labels (name: or name EQU expr).

Number Formats

FormatExampleMeaning
Decimal42Base 10
Hex (prefix)0x2ABase 16
Hex (suffix)2AhBase 16
Binary10101bBase 2
Octal52qBase 8
Character'A'ASCII (65)

Directives

DirectiveSyntaxDescription
ORGORG 100hSet origin address
DBDB 'Hello',0Define byte(s)
DWDW 1234hDefine word (16-bit LE)
EQUPORT EQU 0FFhConstant symbol
ENDENDEnd of source (optional)

WASM API Reference

The emulator exposes a single Emulator class via wasm-bindgen.

Constructor

const emu = new Emulator("8086"); // "8086"|"8085"|"8051"|"6502"|"Z80"|"rv32"

Core

MethodReturnsDescription
assemble(src)Vec<u8>Assemble source to machine code
assemble_info(src)Vec<String>Per-line "ADDR BYTES" for gutter
load(code, origin)—Load code at address, set PC
step()—Execute one instruction
run(max)u32Run up to N steps; returns count
run_to(pc, max)u32Run until target PC is next
pc()u32Current program counter
regs()Vec<String>Register dump ("NAME=val")
flags()Vec<String>Active flag names
mem(addr, len)Vec<u8>Read memory bytes
out()StringDrain program output
halted()boolTrue if CPU halted
reset()—Reset CPU

Debug

MethodDescription
snapshot()Serialize full CPU state (deterministic)
restore(data)Restore from snapshot
disasm(addr, count)Disassemble N instructions
set_reg(name, val)Set a register
set_pc(addr)Set program counter

I/O

MethodISADescription
port_read(port)AllRead I/O port byte
port_write(port, val)AllWrite I/O port byte
push_key(ch)8086Queue type-ahead character
waiting_input()8086True if blocked on INT 21h read
interrupt(kind, data)AllRaise hardware interrupt
serial_rx(ch)8051Inject received serial byte
set_sid(v)8085Set SID input pin
sod()8085Read SOD output pin
set_interrupt_mode(m)Z80Set interrupt mode 0/1/2

Memory

MethodDescription
mem_write(addr, data)Write bytes to memory
load_rom(data, addr)Load ROM (read-only region)
cycles()Total clock cycles executed

8051-Specific

MethodDescription
sfr(addr)Read SFR / IRAM byte
set_sfr(addr, val)Write SFR / IRAM byte
set_ea(active)Set EA (external access) pin

8086-Specific

MethodDescription
gfx()Graphics framebuffer info (base, w, h)
video_mode()Current video mode byte
screen()Text framebuffer (80×25 char/attr)
cursor()Text cursor [col, row]
fs_put(name, data)Preload file into DOS VFS
fs_get(name)Read file from DOS VFS
pit_count(n)PIT channel 0/1/2 reload value

Building from Source

Prerequisites

# Add WASM target (once)
rustup target add wasm32-unknown-unknown

# Build WASM package
wasm-pack build --target web --out-dir docs/pkg --release --features wasm

# Run native tests
cargo test

# Serve locally
python3 -m http.server -d docs 8000

CLI Runner

cargo run --example run -- examples/hello.asm          # 8086
cargo run --example run -- --isa 8085 examples/hello85.asm
cargo run --example run -- --isa 8051 examples/hello51.asm
cargo run --example run -- --isa z80  examples/helloz80.asm
cargo run --example run -- --isa 6502 examples/hello6502.asm
cargo run --example run -- --isa rv32 examples/hellorv32.asm

Project Structure

multi-cpu-emu/
├── Cargo.toml
├── src/
│   ├── lib.rs          # Emulator enum (6 cores)
│   ├── cpu.rs          # Cpu trait, Mem, Output, FlagSet
│   ├── i8086.rs        # 8086 core
│   ├── i8085.rs        # 8085 core
│   ├── mcs51.rs        # 8051 core
│   ├── m6502.rs        # 6502 core
│   ├── z80.rs          # Z80 core
│   ├── rv32.rs         # RV32I core
│   ├── asm/            # Per-ISA assemblers
│   └── wasm.rs         # wasm-bindgen surface
├── docs/               # Web IDE (GitHub Pages)
│   ├── index.html      # Emulator
│   ├── doc.html        # This page
│   ├── style.css
│   ├── app.js
│   ├── devices.js
│   ├── i18n.js
│   └── screenshots/    # Emulator screenshots
└── examples/run.rs     # Native CLI runner

multi-cpu-emu v0.1.0 · MIT License · GitHub · Written in Rust → WASM