Reading FLEX disk images
In my quest for better knowledge of the FLEX disk operating system for the 6800 and 6809 I ended up needing to read old floppies and disk images. Images usually have the *.dsk extension and contains a raw dump of every sector on a disk. No header or other information. I found a few tools that could read raw FLEX images but they were mostly written for Windows and without source. Therefore I began digging into the FLEX disk structure with the goal of creating my own tool that could read raw FLEX images and extract individual files.

FLEX disk layout

FLEX has a hard coded sector size of 256 bytes. Addressing sectors are done by track and sector numbers. Maximum number of tracks are 256 and maximum number of sectors per track are 256, which means a single FLEX file system can be up to 256^3 bytes which is about 16MB raw capacity. Not very big by todays standards but 30 years ago this was huge. The sectors are linked together like linked lists where the first two bytes of each sector is a pointer to the next sector in the chain (actually some sectors on track 00 are exceptions from this but for the rest of the disk this is true). The first two bytes of every directory sector and file data sector contains the track and address of the next sector in the chain. End of chain is marked by setting track and sector to zero. A typical FLEX disk layout for a 40 track floppy with 20 sectors on each track: TRACK 00 SECTOR 00 --- Boot sector TRACK 00 SECTOR 01 --- Boot sector TRACK 00 SECTOR 03 --- System Information Record (SIR) TRACK 00 SECTOR 04 --- Not used TRACK 00 SECTOR 05 --- Start of directory . . TRACK 00 SECTOR 20 --- End of directory TRACK 01 SECTOR 01 --- Start of file data . . TRACK 39 SECTOR 20 --- End of file data (last sector on disk) The first sectors are boot sectors that contain executable code for loading the FLEX kernel from disk and booting the system. They can be ignored by the image reader and non-bootable disks. Tracks appears to be numbered from zero and up, and sectors from one and up. The boot sectors are exceptions from this and appears to be numbered 00 and 01. Track 00 has no sector 02. The first important sector is the System Information Record (SIR). The SIR contains basic information about the disk structure. After the SIR follows the directory sectors. The directory sectors are linked together to form one chain and the file data sectors are linked together to form another chain. The length of the directory can be varied and can span over multiple tracks if needed. The size of the directory is however determined when initializing the disk and it can usually not be changed at a later time. Below is the structure of the System Information Record (SIR). 11 byte --- Volume label 2 byte --- Volume number 1 byte --- First free track 1 byte --- First free sector 1 byte --- Last free track 1 byte --- Last free sector 2 byte --- Number of free sectors 1 byte --- Date month 1 byte --- Date day 1 byte --- Date year 1 byte --- End track 1 byte --- End sector The SIR structure is 24 bytes long and starts at byte 17 of the SIR sector. The first 16 bytes of the SIR sector is not used. The directory structure (DIR) follows a similar pattern. 8 byte --- File name 3 byte --- File extension 2 byte --- Not used 1 byte --- Start track 1 byte --- Start sector 1 byte --- End track 1 byte --- End sector 2 byte --- Total number of sectors 1 byte --- Random file flag 1 byte --- Not used 1 byte --- Date month 1 byte --- Date day 1 byte --- Date year The DIR structure is also 24 bytes long. Just as with the SIR sector the first 16 bytes of every directory sector is not used. The DIR structure is repeated 10 times for each directory sector until the end of the sector chain has been reached (all directory sectors does have the 16 byte padding at the start). One thing that had me puzzled for a while is how FLEX actually marks a file as "deleted" in the directory. After some trial and error I have discovered that deleted file entries are marked by setting the file first byte of the file name to either 0x00 or 0xFF. Another thing that had me scratching my head was the flag byte. It is used for FLEX "Random files". I have not implemented support for this file type so the flag is simply ignored but displayed. Each DIR structure contains a pointer to the first sector of the file it represents. Reading a file is a matter of simply walking the sector chain starting at the sector mentioned in the DIR structure. Each data sector has the structure below. 1 byte --- Next track 1 byte --- Next sector 2 byte --- Sector sequence number 252 byte --- File data Every sector contains a pointer to the next sector in the file, a sequence number and 252 bytes of actual file data. End of chain (and end of file) is marked by setting next track and next sector values to zero. The sequence number is a 16 bit value starting at 1 and is increased by 1 for every sector in the file. It can be used as as simple verification that the file chain appears to be correct. The last sequence number on the last sector of the file should have the same value as the total sectors value of the DIR structure.

The FLEXTRACT program

With this knowledge I began writing my FLEX image file extractor. I call it FLEXTRACT. It's a single C file that can be compiled under GCC. Source code: flextract.c Compilation and installation under Linux: $ gcc flextract.c -o flextract $ sudo cp flextract /usr/local/bin/ Running the program without options displays basic usage information: $ flextract Usage: flextract [options] [file name] [output file] Options: v - Verbose l - List directory 1 - List directory as single column x - Extract file t - Do FLEX text to ASCII conversion d - Print SIR/DIR sector dumps Output file "-" means console (stdout) Version 1.5 by Daniel Tufvesson 2015-2020 Displaying image contents: $ flextract image.dsk Image size is 204800 bytes - 40 tracks, 20 sectors/track Volume label DISK01 Volume number 0000 Free area t2 s14 - t39 s20 Free sectors 766 End sector t39 s20 Creation date 83-02-23 NAME START END SIZE DATE FLAG FILE1.BIN t01 s01 - t02 s06 26 83-02-23 00 FILE2.TXT t02 s07 - t02 s13 7 83-02-23 00 $ Extracting the binary file "FILE1.BIN" from image "image.dsk" and save as "/tmp/file1.bin": $ flextract image.dsk x FILE1.BIN /tmp/file1.bin Extracting the text file "FILE2.TXT" from image "image.dsk" and save as "/tmp/file2.txt": $ flextract image.dsk xt FILE2.TXT /tmp/file2.txt Previewing a file on screen (export to stdout): $ flextract image.dsk xt FILE3.TXT - This a file that is stored on the disk image Adding the "t" option ensures that the file is treated as a FLEX text file. $ 2020 UPDATE: As pointed out by Soren and Alan I have adopted flextract to read FLEX text files more properly now. The "t" option converts the file by stripping out non printable control characters as well as handling the FLEX space compression. FLEX compresses occurrences of consecutive spaces by using a form of run length compression. A 0x09 byte (normally used for tab nowadays) is written to the file followed by another byte determining the number of spaces to be printed.

Executable CMD files

Program files that are executable are a little special. They are stored in FLEX CMD format which is the executable data divided into chunks, each chunk containing its own a load address. This is a flexible solution since it makes it possible to load a single file into different parts of memory before execution. When dealing with the file outside FLEX it's however a bit tricky since CMD files cannot be treated as RAW binary dumps of a program. In order to strip a CMD file of everything but the program code I also had to write the CMD2BIN converter. Source code: cmd2bin.c Compilation and installation under Linux: $ gcc cmd2bin.c -o cmd2bin $ sudo cp cmd2bin /usr/local/bin/ $ cmd2bin Usage: cmd2bin <infile.cmd> <outfile.bin> [start address] [stop address] cmd2bin automatically detects non-continuous parts of the CMD file, which is marked by an extra blank line. $ cmd2bin PROGRAM.CMD PROGRAM.BIN Converting 0000 to FFFF Address: 0100-01C3 Length: 196 Address: 01C4-0287 Length: 196 Address: 0288-034B Length: 196 Address: 034C-040F Length: 196 Address: 0720-07E3 Length: 196 Address: 07E4-08A7 Length: 196 Address: 08A8-096B Length: 196 Address: 096C-0A2F Length: 196 Address: 0A30-0AF3 Length: 196 Address: 0AF4-0BB7 Length: 196 Address: 0BB8-0C7B Length: 196 Address: 0C7C-0D3F Length: 196 Address: 0D40-0E03 Length: 196 Address: 0E04-0E87 Length: 132 $ In the example above PROGRAM.CMD loads into two parts of the memory. Using cmd2bin the program can be exported into separate files for each memory segment. First 0100-040F: $ cmd2bin PROGRAM.CMD PROGRAM_0100.BIN 0100 040F Converting 0100 to 040F Address: 0100-01C3 Length: 196 Address: 01C4-0287 Length: 196 Address: 0288-034B Length: 196 Address: 034C-040F Length: 196 $ Then 0720-0E87: $ cmd2bin PROGRAM.CMD PROGRAM_0720.BIN 0720 0E87 Converting 0720 to 0E87 Address: 0720-07E3 Length: 196 Address: 07E4-08A7 Length: 196 Address: 08A8-096B Length: 196 Address: 096C-0A2F Length: 196 Address: 0A30-0AF3 Length: 196 Address: 0AF4-0BB7 Length: 196 Address: 0BB8-0C7B Length: 196 Address: 0C7C-0D3F Length: 196 Address: 0D40-0E03 Length: 196 Address: 0E04-0E87 Length: 132 $

Summary

