Skip to content

Amiga / m68k Recompilation Landscape

A survey of native-code static reconstruction (in the N64: Recompiled / Zelda 64: Recompiled sense) for the Motorola 68000 family and Amiga specifically, contrasted with emulation, patch-and-load solutions, and source decompilation.

Companion doc: dos-recomp.md — the other platform this project’s corpora actually target, and a useful contrast: DOS has a comparably scalar CPU but no chipset problem, and does have a working static recompiler.

Static recompilation lives or dies on two things: how well-understood the target ISA is, and how much of a platform’s behavior is “just the CPU” versus offloaded to opaque coprocessors. On the first axis, m68k is about as friendly as retro silicon gets: the 68000/68010/68020/68030/68040/68060 line is a single-core, in-order CISC design with orthogonal addressing modes and — critically — no on-chip coprocessor analog to the PS3 Cell’s SPUs or the PS2’s VU0/VU1. Those platforms require a recompiler to also model a separate vector processor with its own local store and instruction set; m68k application code is “just” scalar CISC code over a flat, pre-MMU address space.

Tooling maturity reflects this. GCC has targeted m68k since the 1980s and cross-compilers still ship for it (m68k-amigaos-gcc); Ghidra and IDA both have solid built-in m68k support; and Amiga-specific tooling sits on top — the ghidra-amiga extension (loads Hunk executables, Kickstart ROMs, WinUAE state files), the older ghidra_amiga_ldr Hunks loader, and a WHDLoad-dump-specific Ghidra loader. Decoding m68k opcodes and lifting them to an IR is a solved, decades-old problem — the ISA is no obstacle to static translation.

If “recompilation” only meant “turn 68k instructions into native instructions,” Amiga recomp would already be easy — arguably easier than N64 or PS3. It isn’t, and the reason has nothing to do with the CPU.

2. The chipset, not the CPU, is where it gets hard

Section titled “2. The chipset, not the CPU, is where it gets hard”

Almost no commercial Amiga game talks to AmigaOS the way a Windows game talks to Win32. Most bypass the OS entirely and hit the custom chipset directly: Agnus (DMA/address generation, plus its Blitter and Copper sub-units), Denise (video), and Paula (audio/disk/serial) — see Amiga custom chips, the Amiga Original Chip Set overview, the Coppershade register map, and the Amiga Hardware Reference Manual.

Two sub-units make this genuinely hard, not just big. The Copper is a tiny co-processor with a three-instruction ISA (WAIT, MOVE, SKIP) that runs a “copper list” in lockstep with the video raster beam: WAIT blocks until the beam reaches a given screen position, then MOVE pokes a chipset register — the mechanism behind mid-frame palette swaps, rasterbars, and per-scanline reconfiguration with no CPU involvement. Its entire purpose is timing meaningless outside a cycle-accurate video model. The Blitter is a DMA-driven block engine reading up to three source channels through a programmable boolean function to a destination, running asynchronously and contending with the CPU and Copper for the same DMA cycles (Programming the Blitter). Games routinely “race the beam” — timing CPU work, Copper lists, and Blitter operations against exact PAL/NTSC raster position and each other’s bus contention.

Consequence: translating the 68k instruction stream to native code solves only the scalar-computation half of the problem. Much of a typical game’s actual behavior lives in chipset register writes and Copper lists, not 68k opcodes, so a static recompiler would still need a full cycle-plausible chipset model underneath (Copper interpreter, Blitter DMA engine, Denise raster timing, Paula audio/DMA). This is structurally the same shape of problem N64: Recompiled has with the RDP/RSP, or that ps3recomp has with RSX (CPU lifted natively, graphics command stream still translated via Vulkan/D3D12) — arguably worse here, since the Copper’s whole function is deterministic interaction with video timing that “just translate the CPU code” has no natural place to put.

