Copperline 0.19.0: Amiga debugging from VS Code, Bartman's profiler on Copperline, and two open ROMs
Copperline 0.19.0 is the developer release. A new Debug Adapter Protocol server lets you debug an Amiga program at source level from Visual Studio Code, with breakpoints, stepping and Step Back. Bartman's Amiga C/C++ extension also runs on Copperline, with its visual profiler fed by the emulator's per-colour-clock bus captures.
Developers also get an MCP server for AI coding agents, a WinUAE-compatible
uaelib trap, an HRTMon freezer cartridge and CPU wait attribution in the Frame
Analyzer. Away from the debugger, there are open-source replacements for the
CD32 FMV and A2091/A590 ROMs, Simon Dick's copperhf.device
hard-disk controller, and uncapped integer scaling with autocrop. As always,
the compatibility fixes model the Amiga's chips rather than individual
titles.
Source-level debugging in VS Code
copperline-ctl --dap is a Debug Adapter Protocol server built on
the control protocol, and tools/vscode-copperline packages it as a
VS Code extension. A launch.json names the executable and the
machine. F5 boots the bundled AROS ROM or a Kickstart ROM from 1.3 up,
warp-boots to the program and stops at main with the source open.
From there it works like any other VS Code debugger. Source, function,
instruction, data and exception breakpoints take conditions the machine
evaluates itself (d0 == 5, [$DFF006] != 0). Step
Over, Into and Out work by statement or instruction. There are Registers (FPU
included), Locals and Globals, hovers and watch expressions, and Memory and
Disassembly views with per-instruction cycle counts and ROM addresses named
live from the running guest ([exec] AllocMem+$12). Two things are
specific to Copperline. Step Back and
Reverse Continue work, because the machine is deterministic
and keeps a ring of snapshots. A Chipset scope and a Custom Registers tree
document every custom register's bit fields and access rules, from a new
reference covering all 237.
Debug information comes from vasm's LINE hunks, the DWARF that
amiga-gcc 6.5 leaves in the executable, or an ELF sibling from Bartman's
m68k-amiga-elf-gcc. For relocatable multi-file builds, the reader
applies the relocations itself. The Profile button captures frames as a
source-mapped .cpuprofile with a [Bus wait] child
separating chip-DMA contention from CPU work. nvim-dap and any other DAP client
can use the same adapter. See the VS Code chapter
and the DAP reference.
Bartman's extension, running on Copperline
Bartman's Amiga C/C++ extension (compiler, patched GDB, source annotations and the visual profiler) only spoke to its own WinUAE build. A public fork adds a Copperline backend, proposed upstream as PR 307. The fork is pinned and documented, so nothing waits on the merge.
Copperline gained the other half. --gdb-gui attaches the GDB stub
to the interactive window, so the screen stays visible and the audio plays.
--gdb-dialect bartman speaks the patched GDB's wire contract (hunk
offsets, the return-from-ROM breakpoint, monitor reset,
DBG: output). monitor profile writes the extension's
profile format from Copperline's precise sampler and full bus trace. A windowed
launch waits paused until GDB connects, because on the first attempt the guest
finished loading before the debugger arrived.
The result is Bartman's profiler on a cycle-driven machine. In a captured frame,
the timeline shows the CPU call stack against DMA and blitter activity. The
Resources view reconstructs the displayed bitmap from the recorded Copper writes,
or shows a bitmap the guest registered by name. The Blitter view renders any
channel of any blit from the DMA words it moved, honouring shifts,
masks, modulos and the latched BLTxDAT inputs. The Copper list
traces each MOVE back to its frame and beam position.
The walkthrough, with a reproducible install of the fork, is Bartman with Copperline.
Profiling and chip-bus tracing
None of the above needs VS Code. profile.start over the control
protocol writes one JSON record per committed frame: chip-bus ownership per
Agnus owner, blit records, the guest's idle clocks, and optionally the
per-colour-clock owner grid in vAmiga's DMA-debugger letter code and a
screenshot per frame. "samples": true records every retired
instruction with its PC and colour-clock cost, plus live call stacks from an
unwind table. copperline-ctl profile-report converts a capture to
a Chrome .cpuprofile.
frame.slots and the bus event family expose a
24-byte record per raster colour clock: register, DMA kind and subtype, size,
IPL, CIA E-clock phase, address, data, and a hardware-event mask (blitter
start and finish, Copper WAIT wake, DDF strobes, vertical blank, CIA IRQ pins,
STOP entry and wake). The Frame Analyzer's Beam tab gains a
CPU wait view (W). It attributes every colour clock
the 68000 lost to the DMA class that held the bus, with a per-line stall gutter
and the top stalled PCs. ROM addresses in call stacks, disassembly and profiles
are resolved from the running guest's library and resident lists, so names
follow SetFunction() patches and work on any Kickstart or AROS
revision.
uaelib, MCP, and a freezer cartridge
A WinUAE-compatible uaelib trap at $F0FF60 answers the calls
Bartman's template makes. warpmode() unpaces the window, and
KPrintF output goes to stdout and the debugger console. The
debug_register_* markers feed a new Frame Analyzer Resources tab
with decoded bitmap previews and palette swatches. The overlay commands are
drawn on the window but never reach a screenshot. The trap is 32 bytes of real
68k code decoded on the bus, with no A-line or TRAP hook.
copperline-ctl --mcp exposes every control-protocol method as a
Model Context Protocol tool: 95 of them, plus session launch and attach.
Claude Code, Cursor or any other MCP client can boot a machine, set
breakpoints, step, read memory and receive screenshots as images. For Claude
Code, the whole setup is
claude mcp add copperline -- copperline-ctl --mcp.
[cartridge] model = "hrtmon" fits an Action Replay-style freezer
with HRTMon 2.39, built reproducibly from the upstream GPL source. It has a
1 MiB bank at $A10000, and a freeze copies a shadow of every custom
and CIA register into it. The freeze itself is a level-7 NMI through the current
VBR, which the 68000 takes at the next instruction boundary whatever the SR
mask. Freeze with Tools → Freeze in the window or
--freeze-after headless, and use x in the monitor to
carry on.
Two open ROMs
The last release added the CD32 FMV cartridge but needed Commodore's cartridge
ROM. 0.19.0 ships a clean-room GPL replacement with no firmware copied. It
installs cd32mpeg.device, which reads MPEG sectors through the host
cd.device and feeds the CL450 and L64111 ports. A
videocd.library and boot strap cold-boot a White Book Video CD into
a track player under Kickstart. For AROS, the matching driver was merged
upstream this cycle. Cannon Fodder's filmed intro plays on both paths,
and the CD32 profile now fits the cartridge by default
(fmv_rom = "" gives a stock machine).
The A2091 and A590 get a clean-room 64 KiB autoboot ROM: scsi.device
42.40 derived from the open A4091 software, an RDB automounter with Kickstart
1.3 support, and a WD33C93 transport. The transport uses the board's DMAC for
even-aligned chip-side buffers and bounces through chip RAM otherwise. The
build also emits split U13/U12 EPROM halves for a real board.
copperhf.device
Simon Dick (@sidick)
built copperhf.device, Copperline's own hard-disk controller and
the analogue of WinUAE's uaehf.device. It is a Zorro II board with
a doorbell and completion-queue register block, and its autoboot ROM has an RDB
mounter that works from Kickstart 1.3 to AROS. It implements the full trackdisk
family (TD64, NSD, HD_SCSICMD with autosense, disk-change
interrupts). Completion time is a pure function of emulated time, so host disk
speed never reaches the guest. [copperhf] unit0..unit6
take RDB hardfiles, bare images, .hdz and host directories. The
launcher gains a Copperline HD page, and copperline-import-uae maps
WinUAE's uaeN drives onto it.
Scaling, autocrop, warp boot
A new WGSL scaler pass replaces the pixels crate's built-in draw, so
integer scaling is no longer capped at 4x on a 5K or 6K display. Under the
default TV pixel aspect, it now presents the unresampled canvas with a separate
whole-number factor per axis, chosen to approximate the glass's pixel shape.
[display] autocrop crops the window to the display window the
program sets up. It uses the renderer's own per-line DIW bounds, never
a title list. A latch grows the crop immediately and shrinks it after half a
second of stability, and it works for DblPAL and Multiscan screens too. The
browser build gains both controls.
--warp-boot runs any configuration unpaced from power-on until its
disks have been idle for ten seconds, then re-paces with audio.
--warp-until warps to an emulated timestamp. Lee Hobson's
[emulation] auto_launch boots a saved default straight past the
launcher, and he moved the host data directory out of the hidden config tree
into Documents. --load-uss imports a WinUAE .uss state
as an approximate interchange for resident code. --run now works on
a bare Kickstart 1.3, because the staged boot volume carries its own small GPL
shell commands.
Hardware accuracy fixes
- Floppy motor latch: every drive, DF0 included, clocks /MTR on
its own /SEL edge. DF0 was level-sensitive, which stopped a motor a loader
had just started. Alongside it, the 68000 IPL recognition pipe keeps one
deadline per source and bounds an idle
STOPnap. Pre-display sprite DMA is replayed at its own beam time, and a loader parked on DSKSYNC no longer costs a whole-revolution scan per idle slice (Spooky Town under Kickstart 1.3). - DSKBYTR and IPF density: DSKBYTR is framed by the read shifter's bit counter rather than the track's byte grid, and WORDEQUAL is a one-cell level. IPF density models for Copylock, Speedlock and Brierley tracks decode with their mastered cell timing (Lemmings' key-track check).
- Akiko: subcode frames with a regenerated Q position are delivered during CD audio play (Liberation's intro waits on them). The TX DMA keeps draining the command ring while a lead-in dump streams, so a 39-track disc no longer laps it (Pinball Illusions).
- Agnus: a bitplane fetch run carried past the last display line is
cancelled with the vertical window. This removes a phantom row the refreshed
AROS boot screen exposed, and a new
ddfprobe-vspillgolden pins it. - 68030 and 68040 timing were recalibrated against a real A4000 with three CPU boards and a new bootable probe. The 68030 now runs on the MC68020UM tables and the 68040 gets a single-issue pipeline model, replacing a scaled-68000 approximation that over-billed plain 68040 execution by about 2x.
- Toccata: the mixer no longer holds the last DAC sample forever after the codec stops (Simon Dick).
- Bundled AROS ROM refreshed to upstream master with the open
cd32mpeg.device, the CD32 chip-memory savings and CDXL presentation series, and a locally patched 8 KiB process-stack floor.
Compatibility notes
Save states from 0.18.0 do not load in 0.19.0. The state version moves from 70 to 79. Saves are now written atomically, so a failed save no longer destroys the previous snapshot.
Your host data moved to Documents, with no automatic migration.
Configs, save states, screenshots, recordings, NVRAM, gamepad calibrations and
the WHDLoad library now live in ~/Documents/Copperline/ (macOS,
Linux) or Documents\Copperline\ (Windows). Copy your old
~/.config/copperline or %APPDATA%\copperline there
once, or Copperline starts at factory settings.
Some defaults changed. The CD32 profile fits the open FMV cartridge
unless fmv_rom = "", and an A2091 with no named ROM loads the
bundled one instead of refusing to start. An explicit ROM path is honoured as
before. The uaelib trap is on by default ([emulation] uaelib = false
turns it off), and emulated 68030/68040 speed changed with the recalibration.
No configuration keys were removed or renamed.
Contributed this cycle
Simon Dick (@sidick)
built copperhf.device end to end and fixed the Toccata's stopped-codec
DC offset. Lee Hobson (@hobbo91)
added auto-launch and the Documents move. Bartman wrote the extension this
release builds on, and the AROS developers merged the open FMV driver upstream.
Get it
Pre-built packages for macOS, Linux, and Windows (including Windows on ARM) are on the GitHub release page, and the Homebrew tap has been updated. You can also run the emulator in your browser at copperline.dev/try.
Copperline is funded by its patrons, who pay for the hardware every timing model is measured against. If it is useful to you, consider supporting it on Patreon.
- Andrew Hutchings (LinuxJedi) · linuxjedi.co.uk