3 FDI to raw bit stream converter
4 Copyright (c) 2001 by Toni Wilen <twilen@arabuusimiehet.com>
6 Copyright (c) 2003-2004 by Toni Wilen <twilen@arabuusimiehet.com>
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,
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)
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
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>
40 extern struct Library
*SysBase
;
41 extern struct Library
*DOSBase
;
44 //#include "sysconfig.h"
45 //#include "sysdeps.h"
54 #define RAND_MAX 0x7fffffff
56 unsigned long long rnd_seed
= 0;
59 rnd_seed
= ((rnd_seed
* 1103515245ULL) + 12345ULL) & 0xffffffffULL
;
60 return (int)(rnd_seed
& RAND_MAX
);
68 static const char *datalog (const uae_u8
*src
, unsigned int len
)
70 static char buf
[1000];
77 sprintf (buf
+ offset
, "%02.2X", src
[i
]);
84 if (offset
>= 900) offset
= 0;
88 static const char *datalog (const uae_u8
*src
, unsigned int len
) { return ""; }
92 #define debuglog write_log
94 #define debuglog(...) do { ; } while (0)
97 #define outlog write_log
99 #define outlog(...) do { ; } while (0)
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
112 uae_u32
*avgp
, *minp
, *maxp
;
114 unsigned int avg_free
, idx_free
, min_free
, max_free
;
115 uae_u32 totalavg
, pulses
, maxidx
, indexoffset
;
116 unsigned int weakbits
;
121 uae_u8
*track_src_buffer
;
124 uae_u8
*track_dst_buffer
;
126 uae_u16
*track_dst_buffer_timing
;
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
;
138 unsigned int track_offsets
[MAX_TRACKS
];
143 /* sector described only */
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
)
166 typedef struct node NODE
;
168 static uae_u8 temp
, temp2
;
170 static const uae_u8
*expand_tree (const uae_u8
*stream
, NODE
*node
)
173 fdi_free (node
->left
);
175 fdi_free (node
->right
);
184 const uae_u8
*stream_temp
;
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) {
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
++);
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
)
225 free_nodes (node
->left
);
226 free_nodes (node
->right
);
231 STATIC_INLINE uae_u32
sign_extend16 (uae_u32 v
)
238 STATIC_INLINE uae_u32
sign_extend8 (uae_u32 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
;
251 memset (out
, 0, size
* 4);
252 sub_stream_shift
= 1;
253 while (sub_stream_shift
) {
256 //sub-stream header decode
257 sign_extend
= *stream
++;
258 sub_stream_shift
= sign_extend
& 0x7f;
260 sixteen_bit
= (*stream
++) & 0x80;
262 //huffman tree architecture decode
265 stream
= expand_tree (stream
, &root
);
269 //huffman output values decode
271 stream
= values_tree16 (stream
, &root
);
273 stream
= values_tree8 (stream
, &root
);
275 //sub-stream data decode
277 for (i
= 0; i
< size
; i
++) {
280 current_node
= &root
;
282 if (current_node
->left
== 0) {
291 current_node
= current_node
->right
;
293 current_node
= current_node
->left
;
296 v
= ((uae_u32
*)out
)[i
];
299 v
|= sign_extend16 (current_node
->v
) << sub_stream_shift
;
301 v
|= sign_extend8 (current_node
->v
) << sub_stream_shift
;
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;
322 static void zxx (FDI
*fdi
)
324 outlog ("track %d: unknown track type 0x%02.2X\n", fdi
->current_track
, fdi
->track_type
);
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
);
334 static void track_empty (FDI
*fdi
)
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
);
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
);
351 /* add position of mfm sync bit */
352 static void add_mfm_sync_bit (FDI
*fdi
)
358 fdi
->mfmsync_buffer
[fdi
->mfmsync_offset
++] = fdi
->out
;
360 outlog ("illegal position for mfm sync bit, offset=%d\n",fdi
->out
);
363 if (fdi
->mfmsync_offset
>= MAX_MFM_SYNC_BUFFER
) {
364 fdi
->mfmsync_offset
= 0;
365 outlog ("mfmsync buffer overflow\n");
371 #define BIT_BYTEOFFSET ((fdi->out) >> 3)
372 #define BIT_BITOFFSET (7-((fdi->out)&7))
375 static void bit_add (FDI
*fdi
, int bit
)
381 fdi
->track_dst
[BIT_BYTEOFFSET
] &= ~(1 << BIT_BITOFFSET
);
383 fdi
->track_dst
[BIT_BYTEOFFSET
] |= (1 << BIT_BITOFFSET
);
385 if (fdi
->out
>= MAX_DST_BUFFER
* 8) {
386 outlog ("destination buffer overflow\n");
391 /* add bit and mfm sync bit */
392 static void bit_mfm_add (FDI
*fdi
, int bit
)
394 add_mfm_sync_bit (fdi
);
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) {
411 /* ignore next bit_drop_next() */
412 static void bit_dedrop (FDI
*fdi
)
415 outlog ("bit_drop_next called before bit_dedrop");
422 static void byte_add (FDI
*fdi
, uae_u8 v
)
425 for (i
= 7; i
>= 0; i
--)
426 bit_add (fdi
, v
& (1 << i
));
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
)
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
)
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
)
451 for (i
= 14; i
>= 0; i
-= 2)
452 bit_mfm_add (fdi
, v
& (1 << i
));
456 static void s00(FDI
*fdi
) { bit_add (fdi
, 0); }
458 static void s01(FDI
*fdi
) { bit_add (fdi
, 1); }
460 static void s02(FDI
*fdi
) { word_add (fdi
, 0x4489); }
462 static void s03(FDI
*fdi
) { word_add (fdi
, 0x5224); }
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;
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];
490 debuglog ("s0a:bits=%d,data=%s", bits
, datalog (fdi
->track_src
, (bits
+ 7) / 8));
492 byte_add (fdi
, *fdi
->track_src
++);
497 b
= *fdi
->track_src
++;
499 bit_add (fdi
, b
& (1 << 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;
510 debuglog ("s0b:bits=%d,data=%s", bits
, datalog (fdi
->track_src
, (bits
+ 7) / 8));
512 byte_add (fdi
, *fdi
->track_src
++);
517 b
= *fdi
->track_src
++;
519 bit_add (fdi
, b
& (1 << i
));
524 /* MFM-decoded data */
525 static void s0c(FDI
*fdi
)
527 int i
, bits
= (fdi
->track_src
[0] << 8) | fdi
->track_src
[1];
531 debuglog ("s0c:bits=%d,data=%s", bits
, datalog (fdi
->track_src
, (bits
+ 7) / 8));
533 byte_mfm_add (fdi
, *fdi
->track_src
++);
538 b
= *fdi
->track_src
++;
540 bit_mfm_add (fdi
, b
& (1 << 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;
552 debuglog ("s0d:bits=%d,data=%s", bits
, datalog (fdi
->track_src
, (bits
+ 7) / 8));
554 byte_mfm_add (fdi
, *fdi
->track_src
++);
559 b
= *fdi
->track_src
++;
561 bit_mfm_add (fdi
, b
& (1 << i
));
571 /* just for testing integrity of Amiga sectors */
573 static void rotateonebit (uae_u8
*start
, uae_u8
*end
, unsigned int shift
)
577 while (start
<= end
) {
579 start
[0] |= start
[1] >> (8 - shift
);
584 static int check_offset
;
585 static uae_u16
getmfmword (const uae_u8
*mbuf
)
589 v
= (mbuf
[0] << 8) | (mbuf
[1] << 0);
590 if (check_offset
== 0)
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
;
610 uae_u32 odd
, even
, chksum
, id
, dlong
;
613 uae_u8 bigmfmbuf
[60000];
614 uae_u8
*mbuf
, *mbuf2
, *mend
;
616 uae_u8
*raw
= fdi
->track_dst_buffer
;
620 memset (bigmfmbuf
, 0, sizeof (bigmfmbuf
));
623 for (i
= 0; i
< (fdi
->out
+ 7) / 8; i
++)
629 *mbuf
&= ~((1 << (8 - off
)) - 1);
632 while (i
< (fdi
->out
+ 7) / 8 + 600) {
633 *mbuf
++ |= (raw
[j
] >> off
) | ((raw
[j
+ 1]) << (8 - off
));
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
) {
649 rotateonebit (bigmfmbuf
, mend
, 1);
650 if (getmfmword (mbuf
) == 0)
652 if (secwritten
== 10) {
657 if (check_offset
> 7) {
660 if (mbuf
>= mend
|| *mbuf
== 0)
663 if (getmfmword (mbuf
) == 0x4489)
666 if (mbuf
>= mend
|| *mbuf
== 0)
669 rotateonebit (bigmfmbuf
, mend
, check_offset
);
672 while (getmfmword (mbuf
) == 0x4489)
676 odd
= getmfmlong (mbuf
);
677 even
= getmfmlong (mbuf
+ 2 * 2);
679 id
= (odd
<< 1) | even
;
681 trackoffs
= (id
& 0xff00) >> 8;
682 if (trackoffs
+ 1 > drvsec
) {
683 outlog ("illegal sector offset %d\n",trackoffs
);
688 if ((id
>> 24) != 0xff) {
689 outlog ("sector %d format type %02.2X?\n", trackoffs
, id
>> 24);
694 for (i
= 0; i
< 4; i
++) {
695 odd
= getmfmlong (mbuf
);
696 even
= getmfmlong (mbuf
+ 8 * 2);
699 dlong
= (odd
<< 1) | even
;
700 if (dlong
) slabel
= 1;
701 chksum
^= odd
^ even
;
704 odd
= getmfmlong (mbuf
);
705 even
= getmfmlong (mbuf
+ 2 * 2);
707 if (((odd
<< 1) | even
) != chksum
) {
708 outlog ("sector %d header crc error\n", trackoffs
);
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);
720 odd
= getmfmlong (mbuf
);
721 even
= getmfmlong (mbuf
+ 2 * 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);
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
;
738 outlog ("sector %d data checksum error\n",trackoffs
);
740 } else if (sectable
[trackoffs
]) {
741 outlog ("sector %d already found?\n", trackoffs
);
744 outlog ("sector %d ok\n",trackoffs
);
745 if (slabel
) outlog ("(non-empty sector header)\n");
746 sectable
[trackoffs
] = 1;
752 for (i
= 0; i
< drvsec
; i
++) {
754 outlog ("sector %d missing\n", i
);
761 static void amiga_data_raw (FDI
*fdi
, uae_u8
*secbuf
, uae_u8
*crc
, unsigned int len
)
767 memset (crcbuf
, 0, 4);
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
;
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]));
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
;
795 for (i
= 4; i
< 4 + 512; i
+= 2)
796 dck
^= (mfmbuf
[i
] << 16) | mfmbuf
[i
+ 1];
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
;
817 byte_mfm_add (fdi
, 0);
818 byte_mfm_add (fdi
, 0);
819 word_add (fdi
, 0x4489);
820 word_add (fdi
, 0x4489);
822 memcpy (headerbuf
, header
, 4);
825 headerbuf
[1] = (uae_u8
)fdi
->current_track
;
826 headerbuf
[2] = (uae_u8
)sector
;
827 headerbuf
[3] = (uae_u8
)untilgap
;
830 memcpy (databuf
, data
, 16);
832 memset (databuf
, 0, 16);
834 deven
= ((headerbuf
[0] << 24) | (headerbuf
[1] << 16)
835 | (headerbuf
[2] << 8) | (headerbuf
[3]));
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]));
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
;
855 for (i
= 0; i
< 4 + 16; i
+= 2)
856 hck
^= (mfmbuf
[i
] << 16) | mfmbuf
[i
+ 1];
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
)
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
)
882 debuglog ("s21:header=%s", datalog (fdi
->track_src
, 4));
883 amiga_sector_header (fdi
, fdi
->track_src
, 0, 0, 0);
886 /* standard Amiga sector header */
887 static void s22(FDI
*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]);
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
)
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
)
929 debuglog ("s27:data=%s", datalog (fdi
->track_src
, 512));
930 amiga_data (fdi
, fdi
->track_src
);
931 fdi
->track_src
+= 512;
938 static uae_u16
ibm_crc (uae_u8 byte
, int reset
)
943 if (reset
) crc
= 0xcdb4;
944 for (i
= 0; i
< 8; i
++) {
947 if (!(byte
& 0x80)) crc
^= 0x1021;
950 if (byte
& 0x80) crc
^= 0x1021;
957 static void ibm_data (FDI
*fdi
, const uae_u8
*data
, uae_u8
*crc
, unsigned int len
)
963 word_add (fdi
, 0x4489);
964 word_add (fdi
, 0x4489);
965 word_add (fdi
, 0x4489);
966 byte_mfm_add (fdi
, 0xfb);
968 for (i
= 0; i
< len
; i
++) {
969 byte_mfm_add (fdi
, data
[i
]);
970 crcv
= ibm_crc (data
[i
], 0);
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
)
989 bytes_mfm_add (fdi
, 0, 12);
990 word_add (fdi
, 0x4489);
991 word_add (fdi
, 0x4489);
992 word_add (fdi
, 0x4489);
995 secbuf
[1] = (uae_u8
)(fdi
->current_track
/ 2);
996 secbuf
[2] = (uae_u8
)(fdi
->current_track
% 2);
997 secbuf
[3] = (uae_u8
)secnum
;
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);
1008 memcpy (crcbuf
, crc
, 2);
1010 crcbuf
[0] = (uae_u8
)(crcv
>> 8);
1011 crcbuf
[1] = (uae_u8
)crcv
;
1014 for (i
= 0;i
< 5; i
++)
1015 byte_mfm_add (fdi
, secbuf
[i
]);
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);
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];
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
)
1125 bytes_mfm_add (fdi
, 0x4e, 22);
1126 bytes_mfm_add (fdi
, 0x00, 12);
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
)
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);
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
) {
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
) {
1208 gap3
= 100; /* fixme */
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;
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;
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);
1248 static void track_pc_8 (struct fdi
*fdi
)
1253 static void track_pc_9 (struct fdi
*fdi
)
1258 static void track_pc_15 (struct fdi
*fdi
)
1263 static void track_pc_18 (struct fdi
*fdi
)
1268 static void track_pc_36 (struct fdi
*fdi
)
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;
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
;
1299 fdi
->track_dst
[off3
] &= ~mask3
;
1303 static int handle_sectors_described_track (FDI
*fdi
)
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
);
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
);
1317 decode_sectors_described_track
[fdi
->track_type
](fdi
);
1318 outlog (" %d\n", fdi
->out
- oldout
);
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
);
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
);
1328 } while (fdi
->track_type
!= 0xff);
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
);
1338 unsigned int len
= size
& 0x3fffff;
1340 unsigned int mode
= size
>> 22, i
;
1343 if (mode
== 0 && pulses
* 2 > len
)
1346 dst2
= (uae_u32
*)src
;
1348 for (i
= 0; i
< pulses
; i
++) {
1349 *dst2
++ = get_u32 (src
);
1352 } else if (mode
== 1) {
1353 dst
= fdi_malloc (pulses
* 4);
1355 fdi_decode (src
, pulses
, dst
);
1362 static void dumpstream(int track
, uae_u8
*stream
, int len
)
1368 sprintf (name
, "track_%d.raw", track
);
1369 f
= fopen(name
, "wb");
1370 fwrite (stream
, 1, len
* 4, f
);
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
);
1386 struct pulse_sample
{
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
)
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
;
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 */
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))) ) )
1433 outlog ("No stable and long-enough pulse in track.\n");
1441 init_array(standard_MFM_2_bit_cell_size
, 2);
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) */
1462 while (pulse
< ((avg_size
/ 4) - (avg_size
/ 16))) {
1468 if (rand() <= (indx
* RAND_MAX
) / maxidx
) {
1469 pulse
+= avgp
[i
] - ref_pulse
;
1473 ref_pulse
= avgp
[i
];
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
;
1484 while (adjusted_pulse
>= avg_size
) {
1486 adjusted_pulse
-= avg_size
/ 2;
1488 adjusted_pulse
<<= 3;
1489 while (adjusted_pulse
>= ((avg_size
* 4) + (avg_size
/ 4))) {
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)))
1502 if (adjusted_pulse
> ((avg_size
* 3) - (avg_size
/ 4))) {
1505 if (adjusted_pulse
>= ((avg_size
* 2) + (avg_size
/ 4))) {
1506 if ((2 * ((adjusted_pulse
>> 2) - adjust
)) < (avg_size
+ (avg_size
/ 4)))
1516 for (j
= real_size
; j
> 1; j
--)
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
;
1530 totaldiv
+= real_size
;
1532 if (array_index
>= FDI_MAX_ARRAY
)
1536 fdi
->out
= bitoffset
;
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
;
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
;
1555 /* detects a long-enough stable pulse coming just after another stable pulse */
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))) ) )
1562 outlog ("FDI: No stable and long-enough pulse in track.\n");
1571 init_array(standard_MFM_2_bit_cell_size
, 1 + mfm
);
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) */
1593 while (pulse
< ((avg_size
/ 4) - (avg_size
/ 16))) {
1594 uae_u32 avg_pulse
, min_pulse
, max_pulse
;
1601 if (nexti
>= pulses
)
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
];
1610 max_pulse
-= jitter
;
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
;
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);
1625 randval
= (4 * randval
) - RAND_MAX
;
1627 jitter
= 0 - (randval
* (avg_pulse
- min_pulse
)) / RAND_MAX
;
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);
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
;
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
];
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);
1660 randval
= (4 * randval
) - RAND_MAX
;
1662 avg_pulse
-= (randval
* (avg_pulse
- min_pulse
)) / RAND_MAX
;
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);
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
;
1686 while (adjusted_pulse
>= avg_size
) {
1688 adjusted_pulse
-= avg_size
/ 2;
1690 adjusted_pulse
<<= 3;
1691 while (adjusted_pulse
>= ((avg_size
* 4) + (avg_size
/ 4))) {
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)))
1704 if (adjusted_pulse
> ((avg_size
* 3) - (avg_size
/ 4))) {
1707 if (adjusted_pulse
>= ((avg_size
* 2) + (avg_size
/ 4))) {
1708 if ((2 * ((adjusted_pulse
>> 2) - adjust
)) < (avg_size
+ (avg_size
/ 4)))
1717 while (adjusted_pulse
>= (2*avg_size
))
1720 adjusted_pulse
-=avg_size
;
1723 while (adjusted_pulse
>= ((avg_size
*3)+(avg_size
/4)))
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)))
1742 if (adjusted_pulse
> ((avg_size
*2)-(avg_size
/4)))
1746 if (adjusted_pulse
>= (avg_size
+(avg_size
/4)))
1748 if (((adjusted_pulse
>>1)-adjust
) <= (avg_size
-(avg_size
/4)))
1759 /* after one pass to correctly initialize the average bitrate, outputs the bits */
1762 for (j
= real_size
; j
> 1; j
--)
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
;
1776 totaldiv
+= real_size
;
1778 if (array_index
>= FDI_MAX_ARRAY
)
1782 fdi
->out
= bitoffset
;
1787 static void fdi2_celltiming (FDI
*fdi
, unsigned long totalavg
, unsigned int bitoffset
, uae_u16
*out
)
1793 avg_bit_len
= (double)totalavg
/ (double)bitoffset
;
1794 pt2
= fdi
->track_dst_buffer_timing
;
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
;
1806 static int decode_lowlevel_track (FDI
*fdi
, unsigned int track
, struct fdi_cache
*cache
)
1810 uae_u32
*avgp
, *minp
= 0, *maxp
= 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;
1818 p1
= fdi
->track_src
;
1819 pulses
= get_u32 (p1
);
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;
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
];
1843 if (get_u24 (p1
+ 9)) {
1847 idxp
= fdi_decompress (pulses
, p1
+ 9, p1
+ len
, &idx_free
);
1849 if (idxp
[0] == 0 && idxp
[1] == 0) {
1859 idxp
= fdi_malloc (pulses
* 2);
1861 for (i
= 0; i
< pulses
; i
++) {
1862 idxp
[i
* 2 + 0] = 2;
1863 idxp
[i
* 2 + 1] = 0;
1872 for (i
= 0; i
< pulses
; i
++) {
1873 if (p1
[idx_off1
] + p1
[idx_off2
] > maxidx
)
1874 maxidx
= p1
[idx_off1
] + p1
[idx_off2
];
1878 for (i
= 0; (i
< pulses
) && (p1
[idx_off2
] != 0); i
++) /* falling edge, replace with idx_off1 for rising edge */
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 */
1901 indexoffset
= i
; /* index position detected */
1908 for (i
= 0; i
< pulses
; i
++) {
1909 uae_u32 sum
= p1
[idx_off1
] + p1
[idx_off2
];
1910 if (sum
>= maxidx
) {
1919 len
= totalavg
/ 100000;
1920 outlog ("totalavg=%u index=%d (%d) maxidx=%d weakbits=%d len=%d\n",
1921 totalavg
, indexoffset
, maxidx
, weakbits
, len
);
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;
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
)
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
];
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)
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
;
2009 debuglog ("ALLOC: memory allocated %d\n", fdi_allocated
);
2010 fdi
= fdi_malloc (sizeof(FDI
));
2012 SetIoErr(ERROR_NO_FREE_STORE
);
2015 memset (fdi
, 0, sizeof (FDI
));
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
))) {
2022 SetIoErr(ERROR_OBJECT_WRONG_TYPE
);
2025 if ((fdi
->header
[140] != 1 && fdi
->header
[140] != 2) || fdi
->header
[141] != 0) {
2027 SetIoErr(ERROR_OBJECT_WRONG_TYPE
);
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
);
2048 i
= fdi
->last_track
;
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];
2062 offset
+= (size
& 15) * 512;
2063 else if ((type
& 0xc0) == 0x80)
2064 offset
+= (((type
& 0x3f) << 8) | size
) * 256;
2066 offset
+= size
* 256;
2068 fdi
->track_offsets
[i
] = offset
;
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
);
2088 if (cache
->weakbits
>= 10 && multirev
)
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
);
2098 *indexoffsetp
= idx
;
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
)
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
);
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
++;
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];
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)) {
2159 } else if (fdi
->track_type
< 0x10) {
2161 decode_normal_track
[fdi
->track_type
](fdi
);
2172 // amiga_check_track (fdi);
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);