Yellow Pig's BBC Computer Pages

Native BBC Computer Items

Master 512 | Native | General | Index | Home

Details of BBC ADFS Floppy Disk Format

The following describes the logical structure of ADFS floppy disks for the BBC Computer. (Note that some of the detail in the New Advanced User Guide is incomplete or wrong.)

ADFS files have names of up to 10 characters. There is a hierarchical directory structure. As always on BBC filing systems, the root directory is called "$". Sub-directories, like files, have names of up to 10 characters. A directory can hold up to 47 entries (files or sub-directories).

Every file has associated with it a "Load address" and an "Execution address". There are also four attributes: "W", "R", "L" and "E", meaning "Write enable", "Read enable", "Locked" and "Execute only".

In addition, a "cycle number" is kept for each entry in each directory. This is a number which is incremented and stored in association with the appropriate item, each time one is modified. The cycle numbers are displayed by *CAT, and they give an indication of which files in a directory have been modified most recently, but otherwise they serve no useful purpose.

There are three sizes of disks: Small (160k), Medium (320k) and Large (640k). "Small" means single-sided 40-track disks, "Medium" single-sided 80-track, "Large" double-sided 80-track. (The ADFS system does not cater for double-sided 40-track disks.)

Each disk has a "boot option", a number between 0 and 3 indicating the action to be taken when the disk is booted using Shift/Break.

Note that here BBC terminology is used for number formats, ie hex numbers are preceded with an "&".

Main Structure

     

ADFS disks are recorded using double-density. They have a sector size of 256 bytes, with 16 sectors per track, numbered on each track from 0 to &F.

Logically the sectors on the disk should be considered as a single sequence, starting at logical sector 0, incremented in the order: sector - track - side. (So first are the sectors on side 0, track 0, then side 0, track 1, etc. For "Large" disks (which use two sides) side 0, track 79 is followed by side 1, track 0.)

The data is divided into three areas. All are made of whole numbers of sectors, and they occur in the following order:

     

1. Free Space Map – 2 sectors (Sectors 0 and 1)

2. Root directory – 5 sectors (Sectors 2 to 6)

3. Data area: Files and sub-directories.

There are no gaps between the sections, so the data area starts at sector number 7.

Note: In all that follows multi-byte numbers are always stored low byte first. Sector numbers, etc, in fact never exceed two bytes for floppy disks, but three bytes are allowed to cater for hard disks.

1. Free Space Map

     

Items (files and sub-directories) are stored in ADFS as contiguous pieces of data. They cannot be broken up into sections occupying different parts of the disk. However the system needs to keep track of which sectors are in use, and this is done by means of the "Free Space Map" (or "FS Map").

The FS Map provides a list of those sectors which are not currently in use. They are listed as blocks of sectors, with starting sector and size of free block.

There are a few other items stored in this area as well. In detail the map is laid out:

Sector 0

     
Byte(s)
   
Meaning
                            
  0 - &F5  

Start sector of each free-space block. Three bytes per entry, so bytes 0-2 for the first block, 3-5 for the second, etc. This allows a maximum of 82 blocks of free space.

Note:

      The size of each block is stored in Sector 1
 
 
  The end of the list is defined by the pointer at location &FE in Sector 1.
 
 
  There may be remnants of former disk states in later bytes in the sector but these are of no significance.  
       
  &F6 - &FB   0
       
  &FC - &FE   Total number of sectors on disk (S - &280; M - &500; L - &A00)
       
  &FF   Sector checksum (= [sum-with-carry of bytes &FE to 0] MOD &100. Ie the bytes are added together, starting at the top of the sector, each time using an ADC instruction with no CLC between, so the carry bits (except for the last one) are included. The result is stored in this byte.)

Sector 1

     
Byte(s)
   
