-
I’ve ordered some antistatic brushes for future work. ↩
December Adventure Day 29
The Long Tail
With the month coming to a close, I decided to spend the last few days of my December Adventure to wrap-up some of the loose ends of the projects I’ve worked on this month: I found a few outstanding changes in Reconnect when I added Psion Word conversion support, and there was some further cleanup to do to the OpoLua source tree to set us up for new features in 2026.
OpoLua
As OpoLua has grown, we’re using it in more-and-more projects: it now serves as a cross-platform library for working with EPOC16 and EPOC32 files, and we’re using it in both Reconnect and the Psion Software Index. As is always the case with software projects, the source structure hasn’t evolved at the same pace, so I took some time to tidy it up: I cleaned up the top-level Swift package, added smoke-test builds for this, and updated the OpoLua app to use the package, rather than including the source files directly. Since Reconnect and OpoLua now use the same ‘OpoLuaCore’ library, it will make keeping Reconnect up-to-date much easier. Over time, I hope to move more functionality from the OpoLua app into OpoLuaCore to allow us to use it in other apps.
Reconnect
I caught Reconnect up to the new version of OpoLua and finally got around to adopting the support for customizing SIS file install locations that Tom added sometime ago, unlocking using SIS files with EPOC16—while this was never supported for EPOC16, I hope it will allow us to start packaging EPOC16 programs on the Psion Software Index to make that easier for people to jump into.
I also spent a little time triaging the open issues, and had a quick look at what it would take to convert EPOC16 PIC images—it turns out these are just multi-bitmap MBM files with black and grey planes, which I didn’t quite combine correctly on my first attempt:
A solid day of laying the groundwork for the future. 🧱
December Adventure Day 28
File Conversions
Inspired by Alex’s evergreen enthusiasm for the Psion Series 3 devices, and my recent Series 3a maintenance efforts, I’d love to find a way to incorporate these into my daily routines. Boasting a full keyboard, they are natural writing devices so, for day 28 of my December Adventure, I decided to focus on improving my workflows for journaling and writing-up projects on my Series 3mx.
Out of the box, EPOC16 devices are well set up for writing—Psion Word is an entirely serviceable word processor. This leaves just the process of getting the files into modern formats, and into my other workflows. Reconnect, my modern Psion connectivity suite for macOS, supports file transfer for EPOC16 devices, but doesn’t support conversion for these older file formats, so I set about fixing this sort-fall, starting with Word file conversion.
Tony Smith has already produced an MIT licensed Word parser and converter written in Swift, Word2Text, (thanks Tony!), so this seemed like the natural starting point. Armed with a fully-functional implementation, there wasn’t too much to do but plumb it into Reconnect’s existing file conversion architecture:
private static let converters: [Conversion] = [
// MBM
Conversion { entry in
return entry.fileType == .mbm || entry.pathExtension.lowercased() == "mbm"
} filename: { entry in
return entry.name
.deletingPathExtension
.appendingPathExtension("tiff")
} perform: { sourceURL, destinationURL in
let outputURL = destinationURL.appendingPathComponent(sourceURL.lastPathComponent.deletingPathExtension,
conformingTo: .tiff)
try PsiLuaEnv().convertMultiBitmap(at: sourceURL, to: outputURL)
try FileManager.default.removeItem(at: sourceURL)
return outputURL
},
// WRD
Conversion { entry in
return entry.pathExtension.lowercased() == "wrd"
} filename: { entry in
return entry
.name
.deletingPathExtension
.appendingPathExtension("txt")
} perform: { sourceURL, destinationURL in
let outputURL = destinationURL.appendingPathComponent(sourceURL.lastPathComponent.deletingPathExtension,
conformingTo: .plainText)
let data = try Data(contentsOf: sourceURL)
let bytes = [UInt8](data)[...]
let result: ProcessResult = PsionWord.processFile(bytes)
guard result.errorCode == .noError else {
throw ReconnectError.unknown
}
try result.text.write(to: outputURL, atomically: true, encoding: .utf8)
return outputURL
}
]
Looking again at this code, there are some elements of the architecture that I’d love to revisit: I especially dislike the duplicated filename generation code. This exists because macOS needs to know the target filename upfront for drag-and-drop operations, but I could at least change my converter API to inject it back into the perform: block.
Architectural aspirations aside, everything just worked, and it’s now possible to effortlessly convert Psion Word files to text by drag-and-dropping them from Reconnect! 🥳
While I was at it, I also added a new ‘Conversions’ tab to the Reconnect settings:
I plan to expand on this in the future to allow per-file type options: Word2Text supports conversion to text or Markdown and I’d love to expose that functionality in Reconnect.
December Adventure Day 27
Leaky Batteries
After altogether too long, day 27 of my December Adventure saw me finally tackling, ‘remove Libretto 50CT batteries’, which my Organiser Il lucky dip has reminded me of countless times this month. I filmed the process, but as there are already good teardown guides, I’ve focused on illustrative stills instead of publishing the whole video.
My daily driver Libretto 50CT awaiting surgery on the operating table
As I had feared, the BIOS batteries in both machines had started to leak ever so slightly. The leak wasn’t apparent at first, but the battery contacts were corroded and it was clear it had travelled along the battery wires and into the JST connector on the mainboard.
You can just make out the green corrosion on the connector
Having found the corrosion, I decided to fully tear down both machines and clean the affected area of the mainboard with white vinegar, followed by a healthy rinse in IPA. While I could have done this with the mainboard in the case, I didn’t want to risk further damaging the already-brittle plastics with the vinegar.
I used an old stiff-bristle paintbrush1 for the process and focused on the area around the JST connector. After giving the mainboard time to dry, I reassembled everything taking care not to crack the case and verified both machines still worked.
Thankfully, it looks like I caught the leaks in time, and both machines booted up. I’d still like to switch out the spinning hard disk in my secondary device, but that’s one for another day. 😮💨
Perhaps even more concerning than the leaky batteries was discovering the damage Hawaii is doing to the Libretto I have in daily rotation—the climate here is brutal and sadly shortens the life of devices, old and new.
The humid salt air is rapidly corroding the metallic paint on the Libretto’s case
There’s not much I can do about the climate—I keep what I can in weatherproof totes with desiccants—but I can be more selective about the devices I keep out. Seeing this damage is a good reminder to be more deliberate about the devices I use, an encouragement to let a few go to good homes, and practice a little more minimalism.