Clock Gear Train Calculator
Mon 11 November 2024
I made a Clock Gear Train Calculator
this evening. Read more
Prompts as source code: a vision for the future of programming
Mon 4 November 2024
I'm going to present a vision for the future of programming in which programmers don't work with source code any
more. The idea is that prompts will be to source code as source code is to binaries. Read more
Bare minds
Sun 6 October 2024
Back in the Stone Age, humanity was just scraping by with not much more than our bare hands. Working
with AI has showed me that, all this time: we've just been scraping by with our bare minds.
If computers were meant to be bicycles for the mind, then AI is jetpacks for the mind. Read more
Encyclopedia Mechanica
Tue 10 September 2024
I've been working on a new online encyclopedia project, and it is almost ready to rival Wikipedia.
It's called Encyclopedia Mechanica. Pages are created on-demand by an LLM
in response to user queries, so in a way we actually have more pages than Wikipedia already, albeit with more errors. Read more
I made an LLM-powered Colonel Blotto game
Sun 21 July 2024
Today I made a Colonel Blotto game where you play against GPT-4o,
and after each round you can chat with GPT-4o to get commentary/analysis/coaching. Play with it at blotto.incoherency.co.uk until
I run out of OpenAI credit. Read more
Secrets of the ChatGPT Linux system
Sun 16 June 2024
Have you noticed that ChatGPT sometimes writes out Python code and somehow executes it? How does that work? What
kind of environment is it using? Can we co-opt it for our own ends? Let's find out! Read more
How to read from a TCP socket (but were too afraid to ask)
Sat 10 February 2024
You can get surprisingly far, before it bites you, with only a fuzzy and incorrect understanding of how you should read from a TCP socket.
I see this often in (failing) Protohackers solutions.
Once you are over the initial hurdle of reading enough documentation to actually get a TCP session connected,
there are 2 key things you need to understand: Read more
dnstweak: quick local DNS spoofing tool
Tue 11 July 2023
I spent most of today writing dnstweak, a program that temporarily inserts
itself as the local DNS resolver (by writing to /etc/resolv.conf) and spoofs responses to
selected DNS requests. Read more
Exploiting an insecure cipher in the wild
Thu 6 July 2023
I found that the topology_hiding
module for OpenSIPS encodes data using an insecure
cipher, such that it can be decoded without knowing the key, leaking both the
plaintext and the key. Read more
Revisiting oscillating engine loss calibration
Mon 1 May 2023
Since my Wig-Wag has run in a bit now, I have revisited
the loss calibration. Read more
Calibrating losses in the oscillating engine simulator
Thu 13 April 2023
The biggest unknown variable in the oscillating engine simulator
is the amount of friction loss that an engine is likely to experience. To calibrate the simulation I have measured the speed of my engine at various supply pressures
and then simulated the same conditions, adjusting the simulated loss until the speed matches. Read more
Oscillating Engine Simulator
Sun 19 March 2023
I've been working on an oscillating engine
simulator. It's a type of steam engine where instead of valve gear, the cylinder swings back and forth, exposing a hole
in the cylinder to an inlet port for the power stroke, and to an exhaust port for the exhaust stroke. Very simple.
(I've also been working on building one, in the form of a Wig-Wag,
but I haven't got very far with that). Read more
Solving Protohackers with Fly.io
Sat 24 September 2022
This post walks you through hosting a Go solution for the
Protohackers Smoke
Test problem using Fly.io for free hosting. Read more
Nightdrive
Fri 16 September 2022
I've made a JavaScript simulation of driving at night time on the motorway.
It's hard to classify what it is. It's not a video, because it's generated dynamically.
It's not a game, because you just watch. It's not a screensaver, because it's
not the 90s. Maybe it's a "demo"? Read more
Protohackers problem 1 retrospective
Sat 27 August 2022
I released Protohackers problem 1 on Thursday evening.
The problem asks you to implement a server that accepts JSON-encoded requests, tests numbers for primality,
and gives JSON-encoded responses. (This post contains spoilers for the problem; if you have not solved it
yet, and you would like to solve it, then to avoid disappointment you should not read this until after you've solved it!). Read more
Protohackers: a new server programming challenge
Tue 23 August 2022
For the last couple of weeks I've been working on Protohackers, which is
a programming challenge where you have to implement a server for a network protocol,
and your server is automatically checked to see if it works properly. It's a bit like Advent of Code, but for networking instead of algorithms. Read more
A SLANG interpreter for SCAMP
Wed 10 August 2022
I made the interpreter by ripping the parser out of the compiler, making it produce an AST instead of assembly code,
and writing a recursive evaluator for the AST. It was way less work than writing
the Lisp interpreter, and it runs programs about 100x faster
than the Lisp interpreter. Read more
A Lisp interpreter for SCAMP
Wed 3 August 2022
Lisp has been the most recent step in my search for the ultimate SCAMP programming environment.
Unfortunately what I have so far is so slow that it's probably another dead-end. It's about 300x
slower than compiled SLANG code. Read more
Cheating at chess with a computer for my shoes
Sat 30 July 2022
I have come up with a new way to win at chess:
I have connected up a Raspberry Pi Zero in my pocket to some buttons and vibration motors in my shoes,
so that I can surreptitiously communicate with a chess engine running on the Pi. The project is called "Sockfish" because
it's a way to operate Stockfish with your socks. Read more
Do I really want a lambda calculus cyberdeck?
Wed 13 July 2022
A cyberdeck is an inconvenient portable computing device, often with a retro sci-fi aesthetic.
Lambda calculus is an inconvenient mathematical model of computing. A lambda calculus cyberdeck, therefore,
is an inconvenient device for inconvenient computing. Read more
Eldood: what Doodle used to be
Fri 1 July 2022
I have made Eldood as a replacement for
Doodle, because Doodle is now shit. If you used to like Doodle but have grown
frustrated with it, try Eldood. Read more
The ultimate SCAMP development environment
Wed 15 June 2022
I've been thinking about what I want the SCAMP development workflow to look like for
this year's Advent of Code. At first I was planning to do it in FORTH, but I've tried to
get into FORTH several times and haven't got on with it. I like the simple REPL of FORTH but I very
much do not like the language. So the plan is to come up with a way to make a REPL for
SLANG. Read more
Meshmill: open source 3D CAM
Tue 3 May 2022
For the last couple of weeks I've been working on Meshmill.
It's a new 3D CAM program for Linux. Read more
An Arduino-based USB interface to the Psion Organiser II
Sat 5 February 2022
I built a hacky USB interface to the Psion Organiser II that
lets you send messages to it over USB serial via an Arduino Nano. It involves the organiser executing machine code stored in a string
in its BASIC-like language, and it totally abuses the CPU's bus design. But it's simple and it works. Read more
Waypointer Moto: motorcyle navigation for Bangle.js
Thu 27 January 2022
I have made a Bangle.js app for motorcycle navigation. It's called
"Waypointer Moto" which is a bit of a mouthful but it doesn't matter. Instead of telling
you exactly which roads to use to reach your destination, it just points an arrow directly at your destination and
tells you the straight-line distance. It tells you where you're trying to end up, but leaves the route-finding
and exploring of the environment up to the user.
The idea is that you end up riding new roads and discovering places you
would never normally come across. It's a middle ground between riding around at random, and following
a route dictated by a satnav. Read more
Advent of Code on my homemade CPU
Fri 31 December 2021
This year I've built a 16-bit CPU, along with custom operating system
and programming language. It runs at 1 MHz and has 64 KWords of memory. This December I used it to do Advent of Code. Read more
Choozi for Bangle.js
Tue 14 September 2021
Do you know Chwazi? It is an Android app that chooses a person at random.
Everyone puts in their finger and it selects one at random to highlight. It's
useful for example if you're playing a board game and need to select a person
at random. Read more
Approximating Lenna with a neural net
Wed 8 September 2021
Last night, inspired by a comment on HN about creating
images with randomised neural nets by mapping inputs (x,y) to outputs (r,g,b), I spent some time trying to
train a small neural net to approximate Lenna, the famous image
processing test input. The outputs are quite interesting to look at, but don't approximate Lenna very well. But I don't know
anything about machine learning, so I think you could do much better than I managed. Read more
Play with SCAMP from the comfort of your browser
Mon 9 August 2021
Today I ported the SCAMP emulator to the web, using emscripten
to compile C to WebAssembly, and Xterm.js to provide the terminal
emulator. Read more
Porting Hamurabi to SCAMP
Fri 6 August 2021
That's right! 1968's most exciting video game release is coming to 2021's most disappointing CPU architecture.
Hamurabi
is a single-player text-based game in which you play the leader of ancient Sumeria for
10 years. Each year, you decide how much land to buy or sell, how much food to feed to the population, and how much land to plant with seeds. Occasionally
a plague comes along and kills half the population, or rats eat some of the harvest. Land values, harvest yields, and immigration rates
fluctuate unpredictably. At the end of the 10 years (if you haven't been forcibly removed from office already) your performance is evaluated. Read more
SCAMP update
Thu 24 June 2021
I've made a bit more progress on my SCAMP CPU. I/O performance is
improved significantly since last time, the CompactFlash card now lives on a PCB instead of a breadboard, I'm
using a real (ish) serial console instead of an FTDI cable, and I have a more
permanent power supply instead of the bench power supply. Read more
SCAMP has booted up to the shell for the first time
Sun 25 April 2021
I reached another good milestone on SCAMP this week: the physical hardware booted all the way up to the shell.
Granted, it only happened once, and I couldn't type any input once it got there. But it suggests that there are
no fundamental problems with the hardware design that will prevent the computer from working, which I am very happy about. Read more
The kilo editor
Sat 3 April 2021
Thanks to the excellent Build Your Own Text Editor tutorial,
SCAMP/os now has an editor. It's pretty bare-bones, but perfect for what I need. Read more
SCAMP is alive
Sun 21 March 2021
I have reached a good milestone on the SCAMP hardware: it can now execute code! It runs all the way through the
test program
correctly. Read more
The SCAMP kernel
Sat 27 February 2021
You might think it's a bit early to be working on an operating system, given that I don't have
a CPU to run it on. Maybe you're right. But working on software is easy and working on hardware
is time-consuming, so here we are. Read more
A compiler for SCAMP, and machine code profiling
Fri 19 February 2021
I've been working on a compiler for the SCAMP CPU. It compiles a language I'm calling "SLANG" (which just stands
for "SCAMP Language" pending a better backronym) into SCAMP assembly language. Read more
How to use an AT28C16 EEPROM with an Arduino Uno without a port expander
Wed 17 February 2021
The AT28C16 EEPROM stores 2048 bytes, which means to access it all you need to control 11 address lines and 8 data lines. You also need to operate
"chip enable" (pull low to enable the AT28C16), "output enable" (pull low to enable output), and "write enable" (pull low to enable
writing). That means in total you need to control 22 pins, but the Arduino Uno only has 12 general-purpose digital IO pins. Problem. Fortunately,
there are some tricks that make it workable. Read more
My first attempt at milling a PCB
Fri 12 February 2021
I'm going to get most of the PCBs for SCAMP made by JLCPCB, but I'd like
to try to mill the backplane on the CNC machine because it is both large (expensive at
JLCPCB) and simple (single-sided, no vias, easy to make). Yesterday some small pieces of copper-clad
board arrived and today I had a first attempt to see what would go wrong. Read more
Designing the instruction set for my TTL CPU
Sun 31 January 2021
I (believe I) am making good progress on designing the TTL CPU. Most of the actual CPU design is
relatively stable now, and bug discoveries in the hardware design are infrequent, so now I get to move up
a level and work on the instruction set. After that, it's just the bootloader, operating system, and
application software. Oh, and the small matter of the physical hardware assembly... Read more
Adventures in CPU design
Fri 15 January 2021
On Graham's recommendation, I recently bought an iCE40 FPGA and
have been learning a bit about how to use it. The iCE40 is good to get because there is good open-source tooling that supports it.
I was originally going to get the iCEstick evaluation board,
but there are other alternatives available more cheaply and with more logic elements. I ended up getting an iceFun
and have found it to be quite easy to use. The example projects are helpful. Read more
I wrote a semi-literate brainfuck compiler for CP/M
Tue 29 December 2020
Literate Programming is
"a programming paradigm introduced by Donald Knuth in which a computer program is given an
explanation of its logic in a natural language". It's something I've wanted to have a go
at for a while but never got around to. Yesterday, for fun, I wrote a brainfuck compiler for the
RC2014 and it seemed like a good fit for Literate Programming
because it's short enough to get my feet wet
but has enough detail that there is some interesting stuff to explain. Read more
My Advent of Code Story
Sat 26 December 2020
4.40am. The alarm wakes me up, but I was pretty much awake already. I get out of bed, put on my dressing gown, make a cup of tea,
and sit down at the computer. I warm up my fingers with a few rounds of 10fastfingers.
I open up vim and type out my template: #!/usr/bin/perl, use strict; use warnings; while (<>) { chomp; }. I drink a sip of the tea and wait for
the clock to tick down. 4:59:40. Almost time. My heart races. 4:59:55. I hover the mouse cursor over the number 22. 4:59:58.
Why is time passing so slowly? The wait is agonising. 5:00:00. Finally. I click the left mouse button and off we go. Day 22 part 1: Crab Combat. The next 4 minutes and 58 seconds
pass in a furious blur of reading, thinking, and typing. I submit my answer. 158th place. Gah, close. On to part 2. More reading, thinking, coding, debugging, until
at 5:22:55 I submit my part 2 answer. 139th place. 0 points. Better luck next time. I browse Hacker News and /r/adventofcode
for half an hour while the adrenaline wears off, and then go back to bed. Read more
Seasonal.css: Give your website a seasonal colour scheme
Fri 6 November 2020
I've been working on a project that gives a CSS colour scheme that varies based on the day of the year, with a vague attempt
to match the colour to the season. In case you're wondering why my blog has a new purple colour scheme (at time of writing):
this is why. Have another look tomorrow if you want to see the same content in an imperceptibly-different purple. Read more
CNC toolpath generation from heightmaps
Sat 24 October 2020
I've been struggling with generating complex toolpaths in FreeCAD and thought that an easy approach would be to render a heightmap of the
part, and then generating a toolpath from that should be easy.
I understand that this is already a recognised technique, although I could not find an open source tool that
would do it for me. Most of the heightmap-related stuff I found on DuckDuckGo was to do with auto-levelling the bed.
And, anyway, it's a relatively simple idea and a fun challenge, so I did it myself. Read more
Progress on my Godot racing game for Oculus Quest
Wed 19 August 2020
I've made some decent progress on the Oculus Quest racing game. I think it is already the most realistic driving simulator for the Quest, but
that's not a very high bar as there are not any real competitors. Read more
I'm working on a VR car racing game for Oculus Quest
Sun 26 July 2020
I've been playing a bit of Mini Motor
Racing X on the Oculus Quest recently. It's good. The experience of driving a car in virtual reality is
amazing, but this particular game is too much "game" and not enough "simulator" for my taste. I've always preferred
Gran Turismo to Mario Kart, for example. Unfortunately, the Quest is quite an unusual platform, and none of the
popular racing games are available for it. I recently discovered that the open source game engine
Godot has Oculus Quest support, so I'd like to make a basic car racing
simulator for Oculus Quest. Read more
Making a game with 24a2
Sun 28 June 2020
24a2 is an "ultra-minimalist" game engine. It was posted
on Hacker News this morning and I found it so interesting that I decided to take a day off from
breaking keyboard switches and make a tiny game
instead. Read more
An easy way to package Perl programs
Sat 16 May 2020
The right way to package Perl programs is with RPM, or DEB, or on CPAN with
ExtUtils::MakeMaker or similar. But this is a hassle. Read more
Zero-downtime Docker container deployments with nginx
Thu 14 May 2020
Docker doesn't let you reassign port mappings while containers are running. That means if you want to deploy
a new version of your application, you need to stop the old one and then start the new one, and there is a
brief period of downtime in between. I wrote Ngindock to solve
this problem. Read more
My RC2014 Web Server
Tue 10 December 2019
I wrote a web server for my RC2014. It runs from CP/M, which has no built-in concept of networking,
so I had to implement every layer of the networking stack, which in this case is SLIP, IP, TCP, and HTTP.
It totals about 1200 lines of C, all of which was written on the RC2014 in the ZDE 1.6 text editor, and compiled with the Hi-Tech C compiler. Read more
Telescope tracking with software auto-guiding
Wed 23 January 2019
The Earth rotates around its axis at a
rate of ~360°/day, or ~15°/hr (it's actually slightly slower than this because "1 day" is the amount of time it takes
for the sun to come around again, but we are also moving around the sun, so we don't need to rotate a full 360° per day).
When zoomed in with a field-of-view only 0.25° wide, objects that are not very close
to the North star appear to move quite quickly across the frame. For this reason, my telescope control software
continually updates the coordinates that it wants to
point at,
in order to keep the scope pointed at the same part of the sky. Read more
Hiding messages in chess games
Tue 9 October 2018
I designed a steganography system that encodes data as a chess game.
A convenient way to communicate chess games is PGN,
but any means of communicating the moves of the game would work, as the information is encoded conceptually in the
moves themselves, rather than taking advantage of any redundancy in the PGN format. Read more
A Rock-Paper-Scissors AI that is too good
Fri 25 May 2018
Yesterday I had an idea for a simple Rock-Paper-Scissors AI based on Markov chains. The "state" would be what the opponent played
in the last N rounds, and would be used to predict the probability that the opponent would play Rock, Paper, or Scissors next. The
AI would choose what to play, to beat what the opponent is expected to play, weighted by the expected probability for each
possible action. Read more
How to run SSH and HTTP on the same port
Mon 26 February 2018
Last month I ran a small puzzle in which, after having picked up an SSH key in one of the rounds,
a subsequent round involved connecting to a (supposed) web server using an SSH client.
It's quite a neat trick so I thought it deserved sharing. Read more
Double-check Bitcoin addresses when pasting (Bitcoin TX Generator malware)
Sun 9 July 2017
Back in April I wrote about the Large Bitcoin Collider and how
it is probably malware. Well, now there's another (even more blatant) piece of malware being spread via reddit. Read more
Hardbin: The World's Most Secure Encrypted Pastebin
Fri 19 May 2017
Over the past week I've been working on hardbin.
Hardbin is an encrypted pastebin, with the decryption key passed in the URL fragment,
and the code and data served securely with IPFS. (IPFS is a distributed content-addressable
storage system that is web-compatible; it's basically bittorrent for the web). Read more
Steganographic Bitcoin seeds: Hiding cash in plain sight
Wed 22 February 2017
I made a tool, stegoseed, to generate sentences which steganographically encode Bitcoin
wallet seeds, and to decode such sentences to retrieve wallet seeds. It comes with an example BIP39 seed to play with. Read more
How to copy Wordpress theme customisations to a child theme
Mon 23 May 2016
I've been working with Wordpress a little lately. I learnt that you're supposed to create
a child theme in order to make modifications to it, but I'd already modified the theme
settings (colours, etc.) using the Wordpress 'Customise' tool and couldn't see how to copy
these settings to the child theme. Read more
How to defeat naive image steganography
Wed 27 April 2016
As a teenager, I wrote a C program to do image steganography.
It hid the secret image in the least significant bits of the cover
image. I also made a PHP web interface to it, which now sees about 3,000
users per month. So I've made a better version, it gives previews of the
input images, doesn't upload the images to my server (privacy, yo), and is faster. Read more
How (and why) to make your software faster
Fri 15 April 2016
Have you ever been bothered by how slowly your webapp loads, but never profiled it?
Much like test-driven development and A/B tests, performance profiling almost always throws up surprises and big wins, and
yet most people never bother to do it. If you have anything that
runs too slowly, you should profile it today, you will find improvements to make. Read more
Logrotate race condition with copytruncate
Thu 11 June 2015
The logrotate tool has a mode called copytruncate which copies the log file
and truncates the original, rather than renaming the original, so that the daemon doesn't need to reopen the log file. Read more
How to close a running process's socket
Thu 9 April 2015
I had a problem this morning of a process that was stuck waiting for an HTTP fetch
to complete, and had been stuck for 8 hours. Obviously the fetch had not been successful,
and additionally some sort of timeout
had broken, but I wanted the process to continue executing for the time being. What to do? Read more
West Country Place Name Generator
Fri 18 July 2014
I've recently written a West Country Place Name Generator. Read more
Yurt Lush Live Tracking
Sun 29 June 2014
In about 3 weeks' time I'm setting off on the Mongol Rally as one half of team Yurt Lush. Read more