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

### 17.10 The D82 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 8250 floppy disk. The file size for an 8250 image is 1066496 bytes. It is comprised of 256-byte sectors arranged across 154 tracks, with a varying number of sectors per track for a total of 4166 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 D82. 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
55-64 | 25 | 275
65-77 | 23 | 299
78-116 | 29 | 1131
117-130 | 27 | 378
131-141 | 25 | 275
142-154 | 23 | 299

Track | #Sect | #SectorsIn | D82 Offset
1 | 29 | 0 | $000000
2 | 29 | 29 | $001D00
3 | 29 | 58 | $003A00
4 | 29 | 87 | $005700
5 | 29 | 116 | $007400
6 | 29 | 145 | $009100
7 | 29 | 174 | $00AE00
8 | 29 | 203 | $00CB00
9 | 29 | 232 | $00E800
10 | 29 | 261 | $010500
11 | 29 | 290 | $012200
12 | 29 | 319 | $013F00
13 | 29 | 348 | $015C00
14 | 29 | 377 | $017900
15 | 29 | 406 | $019600
16 | 29 | 435 | $01B300
17 | 29 | 464 | $01D000
18 | 29 | 493 | $01ED00
19 | 29 | 522 | $020A00
20 | 29 | 551 | $022700
21 | 29 | 580 | $024400
22 | 29 | 609 | $026100
23 | 29 | 638 | $027E00
24 | 29 | 667 | $029B00
25 | 29 | 696 | $02B800
26 | 29 | 725 | $02D500
27 | 29 | 754 | $02F200
28 | 29 | 783 | $030F00
29 | 29 | 812 | $032C00
30 | 29 | 841 | $034900
31 | 29 | 870 | $036600
32 | 29 | 899 | $038300
33 | 29 | 928 | $03A000
34 | 29 | 957 | $03BD00
35 | 29 | 986 | $03DA00
36 | 29 | 1015 | $03F700
37 | 29 | 1044 | $041400
38 | 29 | 1073 | $043100
39 | 29 | 1102 | $044E00
40 | 27 | 1131 | $046B00
41 | 27 | 1158 | $048600
42 | 27 | 1185 | $04A100
43 | 27 | 1212 | $04BC00
44 | 27 | 1239 | $04D700
45 | 27 | 1266 | $04F200
46 | 27 | 1293 | $050D00
47 | 27 | 1320 | $052800
48 | 27 | 1347 | $054300
49 | 27 | 1374 | $055E00
50 | 27 | 1401 | $057900
51 | 27 | 1428 | $059400
52 | 27 | 1455 | $05AF00
53 | 27 | 1482 | $05CA00
54 | 25 | 1509 | $05E500
55 | 25 | 1534 | $05FE00
56 | 25 | 1559 | $061700
57 | 25 | 1584 | $063000
58 | 25 | 1609 | $064900
59 | 25 | 1634 | $066200
60 | 25 | 1659 | $067B00
61 | 25 | 1684 | $069400
62 | 25 | 1709 | $06AD00
63 | 25 | 1734 | $06C600
64 | 25 | 1759 | $06DF00
65 | 23 | 1784 | $06F800
66 | 23 | 1807 | $070F00
67 | 23 | 1830 | $072600
68 | 23 | 1853 | $073D00
69 | 23 | 1876 | $075400
70 | 23 | 1899 | $076B00
71 | 23 | 1922 | $078200
72 | 23 | 1945 | $079900
73 | 23 | 1968 | $07B000
74 | 23 | 1991 | $07C700
75 | 23 | 2014 | $07DE00
76 | 23 | 2037 | $07F500
77 | 23 | 2060 | $080C00
78 | 29 | 2083 | $082300
79 | 29 | 2112 | $084000
80 | 29 | 2141 | $085D00
81 | 29 | 2170 | $087A00
82 | 29 | 2199 | $089700
83 | 29 | 2228 | $08B400
84 | 29 | 2257 | $08D100
85 | 29 | 2286 | $08EE00
86 | 29 | 2315 | $090600
87 | 29 | 2344 | $092800
88 | 29 | 2373 | $094500
89 | 29 | 2402 | $096200
90 | 29 | 2431 | $097F00
91 | 29 | 2460 | $099C00
92 | 29 | 2489 | $09B900
93 | 29 | 2518 | $09D600
94 | 29 | 2547 | $09F300
95 | 29 | 2576 | $0A1000
96 | 29 | 2605 | $0A2D00
97 | 29 | 2634 | $0A4A00
98 | 29 | 2663 | $0A6700
99 | 29 | 2692 | $0A8400
100 | 29 | 2721 | $0AA100
101 | 29 | 2750 | $0ABE00
102 | 29 | 2779 | $0ADB00
103 | 29 | 2808 | $0AF800
104 | 29 | 2837 | $0B1500
105 | 29 | 2866 | $0B3200
106 | 29 | 2895 | $0B4F00
107 | 29 | 2924 | $0B6C00
108 | 29 | 2953 | $0B8900
109 | 29 | 2982 | $0BA600
110 | 29 | 3011 | $0BC300
111 | 29 | 3040 | $0BE000
112 | 29 | 3069 | $0BFD00
113 | 29 | 3098 | $0C1A00
114 | 29 | 3137 | $0C3700
115 | 29 | 3156 | $0C5400
116 | 29 | 3185 | $0C7100
117 | 27 | 3214 | $0C8E00
118 | 27 | 3241 | $0CA900
119 | 27 | 3268 | $0CC400
120 | 27 | 3295 | $0CDF00
121 | 27 | 3322 | $0CFA00
122 | 27 | 3349 | $0D1500
123 | 27 | 3376 | $0D3000
124 | 27 | 3403 | $0D4B00
125 | 27 | 3430 | $0D6600
126 | 27 | 3457 | $0D8100
127 | 27 | 3484 | $0D9C00
128 | 27 | 3511 | $0DB700
129 | 27 | 3538 | $0DD200
130 | 27 | 3565 | $0DED00
131 | 25 | 3592 | $0E0800
132 | 25 | 3617 | $0E2100
133 | 25 | 3642 | $0E3A00
134 | 25 | 3667 | $0E5300
135 | 25 | 3692 | $0E6C00
136 | 25 | 3717 | $0E8500
137 | 25 | 3742 | $0E9E00
138 | 25 | 3767 | $0EB700
139 | 25 | 3792 | $0ED000
140 | 25 | 3817 | $0EE900
141 | 25 | 3842 | $0F0200
142 | 23 | 3867 | $0F1B00
143 | 23 | 3890 | $0F3200
144 | 23 | 3913 | $0F4900
145 | 23 | 3936 | $0F6000
146 | 23 | 3959 | $0F7700
147 | 23 | 3982 | $0F8E00
148 | 23 | 4005 | $0FA500
149 | 23 | 4028 | $0FBC00
150 | 23 | 4051 | $0FD300
151 | 23 | 4074 | $0FEA00
152 | 23 | 4097 | $100100
153 | 23 | 4120 | $101800
154 | 23 | 4143 | $102F00

