Claude × retrocomputing: emulating a QIC-117 tape drive

For my next trick frivolous use of LLMs, I’m building an emulated tape drive!

TLDR: The 86Box emulator now allows you to emulate a QIC-117 tape drive connected to the floppy controller, or to a parallel port, and make “backups” to virtual tape images using actual DOS and early Windows-era backup software.

I’ve always been rather obsessed with emulators. I have an extensive collection of bootable disk images that contain virtually every version of DOS, Windows, Mac System versions, Amiga OS, various Unixes, and other more obscure OSes, all ready to run at the click of an icon.

One of my favorite emulators for emulating DOS and early Windows-based systems is 86Box, which is an evolution of the great PCEm emulator. 86Box is a very “low-level” emulator that actually executes the BIOS ROM of various chipsets, and emulates a plethora of devices and peripherals very faithfully. 86Box also happens to be refreshingly accessible for developing and extending.

For a while I’ve had this idea in the back of my mind to combine two of my obsessions: emulation and tape media. Wouldn’t it be neat if we could emulate a tape drive, with a virtual tape cartridge, reading from a virtual tape image file? As far as I know, there are no emulators currently available that emulate a QIC tape drive (specifically QIC-80 and its later cousins like QIC-3020).

image

I deal with recovering data from QIC tapes on a regular basis. And as someone who cares about digital preservation, I always make sure to obtain a complete binary image of the tape, so that it might be possible to reproduce the image onto a different tape, exactly as the original backup software would have written it. (Side note: a truly “proper” preservation of a tape would be to save the actual flux transitions, instead of the higher-level binary bytes, but that’s a subject for a future post.)

And so, with the binary tape images in hand, it would be great to “close the loop” by allowing the original backup software, running in an emulator, to read these tapes by believing that it’s communicating with a real tape drive. Fortunately we are living in a time when one person’s backlog can become their AI agent’s top priority.

image

These QIC tape drives, such as the Colorado 250, Travan, and so on, communicate over the floppy controller using a special protocol called QIC-117. The complete specification of this protocol is readily available on the web. You would think, therefore, that all that’s necessary is for our emulated drive to implement the entire QIC-117 spec, and all will be well.

Sadly that’s not quite the case. In addition to all the standard QIC-117 functions, the spec allows for manufacturer-specific “diagnostic” commands that basically open the spec up to completely arbitrary behavior that the manufacturer desires. And indeed, the manufacturers make generous use of these diagnostic commands, particularly in the detection phase of when the host driver wants to determine the type of drive that is connected.

With just the bare QIC-117 spec implemented, which took Claude Opus 5 just three or four prompts to complete, only a single backup utility for MS-DOS would agree to detect and read from the drive, namely HP Colorado Backup 7 (QBACKUP). This was actually the first utility I tried, which initially gave me false hope, because afterwards I started realizing that different utilities employ wildly different ways of detecting these drives, and QBACKUP happened to employ the least manufacturer-specific trickery.

image

When I tried using tools like Microsoft Backup for Windows 95, for example, I noticed it putting the drive into diagnostic mode and attempting to issue manufacturer-specific commands. Since I was emulating a Colorado drive (the QIC-117 spec requires the drive to reply with a “vendor code” from a predefined list of known vendors), MS Backup was clearly trying to do Colorado-specific things with the drive, which are not documented anywhere.

There are two ways we could uncover what the diagnostic functions do: we could connect a real Colorado drive and attempt to monitor the traffic that goes across a real floppy controller, or…

image

We could unsolder the ROM chip from the drive, perform a disassembly of the ROM, and get a complete understanding of all the commands that the drive supports, including all the diagnostic bits!

