1 /*
2 
3   FDI to raw bit stream converter
4   Copyright (c) 2001 by Toni Wilen <twilen@arabuusimiehet.com>
5   FDI 2.0 support
6   Copyright (c) 2003-2004 by Toni Wilen <twilen@arabuusimiehet.com>
7       and Vincent Joguin
8 
9   FDI format created by Vincent "ApH" Joguin
10 
11   Tiny changes - function type fixes, multiple drives, addition of
12   get_last_head and C++ callability - by Thomas Harte, 2001,
13   T.Harte@excite.co.uk
14 
15 
16   This program is free software; you can redistribute it and/or modify it
17   under the terms of the GNU General Public License as published by the Free
18   Software Foundation; either version 2 of the License, or (at your option)
19   any later version.
20 
21   This program is distributed in the hope that it will be useful, but WITHOUT
22   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
24   more details.
25 
26   You should have received a copy of the GNU General Public License along
27   with this program; if not, write to the Free Software Foundation, Inc.,
28   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
29 
30 */
31 
32 #define STATIC_INLINE
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <stdint.h>
37 
38 /* IF UAE */
39 /*#include "sysconfig.h"
40 #include "sysdeps.h"
41 #include "zfile.h"*/
42 /* ELSE */
43 //#include "types.h"
44 #define xmalloc malloc
45 #include "fdi2raw.h"
46 
47 #include "ibm.h"
48 
49 #undef DEBUG
50 #define VERBOSE
51 #undef VERBOSE
52 
53 #include <assert.h>
54 
55 #ifdef DEBUG
datalog(uae_u8 * src,int len)56 static char *datalog(uae_u8 *src, int len)
57 {
58 	static char buf[1000];
59 	static int offset;
60 	int i = 0, offset2;
61 
62 	offset2 = offset;
63 	buf[offset++]='\'';
64 	while(len--) {
65 		sprintf (buf + offset, "%02.2X", src[i]);
66 		offset += 2;
67 		i++;
68 		if (i > 10) break;
69 	}
70 	buf[offset++]='\'';
71 	buf[offset++] = 0;
72 	if (offset >= 900) offset = 0;
73 	return buf + offset2;
74 }
75 #else
datalog(uae_u8 * src,int len)76 static char *datalog(uae_u8 *src, int len) { return ""; }
77 #endif
78 
79 #define outlog pclog
80 #define debuglog pclog
81 
82 static int fdi_allocated;
83 #ifdef DEBUG
fdi_free(void * p)84 static void fdi_free (void *p)
85 {
86 	int size;
87 	if (!p)
88 		return;
89 	size = ((int*)p)[-1];
90 	fdi_allocated -= size;
91 	write_log ("%d freed (%d)\n", size, fdi_allocated);
92 	free ((int*)p - 1);
93 }
fdi_malloc(int size)94 static void *fdi_malloc (int size)
95 {
96 	void *p = xmalloc (size + sizeof (int));
97 	((int*)p)[0] = size;
98 	fdi_allocated += size;
99 	write_log ("%d allocated (%d)\n", size, fdi_allocated);
100 	return (int*)p + 1;
101 }
102 #else
103 #define fdi_free free
104 #define fdi_malloc xmalloc
105 #endif
106 
107 #define MAX_SRC_BUFFER 4194304
108 #define MAX_DST_BUFFER 40000
109 #define MAX_MFM_SYNC_BUFFER 60000
110 #define MAX_TIMING_BUFFER 400000
111 #define MAX_TRACKS 166
112 
113 struct fdi_cache {
114 	uae_u32 *avgp, *minp, *maxp;
115 	uae_u8 *idxp;
116 	int avg_free, idx_free, min_free, max_free;
117 	uae_u32 totalavg, pulses, maxidx, indexoffset;
118 	int weakbits;
119 	int lowlevel;
120 };
121 
122 struct fdi {
123 	uae_u8 *track_src_buffer;
124 	uae_u8 *track_src;
125 	int track_src_len;
126 	uae_u8 *track_dst_buffer;
127 	uae_u8 *track_dst;
128 	uae_u16 *track_dst_buffer_timing;
129 	uae_u8 track_len;
130 	uae_u8 track_type;
131 	int current_track;
132 	int last_track;
133 	int last_head;
134 	int rotation_speed;
135 	int bit_rate;
136 	int disk_type;
137 	int write_protect;
138 	int err;
139 	uae_u8 header[2048];
140 	int track_offsets[MAX_TRACKS];
141 	FILE *file;
142 	int out;
143 	int mfmsync_offset;
144 	int *mfmsync_buffer;
145 	/* sector described only */
146 	int index_offset;
147 	int encoding_type;
148 	/* bit handling */
149 	int nextdrop;
150 	struct fdi_cache cache[MAX_TRACKS];
151 };
152 
153 #define get_u32(x) ((((x)[0])<<24)|(((x)[1])<<16)|(((x)[2])<<8)|((x)[3]))
154 #define get_u24(x) ((((x)[0])<<16)|(((x)[1])<<8)|((x)[2]))
put_u32(uae_u8 * d,uae_u32 v)155 STATIC_INLINE void put_u32 (uae_u8 *d, uae_u32 v)
156 {
157 	d[0] = v >> 24;
158 	d[1] = v >> 16;
159 	d[2] = v >> 8;
160 	d[3] = v;
161 }
162 
163 struct node {
164 	uae_u16 v;
165 	struct node *left;
166 	struct node *right;
167 };
168 typedef struct node NODE;
169 
170 static uae_u8 temp, temp2;
171 
expand_tree(uae_u8 * stream,NODE * node)172 static uae_u8 *expand_tree (uae_u8 *stream, NODE *node)
173 {
174 	if (temp & temp2) {
175 		fdi_free (node->left);
176 		node->left = 0;
177 		fdi_free (node->right);
178 		node->right = 0;
179 		temp2 >>= 1;
180 		if (!temp2) {
181 			temp = *stream++;
182 			temp2 = 0x80;
183 		}
184 		return stream;
185 	} else {
186 		uae_u8 *stream_temp;
187 		temp2 >>= 1;
188 		if (!temp2) {
189 			temp = *stream++;
190 			temp2 = 0x80;
191 		}
192 		node->left = fdi_malloc (sizeof (NODE));
193 		memset (node->left, 0, sizeof (NODE));
194 		stream_temp = expand_tree (stream, node->left);
195 		node->right = fdi_malloc (sizeof (NODE));
196 		memset (node->right, 0, sizeof (NODE));
197 		return expand_tree (stream_temp, node->right);
198 	}
199 }
200 
values_tree8(uae_u8 * stream,NODE * node)201 static uae_u8 *values_tree8 (uae_u8 *stream, NODE *node)
202 {
203 	if (node->left == 0) {
204 		node->v = *stream++;
205 		return stream;
206 	} else {
207 		uae_u8 *stream_temp = values_tree8 (stream, node->left);
208 		return values_tree8 (stream_temp, node->right);
209 	}
210 }
211 
values_tree16(uae_u8 * stream,NODE * node)212 static uae_u8 *values_tree16 (uae_u8 *stream, NODE *node)
213 {
214 	if (node->left == 0) {
215 		uae_u16 high_8_bits = (*stream++) << 8;
216 		node->v = high_8_bits | (*stream++);
217 		return stream;
218 	} else {
219 		uae_u8 *stream_temp = values_tree16 (stream, node->left);
220 		return values_tree16 (stream_temp, node->right);
221 	}
222 }
223 
free_nodes(NODE * node)224 static void free_nodes (NODE *node)
225 {
226 	if (node) {
227 		free_nodes (node->left);
228 		free_nodes (node->right);
229 		fdi_free (node);
230 	}
231 }
232 
sign_extend16(uae_u32 v)233 static uae_u32 sign_extend16 (uae_u32 v)
234 {
235 	if (v & 0x8000)
236 		v |= 0xffff0000;
237 	return v;
238 }
239 
sign_extend8(uae_u32 v)240 static uae_u32 sign_extend8 (uae_u32 v)
241 {
242 	if (v & 0x80)
243 		v |= 0xffffff00;
244 	return v;
245 }
246 
fdi_decode(uae_u8 * stream,int size,uae_u8 * out)247 static void fdi_decode (uae_u8 *stream, int size, uae_u8 *out)
248 {
249 	int i;
250 	uae_u8 sign_extend, sixteen_bit, sub_stream_shift;
251 	NODE root;
252 	NODE *current_node;
253 
254 	memset (out, 0, size * 4);
255 	sub_stream_shift = 1;
256 	while (sub_stream_shift) {
257 
258 		//sub-stream header decode
259 		sign_extend = *stream++;
260 		sub_stream_shift = sign_extend & 0x7f;
261 		sign_extend &= 0x80;
262 		sixteen_bit = (*stream++) & 0x80;
263 
264 		//huffman tree architecture decode
265 		temp = *stream++;
266 		temp2 =	0x80;
267 		stream = expand_tree (stream, &root);
268 		if (temp2 == 0x80)
269 			stream--;
270 
271 		//huffman output values	decode
272 		if (sixteen_bit)
273 			stream = values_tree16 (stream, &root);
274 		else
275 			stream = values_tree8 (stream, &root);
276 
277 		//sub-stream data decode
278 		temp2 =	0;
279 		for (i = 0; i < size; i++) {
280 			uae_u32 v;
281 			uae_u8 decode = 1;
282 			current_node = &root;
283 			while (decode) {
284 				if (current_node->left == 0) {
285 					decode = 0;
286 				} else {
287 					temp2 >>= 1;
288 					if (!temp2) {
289 						temp2 = 0x80;
290 						temp = *stream++;
291 					}
292 					if (temp & temp2)
293 						current_node = current_node->right;
294 					else
295 						current_node = current_node->left;
296 				}
297 			}
298 			v = ((uae_u32*)out)[i];
299 			if (sign_extend) {
300 				if (sixteen_bit)
301 					v |= sign_extend16 (current_node->v) << sub_stream_shift;
302 				else
303 					v |= sign_extend8 (current_node->v) << sub_stream_shift;
304 			} else {
305 				v |= current_node->v << sub_stream_shift;
306 			}
307 			((uae_u32*)out)[i] = v;
308 		}
309 		free_nodes (root.left);
310 		free_nodes (root.right);
311 	}
312 }
313 
314 
decode_raw_track(FDI * fdi)315 static int decode_raw_track (FDI *fdi)
316 {
317 	int size = get_u32(fdi->track_src);
318 	memcpy (fdi->track_dst, fdi->track_src, (size + 7) >> 3);
319 	fdi->track_src += (size + 7) >> 3;
320 	return size;
321 }
322 
323 /* unknown track */
zxx(FDI * fdi)324 static void zxx (FDI *fdi)
325 {
326 	outlog ("track %d: unknown track type 0x%02.2X\n", fdi->current_track, fdi->track_type);
327 //	return -1;
328 }
329 /* unsupported track */
330 #if 0
331 static void zyy (FDI *fdi)
332 {
333 	outlog ("track %d: unsupported track type 0x%02.2X\n", fdi->current_track, fdi->track_type);
334 //	return -1;
335 }
336 #endif
337 /* empty track */
track_empty(FDI * fdi)338 static void track_empty (FDI *fdi)
339 {
340 //	return 0;
341 }
342 
343 /* unknown sector described type */
dxx(FDI * fdi)344 static void dxx (FDI *fdi)
345 {
346 	outlog ("\ntrack %d: unknown sector described type 0x%02.2X\n", fdi->current_track, fdi->track_type);
347 	fdi->err = 1;
348 }
349 /* unsupported sector described type */
350 #if 0
351 static void dyy (FDI *fdi)
352 {
353 	outlog ("\ntrack %d: unsupported sector described 0x%02.2X\n", fdi->current_track, fdi->track_type);
354 	fdi->err = 1;
355 }
356 #endif
357 /* add position of mfm sync bit */
add_mfm_sync_bit(FDI * fdi)358 static void add_mfm_sync_bit (FDI *fdi)
359 {
360 	if (fdi->nextdrop) {
361 		fdi->nextdrop = 0;
362 		return;
363 	}
364 	fdi->mfmsync_buffer[fdi->mfmsync_offset++] = fdi->out;
365 	if (fdi->out == 0) {
366 		outlog ("illegal position for mfm sync bit, offset=%d\n",fdi->out);
367 		fdi->err = 1;
368 	}
369 	if (fdi->mfmsync_offset >= MAX_MFM_SYNC_BUFFER) {
370 		fdi->mfmsync_offset = 0;
371 		outlog ("mfmsync buffer overflow\n");
372 		fdi->err = 1;
373 	}
374 	fdi->out++;
375 }
376 
377 #define BIT_BYTEOFFSET ((fdi->out) >> 3)
378 #define BIT_BITOFFSET (7-((fdi->out)&7))
379 
380 /* add one bit */
bit_add(FDI * fdi,int bit)381 static void bit_add (FDI *fdi, int bit)
382 {
383 	if (fdi->nextdrop) {
384 		fdi->nextdrop = 0;
385 		return;
386 	}
387 	fdi->track_dst[BIT_BYTEOFFSET] &= ~(1 << BIT_BITOFFSET);
388 	if (bit)
389 		fdi->track_dst[BIT_BYTEOFFSET] |= (1 << BIT_BITOFFSET);
390 	fdi->out++;
391 	if (fdi->out >= MAX_DST_BUFFER * 8) {
392 		outlog ("destination buffer overflow\n");
393 		fdi->err = 1;
394 		fdi->out = 1;
395 	}
396 }
397 /* add bit and mfm sync bit */
bit_mfm_add(FDI * fdi,int bit)398 static void bit_mfm_add (FDI *fdi, int bit)
399 {
400 	add_mfm_sync_bit (fdi);
401 	bit_add (fdi, bit);
402 }
403 /* remove following bit */
bit_drop_next(FDI * fdi)404 static void bit_drop_next (FDI *fdi)
405 {
406 	if (fdi->nextdrop > 0) {
407 		outlog("multiple bit_drop_next() called");
408 	} else if (fdi->nextdrop < 0) {
409 		fdi->nextdrop = 0;
410 		debuglog(":DNN:");
411 		return;
412 	}
413 	debuglog(":DN:");
414 	fdi->nextdrop = 1;
415 }
416 
417 /* ignore next bit_drop_next() */
bit_dedrop(FDI * fdi)418 static void bit_dedrop (FDI *fdi)
419 {
420 	if (fdi->nextdrop) {
421 		outlog("bit_drop_next called before bit_dedrop");
422 	}
423 	fdi->nextdrop = -1;
424 	debuglog(":BDD:");
425 }
426 
427 /* add one byte */
byte_add(FDI * fdi,uae_u8 v)428 static void byte_add (FDI *fdi, uae_u8 v)
429 {
430 	int i;
431 	for (i = 7; i >= 0; i--)
432 		bit_add (fdi, v & (1 << i));
433 }
434 /* add one word */
word_add(FDI * fdi,uae_u16 v)435 static void word_add (FDI *fdi, uae_u16 v)
436 {
437 	byte_add (fdi, (uae_u8)(v >> 8));
438 	byte_add (fdi, (uae_u8)v);
439 }
440 /* add one byte and mfm encode it */
byte_mfm_add(FDI * fdi,uae_u8 v)441 static void byte_mfm_add (FDI *fdi, uae_u8 v)
442 {
443 	int i;
444 	for (i = 7; i >= 0; i--)
445 		bit_mfm_add (fdi, v & (1 << i));
446 }
447 /* add multiple bytes and mfm encode them */
bytes_mfm_add(FDI * fdi,uae_u8 v,int len)448 static void bytes_mfm_add (FDI *fdi, uae_u8 v, int len)
449 {
450 	int i;
451 	for (i = 0; i < len; i++) byte_mfm_add (fdi, v);
452 }
453 /* add one mfm encoded word and re-mfm encode it */
word_post_mfm_add(FDI * fdi,uae_u16 v)454 static void word_post_mfm_add (FDI *fdi, uae_u16 v)
455 {
456 	int i;
457 	for (i = 14; i >= 0; i -= 2)
458 		bit_mfm_add (fdi, v & (1 << i));
459 }
460 
461 /* bit 0 */
s00(FDI * fdi)462 static void s00(FDI *fdi) { bit_add (fdi, 0); }
463 /* bit 1*/
s01(FDI * fdi)464 static void s01(FDI *fdi) { bit_add (fdi, 1); }
465 /* 4489 */
s02(FDI * fdi)466 static void s02(FDI *fdi) { word_add (fdi, 0x4489); }
467 /* 5224 */
s03(FDI * fdi)468 static void s03(FDI *fdi) { word_add (fdi, 0x5224); }
469 /* mfm sync bit */
s04(FDI * fdi)470 static void s04(FDI *fdi) { add_mfm_sync_bit (fdi); }
471 /* RLE MFM-encoded data */
s08(FDI * fdi)472 static void s08(FDI *fdi)
473 {
474 	int bytes = *fdi->track_src++;
475 	uae_u8 byte = *fdi->track_src++;
476 	if (bytes == 0) bytes = 256;
477 	debuglog ("s08:len=%d,data=%02.2X",bytes,byte);
478 	while(bytes--) byte_add (fdi, byte);
479 }
480 /* RLE MFM-decoded data */
s09(FDI * fdi)481 static void s09(FDI *fdi)
482 {
483 	int bytes = *fdi->track_src++;
484 	uae_u8 byte = *fdi->track_src++;
485 	if (bytes == 0) bytes = 256;
486 	bit_drop_next (fdi);
487 	debuglog ("s09:len=%d,data=%02.2X",bytes,byte);
488 	while(bytes--) byte_mfm_add (fdi, byte);
489 }
490 /* MFM-encoded data */
s0a(FDI * fdi)491 static void s0a(FDI *fdi)
492 {
493 	int i, bits = (fdi->track_src[0] << 8) | fdi->track_src[1];
494 	uae_u8 b;
495 	fdi->track_src += 2;
496 	debuglog ("s0a:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
497 	while (bits >= 8) {
498 		byte_add (fdi, *fdi->track_src++);
499 		bits -= 8;
500 	}
501 	if (bits > 0) {
502 		i = 7;
503 		b = *fdi->track_src++;
504 		while (bits--) {
505 			bit_add (fdi, b & (1 << i));
506 			i--;
507 		}
508 	}
509 }
510 /* MFM-encoded data */
s0b(FDI * fdi)511 static void s0b(FDI *fdi)
512 {
513 	int i, bits = ((fdi->track_src[0] << 8) | fdi->track_src[1]) + 65536;
514 	uae_u8 b;
515 	fdi->track_src += 2;
516 	debuglog ("s0b:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
517 	while (bits >= 8) {
518 		byte_add (fdi, *fdi->track_src++);
519 		bits -= 8;
520 	}
521 	if (bits > 0) {
522 		i = 7;
523 		b = *fdi->track_src++;
524 		while (bits--) {
525 			bit_add (fdi, b & (1 << i));
526 			i--;
527 		}
528 	}
529 }
530 /* MFM-decoded data */
s0c(FDI * fdi)531 static void s0c(FDI *fdi)
532 {
533 	int i, bits = (fdi->track_src[0] << 8) | fdi->track_src[1];
534 	uae_u8 b;
535 	fdi->track_src += 2;
536 	bit_drop_next (fdi);
537 	debuglog ("s0c:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
538 	while (bits >= 8) {
539 		byte_mfm_add (fdi, *fdi->track_src++);
540 		bits -= 8;
541 	}
542 	if (bits > 0) {
543 		i = 7;
544 		b = *fdi->track_src++;
545 		while(bits--) {
546 			bit_mfm_add (fdi, b & (1 << i));
547 			i--;
548 		}
549 	}
550 }
551 /* MFM-decoded data */
s0d(FDI * fdi)552 static void s0d(FDI *fdi)
553 {
554 	int i, bits = ((fdi->track_src[0] << 8) | fdi->track_src[1]) + 65536;
555 	uae_u8 b;
556 	fdi->track_src += 2;
557 	bit_drop_next (fdi);
558 	debuglog ("s0d:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
559 	while (bits >= 8) {
560 		byte_mfm_add (fdi, *fdi->track_src++);
561 		bits -= 8;
562 	}
563 	if (bits > 0) {
564 		i = 7;
565 		b = *fdi->track_src++;
566 		while(bits--) {
567 			bit_mfm_add (fdi, b & (1 << i));
568 			i--;
569 		}
570 	}
571 }
572 
573 /* ***** */
574 /* AMIGA */
575 /* ***** */
576 
577 /* just for testing integrity of Amiga sectors */
578 
579 /*static void rotateonebit (uae_u8 *start, uae_u8 *end, int shift)
580 {
581 	if (shift == 0)
582 		return;
583 	while (start <= end) {
584 		start[0] <<= shift;
585 		start[0] |= start[1] >> (8 - shift);
586 		start++;
587 	}
588 }*/
589 
590 //static int check_offset;
591 /*static uae_u16 getmfmword (uae_u8 *mbuf)
592 {
593 	uae_u32 v;
594 
595 	v = (mbuf[0] << 8) | (mbuf[1] << 0);
596 	if (check_offset == 0)
597 		return v;
598 	v <<= 8;
599 	v |= mbuf[2];
600 	v >>= check_offset;
601 	return v;
602 }*/
603 
604 #define MFMMASK 0x55555555
605 /*static uae_u32 getmfmlong (uae_u8 * mbuf)
606 {
607 	return ((getmfmword (mbuf) << 16) | getmfmword (mbuf + 2)) & MFMMASK;
608 }*/
609 
610 #if 0
611 static int amiga_check_track (FDI *fdi)
612 {
613 	int i, j, secwritten = 0;
614 	int fwlen = fdi->out / 8;
615 	int length = 2 * fwlen;
616 	int drvsec = 11;
617 	uae_u32 odd, even, chksum, id, dlong;
618 	uae_u8 *secdata;
619 	uae_u8 secbuf[544];
620 	uae_u8 bigmfmbuf[60000];
621 	uae_u8 *mbuf, *mbuf2, *mend;
622 	char sectable[22];
623 	uae_u8 *raw = fdi->track_dst_buffer;
624 	int slabel, off;
625 	int ok = 1;
626 
627 	memset (bigmfmbuf, 0, sizeof (bigmfmbuf));
628 	mbuf = bigmfmbuf;
629 	check_offset = 0;
630 	for (i = 0; i < (fdi->out + 7) / 8; i++)
631 		*mbuf++ = raw[i];
632 	off = fdi->out & 7;
633 #if 1
634 	if (off > 0) {
635 		mbuf--;
636 		*mbuf &= ~((1 << (8 - off)) - 1);
637 	}
638 	j = 0;
639 	while (i < (fdi->out + 7) / 8 + 600) {
640 		*mbuf++ |= (raw[j] >> off) | ((raw[j + 1]) << (8 - off));
641 		j++;
642 		i++;
643 	}
644 #endif
645 	mbuf = bigmfmbuf;
646 
647 	memset (sectable, 0, sizeof (sectable));
648 	//memcpy (mbuf + fwlen, mbuf, fwlen * sizeof (uae_u16));
649 	mend = bigmfmbuf + length;
650 	mend -= (4 + 16 + 8 + 512);
651 
652 	while (secwritten < drvsec) {
653 		int trackoffs;
654 
655 		for (;;) {
656 			rotateonebit (bigmfmbuf, mend, 1);
657 			if (getmfmword (mbuf) == 0)
658 				break;
659 			if (secwritten == 10) {
660 				mbuf[0] = 0x44;
661 				mbuf[1] = 0x89;
662 			}
663 //			check_offset++;
664 			if (check_offset > 7) {
665 				check_offset = 0;
666 				mbuf++;
667 				if (mbuf >= mend || *mbuf == 0)
668 					break;
669 			}
670 			if (getmfmword (mbuf) == 0x4489)
671 				break;
672 		}
673 		if (mbuf >= mend || *mbuf == 0)
674 			break;
675 
676 		rotateonebit (bigmfmbuf, mend, check_offset);
677 		check_offset = 0;
678 
679 		while (getmfmword (mbuf) == 0x4489)
680 			mbuf+= 1 * 2;
681 		mbuf2 =	mbuf + 8;
682 
683 		odd = getmfmlong (mbuf);
684 		even = getmfmlong (mbuf + 2 * 2);
685 		mbuf +=	4 * 2;
686 		id = (odd << 1) | even;
687 
688 		trackoffs = (id & 0xff00) >> 8;
689 		if (trackoffs + 1 > drvsec) {
690 			outlog("illegal sector offset %d\n",trackoffs);
691 			ok = 0;
692 			mbuf = mbuf2;
693 			continue;
694 		}
695 		if ((id >> 24) != 0xff) {
696 			outlog ("sector %d format type %02.2X?\n", trackoffs, id >> 24);
697 			ok = 0;
698 		}
699 		chksum = odd ^ even;
700 		slabel = 0;
701 		for (i = 0; i < 4; i++) {
702 			odd = getmfmlong (mbuf);
703 			even = getmfmlong (mbuf + 8 * 2);
704 			mbuf += 2* 2;
705 
706 			dlong = (odd << 1) | even;
707 			if (dlong) slabel = 1;
708 			chksum ^= odd ^ even;
709 		}
710 		mbuf += 8 * 2;
711 		odd = getmfmlong (mbuf);
712 		even = getmfmlong (mbuf + 2 * 2);
713 		mbuf += 4 * 2;
714 		if (((odd << 1) | even) != chksum) {
715 			outlog("sector %d header crc error\n", trackoffs);
716 			ok = 0;
717 			mbuf = mbuf2;
718 			continue;
719 		}
720 		outlog("sector %d header crc ok\n", trackoffs);
721 		if (((id & 0x00ff0000) >> 16) != (uae_u32)fdi->current_track) {
722 			outlog("illegal track number %d <> %d\n",fdi->current_track,(id & 0x00ff0000) >> 16);
723 			ok++;
724 			mbuf = mbuf2;
725 			continue;
726 		}
727 		odd = getmfmlong (mbuf);
728 		even = getmfmlong (mbuf + 2 * 2);
729 		mbuf += 4 * 2;
730 		chksum = (odd << 1) | even;
731 		secdata = secbuf + 32;
732 		for (i = 0; i < 128; i++) {
733 			odd = getmfmlong (mbuf);
734 			even = getmfmlong (mbuf + 256 * 2);
735 			mbuf += 2 * 2;
736 			dlong = (odd << 1) | even;
737 			*secdata++ = (uae_u8) (dlong >> 24);
738 			*secdata++ = (uae_u8) (dlong >> 16);
739 			*secdata++ = (uae_u8) (dlong >> 8);
740 			*secdata++ = (uae_u8) dlong;
741 			chksum ^= odd ^ even;
742 		}
743 		mbuf += 256 * 2;
744 		if (chksum) {
745 			outlog("sector %d data checksum error\n",trackoffs);
746 			ok = 0;
747 		} else if (sectable[trackoffs]) {
748 			outlog("sector %d already found?\n", trackoffs);
749 			mbuf = mbuf2;
750 		} else {
751 			outlog("sector %d ok\n",trackoffs);
752 			if (slabel) outlog("(non-empty sector header)\n");
753 			sectable[trackoffs] = 1;
754 			secwritten++;
755 			if (trackoffs == 9)
756 				mbuf += 0x228;
757 		}
758 	}
759 	for (i = 0; i < drvsec; i++) {
760 		if (!sectable[i]) {
761 			outlog ("sector %d missing\n", i);
762 			ok = 0;
763 		}
764 	}
765 	return ok;
766 }
767 #endif
768 
amiga_data_raw(FDI * fdi,uae_u8 * secbuf,uae_u8 * crc,int len)769 static void amiga_data_raw (FDI *fdi, uae_u8 *secbuf, uae_u8 *crc, int len)
770 {
771 	int i;
772 	uae_u8 crcbuf[4];
773 
774 	if (!crc) {
775 		memset (crcbuf, 0, 4);
776 	} else {
777 		memcpy (crcbuf, crc ,4);
778 	}
779 	for (i = 0; i < 4; i++)
780 		byte_mfm_add (fdi, crcbuf[i]);
781 	for (i = 0; i < len; i++)
782 		byte_mfm_add (fdi, secbuf[i]);
783 }
784 
amiga_data(FDI * fdi,uae_u8 * secbuf)785 static void amiga_data (FDI *fdi, uae_u8 *secbuf)
786 {
787 	uae_u16 mfmbuf[4 + 512];
788 	uae_u32 dodd, deven, dck;
789 	int i;
790 
791 	for (i = 0; i < 512; i += 4) {
792 		deven = ((secbuf[i + 0] << 24) | (secbuf[i + 1] << 16)
793 		 | (secbuf[i + 2] << 8) | (secbuf[i + 3]));
794 		dodd = deven >> 1;
795 		deven &= 0x55555555;
796 		dodd &= 0x55555555;
797 		mfmbuf[(i >> 1) + 4] = (uae_u16) (dodd >> 16);
798 		mfmbuf[(i >> 1) + 5] = (uae_u16) dodd;
799 		mfmbuf[(i >> 1) + 256 + 4] = (uae_u16) (deven >> 16);
800 		mfmbuf[(i >> 1) + 256 + 5] = (uae_u16) deven;
801 	}
802 	dck = 0;
803 	for (i = 4; i < 4 + 512; i += 2)
804 		dck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1];
805 	deven = dodd = dck;
806 	dodd >>= 1;
807 	deven &= 0x55555555;
808 	dodd &= 0x55555555;
809 	mfmbuf[0] = (uae_u16) (dodd >> 16);
810 	mfmbuf[1] = (uae_u16) dodd;
811 	mfmbuf[2] = (uae_u16) (deven >> 16);
812 	mfmbuf[3] = (uae_u16) deven;
813 
814 	for (i = 0; i < 4 + 512; i ++)
815 		word_post_mfm_add (fdi, mfmbuf[i]);
816 }
817 
amiga_sector_header(FDI * fdi,uae_u8 * header,uae_u8 * data,int sector,int untilgap)818 static void amiga_sector_header	(FDI *fdi, uae_u8 *header, uae_u8 *data, int sector, int untilgap)
819 {
820 	uae_u8 headerbuf[4], databuf[16];
821 	uae_u32 deven, dodd, hck;
822 	uae_u16 mfmbuf[24];
823 	int i;
824 
825 	byte_mfm_add (fdi, 0);
826 	byte_mfm_add (fdi, 0);
827 	word_add (fdi, 0x4489);
828 	word_add (fdi, 0x4489);
829 	if (header) {
830 		memcpy (headerbuf, header, 4);
831 	} else {
832 		headerbuf[0] = 0xff;
833 		headerbuf[1] = (uae_u8)fdi->current_track;
834 		headerbuf[2] = (uae_u8)sector;
835 		headerbuf[3] = (uae_u8)untilgap;
836 	}
837 	if (data)
838 		memcpy (databuf, data, 16);
839 	else
840 		memset (databuf, 0, 16);
841 
842 	deven =	((headerbuf[0] << 24) | (headerbuf[1] << 16)
843 		| (headerbuf[2] << 8) | (headerbuf[3]));
844 	dodd = deven >> 1;
845 	deven &= 0x55555555;
846 	dodd &= 0x55555555;
847 	mfmbuf[0] = (uae_u16) (dodd >> 16);
848 	mfmbuf[1] = (uae_u16) dodd;
849 	mfmbuf[2] = (uae_u16) (deven >> 16);
850 	mfmbuf[3] = (uae_u16) deven;
851 	for (i = 0; i < 16; i += 4) {
852 		deven = ((databuf[i] << 24) | (databuf[i + 1] << 16)
853 			| (databuf[i + 2] << 8) | (databuf[i + 3]));
854 		dodd = deven >> 1;
855 		deven &= 0x55555555;
856 		dodd &= 0x55555555;
857 		mfmbuf[(i >> 1) + 0 + 4] = (uae_u16) (dodd >> 16);
858 		mfmbuf[(i >> 1) + 0 + 5] = (uae_u16) dodd;
859 		mfmbuf[(i >> 1) + 8 + 4] = (uae_u16) (deven >> 16);
860 		mfmbuf[(i >> 1) + 8 + 5] = (uae_u16) deven;
861 	}
862 	hck = 0;
863 	for (i = 0; i < 4 + 16; i += 2)
864 		hck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1];
865 	deven = dodd = hck;
866 	dodd >>= 1;
867 	deven &= 0x55555555;
868 	dodd &= 0x55555555;
869 	mfmbuf[20] = (uae_u16) (dodd >> 16);
870 	mfmbuf[21] = (uae_u16) dodd;
871 	mfmbuf[22] = (uae_u16) (deven >> 16);
872 	mfmbuf[23] = (uae_u16) deven;
873 
874 	for (i = 0; i < 4 + 16 + 4; i ++)
875 		word_post_mfm_add (fdi, mfmbuf[i]);
876 }
877 
878 /* standard super-extended Amiga sector header */
s20(FDI * fdi)879 static void s20(FDI *fdi)
880 {
881 	bit_drop_next (fdi);
882 	debuglog ("s20:header=%s,data=%s", datalog(fdi->track_src, 4), datalog(fdi->track_src + 4, 16));
883 	amiga_sector_header (fdi, fdi->track_src, fdi->track_src + 4, 0, 0);
884 	fdi->track_src += 4 + 16;
885 }
886 /* standard extended Amiga sector header */
s21(FDI * fdi)887 static void s21(FDI *fdi)
888 {
889 	bit_drop_next (fdi);
890 	debuglog ("s21:header=%s", datalog(fdi->track_src, 4));
891 	amiga_sector_header (fdi, fdi->track_src, 0, 0, 0);
892 	fdi->track_src += 4;
893 }
894 /* standard Amiga sector header */
s22(FDI * fdi)895 static void s22(FDI *fdi)
896 {
897 	bit_drop_next (fdi);
898 	debuglog("s22:sector=%d,untilgap=%d", fdi->track_src[0], fdi->track_src[1]);
899 	amiga_sector_header (fdi, 0, 0, fdi->track_src[0], fdi->track_src[1]);
900 	fdi->track_src += 2;
901 }
902 /* standard 512-byte, CRC-correct Amiga data */
s23(FDI * fdi)903 static void s23(FDI *fdi)
904 {
905 	debuglog("s23:data=%s", datalog (fdi->track_src, 512));
906 	amiga_data (fdi, fdi->track_src);
907 	fdi->track_src += 512;
908 }
909 /* not-decoded, 128*2^x-byte, CRC-correct Amiga data */
s24(FDI * fdi)910 static void s24(FDI *fdi)
911 {
912 	int shift = *fdi->track_src++;
913 	debuglog("s24:shift=%d,data=%s", shift, datalog (fdi->track_src, 128 << shift));
914 	amiga_data_raw (fdi, fdi->track_src, 0, 128 << shift);
915 	fdi->track_src += 128 << shift;
916 }
917 /* not-decoded, 128*2^x-byte, CRC-incorrect Amiga data */
s25(FDI * fdi)918 static void s25(FDI *fdi)
919 {
920 	int shift = *fdi->track_src++;
921 	debuglog("s25:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 128 << shift));
922 	amiga_data_raw (fdi, fdi->track_src + 4, fdi->track_src, 128 << shift);
923 	fdi->track_src += 4 + (128 << shift);
924 }
925 /* standard extended Amiga sector */
s26(FDI * fdi)926 static void s26(FDI *fdi)
927 {
928 	s21 (fdi);
929 	debuglog("s26:data=%s", datalog (fdi->track_src, 512));
930 	amiga_data (fdi, fdi->track_src);
931 	fdi->track_src += 512;
932 }
933 /* standard short Amiga sector */
s27(FDI * fdi)934 static void s27(FDI *fdi)
935 {
936 	s22 (fdi);
937 	debuglog("s27:data=%s", datalog (fdi->track_src, 512));
938 	amiga_data (fdi, fdi->track_src);
939 	fdi->track_src += 512;
940 }
941 
942 /* *** */
943 /* IBM */
944 /* *** */
945 
ibm_crc(uae_u8 byte,int reset)946 static uae_u16 ibm_crc (uae_u8 byte, int reset)
947 {
948 	static uae_u16 crc;
949 	int i;
950 
951 	if (reset) crc = 0xcdb4;
952 	for (i = 0; i < 8; i++) {
953 		if (crc & 0x8000) {
954 			crc <<= 1;
955 			if (!(byte & 0x80)) crc ^= 0x1021;
956 		} else {
957 			crc <<= 1;
958 			if (byte & 0x80) crc ^= 0x1021;
959 		}
960 		byte <<= 1;
961 	}
962 	return crc;
963 }
964 
ibm_data(FDI * fdi,uae_u8 * data,uae_u8 * crc,int len)965 static void ibm_data (FDI *fdi, uae_u8 *data, uae_u8 *crc, int len)
966 {
967 	int i;
968 	uae_u8 crcbuf[2];
969 	uae_u16 crcv = 0;
970 
971 	word_add (fdi, 0x4489);
972 	word_add (fdi, 0x4489);
973 	word_add (fdi, 0x4489);
974 	byte_mfm_add (fdi, 0xfb);
975 	ibm_crc (0xfb, 1);
976 	for (i = 0; i < len; i++) {
977 		byte_mfm_add (fdi, data[i]);
978 		crcv = ibm_crc (data[i], 0);
979 	}
980 	if (!crc) {
981 		crc = crcbuf;
982 		crc[0] = (uae_u8)(crcv >> 8);
983 		crc[1] = (uae_u8)crcv;
984 	}
985 	byte_mfm_add (fdi, crc[0]);
986 	byte_mfm_add (fdi, crc[1]);
987 }
988 
ibm_sector_header(FDI * fdi,uae_u8 * data,uae_u8 * crc,int secnum,int pre)989 static void ibm_sector_header (FDI *fdi, uae_u8 *data, uae_u8 *crc, int secnum, int pre)
990 {
991 	uae_u8 secbuf[5];
992 	uae_u8 crcbuf[2];
993 	uae_u16 crcv;
994 	int i;
995 
996 	if (pre)
997 		bytes_mfm_add (fdi, 0, 12);
998 	word_add (fdi, 0x4489);
999 	word_add (fdi, 0x4489);
1000 	word_add (fdi, 0x4489);
1001 	secbuf[0] = 0xfe;
1002 	if (secnum >= 0) {
1003 		secbuf[1] = (uae_u8)(fdi->current_track/2);
1004 		secbuf[2] = (uae_u8)(fdi->current_track%2);
1005 		secbuf[3] = (uae_u8)secnum;
1006 		secbuf[4] = 2;
1007 	} else {
1008 		memcpy (secbuf + 1, data, 4);
1009 	}
1010 	ibm_crc (secbuf[0], 1);
1011 	ibm_crc (secbuf[1], 0);
1012 	ibm_crc (secbuf[2], 0);
1013 	ibm_crc (secbuf[3], 0);
1014 	crcv = ibm_crc (secbuf[4], 0);
1015 	if (crc) {
1016 		memcpy (crcbuf, crc, 2);
1017 	} else {
1018 		crcbuf[0] = (uae_u8)(crcv >> 8);
1019 		crcbuf[1] = (uae_u8)crcv;
1020 	}
1021 	/* data */
1022 	for (i = 0;i < 5; i++)
1023 		byte_mfm_add (fdi, secbuf[i]);
1024 	/* crc */
1025 	byte_mfm_add (fdi, crcbuf[0]);
1026 	byte_mfm_add (fdi, crcbuf[1]);
1027 }
1028 
1029 /* standard IBM index address mark */
s10(FDI * fdi)1030 static void s10(FDI *fdi)
1031 {
1032 	bit_drop_next (fdi);
1033 	bytes_mfm_add (fdi, 0, 12);
1034 	word_add (fdi, 0x5224);
1035 	word_add (fdi, 0x5224);
1036 	word_add (fdi, 0x5224);
1037 	byte_mfm_add (fdi, 0xfc);
1038 }
1039 /* standard IBM pre-gap */
s11(FDI * fdi)1040 static void s11(FDI *fdi)
1041 {
1042 	bit_drop_next (fdi);
1043 	bytes_mfm_add (fdi, 0x4e, 78);
1044 	bit_dedrop (fdi);
1045 	s10 (fdi);
1046 	bytes_mfm_add (fdi, 0x4e, 50);
1047 }
1048 /* standard ST pre-gap */
s12(FDI * fdi)1049 static void s12(FDI *fdi)
1050 {
1051 	bit_drop_next (fdi);
1052 	bytes_mfm_add (fdi, 0x4e, 78);
1053 }
1054 /* standard extended IBM sector header */
s13(FDI * fdi)1055 static void s13(FDI *fdi)
1056 {
1057 	bit_drop_next (fdi);
1058 	debuglog ("s13:header=%s", datalog (fdi->track_src, 4));
1059 	ibm_sector_header (fdi, fdi->track_src, 0, -1, 1);
1060 	fdi->track_src += 4;
1061 }
1062 /* standard mini-extended IBM sector header */
s14(FDI * fdi)1063 static void s14(FDI *fdi)
1064 {
1065 	debuglog ("s14:header=%s", datalog (fdi->track_src, 4));
1066 	ibm_sector_header (fdi, fdi->track_src, 0, -1, 0);
1067 	fdi->track_src += 4;
1068 }
1069 /* standard short IBM sector header */
s15(FDI * fdi)1070 static void s15(FDI *fdi)
1071 {
1072 	bit_drop_next (fdi);
1073 	debuglog ("s15:sector=%d", *fdi->track_src);
1074 	ibm_sector_header (fdi, 0, 0, *fdi->track_src++, 1);
1075 }
1076 /* standard mini-short IBM sector header */
s16(FDI * fdi)1077 static void s16(FDI *fdi)
1078 {
1079 	debuglog ("s16:track=%d", *fdi->track_src);
1080 	ibm_sector_header (fdi, 0, 0, *fdi->track_src++, 0);
1081 }
1082 /* standard CRC-incorrect mini-extended IBM sector header */
s17(FDI * fdi)1083 static void s17(FDI *fdi)
1084 {
1085 	debuglog ("s17:header=%s,crc=%s", datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 2));
1086 	ibm_sector_header (fdi, fdi->track_src, fdi->track_src + 4, -1, 0);
1087 	fdi->track_src += 4 + 2;
1088 }
1089 /* standard CRC-incorrect mini-short IBM sector header */
s18(FDI * fdi)1090 static void s18(FDI *fdi)
1091 {
1092 	debuglog ("s18:sector=%d,header=%s", *fdi->track_src, datalog (fdi->track_src + 1, 4));
1093 	ibm_sector_header (fdi, 0, fdi->track_src + 1, *fdi->track_src, 0);
1094 	fdi->track_src += 1 + 4;
1095 }
1096 /* standard 512-byte CRC-correct IBM data */
s19(FDI * fdi)1097 static void s19(FDI *fdi)
1098 {
1099 	debuglog ("s19:data=%s", datalog (fdi->track_src , 512));
1100 	ibm_data (fdi, fdi->track_src, 0, 512);
1101 	fdi->track_src += 512;
1102 }
1103 /* standard 128*2^x-byte-byte CRC-correct IBM data */
s1a(FDI * fdi)1104 static void s1a(FDI *fdi)
1105 {
1106 	int shift = *fdi->track_src++;
1107 	debuglog ("s1a:shift=%d,data=%s", shift, datalog (fdi->track_src , 128 << shift));
1108 	ibm_data (fdi, fdi->track_src, 0, 128 << shift);
1109 	fdi->track_src += 128 << shift;
1110 }
1111 /* standard 128*2^x-byte-byte CRC-incorrect IBM data */
s1b(FDI * fdi)1112 static void s1b(FDI *fdi)
1113 {
1114 	int shift = *fdi->track_src++;
1115 	debuglog ("s1b:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src + (128 << shift), 2), datalog (fdi->track_src , 128 << shift));
1116 	ibm_data (fdi, fdi->track_src, fdi->track_src + (128 << shift), 128 << shift);
1117 	fdi->track_src += (128 << shift) + 2;
1118 }
1119 /* standard extended IBM sector */
s1c(FDI * fdi)1120 static void s1c(FDI *fdi)
1121 {
1122 	int shift = fdi->track_src[3];
1123 	s13 (fdi);
1124 	bytes_mfm_add (fdi, 0x4e, 22);
1125 	bytes_mfm_add (fdi, 0x00, 12);
1126 	ibm_data (fdi, fdi->track_src, 0, 128 << shift);
1127 	fdi->track_src += 128 << shift;
1128 }
1129 /* standard short IBM sector */
s1d(FDI * fdi)1130 static void s1d(FDI *fdi)
1131 {
1132 	s15 (fdi);
1133 	bytes_mfm_add (fdi, 0x4e, 22);
1134 	bytes_mfm_add (fdi, 0x00, 12);
1135 	s19 (fdi);
1136 }
1137 
1138 /* end marker */
sff(FDI * fdi)1139 static void sff(FDI *fdi)
1140 {
1141 }
1142 
1143 typedef void (*decode_described_track_func)(FDI*);
1144 
1145 static decode_described_track_func decode_sectors_described_track[] =
1146 {
1147 	s00,s01,s02,s03,s04,dxx,dxx,dxx,s08,s09,s0a,s0b,s0c,s0d,dxx,dxx, /* 00-0F */
1148 	s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s1a,s1b,s1c,s1d,dxx,dxx, /* 10-1F */
1149 	s20,s21,s22,s23,s24,s25,s26,s27,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 20-2F */
1150 	dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 30-3F */
1151 	dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 40-4F */
1152 	dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 50-5F */
1153 	dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 60-6F */
1154 	dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 70-7F */
1155 	dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 80-8F */
1156 	dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 90-9F */
1157 	dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* A0-AF */
1158 	dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* B0-BF */
1159 	dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* C0-CF */
1160 	dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* D0-DF */
1161 	dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* E0-EF */
1162 	dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,sff  /* F0-FF */
1163 };
1164 
track_amiga(struct fdi * fdi,int first_sector,int max_sector)1165 static void track_amiga (struct fdi *fdi, int first_sector, int max_sector)
1166 {
1167 	int i;
1168 
1169 	bit_add (fdi, 0);
1170 	bit_drop_next (fdi);
1171 	for (i = 0; i < max_sector; i++) {
1172 		amiga_sector_header (fdi, 0, 0, first_sector, max_sector - i);
1173 		amiga_data (fdi, fdi->track_src + first_sector * 512);
1174 		first_sector++;
1175 		if (first_sector >= max_sector) first_sector = 0;
1176 	}
1177 	bytes_mfm_add (fdi, 0, 260); /* gap */
1178 }
track_atari_st(struct fdi * fdi,int max_sector)1179 static void track_atari_st (struct fdi *fdi, int max_sector)
1180 {
1181 	int i, gap3 = 0;
1182 	uae_u8 *p = fdi->track_src;
1183 
1184 	switch (max_sector)
1185 		{
1186 		case 9:
1187 		gap3 = 40;
1188 		break;
1189 		case 10:
1190 		gap3 = 24;
1191 		break;
1192 	}
1193 	s15 (fdi);
1194 	for (i = 0; i < max_sector; i++) {
1195 		byte_mfm_add (fdi, 0x4e);
1196 		byte_mfm_add (fdi, 0x4e);
1197 		ibm_sector_header (fdi, 0, 0, fdi->current_track, 1);
1198 		ibm_data (fdi, p + i * 512, 0, 512);
1199 		bytes_mfm_add (fdi, 0x4e, gap3);
1200 	}
1201 	bytes_mfm_add (fdi, 0x4e, 660 - gap3);
1202 	fdi->track_src += fdi->track_len * 256;
1203 }
track_pc(struct fdi * fdi,int max_sector)1204 static void track_pc (struct fdi *fdi, int max_sector)
1205 {
1206 	int i, gap3;
1207 	uae_u8 *p = fdi->track_src;
1208 
1209 	switch (max_sector)
1210 		{
1211 		case 8:
1212 		gap3 = 116;
1213 		break;
1214 		case 9:
1215 		gap3 = 54;
1216 		break;
1217 		default:
1218 		gap3 = 100; /* fixme */
1219 		break;
1220 	}
1221 	s11 (fdi);
1222 	for (i = 0; i < max_sector; i++) {
1223 		byte_mfm_add (fdi, 0x4e);
1224 		byte_mfm_add (fdi, 0x4e);
1225 		ibm_sector_header (fdi, 0, 0, fdi->current_track, 1);
1226 		ibm_data (fdi, p + i * 512, 0, 512);
1227 		bytes_mfm_add (fdi, 0x4e, gap3);
1228 	}
1229 	bytes_mfm_add (fdi, 0x4e, 600 - gap3);
1230 	fdi->track_src += fdi->track_len * 256;
1231 }
1232 
1233 /* amiga dd */
track_amiga_dd(struct fdi * fdi)1234 static void track_amiga_dd (struct fdi *fdi)
1235 {
1236 	uae_u8 *p = fdi->track_src;
1237 	track_amiga (fdi, fdi->track_len >> 4, 11);
1238 	fdi->track_src = p + (fdi->track_len & 15) * 512;
1239 }
1240 /* amiga hd */
track_amiga_hd(struct fdi * fdi)1241 static void track_amiga_hd (struct fdi *fdi)
1242 {
1243 	uae_u8 *p = fdi->track_src;
1244 	track_amiga (fdi, 0, 22);
1245 	fdi->track_src = p + fdi->track_len * 256;
1246 }
1247 /* atari st 9 sector */
track_atari_st_9(struct fdi * fdi)1248 static void track_atari_st_9 (struct fdi *fdi)
1249 {
1250 	track_atari_st (fdi, 9);
1251 }
1252 /* atari st 10 sector */
track_atari_st_10(struct fdi * fdi)1253 static void track_atari_st_10 (struct fdi *fdi)
1254 {
1255 	track_atari_st (fdi, 10);
1256 }
1257 /* pc 8 sector */
track_pc_8(struct fdi * fdi)1258 static void track_pc_8 (struct fdi *fdi)
1259 {
1260 	track_pc (fdi, 8);
1261 }
1262 /* pc 9 sector */
track_pc_9(struct fdi * fdi)1263 static void track_pc_9 (struct fdi *fdi)
1264 {
1265 	track_pc (fdi, 9);
1266 }
1267 /* pc 15 sector */
track_pc_15(struct fdi * fdi)1268 static void track_pc_15 (struct fdi *fdi)
1269 {
1270 	track_pc (fdi, 15);
1271 }
1272 /* pc 18 sector */
track_pc_18(struct fdi * fdi)1273 static void track_pc_18 (struct fdi *fdi)
1274 {
1275 	track_pc (fdi, 18);
1276 }
1277 /* pc 36 sector */
track_pc_36(struct fdi * fdi)1278 static void track_pc_36 (struct fdi *fdi)
1279 {
1280 	track_pc (fdi, 36);
1281 }
1282 
1283 typedef void (*decode_normal_track_func)(FDI*);
1284 
1285 static decode_normal_track_func decode_normal_track[] =
1286 {
1287 	track_empty, /* 0 */
1288 	track_amiga_dd, track_amiga_hd, /* 1-2 */
1289 	track_atari_st_9, track_atari_st_10, /* 3-4 */
1290 	track_pc_8, track_pc_9, track_pc_15, track_pc_18, track_pc_36, /* 5-9 */
1291 	zxx,zxx,zxx,zxx,zxx /* A-F */
1292 };
1293 
fix_mfm_sync(FDI * fdi)1294 static void fix_mfm_sync (FDI *fdi)
1295 {
1296 	int i, pos, off1, off2, off3, mask1, mask2, mask3;
1297 
1298 	for (i = 0; i < fdi->mfmsync_offset; i++) {
1299 		pos = fdi->mfmsync_buffer[i];
1300 		off1 = (pos - 1) >> 3;
1301 		off2 = (pos + 1) >> 3;
1302 		off3 = pos >> 3;
1303 		mask1 = 1 << (7 - ((pos - 1) & 7));
1304 		mask2 = 1 << (7 - ((pos + 1) & 7));
1305 		mask3 = 1 << (7 - (pos & 7));
1306 		if (!(fdi->track_dst[off1] & mask1) && !(fdi->track_dst[off2] & mask2))
1307 			fdi->track_dst[off3] |= mask3;
1308 		else
1309 			fdi->track_dst[off3] &= ~mask3;
1310 	}
1311 }
1312 
handle_sectors_described_track(FDI * fdi)1313 static int handle_sectors_described_track (FDI *fdi)
1314 {
1315 	int oldout;
1316 	uae_u8 *start_src = fdi->track_src ;
1317 	fdi->encoding_type = *fdi->track_src++;
1318 	fdi->index_offset = get_u32(fdi->track_src);
1319 	fdi->index_offset >>= 8;
1320 	fdi->track_src += 3;
1321 	outlog ("sectors_described, index offset: %d\n",fdi->index_offset);
1322 
1323 	do {
1324 		fdi->track_type = *fdi->track_src++;
1325 		outlog ("%06.6X %06.6X %02.2X:",fdi->track_src - start_src + 0x200, fdi->out/8, fdi->track_type);
1326 		oldout = fdi->out;
1327 		decode_sectors_described_track[fdi->track_type](fdi);
1328 		outlog(" %d\n", fdi->out - oldout);
1329 		oldout = fdi->out;
1330 		if (fdi->out < 0 || fdi->err) {
1331 			outlog ("\nin %d bytes, out %d bits\n", fdi->track_src - fdi->track_src_buffer, fdi->out);
1332 			return -1;
1333 		}
1334 		if (fdi->track_src - fdi->track_src_buffer >= fdi->track_src_len) {
1335 			outlog ("source buffer overrun, previous type: %02.2X\n", fdi->track_type);
1336 			return -1;
1337 		}
1338 	} while (fdi->track_type != 0xff);
1339 	outlog("\n");
1340 	fix_mfm_sync (fdi);
1341 	return fdi->out;
1342 }
1343 
fdi_decompress(int pulses,uae_u8 * sizep,uae_u8 * src,int * dofree)1344 static uae_u8 *fdi_decompress (int pulses, uae_u8 *sizep, uae_u8 *src, int *dofree)
1345 {
1346 	uae_u32 size = get_u24 (sizep);
1347 	uae_u32 *dst2;
1348 	int len = size & 0x3fffff;
1349 	uae_u8 *dst;
1350 	int mode = size >> 22, i;
1351 
1352 	*dofree = 0;
1353 	if (mode == 0 && pulses * 2 > len)
1354 		mode = 1;
1355 	if (mode == 0) {
1356 		dst2 = (uae_u32*)src;
1357 		dst = src;
1358 		for (i = 0; i < pulses; i++) {
1359 			*dst2++ = get_u32 (src);
1360 			src += 4;
1361 		}
1362 	} else if (mode == 1) {
1363 		dst = fdi_malloc (pulses *4);
1364 		*dofree = 1;
1365 		fdi_decode (src, pulses, dst);
1366 	} else {
1367 		dst = 0;
1368 	}
1369 	return dst;
1370 }
1371 
dumpstream(int track,uae_u8 * stream,int len)1372 static void dumpstream(int track, uae_u8 *stream, int len)
1373 {
1374 #if 0
1375     char name[100];
1376     FILE *f;
1377 
1378     sprintf (name, "track_%d.raw", track);
1379     f = fopen(name, "wb");
1380     fwrite (stream, 1, len * 4, f);
1381     fclose (f);
1382 #endif
1383 }
1384 
1385 static int bitoffset;
1386 
addbit(uae_u8 * p,int bit)1387 STATIC_INLINE void addbit (uae_u8 *p, int bit)
1388 {
1389 	int off1 = bitoffset / 8;
1390 	int off2 = bitoffset % 8;
1391 	p[off1] |= bit << (7 - off2);
1392 	bitoffset++;
1393 }
1394 
1395 
1396 struct pulse_sample {
1397 	uint32_t size;
1398 	int number_of_bits;
1399 };
1400 
1401 
1402 #define FDI_MAX_ARRAY 10 /* change this value as you want */
1403 static int pulse_limitval = 15; /* tolerance of 15% */
1404 static struct pulse_sample psarray[FDI_MAX_ARRAY];
1405 static int array_index;
1406 static unsigned	long total;
1407 static int totaldiv;
1408 
init_array(uint32_t standard_MFM_2_bit_cell_size,int nb_of_bits)1409 static void init_array(uint32_t standard_MFM_2_bit_cell_size, int nb_of_bits)
1410 {
1411 	int i;
1412 
1413 	for (i = 0; i < FDI_MAX_ARRAY; i++) {
1414 		psarray[i].size = standard_MFM_2_bit_cell_size; // That is (total track length / 50000) for Amiga double density
1415 		total += psarray[i].size;
1416 		psarray[i].number_of_bits = nb_of_bits;
1417 		totaldiv += psarray[i].number_of_bits;
1418 	}
1419 	array_index = 0;
1420 }
1421 
1422 #if 0
1423 
1424 static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *minp, uae_u32 *maxp, uae_u8 *idx, int maxidx, int *indexoffsetp, int pulses, int mfm)
1425 {
1426 	uint32_t adjust;
1427 	uint32_t adjusted_pulse;
1428 	uint32_t standard_MFM_2_bit_cell_size = totalavg / 50000;
1429 	uint32_t standard_MFM_8_bit_cell_size = totalavg / 12500;
1430 	int real_size, i, j, eodat, outstep;
1431 	int indexoffset = *indexoffsetp;
1432 	uae_u8 *d = fdi->track_dst_buffer;
1433 	uae_u16 *pt = fdi->track_dst_buffer_timing;
1434 	uae_u32 ref_pulse, pulse;
1435 
1436 	/* detects a long-enough stable pulse coming just after another stable pulse */
1437 	i = 1;
1438 	while ( (i < pulses) && ( (idx[i] < maxidx)
1439 		|| (idx[i - 1] < maxidx)
1440 		|| (avgp[i] < (standard_MFM_2_bit_cell_size - (standard_MFM_2_bit_cell_size / 4))) ) )
1441 			i++;
1442 	if (i == pulses)  {
1443 		outlog ("No stable and long-enough pulse in track.\n");
1444 		return;
1445 	}
1446 	i--;
1447 	eodat = i;
1448 	adjust = 0;
1449 	total = 0;
1450 	totaldiv = 0;
1451 	init_array(standard_MFM_2_bit_cell_size, 2);
1452 	bitoffset = 0;
1453 	ref_pulse = 0;
1454 	outstep = 0;
1455 	while (outstep < 2) {
1456 
1457 		/* calculates the current average bitrate from previous decoded data */
1458 		uae_u32 avg_size = (total << 3) / totaldiv; /* this is the new average size for one MFM bit */
1459 		/* uae_u32 avg_size = (uae_u32)((((float)total)*8.0) / ((float)totaldiv)); */
1460 		/* you can try tighter ranges than 25%, or wider ranges. I would probably go for tighter... */
1461 		if ((avg_size < (standard_MFM_8_bit_cell_size - (pulse_limitval * standard_MFM_8_bit_cell_size / 100))) ||
1462 			(avg_size > (standard_MFM_8_bit_cell_size + (pulse_limitval * standard_MFM_8_bit_cell_size / 100)))) {
1463 				//init_array(standard_MFM_2_bit_cell_size, 2);
1464 				avg_size = standard_MFM_8_bit_cell_size;
1465 		}
1466 		/* this is to prevent the average value from going too far
1467 		* from the theoretical value, otherwise it could progressively go to (2 *
1468 		* real value), or (real value / 2), etc. */
1469 
1470 		/* gets the next long-enough pulse (this may require more than one pulse) */
1471 		pulse = 0;
1472 		while (pulse < ((avg_size / 4) - (avg_size / 16))) {
1473 			int indx;
1474 			i++;
1475 			if (i >= pulses)
1476 				i = 0;
1477 			indx = idx[i];
1478 			if (rand() <= (indx * RAND_MAX) / maxidx) {
1479 				pulse += avgp[i] - ref_pulse;
1480 				if (indx >= maxidx)
1481 					ref_pulse = 0;
1482 				else
1483 					ref_pulse = avgp[i];
1484 			}
1485 			if (i == eodat)
1486 				outstep++;
1487 			if (outstep == 1 && indexoffset == i)
1488 			    *indexoffsetp = bitoffset;
1489 		}
1490 
1491 		/* gets the size in bits from the pulse width, considering the current average bitrate */
1492 		adjusted_pulse = pulse;
1493 		real_size = 0;
1494 		while (adjusted_pulse >= avg_size) {
1495 			real_size += 4;
1496 			adjusted_pulse -= avg_size / 2;
1497 		}
1498 		adjusted_pulse <<= 3;
1499 		while (adjusted_pulse >= ((avg_size * 4) + (avg_size / 4))) {
1500 			real_size += 2;
1501 			adjusted_pulse -= avg_size * 2;
1502 		}
1503 		if (adjusted_pulse >= ((avg_size * 3) + (avg_size / 4))) {
1504 			if (adjusted_pulse <= ((avg_size * 4) - (avg_size / 4))) {
1505 				if ((2 * ((adjusted_pulse >> 2) - adjust)) <= ((2 * avg_size) - (avg_size / 4)))
1506 					real_size += 3;
1507 				else
1508 					real_size += 4;
1509 			} else
1510 				real_size += 4;
1511 		} else {
1512 			if (adjusted_pulse > ((avg_size * 3) - (avg_size / 4))) {
1513 				real_size += 3;
1514 			} else {
1515 				if (adjusted_pulse >= ((avg_size * 2) + (avg_size / 4))) {
1516 					if ((2 * ((adjusted_pulse >> 2) - adjust)) < (avg_size + (avg_size / 4)))
1517 						real_size += 2;
1518 					else
1519 						real_size += 3;
1520 				} else
1521 					real_size += 2;
1522 			}
1523 		}
1524 
1525 		if (outstep == 1) {
1526 			for (j = real_size; j > 1; j--)
1527 				addbit (d, 0);
1528 			addbit (d, 1);
1529 			for (j = 0; j <	real_size; j++)
1530 				*pt++ =	(uae_u16)(pulse / real_size);
1531 		}
1532 
1533 		/* prepares for the next pulse */
1534 		adjust = ((real_size * avg_size)/8) - pulse;
1535 		total -= psarray[array_index].size;
1536 		totaldiv -= psarray[array_index].number_of_bits;
1537 		psarray[array_index].size = pulse;
1538 		psarray[array_index].number_of_bits = real_size;
1539 		total += pulse;
1540 		totaldiv += real_size;
1541 		array_index++;
1542 		if (array_index	>= FDI_MAX_ARRAY)
1543 			array_index = 0;
1544 	}
1545 
1546 	fdi->out = bitoffset;
1547 }
1548 
1549 #else
1550 
fdi2_decode(FDI * fdi,uint32_t totalavg,uae_u32 * avgp,uae_u32 * minp,uae_u32 * maxp,uae_u8 * idx,int maxidx,int * indexoffsetp,int pulses,int mfm)1551 static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *minp, uae_u32 *maxp, uae_u8 *idx, int maxidx, int *indexoffsetp, int pulses, int mfm)
1552 {
1553 	uint32_t adjust;
1554 	uint32_t adjusted_pulse;
1555 	uint32_t standard_MFM_2_bit_cell_size = totalavg / 50000;
1556 	uint32_t standard_MFM_8_bit_cell_size = totalavg / 12500;
1557 	int real_size, i, j, nexti, eodat, outstep, randval;
1558 	int indexoffset = *indexoffsetp;
1559 	uae_u8 *d = fdi->track_dst_buffer;
1560 	uae_u16	*pt = fdi->track_dst_buffer_timing;
1561 	uae_u32 ref_pulse, pulse;
1562 	long jitter;
1563 
1564 	/* detects a long-enough stable pulse coming just after another stable pulse */
1565 	i = 1;
1566 	while ( (i < pulses) && ( (idx[i] < maxidx)
1567 		|| (idx[i - 1] < maxidx)
1568 		|| (minp[i] < (standard_MFM_2_bit_cell_size - (standard_MFM_2_bit_cell_size / 4))) ) )
1569 			i++;
1570 	if (i == pulses)  {
1571 		outlog ("FDI: No stable and long-enough pulse in track.\n");
1572 		return;
1573 	}
1574 	nexti = i;
1575 	eodat = i;
1576 	i--;
1577 	adjust = 0;
1578 	total = 0;
1579 	totaldiv = 0;
1580 	init_array(standard_MFM_2_bit_cell_size, 1 + mfm);
1581 	bitoffset = 0;
1582 	ref_pulse = 0;
1583 	jitter = 0;
1584 	outstep = -1;
1585 	while (outstep < 2) {
1586 
1587 		/* calculates the current average bitrate from previous decoded data */
1588 		uae_u32 avg_size = (total << (2 + mfm)) / totaldiv; /* this is the new average size for one MFM bit */
1589 		/* uae_u32 avg_size = (uae_u32)((((float)total)*((float)(mfm+1))*4.0) / ((float)totaldiv)); */
1590 		/* you can try tighter ranges than 25%, or wider ranges. I would probably go for tighter... */
1591 		if ((avg_size < (standard_MFM_8_bit_cell_size - (pulse_limitval * standard_MFM_8_bit_cell_size / 100))) ||
1592 			(avg_size > (standard_MFM_8_bit_cell_size + (pulse_limitval * standard_MFM_8_bit_cell_size / 100)))) {
1593 				//init_array(standard_MFM_2_bit_cell_size, mfm + 1);
1594 				avg_size = standard_MFM_8_bit_cell_size;
1595 		}
1596 		/* this	is to prevent the average value from going too far
1597 		* from the theoretical value, otherwise it could progressively go to (2 *
1598 		* real value), or (real value / 2), etc. */
1599 
1600 		/* gets the next long-enough pulse (this may require more than one pulse) */
1601 		pulse = 0;
1602 		while (pulse < ((avg_size / 4) - (avg_size / 16))) {
1603 			uae_u32 avg_pulse, min_pulse, max_pulse;
1604 			i++;
1605 			if (i >= pulses)
1606 				i = 0;
1607 			if (i == nexti) {
1608 				do {
1609 					nexti++;
1610 					if (nexti >= pulses)
1611 						nexti = 0;
1612 				} while (idx[nexti] < maxidx);
1613 			}
1614 			if (idx[i] >= maxidx) { /* stable pulse */
1615 				avg_pulse = avgp[i] - jitter;
1616 				min_pulse = minp[i];
1617 				max_pulse = maxp[i];
1618 				if (jitter >= 0)
1619 					max_pulse -= jitter;
1620 				else
1621 					min_pulse -= jitter;
1622 				if ((maxp[nexti] - avgp[nexti]) < (avg_pulse - min_pulse))
1623 					min_pulse = avg_pulse - (maxp[nexti] - avgp[nexti]);
1624 				if ((avgp[nexti] - minp[nexti]) < (max_pulse - avg_pulse))
1625 					max_pulse = avg_pulse + (avgp[nexti] - minp[nexti]);
1626 				if (min_pulse < ref_pulse)
1627 					min_pulse = ref_pulse;
1628 				randval = rand();
1629 				if (randval < (RAND_MAX / 2)) {
1630 					if (randval > (RAND_MAX / 4)) {
1631 						if (randval <= (3 * RAND_MAX / 8))
1632 							randval = (2 * randval) - (RAND_MAX /4);
1633 						else
1634 							randval = (4 * randval) - RAND_MAX;
1635 					}
1636 					jitter = 0 - (randval * (avg_pulse - min_pulse)) / RAND_MAX;
1637 				} else {
1638 					randval -= RAND_MAX / 2;
1639 					if (randval > (RAND_MAX / 4)) {
1640 						if (randval <= (3 * RAND_MAX / 8))
1641 							randval = (2 * randval) - (RAND_MAX /4);
1642 						else
1643 							randval = (4 * randval) - RAND_MAX;
1644 					}
1645 					jitter = (randval * (max_pulse - avg_pulse)) / RAND_MAX;
1646 				}
1647 				avg_pulse += jitter;
1648 				if ((avg_pulse < min_pulse) || (avg_pulse > max_pulse)) {
1649 					outlog ("FDI: avg_pulse outside bounds! avg=%u min=%u max=%u\n", avg_pulse, min_pulse, max_pulse);
1650 					outlog ("FDI: avgp=%u (%u) minp=%u (%u) maxp=%u (%u) jitter=%d i=%d ni=%d\n",
1651 						avgp[i], avgp[nexti], minp[i], minp[nexti], maxp[i], maxp[nexti], jitter, i, nexti);
1652 				}
1653 				if (avg_pulse < ref_pulse)
1654 					outlog ("FDI: avg_pulse < ref_pulse! (%u < %u)\n", avg_pulse, ref_pulse);
1655 				pulse += avg_pulse - ref_pulse;
1656 				ref_pulse = 0;
1657 				if (i == eodat)
1658 					outstep++;
1659 			} else if (rand() <= ((idx[i] * RAND_MAX) / maxidx)) {
1660 				avg_pulse = avgp[i];
1661 				min_pulse = minp[i];
1662 				max_pulse = maxp[i];
1663 				randval = rand();
1664 				if (randval < (RAND_MAX / 2)) {
1665 					if (randval > (RAND_MAX / 4)) {
1666 						if (randval <= (3 * RAND_MAX / 8))
1667 							randval = (2 * randval) - (RAND_MAX /4);
1668 						else
1669 							randval = (4 * randval) - RAND_MAX;
1670 					}
1671 					avg_pulse -= (randval * (avg_pulse - min_pulse)) / RAND_MAX;
1672 				} else {
1673 					randval -= RAND_MAX / 2;
1674 					if (randval > (RAND_MAX / 4)) {
1675 						if (randval <= (3 * RAND_MAX / 8))
1676 							randval = (2 * randval) - (RAND_MAX /4);
1677 						else
1678 							randval = (4 * randval) - RAND_MAX;
1679 					}
1680 					avg_pulse += (randval * (max_pulse - avg_pulse)) / RAND_MAX;
1681 				}
1682 				if ((avg_pulse > ref_pulse) && (avg_pulse < (avgp[nexti] - jitter))) {
1683 					pulse += avg_pulse - ref_pulse;
1684 					ref_pulse = avg_pulse;
1685 				}
1686 			}
1687 			if (outstep == 1 && indexoffset == i)
1688 			    *indexoffsetp = bitoffset;
1689 		}
1690 
1691 		/* gets the size in bits from the pulse width, considering the current average bitrate */
1692 		adjusted_pulse = pulse;
1693 		real_size = 0;
1694 		if (mfm) {
1695 		    while (adjusted_pulse >= avg_size) {
1696 			    real_size += 4;
1697 			    adjusted_pulse -= avg_size / 2;
1698 		    }
1699 		    adjusted_pulse <<= 3;
1700 		    while (adjusted_pulse >= ((avg_size * 4) + (avg_size / 4))) {
1701 			    real_size += 2;
1702 			    adjusted_pulse -= avg_size * 2;
1703 		    }
1704 		    if (adjusted_pulse >= ((avg_size * 3) + (avg_size / 4))) {
1705 			    if (adjusted_pulse <= ((avg_size * 4) - (avg_size / 4))) {
1706 				    if ((2 * ((adjusted_pulse >> 2) - adjust)) <= ((2 * avg_size) - (avg_size / 4)))
1707 					    real_size += 3;
1708 				    else
1709 					    real_size += 4;
1710 			    } else
1711 				    real_size += 4;
1712 		    } else {
1713 			    if (adjusted_pulse > ((avg_size * 3) - (avg_size / 4))) {
1714 				    real_size += 3;
1715 			    } else {
1716 				    if (adjusted_pulse >= ((avg_size * 2) + (avg_size / 4))) {
1717 					    if ((2 * ((adjusted_pulse >> 2) - adjust)) < (avg_size + (avg_size / 4)))
1718 						    real_size += 2;
1719 					    else
1720 						    real_size += 3;
1721 				    } else
1722 					    real_size += 2;
1723 			    }
1724 		    }
1725 		} else {
1726 		    while (adjusted_pulse >= (2*avg_size))
1727 		    {
1728 			    real_size+=4;
1729 			    adjusted_pulse-=avg_size;
1730 		    }
1731 		    adjusted_pulse<<=2;
1732 		    while (adjusted_pulse >= ((avg_size*3)+(avg_size/4)))
1733 		    {
1734 			    real_size+=2;
1735 			    adjusted_pulse-=avg_size*2;
1736 		    }
1737 		    if (adjusted_pulse >= ((avg_size*2)+(avg_size/4)))
1738 		    {
1739 			    if (adjusted_pulse <= ((avg_size*3)-(avg_size/4)))
1740 			    {
1741 				    if (((adjusted_pulse>>1)-adjust) < (avg_size+(avg_size/4)))
1742 					    real_size+=2;
1743 				    else
1744 					    real_size+=3;
1745 			    }
1746 			    else
1747 				    real_size+=3;
1748 		    }
1749 		    else
1750 		    {
1751 			    if (adjusted_pulse > ((avg_size*2)-(avg_size/4)))
1752 				    real_size+=2;
1753 			    else
1754 			    {
1755 				    if (adjusted_pulse >= (avg_size+(avg_size/4)))
1756 				    {
1757 					    if (((adjusted_pulse>>1)-adjust) <= (avg_size-(avg_size/4)))
1758 						    real_size++;
1759 					    else
1760 						    real_size+=2;
1761 				    }
1762 				    else
1763 					    real_size++;
1764 			    }
1765 		    }
1766 		}
1767 
1768 		/* after one pass to correctly initialize the average bitrate, outputs the bits */
1769 		if (outstep == 1) {
1770 			for (j = real_size; j > 1; j--)
1771 				addbit (d, 0);
1772 			addbit (d, 1);
1773 			for (j = 0; j < real_size; j++)
1774 				*pt++ = (uae_u16)(pulse / real_size);
1775 		}
1776 
1777 		/* prepares for the next pulse */
1778 		adjust = ((real_size * avg_size) / (4 << mfm)) - pulse;
1779 		total -= psarray[array_index].size;
1780 		totaldiv -= psarray[array_index].number_of_bits;
1781 		psarray[array_index].size = pulse;
1782 		psarray[array_index].number_of_bits = real_size;
1783 		total += pulse;
1784 		totaldiv += real_size;
1785 		array_index++;
1786 		if (array_index >= FDI_MAX_ARRAY)
1787 			array_index = 0;
1788 	}
1789 
1790 	fdi->out = bitoffset;
1791 }
1792 
1793 #endif
1794 
fdi2_celltiming(FDI * fdi,uint32_t totalavg,int bitoffset,uae_u16 * out)1795 static void fdi2_celltiming (FDI *fdi, uint32_t totalavg, int bitoffset, uae_u16 *out)
1796 {
1797 	uae_u16 *pt2, *pt;
1798 	double avg_bit_len;
1799 	int i;
1800 
1801 	avg_bit_len = (double)totalavg / (double)bitoffset;
1802 	pt2 = fdi->track_dst_buffer_timing;
1803 	pt = out;
1804 	for (i = 0; i < bitoffset / 8; i++) {
1805 		double v = (pt2[0] + pt2[1] + pt2[2] + pt2[3] + pt2[4] + pt2[5] + pt2[6] + pt2[7]) / 8.0;
1806 		v = 1000.0 * v / avg_bit_len;
1807 		*pt++ = (uae_u16)v;
1808 		pt2 += 8;
1809 	}
1810 	*pt++ = out[0];
1811 	*pt = out[0];
1812 }
1813 
decode_lowlevel_track(FDI * fdi,int track,struct fdi_cache * cache)1814 static int decode_lowlevel_track (FDI *fdi, int track, struct fdi_cache *cache)
1815 {
1816 	uae_u8 *p1;
1817 	uae_u32 *p2;
1818 	uae_u32 *avgp, *minp = 0, *maxp = 0;
1819 	uae_u8 *idxp = 0;
1820 	uae_u32 maxidx, totalavg, weakbits;
1821 	int i, j, len, pulses, indexoffset;
1822 	int avg_free, min_free = 0, max_free = 0, idx_free;
1823 	int idx_off1 = 0, idx_off2 = 0, idx_off3 = 0;
1824 
1825 //	d = fdi->track_dst;
1826 	p1 = fdi->track_src;
1827 	pulses = get_u32 (p1);
1828 	if (!pulses)
1829 		return -1;
1830 	p1 += 4;
1831 	len = 12;
1832 	avgp = (uae_u32*)fdi_decompress (pulses, p1 + 0, p1 + len, &avg_free);
1833 	dumpstream(track, (uae_u8*)avgp, pulses);
1834 	len += get_u24 (p1 + 0) & 0x3fffff;
1835 	if (!avgp)
1836 		return -1;
1837 	if (get_u24 (p1 + 3) && get_u24 (p1 + 6)) {
1838 		minp = (uae_u32*)fdi_decompress (pulses, p1 + 3, p1 + len, &min_free);
1839 		len += get_u24 (p1 + 3) & 0x3fffff;
1840 		maxp = (uae_u32*)fdi_decompress (pulses, p1 + 6, p1 + len, &max_free);
1841 		len += get_u24 (p1 + 6) & 0x3fffff;
1842 		/* Computes the real min and max values */
1843 		for (i = 0; i < pulses; i++) {
1844 			maxp[i] = avgp[i] + minp[i] - maxp[i];
1845 			minp[i] = avgp[i] - minp[i];
1846 		}
1847 	} else {
1848 		minp = avgp;
1849 		maxp = avgp;
1850 	}
1851 	if (get_u24 (p1 + 9)) {
1852 		idx_off1 = 0;
1853 		idx_off2 = 1;
1854 		idx_off3 = 2;
1855 		idxp = fdi_decompress (pulses, p1 + 9, p1 + len, &idx_free);
1856 		if (idx_free) {
1857 			if (idxp[0] == 0 && idxp[1] == 0) {
1858 				idx_off1 = 2;
1859 				idx_off2 = 3;
1860 			} else {
1861 				idx_off1 = 1;
1862 				idx_off2 = 0;
1863 			}
1864 			idx_off3 = 4;
1865 		}
1866 	} else {
1867 		idxp = fdi_malloc (pulses * 2);
1868 		idx_free = 1;
1869 		for (i = 0; i < pulses; i++) {
1870 			idxp[i * 2 + 0] = 2;
1871 			idxp[i * 2 + 1] = 0;
1872 		}
1873 		idxp[0] = 1;
1874 		idxp[1] = 1;
1875 	}
1876 
1877 	maxidx = 0;
1878 	indexoffset = 0;
1879 	p1 = idxp;
1880 	for (i = 0; i < pulses; i++) {
1881 		if (p1[idx_off1] + p1[idx_off2] > maxidx)
1882 			maxidx = p1[idx_off1] + p1[idx_off2];
1883 		p1 += idx_off3;
1884 	}
1885 	p1 = idxp;
1886 	for (i = 0; (i < pulses) && (p1[idx_off2] != 0); i++) /* falling edge, replace with idx_off1 for rising edge */
1887 		p1 += idx_off3;
1888 	if (i < pulses) {
1889 		j = i;
1890 		do {
1891 			i++;
1892 			p1 += idx_off3;
1893 			if (i >= pulses) {
1894 				i = 0;
1895 				p1 = idxp;
1896 			}
1897 		} while ((i != j) && (p1[idx_off2] == 0)); /* falling edge, replace with idx_off1 for rising edge */
1898 		if (i != j) /* index pulse detected */
1899 		{
1900 			while ((i != j) && (p1[idx_off1] > p1[idx_off2])) { /* falling edge, replace with "<" for rising edge */
1901 				i++;
1902 				p1 += idx_off3;
1903 				if (i >= pulses) {
1904 					i = 0;
1905 					p1 = idxp;
1906 				}
1907 			}
1908 			if (i != j)
1909 				indexoffset = i; /* index position detected */
1910 		}
1911 	}
1912 	p1 = idxp;
1913 	p2 = avgp;
1914 	totalavg = 0;
1915 	weakbits = 0;
1916 	for (i = 0; i < pulses; i++) {
1917 		int sum = p1[idx_off1] + p1[idx_off2];
1918 		if (sum >= maxidx) {
1919 			totalavg += *p2;
1920 		} else {
1921 			weakbits++;
1922 		}
1923 		p2++;
1924 		p1 += idx_off3;
1925 		idxp[i] = sum;
1926 	}
1927 	len = totalavg / 100000;
1928 	outlog("totalavg=%u index=%d (%d) maxidx=%d weakbits=%d len=%d\n",
1929 		totalavg, indexoffset, maxidx, weakbits, len);
1930 	cache->avgp = avgp;
1931 	cache->idxp = idxp;
1932 	cache->minp = minp;
1933 	cache->maxp = maxp;
1934 	cache->avg_free = avg_free;
1935 	cache->idx_free = idx_free;
1936 	cache->min_free = min_free;
1937 	cache->max_free = max_free;
1938 	cache->totalavg = totalavg;
1939 	cache->pulses = pulses;
1940 	cache->maxidx = maxidx;
1941 	cache->indexoffset = indexoffset;
1942 	cache->weakbits = weakbits;
1943 	cache->lowlevel = 1;
1944 
1945 	return 1;
1946 }
1947 
1948 static unsigned char fdiid[]={"Formatted Disk Image file"};
1949 static int bit_rate_table[16] = { 125,150,250,300,500,1000 };
1950 
fdi2raw_header_free(FDI * fdi)1951 void fdi2raw_header_free (FDI *fdi)
1952 {
1953 	int i;
1954 
1955 	fdi_free (fdi->mfmsync_buffer);
1956 	fdi_free (fdi->track_src_buffer);
1957 	fdi_free (fdi->track_dst_buffer);
1958 	fdi_free (fdi->track_dst_buffer_timing);
1959 	for (i = 0; i <	MAX_TRACKS; i++) {
1960 		struct fdi_cache *c = &fdi->cache[i];
1961 		if (c->idx_free)
1962 			fdi_free (c->idxp);
1963 		if (c->avg_free)
1964 			fdi_free (c->avgp);
1965 		if (c->min_free)
1966 			fdi_free (c->minp);
1967 		if (c->max_free)
1968 			fdi_free (c->maxp);
1969 	}
1970 	fdi_free (fdi);
1971 	debuglog ("FREE: memory allocated %d\n", fdi_allocated);
1972 }
1973 
fdi2raw_get_last_track(FDI * fdi)1974 int fdi2raw_get_last_track (FDI *fdi)
1975 {
1976 	return fdi->last_track;
1977 }
1978 
fdi2raw_get_num_sector(FDI * fdi)1979 int fdi2raw_get_num_sector (FDI *fdi)
1980 {
1981 	if (fdi->header[152] == 0x02)
1982 		return 22;
1983 	return 11;
1984 }
1985 
fdi2raw_get_last_head(FDI * fdi)1986 int fdi2raw_get_last_head (FDI *fdi)
1987 {
1988 	return fdi->last_head;
1989 }
1990 
fdi2raw_get_rotation(FDI * fdi)1991 int fdi2raw_get_rotation (FDI *fdi)
1992 {
1993 	return fdi->rotation_speed;
1994 }
1995 
fdi2raw_get_bit_rate(FDI * fdi)1996 int fdi2raw_get_bit_rate (FDI *fdi)
1997 {
1998 	return fdi->bit_rate;
1999 }
2000 
fdi2raw_get_type(FDI * fdi)2001 int fdi2raw_get_type (FDI *fdi)
2002 {
2003 	return fdi->disk_type;
2004 }
2005 
fdi2raw_get_write_protect(FDI * fdi)2006 int fdi2raw_get_write_protect (FDI *fdi)
2007 {
2008 	return fdi->write_protect;
2009 }
2010 
fdi2raw_header(FILE * f)2011 FDI *fdi2raw_header(FILE *f)
2012 {
2013 	int i, offset, oldseek;
2014 	uae_u8 type, size;
2015 	FDI *fdi;
2016 
2017 	debuglog ("ALLOC: memory allocated %d\n", fdi_allocated);
2018 	fdi = fdi_malloc(sizeof(FDI));
2019 	memset (fdi, 0, sizeof (FDI));
2020 	fdi->file = f;
2021 	oldseek = ftell (fdi->file);
2022 	fseek (fdi->file, 0, SEEK_SET);
2023 	fread (fdi->header, 2048, 1, fdi->file);
2024 	fseek (fdi->file, oldseek, SEEK_SET);
2025 	if (memcmp (fdiid, fdi->header, strlen ((char *)fdiid)) ) {
2026 		fdi_free(fdi);
2027 		return NULL;
2028 	}
2029 	if ((fdi->header[140] != 1 && fdi->header[140] != 2) || (fdi->header[141] != 0 && !(fdi->header[140]==2 && fdi->header[141]==1))) {
2030 		fdi_free(fdi);
2031 		return NULL;
2032 	}
2033 
2034 	fdi->mfmsync_buffer = fdi_malloc (MAX_MFM_SYNC_BUFFER * sizeof(int));
2035 	fdi->track_src_buffer = fdi_malloc (MAX_SRC_BUFFER);
2036 	fdi->track_dst_buffer = fdi_malloc (MAX_DST_BUFFER);
2037 	fdi->track_dst_buffer_timing = fdi_malloc (MAX_TIMING_BUFFER);
2038 
2039 	fdi->last_track = ((fdi->header[142] << 8) + fdi->header[143]) + 1;
2040 	fdi->last_track *= fdi->header[144] + 1;
2041 	if (fdi->last_track > MAX_TRACKS)
2042 		fdi->last_track = MAX_TRACKS;
2043 	fdi->last_head = fdi->header[144];
2044 	fdi->disk_type = fdi->header[145];
2045 	fdi->rotation_speed = fdi->header[146] + 128;
2046 	fdi->write_protect = fdi->header[147] & 1;
2047 	outlog ("FDI version %d.%d\n", fdi->header[140], fdi->header[141]);
2048 	outlog ("last_track=%d rotation_speed=%d\n",fdi->last_track,fdi->rotation_speed);
2049 
2050 	offset = 512;
2051 	i = fdi->last_track;
2052 	if (i > 180) {
2053 		offset += 512;
2054 		i -= 180;
2055 		while (i > 256) {
2056 			offset += 512;
2057 			i -= 256;
2058 		}
2059 	}
2060 	for (i = 0; i < fdi->last_track; i++) {
2061 		fdi->track_offsets[i] = offset;
2062 		type = fdi->header[152 + i * 2];
2063 		size = fdi->header[152 + i * 2 + 1];
2064 		if (type == 1)
2065 			offset += (size & 15) * 512;
2066 		else if ((type & 0xc0) == 0x80)
2067 			offset += (((type & 0x3f) << 8) | size) * 256;
2068 		else
2069 			offset += size * 256;
2070 	}
2071 	fdi->track_offsets[i] = offset;
2072 
2073 	return fdi;
2074 }
2075 
2076 
fdi2raw_loadrevolution_2(FDI * fdi,uae_u16 * mfmbuf,uae_u16 * tracktiming,int track,int * tracklength,int * indexoffsetp,int * multirev,int mfm)2077 int fdi2raw_loadrevolution_2 (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int *indexoffsetp, int *multirev, int mfm)
2078 {
2079 	struct fdi_cache *cache = &fdi->cache[track];
2080 	int len, i, idx;
2081 
2082 	memset (fdi->track_dst_buffer, 0, MAX_DST_BUFFER);
2083 	idx = cache->indexoffset;
2084 	fdi2_decode (fdi, cache->totalavg,
2085 		cache->avgp, cache->minp, cache->maxp, cache->idxp,
2086 		cache->maxidx, &idx, cache->pulses, mfm);
2087 	//fdi2_gcr_decode (fdi, totalavg, avgp, minp, maxp, idxp, idx_off1, idx_off2, idx_off3, maxidx, pulses);
2088 	outlog("track %d: nbits=%d avg len=%.2f weakbits=%d idx=%d\n",
2089 		track, bitoffset, (double)cache->totalavg / bitoffset, cache->weakbits, cache->indexoffset);
2090 	len = fdi->out;
2091 	if (cache->weakbits >= 10 && multirev)
2092 		*multirev = 1;
2093 	*tracklength = len;
2094 
2095 	for (i = 0; i < (len + 15) / (2 * 8); i++) {
2096 		uae_u8 *data = fdi->track_dst_buffer + i * 2;
2097 		*mfmbuf++ = 256 * *data + *(data + 1);
2098 	}
2099 	fdi2_celltiming (fdi, cache->totalavg, len, tracktiming);
2100 	if (indexoffsetp)
2101 		*indexoffsetp = idx;
2102 	return 1;
2103 }
2104 
fdi2raw_loadrevolution(FDI * fdi,uae_u16 * mfmbuf,uae_u16 * tracktiming,int track,int * tracklength,int mfm)2105 int fdi2raw_loadrevolution (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int mfm)
2106 {
2107 	return fdi2raw_loadrevolution_2 (fdi, mfmbuf, tracktiming, track, tracklength, 0, 0, mfm);
2108 }
2109 
fdi2raw_loadtrack(FDI * fdi,uae_u16 * mfmbuf,uae_u16 * tracktiming,int track,int * tracklength,int * indexoffsetp,int * multirev,int mfm)2110 int fdi2raw_loadtrack (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int *indexoffsetp, int *multirev, int mfm)
2111 {
2112 	uae_u8 *p;
2113 	int outlen, i;
2114 	struct fdi_cache *cache = &fdi->cache[track];
2115 
2116 	if (cache->lowlevel)
2117 		return fdi2raw_loadrevolution_2 (fdi, mfmbuf, tracktiming, track, tracklength, indexoffsetp, multirev, mfm);
2118 
2119 	fdi->err = 0;
2120 	fdi->track_src_len = fdi->track_offsets[track + 1] - fdi->track_offsets[track];
2121 	fseek (fdi->file, fdi->track_offsets[track], SEEK_SET);
2122 	fread (fdi->track_src_buffer, fdi->track_src_len, 1, fdi->file);
2123 	memset (fdi->track_dst_buffer, 0, MAX_DST_BUFFER);
2124 	fdi->track_dst_buffer_timing[0] = 0;
2125 
2126 	fdi->current_track = track;
2127 	fdi->track_src = fdi->track_src_buffer;
2128 	fdi->track_dst = fdi->track_dst_buffer;
2129 	p = fdi->header + 152 + fdi->current_track * 2;
2130 	fdi->track_type = *p++;
2131 	fdi->track_len = *p++;
2132 	fdi->bit_rate = 0;
2133 	fdi->out = 0;
2134 	fdi->mfmsync_offset = 0;
2135 
2136 	if ((fdi->track_type & 0xf0) == 0xf0 || (fdi->track_type & 0xf0) == 0xe0)
2137 		fdi->bit_rate = bit_rate_table[fdi->track_type & 0x0f];
2138 	else
2139 		fdi->bit_rate = 250;
2140 
2141 	outlog ("track %d: srclen: %d track_type: %02.2X, bitrate: %d\n",
2142 		fdi->current_track, fdi->track_src_len, fdi->track_type, fdi->bit_rate);
2143 
2144 	if ((fdi->track_type & 0xc0) == 0x80) {
2145 
2146 		outlen = decode_lowlevel_track (fdi, track, cache);
2147 
2148 	} else if ((fdi->track_type & 0xf0) == 0xf0) {
2149 
2150 		outlen = decode_raw_track (fdi);
2151 
2152 	} else if ((fdi->track_type & 0xf0) == 0xe0) {
2153 
2154 		outlen = handle_sectors_described_track (fdi);
2155 
2156 	} else if ((fdi->track_type & 0xf0)) {
2157 
2158 		zxx (fdi);
2159 		outlen = -1;
2160 
2161 	} else if (fdi->track_type < 0x10) {
2162 
2163 		decode_normal_track[fdi->track_type](fdi);
2164 		fix_mfm_sync (fdi);
2165 		outlen = fdi->out;
2166 
2167 	} else {
2168 
2169 		zxx (fdi);
2170 		outlen = -1;
2171 
2172 	}
2173 
2174 //	amiga_check_track (fdi);
2175 
2176 	if (fdi->err)
2177 		return 0;
2178 
2179 	if (outlen > 0) {
2180 		if (cache->lowlevel)
2181 			return fdi2raw_loadrevolution_2 (fdi, mfmbuf, tracktiming, track, tracklength, indexoffsetp, multirev, mfm);
2182 		*tracklength = fdi->out;
2183 		for (i = 0; i < ((*tracklength) + 15) / (2 * 8); i++) {
2184 			uae_u8 *data = fdi->track_dst_buffer + i * 2;
2185 			*mfmbuf++ = 256 * *data + *(data + 1);
2186 		}
2187 	}
2188 	return outlen;
2189 }
2190 
2191