Like many people during the months of April and May, I found myself with a lot more free time on my hands after being put on furlough whilst COVID-19 caused things to grind to a halt across the world. I’d been spending some of it playing around with the ZX-UNO I purchased a while back. This is an FPGA recreation of the Sinclair Spectrum family of computers which also has support for the Russian ‘Pentagon 128’ variant – and the ability to simulate other 8 bit micros like the BBC, C64 and Amstrad.
It uses an SD card to provide an emulated DivIDE/DivMMC interface. These are hardware that let you access an IDE drive, Compact Flash or SD Cards on a real Spectrum. The ‘OS’ these devices use is called ESXDOS. This gives you a command driven interface for accessing files on the disk as well as providing a hardware NMI (Non Maskable Interrupt) button which launches a file browser. This works like a freezer cartridge letting you break in at any point to save a snapshot of the currently running program. It can navigate the contents of the disk as well as letting you automatically load .tap files (virtual Spectrum tape images), .sna, .z80 (memory snapshots) and .trd files (virtual Spectrum disk images normally found on Pentagon machines).
For reference, here’s the standard ESXDOS NMI browser:
You’ll notice it doesn’t handle long file names. ESXDOS supports FAT16 and FAT32 file systems but is limited to the old DOS 8.3 style filenames. The files are also listed in the order they appear on the disk – not in alphabetical order. After using this for a while and having forgotten the joys of dealing with an 8.3 filename world, I started to wonder whether it was possible to do a nicer file browser that could somehow support long filenames.
My first attempt was to write a Python script which took a folder on the SD card and read in all the long filenames and wrote them out to a binary file with a special filename in that folder. I then wrote a basic browser program in C that looked for this file and displayed the contents on the screen to show the long filenames. It then converted the long file name on the fly back to the 8.3 form and launched that through ESXDOS. This sort of worked but had several limitations.
Any time you deleted a file, created a folder, added a new file or renamed an existing one you needed to rebuild the special data file to keep everything in sync. I also ran into an issue during development (I’m primarily running Ubuntu these days. Life’s too short for Windows 10 hassle) where I couldn’t easily determine the 8.3 filename from the original long filename. Most of the time, this wasn’t an issue as the majority of the files all mapped to unique 8.3 filenames. The order of files I was getting in my Python script when enumerating a folder wasn’t quite the same as the order on the disk. So I couldn’t be a 100% sure when you had two filenames like ‘Jet Set Willy.tap’ and ‘Jet Set Willy 2.tap’ – which would appear in 8.3 format as JETSET~1.TAP and JETSET~2.TAP – which short filename related to which long filename.
I decided to start again, this time seeing whether I could access the information directly from the FAT file system. Using the supplied ESXDOS dot command .dskprobe (a low level disk utility) I saw it was possible to access the FAT boot sector which was the first step in getting the information I required. At this point, I switched to C and wrote a test console program that loaded in a disk image I had made of the 512MB FAT16 SD card I’d been using with the ZX-UNO.
After reading a few web pages on the FAT file system, a couple of trips to the hex editor to confer with my disk image and lots of trial and error I had located the root folder and could read the directory entries in it. Long filename support on FAT is rather convoluted due to maintaining backwards compatibility with existing software (it uses pseudo invalid 8.3 filename entries to store the additional information). After getting my head round that, I now had some test code which could list the files in a given directory and show long filenames where used.
The browser code I’d written during my first attempt was then modified to use a list of data structure supplied directly from the FAT rather than from the pre-populated binary file – so that wasn’t a complete waste. I had to do a spot of disassembly on the .dskprobe program as the parameters to the ESXDOS API call to access the disk were not particularly well documented. This wasn’t the only time I had to resort to disassembling ESXDOS components during development of the browser. Fortunately, z88dk has ESXDOS support so it’s includes and code filled in a lot of the blanks.
After a couple of days of hacking around with my FAT test program, I’d knocked up a prototype .dot command called .browse using z88dk. The C FAT code from my test program cross compiled without major issues in z88dk (most of the browser was written in C, except for some assembly graphics routines).
Here’s how the initial version 0.01 of .browse looked:
It supported long file names and also sorted the filenames – directories first, then files in A-Z order. The colours were hardcoded so folders appeared in blue and files appeared in black. Launching .tap files was supported – the other formats – .sna, .z80 and .trd weren’t. It was also limited to FAT16. There was no support for FAT32. At this stage it was a bit rough around the edges and lacked some key features but was a good enough proof of concept.
My first go at FAT32 support was added in version 0.02, alongside some fixes to the existing FAT code to handle folders that spanned multiple clusters. I also fixed an issue from the first version where on launching .browse, you were always dumped into the root folder regardless of your current directory before hand. I added some code that took the current directory and located it in the FAT.
On the Spectrum, if you use 8×8 characters in your font you can fit 32 characters on a line. There have been a number of ways to workaround this limitation. Tasword Two, a word processor that shipped with certain editions of the Spectrum 48k+ used a custom font of 4 x 8 to fit 64 characters on to the line. This works but the characters can look poorly defined due to the halved width. A good compromise is custom font of 6 x 8 which gives you 42 characters. I’d seen this used to good effect having played the Adventure International adventure games like Spiderman or Buckaroo Banzai. I decided to go with this to give the browser a bit more space to show filenames. I wrote the 42 column text routine myself in assembly which was a bit of challenge due to the memory layout of the screen on the Spectrum.
Alongside the more compact display, very long filenames were now truncated to the screen width with a custom ellipsis character. I also got .trd files to auto start from the browser after disassembling the .vdisk dot command and ESXDOS NMI browser to see how this was achieved. This was released as v0.03 and was the point when I noticed I was starting to get traction with the project. I’d started a topic on the Spectrum Computing website forum and was getting replies and feedback. From this, I discovered that my FAT code had a number of issues. On some configurations the browser just showed a blank screen and failed to start or listed the root folder correctly but showed empty sub folders or folders full of garbage characters.
v0.04 had a fix for the FAT16 problem where empty or garbage folders were being displayed rather than the actual contents. I also added the ability to load .z80 and .sna files using the ESXDOS .snapload dot command.
A user asked for the ability to change the colour scheme so I wrote a separate configuration editor program to adjust the colours. I also added the ability to specify the ESXDOS device identifier to use for directly accessing the disk in the browser for configurations with multiple disks or partitions. This was released in version 0.05 alongside some more FAT fixes – I wasn’t handling FAT32 clusters correctly which meant that files on larger drives with clusters greater than 65536 were returning empty folders or garbage folder listings. To my knowledge the FAT code is now working correctly (famous last words).
The hopeful finalisation of the FAT code seems like a good point to pause the story of developing the browser. There’s a lot of other things to go through – replacing the NMI, hitting the limit of .dot commands and accessing the ZX-UNO turbo modes – but that’s for another post.