revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / diskimage / plugins / fdi / fdi2raw.c
blob2e1803a0c82e372ea98a1f697f444bb8393f718e
1 /*
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
9 FDI format created by Vincent "ApH" Joguin
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
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.
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.
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
32 #define STATIC_INLINE static inline
34 #include <exec/memory.h>
35 #include <proto/exec.h>
36 #include <proto/dos.h>
37 #include <stdlib.h>
38 #include <string.h>
40 extern struct Library *SysBase;
41 extern struct Library *DOSBase;
43 /* IF UAE */
44 //#include "sysconfig.h"
45 //#include "sysdeps.h"
46 //#include "zfile.h"
47 /* ELSE */
48 //#include "types.h"
50 #include "fdi2raw.h"
52 #ifdef __AROS__
53 #undef RAND_MAX
54 #define RAND_MAX 0x7fffffff
56 unsigned long long rnd_seed = 0;
57 int rand (void)
59 rnd_seed = ((rnd_seed * 1103515245ULL) + 12345ULL) & 0xffffffffULL;
60 return (int)(rnd_seed & RAND_MAX);
62 #endif
64 #undef DEBUG
65 #undef VERBOSE
67 #ifdef DEBUG
68 static const char *datalog (const uae_u8 *src, unsigned int len)
70 static char buf[1000];
71 static int offset;
72 int i = 0, offset2;
74 offset2 = offset;
75 buf[offset++]='\'';
76 while (len--) {
77 sprintf (buf + offset, "%02.2X", src[i]);
78 offset += 2;
79 i++;
80 if (i > 10) break;
82 buf[offset++]='\'';
83 buf[offset++] = 0;
84 if (offset >= 900) offset = 0;
85 return buf + offset2;
87 #else
88 static const char *datalog (const uae_u8 *src, unsigned int len) { return ""; }
89 #endif
91 #ifdef DEBUG
92 #define debuglog write_log
93 #else
94 #define debuglog(...) do { ; } while (0)
95 #endif
96 #ifdef VERBOSE
97 #define outlog write_log
98 #else
99 #define outlog(...) do { ; } while (0)
100 #endif
102 #define fdi_free(ptr) FreeVec(ptr)
103 #define fdi_malloc(size) AllocVec(size, MEMF_ANY|MEMF_CLEAR)
105 #define MAX_SRC_BUFFER 4194304
106 #define MAX_DST_BUFFER 40000
107 #define MAX_MFM_SYNC_BUFFER 60000
108 #define MAX_TIMING_BUFFER 400000
109 #define MAX_TRACKS 166
111 struct fdi_cache {
112 uae_u32 *avgp, *minp, *maxp;
113 uae_u8 *idxp;
114 unsigned int avg_free, idx_free, min_free, max_free;
115 uae_u32 totalavg, pulses, maxidx, indexoffset;
116 unsigned int weakbits;
117 int lowlevel;
120 struct fdi {
121 uae_u8 *track_src_buffer;
122 uae_u8 *track_src;
123 int track_src_len;
124 uae_u8 *track_dst_buffer;
125 uae_u8 *track_dst;
126 uae_u16 *track_dst_buffer_timing;
127 uae_u8 track_len;
128 uae_u8 track_type;
129 unsigned int current_track;
130 unsigned int last_track;
131 unsigned int last_head;
132 unsigned int rotation_speed;
133 unsigned int bit_rate;
134 int disk_type;
135 int write_protect;
136 int err;
137 uae_u8 header[2048];
138 unsigned int track_offsets[MAX_TRACKS];
139 BPTR file;
140 int out;
141 int mfmsync_offset;
142 int *mfmsync_buffer;
143 /* sector described only */
144 int index_offset;
145 int encoding_type;
146 /* bit handling */
147 int nextdrop;
148 struct fdi_cache cache[MAX_TRACKS];
151 #define get_u32(x) ((((x)[0])<<24)|(((x)[1])<<16)|(((x)[2])<<8)|((x)[3]))
152 #define get_u24(x) ((((x)[0])<<16)|(((x)[1])<<8)|((x)[2]))
153 STATIC_INLINE void put_u32 (uae_u8 *d, uae_u32 v)
155 d[0] = v >> 24;
156 d[1] = v >> 16;
157 d[2] = v >> 8;
158 d[3] = v;
161 struct node {
162 uae_u16 v;
163 struct node *left;
164 struct node *right;
166 typedef struct node NODE;
168 static uae_u8 temp, temp2;
170 static const uae_u8 *expand_tree (const uae_u8 *stream, NODE *node)
172 if (temp & temp2) {
173 fdi_free (node->left);
174 node->left = 0;
175 fdi_free (node->right);
176 node->right = 0;
177 temp2 >>= 1;
178 if (!temp2) {
179 temp = *stream++;
180 temp2 = 0x80;
182 return stream;
183 } else {
184 const uae_u8 *stream_temp;
185 temp2 >>= 1;
186 if (!temp2) {
187 temp = *stream++;
188 temp2 = 0x80;
190 node->left = fdi_malloc (sizeof (NODE));
191 memset (node->left, 0, sizeof (NODE));
192 stream_temp = expand_tree (stream, node->left);
193 node->right = fdi_malloc (sizeof (NODE));
194 memset (node->right, 0, sizeof (NODE));
195 return expand_tree (stream_temp, node->right);
199 static const uae_u8 *values_tree8 (const uae_u8 *stream, NODE *node)
201 if (node->left == 0) {
202 node->v = *stream++;
203 return stream;
204 } else {
205 const uae_u8 *stream_temp = values_tree8 (stream, node->left);
206 return values_tree8 (stream_temp, node->right);
210 static const uae_u8 *values_tree16 (const uae_u8 *stream, NODE *node)
212 if (node->left == 0) {
213 uae_u16 high_8_bits = (*stream++) << 8;
214 node->v = high_8_bits | (*stream++);
215 return stream;
216 } else {
217 const uae_u8 *stream_temp = values_tree16 (stream, node->left);
218 return values_tree16 (stream_temp, node->right);
222 static void free_nodes (NODE *node)
224 if (node) {
225 free_nodes (node->left);
226 free_nodes (node->right);
227 fdi_free (node);
231 STATIC_INLINE uae_u32 sign_extend16 (uae_u32 v)
233 if (v & 0x8000)
234 v |= 0xffff0000;
235 return v;
238 STATIC_INLINE uae_u32 sign_extend8 (uae_u32 v)
240 if (v & 0x80)
241 v |= 0xffffff00;
242 return v;
245 static void fdi_decode (const uae_u8 *stream, unsigned int size, uae_u8 *out)
247 uae_u8 sign_extend, sixteen_bit, sub_stream_shift;
248 NODE root;
249 NODE *current_node;
251 memset (out, 0, size * 4);
252 sub_stream_shift = 1;
253 while (sub_stream_shift) {
254 unsigned int i;
256 //sub-stream header decode
257 sign_extend = *stream++;
258 sub_stream_shift = sign_extend & 0x7f;
259 sign_extend &= 0x80;
260 sixteen_bit = (*stream++) & 0x80;
262 //huffman tree architecture decode
263 temp = *stream++;
264 temp2 = 0x80;
265 stream = expand_tree (stream, &root);
266 if (temp2 == 0x80)
267 stream--;
269 //huffman output values decode
270 if (sixteen_bit)
271 stream = values_tree16 (stream, &root);
272 else
273 stream = values_tree8 (stream, &root);
275 //sub-stream data decode
276 temp2 = 0;
277 for (i = 0; i < size; i++) {
278 uae_u32 v;
279 uae_u8 decode = 1;
280 current_node = &root;
281 while (decode) {
282 if (current_node->left == 0) {
283 decode = 0;
284 } else {
285 temp2 >>= 1;
286 if (!temp2) {
287 temp2 = 0x80;
288 temp = *stream++;
290 if (temp & temp2)
291 current_node = current_node->right;
292 else
293 current_node = current_node->left;
296 v = ((uae_u32*)out)[i];
297 if (sign_extend) {
298 if (sixteen_bit)
299 v |= sign_extend16 (current_node->v) << sub_stream_shift;
300 else
301 v |= sign_extend8 (current_node->v) << sub_stream_shift;
302 } else {
303 v |= current_node->v << sub_stream_shift;
305 ((uae_u32*)out)[i] = v;
307 free_nodes (root.left);
308 free_nodes (root.right);
313 static unsigned int decode_raw_track (FDI *fdi)
315 unsigned int size = get_u32(fdi->track_src);
316 memcpy (fdi->track_dst, fdi->track_src, (size + 7) >> 3);
317 fdi->track_src += (size + 7) >> 3;
318 return size;
321 /* unknown track */
322 static void zxx (FDI *fdi)
324 outlog ("track %d: unknown track type 0x%02.2X\n", fdi->current_track, fdi->track_type);
325 // return -1;
327 /* unsupported track */
328 static void zyy (FDI *fdi)
330 outlog ("track %d: unsupported track type 0x%02.2X\n", fdi->current_track, fdi->track_type);
331 // return -1;
333 /* empty track */
334 static void track_empty (FDI *fdi)
336 // return 0;
339 /* unknown sector described type */
340 static void dxx (FDI *fdi)
342 outlog ("\ntrack %d: unknown sector described type 0x%02.2X\n", fdi->current_track, fdi->track_type);
343 fdi->err = 1;
345 /* unsupported sector described type */
346 static void dyy (FDI *fdi)
348 outlog ("\ntrack %d: unsupported sector described 0x%02.2X\n", fdi->current_track, fdi->track_type);
349 fdi->err = 1;
351 /* add position of mfm sync bit */
352 static void add_mfm_sync_bit (FDI *fdi)
354 if (fdi->nextdrop) {
355 fdi->nextdrop = 0;
356 return;
358 fdi->mfmsync_buffer[fdi->mfmsync_offset++] = fdi->out;
359 if (fdi->out == 0) {
360 outlog ("illegal position for mfm sync bit, offset=%d\n",fdi->out);
361 fdi->err = 1;
363 if (fdi->mfmsync_offset >= MAX_MFM_SYNC_BUFFER) {
364 fdi->mfmsync_offset = 0;
365 outlog ("mfmsync buffer overflow\n");
366 fdi->err = 1;
368 fdi->out++;
371 #define BIT_BYTEOFFSET ((fdi->out) >> 3)
372 #define BIT_BITOFFSET (7-((fdi->out)&7))
374 /* add one bit */
375 static void bit_add (FDI *fdi, int bit)
377 if (fdi->nextdrop) {
378 fdi->nextdrop = 0;
379 return;
381 fdi->track_dst[BIT_BYTEOFFSET] &= ~(1 << BIT_BITOFFSET);
382 if (bit)
383 fdi->track_dst[BIT_BYTEOFFSET] |= (1 << BIT_BITOFFSET);
384 fdi->out++;
385 if (fdi->out >= MAX_DST_BUFFER * 8) {
386 outlog ("destination buffer overflow\n");
387 fdi->err = 1;
388 fdi->out = 1;
391 /* add bit and mfm sync bit */
392 static void bit_mfm_add (FDI *fdi, int bit)
394 add_mfm_sync_bit (fdi);
395 bit_add (fdi, bit);
397 /* remove following bit */
398 static void bit_drop_next (FDI *fdi)
400 if (fdi->nextdrop > 0) {
401 outlog ("multiple bit_drop_next() called");
402 } else if (fdi->nextdrop < 0) {
403 fdi->nextdrop = 0;
404 debuglog (":DNN:");
405 return;
407 debuglog (":DN:");
408 fdi->nextdrop = 1;
411 /* ignore next bit_drop_next() */
412 static void bit_dedrop (FDI *fdi)
414 if (fdi->nextdrop) {
415 outlog ("bit_drop_next called before bit_dedrop");
417 fdi->nextdrop = -1;
418 debuglog (":BDD:");
421 /* add one byte */
422 static void byte_add (FDI *fdi, uae_u8 v)
424 int i;
425 for (i = 7; i >= 0; i--)
426 bit_add (fdi, v & (1 << i));
428 /* add one word */
429 static void word_add (FDI *fdi, uae_u16 v)
431 byte_add (fdi, (uae_u8)(v >> 8));
432 byte_add (fdi, (uae_u8)v);
434 /* add one byte and mfm encode it */
435 static void byte_mfm_add (FDI *fdi, uae_u8 v)
437 int i;
438 for (i = 7; i >= 0; i--)
439 bit_mfm_add (fdi, v & (1 << i));
441 /* add multiple bytes and mfm encode them */
442 static void bytes_mfm_add (FDI *fdi, uae_u8 v, unsigned int len)
444 unsigned int i;
445 for (i = 0; i < len; i++) byte_mfm_add (fdi, v);
447 /* add one mfm encoded word and re-mfm encode it */
448 static void word_post_mfm_add (FDI *fdi, uae_u16 v)
450 int i;
451 for (i = 14; i >= 0; i -= 2)
452 bit_mfm_add (fdi, v & (1 << i));
455 /* bit 0 */
456 static void s00(FDI *fdi) { bit_add (fdi, 0); }
457 /* bit 1*/
458 static void s01(FDI *fdi) { bit_add (fdi, 1); }
459 /* 4489 */
460 static void s02(FDI *fdi) { word_add (fdi, 0x4489); }
461 /* 5224 */
462 static void s03(FDI *fdi) { word_add (fdi, 0x5224); }
463 /* mfm sync bit */
464 static void s04(FDI *fdi) { add_mfm_sync_bit (fdi); }
465 /* RLE MFM-encoded data */
466 static void s08(FDI *fdi)
468 unsigned int bytes = *fdi->track_src++;
469 uae_u8 byte = *fdi->track_src++;
470 if (bytes == 0) bytes = 256;
471 debuglog ("s08:len=%d,data=%02.2X",bytes,byte);
472 while(bytes--) byte_add (fdi, byte);
474 /* RLE MFM-decoded data */
475 static void s09(FDI *fdi)
477 unsigned int bytes = *fdi->track_src++;
478 uae_u8 byte = *fdi->track_src++;
479 if (bytes == 0) bytes = 256;
480 bit_drop_next (fdi);
481 debuglog ("s09:len=%d,data=%02.2X",bytes,byte);
482 while(bytes--) byte_mfm_add (fdi, byte);
484 /* MFM-encoded data */
485 static void s0a(FDI *fdi)
487 int i, bits = (fdi->track_src[0] << 8) | fdi->track_src[1];
488 uae_u8 b;
489 fdi->track_src += 2;
490 debuglog ("s0a:bits=%d,data=%s", bits, datalog (fdi->track_src, (bits + 7) / 8));
491 while (bits >= 8) {
492 byte_add (fdi, *fdi->track_src++);
493 bits -= 8;
495 if (bits > 0) {
496 i = 7;
497 b = *fdi->track_src++;
498 while (bits--) {
499 bit_add (fdi, b & (1 << i));
500 i--;
504 /* MFM-encoded data */
505 static void s0b(FDI *fdi)
507 int i, bits = ((fdi->track_src[0] << 8) | fdi->track_src[1]) + 65536;
508 uae_u8 b;
509 fdi->track_src += 2;
510 debuglog ("s0b:bits=%d,data=%s", bits, datalog (fdi->track_src, (bits + 7) / 8));
511 while (bits >= 8) {
512 byte_add (fdi, *fdi->track_src++);
513 bits -= 8;
515 if (bits > 0) {
516 i = 7;
517 b = *fdi->track_src++;
518 while (bits--) {
519 bit_add (fdi, b & (1 << i));
520 i--;
524 /* MFM-decoded data */
525 static void s0c(FDI *fdi)
527 int i, bits = (fdi->track_src[0] << 8) | fdi->track_src[1];
528 uae_u8 b;
529 fdi->track_src += 2;
530 bit_drop_next (fdi);
531 debuglog ("s0c:bits=%d,data=%s", bits, datalog (fdi->track_src, (bits + 7) / 8));
532 while (bits >= 8) {
533 byte_mfm_add (fdi, *fdi->track_src++);
534 bits -= 8;
536 if (bits > 0) {
537 i = 7;
538 b = *fdi->track_src++;
539 while(bits--) {
540 bit_mfm_add (fdi, b & (1 << i));
541 i--;
545 /* MFM-decoded data */
546 static void s0d(FDI *fdi)
548 int i, bits = ((fdi->track_src[0] << 8) | fdi->track_src[1]) + 65536;
549 uae_u8 b;
550 fdi->track_src += 2;
551 bit_drop_next (fdi);
552 debuglog ("s0d:bits=%d,data=%s", bits, datalog (fdi->track_src, (bits + 7) / 8));
553 while (bits >= 8) {
554 byte_mfm_add (fdi, *fdi->track_src++);
555 bits -= 8;
557 if (bits > 0) {
558 i = 7;
559 b = *fdi->track_src++;
560 while(bits--) {
561 bit_mfm_add (fdi, b & (1 << i));
562 i--;
567 /* ***** */
568 /* AMIGA */
569 /* ***** */
571 /* just for testing integrity of Amiga sectors */
573 static void rotateonebit (uae_u8 *start, uae_u8 *end, unsigned int shift)
575 if (shift == 0)
576 return;
577 while (start <= end) {
578 start[0] <<= shift;
579 start[0] |= start[1] >> (8 - shift);
580 start++;
584 static int check_offset;
585 static uae_u16 getmfmword (const uae_u8 *mbuf)
587 uae_u32 v;
589 v = (mbuf[0] << 8) | (mbuf[1] << 0);
590 if (check_offset == 0)
591 return v;
592 v <<= 8;
593 v |= mbuf[2];
594 v >>= check_offset;
595 return v;
598 #define MFMMASK 0x55555555
599 static uae_u32 getmfmlong (const uae_u8 *mbuf)
601 return ((getmfmword (mbuf) << 16) | getmfmword (mbuf + 2)) & MFMMASK;
604 static int amiga_check_track (FDI *fdi)
606 int i, j, secwritten = 0;
607 int fwlen = fdi->out / 8;
608 int length = 2 * fwlen;
609 int drvsec = 11;
610 uae_u32 odd, even, chksum, id, dlong;
611 uae_u8 *secdata;
612 uae_u8 secbuf[544];
613 uae_u8 bigmfmbuf[60000];
614 uae_u8 *mbuf, *mbuf2, *mend;
615 char sectable[22];
616 uae_u8 *raw = fdi->track_dst_buffer;
617 int slabel, off;
618 int ok = 1;
620 memset (bigmfmbuf, 0, sizeof (bigmfmbuf));
621 mbuf = bigmfmbuf;
622 check_offset = 0;
623 for (i = 0; i < (fdi->out + 7) / 8; i++)
624 *mbuf++ = raw[i];
625 off = fdi->out & 7;
626 #if 1
627 if (off > 0) {
628 mbuf--;
629 *mbuf &= ~((1 << (8 - off)) - 1);
631 j = 0;
632 while (i < (fdi->out + 7) / 8 + 600) {
633 *mbuf++ |= (raw[j] >> off) | ((raw[j + 1]) << (8 - off));
634 j++;
635 i++;
637 #endif
638 mbuf = bigmfmbuf;
640 memset (sectable, 0, sizeof (sectable));
641 //memcpy (mbuf + fwlen, mbuf, fwlen * sizeof (uae_u16));
642 mend = bigmfmbuf + length;
643 mend -= (4 + 16 + 8 + 512);
645 while (secwritten < drvsec) {
646 int trackoffs;
648 for (;;) {
649 rotateonebit (bigmfmbuf, mend, 1);
650 if (getmfmword (mbuf) == 0)
651 break;
652 if (secwritten == 10) {
653 mbuf[0] = 0x44;
654 mbuf[1] = 0x89;
656 // check_offset++;
657 if (check_offset > 7) {
658 check_offset = 0;
659 mbuf++;
660 if (mbuf >= mend || *mbuf == 0)
661 break;
663 if (getmfmword (mbuf) == 0x4489)
664 break;
666 if (mbuf >= mend || *mbuf == 0)
667 break;
669 rotateonebit (bigmfmbuf, mend, check_offset);
670 check_offset = 0;
672 while (getmfmword (mbuf) == 0x4489)
673 mbuf+= 1 * 2;
674 mbuf2 = mbuf + 8;
676 odd = getmfmlong (mbuf);
677 even = getmfmlong (mbuf + 2 * 2);
678 mbuf += 4 * 2;
679 id = (odd << 1) | even;
681 trackoffs = (id & 0xff00) >> 8;
682 if (trackoffs + 1 > drvsec) {
683 outlog ("illegal sector offset %d\n",trackoffs);
684 ok = 0;
685 mbuf = mbuf2;
686 continue;
688 if ((id >> 24) != 0xff) {
689 outlog ("sector %d format type %02.2X?\n", trackoffs, id >> 24);
690 ok = 0;
692 chksum = odd ^ even;
693 slabel = 0;
694 for (i = 0; i < 4; i++) {
695 odd = getmfmlong (mbuf);
696 even = getmfmlong (mbuf + 8 * 2);
697 mbuf += 2* 2;
699 dlong = (odd << 1) | even;
700 if (dlong) slabel = 1;
701 chksum ^= odd ^ even;
703 mbuf += 8 * 2;
704 odd = getmfmlong (mbuf);
705 even = getmfmlong (mbuf + 2 * 2);
706 mbuf += 4 * 2;
707 if (((odd << 1) | even) != chksum) {
708 outlog ("sector %d header crc error\n", trackoffs);
709 ok = 0;
710 mbuf = mbuf2;
711 continue;
713 outlog ("sector %d header crc ok\n", trackoffs);
714 if (((id & 0x00ff0000) >> 16) != (uae_u32)fdi->current_track) {
715 outlog ("illegal track number %d <> %d\n", fdi->current_track, (id & 0x00ff0000) >> 16);
716 ok++;
717 mbuf = mbuf2;
718 continue;
720 odd = getmfmlong (mbuf);
721 even = getmfmlong (mbuf + 2 * 2);
722 mbuf += 4 * 2;
723 chksum = (odd << 1) | even;
724 secdata = secbuf + 32;
725 for (i = 0; i < 128; i++) {
726 odd = getmfmlong (mbuf);
727 even = getmfmlong (mbuf + 256 * 2);
728 mbuf += 2 * 2;
729 dlong = (odd << 1) | even;
730 *secdata++ = (uae_u8) (dlong >> 24);
731 *secdata++ = (uae_u8) (dlong >> 16);
732 *secdata++ = (uae_u8) (dlong >> 8);
733 *secdata++ = (uae_u8) dlong;
734 chksum ^= odd ^ even;
736 mbuf += 256 * 2;
737 if (chksum) {
738 outlog ("sector %d data checksum error\n",trackoffs);
739 ok = 0;
740 } else if (sectable[trackoffs]) {
741 outlog ("sector %d already found?\n", trackoffs);
742 mbuf = mbuf2;
743 } else {
744 outlog ("sector %d ok\n",trackoffs);
745 if (slabel) outlog ("(non-empty sector header)\n");
746 sectable[trackoffs] = 1;
747 secwritten++;
748 if (trackoffs == 9)
749 mbuf += 0x228;
752 for (i = 0; i < drvsec; i++) {
753 if (!sectable[i]) {
754 outlog ("sector %d missing\n", i);
755 ok = 0;
758 return ok;
761 static void amiga_data_raw (FDI *fdi, uae_u8 *secbuf, uae_u8 *crc, unsigned int len)
763 unsigned int i;
764 uae_u8 crcbuf[4];
766 if (!crc) {
767 memset (crcbuf, 0, 4);
768 } else {
769 memcpy (crcbuf, crc ,4);
771 for (i = 0; i < 4; i++)
772 byte_mfm_add (fdi, crcbuf[i]);
773 for (i = 0; i < len; i++)
774 byte_mfm_add (fdi, secbuf[i]);
777 static void amiga_data (FDI *fdi, const uae_u8 *secbuf)
779 uae_u16 mfmbuf[4 + 512];
780 uae_u32 dodd, deven, dck;
781 unsigned int i;
783 for (i = 0; i < 512; i += 4) {
784 deven = ((secbuf[i + 0] << 24) | (secbuf[i + 1] << 16)
785 | (secbuf[i + 2] << 8) | (secbuf[i + 3]));
786 dodd = deven >> 1;
787 deven &= 0x55555555;
788 dodd &= 0x55555555;
789 mfmbuf[(i >> 1) + 4] = (uae_u16) (dodd >> 16);
790 mfmbuf[(i >> 1) + 5] = (uae_u16) dodd;
791 mfmbuf[(i >> 1) + 256 + 4] = (uae_u16) (deven >> 16);
792 mfmbuf[(i >> 1) + 256 + 5] = (uae_u16) deven;
794 dck = 0;
795 for (i = 4; i < 4 + 512; i += 2)
796 dck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1];
797 deven = dodd = dck;
798 dodd >>= 1;
799 deven &= 0x55555555;
800 dodd &= 0x55555555;
801 mfmbuf[0] = (uae_u16) (dodd >> 16);
802 mfmbuf[1] = (uae_u16) dodd;
803 mfmbuf[2] = (uae_u16) (deven >> 16);
804 mfmbuf[3] = (uae_u16) deven;
806 for (i = 0; i < 4 + 512; i ++)
807 word_post_mfm_add (fdi, mfmbuf[i]);
810 static void amiga_sector_header (FDI *fdi, const uae_u8 *header, const uae_u8 *data, unsigned int sector, unsigned int untilgap)
812 uae_u8 headerbuf[4], databuf[16];
813 uae_u32 deven, dodd, hck;
814 uae_u16 mfmbuf[24];
815 unsigned int i;
817 byte_mfm_add (fdi, 0);
818 byte_mfm_add (fdi, 0);
819 word_add (fdi, 0x4489);
820 word_add (fdi, 0x4489);
821 if (header) {
822 memcpy (headerbuf, header, 4);
823 } else {
824 headerbuf[0] = 0xff;
825 headerbuf[1] = (uae_u8)fdi->current_track;
826 headerbuf[2] = (uae_u8)sector;
827 headerbuf[3] = (uae_u8)untilgap;
829 if (data)
830 memcpy (databuf, data, 16);
831 else
832 memset (databuf, 0, 16);
834 deven = ((headerbuf[0] << 24) | (headerbuf[1] << 16)
835 | (headerbuf[2] << 8) | (headerbuf[3]));
836 dodd = deven >> 1;
837 deven &= 0x55555555;
838 dodd &= 0x55555555;
839 mfmbuf[0] = (uae_u16) (dodd >> 16);
840 mfmbuf[1] = (uae_u16) dodd;
841 mfmbuf[2] = (uae_u16) (deven >> 16);
842 mfmbuf[3] = (uae_u16) deven;
843 for (i = 0; i < 16; i += 4) {
844 deven = ((databuf[i] << 24) | (databuf[i + 1] << 16)
845 | (databuf[i + 2] << 8) | (databuf[i + 3]));
846 dodd = deven >> 1;
847 deven &= 0x55555555;
848 dodd &= 0x55555555;
849 mfmbuf[(i >> 1) + 0 + 4] = (uae_u16) (dodd >> 16);
850 mfmbuf[(i >> 1) + 0 + 5] = (uae_u16) dodd;
851 mfmbuf[(i >> 1) + 8 + 4] = (uae_u16) (deven >> 16);
852 mfmbuf[(i >> 1) + 8 + 5] = (uae_u16) deven;
854 hck = 0;
855 for (i = 0; i < 4 + 16; i += 2)
856 hck ^= (mfmbuf[i] << 16) | mfmbuf[i + 1];
857 deven = dodd = hck;
858 dodd >>= 1;
859 deven &= 0x55555555;
860 dodd &= 0x55555555;
861 mfmbuf[20] = (uae_u16) (dodd >> 16);
862 mfmbuf[21] = (uae_u16) dodd;
863 mfmbuf[22] = (uae_u16) (deven >> 16);
864 mfmbuf[23] = (uae_u16) deven;
866 for (i = 0; i < 4 + 16 + 4; i ++)
867 word_post_mfm_add (fdi, mfmbuf[i]);
870 /* standard super-extended Amiga sector header */
871 static void s20(FDI *fdi)
873 bit_drop_next (fdi);
874 debuglog ("s20:header=%s,data=%s", datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 16));
875 amiga_sector_header (fdi, fdi->track_src, fdi->track_src + 4, 0, 0);
876 fdi->track_src += 4 + 16;
878 /* standard extended Amiga sector header */
879 static void s21(FDI *fdi)
881 bit_drop_next (fdi);
882 debuglog ("s21:header=%s", datalog (fdi->track_src, 4));
883 amiga_sector_header (fdi, fdi->track_src, 0, 0, 0);
884 fdi->track_src += 4;
886 /* standard Amiga sector header */
887 static void s22(FDI *fdi)
889 bit_drop_next (fdi);
890 debuglog ("s22:sector=%d,untilgap=%d", fdi->track_src[0], fdi->track_src[1]);
891 amiga_sector_header (fdi, 0, 0, fdi->track_src[0], fdi->track_src[1]);
892 fdi->track_src += 2;
894 /* standard 512-byte, CRC-correct Amiga data */
895 static void s23(FDI *fdi)
897 debuglog ("s23:data=%s", datalog (fdi->track_src, 512));
898 amiga_data (fdi, fdi->track_src);
899 fdi->track_src += 512;
901 /* not-decoded, 128*2^x-byte, CRC-correct Amiga data */
902 static void s24(FDI *fdi)
904 int shift = *fdi->track_src++;
905 debuglog ("s24:shift=%d,data=%s", shift, datalog (fdi->track_src, 128 << shift));
906 amiga_data_raw (fdi, fdi->track_src, 0, 128 << shift);
907 fdi->track_src += 128 << shift;
909 /* not-decoded, 128*2^x-byte, CRC-incorrect Amiga data */
910 static void s25(FDI *fdi)
912 int shift = *fdi->track_src++;
913 debuglog ("s25:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 128 << shift));
914 amiga_data_raw (fdi, fdi->track_src + 4, fdi->track_src, 128 << shift);
915 fdi->track_src += 4 + (128 << shift);
917 /* standard extended Amiga sector */
918 static void s26(FDI *fdi)
920 s21 (fdi);
921 debuglog ("s26:data=%s", datalog (fdi->track_src, 512));
922 amiga_data (fdi, fdi->track_src);
923 fdi->track_src += 512;
925 /* standard short Amiga sector */
926 static void s27(FDI *fdi)
928 s22 (fdi);
929 debuglog ("s27:data=%s", datalog (fdi->track_src, 512));
930 amiga_data (fdi, fdi->track_src);
931 fdi->track_src += 512;
934 /* *** */
935 /* IBM */
936 /* *** */
938 static uae_u16 ibm_crc (uae_u8 byte, int reset)
940 static uae_u16 crc;
941 int i;
943 if (reset) crc = 0xcdb4;
944 for (i = 0; i < 8; i++) {
945 if (crc & 0x8000) {
946 crc <<= 1;
947 if (!(byte & 0x80)) crc ^= 0x1021;
948 } else {
949 crc <<= 1;
950 if (byte & 0x80) crc ^= 0x1021;
952 byte <<= 1;
954 return crc;
957 static void ibm_data (FDI *fdi, const uae_u8 *data, uae_u8 *crc, unsigned int len)
959 unsigned int i;
960 uae_u8 crcbuf[2];
961 uae_u16 crcv = 0;
963 word_add (fdi, 0x4489);
964 word_add (fdi, 0x4489);
965 word_add (fdi, 0x4489);
966 byte_mfm_add (fdi, 0xfb);
967 ibm_crc (0xfb, 1);
968 for (i = 0; i < len; i++) {
969 byte_mfm_add (fdi, data[i]);
970 crcv = ibm_crc (data[i], 0);
972 if (!crc) {
973 crc = crcbuf;
974 crc[0] = (uae_u8)(crcv >> 8);
975 crc[1] = (uae_u8)crcv;
977 byte_mfm_add (fdi, crc[0]);
978 byte_mfm_add (fdi, crc[1]);
981 static void ibm_sector_header (FDI *fdi, const uae_u8 *data, const uae_u8 *crc, int secnum, int pre)
983 uae_u8 secbuf[5];
984 uae_u8 crcbuf[2];
985 uae_u16 crcv;
986 int i;
988 if (pre)
989 bytes_mfm_add (fdi, 0, 12);
990 word_add (fdi, 0x4489);
991 word_add (fdi, 0x4489);
992 word_add (fdi, 0x4489);
993 secbuf[0] = 0xfe;
994 if (secnum >= 0) {
995 secbuf[1] = (uae_u8)(fdi->current_track / 2);
996 secbuf[2] = (uae_u8)(fdi->current_track % 2);
997 secbuf[3] = (uae_u8)secnum;
998 secbuf[4] = 2;
999 } else {
1000 memcpy (secbuf + 1, data, 4);
1002 ibm_crc (secbuf[0], 1);
1003 ibm_crc (secbuf[1], 0);
1004 ibm_crc (secbuf[2], 0);
1005 ibm_crc (secbuf[3], 0);
1006 crcv = ibm_crc (secbuf[4], 0);
1007 if (crc) {
1008 memcpy (crcbuf, crc, 2);
1009 } else {
1010 crcbuf[0] = (uae_u8)(crcv >> 8);
1011 crcbuf[1] = (uae_u8)crcv;
1013 /* data */
1014 for (i = 0;i < 5; i++)
1015 byte_mfm_add (fdi, secbuf[i]);
1016 /* crc */
1017 byte_mfm_add (fdi, crcbuf[0]);
1018 byte_mfm_add (fdi, crcbuf[1]);
1021 /* standard IBM index address mark */
1022 static void s10 (FDI *fdi)
1024 bit_drop_next (fdi);
1025 bytes_mfm_add (fdi, 0, 12);
1026 word_add (fdi, 0x5224);
1027 word_add (fdi, 0x5224);
1028 word_add (fdi, 0x5224);
1029 byte_mfm_add (fdi, 0xfc);
1031 /* standard IBM pre-gap */
1032 static void s11 (FDI *fdi)
1034 bit_drop_next (fdi);
1035 bytes_mfm_add (fdi, 0x4e, 78);
1036 bit_dedrop (fdi);
1037 s10 (fdi);
1038 bytes_mfm_add (fdi, 0x4e, 50);
1040 /* standard ST pre-gap */
1041 static void s12 (FDI *fdi)
1043 bit_drop_next (fdi);
1044 bytes_mfm_add (fdi, 0x4e, 78);
1046 /* standard extended IBM sector header */
1047 static void s13 (FDI *fdi)
1049 bit_drop_next (fdi);
1050 debuglog ("s13:header=%s", datalog (fdi->track_src, 4));
1051 ibm_sector_header (fdi, fdi->track_src, 0, -1, 1);
1052 fdi->track_src += 4;
1054 /* standard mini-extended IBM sector header */
1055 static void s14 (FDI *fdi)
1057 debuglog ("s14:header=%s", datalog (fdi->track_src, 4));
1058 ibm_sector_header (fdi, fdi->track_src, 0, -1, 0);
1059 fdi->track_src += 4;
1061 /* standard short IBM sector header */
1062 static void s15 (FDI *fdi)
1064 bit_drop_next (fdi);
1065 debuglog ("s15:sector=%d", *fdi->track_src);
1066 ibm_sector_header (fdi, 0, 0, *fdi->track_src++, 1);
1068 /* standard mini-short IBM sector header */
1069 static void s16 (FDI *fdi)
1071 debuglog ("s16:track=%d", *fdi->track_src);
1072 ibm_sector_header (fdi, 0, 0, *fdi->track_src++, 0);
1074 /* standard CRC-incorrect mini-extended IBM sector header */
1075 static void s17 (FDI *fdi)
1077 debuglog ("s17:header=%s,crc=%s", datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 2));
1078 ibm_sector_header (fdi, fdi->track_src, fdi->track_src + 4, -1, 0);
1079 fdi->track_src += 4 + 2;
1081 /* standard CRC-incorrect mini-short IBM sector header */
1082 static void s18 (FDI *fdi)
1084 debuglog ("s18:sector=%d,header=%s", *fdi->track_src, datalog (fdi->track_src + 1, 4));
1085 ibm_sector_header (fdi, 0, fdi->track_src + 1, *fdi->track_src, 0);
1086 fdi->track_src += 1 + 4;
1088 /* standard 512-byte CRC-correct IBM data */
1089 static void s19 (FDI *fdi)
1091 debuglog ("s19:data=%s", datalog (fdi->track_src , 512));
1092 ibm_data (fdi, fdi->track_src, 0, 512);
1093 fdi->track_src += 512;
1095 /* standard 128*2^x-byte-byte CRC-correct IBM data */
1096 static void s1a (FDI *fdi)
1098 int shift = *fdi->track_src++;
1099 debuglog ("s1a:shift=%d,data=%s", shift, datalog (fdi->track_src , 128 << shift));
1100 ibm_data (fdi, fdi->track_src, 0, 128 << shift);
1101 fdi->track_src += 128 << shift;
1103 /* standard 128*2^x-byte-byte CRC-incorrect IBM data */
1104 static void s1b (FDI *fdi)
1106 int shift = *fdi->track_src++;
1107 debuglog ("s1b:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src + (128 << shift), 2), datalog (fdi->track_src , 128 << shift));
1108 ibm_data (fdi, fdi->track_src, fdi->track_src + (128 << shift), 128 << shift);
1109 fdi->track_src += (128 << shift) + 2;
1111 /* standard extended IBM sector */
1112 static void s1c (FDI *fdi)
1114 int shift = fdi->track_src[3];
1115 s13 (fdi);
1116 bytes_mfm_add (fdi, 0x4e, 22);
1117 bytes_mfm_add (fdi, 0x00, 12);
1118 ibm_data (fdi, fdi->track_src, 0, 128 << shift);
1119 fdi->track_src += 128 << shift;
1121 /* standard short IBM sector */
1122 static void s1d (FDI *fdi)
1124 s15 (fdi);
1125 bytes_mfm_add (fdi, 0x4e, 22);
1126 bytes_mfm_add (fdi, 0x00, 12);
1127 s19 (fdi);
1130 /* end marker */
1131 static void sff (FDI *fdi)
1135 typedef void (*decode_described_track_func)(FDI*);
1137 static decode_described_track_func const decode_sectors_described_track[] =
1139 s00,s01,s02,s03,s04,dxx,dxx,dxx,s08,s09,s0a,s0b,s0c,s0d,dxx,dxx, /* 00-0F */
1140 s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s1a,s1b,s1c,s1d,dxx,dxx, /* 10-1F */
1141 s20,s21,s22,s23,s24,s25,s26,s27,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 20-2F */
1142 dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 30-3F */
1143 dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 40-4F */
1144 dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 50-5F */
1145 dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 60-6F */
1146 dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 70-7F */
1147 dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 80-8F */
1148 dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* 90-9F */
1149 dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* A0-AF */
1150 dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* B0-BF */
1151 dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* C0-CF */
1152 dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* D0-DF */
1153 dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx, /* E0-EF */
1154 dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,dxx,sff /* F0-FF */
1157 static void track_amiga (struct fdi *fdi, unsigned int first_sector, unsigned int max_sector)
1159 unsigned int i;
1161 bit_add (fdi, 0);
1162 bit_drop_next (fdi);
1163 for (i = 0; i < max_sector; i++) {
1164 amiga_sector_header (fdi, 0, 0, first_sector, max_sector - i);
1165 amiga_data (fdi, fdi->track_src + first_sector * 512);
1166 first_sector++;
1167 if (first_sector >= max_sector) first_sector = 0;
1169 bytes_mfm_add (fdi, 0, 260); /* gap */
1171 static void track_atari_st (struct fdi *fdi, unsigned int max_sector)
1173 unsigned int i, gap3 = 0;
1174 uae_u8 *p = fdi->track_src;
1176 switch (max_sector) {
1177 case 9:
1178 gap3 = 40;
1179 break;
1180 case 10:
1181 gap3 = 24;
1182 break;
1184 s15 (fdi);
1185 for (i = 0; i < max_sector; i++) {
1186 byte_mfm_add (fdi, 0x4e);
1187 byte_mfm_add (fdi, 0x4e);
1188 ibm_sector_header (fdi, 0, 0, fdi->current_track, 1);
1189 ibm_data (fdi, p + i * 512, 0, 512);
1190 bytes_mfm_add (fdi, 0x4e, gap3);
1192 bytes_mfm_add (fdi, 0x4e, 660 - gap3);
1193 fdi->track_src += fdi->track_len * 256;
1195 static void track_pc (struct fdi *fdi, unsigned int max_sector)
1197 unsigned int i, gap3;
1198 uae_u8 *p = fdi->track_src;
1200 switch (max_sector) {
1201 case 8:
1202 gap3 = 116;
1203 break;
1204 case 9:
1205 gap3 = 54;
1206 break;
1207 default:
1208 gap3 = 100; /* fixme */
1209 break;
1211 s11 (fdi);
1212 for (i = 0; i < max_sector; i++) {
1213 byte_mfm_add (fdi, 0x4e);
1214 byte_mfm_add (fdi, 0x4e);
1215 ibm_sector_header (fdi, 0, 0, fdi->current_track, 1);
1216 ibm_data (fdi, p + i * 512, 0, 512);
1217 bytes_mfm_add (fdi, 0x4e, gap3);
1219 bytes_mfm_add (fdi, 0x4e, 600 - gap3);
1220 fdi->track_src += fdi->track_len * 256;
1223 /* amiga dd */
1224 static void track_amiga_dd (struct fdi *fdi)
1226 uae_u8 *p = fdi->track_src;
1227 track_amiga (fdi, fdi->track_len >> 4, 11);
1228 fdi->track_src = p + (fdi->track_len & 15) * 512;
1230 /* amiga hd */
1231 static void track_amiga_hd (struct fdi *fdi)
1233 uae_u8 *p = fdi->track_src;
1234 track_amiga (fdi, 0, 22);
1235 fdi->track_src = p + fdi->track_len * 256;
1237 /* atari st 9 sector */
1238 static void track_atari_st_9 (struct fdi *fdi)
1240 track_atari_st (fdi, 9);
1242 /* atari st 10 sector */
1243 static void track_atari_st_10 (struct fdi *fdi)
1245 track_atari_st (fdi, 10);
1247 /* pc 8 sector */
1248 static void track_pc_8 (struct fdi *fdi)
1250 track_pc (fdi, 8);
1252 /* pc 9 sector */
1253 static void track_pc_9 (struct fdi *fdi)
1255 track_pc (fdi, 9);
1257 /* pc 15 sector */
1258 static void track_pc_15 (struct fdi *fdi)
1260 track_pc (fdi, 15);
1262 /* pc 18 sector */
1263 static void track_pc_18 (struct fdi *fdi)
1265 track_pc (fdi, 18);
1267 /* pc 36 sector */
1268 static void track_pc_36 (struct fdi *fdi)
1270 track_pc (fdi, 36);
1273 typedef void (*decode_normal_track_func)(FDI*);
1275 static decode_normal_track_func const decode_normal_track[] =
1277 track_empty, /* 0 */
1278 track_amiga_dd, track_amiga_hd, /* 1-2 */
1279 track_atari_st_9, track_atari_st_10, /* 3-4 */
1280 track_pc_8, track_pc_9, track_pc_15, track_pc_18, track_pc_36, /* 5-9 */
1281 zxx,zxx,zxx,zxx,zxx /* A-F */
1284 static void fix_mfm_sync (FDI *fdi)
1286 int i, pos, off1, off2, off3, mask1, mask2, mask3;
1288 for (i = 0; i < fdi->mfmsync_offset; i++) {
1289 pos = fdi->mfmsync_buffer[i];
1290 off1 = (pos - 1) >> 3;
1291 off2 = (pos + 1) >> 3;
1292 off3 = pos >> 3;
1293 mask1 = 1 << (7 - ((pos - 1) & 7));
1294 mask2 = 1 << (7 - ((pos + 1) & 7));
1295 mask3 = 1 << (7 - (pos & 7));
1296 if (!(fdi->track_dst[off1] & mask1) && !(fdi->track_dst[off2] & mask2))
1297 fdi->track_dst[off3] |= mask3;
1298 else
1299 fdi->track_dst[off3] &= ~mask3;
1303 static int handle_sectors_described_track (FDI *fdi)
1305 int oldout;
1306 uae_u8 *start_src = fdi->track_src ;
1307 fdi->encoding_type = *fdi->track_src++;
1308 fdi->index_offset = get_u32(fdi->track_src);
1309 fdi->index_offset >>= 8;
1310 fdi->track_src += 3;
1311 outlog ("sectors_described, index offset: %d\n",fdi->index_offset);
1313 do {
1314 fdi->track_type = *fdi->track_src++;
1315 outlog ("%06.6X %06.6X %02.2X:",fdi->track_src - start_src + 0x200, fdi->out/8, fdi->track_type);
1316 oldout = fdi->out;
1317 decode_sectors_described_track[fdi->track_type](fdi);
1318 outlog (" %d\n", fdi->out - oldout);
1319 oldout = fdi->out;
1320 if (fdi->out < 0 || fdi->err) {
1321 outlog ("\nin %d bytes, out %d bits\n", fdi->track_src - fdi->track_src_buffer, fdi->out);
1322 return -1;
1324 if (fdi->track_src - fdi->track_src_buffer >= fdi->track_src_len) {
1325 outlog ("source buffer overrun, previous type: %02.2X\n", fdi->track_type);
1326 return -1;
1328 } while (fdi->track_type != 0xff);
1329 outlog ("\n");
1330 fix_mfm_sync (fdi);
1331 return fdi->out;
1334 static uae_u8 *fdi_decompress (unsigned int pulses, uae_u8 *sizep, const uae_u8 *src, unsigned int *dofree)
1336 uae_u32 size = get_u24 (sizep);
1337 uae_u32 *dst2;
1338 unsigned int len = size & 0x3fffff;
1339 uae_u8 *dst;
1340 unsigned int mode = size >> 22, i;
1342 *dofree = 0;
1343 if (mode == 0 && pulses * 2 > len)
1344 mode = 1;
1345 if (mode == 0) {
1346 dst2 = (uae_u32*)src;
1347 dst = (uae_u8*)src;
1348 for (i = 0; i < pulses; i++) {
1349 *dst2++ = get_u32 (src);
1350 src += 4;
1352 } else if (mode == 1) {
1353 dst = fdi_malloc (pulses * 4);
1354 *dofree = 1;
1355 fdi_decode (src, pulses, dst);
1356 } else {
1357 dst = 0;
1359 return dst;
1362 static void dumpstream(int track, uae_u8 *stream, int len)
1364 #if 0
1365 char name[100];
1366 FILE *f;
1368 sprintf (name, "track_%d.raw", track);
1369 f = fopen(name, "wb");
1370 fwrite (stream, 1, len * 4, f);
1371 fclose (f);
1372 #endif
1375 static int bitoffset;
1377 STATIC_INLINE void addbit (uae_u8 *p, int bit)
1379 int off1 = bitoffset / 8;
1380 int off2 = bitoffset % 8;
1381 p[off1] |= bit << (7 - off2);
1382 bitoffset++;
1386 struct pulse_sample {
1387 unsigned long size;
1388 int number_of_bits;
1392 #define FDI_MAX_ARRAY 10 /* change this value as you want */
1393 static const int pulse_limitval = 15; /* tolerance of 15% */
1394 static struct pulse_sample psarray[FDI_MAX_ARRAY];
1395 static int array_index;
1396 static unsigned long total;
1397 static int totaldiv;
1399 static void init_array(unsigned long standard_MFM_2_bit_cell_size, int nb_of_bits)
1401 int i;
1403 for (i = 0; i < FDI_MAX_ARRAY; i++) {
1404 psarray[i].size = standard_MFM_2_bit_cell_size; // That is (total track length / 50000) for Amiga double density
1405 total += psarray[i].size;
1406 psarray[i].number_of_bits = nb_of_bits;
1407 totaldiv += psarray[i].number_of_bits;
1409 array_index = 0;
1412 #if 0
1414 static void fdi2_decode (FDI *fdi, unsigned long totalavg, uae_u32 *avgp, uae_u32 *minp, uae_u32 *maxp, uae_u8 *idx, int maxidx, int *indexoffsetp, int pulses, int mfm)
1416 unsigned long adjust;
1417 unsigned long adjusted_pulse;
1418 unsigned long standard_MFM_2_bit_cell_size = totalavg / 50000;
1419 unsigned long standard_MFM_8_bit_cell_size = totalavg / 12500;
1420 int real_size, i, j, eodat, outstep;
1421 int indexoffset = *indexoffsetp;
1422 uae_u8 *d = fdi->track_dst_buffer;
1423 uae_u16 *pt = fdi->track_dst_buffer_timing;
1424 uae_u32 ref_pulse, pulse;
1426 /* detects a long-enough stable pulse coming just after another stable pulse */
1427 i = 1;
1428 while ( (i < pulses) && ( (idx[i] < maxidx)
1429 || (idx[i - 1] < maxidx)
1430 || (avgp[i] < (standard_MFM_2_bit_cell_size - (standard_MFM_2_bit_cell_size / 4))) ) )
1431 i++;
1432 if (i == pulses) {
1433 outlog ("No stable and long-enough pulse in track.\n");
1434 return;
1436 i--;
1437 eodat = i;
1438 adjust = 0;
1439 total = 0;
1440 totaldiv = 0;
1441 init_array(standard_MFM_2_bit_cell_size, 2);
1442 bitoffset = 0;
1443 ref_pulse = 0;
1444 outstep = 0;
1445 while (outstep < 2) {
1447 /* calculates the current average bitrate from previous decoded data */
1448 uae_u32 avg_size = (total << 3) / totaldiv; /* this is the new average size for one MFM bit */
1449 /* uae_u32 avg_size = (uae_u32)((((float)total)*8.0) / ((float)totaldiv)); */
1450 /* you can try tighter ranges than 25%, or wider ranges. I would probably go for tighter... */
1451 if ((avg_size < (standard_MFM_8_bit_cell_size - (pulse_limitval * standard_MFM_8_bit_cell_size / 100))) ||
1452 (avg_size > (standard_MFM_8_bit_cell_size + (pulse_limitval * standard_MFM_8_bit_cell_size / 100)))) {
1453 //init_array(standard_MFM_2_bit_cell_size, 2);
1454 avg_size = standard_MFM_8_bit_cell_size;
1456 /* this is to prevent the average value from going too far
1457 * from the theoretical value, otherwise it could progressively go to (2 *
1458 * real value), or (real value / 2), etc. */
1460 /* gets the next long-enough pulse (this may require more than one pulse) */
1461 pulse = 0;
1462 while (pulse < ((avg_size / 4) - (avg_size / 16))) {
1463 int indx;
1464 i++;
1465 if (i >= pulses)
1466 i = 0;
1467 indx = idx[i];
1468 if (rand() <= (indx * RAND_MAX) / maxidx) {
1469 pulse += avgp[i] - ref_pulse;
1470 if (indx >= maxidx)
1471 ref_pulse = 0;
1472 else
1473 ref_pulse = avgp[i];
1475 if (i == eodat)
1476 outstep++;
1477 if (outstep == 1 && indexoffset == i)
1478 *indexoffsetp = bitoffset;
1481 /* gets the size in bits from the pulse width, considering the current average bitrate */
1482 adjusted_pulse = pulse;
1483 real_size = 0;
1484 while (adjusted_pulse >= avg_size) {
1485 real_size += 4;
1486 adjusted_pulse -= avg_size / 2;
1488 adjusted_pulse <<= 3;
1489 while (adjusted_pulse >= ((avg_size * 4) + (avg_size / 4))) {
1490 real_size += 2;
1491 adjusted_pulse -= avg_size * 2;
1493 if (adjusted_pulse >= ((avg_size * 3) + (avg_size / 4))) {
1494 if (adjusted_pulse <= ((avg_size * 4) - (avg_size / 4))) {
1495 if ((2 * ((adjusted_pulse >> 2) - adjust)) <= ((2 * avg_size) - (avg_size / 4)))
1496 real_size += 3;
1497 else
1498 real_size += 4;
1499 } else
1500 real_size += 4;
1501 } else {
1502 if (adjusted_pulse > ((avg_size * 3) - (avg_size / 4))) {
1503 real_size += 3;
1504 } else {
1505 if (adjusted_pulse >= ((avg_size * 2) + (avg_size / 4))) {
1506 if ((2 * ((adjusted_pulse >> 2) - adjust)) < (avg_size + (avg_size / 4)))
1507 real_size += 2;
1508 else
1509 real_size += 3;
1510 } else
1511 real_size += 2;
1515 if (outstep == 1) {
1516 for (j = real_size; j > 1; j--)
1517 addbit (d, 0);
1518 addbit (d, 1);
1519 for (j = 0; j < real_size; j++)
1520 *pt++ = (uae_u16)(pulse / real_size);
1523 /* prepares for the next pulse */
1524 adjust = ((real_size * avg_size)/8) - pulse;
1525 total -= psarray[array_index].size;
1526 totaldiv -= psarray[array_index].number_of_bits;
1527 psarray[array_index].size = pulse;
1528 psarray[array_index].number_of_bits = real_size;
1529 total += pulse;
1530 totaldiv += real_size;
1531 array_index++;
1532 if (array_index >= FDI_MAX_ARRAY)
1533 array_index = 0;
1536 fdi->out = bitoffset;
1539 #else
1541 static void fdi2_decode (FDI *fdi, unsigned long totalavg, uae_u32 *avgp, uae_u32 *minp, uae_u32 *maxp, uae_u8 *idx, unsigned int maxidx, unsigned int *indexoffsetp, unsigned int pulses, int mfm)
1543 unsigned long adjust;
1544 unsigned long adjusted_pulse;
1545 unsigned long standard_MFM_2_bit_cell_size = totalavg / 50000;
1546 unsigned long standard_MFM_8_bit_cell_size = totalavg / 12500;
1547 unsigned int real_size, i, nexti, eodat, randval;
1548 int outstep;
1549 unsigned int indexoffset = *indexoffsetp;
1550 uae_u8 *d = fdi->track_dst_buffer;
1551 uae_u16 *pt = fdi->track_dst_buffer_timing;
1552 uae_u32 ref_pulse, pulse;
1553 long jitter;
1555 /* detects a long-enough stable pulse coming just after another stable pulse */
1556 i = 1;
1557 while ( (i < pulses) && ( (idx[i] < maxidx)
1558 || (idx[i - 1] < maxidx)
1559 || (minp[i] < (standard_MFM_2_bit_cell_size - (standard_MFM_2_bit_cell_size / 4))) ) )
1560 i++;
1561 if (i == pulses) {
1562 outlog ("FDI: No stable and long-enough pulse in track.\n");
1563 return;
1565 nexti = i;
1566 eodat = i;
1567 i--;
1568 adjust = 0;
1569 total = 0;
1570 totaldiv = 0;
1571 init_array(standard_MFM_2_bit_cell_size, 1 + mfm);
1572 bitoffset = 0;
1573 ref_pulse = 0;
1574 jitter = 0;
1575 outstep = -1;
1576 while (outstep < 2) {
1578 /* calculates the current average bitrate from previous decoded data */
1579 uae_u32 avg_size = (total << (2 + mfm)) / totaldiv; /* this is the new average size for one MFM bit */
1580 /* uae_u32 avg_size = (uae_u32)((((float)total)*((float)(mfm+1))*4.0) / ((float)totaldiv)); */
1581 /* you can try tighter ranges than 25%, or wider ranges. I would probably go for tighter... */
1582 if ((avg_size < (standard_MFM_8_bit_cell_size - (pulse_limitval * standard_MFM_8_bit_cell_size / 100))) ||
1583 (avg_size > (standard_MFM_8_bit_cell_size + (pulse_limitval * standard_MFM_8_bit_cell_size / 100)))) {
1584 //init_array(standard_MFM_2_bit_cell_size, mfm + 1);
1585 avg_size = standard_MFM_8_bit_cell_size;
1587 /* this is to prevent the average value from going too far
1588 * from the theoretical value, otherwise it could progressively go to (2 *
1589 * real value), or (real value / 2), etc. */
1591 /* gets the next long-enough pulse (this may require more than one pulse) */
1592 pulse = 0;
1593 while (pulse < ((avg_size / 4) - (avg_size / 16))) {
1594 uae_u32 avg_pulse, min_pulse, max_pulse;
1595 i++;
1596 if (i >= pulses)
1597 i = 0;
1598 if (i == nexti) {
1599 do {
1600 nexti++;
1601 if (nexti >= pulses)
1602 nexti = 0;
1603 } while (idx[nexti] < maxidx);
1605 if (idx[i] >= maxidx) { /* stable pulse */
1606 avg_pulse = avgp[i] - jitter;
1607 min_pulse = minp[i];
1608 max_pulse = maxp[i];
1609 if (jitter >= 0)
1610 max_pulse -= jitter;
1611 else
1612 min_pulse -= jitter;
1613 if ((maxp[nexti] - avgp[nexti]) < (avg_pulse - min_pulse))
1614 min_pulse = avg_pulse - (maxp[nexti] - avgp[nexti]);
1615 if ((avgp[nexti] - minp[nexti]) < (max_pulse - avg_pulse))
1616 max_pulse = avg_pulse + (avgp[nexti] - minp[nexti]);
1617 if (min_pulse < ref_pulse)
1618 min_pulse = ref_pulse;
1619 randval = rand();
1620 if (randval < (RAND_MAX / 2)) {
1621 if (randval > (RAND_MAX / 4)) {
1622 if (randval <= (3 * (RAND_MAX / 8)))
1623 randval = (2 * randval) - (RAND_MAX /4);
1624 else
1625 randval = (4 * randval) - RAND_MAX;
1627 jitter = 0 - (randval * (avg_pulse - min_pulse)) / RAND_MAX;
1628 } else {
1629 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;
1636 jitter = (randval * (max_pulse - avg_pulse)) / RAND_MAX;
1638 avg_pulse += jitter;
1639 if ((avg_pulse < min_pulse) || (avg_pulse > max_pulse)) {
1640 outlog ("FDI: avg_pulse outside bounds! avg=%u min=%u max=%u\n", avg_pulse, min_pulse, max_pulse);
1641 outlog ("FDI: avgp=%u (%u) minp=%u (%u) maxp=%u (%u) jitter=%d i=%d ni=%d\n",
1642 avgp[i], avgp[nexti], minp[i], minp[nexti], maxp[i], maxp[nexti], jitter, i, nexti);
1644 if (avg_pulse < ref_pulse)
1645 outlog ("FDI: avg_pulse < ref_pulse! (%u < %u)\n", avg_pulse, ref_pulse);
1646 pulse += avg_pulse - ref_pulse;
1647 ref_pulse = 0;
1648 if (i == eodat)
1649 outstep++;
1650 } else if ((unsigned int)rand () <= ((idx[i] * RAND_MAX) / maxidx)) {
1651 avg_pulse = avgp[i];
1652 min_pulse = minp[i];
1653 max_pulse = maxp[i];
1654 randval = rand();
1655 if (randval < (RAND_MAX / 2)) {
1656 if (randval > (RAND_MAX / 4)) {
1657 if (randval <= (3 * (RAND_MAX / 8)))
1658 randval = (2 * randval) - (RAND_MAX /4);
1659 else
1660 randval = (4 * randval) - RAND_MAX;
1662 avg_pulse -= (randval * (avg_pulse - min_pulse)) / RAND_MAX;
1663 } else {
1664 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;
1671 avg_pulse += (randval * (max_pulse - avg_pulse)) / RAND_MAX;
1673 if ((avg_pulse > ref_pulse) && (avg_pulse < (avgp[nexti] - jitter))) {
1674 pulse += avg_pulse - ref_pulse;
1675 ref_pulse = avg_pulse;
1678 if (outstep == 1 && indexoffset == i)
1679 *indexoffsetp = bitoffset;
1682 /* gets the size in bits from the pulse width, considering the current average bitrate */
1683 adjusted_pulse = pulse;
1684 real_size = 0;
1685 if (mfm) {
1686 while (adjusted_pulse >= avg_size) {
1687 real_size += 4;
1688 adjusted_pulse -= avg_size / 2;
1690 adjusted_pulse <<= 3;
1691 while (adjusted_pulse >= ((avg_size * 4) + (avg_size / 4))) {
1692 real_size += 2;
1693 adjusted_pulse -= avg_size * 2;
1695 if (adjusted_pulse >= ((avg_size * 3) + (avg_size / 4))) {
1696 if (adjusted_pulse <= ((avg_size * 4) - (avg_size / 4))) {
1697 if ((2 * ((adjusted_pulse >> 2) - adjust)) <= ((2 * avg_size) - (avg_size / 4)))
1698 real_size += 3;
1699 else
1700 real_size += 4;
1701 } else
1702 real_size += 4;
1703 } else {
1704 if (adjusted_pulse > ((avg_size * 3) - (avg_size / 4))) {
1705 real_size += 3;
1706 } else {
1707 if (adjusted_pulse >= ((avg_size * 2) + (avg_size / 4))) {
1708 if ((2 * ((adjusted_pulse >> 2) - adjust)) < (avg_size + (avg_size / 4)))
1709 real_size += 2;
1710 else
1711 real_size += 3;
1712 } else
1713 real_size += 2;
1716 } else {
1717 while (adjusted_pulse >= (2*avg_size))
1719 real_size+=4;
1720 adjusted_pulse-=avg_size;
1722 adjusted_pulse<<=2;
1723 while (adjusted_pulse >= ((avg_size*3)+(avg_size/4)))
1725 real_size+=2;
1726 adjusted_pulse-=avg_size*2;
1728 if (adjusted_pulse >= ((avg_size*2)+(avg_size/4)))
1730 if (adjusted_pulse <= ((avg_size*3)-(avg_size/4)))
1732 if (((adjusted_pulse>>1)-adjust) < (avg_size+(avg_size/4)))
1733 real_size+=2;
1734 else
1735 real_size+=3;
1737 else
1738 real_size+=3;
1740 else
1742 if (adjusted_pulse > ((avg_size*2)-(avg_size/4)))
1743 real_size+=2;
1744 else
1746 if (adjusted_pulse >= (avg_size+(avg_size/4)))
1748 if (((adjusted_pulse>>1)-adjust) <= (avg_size-(avg_size/4)))
1749 real_size++;
1750 else
1751 real_size+=2;
1753 else
1754 real_size++;
1759 /* after one pass to correctly initialize the average bitrate, outputs the bits */
1760 if (outstep == 1) {
1761 unsigned int j;
1762 for (j = real_size; j > 1; j--)
1763 addbit (d, 0);
1764 addbit (d, 1);
1765 for (j = 0; j < real_size; j++)
1766 *pt++ = (uae_u16)(pulse / real_size);
1769 /* prepares for the next pulse */
1770 adjust = ((real_size * avg_size) / (4 << mfm)) - pulse;
1771 total -= psarray[array_index].size;
1772 totaldiv -= psarray[array_index].number_of_bits;
1773 psarray[array_index].size = pulse;
1774 psarray[array_index].number_of_bits = real_size;
1775 total += pulse;
1776 totaldiv += real_size;
1777 array_index++;
1778 if (array_index >= FDI_MAX_ARRAY)
1779 array_index = 0;
1782 fdi->out = bitoffset;
1785 #endif
1787 static void fdi2_celltiming (FDI *fdi, unsigned long totalavg, unsigned int bitoffset, uae_u16 *out)
1789 uae_u16 *pt2, *pt;
1790 double avg_bit_len;
1791 unsigned int i;
1793 avg_bit_len = (double)totalavg / (double)bitoffset;
1794 pt2 = fdi->track_dst_buffer_timing;
1795 pt = out;
1796 for (i = 0; i < bitoffset / 8; i++) {
1797 double v = (pt2[0] + pt2[1] + pt2[2] + pt2[3] + pt2[4] + pt2[5] + pt2[6] + pt2[7]) / 8.0;
1798 v = 1000.0 * v / avg_bit_len;
1799 *pt++ = (uae_u16)v;
1800 pt2 += 8;
1802 *pt++ = out[0];
1803 *pt = out[0];
1806 static int decode_lowlevel_track (FDI *fdi, unsigned int track, struct fdi_cache *cache)
1808 uae_u8 *p1, *d;
1809 uae_u32 *p2;
1810 uae_u32 *avgp, *minp = 0, *maxp = 0;
1811 uae_u8 *idxp = 0;
1812 uae_u32 maxidx, totalavg, weakbits;
1813 unsigned int i, j, len, pulses, indexoffset;
1814 unsigned int avg_free, min_free = 0, max_free = 0, idx_free;
1815 unsigned int idx_off1 = 0, idx_off2 = 0, idx_off3 = 0;
1817 d = fdi->track_dst;
1818 p1 = fdi->track_src;
1819 pulses = get_u32 (p1);
1820 if (!pulses)
1821 return -1;
1822 p1 += 4;
1823 len = 12;
1824 avgp = (uae_u32*)fdi_decompress (pulses, p1 + 0, p1 + len, &avg_free);
1825 dumpstream(track, (uae_u8*)avgp, pulses);
1826 len += get_u24 (p1 + 0) & 0x3fffff;
1827 if (!avgp)
1828 return -1;
1829 if (get_u24 (p1 + 3) && get_u24 (p1 + 6)) {
1830 minp = (uae_u32*)fdi_decompress (pulses, p1 + 3, p1 + len, &min_free);
1831 len += get_u24 (p1 + 3) & 0x3fffff;
1832 maxp = (uae_u32*)fdi_decompress (pulses, p1 + 6, p1 + len, &max_free);
1833 len += get_u24 (p1 + 6) & 0x3fffff;
1834 /* Computes the real min and max values */
1835 for (i = 0; i < pulses; i++) {
1836 maxp[i] = avgp[i] + minp[i] - maxp[i];
1837 minp[i] = avgp[i] - minp[i];
1839 } else {
1840 minp = avgp;
1841 maxp = avgp;
1843 if (get_u24 (p1 + 9)) {
1844 idx_off1 = 0;
1845 idx_off2 = 1;
1846 idx_off3 = 2;
1847 idxp = fdi_decompress (pulses, p1 + 9, p1 + len, &idx_free);
1848 if (idx_free) {
1849 if (idxp[0] == 0 && idxp[1] == 0) {
1850 idx_off1 = 2;
1851 idx_off2 = 3;
1852 } else {
1853 idx_off1 = 1;
1854 idx_off2 = 0;
1856 idx_off3 = 4;
1858 } else {
1859 idxp = fdi_malloc (pulses * 2);
1860 idx_free = 1;
1861 for (i = 0; i < pulses; i++) {
1862 idxp[i * 2 + 0] = 2;
1863 idxp[i * 2 + 1] = 0;
1865 idxp[0] = 1;
1866 idxp[1] = 1;
1869 maxidx = 0;
1870 indexoffset = 0;
1871 p1 = idxp;
1872 for (i = 0; i < pulses; i++) {
1873 if (p1[idx_off1] + p1[idx_off2] > maxidx)
1874 maxidx = p1[idx_off1] + p1[idx_off2];
1875 p1 += idx_off3;
1877 p1 = idxp;
1878 for (i = 0; (i < pulses) && (p1[idx_off2] != 0); i++) /* falling edge, replace with idx_off1 for rising edge */
1879 p1 += idx_off3;
1880 if (i < pulses) {
1881 j = i;
1882 do {
1883 i++;
1884 p1 += idx_off3;
1885 if (i >= pulses) {
1886 i = 0;
1887 p1 = idxp;
1889 } while ((i != j) && (p1[idx_off2] == 0)); /* falling edge, replace with idx_off1 for rising edge */
1890 if (i != j) /* index pulse detected */
1892 while ((i != j) && (p1[idx_off1] > p1[idx_off2])) { /* falling edge, replace with "<" for rising edge */
1893 i++;
1894 p1 += idx_off3;
1895 if (i >= pulses) {
1896 i = 0;
1897 p1 = idxp;
1900 if (i != j)
1901 indexoffset = i; /* index position detected */
1904 p1 = idxp;
1905 p2 = avgp;
1906 totalavg = 0;
1907 weakbits = 0;
1908 for (i = 0; i < pulses; i++) {
1909 uae_u32 sum = p1[idx_off1] + p1[idx_off2];
1910 if (sum >= maxidx) {
1911 totalavg += *p2;
1912 } else {
1913 weakbits++;
1915 p2++;
1916 p1 += idx_off3;
1917 idxp[i] = sum;
1919 len = totalavg / 100000;
1920 outlog ("totalavg=%u index=%d (%d) maxidx=%d weakbits=%d len=%d\n",
1921 totalavg, indexoffset, maxidx, weakbits, len);
1922 cache->avgp = avgp;
1923 cache->idxp = idxp;
1924 cache->minp = minp;
1925 cache->maxp = maxp;
1926 cache->avg_free = avg_free;
1927 cache->idx_free = idx_free;
1928 cache->min_free = min_free;
1929 cache->max_free = max_free;
1930 cache->totalavg = totalavg;
1931 cache->pulses = pulses;
1932 cache->maxidx = maxidx;
1933 cache->indexoffset = indexoffset;
1934 cache->weakbits = weakbits;
1935 cache->lowlevel = 1;
1937 return 1;
1940 static const char fdiid[] = "Formatted Disk Image file";
1941 static const unsigned int bit_rate_table[16] = { 125,150,250,300,500,1000 };
1943 void fdi2raw_header_free (FDI *fdi)
1945 int i;
1947 fdi_free (fdi->mfmsync_buffer);
1948 fdi_free (fdi->track_src_buffer);
1949 fdi_free (fdi->track_dst_buffer);
1950 fdi_free (fdi->track_dst_buffer_timing);
1951 for (i = 0; i < MAX_TRACKS; i++) {
1952 struct fdi_cache *c = &fdi->cache[i];
1953 if (c->idx_free)
1954 fdi_free (c->idxp);
1955 if (c->avg_free)
1956 fdi_free (c->avgp);
1957 if (c->min_free)
1958 fdi_free (c->minp);
1959 if (c->max_free)
1960 fdi_free (c->maxp);
1962 fdi_free (fdi);
1963 debuglog ("FREE: memory allocated %d\n", fdi_allocated);
1966 int fdi2raw_get_last_track (FDI *fdi)
1968 return fdi->last_track;
1971 int fdi2raw_get_num_sector (FDI *fdi)
1973 if (fdi->header[152] == 0x02)
1974 return 22;
1975 return 11;
1978 unsigned int fdi2raw_get_last_head (FDI *fdi)
1980 return fdi->last_head;
1983 unsigned int fdi2raw_get_rotation (FDI *fdi)
1985 return fdi->rotation_speed;
1988 unsigned int fdi2raw_get_bit_rate (FDI *fdi)
1990 return fdi->bit_rate;
1993 int fdi2raw_get_type (FDI *fdi)
1995 return fdi->disk_type;
1998 int fdi2raw_get_write_protect (FDI *fdi)
2000 return fdi->write_protect;
2003 FDI * fdi2raw_header(BPTR f)
2005 unsigned int i, offset, oldseek;
2006 uae_u8 type, size;
2007 FDI *fdi;
2009 debuglog ("ALLOC: memory allocated %d\n", fdi_allocated);
2010 fdi = fdi_malloc (sizeof(FDI));
2011 if (!fdi) {
2012 SetIoErr(ERROR_NO_FREE_STORE);
2013 return NULL;
2015 memset (fdi, 0, sizeof (FDI));
2016 fdi->file = f;
2017 oldseek = Seek(fdi->file, 0, OFFSET_BEGINNING);
2018 Read(fdi->file, fdi->header, 2048);
2019 Seek(fdi->file, oldseek, OFFSET_BEGINNING);
2020 if (memcmp (fdiid, fdi->header, strlen (fdiid))) {
2021 fdi_free(fdi);
2022 SetIoErr(ERROR_OBJECT_WRONG_TYPE);
2023 return NULL;
2025 if ((fdi->header[140] != 1 && fdi->header[140] != 2) || fdi->header[141] != 0) {
2026 fdi_free(fdi);
2027 SetIoErr(ERROR_OBJECT_WRONG_TYPE);
2028 return NULL;
2031 fdi->mfmsync_buffer = fdi_malloc (MAX_MFM_SYNC_BUFFER * sizeof(int));
2032 fdi->track_src_buffer = fdi_malloc (MAX_SRC_BUFFER);
2033 fdi->track_dst_buffer = fdi_malloc (MAX_DST_BUFFER);
2034 fdi->track_dst_buffer_timing = fdi_malloc (MAX_TIMING_BUFFER);
2036 fdi->last_track = ((fdi->header[142] << 8) + fdi->header[143]) + 1;
2037 fdi->last_track *= fdi->header[144] + 1;
2038 if (fdi->last_track > MAX_TRACKS)
2039 fdi->last_track = MAX_TRACKS;
2040 fdi->last_head = fdi->header[144];
2041 fdi->disk_type = fdi->header[145];
2042 fdi->rotation_speed = fdi->header[146] + 128;
2043 fdi->write_protect = fdi->header[147] & 1;
2044 outlog ("FDI version %d.%d\n", fdi->header[140], fdi->header[141]);
2045 outlog ("last_track=%d rotation_speed=%d\n", fdi->last_track, fdi->rotation_speed);
2047 offset = 512;
2048 i = fdi->last_track;
2049 if (i > 180) {
2050 offset += 512;
2051 i -= 180;
2052 while (i > 256) {
2053 offset += 512;
2054 i -= 256;
2057 for (i = 0; i < fdi->last_track; i++) {
2058 fdi->track_offsets[i] = offset;
2059 type = fdi->header[152 + i * 2];
2060 size = fdi->header[152 + i * 2 + 1];
2061 if (type == 1)
2062 offset += (size & 15) * 512;
2063 else if ((type & 0xc0) == 0x80)
2064 offset += (((type & 0x3f) << 8) | size) * 256;
2065 else
2066 offset += size * 256;
2068 fdi->track_offsets[i] = offset;
2070 return fdi;
2074 static int fdi2raw_loadrevolution_2 (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, unsigned int track, unsigned int *tracklength, unsigned int *indexoffsetp, int *multirev, int mfm)
2076 struct fdi_cache *cache = &fdi->cache[track];
2077 unsigned int len, i, idx;
2079 memset (fdi->track_dst_buffer, 0, MAX_DST_BUFFER);
2080 idx = cache->indexoffset;
2081 fdi2_decode (fdi, cache->totalavg,
2082 cache->avgp, cache->minp, cache->maxp, cache->idxp,
2083 cache->maxidx, &idx, cache->pulses, mfm);
2084 //fdi2_gcr_decode (fdi, totalavg, avgp, minp, maxp, idxp, idx_off1, idx_off2, idx_off3, maxidx, pulses);
2085 outlog ("track %d: nbits=%d avg len=%.2f weakbits=%d idx=%d\n",
2086 track, bitoffset, (double)cache->totalavg / bitoffset, cache->weakbits, cache->indexoffset);
2087 len = fdi->out;
2088 if (cache->weakbits >= 10 && multirev)
2089 *multirev = 1;
2090 *tracklength = len;
2092 for (i = 0; i < (len + 15) / (2 * 8); i++) {
2093 uae_u8 *data = fdi->track_dst_buffer + i * 2;
2094 *mfmbuf++ = 256 * *data + *(data + 1);
2096 fdi2_celltiming (fdi, cache->totalavg, len, tracktiming);
2097 if (indexoffsetp)
2098 *indexoffsetp = idx;
2099 return 1;
2102 int fdi2raw_loadrevolution (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, unsigned int track, unsigned int *tracklength, int mfm)
2104 return fdi2raw_loadrevolution_2 (fdi, mfmbuf, tracktiming, track, tracklength, 0, 0, mfm);
2107 int fdi2raw_loadtrack (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, unsigned int track, unsigned int *tracklength, unsigned int *indexoffsetp, int *multirev, int mfm)
2109 uae_u8 *p;
2110 int outlen;
2111 unsigned int indexoffset = 0;
2112 struct fdi_cache *cache = &fdi->cache[track];
2114 if (cache->lowlevel)
2115 return fdi2raw_loadrevolution_2 (fdi, mfmbuf, tracktiming, track, tracklength, indexoffsetp, multirev, mfm);
2117 fdi->err = 0;
2118 fdi->track_src_len = fdi->track_offsets[track + 1] - fdi->track_offsets[track];
2119 Seek(fdi->file, fdi->track_offsets[track], OFFSET_BEGINNING);
2120 Read(fdi->file, fdi->track_src_buffer, fdi->track_src_len);
2121 memset (fdi->track_dst_buffer, 0, MAX_DST_BUFFER);
2122 fdi->track_dst_buffer_timing[0] = 0;
2124 fdi->current_track = track;
2125 fdi->track_src = fdi->track_src_buffer;
2126 fdi->track_dst = fdi->track_dst_buffer;
2127 p = fdi->header + 152 + fdi->current_track * 2;
2128 fdi->track_type = *p++;
2129 fdi->track_len = *p++;
2130 fdi->bit_rate = 0;
2131 fdi->out = 0;
2132 fdi->mfmsync_offset = 0;
2134 if ((fdi->track_type & 0xf0) == 0xf0 || (fdi->track_type & 0xf0) == 0xe0)
2135 fdi->bit_rate = bit_rate_table[fdi->track_type & 0x0f];
2136 else
2137 fdi->bit_rate = 250;
2139 outlog ("track %d: srclen: %d track_type: %02.2X, bitrate: %d\n",
2140 fdi->current_track, fdi->track_src_len, fdi->track_type, fdi->bit_rate);
2142 if ((fdi->track_type & 0xc0) == 0x80) {
2144 outlen = decode_lowlevel_track (fdi, track, cache);
2146 } else if ((fdi->track_type & 0xf0) == 0xf0) {
2148 outlen = decode_raw_track (fdi);
2150 } else if ((fdi->track_type & 0xf0) == 0xe0) {
2152 outlen = handle_sectors_described_track (fdi);
2154 } else if ((fdi->track_type & 0xf0)) {
2156 zxx (fdi);
2157 outlen = -1;
2159 } else if (fdi->track_type < 0x10) {
2161 decode_normal_track[fdi->track_type](fdi);
2162 fix_mfm_sync (fdi);
2163 outlen = fdi->out;
2165 } else {
2167 zxx (fdi);
2168 outlen = -1;
2172 // amiga_check_track (fdi);
2174 if (fdi->err)
2175 return 0;
2177 if (outlen > 0) {
2178 unsigned int i;
2180 if (cache->lowlevel)
2181 return fdi2raw_loadrevolution_2 (fdi, mfmbuf, tracktiming, track, tracklength, indexoffsetp, multirev, mfm);
2182 *tracklength = fdi->out;
2184 for (i = 0; i < ((*tracklength) + 15) / (2 * 8); i++) {
2185 uae_u8 *data = fdi->track_dst_buffer + i * 2;
2186 *mfmbuf++ = 256 * *data + *(data + 1);
2189 return outlen;