qdosmsq:fs:dsdd

QL Floppy Discs

This section gives some information on QL floppy discs, I have found much of it by exploration although some came from the MMSE manual and some from Simon Goodwyn and the DIY Toolkit series in QL WORLD.

This section only covers the DS/DD 720 KB and DS/HD 1.4 MB floppy discs known as QL5A and QL5B. There is/was a 3.2 Mb floppy format known as DS/ED but these proved to be, sadly, short lived as they never were accepted by the PC market, so died off rather quickly.

There will be a section added, at some point, describing these enhanced discs.

The very first sector af any QL disc holds the first map sector. There are either 3 or 6 map sectors depending on the disc foramt. A QL5A formatted disc has 3 sectors while a QL5B has 6.

Sector 1 of the map contains 96 bytes of disc information as follows :

ByteSizeDescription (Byte & size are in HEX)
0004Header flag QL5A or QL5B.
040AMedium name space padded.
0E02Format random number.
1004Update counter for this disc.
1402Free sector count.
1602Good sector count.
1802Total sector count.
1A02Number of sectors per track, default = 9.
1C02Number of sectors per cylinder, 9 (Single sided) or 18 (Double sided).
1E02Number of tracks per disc, 40 or 80.
2002Number of sectors per block, default = 3 (For QL5A and QL5B discs).
2202Block number of the directory end of file.
2402Byte in block of directory end of file ( plus 1).
2602Sector offset per track, default = 5.
2812Logical → physical translation table.
3A12Physical → logical translation table.
4C14Spare bytes, currently unused.

The remaining 416 bytes make up the first part of the map for this disc.

The format random number is used to detect when the disc has been swapped.

The update counter is used to detect when the disc has been removed, put into another drive, updated & then returned to the original drive.

The sector offset is used to allow for some sectors passing under the heads when the drive has to step from the current track to the next one. This means that logical sector 0 is physical sector 3 on track 0, 6 on track 1 or 9 on track 2 etc, of course, physical tracks number from 1 to 9 while the logical ones are from 0 to 8 just to confuse matters.

As stated above, the map is always 3 sectors (QL5A) or 6 sectors (QL5B) , the first being the very first sector on the disc, the positions of the other sectors are held in byte 42 and byte 43 of the first sector (starting from 1, not 0) plus 1, or in a SuperBasic string holding the first sector CODE(sector$(42)) + 1 and CODE(sector$(43)) + 1.

The remainder of the map holds information about the current whereabouts of each file on the disc. There are 480 (QL5A - DS/DD 720KB) or 960 (QL5B - DS/HD 1.4MB) allocation units or blocks in the map.

Each allocation unit is 24 bits in length, the first 12 bits hold the file number on the disc, the last 12 bits hold the block number within the file (starting at 0) as follows :

The allocation unit details are stored sequentially in the map. Allocation unit 0 is the first one and 479 (or 959) is the last one.

There are values used by the QL for its own internal workings, these are held in the first 12 bits only and the last 12 bits are ignored.

The root directory always has file number $000 in its map block entries.

The map itself is always file number $F80 in the map. The first entry in every map is that of the map itself. The next entry is always the root directory - file zero.

  • Blocks pending a deletion are held as file number $FCx.
  • Free blocks are held as file number $FDx.
  • Bad blocks are held as file number $FEx.
  • Blocks that do not exist are held as file number $FFx.

Note: the lower 4 bits of the file number are not used for the last 3 of these and may be undefined. My own experience shows that they are probably $F.

An allocation block which has a file number between $001 and $F7F will belong to a user file, although a DS/HD disc can only have 960 files on it as an absolute maximum, so you are highly unlikely to see file numbers above $3C0.

The sectors making up the map are as follows:

+----------+------------------+------------------------------+-----------------------------+
|0       95|96             511|512                           |1024                     1535|
+----------+------------------+------------------------------+-----------------------------+
| Header   | Map (480 entries)                                                             |
+----------+------------------+------------------------------+-----------------------------+
| 96 Bytes | 416 bytes        | 512 bytes                    | 512 bytes                   |
+----------+------------------+------------------------------+-----------------------------+
| Sector 0                    | Sector 1                     | Sector 2                    |
+----------+------------------+------------------------------+-----------------------------+

