The port had inverted the C ownership chain: the Cpu held no memory, and One/Two implemented a Bus trait and pattern-matched addresses to their peripherals inline. This puts the mem.c design back: - New ewm-core/src/mem.rs: Memory is the mem.c region table — a base-RAM fast path (addr < ram_size) plus RAM/ROM/Device regions walked newest-first (the C list-prepend order). Devices implement the Device trait (the cpu_add_iom handlers + obj pointer) and get the absolute address; typed DeviceHandles give machines access to their peripherals afterwards. - Cpu owns the Memory; step/reset/irq/nmi lose the bus parameter and instruction handlers land on the C typedef shapes (fn(&mut Cpu), fn(&mut Cpu, u8), fn(&mut Cpu, u16)). Cpu::step stamps mem.cycles from counter, replacing the Two.cycles mirror every run loop had to maintain. - Machines shrink to composition, as in ewm_one_init/ewm_two_init: One = RAM + ROM + Pia; Two = RAM + TwoIo (the $C000-$C07F soft switches, moved out of Two with the state they own) + Alc (which now owns the machine ROM it shadows, covering $C08x and $D000-$FFFF) + Dsk + the slot 6 boot ROM region. - The Bus trait and TestBus are gone; CPU tests and benches use a flat 64K Memory, which is what cpu_test.c set up. Zero behavior change: all golden gates pass unchanged (Dormann 6502 + 65C02, the 100k golden trace, machine boots, DOS 3.3 boot + CATALOG, golden screenshot). One documented alignment: One's --memory extras now lose to base RAM like the C fast path (REWRITE.md). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Emulated Woz Machine
EWM is an emulator for the machines Steve Wozniak built: the Apple 1, the Replica 1 and the Apple ][+. It started life many years ago as a tiny 6502 emulator written between christmas and new year, and has since grown into a full emulator with Disk II support, graphics, and sound.
Note: EWM is a hobby project and still under development. Things may be incomplete, quirky, or broken — bug reports and pull requests are welcome. See REWRITE.md for the project's verification gates and a list of known quirks and deliberate divergences.
![]() |
![]() |
| Replica 1 — KRUSADER 1.3 from the Woz Monitor | Apple ][+ — booting the DOS 3.3 sample programs disk |
![]() |
![]() |
| Frogger in color hi-res graphics | Bandits by Sirius Software |
What's emulated
- Apple 1 — 6502, 8KB RAM, Woz Monitor
- Replica 1 — 65C02, 32KB RAM, KRUSADER assembler ROM
- Apple ][+ — 6502, 48KB RAM, Apple Language Card, Disk II with two drives, 40-column text, low-resolution and high-resolution graphics (color or green monochrome), speaker sound, joystick paddles and buttons
Requirements
- A Rust toolchain (the pinned version is in
rust-toolchain.toml; rustup picks it up automatically) - SDL2 —
brew install sdl2on macOS,apt install libsdl2-devon Debian/Ubuntu
Building
cargo build --release
Running
Running EWM with no arguments opens the bootloader, a menu where keys 1/2/3 select the machine to start:
cargo run --release
Or start a machine directly:
# Apple ][+ with color graphics and the DOS 3.3 sample programs disk
cargo run --release -- two --color --drive1 disks/DOS33-SamplePrograms.dsk
# Replica 1 (Woz Monitor + KRUSADER)
cargo run --release -- one --model replica1
# Classic Apple 1
cargo run --release -- one --model apple1
Each subcommand accepts --help for all options. Useful keys while the
emulator runs:
| Key | Action |
|---|---|
| Cmd-Esc | Reset the machine |
| Cmd-Return | Toggle fullscreen |
| Cmd-P | Pause (Apple ][+) |
| Cmd-I | Toggle the status bar with drive lights (Apple ][+) |
There are also headless terminal consoles, handy for quick experiments without a window:
cargo run -p ewm-core --example one # Woz Monitor
cargo run -p ewm-core --example two -- disks/DOS33-SystemMaster.dsk # AppleSoft / DOS 3.3
Testing
cargo test
This runs the full verification suite: the Klaus Dormann 6502 and 65C02
functional tests, golden instruction traces, headless machine boot tests,
a complete DOS 3.3 boot with CATALOG, and a golden screenshot comparison.
The cc65 assembly sources under tests/ are manual test programs for the
machines themselves and are not part of the automated suite.
History
EWM was originally written in C and was ported to Rust in 2026 — the full phase-by-phase plan, parity checklist, and benchmark numbers are preserved in REWRITE.md. The original C implementation lives in the git history.
License
MIT, as declared in Cargo.toml (the same license the original C carried
in its source headers).


![Apple ][+ booting DOS 3.3](/Apple-2-Tools/ewm/media/branch/memory-abstraction/screenshots/Screenshot%202026-07-05%20at%2011.30.59.png)