Armed with nothing more than a dump of the ROM and a photo of the PC board, I told Claude to “see what you can do with this”, and it obediently disassembled the ROM and laid out exactly what custom commands the drive supports, and exactly how the drive deviates from the spec for certain standard commands. Have a look at the repo where I put the resulting analysis of the ROM disassembly from the Colorado drive, as well as a few other related drives in my collection. You’ll find all of these rather interesting tidbits in the repo:

  • A FINDINGS.md document with an extremely detailed breakdown of all the commands supported by the drive, including some very interesting possibilities for future work in enabling the drive to read tapes that were previously believed to be unreadable, as well as enabling a custom controller, such as a Greaseweazle, to control the drive and read the raw flux transitions, for truly proper digital preservation.
  • Disassembler (written in Python) for the Intel 8051 processor, which is the main IC that controls the drive. There is also a disassembler for the Zilog Z8 processor, used by a couple of the other drives. Both of these disassemblers were thrown together by the LLM as an effortless prerequisite for its work.

This filled in all the missing pieces necessary to complete the emulated QIC-117 drive, now usable in 86Box:

image

Afterwards, for the sake of completeness, I also implemented support for a parallel port version of these drives (LPT port with EPP), which emulates an Iomega Ditto drive. This drive is actually a QIC-117 drive internally, but contains an extra chip that allows it to communicate over the parallel port using a protocol called Backpack, developed by MicroSolutions.

image

The Iomega Ditto 2GB drive in particular is one of my go-to drives for reading QIC cartridges, because of its excellent backwards compatibility with older cartridges, being able to read not only the first-party Ditto cartridges, but other smaller-capacity tapes like Travan, QIC-3020, all the way down to QIC-2080. All of these are now supported as emulated cartridges in 86Box, when configuring your emulated Ditto drive on the parallel port.

image

One minor quirk is that Ditto cartridges always came pre-formatted, and there’s no way for the end user to format a completely blank tape image. Therefore I made a repository of pre-formatted tape images for you to download and use for yourself. The repository also contains a Python script that lets you generate a tape image with your desired capacity and custom label. Have fun!

Claude × retrocomputing: emulating the TC2000 supercomputer

A few years ago I received a package of tapes that came from a TC2000 system, which was a supercomputer from the late 1980s built by a company called BBN (Bolt, Beranek and Newman). The data on these tapes was recovered without any issues, and it turned out to be a minor treasure trove of software for the TC2000, as well as its cousin the GP1000.

image

One of the tapes was an actual “boot” tape — the system would boot from this tape, which then allows the user to install the operating system (called “nX”, based on 4.3BSD Unix) onto a hard disk. (Unfortunately the system installation tape was not part of this collection; just the boot tape, and a few other supplemental software tapes, so it isn’t possible to reconstruct a “complete” TC2000 system from what we have here.)

Ever since then, I’ve had a bullet point deep in my backlog to build an emulator for this system, and actually boot this tape image, and see the 4.3BSD kernel messages from 1989 flying across the screen. Sort of… like this:

The above is literally the live TC2000 system, booting into the real tape image with vmunix on it, running in your browser, and letting you interact with it (here is the source code!). Admittedly there isn’t much to do in this boot environment. It expects you to execute nxinstall and proceed to install the operating system onto a hard disk, but like I said, the actual full operating system is on another, missing tape. So instead, I took the boot tape image and combined it with some of the aforementioned “supplemental” software tools, which includes a number of games that you can play in the above console. Go to /usr/games/ and experience for yourself the kind of fun that users of the TC2000 were having in 1989.

(I should note that the emulation is not perfect, because much of it needed to be reverse-engineered from the actual instructions of the kernel executable. So, if any program you run in the emulator crashes or gets stuck, you can click the “Restart” button to reboot.)

***

The thing is, this emulator was built almost entirely by an LLM (Claude Opus 5, over the course of a few days of prompting and iterating), and you know what? I think I’m okay with that. If you’ll permit some philosophizing and grappling with the use of an LLM for a hobby project like this:

My hobby is retrocomputing. But ultimately, the real satisfaction I derive from this hobby is making something work. For me, the end result of seeing something working is the satisfying payoff. The tools I use for making something work are a secondary detail. Using an LLM is a new tool for getting something to work. That the LLM was able to build a TC2000 emulator for me is therefore a genuine win.

