Next: The D82 disk image format, Previous: The D81 disk image format, Up: The emulator file formats [Contents][Index]

### 17.9 The D80 disk image format

(This section was contributed by Peter Schepers and slightly edited by Marco van den Heuvel.)

This is a sector-for-sector copy of an 8050 floppy disk. The file size for an 8050 image is 533248 bytes. It is comprised of 256-byte sectors arranged across 77 tracks, with a varying number of sectors per track for a total of 2083 sectors. Track counting starts at 1 (not 0) and sector counting starts at 0 (not 1), therefore a track with 29 sectors will go from 0 to 28.

The original media (a 5.25" disk) has the tracks laid out in circles, with track 1 on the very outside of the disk (closest to the sides) to track 77 being on the inside of the disk (closest to the inner hub ring). Commodore, in their infinite wisdom, varied the number of sectors per track and data densities across the disk to optimize available storage, resulting in the chart below. It shows the sectors/track for a D80. Since the outside diameter of a circle is the largest (versus closer to the center), the outside tracks have the largest amount of storage.

Track Range | Sectors/track | # Sectors
1-39 | 29 | 1131
40-53 | 27 | 378
54-64 | 25 | 275
65-77 | 23 | 299

Track | #Sect | #SectorsIn | D8x Offset
1 | 29 | 0 | $00000
2 | 29 | 29 | $01D00
3 | 29 | 58 | $03A00
4 | 29 | 87 | $05700
5 | 29 | 116 | $07400
6 | 29 | 145 | $09100
7 | 29 | 174 | $0AE00
8 | 29 | 203 | $0CB00
9 | 29 | 232 | $0E800
10 | 29 | 261 | $10500
11 | 29 | 290 | $12200
12 | 29 | 319 | $13F00
13 | 29 | 348 | $15C00
14 | 29 | 377 | $17900
15 | 29 | 406 | $19600
16 | 29 | 435 | $1B300
17 | 29 | 464 | $1D000
18 | 29 | 493 | $1ED00
19 | 29 | 522 | $20A00
20 | 29 | 551 | $22700
21 | 29 | 580 | $24400
22 | 29 | 609 | $26100
23 | 29 | 638 | $27E00
24 | 29 | 667 | $29B00
25 | 29 | 696 | $2B800
26 | 29 | 725 | $2D500
27 | 29 | 754 | $2F200
28 | 29 | 783 | $30F00
29 | 29 | 812 | $32C00
30 | 29 | 841 | $34900
31 | 29 | 870 | $36600
32 | 29 | 899 | $38300
33 | 29 | 928 | $3A000
34 | 29 | 957 | $3BD00
35 | 29 | 986 | $3DA00
36 | 29 | 1015 | $3F700
37 | 29 | 1044 | $41400
38 | 29 | 1073 | $43100
39 | 29 | 1102 | $44E00
40 | 27 | 1131 | $46B00
41 | 27 | 1158 | $48600
42 | 27 | 1185 | $4A100
43 | 27 | 1212 | $4BC00
44 | 27 | 1239 | $4D700
45 | 27 | 1266 | $4F200
46 | 27 | 1293 | $50D00
47 | 27 | 1320 | $52800
48 | 27 | 1347 | $54300
49 | 27 | 1374 | $55E00
50 | 27 | 1401 | $57900
51 | 27 | 1428 | $59400
52 | 27 | 1455 | $5AF00
53 | 27 | 1482 | $5CA00
54 | 25 | 1509 | $5E500
55 | 25 | 1534 | $5FE00
56 | 25 | 1559 | $61700
57 | 25 | 1584 | $63000
58 | 25 | 1609 | $64900
59 | 25 | 1634 | $66200
60 | 25 | 1659 | $67B00
61 | 25 | 1684 | $69400
62 | 25 | 1709 | $6AD00
63 | 25 | 1734 | $6C600
64 | 25 | 1759 | $6DF00
65 | 23 | 1784 | $6F800
66 | 23 | 1807 | $70F00
67 | 23 | 1830 | $72600
68 | 23 | 1853 | $73D00
69 | 23 | 1876 | $75400
70 | 23 | 1899 | $76B00
71 | 23 | 1922 | $78200
72 | 23 | 1945 | $79900
73 | 23 | 1968 | $7B000
74 | 23 | 1991 | $7C700
75 | 23 | 2014 | $7DE00
76 | 23 | 2037 | $7F500
77 | 23 | 2060 | $80C00

The BAM (Block Availability Map) is on track 38. The D80 is only 77 tracks and so the BAM is contained on 38/0 and 38/3. The BAM interleave is 3.

The directory is on track 39, with 39/0 contains the header (DOS type, disk name, disk ID’s) and sectors 1-28 contain the directory entries. Both files and the directory use an interleave of 1. Since the directory is only 28 sectors large (29 less one for the header), and each sector can contain only 8 entries (32 bytes per entry), the maximum number of directory entries is 28 * 8 = 224. The first directory sector is always 39/1. It then follows a chain structure using a sector interleave of 1 making the links go 39/1, 39/2, 39/3 etc.

When reading a disk, you start with 39/0 (disk label/ID) which points to 38/0 (BAM0), 38/3 (BAM1), and finally to 39/1 (first dir entry sector). When writing a file to a blank disk, it will start at 38/1 because 38/0 is already allocated.

Below is a dump of the header sector 39/0:

        00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
        -----------------------------------------------
    00: 26 00 43 00 00 00 73 61 6D 70 6C 65 20 64 38 30
    10: A0 A0 A0 A0 A0 A0 A0 A0 65 72 A0 32 43 A0 A0 A0
    20: A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    …
    F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Bytes | Description
$00-$01 | T/S pointer to first BAM sector (38/0)
$02 | $43 ’C’ is for DOS format version
$03 | Reserved
$04-$05 | Unused
$06-$16 | Disk name, padded with 0xA0 ("sample d80")
$17 | 0xA0
$18-$19 | Disk ID bytes "er"
$1A | 0xA0
$1B-$1C | DOS version bytes "2C"
$1D-$20 | 0xA0
$21-$FF | Unused

Below is a dump of the first directory sector, 39/1

        00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
        -----------------------------------------------
    00: 27 02 82 26 01 54 45 53 54 A0 A0 A0 A0 A0 A0 A0
    10: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
    20: 00 00 82 26 02 54 45 53 54 32 A0 A0 A0 A0 A0 A0
    30: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
    40: 00 00 82 26 04 54 45 53 54 33 A0 A0 A0 A0 A0 A0
    50: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 05 00
    60: 00 00 82 26 0B 54 45 53 54 34 A0 A0 A0 A0 A0 A0
    70: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 09 00
    80: 00 00 82 26 14 54 45 53 54 35 A0 A0 A0 A0 A0 A0
    90: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 0C 00
    A0: 00 00 82 28 00 54 45 53 54 36 A0 A0 A0 A0 A0 A0
    B0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
    C0: 00 00 82 28 01 54 45 53 54 37 A0 A0 A0 A0 A0 A0
    D0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
    E0: 00 00 82 28 02 54 45 53 54 38 A0 A0 A0 A0 A0 A0
    F0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00

The first two bytes of the directory sector ($27/$02) indicate the location of the next track/sector of the directory (39/2). If the track is set to $00, then it is the last sector of the directory.

When the directory is done, the track value will be $00. The sector link should contain a value of $FF, meaning the whole sector is allocated, but the actual value doesn’t matter. The drive will return all the available entries anyways. This is a breakdown of a standard directory sector:

Bytes | Description
$00-$1F | First directory entry
$20-$3F | Second dir entry
$40-$5F | Third dir entry
$60-$7F | Fourth dir entry
$80-$9F | Fifth dir entry
$A0-$BF | Sixth dir entry
$C0-$DF | Seventh dir entry
$E0-$FF | Eighth dir entry

This is a breakdown of a standard directory entry:

Bytes | Description
$00-$01 | Track/Sector location of next directory sector ($00 $00 if not the first entry in the sector)
$02 | File type
$03-$04 | Track/sector location of first sector of file
$05-$14 | 16 character filename (in PETASCII, padded with $A0)
$15-$16 | Track/Sector location of first side-sector block (REL file only)
$17 | REL file record length (REL file only, max. value 254)
$18-$1D | Unused
$1E-$1F | File size in sectors, low/high byte order ($1E+$1F*256). The approx. filesize in bytes is <= #sectors * 254

The file type field is used as follows:

Bits | Description
0-3 | The actual file type
4 | Unused
5 | Used only during SAVE-@ replacement
6 | Locked flag (Set produces ">" locked files)
7 | Closed flag (Not set produces "*", or "splat" files)

The actual file type can be one of the following:

Binary | Decimal | File type
0000 | 0 | DEL
0001 | 1 | SEQ
0010 | 2 | PRG
0011 | 3 | USR
0100 | 4 | REL

Values 5-15 are illegal, but if used will produce very strange results.

#### 17.9.1 Non-Standard & Long Directories

Most Commdore floppy disk drives use a single dedicated directory track where all filenames are stored. This limits the number of files stored on a disk based on the number of sectors on the directory track. There are some disk images that contain more files than would normally be allowed. This requires extending the directory off the default directory track by changing the last directory sector pointer to a new track, allocating the new sectors in the BAM, and manually placing (or moving existing) file entries there. The directory of an extended disk can be read and the files that reside there can be loaded without problems on a real drive. However, this is still a very dangerous practice as writing to the extended portion of the directory will cause directory corruption in the non-extended part. Many of the floppy drives core ROM routines ignore the track value that the directory is on and assume the default directory track for operations.

#### 17.9.2 BAM layout

The BAM only occupies up to four sectors on track 38, so the rest of the track is empty and is available for file storage. Below is a dump of the first BAM block, 38/0. A D80 will only contain two BAM sectors, 38/0 and 38/3. Each entry takes 5 bytes, 1 for the free count on that track, and 4 for the BAM bits.

        00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
        -----------------------------------------------
    00: 26 03 43 00 01 33 1D FF FF FF 1F 1D FF FF FF 1F
    10: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D
    20: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF
    30: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF
    40: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF
    50: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F
    60: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D
    70: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF
    80: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF
    90: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF
    A0: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F
    B0: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1B
    C0: F6 FF FF 1F 1B FC FF FF 1F 1B FF FF FF 07 1B FF
    D0: FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF
    E0: FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF
    F0: 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF 07

Bytes | Description
$00-$01 | T/S pointer to second BAM sector (38/3)
$02 | DOS version byte (0x43=’C’)
$03 | Reserved
$04 | Lowest track covered by this BAM (0x01=1)
$05 | Highest+1 track covered by this BAM (0x33=51)
$06-$0A | BAM for track 1. The first byte shows the "blocks free" for this track, the remaining 4 show the BAM for the track.
$0B-$0F | BAM for track 2
… | …
$FB-$FF | BAM for track 50

Being bit-based, the BAM entries need some explanation. The first track entry in the above BAM sector is at offset 06, "1D FF FF FF 1F". The first number is how many blocks are free on this track ($1D=29) and the remainder is the bit representation of the usage map for the track. These entries must be viewed in binary to make any sense. First convert the values to binary:

     FF=11111111, FF=11111111, FF=11111111, 1F=00011111

In order to make any sense from the binary notation, flip the bits around.

                111111 11112222 222222
     01234567 89012345 67890123 456789…
     -------------------------- ---------
     11111111 11111111 11111111 11111000
     ^                              ^
     sector 0                   sector 28

Since we are on the first track, we have 29 sectors, and only use up to the bit 28 position. If a bit is on (1), the sector is free. Therefore, track 1 is clean, all sectors are free. Any leftover bits that refer to sectors that don’t exist, like bits 29-31 in the above example, are set to allocated.

Second BAM block 38/3.

        00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
        -----------------------------------------------
    00: 27 01 43 00 33 4E 1B FF FF FF 07 1B FF FF FF 07
    10: 1B FF FF FF 07 19 FF FF FF 01 19 FF FF FF 01 19
    20: FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF
    30: FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF FF
    40: FF 01 19 FF FF FF 01 19 FF FF FF 01 17 FF FF 7F
    50: 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00
    60: 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17
    70: FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF
    80: FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 00 00 00
    90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Bytes | Description
$00-$01 | T/S pointer to second BAM sector (39/1)
$02 | DOS version byte (0x43=’C’)
$03 | Reserved
$04 | Lowest track covered by this BAM (0x33=51)
$05 | Highest+1 track covered by this BAM (0x43=78)
$06-$0A | BAM for track 51. The first byte shows the "blocks free" for this track, the remaining 4 show the BAM for the track.
$0B-$0F | BAM for track 52
… | …
$88-$8C | BAM for track 77
$8D-$FF | Not used

Next: The D82 disk image format, Previous: The D81 disk image format, Up: The emulator file formats [Contents][Index]