The BAM (Block Availability Map) is on track 38. The D82 is 154 tracks and so the BAM is contained on 38/0, 38/3, 38/6 and 38/9. 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), 38/6 (BAM2), 38/9 (BAM3, 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 d82")
$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.10.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.10.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 D82 will contain four BAM sectors, 38/0, 38/3, 38/6 and 38/9. 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: 26 06 43 00 33 65 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 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 1D
    C0: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF
    D0: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF
    E0: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF
    F0: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F

Bytes | Description
$00-$01 | T/S pointer to third BAM sector (38/6)
$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 (0x65=101)
$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
… | …
$FB-$FF | BAM for track 100

Third BAM block 38/6

        00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
        -----------------------------------------------
    00: 26 09 43 00 65 97 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 1B FF FF FF 07 1B FF FF FF 07
    60: 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B
    70: FF FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF
    80: FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF
    90: FF 07 1B FF FF FF 07 1B FF FF FF 07 19 FF FF FF
    A0: 01 19 FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01
    B0: 19 FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19
    C0: FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF
    D0: FF FF 01 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF
    E0: 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F
    F0: 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00

Bytes | Description
$00-$01 | T/S pointer to fourth BAM sector (38/9)
$02 | DOS version byte (0x43=’C’)
$03 | Reserved
$04 | Lowest track covered by this BAM (0x65=101)
$05 | Highest+1 track covered by this BAM (0x97=151)
$06-$0A | BAM for track 101. The first byte shows the "blocks free" for this track, the remaining 4 show the BAM for the track.
$0B-$0F | BAM for track 102
… | …
$FB-$FF | BAM for track 150

Fourth BAM block 38/9

        00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
        -----------------------------------------------
    00: 27 01 43 00 97 9B 17 FF FF 7F 00 17 FF FF 7F 00
    10: 17 FF FF 7F 00 17 FF FF 7F 00 00 00 00 00 00 00
    20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    40: 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 directory sector (39/1)
$02 | DOS version byte (0x43=’C’)
$03 | Reserved
$04 | Lowest track covered by this BAM (0x97=151)
$05 | Highest+1 track covered by this BAM (0x9B=155)
$06-$0A | BAM for track 151. The first byte shows the "blocks free" for this track, the remaining 4 show the BAM for the track.
$0B-$0F | BAM for track 152
… | …
$15-$19 | BAM for track 154
$1A-$FF | Not used

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