| Crates.io | retro-z80-emulator |
| lib.rs | retro-z80-emulator |
| version | 0.1.5 |
| created_at | 2025-12-08 02:21:49.176647+00 |
| updated_at | 2026-01-06 23:01:00.437387+00 |
| description | Z80 emulator for RetroShield firmware with TUI debugger |
| homepage | https://github.com/ajokela/retro-z80-emulator |
| repository | https://github.com/ajokela/retro-z80-emulator |
| max_upload_size | |
| id | 1972661 |
| size | 355,401 |
A Z80 emulator written in Rust for testing RetroShield Z80 firmware. Includes a simple passthrough emulator, a full-featured TUI debugger, and a WebAssembly build for browser-based emulation.
retroshield - Simple passthrough (stdin/stdout)retroshield_tui - Full TUI debugger with registers, disassembly, stack, memory viewcargo build --release
Binaries will be in target/release/.
To build for the browser, you'll need wasm-pack:
# Install wasm-pack if you don't have it
cargo install wasm-pack
# Build the WASM package
wasm-pack build --target web --out-dir pkg
This produces:
pkg/retro_z80_emulator.js - JavaScript bindingspkg/retro_z80_emulator_bg.wasm - WebAssembly binary<script type="module">
import init, { Z80Emulator } from './pkg/retro_z80_emulator.js';
async function main() {
await init();
const emulator = new Z80Emulator();
// Load a ROM
const response = await fetch('rom.bin');
const data = new Uint8Array(await response.arrayBuffer());
emulator.load_rom(data);
// For 8251-based ROMs (like Grant's BASIC)
// emulator.set_8251_mode(true);
// Run emulation loop
function runLoop() {
emulator.run(50000); // Run 50000 cycles
// Get any output from the serial port
const output = emulator.get_output_string();
if (output.length > 0) {
console.log(output);
}
requestAnimationFrame(runLoop);
}
runLoop();
// Send keyboard input
document.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
emulator.send_char(13);
} else if (e.key.length === 1) {
emulator.send_char(e.key.charCodeAt(0));
}
});
}
main();
</script>
| Method | Description |
|---|---|
new Z80Emulator() |
Create a new emulator instance |
load_rom(data: Uint8Array) |
Load ROM data and reset CPU |
reset() |
Reset the CPU |
run(cycles: number) |
Execute given number of cycles |
send_char(c: number) |
Send a character to serial input |
send_string(s: string) |
Send a string to serial input |
get_output_string() |
Get and clear serial output buffer |
set_8251_mode(enabled: boolean) |
Switch between ACIA and 8251 mode |
get_pc() |
Get program counter |
get_cycles() |
Get total cycles executed |
is_halted() |
Check if CPU is halted |
Simple emulator that connects stdin/stdout directly to the emulated serial port:
./target/release/retroshield [OPTIONS] <rom.bin>
Options:
-d Debug mode (prints load info)
-c <cycles> Run for specified cycles then exit
Full-screen debugger with register display, disassembly, stack view, memory view, and terminal:
./target/release/retroshield_tui <rom.bin>
┌─ Registers ─────────┬─ Disassembly ──────────┬─ Stack ─────────┐
│ PC:0075 SP:FFC2 │ >0075: LD A,($2043) │>FFC2: 0075 │
│ AF:0042 BC:010D │ 0078: CP $00 │ FFC4: 0120 │
│ DE:215C HL:20A6 │ 007A: JR Z,$0075 │ FFC6: 0000 │
│ IX:0000 IY:0000 │ ├─ CPU State ─────┤
│ Flags: -Z----N- │ │ IM:1 IFF1:1 │
├─ Memory @ $2000 ────┤ │ HALT:0 I:00 R:7F│
│ 2000: 00 0D 50 52...├────────────────────────┴─────────────────┤
│ 2010: 57 20 57 4F...│ Terminal │
│ ... │ Z80 BASIC Ver 4.7b │
│ │ Ok │
│ │ █ │
└─────────────────────┴──────────────────────────────────────────┘
[RUNNING] Z80:31.16MHz CPU:5.8% Mem:8.5MB F5:Run F6:Step F12:Quit
| Key | Action |
|---|---|
| F5 | Run continuously |
| F6 | Step one instruction |
| F7 | Pause execution |
| F8 | Reset CPU |
| F9/F10 | Memory view scroll up/down |
| PgUp/PgDn | Memory view scroll (16 lines) |
| Alt+=/Alt+- | Adjust emulation speed |
| F12 | Quit |
| Other keys | Send to emulated terminal |
The TUI starts in paused mode. Press F5 to run or F6 to step.
The status bar shows:
| Port | Read | Write |
|---|---|---|
| $80 | Status register | Control register |
| $81 | Receive data | Transmit data |
| Port | Read | Write |
|---|---|---|
| $00 | Receive data | Transmit data |
| $01 | Status register | Mode/Command register |
The roms/ directory contains pre-built ROM binaries for testing:
| ROM | Description | Serial | Source |
|---|---|---|---|
mint.z80.bin |
MINT interpreter | ACIA | kz80_mint |
firth.z80.bin |
Firth Forth | ACIA | jhlagado/firth |
monty.z80.bin |
Monty interpreter | ACIA | kz80_monty |
pascal.bin |
Retro Pascal | ACIA | retro-pascal |
grantz80_basic_new.bin |
Grant's BASIC 4.7b | 8251 | kz80_grantz80 |
basic_gs47b.bin |
Grant Searle BASIC | 8251 | Grant Searle |
efex.bin |
EFEX monitor | 8251 | kz80_efex |
# Run MINT
./target/release/retroshield roms/mint.z80.bin
# Run Grant's BASIC with TUI
./target/release/retroshield_tui roms/grantz80_basic_new.bin
# Run Firth Forth
./target/release/retroshield roms/firth.z80.bin
# Run Retro Pascal with TUI
./target/release/retroshield_tui roms/pascal.bin
MIT License - see LICENSE