Start
ncpdto connect to the Psion:ncpd -s /dev/cu.usbserial-A9DA9DOF -dRun
plpftpto browse and transfer files:plpftp
December Adventure' March 16
A Slow Start
I started the week with grand plans of adding a small feature a day to one of plptools or Reconnect—perhaps a backup command, TCP support for connecting to MAME, improvements to the file transfer, or incremental backups in Reconnect. One day in, it’s clear I’m certainly not going to manage one a day.
Usability Improvements
plptools adheres to a very Linux mindset, comprising multiple command line apps, each providing a distinct piece of functionality. These all rely on a central daemon—ncpd—for managing the serial port and connections to a Psion. While it’s a great system that allows you to run multiple tools in parallel (e.g., installing a program and managing your files at the same time), it does require users to run ncpd in addition to whatever tool they wish to use. For example, I run the following two commands to connect to my Series 3mx:
Inspite of the clear benefits of the architecture, unless you’re planning to run the daemon all the time (which Reconnect does but we don’t have a great story for yet in plptools), this can feel pretty heavyweight just to copy a file. I also have a theory that having to understand the plptools architecture sufficiently to know to run ncpd is a pretty big barrier to getting started. With that in mind, I plan to allow the different plptools apps to self-host the daemon if you specify a serial port. This will reduce the above to:
plpftp -s /dev/cu.usbserial-A9DA9DOF
Doing this means using reusing the NCPSession class from ncpd in plpftp, necessitating moving it into libplp (the library that’s shared between all the plptools CLI apps). This should be simple, but moving it left me with an app that segfaults as soon as the Psion connects. My working theory is that I’ve subtly changed the timing or object life cycle in a way that exposes existing race conditions. With that, I returned to the exercise of gently tidying the codebase and the work of adding thread-safety to ncpd—an incredibly nuanced process with a codebase as long-in-the-tooth as plptools.
Adventure Time
Inspired by Eli’s post, I’m spending the next week doing some not-quite-December adventuring. It’s hard to believe we’re nearly ¼ of the way through 2026, but here we are, and I suspect many of us already feel we need a break from it all. Time for an adventure!
As I’ve only got a week, I’m planning to keep things simple by focusing on improving the Psion connectivity story with plptools and Reconnect. If I can, I’d like to make one meaningful improvement each day—I think there’s room for a few small changes to each that will make things easier for folks using Psions in 2026.
Syntax Highlighting
Yesterday, I finally got around to publishing my OPL support for highlight.js. I’ve been using it here since I wrote it a couple of months ago, but now it’s available on GitHub and NPM for others to use.
PROC hello:
PRINT "OPL is amazing!"
GET
ENDP
Just like highlight.js itself, it’s incredibly easy to use, and there are a few different options.
You can use the module directly (what I do on this website):
import hljs from '../highlight.js/es/highlight.js';
import opl from './highlightjs-opl/src/languages/opl.js';
hljs.registerLanguage('opl', opl);
hljs.highlightAll();
Or add the minified self-registering version from the UNPKG CDN to your site’s head (how I’m using it on the OpoLua website):
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/highlightjs-opl/dist/opl.min.js"></script>
<script type="text/javascript">
hljs.highlightAll();
</script>
I’m looking forward to seeing all your OPL projects!