A QL5A disc has 480 map entries (three bytes each) plus a 96 byte header making exactly three 512 byte sectors.

+----------+------------------+------------------------------+-----------------------------+
|0       95|96                |512   |1024   |1536   |2048   |2560                     3071|
+----------+------------------+------------------------------+-----------------------------+
| Header   | Map (960 entries)                                                  | Unused   |
+----------+------------------+------------------------------+-----------------------------+
| 96 Bytes | 416 bytes        | 512 bytes each = 2048 bytes  | 416 bytes        | 96 Bytes |
+----------+------------------+------------------------------+-----------------------------+
| Sector 0                    | Sectors 1 through 4          | Sector 5                    |
+----------+------------------+------------------------------+-----------------------------+

A QL5B disc has 960 map entries (three bytes each) plus a 96 byte header making six 512 byte sectors in all but with the final 96 bytes of the last sector unused.

The unit number must be in range 0 to 479 or 959 depending on disc type.

The TRACK number is the UNIT DIV 6.
The logical BLOCK number is the UNIT MOD 6.

This gives TRACK from 0 to 79 and logical BLOCK within TRACK as 0 to 5.

The offset into the Logical → Physical table for this logical block is:

(logical block * 3) + 1

assuming you are in basic and count from 1 otherwise lose the 1.

The sector numbers for this logical block are the bytes at offset 0,1 & 2 from the offset into the Logical → Physical table (follow ?).

Now for each sector number, if it is greater or equal to 128, then the side is 1 and the sector = sector - 128, otherwise the side is 0.

This is fine if we are still on track 0, however, as mentioned above, there is a track offset to be taken into account as follows :

(adjusted sector + (TRACK * track offset)) MOD 9

as this gives a 0 to 8 number, add 1 to get a true sector number of 1 to 9.

Now you have a SIDE, TRACK and 3 sectors for this allocation unit. Easy.

Alocation unit 423:

TRACK     = 423 DIV 6 ===> 70.
BLOCK     = 423 MOD 6 ===>  3.
LP_OFFSET = (BLOCK * 3) + 1 ===> 10.

Assume that the LP table has bytes $81, $84 & $87 at LP_OFFSET:

SIDE = 1
SECTORS = 1, 4 and 7.

As above, the sector offset is 5 (normally)

So the actual sectors on track 70 of side 1 are :

(1 + (70 * 5)) MOD 9) ====> 8
(4 + (70 * 5)) MOD 9) ====> 2
(7 + (70 * 5)) MOD 9) ====> 5

Therefore, the 3 sectors of the disc that are used by the file are located at

SIDE 1, TRACK 70, SECTORS 8, 2 and 5 (in that order).

The file in question is of course unknown, but if you take the 24 bits held in the 3 characters of the map that relate to this allocation unit and convert them into hex, you will get something like $007002 which means that the actual file number is 7 and the block within the file is 2.

If the file number is not a 'special' as listed above, then the file name is found as follows :

DIR_OFFSET = (File number - 1) * 64

it appears that there is no way to access the directories own information from the directory, hence the minus 1.

The next 64 bytes of the directory hold all the information for that file, including its name, dataspace, type etc etc.

The first 64 bytes of each files very first sector contain a copy of the file header, this is never ever ever updated by the QL, so is of no use at all. All it does is waste 64 bytes per file and eventually, as the disc gets used and files deleted with others saved, these 64 bytes seem to contain what ever data was on the disc when the file was written to the sector.

When a file gets deleted, its map entries have the first byte set to $FD, the other information in the map does not seem to be affected. This is slightly unfortunate as it means that an UNDELETE program could not be entirely successful as there could be more than one file in the map which had been deleted from the disc.

  • qdosmsq/fs/dsdd.txt
  • Last modified: 2010/05/10 09:37
  • by norman