WHDLoad — patch-and-load, not recompilation. WHDLoad is the de facto standard for running original Amiga floppy binaries from hard disk (or, in emulators like Amiberry, from disk images) without their original boot/copy-protection assumptions. Each title gets a hand-written “slave” that traps the hardware/OS accesses the game expects and redirects them — memory tricks, disk-swap emulation via file access, reset trapping — per the WHDLoad deep dive, Byte Cellar, and Pure Amiga. The original 68k code still executes, unmodified in substance — WHDLoad relocates and patches around it, it does not translate it. It’s nonetheless the foundation almost all Amiga preservation builds on (thousands of slaves at whdload.de), the only approach mature enough to reliably run a back catalog full of titles making invasive, undocumented hardware assumptions.

The UAE family — dynamic JIT, not static. WinUAE, FS-UAE, and Amiberry all descend from the UAE lineage and offer an optional JIT dynamic recompiler for 68020+ CPUs, translating blocks of 68k code to host-native code at runtime and caching them (incompatible with MMU emulation per WinUAE’s docs). This is dynamic/JIT emulation, not ahead-of-time static recompilation — no native executable is produced, and the chipset is still emulated in software alongside the CPU JIT. Amiberry ships its own custom JIT tuned for ARM64/x86_64 hosts (wiki, JIT issue thread) — same category as WinUAE/FS-UAE, separate implementation.

Static/AOT recompilation for Amiga specifically: essentially nothing found. No active or historical project statically recompiles Amiga 68k binaries to native executables in the N64:Recompiled sense turned up in extensive searching — no chipset-aware static translator comparable to ps3recomp or N64Recomp targeting Amiga titles. That’s a real, notable absence: WHDLoad’s dominance plus the mandatory chipset-emulation layer from §2 appear to have left the ground unclaimed.

Adjacent m68k precedent, off-Amiga. Sega Genesis/Mega Drive has the most mature m68k decompilation scene of any platform, anchored by Sonic Retro’s byte-exact disassemblies (s1disasm, skdisasm, which rebuilds byte-perfect Sonic & Knuckles / Sonic 3 & Knuckles ROMs) — full source-level reconstructions, adjacent to decompilation despite being framed as “ROM hacking.” Genesis static recompilation is genuinely happening: matiaszanolli/aerobiz-disasm and sega-vr-disasm (Sega 32X) sit under GitHub’s static-recompilation topic, and a personal writeup describes AI-assisted static recompilation of Sonic 1 and 2, built on Sonic Retro’s disassemblies. None of this is Amiga, but it confirms static m68k→native recompilation is demonstrated elsewhere, just not applied to Amiga yet. Classic 68k Mac emulation (Basilisk II, SheepShaver, Executor) merits a line: Basilisk II’s optional JIT is dynamic translation like UAE’s, though one standalone project has statically recompiled the copy-protected Mac game Shufflepuck Cafe to native C (also under the static-recompilation topic).

Amiga/m68k static recompilation is markedly less developed than the other platforms surveyed — not “early but real” like PS3, not “mature for one franchise” like PS2, but close to unstarted. ps3recomp is an active, real static recompiler (Cell PPU lifted via an adapted PowerPC lifter, LLVM codegen, RSX translated to Vulkan/D3D12), with at least one shipped title, flOw. OpenGOAL/jak-project is mature and shipping (Jak and Daxter, Jak 2 natively on PC) but not general-purpose — it works because Naughty Dog wrote these games in a custom Lisp-like language (GOAL), a structural gift no other PS2 game shares. PSX has scattered game-specific decompilation projects, no general tool. Amiga has no comparable project at all, for any single title — the closest work in the same technique category is entirely off-platform, on Genesis and one Mac game. On-platform, the field is occupied by two mature but categorically different techniques (WHDLoad’s patching, UAE/Amiberry’s dynamic JIT), neither of which is recompilation, and both already deliver near-native performance and compatibility — leaving little pressure to attempt the harder chipset-aware static route that Genesis’s simpler, less coprocessor-dependent hardware made worthwhile to a handful of developers.