Cycle-driven chip bus
The chip bus is arbitrated per colour clock between refresh, display, sprite, disk and audio DMA, the Copper, the blitter and the CPU - with hardware per-word bus sequences and modelled 68000 interrupt-recognition latency.
Cycle-driven · OCS / ECS / AGA · written in Rust
Cycle-driven means the whole machine advances on one colour-clock timeline - CPU, DMA, Copper, blitter, all of it. Built around that core: a debugger that steps backwards, a chip-bus frame analyzer, and byte-identical record and replay.
0.11.0 is out · read what's new
A macOS .dmg, a Linux AppImage or a Windows zip from the latest release - or install with Homebrew.
Copperline boots the bundled open-source AROS ROM straight away. No Kickstart hunt before you see a working machine.
Load an ADF from the status bar's disk controls, or skip the window
entirely: copperline game.adf.
Have real Kickstart ROMs and disk images? They work too - point the launcher at them. Copperline just doesn't make you find them before you can try it.
The 68000, Agnus, Denise, Paula, the CIAs and the floppy, all scheduled against a single colour-clock timeline. 68000 cycle counts are validated against the TomHarte SingleStepTests, and chip-bus timing against a test disk cross-checked on real hardware and the vAmigaTS suite.
The chip bus is arbitrated per colour clock between refresh, display, sprite, disk and audio DMA, the Copper, the blitter and the CPU - with hardware per-word bus sequences and modelled 68000 interrupt-recognition latency.
Independent Agnus / Denise revisions and machine profiles spanning the A1000, A500 / A500+ and A1200, plus CDTV and CD32. Boots the bundled AROS ROM out of the box - no Kickstart needed - as well as Kickstart 1.3 / 2.05 / 3.1 and DiagROM, and runs the timing-sensitive regression set at real speed.
Selectable 68000 / 68EC020 / 68020 / 68030 / 68040 / 68060 and clock, accurate 68000 cycle counts, the 68030 / 68040 / 68060 MMUs, on-chip caches (on by default where the silicon had them), 68060 superscalar dual-issue with its branch cache, and an 80-bit 68881 / 68882 FPU with pure-Rust softfloat transcendentals and packed-decimal reals.
A bit-timed keyboard (6500/1 MCU), mouse, USB gamepad (pure-Rust gilrs, no SDL2), and 4-channel Paula audio with the LED filter, selectable host output device and mono / stereo shaping - plus Paula's serial port bridged to host MIDI or TCP.
Up to four floppies (ADF / ADZ / DMS / SCP, plain or zipped) with multi-disk swap playlists, Gayle IDE and A2091 / A4091 SCSI boards carrying up to seven drives, CDTV and CD32 CD-ROM, Zorro II / III autoconfig, and host directories mounted as live AmigaDOS volumes - bootable ones included.
Functional Zorro boards sit behind a clean device boundary, so external WASM plugin boards can add deterministic read / write / tick / interrupt behaviour, with optional DMA, file resources and networking. A built-in Commodore A2065 Ethernet board (Am7990 LANCE) ships with a loopback backend.
8 bitplanes, a 256-entry 25-bit palette, HAM8, FMODE wide fetch, dual playfield, EHB, sprites and hardware collisions - replayed by beam position so the renderer never races the chipset.
Optional phosphor persistence, a motion-adaptive deinterlacer for laced screens, and tv / full overscan. The woven field is presented at a TV-like 4:3, the way the hardware drove a real monitor.
An in-window debugger that steps backwards, a GDB-flavoured console, a chip-bus frame analyzer, deterministic save states, input recording / replay, and headless screenshot & frame-dump capture. Every replay is byte-identical.
Real captures from the emulator window - chrome, status bar and all. Save a still to PNG, or record the screen to a lossless AVI - both locked to the emulated clock, so even a warp-speed capture plays back at the right speed.
Launch Copperline with no options and it opens a full machine-configuration launcher - also reachable from the menu. Pick a base profile, tweak it, then Run - no hand-written TOML required to get going.
Edit the machine profile, chipset, CPU, memory, ROM, floppy, hard disk, CD, Zorro boards, audio / video and emulation behaviour through a graphical front-end - including settings declared by external plugin boards.
It reads and writes the same TOML schema as a hand-edited config, so Load, Save, Run and Defaults round-trip cleanly with the config files you already keep.
Press Cmd+B to pause and open the in-window debugger: eight tabs covering the CPU, the chipset, the Copper, the display pipeline, Paula audio, memory, the IO map and breakpoints - with a GDB-flavoured console (Cmd+K) in its own window alongside. Then step the machine backwards.
The recurring hard question in a corruption bug is "the value at address X is wrong by the time I look - which instruction wrote it?". Stop at the symptom, then walk backwards to the culprit.
Because the core is deterministic and already snapshots the whole machine, going
back in time needs no special record layer the way a tool like rr
does. The emulator keeps a ring of in-memory snapshots; to reach an earlier
point it restores the nearest one and replays forward - byte-identical.
There is also a headless "last writer" reverse watchpoint for automated root-cause hunts. See the reverse-debugging guide.
Pause the machine and open the chip-bus frame analyzer. It paints one captured frame as the full raster - x is hpos in colour clocks, y is the beam line - with every cycle coloured by the bus master that owned it.
Refresh, bitplane, sprite, disk and audio DMA, the Copper, the blitter and the CPU all compete for one chip bus. The analyzer tallies who won every slot across the frame, so a dropped line or a blit that starves the CPU is visible directly.
It breaks out blitter grant against wait - the cycles the blitter held the bus versus the cycles it stalled behind higher-priority DMA - and you can click any cycle to read back its line, hpos and owner.
// chip-bus owners, one frame
The core is deterministic and independent of the host: a windowless, unthrottled run produces the same emulated result as a real-time windowed one, given the same inputs and media. That determinism is what makes captures reproducible, and it is also what lets the debugger step backwards.
--model, --cpu, --chip and friends - no
config file required..clscript and replay it byte-for-byte - a bug report that always
reproduces.--load-state brings a
machine snapshot back even when the original Kickstart isn't on hand - the
save state carries the whole machine.# boot a disk, tap space, wait, grab a screenshot - no window
copperline game.adf --noaudio \
--press-after 4 SPACE \
--screenshot-after 12 shot.png
# record a whole session, then replay it byte-identically
copperline game.adf --record-input run.clscript
copperline game.adf --script run.clscript --audio-wav run.wav
From the 68000 prefetch queue to Paula's audio mixer - the timing model is documented next to the code and backed by named regression tests.
A vendored pure-Rust m68k core drives the CPU, with 68000 cycle counts validated against the TomHarte SingleStepTests to within about a percent. A bootable timing-test disk cross-checks chip-bus timing against real hardware and other emulators, a golden-render probe suite compares chipset timing output pixel-for-pixel on every CI run, and the vAmigaTS suite runs as a compatibility regression. The detailed architecture and timing model live in the internals docs.
Emulator pages tend to list only the good parts. Copperline is young and moving fast, so here is the actual state of things - the rough edges included. This list changes every release.
Development happens in the open, and main usually runs well ahead
of the release you can download. Right now it doesn't: 0.11.0 has just shipped,
so for once the release and main are the same machine.
Every release gets a write-up on the news page when it
ships. If you want to follow development commit by commit,
brew install --HEAD copperline builds main today.
Grab the latest release, or build from source with a stable Rust toolchain. Developed and tested on macOS, with a universal macOS .dmg, a Linux AppImage and a Windows build available. Every build ships the open-source AROS boot ROM, so it runs out of the box with no Kickstart required.
Download the latest release# open Copperline-0.11.0-macos-universal.dmg and drag
# Copperline.app into your Applications folder, then launch it
# the build is not notarized, so macOS blocks the first launch.
# approve it once under System Settings > Privacy & Security
# (click "Open Anyway"), and it launches normally from then on
# tap the repository and install the latest release
brew tap LinuxJedi/copperline https://github.com/LinuxJedi/Copperline
brew install copperline
# or build the latest development version from main
brew install --HEAD copperline
# grab the .AppImage from the latest release, then make it executable
chmod +x Copperline-0.11.0-x86_64.AppImage
# run it - the bundled AROS ROM means no Kickstart is required
./Copperline-0.11.0-x86_64.AppImage
# or boot your own Kickstart ROM, or a config file
./Copperline-0.11.0-x86_64.AppImage path/to/kickstart.rom
./Copperline-0.11.0-x86_64.AppImage --config copperline.toml
# with Homebrew on Linux, tap the repository and install
brew tap LinuxJedi/copperline https://github.com/LinuxJedi/Copperline
brew install copperline
# or build the latest development version from main
brew install --HEAD copperline
# download and extract Copperline-0.11.0-win-x64.zip, then from a terminal
# with no ROM it boots the bundled AROS Kickstart replacement
copperline.exe
copperline.exe path\to\kickstart.rom
copperline.exe --config copperline.toml
# clone and build (release - debug is too slow for real-time)
git clone https://github.com/LinuxJedi/Copperline.git
cd Copperline
cargo build --release
# run it - with no ROM it boots the bundled AROS Kickstart replacement
./target/release/copperline
# or boot your own Kickstart ROM, or a config file
./target/release/copperline path/to/kickstart.rom
./target/release/copperline --config copperline.toml
Requires Rust 1.87+ (stable). No SDL2 dependency.
No. Every build bundles the open-source AROS boot ROM, so Copperline starts into a working machine out of the box. Most commercial games and Workbench still want a real Kickstart, though - use one dumped from your own Amiga, or a licensed copy (Cloanto's Amiga Forever is the usual route). Copperline does not ship Commodore ROMs and never will.
Copperline is a free-time project and I don't keep a paid Apple Developer subscription for it. The .dmg is ad-hoc signed, so macOS asks you to approve the first launch under Privacy & Security - once, then never again.
If you'd rather not click through that at all, the Homebrew tap builds from source on your machine, so Gatekeeper never gets involved.
They are mature emulators with decades of compatibility work behind them, and if you just want to play Amiga games today, they are the safer pick. I cross-check Copperline's chip-bus timing against real hardware and other emulators with a bootable test disk, so I say this with some affection.
Copperline's angle is the deterministic core and the tooling built on top of it - the reverse debugger, the frame analyzer, headless scripting - plus being a single from-scratch Rust codebase you can read end to end.
Maybe - and it gets more likely every release. A growing timing-sensitive regression set runs at real speed, and fixes always target the underlying hardware behaviour rather than patching individual titles. But compatibility is still behind the mature emulators, and some things will break.
When something does, an issue with a .clscript recording
attached is gold: it replays byte-identically, so I can watch exactly what
you saw and step the machine backwards from the moment it went wrong.
Yes, openly. Copperline began partly as an experiment in whether an AI agent could investigate emulator bugs on its own from screenshots and debug output, and its development is AI-driven - directed by me, and grounded in books, my own knowledge of Amiga internals, and test disks I run on real hardware.
Judge the result the way any emulator should be judged: named regression tests, cycle counts validated against published test suites, cross-checks against real machines, and public code.
The Copper - the Amiga co-processor that executes a program locked to the display beam - and the copper raster bars it painted across a thousand demos. For an emulator whose whole design hangs off the colour clock, it felt right.
Copperline started as a two-part experiment: could I build an Amiga emulator that is easy to drive from the command line, and could I give it the tooling to feed debugging data and screenshots back to an AI agent, so a bug could be investigated from nothing but a timestamp or a snapshot? The first milestone was getting DiagROM to boot far enough to show its menu.
It didn't stay small. The features I care most about are the ones I kept wishing for while chasing timing bugs: a debugger that steps backwards, an analyzer that shows who owned every cycle of the chip bus, replays that always reproduce. Everything else on this page grew around that core.
When I'm not writing Rust, I'm usually elbow-deep in the real machines - collecting, repairing and designing hardware for them. That is where Copperline's real-hardware timing references come from, and probably why I care so much that the emulated machine earns its cycle counts.
- Andrew Hutchings (LinuxJedi) · linuxjedi.co.uk · GitHub