.@ Tony Finch – blog

In my previous entry I wrote about constructing a four-point egg, using curcular arcs that join where their tangents are at 45°. I wondered if I could do something similar with ellipses.

As before, I made an interactive ellipse workbench to experiment with the problem. I got something working, but I have questions…

a screenshot of the ellipse workbench

read more ...

For reasons beyond the scope of this entry, I have been investigating elliptical and ovoid shapes. The Wikipedia article for Moss’s egg has a link to a tutorial on Euclidean Eggs by Freyja Hreinsdóttir which (amongst other things) describes how to construct the “four point egg”. I think it is a nicer shape than Moss’s egg.

read more ...

Another recent food obsession!

I think the instigation was a YouTube food video which led me to try making popcorn at home from scratch with Nico. It was enormous fun! And several weeks later it’s still really entertaining to make (especially when a stray kernel pops after I take the lid off the pan, catapaulting a few pieces in random directions!)

Swedish Chef popcorn bucket

Turn on the captions while watching the YouTube vid!

read more ...

The Novelkeys Kailh Big Switch is a working MX-style mechanical keyboard switch, but 4x larger in every dimension.

big switch little switch

I realised at the weekend that the Big Switch should fit nicely in a simple Lego enclosure. Because an MX-style switch is usually mounted in a 14x14 mm square plate cutout, at 4x larger the Big Switch would need a 56x56 mm mounting hole. Lego aficionados know that studs are arranged on an 8x8 mm grid; this means the Big Switch hole is exactly 7x7 studs. A plan was hatched and a prototype was made.

read more ...

In recent weeks I have been obsessed with carbonara: I have probably been eating it far too frequently. Here’s my recipe. It works well for 1 - 3 people but gets unweildy at larger quantities.


Rough quantities per person:


I’m a beginner at PCB design, or rather, I haven’t made a PCB since I was at school 30 years ago, and a lot has changed since then! So my aim for Keybird69’s PCB was to learn my way around the design, manufacturing, and assembly process.

