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