1 // license:BSD-3-Clause
2 // copyright-holders:tim lindner, 68bit
3 /*********************************************************************
4
5 formats/os9_dsk.c
6
7 OS-9 disk images
8
9 OS-9 Level 2 Technical Reference, Chapter 5, Random Block File
10 Manager, page 2
11
12 Available: http://www.colorcomputerarchive.com/coco/Documents/Manuals/
13 Operating Systems/OS-9 Level 2 Manual (Tandy).pdf
14
15 Some OS9 floppy drivers use a base sector ID of zero, for example SWTPC
16 and Gimix OS9, and some drivers use a base sector ID of one, for example
17 COCO OS9. The disk images do not encode the sector IDs so it is a
18 challenge to detect this base ID by looking at the disk content.
19
20 The OS9 disk header, at LSN0, does not necessarily encode the base sector
21 ID either. However it may optionally include a block of the device
22 descriptor information from when it was formatted and although this
23 optional content can vary across OS9 variants it appears to be regular
24 enough for COCO compatible formats to reply on it to identify a COCO
25 compatible disk and determine the base sector ID for these. All non-COCO
26 formats are assumed to have a base sector ID of zero and not exceptions to
27 this have been noted.
28
29 Commonly the 'coco' bit, bit 5, in the optional 'type' byte is set in COCO
30 format disks. Alternatively some OS9 formats set bit 7 of the optional
31 'density' byte to indicate a COCO format disk, for example some Gimix
32 drivers with COCO support. Some of the other optional information also can
33 be checked for consistency to better identify the format.
34
35 Some formats encode the first track, on the first head only, in single
36 density even when the remainder of the disk is encoded in double density,
37 and this can typically be identified from the disk geometry and the image
38 size and the total number of logical sectors written in the header.
39 E.g. At least some versions of OS9 for the SWTPC and the Gimix encode this
40 first track in single density whereas COCO format disks are typically all
41 double density. The number of sectors on track zero is also typically
42 encoded in the optional header information and can be checked for
43 consistency.
44
45 *********************************************************************/
46
47 #include "os9_dsk.h"
48 #include "imageutl.h"
49
50 #include "coretmpl.h" // BIT
51
52
os9_format()53 os9_format::os9_format() : wd177x_format(formats)
54 {
55 }
56
name() const57 const char *os9_format::name() const
58 {
59 return "os9";
60 }
61
description() const62 const char *os9_format::description() const
63 {
64 return "OS-9 floppy disk image";
65 }
66
extensions() const67 const char *os9_format::extensions() const
68 {
69 return "dsk,os9";
70 }
71
identify(io_generic * io,uint32_t form_factor)72 int os9_format::identify(io_generic *io, uint32_t form_factor)
73 {
74 int type = find_size(io, form_factor);
75
76 if (type != -1)
77 return 75;
78 return 0;
79 }
80
find_size(io_generic * io,uint32_t form_factor)81 int os9_format::find_size(io_generic *io, uint32_t form_factor)
82 {
83 uint64_t size = io_generic_size(io);
84
85 uint8_t os9_header[0x60];
86 io_generic_read(io, os9_header, 0, sizeof(os9_header));
87
88 int os9_total_sectors = pick_integer_be(os9_header, 0x00, 3);
89 int os9_heads = util::BIT(os9_header[0x10], 0) ? 2 : 1;
90 int os9_sectors = pick_integer_be(os9_header, 0x11, 2);
91
92 if (os9_total_sectors <= 0 || os9_heads <= 0 || os9_sectors <= 0)
93 return -1;
94
95 // The optional header information, which may contain a copy of the
96 // device descriptor used to format the disk. COCO format disks are
97 // expected to include this optional information.
98 int opt_dtype = os9_header[0x3f + 0];
99 int opt_type = os9_header[0x3f + 3];
100 int opt_density = os9_header[0x3f + 4];
101 int opt_cylinders = pick_integer_be(os9_header, 0x3f + 5, 2);
102 int opt_sides = os9_header[0x3f + 7];
103 int opt_sectors_per_track = pick_integer_be(os9_header, 0x3f + 9, 2);
104 int opt_track0_sectors = pick_integer_be(os9_header, 0x3f + 11, 2);
105 int opt_interleave = os9_header[0x3f + 13];
106
107 int opt_mfm = util::BIT(opt_density, 0);
108
109 // The NitrOS9 rb1773 driver uses bit 1 of opt_type to distinguish
110 // between a sector base ID of zero or one, so recognise that here.
111 int opt_sector_base_id = util::BIT(opt_type, 1) ? 0 : 1;
112 int opt_sector_size = util::BIT(opt_type, 2) ? 512 : 256;
113 int opt_coco = util::BIT(opt_type, 5);
114
115 // Some OS9 versions appear to use bit 7 of the opt_density rather
116 // than bit 5 of opt_type to signify a COCO format disk. E.g. Gimix
117 // OS9 is documented to use this bit and had a floppy driver that
118 // could read both non-COCO and COCO format disks.
119 if (util::BIT(opt_density, 7))
120 opt_coco = 1;
121
122 // COCO format disks are expected for have an opt_dtype of 1.
123 if (opt_dtype != 1)
124 opt_coco = 0;
125
126 for (int i=0; formats[i].form_factor; i++) {
127 const format &f = formats[i];
128 if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
129 continue;
130
131 if ((os9_heads != f.head_count) || (os9_sectors != f.sector_count)) {
132 continue;
133 }
134
135 unsigned int format_size = 0;
136 for (int track=0; track < f.track_count; track++) {
137 for (int head=0; head < f.head_count; head++) {
138 const format &tf = get_track_format(f, head, track);
139 format_size += compute_track_size(tf);
140 }
141 }
142
143 if (format_size != size)
144 continue;
145
146 if (format_size < os9_total_sectors * 256)
147 continue;
148
149 // Accept the format if the total number of sectors used is
150 // consistent with at least 10 sectors being used on track
151 // zero, as happens when the driver or descriptor is coded for
152 // a single density track zero with 10 sectors and so uses
153 // only 10 of these track zero sectors.
154
155 if (f.sector_count < 10 || format_size > (os9_total_sectors + f.sector_count - 10) * 256)
156 continue;
157
158 const format &tf = get_track_format(f, 0, 0);
159
160 if (opt_coco) {
161 // Looks like a COCO format disk.
162
163 // Check the sector base ID.
164 if (f.sector_base_id != opt_sector_base_id &&
165 (f.sector_base_id != -1 || f.per_sector_id[0] != opt_sector_base_id))
166 continue;
167 if (tf.sector_base_id != opt_sector_base_id &&
168 (tf.sector_base_id != -1 || tf.per_sector_id[0] != opt_sector_base_id))
169 continue;
170
171 // Check some other optional fields for consistency.
172
173 // If the device descriptor is not MFM capable then
174 // the disk it not expected to be MFM encoded.
175 if (opt_mfm == 0 && f.encoding == floppy_image::MFM)
176 continue;
177
178 // Should not be more cylinders than suppored in the
179 // device descriptor.
180 if (f.track_count > opt_cylinders)
181 continue;
182
183 // Should not be more heads than suppored in the
184 // device descriptor.
185 if (f.head_count > opt_sides)
186 continue;
187
188 // Should not be more sectors per track than supported
189 // in the device descriptor.
190 if (f.sector_count > opt_sectors_per_track ||
191 tf.sector_count > opt_track0_sectors) {
192 continue;
193 }
194
195 // The sector size should be consistent.
196 if (opt_sector_size != f.sector_base_size)
197 continue;
198
199 // The sector interleave should not be greater than
200 // the number of sectors.
201 if (opt_interleave > f.sector_count)
202 continue;
203 }
204 else
205 {
206 // Not a recognizable COCO OS9 format. The options
207 // can not be relied on here, they are driver
208 // dependent, and the sector base ID is assumed to be
209 // zero. Check that format sector base ID is zero.
210 if (f.sector_base_id != 0 && (f.sector_base_id != -1 || f.per_sector_id[0] != 0))
211 continue;
212 if (tf.sector_base_id != 0 && (tf.sector_base_id != -1 || tf.per_sector_id[0] != 0))
213 continue;
214 }
215
216 LOG_FORMATS("OS9 matching format index %d\n", i);
217 return i;
218 }
219 return -1;
220 }
221
get_track_format(const format & f,int head,int track)222 const wd177x_format::format &os9_format::get_track_format(const format &f, int head, int track)
223 {
224 int n = -1;
225
226 for (int i = 0; formats[i].form_factor; i++) {
227 if (&formats[i] == &f) {
228 n = i;
229 break;
230 }
231 }
232
233 if (n < 0) {
234 LOG_FORMATS("Error format not found\n");
235 return f;
236 }
237
238 if (head >= f.head_count) {
239 LOG_FORMATS("Error invalid head %d\n", head);
240 return f;
241 }
242
243 if (track >= f.track_count) {
244 LOG_FORMATS("Error invalid track %d\n", track);
245 return f;
246 }
247
248 if (track == 0 && head == 0) {
249 const format &t0 = formats_track0[n];
250 if (t0.form_factor)
251 return t0;
252 }
253
254 return f;
255 }
256
257 const os9_format::format os9_format::formats[] = {
258 // COCO formats, with a sector base ID of one.
259
260 { // 0 157.5K 5"25 double density
261 floppy_image::FF_525, floppy_image::SSDD, floppy_image::MFM,
262 2000, 18, 35, 1, 256, {}, -1, {1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10, 16, 5, 11, 17, 6, 12, 18}, 18, 28, 20
263 },
264 { // 1 315K 5"25 double density
265 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
266 2000, 18, 35, 2, 256, {}, -1, {1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10, 16, 5, 11, 17, 6, 12, 18}, 18, 28, 20
267 },
268 { // 2 180K 5"25 double density
269 floppy_image::FF_525, floppy_image::SSDD, floppy_image::MFM,
270 2000, 18, 40, 1, 256, {}, -1, {1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10, 16, 5, 11, 17, 6, 12, 18}, 18, 28, 20
271 },
272 { // 3 360K 5"25 double density
273 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
274 2000, 18, 40, 2, 256, {}, -1, {1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10, 16, 5, 11, 17, 6, 12, 18}, 18, 28, 20
275 },
276 { // 4 360K 5"25 double density
277 floppy_image::FF_525, floppy_image::SSDD, floppy_image::MFM,
278 2000, 18, 80, 1, 256, {}, -1, {1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10, 16, 5, 11, 17, 6, 12, 18}, 18, 28, 20
279 },
280 { // 5 720K 5"25 double density
281 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
282 2000, 18, 80, 2, 256, {}, -1, {1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10, 16, 5, 11, 17, 6, 12, 18}, 18, 28, 20
283 },
284
285 // Non-COCO formats, with a sector base ID of zero.
286
287 { // 6 87.5K 5 1/4 inch single density
288 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
289 4000, 10, 35, 1, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
290 },
291 { // 7 100K 5 1/4 inch single density
292 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
293 4000, 10, 40, 1, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
294 },
295 { // 8 200K 5 1/4 inch single density
296 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
297 4000, 10, 80, 1, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
298 },
299 { // 9 175K 5 1/4 inch single density
300 floppy_image::FF_525, floppy_image::DSSD, floppy_image::FM,
301 4000, 10, 35, 2, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
302 },
303 { // 10 200K 5 1/4 inch single density
304 floppy_image::FF_525, floppy_image::DSSD, floppy_image::FM,
305 4000, 10, 40, 2, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
306 },
307 { // 11 400K 5 1/4 inch single density
308 floppy_image::FF_525, floppy_image::DSSD, floppy_image::FM,
309 4000, 10, 80, 2, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
310 },
311 { // 12 138.5K 5 1/4 inch double density (single density track 0)
312 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
313 2000, 16, 35, 1, 256, {}, -1, {0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13}, 18, 28, 20
314 },
315 { // 13 140K 5 1/4 inch double density
316 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
317 2000, 16, 35, 1, 256, {}, -1, {0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13}, 18, 28, 20
318 },
319 { // 14 278.5K 5 1/4 inch double density (single density track 0)
320 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
321 2000, 16, 35, 2, 256, {}, -1, {0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13}, 18, 28, 20
322 },
323 { // 15 280K 5 1/4 inch double density
324 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
325 2000, 16, 35, 2, 256, {}, -1, {0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13}, 18, 28, 20
326 },
327 { // 16 158.5K 5 1/4 inch double density (single density track 0)
328 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
329 2000, 16, 40, 1, 256, {}, -1, {0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13}, 18, 28, 20
330 },
331 { // 17 160K 5 1/4 inch double density
332 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
333 2000, 16, 40, 1, 256, {}, -1, {0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13}, 18, 28, 20
334 },
335 { // 18 318.5K 5 1/4 inch double density (single density track 0)
336 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
337 2000, 16, 40, 2, 256, {}, -1, {0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13}, 18, 28, 20
338 },
339 { // 19 320K 5 1/4 inch double density
340 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
341 2000, 16, 40, 2, 256, {}, -1, {0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13}, 18, 28, 20
342 },
343 { // 20 318.5K 5 1/4 inch double density (single density track 0)
344 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
345 2000, 16, 80, 1, 256, {}, -1, {0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13}, 18, 28, 20
346 },
347 { // 21 320K 5 1/4 inch double density
348 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
349 2000, 16, 80, 1, 256, {}, -1, {0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13}, 18, 28, 20
350 },
351 { // 22 638.5 5 1/4 inch double density (single density track 0)
352 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
353 2000, 16, 80, 2, 256, {}, -1, {0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13}, 18, 28, 20
354 },
355 { // 23 640K 5 1/4 inch double density
356 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
357 2000, 16, 80, 2, 256, {}, -1, {0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13}, 18, 28, 20
358 },
359 { // 24 155.5K 5 1/4 inch double density (single density track 0)
360 floppy_image::FF_525, floppy_image::SSDD, floppy_image::MFM,
361 2000, 18, 35, 1, 256, {}, -1, {0, 5, 10, 15, 2, 7, 12, 17, 4, 9, 14, 1, 6, 11, 16, 3, 8, 13}, 80, 22, 24
362 },
363 { // 25 157.5K 5 1/4 inch double density
364 floppy_image::FF_525, floppy_image::SSDD, floppy_image::MFM,
365 2000, 18, 35, 1, 256, {}, -1, {0, 5, 10, 15, 2, 7, 12, 17, 4, 9, 14, 1, 6, 11, 16, 3, 8, 13}, 80, 22, 24
366 },
367 { // 26 311K 5 1/4 inch double density (single density track 0)
368 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
369 2000, 18, 35, 2, 256, {}, -1, {0, 5, 10, 15, 2, 7, 12, 17, 4, 9, 14, 1, 6, 11, 16, 3, 8, 13}, 80, 22, 24
370 },
371 { // 27 315K 5 1/4 inch double density
372 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
373 2000, 18, 35, 2, 256, {}, -1, {0, 5, 10, 15, 2, 7, 12, 17, 4, 9, 14, 1, 6, 11, 16, 3, 8, 13}, 80, 22, 24
374 },
375 { // 28 178K 5 1/4 inch double density (single density track 0)
376 floppy_image::FF_525, floppy_image::SSDD, floppy_image::MFM,
377 2000, 18, 40, 1, 256, {}, -1, {0, 5, 10, 15, 2, 7, 12, 17, 4, 9, 14, 1, 6, 11, 16, 3, 8, 13}, 80, 22, 24
378 },
379 { // 29 180K 5 1/4 inch double density
380 floppy_image::FF_525, floppy_image::SSDD, floppy_image::MFM,
381 2000, 18, 40, 1, 256, {}, -1, {0, 5, 10, 15, 2, 7, 12, 17, 4, 9, 14, 1, 6, 11, 16, 3, 8, 13}, 80, 22, 24
382 },
383 { // 30 356K 5 1/4 inch double density (single density track 0)
384 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
385 2000, 18, 40, 2, 256, {}, -1, {0, 5, 10, 15, 2, 7, 12, 17, 4, 9, 14, 1, 6, 11, 16, 3, 8, 13}, 80, 22, 24
386 },
387 { // 31 360K 5 1/4 inch double density
388 floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM,
389 2000, 18, 40, 2, 256, {}, -1, {0, 5, 10, 15, 2, 7, 12, 17, 4, 9, 14, 1, 6, 11, 16, 3, 8, 13}, 80, 22, 24
390 },
391 { // 32 358K 5 1/4 inch quad density (single density track 0)
392 floppy_image::FF_525, floppy_image::SSQD, floppy_image::MFM,
393 2000, 18, 80, 1, 256, {}, -1, {0, 5, 10, 15, 2, 7, 12, 17, 4, 9, 14, 1, 6, 11, 16, 3, 8, 13}, 80, 22, 24
394 },
395 { // 33 360K 5 1/4 inch quad density
396 floppy_image::FF_525, floppy_image::SSQD, floppy_image::MFM,
397 2000, 18, 80, 1, 256, {}, -1, {0, 5, 10, 15, 2, 7, 12, 17, 4, 9, 14, 1, 6, 11, 16, 3, 8, 13}, 80, 22, 24
398 },
399 { // 34 716K 5 1/4 inch quad density (single density track 0)
400 floppy_image::FF_525, floppy_image::DSQD, floppy_image::MFM,
401 2000, 18, 80, 2, 256, {}, -1, {0, 5, 10, 15, 2, 7, 12, 17, 4, 9, 14, 1, 6, 11, 16, 3, 8, 13}, 80, 22, 24
402 },
403 { // 35 720K 5 1/4 inch quad density
404 floppy_image::FF_525, floppy_image::DSQD, floppy_image::MFM,
405 2000, 18, 80, 2, 256, {}, -1, {0, 5, 10, 15, 2, 7, 12, 17, 4, 9, 14, 1, 6, 11, 16, 3, 8, 13}, 80, 22, 24
406 },
407 { // 36 288.75K 8 inch single density
408 floppy_image::FF_8, floppy_image::SSSD, floppy_image::FM,
409 2000, 15, 77, 1, 256, {}, -1, {0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13}, 40, 12, 12
410 },
411 { // 37 577.5K 8 inch single density
412 floppy_image::FF_8, floppy_image::DSSD, floppy_image::FM,
413 2000, 15, 77, 2, 256, {}, -1, {0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13}, 40, 12, 12
414 },
415 { // 38 308K 8 inch single density
416 floppy_image::FF_8, floppy_image::SSSD, floppy_image::FM,
417 2000, 16, 77, 1, 256, {}, -1, {0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15}, 35, 12, 12
418 },
419 { // 39 616K 8 inch single density
420 floppy_image::FF_8, floppy_image::DSSD, floppy_image::FM,
421 2000, 16, 77, 2, 256, {}, -1, {0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15}, 35, 12, 12
422 },
423 { // 40 497.75K 8 inch double density (single density track 0)
424 floppy_image::FF_8, floppy_image::SSDD, floppy_image::MFM,
425 1000, 26, 77, 1, 256, {}, -1, {0, 19, 12, 5, 24, 17, 10, 3, 22, 15, 8, 1, 20, 13, 6, 25, 18, 11, 4, 23, 16, 9, 2, 21, 14, 7}, 80, 22, 24
426 },
427 { // 41 500.5K 8 inch double density
428 floppy_image::FF_8, floppy_image::SSDD, floppy_image::MFM,
429 1000, 26, 77, 1, 256, {}, -1, {0, 19, 12, 5, 24, 17, 10, 3, 22, 15, 8, 1, 20, 13, 6, 25, 18, 11, 4, 23, 16, 9, 2, 21, 14, 7}, 80, 22, 24
430 },
431 { // 42 995.5K 8 inch double density (single density track 0)
432 floppy_image::FF_8, floppy_image::DSDD, floppy_image::MFM,
433 1000, 26, 77, 2, 256, {}, -1, {0, 19, 12, 5, 24, 17, 10, 3, 22, 15, 8, 1, 20, 13, 6, 25, 18, 11, 4, 23, 16, 9, 2, 21, 14, 7}, 80, 22, 24
434 },
435 { // 43 1001K 8 inch double density
436 floppy_image::FF_8, floppy_image::DSDD, floppy_image::MFM,
437 1000, 26, 77, 2, 256, {}, -1, {0, 19, 12, 5, 24, 17, 10, 3, 22, 15, 8, 1, 20, 13, 6, 25, 18, 11, 4, 23, 16, 9, 2, 21, 14, 7}, 80, 22, 24
438 },
439 { // 44 1440K 3 1/2 inch high density (single density track 0)
440 floppy_image::FF_35, floppy_image::DSHD, floppy_image::MFM,
441 1000, 36, 80, 2, 256, {}, -1, {0, 25, 14, 3, 28, 17, 6, 31, 20, 9, 34, 23, 12, 1, 26, 15, 4, 29, 18, 7, 32, 21, 10, 35, 24, 13, 2, 27, 16, 5, 30, 19, 8, 33, 22, 11}, 80, 22, 24
442 },
443 { // 45 1440K 3 1/2 inch high density.
444 floppy_image::FF_35, floppy_image::DSHD, floppy_image::MFM,
445 1000, 36, 80, 2, 256, {}, -1, {0, 25, 14, 3, 28, 17, 6, 31, 20, 9, 34, 23, 12, 1, 26, 15, 4, 29, 18, 7, 32, 21, 10, 35, 24, 13, 2, 27, 16, 5, 30, 19, 8, 33, 22, 11}, 80, 22, 24
446 },
447 {}
448 };
449
450 const os9_format::format os9_format::formats_track0[] = {
451 // COCO formats, with a sector base ID of one.
452
453 { // 0 157.5K 5"25 double density
454 },
455 { // 1 315K 5"25 double density
456 },
457 { // 2 180K 5"25 double density
458 },
459 { // 3 360K 5"25 double density
460 },
461 { // 4 360K 5"25 double density
462 },
463 { // 5 720K 5"25 double density
464 },
465
466 // Non-COCO formats, with a sector base ID of zero.
467
468 { // 6 87.5K 5 1/4 inch single density
469 },
470 { // 7 100K 5 1/4 inch single density
471 },
472 { // 8 200K 5 1/4 inch single density
473 },
474 { // 9 175K 5 1/4 inch single density
475 },
476 { // 10 200K 5 1/4 inch single density
477 },
478 { // 11 400K 5 1/4 inch single density
479 },
480 { // 12 138.5K 5 1/4 inch double density (single density track 0)
481 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
482 4000, 10, 35, 1, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
483 },
484 { // 13 140K 5 1/4 inch double density
485 },
486 { // 14 278.5K 5 1/4 inch double density (single density track 0)
487 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
488 4000, 10, 35, 2, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
489 },
490 { // 15 280K 5 1/4 inch double density
491 },
492 { // 16 158.5K 5 1/4 inch double density (single density track 0)
493 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
494 4000, 10, 40, 1, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
495 },
496 { // 17 160K 5 1/4 inch double density
497 },
498 { // 18 318.5K 5 1/4 inch double density (single density track 0)
499 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
500 4000, 10, 40, 2, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
501 },
502 { // 19 320K 5 1/4 inch double density
503 },
504 { // 20 318.5K 5 1/4 inch double density (single density track 0)
505 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
506 4000, 10, 80, 1, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
507 },
508 { // 21 320K 5 1/4 inch double density
509 },
510 { // 22 638.5 5 1/4 inch double density (single density track 0)
511 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
512 4000, 10, 80, 2, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
513 },
514 { // 23 640K 5 1/4 inch double density
515 },
516 { // 24 155.5K 5 1/4 inch double density (single density track 0)
517 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
518 4000, 10, 35, 1, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
519 },
520 { // 25 157.5K 5 1/4 inch double density
521 },
522 { // 26 311K 5 1/4 inch double density (single density track 0)
523 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
524 4000, 10, 35, 2, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
525 },
526 { // 27 315K 5 1/4 inch double density
527 },
528 { // 28 178K 5 1/4 inch double density (single density track 0)
529 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
530 4000, 10, 40, 1, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
531 },
532 { // 29 180K 5 1/4 inch double density
533 },
534 { // 30 356K 5 1/4 inch double density (single density track 0)
535 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
536 4000, 10, 40, 2, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
537 },
538 { // 31 360K 5 1/4 inch double density
539 },
540 { // 32 358K 5 1/4 inch quad density (single density track 0)
541 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
542 4000, 10, 80, 1, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
543 },
544 { // 33 360K 5 1/4 inch quad density
545 },
546 { // 34 716K 5 1/4 inch quad density (single density track 0)
547 floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
548 4000, 10, 80, 2, 256, {}, -1, {0, 3, 6, 9, 2, 5, 8, 1, 4, 7}, 40, 16, 11
549 },
550 { // 35 720K 5 1/4 inch quad density
551 },
552 { // 36 288.75K 8 inch single density
553 },
554 { // 37 577.5K 8 inch single density
555 },
556 { // 38 308K 8 inch single density
557 },
558 { // 39 616K 8 inch single density
559 },
560 { // 40 497.75K 8 inch double density (single density track 0)
561 floppy_image::FF_8, floppy_image::DSSD, floppy_image::FM,
562 2000, 15, 77, 1, 256, {}, -1, {0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13}, 40, 12, 12
563 },
564 { // 41 500.5K 8 inch double density
565 },
566 { // 42 995.5K 8 inch double density (single density track 0)
567 floppy_image::FF_8, floppy_image::DSSD, floppy_image::FM,
568 2000, 15, 77, 2, 256, {}, -1, {0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13}, 40, 12, 12
569 },
570 { // 43 1001K 8 inch double density
571 },
572 { // 44 1440K 3 1/2 inch high density (single density track 0)
573 floppy_image::FF_35, floppy_image::DSSD, floppy_image::FM,
574 2000, 18, 80, 2, 256, {}, -1, {0, 5, 10, 15, 2, 7, 12, 17, 4, 9, 14, 1, 6, 11, 16, 3, 8, 13}, 40, 12, 12
575 },
576 { // 45 1440K 3 1/2 inch high density.
577 },
578 {}
579 };
580
581 const floppy_format_type FLOPPY_OS9_FORMAT = &floppy_image_format_creator<os9_format>;
582