a picture of the waveshare rp2040-tiny microcontroller and usb boards, a kailh hotswap socket, a key switch, a blue alt keycap, and a batman lego minifigure for scale (this is the article's hero image)

read more ...

My Keybird69 uses LEGO in its enclosure, in an unconventional way.

story time

Two years ago I planned to make a typical acrylic sandwich case for HHKBeeb, in the style of the BBC Micro’s black and yellowish beige case. But that never happened because it was too hard to choose a place to get the acrylic cut so my spec.

My idea for using LEGO in a keyboard case was originally inspired by James Munns, who uses LEGO for mounting PCBs, including at least one keyboard.

Howver, I could not work out how to make a case that is nice and slender and into which the parts would fit. It is possible – the KBDcraft Adam solves the problem nicely, and by all reports it’s pretty good as a keyboard, not just a gimmick.

To make the PCB design easier, I am using a Waveshare RP2040-Tiny. It’s more flexible than the usual dev boards used in custom keyboards because it has a separate daughterboard for the USB socket, but I had the devil of a time working out how to make it fit with LEGO.


read more ...

There’s plenty of material online about the bewildering variety of keycaps, eg, eg, but I learned a few things that surprised me when working on Keybird69.

read more ...

A proper Unix keyboard layout must have escape next to 1 and control next to A.

Compared to the usual ANSI layout, backquote is displaced from its common position next to 1. But a proper Unix keyboard should cover the entire ASCII repertoire, 94 printing characters on 47 keys, plus space, in the main block of keys.

To make a place for backquote, we can move delete down a row so it is above return, and put backslash and backquote where delete was.

(Aside: the delete key emits the delete character, ASCII 127, and the return key emits the carriage return character, ASCII 13. That is why I don’t call them backspace and enter.)

This produces a layout similar to the main key block of Sun Type 3, Happy Hacking, and True Fox keyboard layouts.

Personally, I prefer compact keyboards so I don’t have to reach too far for the mouse, but I can’t do without arrow keys. So a 65% keyboard size (5 rows, 16 keys wide) is ideal.

If you apply the Unix layout requirements to a typical ANSI 68-key 65% layout, you get a 69-key layout. I call it unix69. (1969 was also the year Unix started.)


a screenshot of the unix69 keyboard layout from the KLE link above

I have arranged the bottom row modifiers for Emacs: there are left and right meta keys and a right ctrl key for one-handed navigation. Meta is what the USB HID spec calls the “GUI” key; it sometimes has a diamond icon legend. Like the HHKB, and like Unix workstations made by Apple and Sun, the meta keys are either side of the space bar.

There are left and right fn keys for things that don’t have dedicated keys, e.g. fn+arrows for page up/page down, home, end. The rightmost column has user-programmable macro keys, which I use for window management.

unix69 vs ansi 65%


ANSI 65% keyboards have caps lock where control should be.

They have an ugly oversized backslash and lack a good place for backquote.

The right column is usually wasted on fixed-function keys.

It’s common for 65% keyboards to have 67 or 68 keys, the missing key making a gap between the modifiers and arrow keys on the bottom row. I prefer to have more rather than fewer modifier keys.

unix69 vs true fox


Matteo Spinelli’s Whitefox / Nightfox “True Fox” layout has top 2 rows similar to unix69. It sometimes has backslash and backquote swapped.

Unfortunately it has caps lock where control should be. Its right column is wasted on fixed-function keys (though the keyboards are reprogrammable so it’s mainly a keycap problem).

On the bottom row, True Fox has two modifers and a gap between space and arrows, whereas unix69 has three modifiers and no gap.

unix69 vs hhkb


The Happy hacking keyboard layout is OK for a 60% Unix layout. However it lacks a left fn key, and lacks space for full-size arrow keys, so I prefer a 65% layout.

unix69 vs keybird69


Owing to the difficulty of getting keycaps with exactly the legends I would like, the meta keys on my keybird69 are labelled super and the delete key is labelled backspace. I used F1 to F4 keycaps for the macro keys, tho they are programmed to generate F13 to F16 which are set up as Hammerspoon hot keys.

But otherwise keybird69 is a proper unix69 keyboard.

Another keyboard!


A couple of years ago I made a BBC Micro tribute keyboard in the runup to the beeb’s 40th anniversary. I called it HHKBeeb:

a dusty compact keyboard with red number keys and brown modifier keys; the ALT keys feature the BBC computer literacy project owl logo; to the right of the keyboard is a Kensington Expert Mouse trackball

The HHKBeeb is made from:

I planned to make a beeb-style acrylic sandwich case, but it was too hard to choose a place to get the acrylic cut, so that never happened.

In practice I find 60% keyboards (like the Happy Hacking Keyboard) too small – I need an arrow cluster. So I used the HHKBeeb with a Keybow 2040 macro pad to give me arrows and a few function keys for moving windows around.


My new keyboard is for a Finch and it has 69 keys, so it’s called Keybird69. (I was surprised that this feeble pun has not already been used by any of the keyboards known to QMK or VIA!)

a compact keyboard; most of the keycaps are warm grey with white legends, but the modifiers and special keys are black and white, escept for escape and arrows which are red and white; to the right is a Kensington Slimblade trackball, and below both of them is a dark wooden wrist rest

It is made from:


A combination of reasons:

story time

I have been mildly obsessed with compact keyboards practically forever, but back in the 1990s there were no good options available to buy, so I made do without.

The first small keyboard I liked was the (now discontinued) HHKB Lite 2, which has an arrow cluster unlike the pure HHKB. I have a couple of these lurking in the Boxes Of Stuff in the corner. But I’m not a huge fan of the limited modifiers, or the Topre HHKB Lite 2 key switches (they’re a bit mushy), or the styling of the HHKB case.

Correction: the HHKB Lite 2 did not actually use Topre switches.

I gradually used Macs more, and switched to using the Apple Aluminium keyboard - the model A1242 compact wired version, and the model A1314 wireless version. I also switched from a Kensington Expert Mouse trackball to an Apple Magic Trackpad.

But then Apple lost the plot with its input devices, so I thought I should plan to wean myself off. And in the mean time, the custom keyboard scene had flourished into a vibrant ecosystem of open source hardware and software.

So instead of relying on someone else to make a keyboard I like, I could make one myself! My own PCB and switch plate, designed for just the layout I want.

And with QMK open source firmware, I can make good use of the fn key that was so disappointingly unconfigurable on the HHKB and Apple keyboards.

what’s next

I’m planning to write some more notes about various details of the design:

I got some interesting comments about my previous notes on random floating point numbers on Lobsters, Dreamwidth, and from Pete Cawley on Twitter.

Here’s an addendum about an alternative model of uniformity.

There are 2^62 double precision floats between 0.0 and 1.0, but as I described before under “the problem”, they are not distributed uniformly: the smaller ones are much denser. Because of this, there are two ways to model a uniform distribution using floating point numbers.

Both algorithms in my previous note use a discrete model: the functions return one of 2^52 or 2^53 evenly spaced numbers.

You can also use a continuous model, where you imagine a uniformly random real number with unbounded precision, and return the closest floating point result. This can have better behaviour if you go on to transform the result to model different distrbutions (normal, poisson, exponential, etc.)

Taylor Campbell explains how to generate uniform random double-precision floating point numbers with source code. Allen Downey has an older description of generating pseudo-random floating-point values.

In practice, the probability of entering the arbitrary-precision loop in Campbell’s code is vanishingly tiny, so with some small adjustments it can be omitted entirely. Marc Reynolds explains how to generate higher density uniform floats this way, and Pete Cawley has terse implementations that use one or two random integers per double. (Reynolds also has a note about adjusting the range and fenceposts of discrete random floating point numbers.)

Here are a couple of algorithms for generating uniformly distributed floating point numbers 0.0 <= n < 1.0 using an unbiased random bit generator and IEEE 754 double precision arithmetic. Both of them depend on details of how floating point numbers work, so before getting into the algorithms I’ll review IEEE 754.

The first algorithm uses bit hacking and type punning. The second uses a hexadecimal floating point literal. They are both fun and elegant in their own ways, but these days the second one is better.

read more ...

Last week I was interested to read about the proposed math/rand/v2 for Golang’s standard library. It mentioned a new-ish flavour of PCG random number generator which I had not previously encountered, called PCG64 DXSM. This blog post collects what I have learned about it. (I have not found a good summary elsewhere.)

At the end there is source code for PCG64 DXSM that you can freely copy and use.

read more ...

I am pleased that so many people enjoyed my talk about time at RIPE86. I thought I would write a few notes on some of the things I left out.

read more ...

This week I was in Rotterdam for a RIPE meeting. On Friday morning I gave a lightning talk called where does my computer get the time from? The RIPE meeting website has a copy of my slides and a video of the talk; this is a blogified low-res version of the slides with a rough and inexact transcript.

I wrote a follow-up note, “Where does ‘where does my computer get the time from?’ come from?” about some things I left out of the talk.

read more ...

This weekend I was in Rotterdam for the RIPE DNS Hackathon.

About 50 people gathered with several ideas for potential projects: things like easier DNSSEC provisioning, monitoring DNS activity in the network, what is the environmental cost of the DNS, …

At the start of the weekend we were asked to introduce ourselves and say what our goals were. My goal was to do something different from my day job working on BIND. I was successful, tho I did help some others out with advice on a few of BIND’s obscurities.

The team I joined was very successful at producing a working prototype and a cool demo.

read more ...

In 2021, I came up with a design for a new memory layout for a qp-trie, and I implemented a prototype of the design in NLnet Labs NSD (see my git repo or github).

Since I started work at ISC my main project has been to adapt the NSD prototype into a qp-trie for use in BIND. The ultimate aim is to replace BIND’s red-black tree database, its in-memory store of DNS records.

Yesterday I merged the core qp-trie implementation into BIND so it’s a good time to write some blog notes about it.

The core of the design is still close to what I sketched in 2021 and implemented in NSD, so these notes are mostly about what’s different, and the mistakes I made along the way…

read more ...

Chris Wellons posted a good review of why large chunks of the C library are terrible, especially if you are coding on Windows - good fun if you like staring into the abyss. He followed up with let’s write a setjmp which is fun in a more positive way. I was also pleased to learn about __builtin_longjmp! There’s a small aside in this article about the signal mask, which skates past another horrible abyss - which might even make it sensible to DIY longjmp.

Some of the nastiness can be seen in the POSIX rationale for sigsetjmp which says that on BSD-like systems, setjmp and _setjmp correspond to sigsetjmp and setjmp on System V Unixes. The effect is that setjmp might or might not involve a system call to adjust the signal mask. The syscall overhead might be OK for exceptional error recovery, such as Chris’s arena out of memory example, but it’s likely to be more troublesome if you are implementing coroutines.

But why would they need to mess with the signal mask? Well, if you are using BSD-style signals or you are using sigaction correctly, a signal handler will run with its signal masked. If you decide to longjmp out of the handler, you also need to take care to unmask the signal. On BSD-like systems, longjmp does that for you.

The problem is that longjmp out of a signal handler is basically impossible to do correctly. (There’s a whole flamewar in the wg14 committee documents on this subject.) So this is another example of libc being optimized for the unusual, broken case at the cost of the typical case.

The other day, Paul McKenney posted an article on LiveJournal about different flavours of RCU, prompted by a question about couple of Rust RCU crates. (There are a few comments about it on LWN.)

McKenney goes on to propose an RCU classification system based on the API an implementation provides to its users. (I am curious that the criteria do not involve how RCU works.)

Here’s how I would answer the questions for QSBR in BIND:

Previously, I wrote about implementing safe memory reclamation for my qp-trie code in BIND. I have now got it working with a refactored qp-trie that has been changed to support asynchronous memory reclamation - working to the point where I can run some benchmarks to compare the performance of the old and new versions.

read more ...