Is the win cheapened by the fact that I didn’t write most of the code? I don’t believe so. The fact is, if LLMs didn’t exist, then this random idea would have languished in my backlog forever, and would have never gotten done. Would it have been possible for me to write all this code myself? Absolutely, over the course of several years of this project taking priority over other things in my life, which would simply not be worth it. Is the win cheapened by the fact that “anyone can do it” now? I don’t believe so. Yes, it is true that anyone else could have done this. So then… go ahead and do it! Who’s stopping you from picking a random idea you had ages ago, and getting it done?

***

So there we have it: here is the repo of the TC2000 emulator, which emulates a Motorola 88100 CPU, an 88200 CMMU, and all the other accoutrements to get the system booted. See the README file in the repo for much more details of how the system works. Unfortunately the emulator can’t go much further without more of the missing pieces from the original TC2000 system: ROM images, the full OS installation tape, and so on. Without these things, the emulator won’t be able to emulate the major selling point of this whole system: the “Butterfly switch” that actually allows multiple processor nodes to run processes independently (currently it emulates just a single node). If you or someone you know has access to these materials, or has additional stories from the BBN days, please get in touch!

Brain dump, May 2026

My old Kindles

With Amazon having ended support for many older-generation Kindle devices, I thought I’d go back and make sure that my existing Kindles will still be usable for the foreseeable future. Up until now, I’ve been using a 2nd generation Kindle (yes, literally the Kindle 2, released in 2009), and my wife has been using a 3rd generation Kindle, released in 2010.

image

We use and enjoy these devices almost every day, because they still work perfectly well for the purpose of reading books. I mostly read free eBooks from Gutenberg, as well as technical PDF files, since my Kindle 2 doesn’t support WiFi, which is fine with me. If I need to load a new book or document onto my Kindle, I don’t mind connecting it to my PC and transferring the book over.

The Kindle 3 that my wife had been using supports WiFi (the first Kindle model to do so), and she had enjoyed borrowing books from our library through her Amazon account. When she heard the news that Amazon was dropping support for her Kindle, despite my pleas, she insisted on finally upgrading to a more modern Kindle, and ended up getting the Kindle 11, released in 2024.

image

Even though the Kindle 11 is better in some ways than the Kindle 3, both my wife and I agree that it’s not 8 generations-worth better. Yes, it’s more responsive overall, and the e-ink refreshes slightly faster, and the backlight can be useful in low light conditions. But certain other things feel like either regressions or just unnecessary product churn. Why, I ask you, did they get rid of physical buttons to go to the next or previous page? These were extremely convenient and intuitive affordances that allowed single-handed navigation through the book, and saved the display from getting smudged due to constant tapping and swiping.

Would it kill them to keep physical buttons for turning pages? Is it some kind of competition of minimalism? Are they showing off their ability to incorporate touch gestures into their e-ink display technology? We get it, you can make a capacitive e-ink touchscreen. But physical buttons are good, too!

I suppose, on the one hand, Amazon can be commended for continuing support for these devices for the last 15 years, which is longer than many other hardware vendors I can name. But on the other hand, is it really that difficult to continue supporting them further? This really feels like planned forced obsolescence. It feels like Amazon unwittingly made these older devices too good, and now wants to force users to upgrade.

In any case, now that my wife has switched to the Kindle 11, I will be switching to her old Kindle 3, but not just a Kindle 3 — a jailbroken Kindle 3! Jailbreaking allows you to do numerous interesting things with the Kindle, including customizing the screensaver illustrations, and even having a functioning console:

image

Typing actual commands into this e-ink console using the Kindle keyboard is as excruciating as you might expect, but just seeing it work is reward enough.

But seriously, the real benefit of jailbreaking is to install a custom non-Amazon reader app that supports the EPUB format natively (among others), whereas previously I would need to convert from the EPUB to the MOBI format. And with these updates, I will be keeping my Kindle 3 until either its hardware fails entirely, or I drop it into a lake. Otherwise, I see no reason at all to upgrade to a newer model.

Retro handhelds

