Skip to content

andrewimm/ezpc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EZPC - 8088 IBM PC Emulator

A high-performance, cycle-accurate emulator of the original IBM PC with Intel 8088 processor, implemented in Rust. The emulator features a three-tier execution system (cold/warm/hot paths) designed for progressive optimization as code executes, aiming to achieve both accuracy and performance through direct dispatch, decode caching, and compiled basic blocks.

The Real Goal: AI-Generated Code Experiment

While the original goal was to build an insanely efficient PC emulator, the actual goal became to see if Claude Code could write the entire thing, end to end. Every single line of code in this repository was generated by Claude (Anthropic's AI assistant). I haven't written any code myself—I've architected the design, provided prompts and direction, reviewed the output, and guided the implementation, but 100% of the actual code was AI-generated.

This project serves as an exploration of what's possible with AI-assisted development in 2025, particularly for complex systems programming tasks like emulator development.

Current Status

The emulator now successfully POSTs and boots IBM Cassette BASIC! 🎉

The CPU core and essential peripherals are functional, allowing real IBM PC BIOS to execute.

CPU Instructions (Complete 8088 Instruction Set)

  • Data Transfer: MOV, XCHG, LEA, LDS, LES, XLAT, PUSH, POP (registers and segments)
  • Arithmetic: ADD, ADC, SUB, SBB, INC, DEC, CMP, NEG, MUL, IMUL, DIV, IDIV, AAA, AAS, AAM, AAD, DAA, DAS, CBW, CWD
  • Logic: AND, OR, XOR, TEST, NOT
  • Shift/Rotate: SHL, SHR, SAR, ROL, ROR, RCL, RCR
  • Control Flow: JMP, CALL, RET (near/far), INT, IRET, conditional jumps (Jcc), LOOP family
  • String Operations: MOVS, STOS, LODS, CMPS, SCAS (byte/word with REP/REPE/REPNE)
  • Flag Manipulation: CLC, STC, CMC, CLI, STI, CLD, STD, PUSHF, POPF, SAHF, LAHF
  • I/O: IN, OUT (immediate and DX port)
  • Prefixes: Segment overrides (ES, CS, SS, DS), REP, REPE, REPNE
  • System: HLT, NOP

Hardware Components

  • 8088 CPU: Full instruction set with lazy flag evaluation
  • MDA (Monochrome Display Adapter): 80x25 text mode with 720x350 graphical output
  • 8259 PIC (Programmable Interrupt Controller): Edge-triggered interrupts, priority handling, masking
  • 8253 PIT (Programmable Interval Timer): Timer channel 0 with IRQ0 generation
  • 8255 PPI (Programmable Peripheral Interface): Keyboard input, DIP switches, reset control
  • Memory: 64KB RAM, 64KB ROM/BIOS, MDA VRAM at 0xB0000

Core Features

  • Lazy flag evaluation for performance
  • ModR/M decoding with all addressing modes
  • Segment:offset memory addressing
  • Hardware interrupt handling via PIC
  • REP prefix support with conditional termination
  • GDB remote debugging over Unix socket
  • Comprehensive test suite (479+ tests)

Architecture

The emulator is designed around three execution tiers:

  1. Tier 1 (Cold Path): Direct dispatch using function pointers for first-time instruction execution
  2. Tier 2 (Warm Path): Decode cache for frequently executed instructions
  3. Tier 3 (Hot Path): Compiled basic blocks for the hottest code paths

Currently, Tier 1 is implemented and functional. See ARCH.md for detailed architecture and implementation plan.

Building and Testing

# Build the project
cargo build

# Run tests
cargo test

# Run in release mode (for benchmarking)
cargo build --release

GDB Remote Debugging

The emulator includes built-in support for GDB remote debugging over a Unix socket. This allows you to inspect CPU state, set breakpoints, single-step through code, and examine memory while the emulator runs.

Basic Usage

  1. Start the emulator with GDB enabled:
cargo run --release -- --gdb /tmp/ezpc.sock bios.rom
  1. In another terminal, connect with GDB:
gdb
(gdb) set architecture i8086
(gdb) target remote /tmp/ezpc.sock

GDB Commands

Once connected, you can use standard GDB commands:

# View registers
(gdb) info registers

# Read memory (segmented addressing)
(gdb) x/16xb 0xf000:0xfff0

# Set a breakpoint at a specific address
(gdb) break *0xf000:0xe000

# Single-step instructions
(gdb) stepi

# Continue execution
(gdb) continue

# Read/write registers
(gdb) print $eip
(gdb) set $ax = 0x1234

Supported GDB Features

  • ✅ Register read/write (AX, BX, CX, DX, SI, DI, SP, BP, IP, FLAGS, CS, SS, DS, ES)
  • ✅ Memory read/write (linear addressing)
  • ✅ Breakpoints (software breakpoints at any address)
  • ✅ Single-step execution (stepi)
  • ✅ Continue execution (continue)
  • ✅ Halt reason reporting (SIGTRAP on break/step)

Architecture Notes

The GDB integration uses non-blocking I/O to avoid impacting emulation performance:

  • Socket I/O runs in a separate thread
  • Commands are queued and processed each frame
  • Emulation never blocks waiting for GDB
  • Zero performance overhead when debugger not connected

Help

# View all command-line options
cargo run -- --help

Project Structure

  • src/cpu/ - CPU emulation core
    • state.rs - CPU registers, flags, and state management
    • decode/ - Instruction decoding (ModR/M, operands)
    • execute/ - Instruction handlers by category
    • tier1/ - Direct dispatch implementation
  • src/debugger/ - GDB remote debugging support
    • protocol.rs - GDB Remote Serial Protocol packet handling
    • socket.rs - Non-blocking Unix socket I/O thread
    • commands.rs - GDB command handlers (g, m, s, c, Z, etc.)
    • mod.rs - Debugger core and state management
  • src/components/ - Hardware components
    • mda.rs - Monochrome Display Adapter with font ROM
    • pic.rs - 8259 Programmable Interrupt Controller
    • pit.rs - 8253 Programmable Interval Timer
    • ppi.rs - 8255 Programmable Peripheral Interface
    • keyboard.rs - XT keyboard with scancode generation
    • dma.rs - 8237 DMA Controller (stub)
  • src/emulator/ - Emulator state and coordination
    • graphics.rs - WGPU-based framebuffer rendering
    • scancode.rs - PC XT scancode translation
  • src/memory.rs - Memory bus with RAM/ROM/VRAM
  • tests/ - Comprehensive test suite organized by instruction type

Development Approach

This project follows a strict incremental development methodology:

  • Small, atomic commits representing single logical changes
  • Test-driven development with tests written alongside implementations
  • Continuous verification (cargo check, cargo test, cargo fmt before each commit)
  • Architecture-guided implementation following the phases in ARCH.md

Every commit represents a complete, working state of the emulator with all tests passing.

License

MIT License - See LICENSE file for details.


Note: This is an active experiment in AI-generated code. The human's role has been purely architectural and directorial—the implementation is entirely Claude's work.

About

IBM PC Model 5150 Emulator

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages