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 <image file> [options] [file name] [output file] Options: v - Verbose l - List directory 1 - List directory as single column x - Extract file t - Convert to clean ASCII text d - Print SIR/DIR sector dumps Output file "-" means console (stdout) Version 1.0 by Daniel Tufvesson 2015 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.TXT t01 s01 - t02 s06 26 83-02-23 00 FILE2.TXT t02 s07 - t02 s13 7 83-02-23 00 $ Extracting the file "FILE1.TXT" from image "image.dsk" and save as "/tmp/file1.txt": $ flextract image.dsk x FILE1.TXT /tmp/file1.txt Previewing a file on screen (export to stdout): $ flextract image.dsk xt FILE1.TXT - This a file that is stored on the disk image Adding the "t" option ensures that end of line markers are compatible and that only "safe" ASCII characters are exported $ Since there a a lot of different ways of encoding text files I have included the "t" option to parse files as ASCII and try to make them readable regardless of the end of line format of other non-readable codes. It works well for most plain text files such as assembly sources.

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


Write a comment

Name

E-mail (not visible)

Comment


Code from above