I’ve been kind of obsessed with super-cheap handheld retro gaming consoles lately! During a shopping spree on AliExpress for some unrelated electronics, I randomly came across these devices and picked up a couple, namely the RGB30 ($60 with a discount), and the R36S (regularly $60, but I got a “clone” version for $30 which seems to work just fine). These devices run Linux, and boot from a microSD card that also holds the game ROM files that you want to play. And since it’s Linux, there is naturally a thriving community that builds custom OS images with all kinds of customizable features and tweaks. I loaded dArkOS on both of these devices, and it runs perfectly.

image

I’m not a “gamer” by any stretch at all, nor do I really want to be. I did, however, used to play plenty of games in the old days on MS-DOS, Commodore 64, various arcades, all the way up to Nintendo 64, but not much beyond that.

And that’s where these devices really rise to the occasion: they run an emulation platform (RetroArch, running on top of Linux) that can emulate all of these old game systems, and many others, with impressive accuracy. Just put your ROM files onto the microSD card, and off you go.

These devices are definitely “cheap” in most senses. The ergonomics are so-so, the buttons and joysticks are a bit flimsy, battery life is not great, and so on. However, one area where these devices shine is the display: the screens on these devices are quite nice, with good brightness and crisp pixels, particularly if you emulate the games with integer scaling.

The RGB30 (my favorite of the two, although more expensive) has a display resolution of 720×720 — yes, a square aspect ratio — which is super interesting, because this offers the versatility of playing e.g. GameBoy Advance games with integer scaling (the GBA had a resolution of 240×160, which scales nicely to 720), but also playing arcade games, which are often played in portrait (vertical) orientation, which also looks great on this display.

image

And the R36S has a display resolution of 640×480, which is also very interesting, because this is great for integer scaling of DOS games, most of which used 320×200 VGA resolution, and look fantastic on this device:

image

Spend just a few minutes customizing the key bindings of the device’s buttons to correspond to the specific game’s controls, and you’re good to go. Even mouse-driven point-and-click games for DOS (King’s Quest, Kyrandia, etc.) work great, with the mouse emulated using one of the analog joysticks. If you’re feeling particularly masochistic, you could even run Windows 3.1, or even Windows 95, and go nuts.

image

And that’s why I like these handheld devices so much — they scratch the itch of getting something working just right, and they deliver an instant hit of nostalgia; I play a game for about 10 minutes, get bored, and then move on with my day. It’s perfect.

Defeating a 40-year-old copy protection dongle

image

That’s right — this little device is what stood between me and the ability to run an even older piece of software that I recently unearthed during an expedition of software archaeology.

For a bit more background, I was recently involved in helping a friend’s accounting firm to move away from using an extremely legacy software package that they had locked themselves into using for the last four decades.

This software was built using a programming language called RPG (“Report Program Generator”), which is older than COBOL (!), and was used with IBM’s midrange computers such as the System/3, System/32, and all the way up to the AS/400. Apparently, RPG was subsequently ported to MS-DOS, so that the same software tools built with RPG could run on personal computers, which is how we ended up here.

This accounting firm was actually using a Windows 98 computer (yep, in 2026), and running the RPG software inside a DOS console window. And it turned out that, in order to run this software, it requires a special hardware copy-protection dongle to be attached to the computer’s parallel port! This was a relatively common practice in those days, particularly with “enterprise” software vendors who wanted to protect their very important™ software from unauthorized use.

image

Sadly, most of the text and markings on the dongle’s label has been worn or scratched off, but we can make out several clues:

  • The words “Stamford, CT”, and what’s very likely the logo of a company called “Software Security Inc”. The only evidence for the existence of this company is this record of them exhibiting their wares at SIGGRAPH conferences in the early 1990s, as well as several patents issued to them, relating to software protection.
  • A word that seems to say “RUNTIME”, which will become clear in a bit.

My first course of action was to take a disk image of the Windows 98 PC that was running this software, and get it running in an emulator, so that we could see what the software actually does, and perhaps export the data from this software into a more modern format, to be used with modern accounting tools. But of course all of this requires the hardware dongle; none of the accounting tools seem to work without it plugged in.

Before doing anything, I looked through the disk image for any additional interesting clues, and found plenty of fascinating (and archaeologically significant?) stuff:

