Hi there! I’m nyanpasu64 and I like headpats.

This is my blog about low-level and human-scale programming, hardware tinkering, DSP, and computer music and chiptune, where I share things that others might enjoy or learn from.

Making iron gall ink from oak galls

Back in May, I was taking a walk around the neighborhood when I came across an oak tree with dozens of galls hanging from the stem. At first I thought these were seed pods and didn't even recognize the tree as an oak, but PlantNet (and later Seek) informed me it was a valley oak. At this point I realized the pulpy brown masses hanging from the stems were oak galls, and I had the idea to make my own iron gall ink like people did in centuries past.

Update: CRT modelines and EDID editing

I've released a major update to my article, "A deep dive into CRT modelines and EDID editing". I've expanded on getting a VGA output using HDMI-to-VGA adapters (DACs), reading, writing, and editing EDID data on Windows, Linux, and Mac, and tuning modelines in CRU to improve geometry and sharpness. If you're interested in using CRT monitors on computers, be sure to check it out!

Diagnosing video signal loss on Wii and GBS-Control

Last year I bought a GBS-Control to upscale and transcode game consoles for a VGA CRT monitor, and have been using and developing for it since. A few months ago, while playing my Wii in 480p with the GBS-C in passthrough mode (zero-latency non-scaling transcoder), I started getting random black screens every few hours. While I initially suspected a simple software problem, locating the cause of this bug spiraled into a multi-month adventure involving overheating chips, transmission-line time-delay measurements, and chasing RF interference.

A deep dive into CRT modelines and EDID editing

In the process of setting up CRT TVs and monitors, I've often worked with modelines, the cryptic strings of numbers which define how a GPU should drive a display cable with rows of pixels. Once critical to 90's Linux users trying to setup XFree86 to display on their CRT monitors, modelines have found a new life among hobbyists who tinker with resolutions and framerates to bring out the full potential from their CRT and gaming LCD monitors.

Exploring the appearance of CRT televisions and monitors

There's a recurring school of thought that the best way to experience the visuals of pre-HD console and PC games is to play them on period-accurate CRT displays. CRT images have a characteristic rich colorful look, with soft warm scanlines and crisp phosphors, as well as zero (added) latency and unmatched motion characteristics, all which make CRTs so beloved by retro gamers. Here we will explore how TV/monitor construction and operation create the various features making up the CRT look.

A filesystem only a penguin could love

About a year ago, when loading games onto my Wii's USB hard drive (shhhh), I found the hard drive would not mount on the Wii but only on Linux. Although I initially suspected a disk incompatibility, digging revealed a bizarre rabbit hole, where broken Linux FAT32 resizing tools produced corrupt partition headers only recognized by Linux, which fsck couldn't fix, and PhotoRec outright hung on when reading.

Adjusting the backlight PWM frequency on an Ivy Bridge laptop

After chip-level-flashing a Ivy Bridge Dell laptop (Inspiron 15R SE 7520) with a corrupted BIOS chip (the BIOS spontaneously corrupted in 2014 then I fried the EC trying to reflash the BIOS, but that's a story for another time), I was disappointed to find that the backlight was dimmed using PWM at 200 Hz (a period of 5ms).

Playing Stray (2022) on a CRT TV in 480i

One of my recent projects was to get my PC to output 480i signals to my recently acquired Trinitron TV for running modern and historical games on a CRT TV. (I'd definitely be better served by a CRT monitor, but I didn't have one and still don't 😿.)

Porting my blog to Zola

🔗 Moving away from GitHub Pages and Jekyll I've hosted my blog for a few years on GitHub Pages and Jekyll, sporadically updating it with new content. Recently I've grown frustrated with the difficulty of writing posts, and synchronizing drafts between devices without pushing to m…

Implementing low-latency shared/exclusive mode audio output/duplex

Audio output and duplex is actually quite tricky, and even libraries like RtAudio's ALSA backend get it wrong. If you're writing an app that needs low-latency audio without glitches, the proper implementation architecture differs between apps talking to pull-mode (well-designed, low-latency) mixing daemons, and apps talking to hardware.

The missing guide for Arch Linux PKGBUILD's pkgver() version numbers

Pacman's version comparison algorithm was designed over a decade ago to properly sort many categories of real-world version numbers, and is now set in stone, quirks and all. Later on, the AUR developed pkgver() conventions and templates which turn Git commits into version numbers…

ExoTracker Newsletter #2 - Pivoting to SNES, designing an instrument list

For those of you who aren't already aware, ExoTracker is a tracker-like composing tool, based around subdividing beats instead of integer rows. This allows the user to place notes at arbitrary fractions of a beat (like sheet music), and additionally allows tracker-like delay effe…

An unsafe tour of Rust's Send and Sync

Rust's concurrency safety is based around the Send and Sync traits. For people writing safe code, you don't really need to understand these traits on a deep level, only enough to satisfy the compiler when it spits errors at you (or switch from std threads to Crossbeam scoped threads to make errors go away).

ExoTracker Issues - Abandoning the grid

Trackers have decades of design, with interlocking features and design decisions, many based on the assumption that every event is quantized on a grid: You don't need lines above events, since it's obvious which row the event is in. In regular trackers, events are treated as ta…

ExoTracker Newsletter #1

I just finished implementing timeline entry editing. Since I have school coming up, I decided to release a demo of its current state. Since my summary was getting a bit too long to post in Discord, I decided to write a blog post / newsletter. 🔗 Demo download Windows 64-bit: https…

Describing convolution using item-based indexing and inclusive ranges

This is a follow-up to my previous post, "The gridline mental model of indexing and slicing". I split this out because it's related to DSP as well as programming, and may not be as interesting to the broader programming audience. In some cases, it's useful to think of …

The gridline mental model of indexing and slicing

Republished from my Github gist. Integer indexes can either represent fenceposts (gridlines) or item pointers, and there's a sort of duality. 🔗 Mental model: Gridline-based "asymmetric indexing" Memory or data is treated as a "pool of memory". Pointers and ind…