Drop-in classic Macintosh for your static recompilation project.
68k CODE resources Your recompiled C
from a 1980s Mac app (one function per 68k sub)
│ │
│ extract · disassemble · lift │ calls Toolbox traps
▼ ▼
┌──────────────────────────────────────────────────────┐
│ macrecomp │
│ m68k CPU state · A5 world · resource mgr · QuickDraw │
│ Event/Menu/Window/Dialog Mgr · Sound Mgr │
└──────────────────────────────────────────────────────┘
│
▼
SDL2 window + audio
The System 6/7 Toolbox, chopped into a linkable C library — so you never reverse-engineer QuickDraw twice.
Static recompilation takes an old program's machine code and turns it into native C that runs today. For a console game the hard part is the hardware (that's what snesrecomp provides). For a classic Macintosh application the hard part is the Toolbox — the ~1000 ROM/System traps every Mac app calls for graphics, windows, menus, events and sound.
Every 68k Mac app draws through QuickDraw, pumps GetNextEvent, and plays
sound through the Sound Manager. So why reimplement that for every recomp?
macrecomp packages the pieces a lifted 68k Mac app needs — a small m68k CPU state model, the A5 world + segment/jump-table loader, a resource-fork manager, and a growing HAL that maps Toolbox traps onto SDL2 — as a linkable library plus the tooling to get you there. This is the same "chop the platform into libraries, let each game link against them" approach as N64Recomp and snesrecomp, aimed at the Mac.
It is the sibling of the x86/DOS pcrecomp toolkit, for 68k + Toolbox instead of 8086 + DOS INTs.
App (HFS resource fork: CODE 0..N + PICT/snd/ASND/MENU…)
│ ① extract tools/extract_resources.py (dc42/HFS → CODE + assets + inventory.json)
▼
CODE segments + asset catalog
│ ② disassemble tools/disasm_code.py (capstone M68K)
│ ③ classify tools/scan_traps.py (enumerate A-line Toolbox traps ← the scope gate)
▼
function table + trap set
│ ④ lift tools/lift68k.py (68k → C against the macrecomp runtime)
▼
C source ──⑤ HAL──▶ QuickDraw→SDL2, traps→runtime ──⑥ build──▶ native app
Steps ①–③ are cheap and tell you the real cost of a title before you commit to it: the trap set from ③ is exactly the Toolbox surface you must implement.
🚧 v0 — tooling first. The dig tools are real; the runtime HAL grows per game.
| Component | What it does | State |
|---|---|---|
extract_resources.py |
DiskCopy 4.2 / raw HFS → CODE segments, asset catalog, inventory.json |
✅ working |
disasm_code.py |
capstone-M68K disassembly, annotated with traps + A5 jump-table calls | ✅ working |
scan_traps.py |
enumerate A-line ($Axxx) Toolbox traps; parse the CODE 0 jump table |
✅ working (validated on Finder) |
traps.json |
1177 trap word↔name mappings (Inside Macintosh) for the two tools above | ✅ |
pict2png.py |
decode 1-bit QuickDraw PICT (v1) resources → PNG (BitsRect/PackBitsRect) | ✅ |
unprotect.py |
statically unpack self-decrypting/protected CODE | ✅ fully solved (jump table + segment bodies, byte-exact) |
ghidra/EmuDecrypt.java |
run an isolated decrypt routine in Ghidra's p-code emulator (the oracle for cracking an unknown cipher) | ✅ |
lift68k.py |
mechanical 68k → C lifter (per-function; branches→goto; traps→HAL) | ✅ 98–100% instruction coverage |
runtime m68k.{h,c}: CPU state + big-endian memory + faithful CCR flags + function table/dispatch |
the execution substrate | ✅ |
runtime quickdraw.c + platform_sdl.c: 1-bit framebuffer + pen/rect/line/oval/text/CopyBits → SDL2 window |
the video HAL | ✅ core (self-tested) |
runtime toolbox.c: A-trap dispatch, Resource Mgr (serves the app's resources), QuickDraw incl. CopyBits + DrawPicture, Window/Menu/Dialog/File stubs, Memory Mgr heap |
the OS HAL | 🟢 ~95 traps; boots real games |
| Sound (ASND) · full Menu/Dialog interaction | ⬜ |
First customer: shufflepuck-cafe (Broderbund, 1988) — 6 CODE segments, ~52 KB of 68k, B&W QuickDraw.
Add it as a submodule (this is how the game repos consume it):
git submodule add https://github.com/sp00nznet/macrecomp.git ext/macrecomp# In your game's CMakeLists.txt:
add_subdirectory(ext/macrecomp)
target_link_libraries(my_recomp PRIVATE macrecomp SDL2::SDL2main)Extract a title's resources to start digging:
python ext/macrecomp/tools/extract_resources.py "MyGame.dc42" -o work/
# → work/code/CODE_0.bin … CODE_N.bin, work/inventory.json, work/assets/…macrecomp/
tools/ extract / disasm / scan-traps / lift (the dig kit, Python)
runtime/ the linkable C library — m68k state, A5 world, Toolbox HAL → SDL2
include/ public headers (macrecomp/*.h)
docs/ ARCHITECTURE.md and trap-mapping notes
examples/ minimal harnesses
- macresources + machfs by Elliot Nunn — pure-Python HFS + resource-fork parsing. The extractor stands on these.
- capstone — M68K disassembly.
- Inside Macintosh (Apple, 1985–) and the open-source Executor clean-room Toolbox — reference semantics for the trap HAL. No Apple ROM or code is used or redistributed here.
- Approach borrowed from N64Recomp and snesrecomp.
MIT — see LICENSE. The toolkit is original work. It ships no Apple ROM, System software, or copyrighted game data — you bring your own copy of whatever you're recompiling.