image

  • We’ve got a compiler for the RPG II language (excellent!), made by a company called Software West Inc.
  • Even better, there are two versions of the RPG II compiler, released on various dates in the 1990s by Software West.
  • We’ve got the complete source code of the accounting software, written in RPG. It looks like the full accounting package consists of numerous RPG modules, with a gnarly combination of DOS batch files for orchestrating them, all set up as a “menu” system for the user to navigate using number combinations. Clearly the author of this accounting system was originally an IBM mainframe programmer, and insisted on bringing those skills over to DOS, with mixed results.

I began by playing around with the RPG compiler in isolation, and I learned very quickly that it’s the RPG compiler itself that requires the hardware dongle, and then the compiler automatically injects the same copy-protection logic into any executables it generates. This explains the text that seems to say “RUNTIME” on the dongle.

The compiler consists of a few executable files, notably RPGC.EXE, which is the compiler, and SEU.EXE, which is a source editor (“Source Entry Utility”). Here’s what we get when we launch SEU without the dongle, after a couple of seconds:

image

A bit rude, but this gives us an important clue: this program must be trying to communicate over the parallel port over the course of a few seconds (which could give us an opportunity to pause it for debugging, and see what it’s doing during that time), and then exits with a message (which we can now find in a disassembly of the program, and trace how it gets there).

A great tool for disassembling executables of this vintage is Reko. It understands 16-bit real mode executables, and even attempts to decompile them into readable C code that corresponds to the disassembly.

image

And so, looking at the decompiled/disassembled code in Reko, I expected to find in and out instructions, which would be the telltale sign of the program trying to communicate with the parallel port through the PC’s I/O ports. However… I didn’t see an in or out instruction anywhere! But then I noticed something: Reko disassembled the executable into two “segments”: 0800 and 0809, and I was only looking at segment 0809.

image

If we look at segment 0800, we see the smoking gun: in and out instructions, meaning that the copy-protection routine is definitely here, and best of all, the entire code segment is a mere 0x90 bytes, which suggests that the entire routine should be pretty easy to unravel and understand. For some reason, Reko was not able to decompile this code into a C representation, but it still produced a disassembly, which will work just fine for our purposes. Maybe this was a primitive form of obfuscation from those early days, which is now confusing Reko and preventing it from associating this chunk of code with the rest of the program… who knows.

Here is a GitHub Gist with the disassembly of this code, along with my annotations and notes. My x86 assembly knowledge is a little rusty, but here is the gist of what this code does:

  • It’s definitely a single self-contained routine, intended to be called using a “far” CALL instruction, since it returns with a RETF instruction.
  • It begins by detecting the address of the parallel port, by reading the BIOS data area. If the computer has more than one parallel port, the dongle must be connected to the first parallel port (LPT1).
  • It performs a loop where it writes values to the data register of the parallel port, and then reads the status register, and accumulates responses in the BH and BL registers.
  • At the end of the routine, the “result” of the whole procedure is stored in the BX register (BH and BL together), which will presumably be “verified” by the caller of the routine.
  • Very importantly, there doesn’t seem to be any “input” into this routine. It doesn’t pop anything from the stack, nor does it care about any register values passed into it. Which can only mean that the result of this routine is completely constant! No matter what complicated back-and-forth it does with the dongle, the result of this routine should always be the same.

With the knowledge that this routine must exit with some magic value stored in BX, we can now patch the first few bytes of the routine to do just that! Not yet knowing which value to put in BX, let’s start with 1234:

BB 34 12       MOV BX, 1234h
CB             RETF

Only the first four bytes need patching — set BX to our desired value, and get out of there (RETF). Running the patched executable with these new bytes still fails (expectedly) with the same message of “No dongle, no edit”, but it fails immediately, instead of after several seconds of talking to the parallel port. Progress!

Stepping through the disassembly more closely, we get another major clue: The only value that BH can be at the end of the routine is 76h (this is hard-coded into the routine). So, our total value for the magic number in BX must be of the form 76xx. In other words, only the BL value remains unknown:

BB __ 76       MOV BX, 76__h
CB             RETF

