Monday, March 16, 2015

QR codes on the BBC Micro, Epilogue: KryoFlux to the rescue

In which I once more revel in nostalgia and still fiddle with bits, but do not talk about QR codes at all.

So with the BBC Micro quite dead, but my floppy disks and possibly the disk drive still intact, I looked around on the internet what other options I had. I found a few products which promised to control old floppy drives and convert the result to something more modern. In the end, I decided to buy the KryoFlux package, mostly because of its extensive documentation and active support forums. The KryoFlux is a small circuit board with a floppy drive cable connector on one side and a USB connector on the other.

But I also needed another disk drive, because the Beeb's drive didn't have the right plug. Or so I thought. So I found a list of drives known to work with the KryoFlux and searched for them on eBay. These turned out to be really easy to find, and on the second auction I was the highest bidder at the shocking price of €16,50 (including shipping).

A few weeks later, both the KryoFlux and the disk drive were sitting on my desk, ready to be hooked up. I followed the instructions to connect everything up, and installed the somewhat arcane command line tool. Then I typed dtc -c2 to detect how many tracks the drive can access. The disk drive made a noise, its head moved around, and eventually the tool printed maxtrack=83. That's quite a common number, so everything seemed to work so far.

Fortunately, when my dad brought the BBC Micro over, he also included all of his old floppy disks. They mostly contained teaching material that nobody cared about anymore, so I had plenty of disks to experiment with and possibly ruin. I popped one of these into the drive and figured out the command to make a raw image.

The KryoFlux was explicitly designed for software archival and forensics, and is able to read floppy disks at a much lower level than most hardware. What you get out of it isn't bytes, it isn't even bits, but it's the raw magnetic fluxes coming directly from the disk surface. This is great, because even if you can't salvage all of your data right away, you can still save off everything that's on the disk before it degrades even more, and do your rescue operation offline. It's also possible to decode the data on the fly, so that unreadable sectors can be retried automatically.

And it comes with a nice GUI tool to visualize the spectrum coming off the disk:

In the process, I learned a thing or two about how floppy disks work. You probably know that the disk surface contains magnetic patterns. The data is arranged in 80 (or 84) tracks, which are laid out as concentric rings, track 0 on the outside, track 79 (or 83) on the inside. The disk drive positions the head above the track it wants to read, spins around the disk at 300 rpm, and the resulting fluctuations in the magnetic field result in an electrical current in the drive's head. Essentially, the output of the floppy drive is just an analog waveform, and it's up to the controller to make sense of it.

There are different ways to encode data in such a wave. The disks I was looking at use FM, which – indeed – is Frequency Modulation. It's really simple: one frequency is used to encode a zero, another frequency is used to encode a one. To allow the drive to figure out where one bit ends and the next starts, clock bits are inserted into the stream: each other bit is a clock bit, and they are all set to 1. So, for example, the bit sequence 0110 would be encoded as 10111110. (The problem with this is that you might lose synchronization if you get a long run of just 1s. That's why MFM was invented.)

Now you can probably make sense of the spectrum shown in the screenshot above. The 4.0 µs band shows the zeros, the 8.0 µs band shows the ones. When you zoom in, you can even somewhat make out the individual bits:

Fun fact: The magnetic flux was sometimes also used to write special copy protection patterns to the disk, which couldn't be reproduced by normal byte-based disk copy tools. This article shows a gorgeous example near the end.

So with the help of the KryoFlux tool, I was able to create a series of files (one per track) that contained these raw waves straight off the disk. But the tool doesn't stop there; it also lets you decode the FM (or other) format into bytes, in a proper disk image. And it gives you some indication of how well it succeeded.

As it turned out, not very well. Decoding the FM stream would consistently get me for the first dozen or so tracks on the disk. From there on out, it got slightly better, with the occasional track showing OK*, and near the end of the disk all tracks were supposedly OK*. Except they weren't. When running strings on the resulting disk image, I got stuff like this:

This test consists`of two perts. Part One is about the works you have read
in class with yo}r teakher. Part Two is about the books you have read on
your own. You only have to answer questionw0

It got better near the end of the disk, but still not good enough. To preserve actually working software, we need every last bit to be correct.

I tried with two more disks, including some that did work in the BBC Micro only weeks before, but both showed the same pattern. I suspected that the drive I bought on eBay might be faulty. Before buying yet another drive, I asked on the support forums if anyone had a clue what might be wrong, but didn't get much useful info.

I left the project alone for a few weeks, and eventually decided to modify the BBC Micro's original drive so I could connect it to the KryoFlux. The data cable looked like a regular old flatcable, but the power connector was all weird. I opened up the drive case so I could see how it was wired up, but lo and behold! On the inside, the weird power cable ended in a standard molex plug that connected to the drive!

Encouraged, I went through the setup procedure again with this drive. Would it still work, or did it break along with the Beeb itself? I connected the data cable, and nothing interesting happened. I connected the power cable, and no smoke came out. I sniffed the drive, but it didn't emit that typical fried-electronics smell. So far so good.

Then I ran the KryoFlux calibration tool again. The drive head moved! It seemed to bump up against something near the end, but the tool still reported maxtrack=83. Oh well, it's probably fine. Let's read a disk.

And yes! Yes! The tool printed a slew of OKs! Let's look at the image content:

This test consists of two parts. Part One is about the works you have read
in class with your teacher. Part Two is about the books you have read on
your own. You only have to answer questions about the books you have read.

Now that is proper English!

Would the entire disk be okay? In particular, would we be able to read the catalogue that stores where files reside on the disk? To check that, we have DFS Explorer. And it looks like this:

Oooh yeah. Actual files! Readable ones, too. Just to make sure that everything was working properly, I made another image of the same disk and compared the two. Some bad sectors seemed to throw it off, but the good sectors did not seem to have any differences.

I could also load the disk into the emulater BeebEm, but that seemed to lack the Wordwise word processing ROM, so I couldn't view any of the files. Time to try with a disk containing actual programs; mostly games I used to play (but didn't write).

Track 0: OK. Track 1: OK. Track 2: OK. And so on… this disk seemed absolutely fine! Excited, I loaded it into BeebEm, and got a scary message: "WARNING - Incorrect disc type selected? This disc file looks like a double sided disc image. Check files before copying them." Indeed, I could get a disk catalogue but everything I tried to load gave me Bad program.

Eventually, I figured out that naming it spel.dsd (for double sided disk, as opposed to spel.ssd or spel.img) fixed things. I was in business! Look at all the cool stuff on this disk!


The exciting game MUNCHING MOUSE, where you run from left to right in the shortest time possible, collecting the cheese:

The even more exciting game BAT'N'BALL, which… well, you guessed it:

The actually somewhat interesting YELLOW RIVER KINGDOM, where you assign your villagers to (a) defend the dyke to prevent flooding, (b) work in the fields to grow rice, or (c) protect the villages from thieves:

And on the other side of the disk, I rediscovered one of my childhood classics: CASTLE OF NIGHTMARES. Damn, this game is hard. I can't seem to be able to record uncorrupted video with BeebEm, but here's the music:

Hmm, maybe a bit repetitive? How about this great tune instead? The soundtrack of my childhood!

Another great program I recovered was "Speech!", a wonderfully retro speech synthesizer that sounds like this:

Now I really want to use that in a game some day.

Speaking of games, what about this '80s version of Kerbal Space Program?

I once wrote a PC clone of that in QBasic when I was 13. And a sequel to that clone. And a mouse-driven GUI level editor for the sequel.

There were also a few files I couldn't readily identify. They were neither text files nor BASIC programs. Looking at the hex dump, I noticed there were some repeating patterns: a streak of 0xff bytes, then some other bytes, then another streak of 0xff bytes, and so on. Could these files be… images? And how would you store an image on the BBC Micro, if not by writing the contents of the video memory directly to disk? We can reverse that with a simple *LOAD command!

Copyright © yours truly, year unknown. Notice how IKON, the drawing program, didn't even bother to remove its own UI elements from the saved file.

So far, I'd only converted compilation disks, with programs probably typed in from magazines and such. Most of the old disks were still 100% readable, and although some had bad sectors, even they were largely still usable. Eventually, this gave me the courage to put in a disk with my own programs. Apparently, I once started work on a Breakout clone, imaginatively named BREAKOUT. The ball bounces and the paddle moves, but blocks you hit don't disappear and the game crashes when you die.

There was also a Mastermind game that I was sure I couldn't have written, until I encountered my name in the comments. Go me for commenting stuff! But it appeared to give me contradictory clues, so maybe that wasn't finished either.

I even dabbled in cryptography! Can you figure out the algorithm?

And apparently I had some database program cunningly disguised as MARIO, which was password-protected; look at how I obfuscated the password (didImentionthatthingaboutspacesbeingoptional?):

170IFLEFT$(T$,9)=CHR$(74)+CHR$(5*13)+CHR$(79-1)+CHR$(68)+CHR$(80-1)+CHR$(59+10)+CHR$(70-2)+CHR$(70-1)+CHR$(76)THENPRINTTAB(12,13)"Wachtwoord correct":T=TIME:REPEATUNTILTIME-T>200:GOTO240

Never mind that if somebody could read this code, they could also just replace it by GOTO240 and have instant access – but it might have kept out non-programmers who could still type LIST (i.e. my brother). I don't think I ever even put any data into this…

I did have some trouble with bad sectors during the salvage operation, but eventually, bumping it up to a hundred retries or so, every last bit came off of the disks I cared about. Even then, one disk gave me trouble: ADFS Explorer would read it just fine, but the BeebEm emulator reported Bad directory instead of giving me a listing. Diving into the internals of the ADFS filesystem showed why: the directory's sequence counter is written to disk twice, once in the directory header and once in the footer, and the two must match. A one-byte change in a hex editor later, and this last disk image too was perfectly usable. I don't know if it was bitrot, or if the disk had been corrupted previously during a write operation.

I'd like to put all my old stuff up on GitHub at some point, but the disk images contain some private information (e.g. address stickers, letters I typed up for other people) so I'll have to curate them first. But the bits are safe now, which is what counts!


Robin Slader said...

That was an incredibly good read, thanks very much for writing up your experiences of KryoFlux.

I so wish I could get hold of the stuff I produced when I was young. Just for the nostalgia (and the laughs). Nothing like you did though, I'm very impressed!

Anonymous said...

To protect your BASIC programs from getting LISTed, you could have inserted REM statements with control characters in the comments. I used to put a clear-screen (form feed?), a few beeps (ascii 7) and then some other character that jammed up the screen somehow and required a reboot. To get these into the comments was a bit tricky. I think we used to put an ordinary comment, figure out where the comment was in RAM, then overwrite those memory locations with nasty characters.

Aeldra Robinson said...

Most QR codes are fairly small, as they contain just a web address or some such. But they can actually grow to the “Level 40” monster code of 177×177 squares, which can hold 2953 bytes of arbitrary binary data. That’s about 60 QR codes to transfer the contents of one floppy.
security static code analysis