Deep Dive: Simulating DATAPAC, Canada's Forgotten Internet
Rebuilding the DATAPAC PAD experience in code: the command loop, X.25 NUAs, and five period-authentic hosts behind a 300-baud prompt.
Writeups, deep dives, and devlogs — antennas and packet radio at one end, emulators and language design at the other.
Rebuilding the DATAPAC PAD experience in code: the command loop, X.25 NUAs, and five period-authentic hosts behind a 300-baud prompt.
Shrinking the emulator's main bundle from 1.1MB to 104KB by lazy-loading backends, and hiding the fetch inside the dial tone.
JetStream redelivered the message and the work was still lost. Moving job ownership out of the queue and into the database.
Five classic CPU cores in Rust, compiled to WebAssembly: 8008, 8080, 8088, Z80, and 6502, and the edge cases that keep emulation honest.
A BBS emulator that outgrew localStorage: gRPC services, NATS messaging, a gateway, and the question of whether any of it was necessary.
Migrating backends to server APIs with NATS pub/sub, adding microservices, and building the peripheral slot system alongside the Canada Goose game.
A quick script turned into two days of yak-shaving through collection speed, chart performance, and an audio bug that took hours to find and one line to fix.
Identity got real: guest sessions, passkeys, and a server‑backed auth surface, plus gopher content routing, Z‑Machine version wiring, and a formatting sweep.
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.
Shipping the TI CC-40 backend with authentic CALL commands and audio, plus a full IVR phone tree system.
Building a Kansas City Standard cassette peripheral: FSK at 2400/1200 Hz, tape transport simulation, and why saving 8 KB takes five minutes.
Floppy, hard drive, and cassette peripherals with Kansas City Standard encoding, plus a peripheral audio bus that makes the machine feel physical.
Kubernetes/K3s deployment configs, CI/CD scaffolding, schema-driven API generation, and the Star Trek BASIC backend.
Building BASIC, Forth, and Scheme interpreters in Rust, running them in browser workers, and what the contrast between them revealed.
Moving the web app under web/, migrating three parsers to Pest and Pratt, and getting the Z-Machine opcode engine executing.
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 like dial-up.
Building a Z-Machine transpiler in Rust: opcode decoding, Z-strings, branch offsets, and the constraints that make Infocom's bytecode tick.
Z-Machine decoder work, text handling, and SAVE/RESTORE, plus content-addressable storage with S3 sync.