Meaning
                            
  0 - &F5   Size of each free-space block in number of sectors. As with Sector 0, three bytes per entry, so bytes 0-2 for the first block, 3-5 for the second, etc.
       
  &F6 - &FA   0
       
  &FB,&FC   Disk identifier. These bytes are apparently random (probably constructed from the system time) and written to the disk every time a change is made. The result is that they are always different for any two disks, even when one has been copied track-by-track from the other. This enables the system to recongnise when the disk has been changed.
       
  &FD   Boot option number
     
  &FE   Pointer to end of free space list. This points to the byte offset (in both these sectors) beyond the end of the free space list. It is thus 3 times the number of free space blocks in the FS Map.
       
  &FF   Sector checksum (as in the previous sector)

2. Directory Structure

     

Each directory is stored as a block of 5 sectors, ie &500 bytes. The root directory takes up sectors 2 to 6, others are elsewhere on the disk. A block of data is a sub-directory (rather than a file) if the top bit is set in byte 3 of its own entry in its parent directory. There are also identifiers within the structure, in particular the directory identifier string stored twice at location offsets 1 and &4FB

The overall layout is as follows (a few items are not relevant for the root directory):

     
Byte(s)
   
Meaning
                              
  0   Cycle number for directory (stored in "Binary coded decimal" (BCD) format)
     
  1 - 4   Directory identifier string. This always reads "Hugo", ie the 4 bytes &48,&75,&67,&6F, and is a way of identifying the block of data as a directory.
       
  5 - &4CA   Directory entries. Each entry takes up 26 (&1A) bytes, and there is room here for 47 entries. (See below for details of each entry)
       
  &4CB   0
       
  &4CC - &4D5   Directory name. For the root directory this is the single character "$", and the remaining bytes are zeros. For other directories it is the name in ASCII, terminated with &D if it is less than 10 bytes long. (There is no &D terminator for the root directory nor for names taking up the full 10 bytes.)
       
  &4D6 - &4D8   Start sector of parent directory (Note: For the root directory this is set to 2, so it points to itself – an attempt to move up the tree from the root directory stays at the root.)
       
  &4D9 - &4EB  

Directory title. (Each directory can have a "title" as well as a "name". It is defined by *TITLE and displayed by *CAT, but otherwise is non-functional.) The string is terminated with &D if it does not fill the whole 19-byte block, except for the original value for the root directory when it is just "$" followed by zeros.

       
  &4EC - &4F9   0
       
  &4FA   Cycle number for directory (stored in BCD format) – same as byte 0
     
  &4FB - &4FE   Directory identifier string. Again the string "Hugo", the same as bytes 1 - 4.
       
  &4FF   0

Each directory entry takes up 26 (&1A) bytes, and has the following format:

     
Byte(s)
   
Meaning
                          
  0 - 9   Name and attributes (see below)
       
  &A - &D   Load address
       
  &E - &11   Execution address
       
  &12 - &15   File length (in bytes)
       
  &16 - &18   Start sector
       
  &19   Cycle number

Note that sub-directory entries have load and execution addresses both set to 0, and file length set to &500.

Names and Attributes

     

Characters in file and directory names must be standard ASCII (values between &21 and &7E – "top bit set" characters are not allowed, and various other characters (such as ".") will confuse the system so should not be used). The names are terminated with &D or a zero byte, unless they fill the whole space allocated to them.

The top bits of the first five bytes of the name (extending beyond the end of the name if it is shorter than 5 characters) are used for attributes as follows. In each case the attribute is set if the bit is 1, clear if it is 0.

      Byte     Meaning if top bit is set        
       
    0      R – Can be read
       
    1      W – Can be written to
       
    2      L – File locked
       
    3      Item is a subdirectory
       
    4      E – Execute only

Sub-directories

     

A sub-directory is a data item like a file, the only difference being that the "directory" bit (top bit of byte 3) is set in its own directory entry.

The structure of a sub-directory is exactly the same as the root directory.

3. Data Area

     

The file data and sub-directory entries are stored on the rest of the disk, starting at Sector 7.

Master 512 | Native | General | Index | Home