Since BL is an 8-bit register, it can only have 256 possible values. And what do we do when we have 256 combinations to try? Brute force it! I whipped up a script that plugs a value into that particular byte (from 0 to 255) and programmatically launches the executable in DosBox, and observes the output. Lo and behold, it worked! The brute forcing didn’t take long at all, because the correct number turned out to be… 6. Meaning that the total magic number in BX should be 7606h:

BB 06 76       MOV BX, 7606h
CB             RETF

image

Bingo!
And then, proceeding to examine the other executable files in the compiler suite, the parallel port routine turns out to be exactly the same. All of the executables have the exact same copy protection logic, as if it was rubber-stamped onto them. In fact, when the compiler (RPGC.EXE) compiles some RPG source code, it seems to copy the parallel port routine from itself into the compiled program. That’s right: the patched version of the compiler will produce executables with the same patched copy protection routine! Very convenient.

I must say, this copy protection mechanism seems a bit… simplistic? A hardware dongle that just passes back a constant number? Defeatable with a four-byte patch? Is this really worthy of a patent? But who am I to pass judgment. It’s possible that I haven’t fully understood the logic, and the copy protection will somehow re-surface in another way. It’s also possible that the creators of the RPG compiler (Software West, Inc) didn’t take proper advantage of the hardware dongle, and used it in a way that is so easily bypassed.

In any case, Software West’s RPG II compiler is now free from the constraint of the parallel port dongle! And at some point soon, I’ll work on purging any PII from the compiler directories, and make this compiler available as an artifact of computing history. It doesn’t seem to be available anywhere else on the web. If anyone reading this was associated with Software West Inc, feel free to get in touch — I have many questions!

Brain dump, October 2025

What do I do with old Android phones that I’d like to keep around for testing purposes, while no longer worrying about the long-term fate of the lithium battery inside them? Here’s what:

I take the battery out, make sure it’s fully discharged, and surgically remove the controller logic board from the battery (don’t try this yourself unless you know exactly what you’re doing).

image

I then solder this PCB directly onto the battery terminals in the phone, and finally solder my actual power inputs onto the positive and negative pads on the underside of the PCB.

image

The above example is a Samsung Galaxy Note 4, still plenty powerful for all kinds of development and testing purposes, and is now usable without a battery! I opted to use a cheap standard barrel connector for my power cable, simply because that’s what I had on hand, and also to emphasize that it must be connected to a proper power supply that outputs ~4 volts and is capable of at least 2 amps.

Here is the Note 4, running off a 12V power supply, through a cheap adjustable buck converter that is tuned to output exactly 4.0V, which makes the phone believe the battery is 85% charged.

image


Speaking of “Android” devices, I had a bit of fun playing with a couple of these intriguing things:

image

This is an LTE/WiFi dongle, which lets you insert your SIM card that has a data plan, for when you want to connect to the internet from your laptop on the go. But under the surface, there are several things about this dongle that are very interesting indeed:

First, this stick is basically a fully-fledged Android device on the inside. That’s right — it contains all the internals of a low-end Android phone, cleverly packaged into a USB stick form-factor.

image

Another interesting thing is the price: at the time of writing, I was able to obtain several of these devices for about $8 each from AliExpress, which is an incredible value for the functionality you can unlock, because:

The final interesting thing about these devices is that they’re very hackable. In fact, there’s an entire community (because of course there is!) that has figured out how to load a completely standard Debian distro onto this stick, with all the bells and whistles that provides, including USB gadget capabilities, allowing you to turn this stick into any type of USB device of your choosing, such as a mass storage device, or an HID keyboard (à la Rubber Ducky, except for 1/10th the price), or an RNDIS network interface (which can capture and record packets), or any number of other types of gadgets, all while still allowing you to “log in” to it via its WiFi hotspot or LTE modem.

I went a little overboard and soldered some wires onto the UART pins, then routed the wires around the metal shielding so that they’d stick out of the plastic case.

image

I then put some hot glue over the wires and smooshed the plastic case over it, so that the wires are nicely secured. And now I have a nicely debuggable platform for doing further tinkering with this amazing little stick!

image
image