Copperline 0.16.0: one-command WHDLoad, a game library, and a new Amiga game built on Copperline
A WHDLoad-installed game now boots straight from its archive with
one command, copperline --whdload Turrican.lha, and
the launcher grows a game library around it, with details and
cover art from OpenRetro. For people writing new Amiga software,
--run warp-boots a freshly built executable from the
host filesystem. Several of this cycle's accuracy fixes came from
that kind of use: a studio is building a new commercial Amiga game
with Copperline running beside real AGA hardware.
Storage gains a built-in lide.device-compatible IDE board with ATAPI CD-ROM support, OFS directory mounts that boot Kickstart 1.3, a Create Image workshop for new ADFs and HDFs, and gzip-compressed hardfiles. Elsewhere: configurable output paths with an opt-in portable mode, Kickstart ROM identification by checksum, an on-screen keyboard and picture centring on the desktop, bezel sticker decals, and IPF images in the browser build. As always, compatibility fixes model the underlying Amiga subsystems rather than individual titles.
A new Amiga game is being built on Copperline
Brazen Gameplay are developing Urb-X Warriors: The Lost City, a new commercial 16-bit Amiga platformer. Copperline is part of their development workflow: they run work-in-progress builds in the emulator beside real AGA hardware. A studio writing new code pushes the machine in ways thirty-year-old software does not.
My favourite find of the cycle came from them. Their code read back a write-only chip register and OR-ed the result into palette writes. On real AGA hardware the chip data bus floats, so the read returns whatever residue the last driven bus cycle left behind, and the palette went dark. Copperline, like other emulators, returned a clean zero, so the bug hid. As of 0.16.0 Copperline models the floating bus, and the same code misbehaves in the emulator as it does on the real silicon. For a development tool, being right sometimes means reproducing your bugs faithfully.
The same collaboration led to the bitplane-pointer and wide-fetch fixes below, and to a guarantee that pausing a session to inspect the machine never changes what it goes on to do. Their Kickstarter page is the place to follow the game.
Direct WHDLoad boot
copperline --whdload game.lha boots a WHDLoad-installed
game package directly, with no Workbench disk or hand-built hard
drive. The package is extracted once into a per-game library, so
savegames persist on the host. A boot volume is regenerated around
the real WHDLoad program on every launch. The machine is derived
from the slave header: the canonical A1200 with 8 MiB of fast RAM,
unless your config says otherwise.
Kickstart images are identified by content, using the same CRC WHDLoad uses, so byte-swapped dumps, doubled images and Cloanto-encrypted ROMs are all recognized. A slave that needs a missing image fails with the name of the exact file it wants. The WHDLoad and skick support archives are fetched with pinned checksums at packaging time. You still supply the Kickstart ROMs yourself.
A game library
The launcher's WHDLoad page becomes a browsable collection. Point
it at a folder of games as .lha, .zip or
plain directories and it lists them with details and cover art
from OpenRetro, plus A-Z shortcuts to jump through the list.
Dropping a package onto a running machine reboots into it.
Contributed by Lee Hobson
(@hobbo91).
--run: a developer warp launch
copperline --run build/hello stages a minimal boot
volume, mounts the executable's directory live, and warp-boots
until the guest OS loads the program. On the bundled AROS ROM that
takes about one wall-clock second, in the spirit of the
vscode-amiga-debug workflow. With --gdb the session
stops at the program's first instruction, and the control protocol
gains a loadseg breakpoint kind for scripted sessions.
It works with every headless flag, so a CI run can build an Amiga
binary and screenshot it running.
A lide.device IDE board, and ATAPI everywhere
A new built-in Zorro II IDE board is compatible with LIV2's
open-source lide.device (RIPPLE, RIDE and AT-Bus 2008
personalities). ATAPI CD-ROM support also arrives on all three IDE
interfaces: Gayle, the A4000's motherboard port and the new board.
A .cue, .iso or .chd path on
any IDE drive slot attaches a real IDE CD-ROM drive, and
[[host_disk]] can hand a real host disk to a lide
channel. Contributed by Simon Dick
(@sidick).
OFS mounts that boot Kickstart 1.3
A hard-drive slot pointing at a host directory can now build its
volume as OFS (filesystem = "ofs"), the filesystem
every Kickstart ROM since 1.2 carries. A directory mount can
therefore boot a stock Kickstart 1.3 machine to Workbench with no
FFS handler installed anywhere. Contributed by Simon Dick.
A Create Image workshop
Storage → Create Image... makes new disk images from inside the launcher. Floppies can be DD or HD, standard or extended ADF, with any of the eight DOS types, boot code and a volume name. Hard-disk images go up to 9999 MB or GB, with or without an RDB, and support custom geometry, boot priority and sparse allocation. Contributed by Lee Hobson.
Configurable paths, portable mode and a default config
Everything Copperline produces (screenshots, save states, video
and input recordings, NVRAM, traces and waveform captures) now
lands in named folders under the host-data directory instead of
the process working directory. A new [paths] section,
with its own launcher page, sets where each kind of output goes and
where empty file dialogs open. Relative entries follow a movable
base. A portable.txt next to the executable makes the
whole installation self-contained, saves included, so it can run
from a USB stick. The launcher's Save button now offers Save As,
Save default and Reset default, and a saved default is what
Copperline starts with when nothing else names a config.
Contributed by Lee Hobson.
Kickstart ROMs, identified by checksum
A ROM file's name is whatever its dumper called it. Copperline now identifies which Kickstart it is from 67 known images, 1.0 to 3.2.3, including betas, prototypes and the CD32 and CDTV extended ROMs. The result appears in the startup banner, the About panel, the ROM-load OSD and the launcher's ROM tab.
The desktop, the bezels and the browser
The A600 keyboard strip from the browser build arrives in the desktop window with a status-bar toggle. New H / V-centre controls nudge the TV picture the way a monitor's front-panel knobs did. The 1084 front is rebuilt from new reference photography and is much closer to the real monitor (contributed by Lee Hobson). The tube now shows the whole captured raster, and a bezel stickers folder puts your own decals on the case, on desktop and web alike.
copperline.dev/try now reads IPF images, offers both monitor fronts, and separates Esc from fullscreen with the Keyboard Lock API: tap Esc to release the mouse, hold it to leave fullscreen.
Storage and capture odds
- Gzip-compressed hardfiles (
.hdz) open directly, with session-only writes. - DMS archives with non-linear track layouts extract correctly.
- The launcher's Storage Browse dialog picks directories, and serial TCP addresses are typed straight into the I/O Ports tab.
--screenshot-afterand--save-state-afternow repeat, so one run can capture a whole sequence.
Hardware accuracy fixes
- Agnus bitplane pointers are one live counter. They are never reloaded at vertical blank, and a CPU half-write merges into the DMA-advanced live value. A display that rewrites its pointers mid-frame depends on this.
- An AGA display fetching 64 pixels per gulp is placed from the absolute wide-fetch grid, so the first gulp sits left of the display window instead of leaking a seam onto it.
- Reading a write-only custom register returns the residue of the last driven chip-bus cycle, not a clean zero. Brazen Gameplay reported this floating-bus behaviour from real AGA hardware.
- CPU palette writes resolve against the live BPLCON3 bank, and an out-of-range playfield priority blanks the playfield on Denise only, matching photographed real-chip behaviour in the Bubble and Squeak and Alfred Chicken in-game graphics.
- Each ATA device keeps its own cylinder registers, as on real hardware where the signature a driver probes belongs to the selected device.
- Cold-boot RAM contents are configurable (zero, seeded random or a fixed 16-bit pattern) for software whose behaviour depends on what a real machine's DRAM woke up holding.
- Host volume names are converted to the Amiga's own Latin-1 character set, so an accented label survives the trip into AmigaDOS (Volker Schwaberow).
Desktop, tooling and platform
- Stopping a session at an exact time through the control
protocol no longer perturbs the timeline: a single
run_untiland the same span sampled in ten stops now end on the same cycle, so an investigation can add observation points without changing what it observes. - Opening the debugger or another tool window leaves main-window Amiga input alive.
- A trapping WASM plugin board is isolated permanently instead of re-trapping every frame, and its DMA commits transactionally. A two-level case-insensitive path cache speeds up directory-mounted volumes. (Both by Volker Schwaberow.)
- Debugger fixes: the memory-scan address is masked to the bus width, and copper-list disassembly aligns to the list start (Volker Schwaberow).
- HostSocket's
bsdsocket.libraryLVO table extends through the real end of the jump table, so software indexing deep LVOs finds them (Simon Dick). - The dependency tree moves to current releases, and the
m68k
core at 0.10.14 fixes a real 68000
MOVEM.Lbus-order bug that corruptedlide.devicesector reads under real Kickstart. - Homebrew installs from the release archive again (the 0.15.0 formula needed a fix).
Contributed this cycle
Copperline welcomes a new contributor this cycle: Volker Schwaberow (@vschwaberow), who arrived with five merged PRs. They cover WasmBoard fault isolation and transactional DMA, the host-filesystem path cache, two debugger fixes, Latin-1 volume labels and a disassembler cleanup. Welcome aboard.
Lee Hobson (@hobbo91) again wrote more code this cycle than I did: 24,000 lines to my 16,000. I have made my peace with it. His work this cycle was the WHDLoad game library with OpenRetro details, cover art and A-Z navigation, the Create Image workshop, the configurable-paths system with portable mode and the saved default config, and the rebuilt 1084 bezel.
Simon Dick (@sidick) contributed the lide.device-compatible IDE board with ATAPI CD-ROM and host-disk support, OFS for directory-mounted hard drives, the launcher's directory picker, and the full-length bsdsocket LVO table.
Brazen Gameplay fed back findings from running their work-in-progress game on Copperline beside real AGA hardware. The floating-bus model, the bitplane-pointer fix, the wide-fetch origin fix and the deterministic control stepping all came from that collaboration. Four people shipped 201 commits in seven days. This project has become a team, and it is wonderful to watch.
Compatibility notes
Save states from 0.15.0 do not load in 0.16.0. The serialized machine shape changed several times this cycle, so the state format version moves from 50 to 54. Re-create snapshots after upgrading.
Output files move out of the working directory.
Screenshots, save states, recordings, NVRAM, traces and waveform
captures now land in named folders under the host-data directory,
or wherever [paths] points. Explicit CLI paths
(--screenshot-after and friends) are still used
exactly as written. Legacy battmem.nvram and
cd32-nvram.bin files in the working directory are
still used from there, so real game saves are never silently
relocated.
A saved default configuration now auto-loads. A
default saved from the launcher is what Copperline starts with
when neither --config nor
./copperline.toml names one. For reproducible runs on
a machine you do not control, pass --factory to
ignore it.
Get it
Builds for macOS, Linux and Windows are on the release page, and the Homebrew tap is updated. Or skip the download entirely: copperline.dev/try is the same emulator.
Copperline also has a Patreon. Nothing there buys a feature or a place in the queue - monthly support goes towards development time, real hardware to measure the emulator against, and the code-signing subscriptions that would let the downloads open without a warning.
- Andrew Hutchings (LinuxJedi) · linuxjedi.co.uk