Next: The D90 disk image format, Previous: The D80 disk image format, Up: The emulator file formats [Contents][Index]
(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.
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.
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]