Anatomy of a Retro BIOS
Designing firmware for emulated retro computers—reset vectors, service calls, UART I/O, toolchains, and the boot theatre that makes it feel real.
In-depth technical explorations of specific topics, technologies, and implementations.
Designing firmware for emulated retro computers—reset vectors, service calls, UART I/O, toolchains, and the boot theatre that makes it feel real.
Centralising modem, line, backend, and peripheral audio in a single bus system, and why fewer hops beat fancy decoupling.
I mapped code history onto a small audio graph and treated volume as a data contract, not a vibe.
The iteration that turned a text adventure into something playable—balance tuning, achievement scaffolding, and the 1081-line manual that made it legible.
Building cross-assemblers for retro CPUs in Rust, migrating to Pest parsers, and discovering why load addresses matter more than you think.
How a deadpan text adventure about mild chaos became the BBS system's most extensively tested game—79 tests, procedural honk audio, and a migration ending instead of game over.
Chart.js redraws the full scene every frame—correct for dashboards, wrong for playback. The fix was to treat the chart as a video surface.
Rebuilding the DATAPAC PAD experience in code — the command loop, X.25 NUAs, and five period-authentic hosts behind a 300-baud prompt.
How I shrank the emulator's main bundle from 1MB to 104KB by lazy-loading backends during dial tones—and why users never notice the delay.
A database-first ownership model for long-running jobs, with heartbeats, stale detection, and deterministic recovery.
Building five classic CPU cores in Rust for WebAssembly: 8008, 8080, 8088, Z80, and 6502, with shared state formats, cycle timing, and the edge cases that keep emulation honest.
How a BBS emulator grew into a distributed system with gRPC services, NATS messaging, gateway routing, and real backends instead of localStorage.
Passkeys in a 300‑baud world: the smallest WebAuthn flow, the server state it requires, and how I kept it in tune with emulator.ca's identity model.
Building a 1976-era cassette peripheral—FSK encoding at 2400/1200 Hz, tape transport simulation, and why saving 8KB took six minutes.
Building BASIC, Forth, and Scheme interpreters in Rust, running them in browser workers, and what that architecture taught me about language shape.
Why you can't just shovel bytes through a virtual modem—RTS/CTS backpressure, buffer gates, and the timing budget that makes dial-up feel real.
Building a Z-Machine transpiler in Rust—opcode decoding, Z-strings, branch offsets, and the constraints that make Infocom's bytecode tick.
Translating PETSCII screen memory into ANSI terminal output—character maps, colour translation, and the minimal contract a terminal-based VIC‑II can keep.
When 300 baud isn't enough—simulating faster modem handshakes with phase modulation, training sweeps, and the controlled chaos of negotiation audio.
Implementing the 1962 modem standard that made 300 baud dialup possible—FSK modulation, Goertzel demodulation, and the two-band trick that keeps full‑duplex honest.