PageRenderTime 53ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/fdi2raw.cpp

https://github.com/tonioni/WinUAE
C++ | 2205 lines | 1902 code | 166 blank | 137 comment | 348 complexity | b25a4f18fa0d71c8e9c5d50671ad97e1 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

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

Large files files are truncated, but you can click here to view the full file