Both FLEXTRACT and CMD2BIN has proven very useful to me and hopefully someone else will find them useful as well. They work fine for both FLEX 2 and FLEX 9 images (6800 & 6809). It feels very nice to have a non-windows way of dealing with FLEX images. With this I can only read and not create images but it's a good start!
by Neal 2015-06-11 22:45 UTC
Thanks for a well-written article and two very useful utilities. I performed a port of FLEX from scratch (https://github.com/nealcrook/multicomp6809) and your description and your utilities were both very helpful to me. I think they made a lot of very good design decisions with FLEX. The linked-list files, the boot process and the binary format are all simple but elegant solutions.


by Daniel 2015-06-29 11:14 UTC
Rally cool project Neal! Fun to see others are working on new FLEX projects. I totally agree with you about the very simple and yet powerful design of FLEX in many ways. Some very good decisions was indeed made. Also that they kept the file system compatible between FLEX 2 and FLEX 9 is really great!


by Alan 2015-08-14 08:56 UTC
Great applications Daniel and a real neat web-page. I recently restored my 6809 Microtan and these apps have now made a whole host of software available to me. Many thanks.


by Daniel 2015-09-08 15:42 UTC
Thank you for the kind words Alan! I'm glad you found my tools and site useful :)


by Alan 2016-12-03 19:44 UTC
Thanks - just what I needed to unpack some ancient source code


by Soren 2019-11-23 13:39 UTC
I have been working to recover Stylograph for OS-9 and I found your page while looking for ways to read FLEX images containing Stylo code. It saved my day. However, I think that flextract doesn't handle the 0x09 code correctly in texts. It works much better if the following byte determines how many spaces to generate. I was able to compare two texts that both exist in FLEX and OS-9. I can send you the modifications to flextract.c


by daniel 2020-05-16 20:49 UTC
Thank you Soren for pointing this out! I have now updated flextract to properly handle FLEX text files.


by Martin gren 2020-06-14 21:37 UTC
Hej, antar du ör svensk! Jag är en stor 6809 fan och Axis byggde på 6809 första 5 åren. Jag har massor med 5 1/4 tum Flex diskar. Vad har du för hårdvara när du läser diskarna ? Det ser ut som en linux, hur kopplar du en gammal disk dit? Jag vill göra om mina flex diskar till dsk filer jag kan spara, samt såklart få ut dem också. Jag har fått igång mitt gamla flex system, fungerar bra! Fick byta power supply först bara.....


by Daniel 2020-06-15 19:21 UTC
Hej! Kul att du fått igång ditt system! Som du säger, lite översyn av strömförsörjning och eventuellt lite nya kondingar här och var så går de ofta fint fortfarande. Visste inte att Axis hade historisk koppling till 6809. Riktigt kul! För att läsa gamla diskar har jag använt mig av lite olika lösningar. Eftersom FLEX i regel använder FM/MFM så går diskarna att läsa i många andra system. På senare tid har det dykt upp några bra alternativ. Till att börja med (för ca 15-20 år sedan) skrev jag en rutin till FLEX 2.0 (6800) som ihop med en WD1771 kontroller läste sektor för sektor och skickade datat över till en PC via RS-232. Det var lite pyssel, långsamt och krävde att diskarna var i relativt gott skick. Efter det gick jag över till att läsa diskar direkt via en PC med hjälp av Dave Dunfields program ImageDisk (http://www.classiccmp.org/dunfield/img/index.htm) och en gammal diskdrive. Det fungerar väldigt bra men kräver en PC modell lite äldre och körs bäst direkt under DOS (jag kör en gammal 386:a till just detta). För en lite modernare lösning rekommenderar jag KryoFlux (https://www.kryoflux.com/). Tar liten plats och stödjer i princip allt med Shugart-interface. Oavsett lösning så behövs en eller flera gamla diskdrivar, en DD och en HD 5 1/4 tum till exempel, och var beredd att hålla läshuvudena rena med tops och IPA :)


by Create FLEX disk images 2020-07-04 20:21 UTC
Hello, I search to save my FLEX disk on my Windows computer . Where can I find an utility to do that et also to re-create disk from disk image ? Thanks. Regards,


by Daniel 2020-07-05 10:41 UTC
Hi! I recommend the KryoFLux for this. It can both read and write images to and from any floppy with standard Shugart interface. It has become my universal disk imaging tool. Checkout https://www.kryoflux.com/ A cheaper alternative may be the Greaseweazle (https://github.com/keirf/Greaseweazle) if you don't mind the extra work assembling it. The software part is less polished but if you are a fan of Python this may be for you. In my opinion, if you are preserving old disks, get the KryoFlux. It's is proven to be reliable and widely used. With old media you don't get that many chances to get it right before the disk surface may be gone for ever. On the other hand, for creating new disks with no risk of data loss then go ahead and tinker with cheaper alternatives.


by Vlad 2021-09-24 22:29 UTC
I am wondering if you managed to run Flex on your MC3. I am also building SBC with HD6303, but I am worry the fact that MCU is using addresses 0 - 20h for its registers might be issue with Flex. It cannot be re-mapped to other addresses.


by Mark C 2024-01-28 12:08 UTC
great info Daniel, I am porting FLEX2 to an ET-3400 with a Compact Flash interface, and while researching I found your article. I think there is an error at in the first section where you describe: "A typical FLEX disk layout for a 40 track floppy with 20 sectors on each track: TRACK 00 SECTOR 00 --- Boot sector TRACK 00 SECTOR 01 --- Boot sector TRACK 00 SECTOR 03 --- System Information Record (SIR) TRACK 00 SECTOR 04 --- Not used TRACK 00 SECTOR 05 --- Start of directory . . TRACK 00 SECTOR 20 --- End of directory TRACK 01 SECTOR 01 --- Start of file data . . TRACK 39 SECTOR 20 --- End of file data (last sector on disk)" I think the sector numbers are from 01 to 20, not 00 to 20 as it shows for track 00, however I am not certain so you might need to confirm this. This is one area I've been trying to confirm for my port. regards, Mark C in Oz


by Neil Cherry 2024-02-04 04:25 UTC
Mark C, Tracks start at 0 and go to 255, Sectors start at 1 (the number 0 is reserved). Check the Flex manuals. :-) I know I've seen you on the ET-3400 mail list, also check out the FuFu (Flex Users Group) mailing list.


by Neil Cherry 2024-02-04 15:03 UTC
Mark C, this might be of use but the Flex documents provide more details http://archive.retro.co.za/archive/computers/Flex%20Explained.pdf


by Mark C 2024-02-21 08:20 UTC
Neil, thanks for the link. I've seen some of your posts on the ET-3400 group. I wasn't able to clarify my observation in that article either, but after working on this for quite a while now I came to the same conclusion of tracks starting at 00 and sectors starting at 01, which indicates to me there is a small error in Daniels disk layout table at the top of the article. Instead of sector numbers 00, 01, 03, 04, 05 ... 20, it should read 01, 02, 04, 05, 06 ... 20. I've also confirmed this when looking at dozens of disk image files for FLEX. At no stage do any TS links use a Sector number of 00, except when the last TS link to a file or directory etc. is inserted. As far as Sector reference of 00, although you mention it is reserved probably just to mark the last TS sector. In my implementation I am trying to use that to refer to sector #256 to make the math routines a bit faster for some new HDD disk geometries I am using, but until I get as far as running Flex and creating the disk drivers, I don't know if this will pass any FLEX filters. I'm not a member of the Flex UG as yet, but I've just submitted an application.


by Daniel 2024-02-21 08:31 UTC
Thank you for dropping by! Very interesting questions. It's been quite a while now since I worked on this but from what I recall FLEX sectors indeed generally start at 01 with the exception of the first track 00 which has a sector 00 as well. This is done to be compatible with most ROM boot routines. Most of them are pretty rudimentary and just reads the first two sectors from the disk into memory starting at track 00 sector 00. That's the reason for the 00 sector on the first track but not the others. If they started the sector numbering at 01 most boot routines would have to be patched for FLEX compatibility. Hope I remembered this correctly. I'll do some more reading as well.


by Mark C 2024-02-24 16:46 UTC
hi Daniel, I think that some people or documents may refer to it as sector 00 on track 00, but they mean the first sector (01) on track 00, otherwise there is more sectors/track than the other tracks on the disk. You wouldn't have 21 sectors on track 00 and 20 on the rest of the tracks as they probably wouldn't fit. I've also found that some real floppy disks have Single Density and half the number of sectors for track 00 so it can be booted by lower density drives. However this doesn't apply to a CF card. I've avoided those disk images at the moment because my NEWDISK program would be more complicated than it already is. However I think that I could insert 00 bytes to push it out to make it the same as a double density layout. Mark C.


by roelof 2024-02-25 15:04 UTC
Nice job! According to the TSC adaptation guide first tracks are always written in single density (FM recording). Following tracks can be single density of double density. FLEX detects double density during reading and changes over. For double density usually (on a 5" floppy at least) typically there are 16 or 18 sectors per side which compares to 10 sectors per side for single density (track0). A small modification of the code will do the trick to include this type of discs.


Write a comment

Name or handle

E-mail (optional and not visible to others)

Comment


Code from above