Christopher Griffiths

Independent builder focused on practical software systems, particularly in health data, simulation tooling and self-hosted infrastructure.

Areas of interest

Sim racing tooling and telemetry workflows Local-first health data and glucose modelling Self-hosted systems and infrastructure Welsh language and technology

How I test things

islet has over 600 tests. casectl has 313. cable-club has 19 accuracy tests that compare framebuffer output pixel-by-pixel against a reference emulator. These are different projects in different languages solving different problems, and they all test heavily. This is not an accident. The principle If you cannot verify a claim automatically, you do not actually know if it is true. You think it works. You believe it works. You tested it manually once and it seemed fine. None of that counts. What counts is a command you can run that tells you, definitively, whether the system does what it is supposed to do. ...

April 5, 2026 · 5 min · Christopher Griffiths

Sound

For the first four days, cable-club was silent. The screen showed FireRed's intro — the title screen, the Oak speech, the options menu — but there was no sound. Audio registers existed as stubs that accepted writes and returned zeros. The game thought it was playing music. Nothing came out. The GBA’s audio hardware The Game Boy Advance has two audio systems running simultaneously. The PSG (Programmable Sound Generator) is inherited from the original Game Boy. Four channels: two square waves with configurable duty cycle and frequency sweep, one custom waveform channel that plays samples from a 32-byte wave RAM, and one noise channel driven by a linear feedback shift register. Each channel has its own length counter and volume envelope. This is the chip-tune hardware — the beeps, the bloops, the sound effects. ...

April 5, 2026 · 5 min · Christopher Griffiths

Extracting the judge

When I rewrote cable-club, the first thing I built was not the CPU or the renderer. It was the test harness. An emulator without accuracy tests is a program that produces plausible-looking output with no way to know if it is correct. I had already learned that lesson once. What accuracy testing means A GBA emulator can pass every standard CPU test suite — every ARM instruction, every Thumb instruction, every edge case in isolation — and still produce the wrong output when running a real game. The test suites verify that individual instructions behave correctly. They do not verify that the CPU, memory bus, DMA controller, interrupt system, and PPU all interact correctly over thousands of frames. ...

April 4, 2026 · 4 min · Christopher Griffiths

Frame 476

FireRed crashed eight seconds after boot. Every time. Frame 476. Not a hang, not a glitch — the CPU branched to garbage in palette RAM and stopped executing real instructions. The crash was 100% deterministic. Same frame, same instruction, same corrupted address. That kind of determinism means there is a root cause, and it is findable. The symptom Pokemon FireRed uses a sound engine called m4a (MusicPlayer2000). It runs in IWRAM — the GBA’s fast 32KB internal RAM — and mixes audio samples into a buffer every VBlank. A register called R5 tracks the write position in the buffer. Normally, R5 stays within the buffer boundaries: a 1,584-byte region starting at 0x030061B0. ...

April 4, 2026 · 5 min · Christopher Griffiths

I threw away a working emulator

On March 29, I started writing a Game Boy Advance emulator from scratch in Rust. By March 30 — seventeen commits and roughly thirty-six hours later — Pokemon FireRed was playing its intro cinematic. The CPU passed 100% of the standard ARM and Thumb test suites. The relay server was working. I had a functioning emulator. Then I threw it away. Why a GBA emulator My nephew Declan has never seen a Game Boy. I wanted to trade Pokemon with him over the internet, the way I did with a link cable twenty years ago. That is the entire motivation. ...

March 31, 2026 · 5 min · Christopher Griffiths

Controlling the case

In late March, I bought a Freenove case kit for griffpi — the Raspberry Pi that runs everything. Three PWM fans, four addressable LEDs, a small OLED screen, and an STM32 expansion board that ties it all together over I2C. The case came with a Python script. The script was not good enough. The problem The stock software was a single monolithic script that assumed it was the only thing running on the Pi. It pinned a CPU core polling temperature in a tight loop. It had no configuration file. It could not be controlled remotely. If you wanted to change the fan speed, you edited the script, killed the process, and restarted it. ...

March 25, 2026 · 4 min · Christopher Griffiths

Pwyslais

I am never going to open a journal app and write "today this happened." I know this about myself with absolute certainty. Every journaling app I have tried — Day One, Notion, Apple Journal, plain text files — assumes the user will voluntarily sit down and compose an entry. That assumption is the entire reason they fail for me. pwyslais starts from the opposite premise: I will not write unless something asks me to. ...

March 21, 2026 · 7 min · Christopher Griffiths

Software for one

islet has one user. pwyslais has one user. llywio has one user. ira has one user. I am that user. This is not a limitation — it is the design constraint that makes everything else possible. The advantage When you build for one person, every decision collapses into a question you can answer immediately: does this work for me? Not “does this work for most users” or “will this confuse new signups” or “should we A/B test this.” Does it work for me, right now, on my hardware, with my constraints. ...

March 21, 2026 · 4 min · Christopher Griffiths

Back on Track

I raced 195 times in January. Then islet happened. February dropped to 23 races. March, so far, 16. My iRating has cratered. My incident count is embarrassing. Mae'n dda bod nôl — but being back doesn't mean being good. The numbers don’t lie My recent results read like a comedy of errors. Last ten finishes: P11, P4, P25, P28, P46, P2, P21, P15, P6, P24. Average finish: P18. Average incidents per race in March: 6.7. That P46 was a 13th Week Track Day in a Mercedes-AMG GT4 at VIR where I completed precisely zero competitive laps. The P2 at Okayama? Probably the only clean race in the batch. ...

March 16, 2026 · 3 min · Christopher Griffiths

Six Plans, One Session

On Friday morning, islet had 766 tests and no concept of food components, rate limiting, or offline caching. By Sunday evening it had 1,750 tests, schema v8, a tiered rate limiter, photo-based meal estimation, a component meal architecture, a sync infrastructure, an iOS SwiftData cache, an alert detection engine, and a time-in-range dashboard showing 51.8% TIR across 14,000 CGM entries. One session. Safety note: islet is a personal project and is not medical advice. It does not make dosing decisions. ...

March 16, 2026 · 4 min · Christopher Griffiths