Big Repo Restructure and Backend Migration
Splitting the repository into clear domains—cores, languages, assemblers, BIOS—and making future work less of a guessing game.
Big repo restructure and backend migration
I woke up knowing I was going to spend the day moving files. Hundreds of them. The kind of work that looks invisible when you’re done—the repo is tidier, but to anyone who wasn’t there, it just looks like it was always this way.
The emulator had grown past its original shape. What started as a handful of files had become a sprawl: CPU cores mixed with language interpreters mixed with BIOS code mixed with frontend utilities. Finding anything meant holding the whole directory structure in your head. Adding anything meant guessing where it should go.
So I ripped it apart and put it back together with clear boundaries:
cores/ # Rust CPU emulators (Z80, 6502, 8088, 8080, 8008)
languages/ # Rust interpreters (BASIC, Scheme, Forth, Prolog, ZIL, etc.)
assemblers/ # Rust assemblers (6502, Z80, x86)
bios/ # C/Rust BIOS implementations
web/ # Frontend + serial + backends + UI
That’s the new backbone. Each domain is self-contained. The Z80 core doesn’t know anything about BASIC. The assembler tests don’t need to boot the web app. You can hand someone cores/z80/ and say “here, this is everything” instead of “clone the whole repo and good luck.”
Why this matters beyond neat folders
The real win is isolation. Before, testing the CPU core meant loading half the system because of tangled imports. Now I can run cargo test in cores/z80/ and get results in seconds. The feedback loop tightened from “wait for the world to compile” to “instant answers.”
It also means parallel work becomes possible. If I want to add an 8086 core while someone else works on the Scheme interpreter, we’re not stepping on each other. The boundaries are real, not just conceptual.
(The migration itself was exactly as tedious as you’d expect. Move a file, fix twenty imports. Move another file, discover that something depended on an implicit re-export that no longer exists. Fix that, find three more. I probably should have scripted it, but I didn’t, and now I know every import path in the project by heart.)
The backend world shifted too
Services that used to sit in a loose cluster got moved into a more consistent structure. The emulator stopped feeling like one big app with modes and started feeling like a proper system: CPU cores in Rust, language interpreters in Rust/WASM, and a frontend that loads them as needed.
The manuals and documentation got updated along the way. That part is never as fun, but it matters. I want someone new to land on the repo and make sense of it without a private tour. The README should be enough.
The changes
- Restructured the repo into clear domains (cores, languages, assemblers, bios)
- Migrated backend directories and updated import paths across the codebase
- Added/expanded language backends and upgraded BIOS/emulator support
- Converted manuals and documentation formats for consistency
What I was going for
Clarity. It turns out you can move fast only if the project’s shape makes sense to you.
What went sideways
Production build failures and test breakages cropped up immediately after the move, plus the usual long tail of path fixes. I probably should have done this in smaller chunks, but sometimes you just have to rip the bandage off. The final hour was a scramble of “wait, that test was passing before” fixes.
What’s next
The structure feels right. Next was making the build system and tooling catch up with the new reality.
Previous: 2026-01-22