GitHub - DominoTree/modern-m68k-toolchains · GitHub
/" data-turbo-transient="true" />
Skip to content
Search or jump to...
Search code, repositories, users, issues, pull requests...
-->
Search
Clear
Search syntax tips
Provide feedback
--><br>We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
Cancel
Submit feedback
Saved searches
Use saved searches to filter your results more quickly
-->
Name
Query
To see all available qualifiers, see our documentation.
Cancel
Create saved search
Sign in
/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up
Appearance settings
Resetting focus
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
DominoTree
modern-m68k-toolchains
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star<br>15
main
BranchesTags
Go to file
CodeOpen more actions menu
Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit
History<br>1 Commit<br>1 Commit
atari-tos
atari-tos
mac-68k
mac-68k
.gitignore
.gitignore
LICENSE
LICENSE
README.md
README.md
View all files
Repository files navigation
modern-m68k-toolchains
Intro
This is a silly PoC that I'd been wanting to try since I learned that the LLVM<br>backend had M68k support.
Outside of the Atari / Rust and Atari / Zig toolchains, this was all largely<br>vibe-coded due to me not having much experience with Swift or Mac. These toolchains<br>largely rely on inline assembly to make things work, and exclude things like<br>applicable runtimes or stdlib. This inline ASM could certainly be extracted out into<br>platform-specific libraries, and in the case of Rust, I have a feeling things like<br>the Embassy async framework could also be ported/adopted.
Each port is a self-contained "hello world": it opens a native alert dialog<br>showing the language and LLVM versions it was built with, then exits cleanly.
Status: proof-of-concept, complete. Six working ports across two target<br>systems. Prebuilt binaries are committed so you can run them without reconstructing<br>the toolchains.
The ports
Safety checks (array-bounds, integer-overflow, …) are off in the Swift and Zig<br>builds — Swift via Unchecked, Zig via ReleaseSmall — on both targets, to match<br>the Rust/Zig release posture. They can be turned back on for minimal cost: for these<br>hello-world programs re-enabling Swift's checks (dropping Unchecked) is<br>byte-for-byte free (nothing on the live path is ever indexed or overflows), and<br>enabling Zig's runtime safety in place with @setRuntimeSafety(true) adds only<br>~30–40 B while keeping the size-optimized build. (Rust already keeps slice-bounds<br>checks on in release — only its integer-overflow checks are off.)
Atari TOS — GEMDOS .PRG
Language<br>Built with<br>Approach<br>.PRG size<br>Dir
Rust<br>Rust nightly / LLVM 22.1.4<br>#![no_std], custom m68k-tos.json target spec, build-std<br>506 B<br>atari-tos/rust
Swift<br>Swift 6.3.2 / LLVM 21.1.6<br>Embedded Swift (-enable-experimental-feature Embedded), no stdlib runtime; m68k trap glue in gemdos.c; size config matched to Rust/Zig (-function-sections + --gc-sections, Unchecked)<br>581 B<br>atari-tos/swift
Zig<br>Zig (custom build) / LLVM 21.1.8<br>freestanding, no std, every syscall is inline m68k asm<br>439 B<br>atari-tos/zig
All three strip the PRG symbol table uniformly at the shared toslink -s step, so the<br>sizes above are like-for-like regardless of what each compiler strips upstream.
Each running under Hatari + EmuTOS:
Rust<br>Swift<br>Zig
All three share the same back-end pipeline:
-> m68k ELF object(s)<br>m68k-elf-ld --relocatable --script=prg.ld -> hello.elf<br>toslink (from toslibc) -> HELLO.PRG (GEMDOS 0x601a executable)"> -> m68k ELF object(s)<br>m68k-elf-ld --relocatable --script=prg.ld -> hello.elf<br>toslink (from toslibc) -> HELLO.PRG (GEMDOS 0x601a executable)
Classic Macintosh, System 1.0 — CODE-resource APPL
Language<br>Built with<br>Approach<br>.bin size<br>Dir
Rust<br>Rust nightly / LLVM 22.1.4<br>#![no_std], custom m68k-mac.json (pic), Toolbox trap glue inlined in Rust asm; comptime banner<br>1,152 B<br>mac-68k/rust
Swift<br>Swift 6.3.2 / LLVM 21.1.6<br>Embedded Swift , Mac Toolbox trap glue in mactraps.c; a NoteAlert dialog driven via ParamText<br>2,048 B<br>mac-68k/swift
Zig<br>Zig 0.16.0-dev / LLVM 21.1.8<br>freestanding, Toolbox trap glue inlined in Zig asm; comptime banner<br>1,152 B<br>mac-68k/zig
The .bin is a MacBinary II file (128-byte header + a resource fork padded to<br>128-byte boundaries), so the figures above quantize; the raw CODE blobs are<br>506 B (Rust), 490 B (Zig), and 1,372 B (Swift). Swift's is larger<br>mostly because its banner string is copied into a Pascal buffer at runtime and<br>its A5-world buffers are bigger — the Rust/Zig ports assemble the banner at<br>compile time. (The same Toolbox bootstrap — QuickDraw/Dialog init + menu bar —<br>is why every Mac...