fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/utils/pfi/decode.c *
7 * Created: 2012-01-20 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2012-2025 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include "main.h"
24
25#include <stdlib.h>
26#include <stdio.h>
27#include <string.h>
28
29#include <drivers/pfi/pfi.h>
30#include <drivers/pfi/decode-bits.h>
31
32#include <drivers/pri/pri.h>
33#include <drivers/pri/pri-img.h>
34
35
36#define MODE_NONE 0
37#define MODE_MAC_DD_490 1
38#define MODE_MAC_DD_500 2
39
40
41struct decode_bits_s {
42 const char *type;
43 FILE *fp;
44 unsigned long rate;
45};
46
47
48struct decode_pri_s {
49 pri_img_t *img;
50 unsigned long default_rate;
51 unsigned revolution;
52
53 unsigned rate_cnt;
54 unsigned long *rate;
55
56 unsigned fold_mode;
57 unsigned fold_window;
58 unsigned long max_compare;
59};
60
61
62static
63int pfi_decode_bits_raw (FILE *fp, const unsigned char *buf, unsigned long cnt)
64{
65 if (fwrite (buf, (cnt + 7) / 8, 1, fp) != 1) {
66 return (1);
67 }
68
69 return (0);
70}
71
72static
73int pfi_decode_bits_mfm (FILE *fp, const unsigned char *buf, unsigned long cnt)
74{
75 unsigned msk;
76 unsigned outbuf, outcnt;
77 unsigned val, clk;
78
79 msk = 0x80;
80
81 val = 0;
82 clk = 0xffff;
83
84 outbuf = 0;
85 outcnt = 0;
86
87 while (cnt > 0) {
88 val = (val << 1) | ((*buf & msk) != 0);
89 clk = (clk << 1) | ((clk ^ 1) & 1);
90
91 if ((val & 0xffff) == 0x4489) {
92 if (outcnt > 0) {
93 fputc (outbuf << (8 - outcnt), fp);
94 outbuf = 0;
95 outcnt = 0;
96 }
97
98 clk = 0xaaaa;
99 }
100
101 if ((clk & 0x8000) == 0) {
102 outbuf = (outbuf << 1) | ((val & 0x8000) != 0);
103 outcnt += 1;
104
105 if (outcnt >= 8) {
106 fputc (outbuf, fp);
107 outbuf = 0;
108 outcnt = 0;
109 }
110 }
111
112 msk >>= 1;
113
114 if (msk == 0) {
115 msk = 0x80;
116 buf += 1;
117 }
118
119 cnt -= 1;
120 }
121
122 return (0);
123}
124
125static
126int pfi_decode_bits_gcr (FILE *fp, const unsigned char *buf, unsigned long cnt)
127{
128 unsigned val, msk;
129
130 msk = 0x80;
131 val = 0;
132
133 while (cnt > 0) {
134 val = (val << 1) | ((*buf & msk) != 0);
135
136 if (val & 0x80) {
137 fputc (val, fp);
138 val = 0;
139 }
140
141 msk >>= 1;
142
143 if (msk == 0) {
144 msk = 0x80;
145 buf += 1;
146 }
147
148 cnt -= 1;
149 }
150
151 return (0);
152}
153
154static
155int pfi_decode_bits_cb (pfi_img_t *img, pfi_trk_t *trk, unsigned long c, unsigned long h, void *opaque)
156{
157 int r;
158 struct decode_bits_s *par;
159 pfi_dec_t bit;
160
161 par = opaque;
162
163 pfi_dec_init (&bit, 0);
164
165 if (pfi_trk_decode_bits (trk, &bit, par->rate, par_revolution)) {
166 pfi_dec_free (&bit);
167 return (1);
168 }
169
170 if (strcmp (par->type, "raw") == 0) {
171 r = pfi_decode_bits_raw (par->fp, bit.buf, bit.index);
172 }
173 else if (strcmp (par->type, "gcr-raw") == 0) {
174 r = pfi_decode_bits_gcr (par->fp, bit.buf, bit.index);
175 }
176 else if (strcmp (par->type, "mfm-raw") == 0) {
177 r = pfi_decode_bits_mfm (par->fp, bit.buf, bit.index);
178 }
179 else {
180 r = 1;
181 }
182
183 pfi_dec_free (&bit);
184
185 return (r);
186}
187
188int pfi_decode_bits (pfi_img_t *img, const char *type, unsigned long rate, const char *fname)
189{
190 int r;
191 struct decode_bits_s par;
192
193 par.type = type;
194 par.rate = rate;
195 par.fp = fopen (fname, "wb");
196
197 if (par.fp == NULL) {
198 return (1);
199 }
200
201 r = pfi_for_all_tracks (img, pfi_decode_bits_cb, &par);
202
203 fclose (par.fp);
204
205 return (r);
206}
207
208static
209unsigned long pfi_bit_diff (const unsigned char *p1, unsigned long i1, const unsigned char *p2, unsigned long i2, unsigned long cnt)
210{
211 unsigned long i;
212 unsigned j1, j2;
213 unsigned long ret;
214
215 j1 = ~i1 & 7;
216 j2 = ~i2 & 7;
217
218 p1 += i1 / 8;
219 p2 += i2 / 8;
220
221 ret = 0;
222
223 for (i = 0; i < cnt; i++) {
224 ret += ((*p1 >> j1) ^ (*p2 >> j2)) & 1;
225
226 if (j1 == 0) {
227 p1 += 1;
228 j1 = 7;
229 }
230 else {
231 j1 -= 1;
232 }
233
234 if (j2 == 0) {
235 p2 += 1;
236 j2 = 7;
237 }
238 else {
239 j2 -= 1;
240 }
241 }
242
243 return (ret);
244}
245
246static
247int pfi_dec_fold_mindiff (pfi_dec_t *bit, unsigned window, unsigned long max, unsigned c, unsigned h)
248{
249 unsigned i;
250 unsigned long val, pos, cnt;
251 unsigned long min_val, min_pos, min_cnt, dist;
252
253 if ((bit->index < 256) || ((bit->cnt - bit->index) < 256)) {
254 return (0);
255 }
256
257 min_val = 0;
258 min_pos = bit->index;
259 min_cnt = min_pos;
260
261 for (i = 1; i < window; i++) {
262 pos = (i & 1) ? (bit->index - i / 2) : (bit->index + i / 2);
263
264 cnt = bit->cnt - pos;
265
266 if (cnt > pos) {
267 cnt = pos;
268 }
269
270 if (cnt > max) {
271 cnt = max;
272 }
273
274 val = pfi_bit_diff (bit->buf, 0, bit->buf, pos, cnt);
275
276 if ((val < min_val) || (i == 1)) {
277 min_val = val;
278 min_pos = pos;
279 min_cnt = cnt;
280 }
281
282 if (val == 0) {
283 break;
284 }
285 }
286
287 dist = (min_pos < bit->index) ? (bit->index - min_pos) : (min_pos - bit->index);
288
289 if (par_verbose || (min_val > (min_cnt / 16))) {
290 fprintf (stderr, "track %2u/%u: %7.3f%% at %6lu %c %lu\n",
291 c, h,
292 100.0 * (double) min_val / min_cnt,
293 min_pos, (min_pos < bit->index) ? '-' : '+', dist
294 );
295 }
296
297 bit->index = min_pos;
298
299 return (0);
300}
301
302static
303unsigned long pfi_bit_run (const unsigned char *p1, unsigned long i1, const unsigned char *p2, unsigned long i2, unsigned long max)
304{
305 unsigned long i;
306 unsigned j1, j2;
307
308 j1 = ~i1 & 7;
309 j2 = ~i2 & 7;
310
311 p1 += i1 / 8;
312 p2 += i2 / 8;
313
314 for (i = 0; i < max; i++) {
315 if (((*p1 >> j1) ^ (*p2 >> j2)) & 1) {
316 return (i);
317 }
318
319 if (j1 == 0) {
320 p1 += 1;
321 j1 = 7;
322 }
323 else {
324 j1 -= 1;
325 }
326
327 if (j2 == 0) {
328 p2 += 1;
329 j2 = 7;
330 }
331 else {
332 j2 -= 1;
333 }
334 }
335
336 return (max);
337}
338
339static
340int pfi_dec_fold_maxrun (pfi_dec_t *bit, unsigned window, unsigned long max, unsigned c, unsigned h)
341{
342 unsigned i;
343 unsigned long val, pos, cnt;
344 unsigned long max_val, max_pos, dist;
345
346 if ((bit->index < 256) || ((bit->cnt - bit->index) < 256)) {
347 return (0);
348 }
349
350 max_val = 0;
351 max_pos = bit->index;
352
353 for (i = 1; i < window; i++) {
354 pos = (i & 1) ? (bit->index - i / 2) : (bit->index + i / 2);
355
356 cnt = bit->cnt - pos;
357
358 if (cnt > pos) {
359 cnt = pos;
360 }
361
362 if (cnt > max) {
363 cnt = max;
364 }
365
366 val = pfi_bit_run (bit->buf, 0, bit->buf, pos, cnt);
367
368 if ((val > max_val) || (i == 1)) {
369 max_val = val;
370 max_pos = pos;
371 }
372 }
373
374 dist = (max_pos < bit->index) ? (bit->index - max_pos) : (max_pos - bit->index);
375
376 if (par_verbose || (max_val < max)) {
377 fprintf (stderr, "track %2u/%u: %6lu at %6lu (%lu %c %lu)\n",
378 c, h,
379 max_val, max_pos,
380 bit->index, (max_pos < bit->index) ? '-' : '+', dist
381 );
382 }
383
384 bit->index = max_pos;
385
386 return (0);
387}
388
389static
390void pfi_decode_weak (pri_trk_t *trk, pfi_dec_t *bit, unsigned long i1, unsigned long i2)
391{
392 unsigned long i;
393 unsigned long val;
394
395 if ((i1 + i2) >= bit->index) {
396 return;
397 }
398
399 val = 0;
400
401 for (i = i1; i < (bit->index - i2); i++) {
402 val <<= 1;
403
404 if (bit->weak[i >> 3] & (0x80 >> (i & 7))) {
405 val |= 1;
406 }
407
408 if (val & 0x80000000) {
409 pri_trk_evt_add (trk, PRI_EVENT_FUZZY, i - 31, val);
410 val = 0;
411 }
412 }
413}
414
415static
416void pfi_decode_clock (pri_trk_t *trk, pfi_dec_t *bit, unsigned long tolerance)
417{
418 int have_clock;
419 unsigned long i, val;
420 unsigned long clk, clk_min, clk_max;
421 unsigned long cnt_min, cnt_max;
422
423 pfi_dec_clock_median (bit);
424 pfi_dec_clock_average (bit);
425
426 cnt_min = 0;
427 cnt_max = 0;
428
429 clk = trk->clock;
430 clk_min = ((1000 - tolerance) * clk + 500) / 1000;
431 clk_max = ((1000 + tolerance) * clk + 500) / 1000;
432
433 have_clock = 0;
434
435 for (i = 0; i < bit->index; i++) {
436 if (bit->clk[i] < clk_min) {
437 cnt_min += 1;
438 cnt_max = 0;
439 }
440 else if (bit->clk[i] > clk_max) {
441 cnt_min = 0;
442 cnt_max += 1;
443 }
444 else {
445 cnt_min = 0;
446 cnt_max = 0;
447 }
448
449 if ((cnt_min > 255) || (cnt_max > 255)) {
450 unsigned long j, n, v;
451
452 n = (cnt_min > cnt_max) ? cnt_min : cnt_max;
453 v = 0;
454
455 for (j = 0; j < n; j++) {
456 v += bit->clk[i - j];
457 }
458
459 clk = v / n;
460 val = (65536ULL * clk) / trk->clock;
461
462 if ((val > 64880) && (val < 66192)) {
463 clk = trk->clock;
464 val = 0;
465 }
466
467 pri_trk_evt_add (trk, PRI_EVENT_CLOCK, i - n + 1, val);
468
469 clk_min = ((1000 - tolerance) * clk + 500) / 1000;
470 clk_max = ((1000 + tolerance) * clk + 500) / 1000;
471
472 cnt_min = 0;
473 cnt_max = 0;
474
475 have_clock = (val != 0);
476 }
477 }
478
479 if (have_clock) {
480 pri_trk_evt_add (trk, PRI_EVENT_CLOCK, 0, 0);
481 }
482}
483
484static
485int pfi_decode_pri_trk_cb (pfi_img_t *img, pfi_trk_t *strk, unsigned long c, unsigned long h, void *opaque)
486{
487 unsigned long rate;
488 pri_trk_t *dtrk;
489 struct decode_pri_s *par;
490 pfi_dec_t bit;
491
492 par = opaque;
493
494 if ((dtrk = pri_img_get_track (par->img, c, h, 1)) == NULL) {
495 return (1);
496 }
497
498 if (pfi_dec_init (&bit, 0)) {
499 return (1);
500 }
501
502 pfi_trk_rewind (strk);
503
504 if (c < par->rate_cnt) {
505 rate = par->rate[c];
506 }
507 else {
508 rate = par->default_rate;
509 }
510
511 if (pfi_trk_decode_bits (strk, &bit, rate, par->revolution)) {
512 pfi_dec_free (&bit);
513 return (1);
514 }
515
516 switch (par->fold_mode) {
517 case PFI_FOLD_MAXRUN:
518 pfi_dec_fold_maxrun (&bit, par->fold_window, par->max_compare, c, h);
519 break;
520
521 case PFI_FOLD_MINDIFF:
522 pfi_dec_fold_mindiff (&bit, par->fold_window, par->max_compare, c, h);
523 break;
524
525 default:
526 bit.cnt = bit.index;
527 break;
528 }
529
530 pri_trk_set_clock (dtrk, rate);
531 pri_trk_set_size (dtrk, bit.index);
532
533 memcpy (dtrk->data, bit.buf, (bit.index + 7) / 8);
534
535 if (par_weak_bits) {
536 pfi_decode_weak (dtrk, &bit, par_weak_i1, par_weak_i2);
537 }
538
539 if (par_decode_clock) {
540 pfi_decode_clock (dtrk, &bit, par_clock_tolerance);
541 }
542
543 pfi_dec_free (&bit);
544
545 pri_trk_clear_slack (dtrk);
546
547 return (0);
548}
549
550static
551pri_img_t *pfi_decode_pri (pfi_img_t *img, unsigned mode, unsigned long rate)
552{
553 unsigned i;
554 struct decode_pri_s par;
555 unsigned long rate_mac[80];
556
557 static unsigned long rate_mac_490[] = {
558 381132, 349371, 317610, 285849, 254088
559 };
560
561 static unsigned long rate_mac_500[] = {
562 373205, 342104, 311004, 279904, 248803
563
564 };
565
566 if ((par.img = pri_img_new()) == NULL) {
567 return (NULL);
568 }
569
570 par.default_rate = rate;
571 par.revolution = par_revolution;
572
573 if (mode == MODE_MAC_DD_490) {
574 for (i = 0; i < 80; i++) {
575 rate_mac[i] = rate_mac_490[i / 16];
576 }
577
578 par.rate_cnt = 80;
579 par.rate = rate_mac;
580 }
581 else if (mode == MODE_MAC_DD_500) {
582 for (i = 0; i < 80; i++) {
583 rate_mac[i] = rate_mac_500[i / 16];
584 }
585
586 par.rate_cnt = 80;
587 par.rate = rate_mac;
588 }
589 else {
590 par.rate_cnt = 0;
591 par.rate = NULL;
592 }
593
594 par.fold_mode = par_fold_mode;
595 par.fold_window = par_fold_window;
596 par.max_compare = par_fold_max;
597
598 if (pfi_for_all_tracks (img, pfi_decode_pri_trk_cb, &par)) {
599 pri_img_del (par.img);
600 return (NULL);
601 }
602
603 if (img->comment_size > 0) {
604 pri_img_set_comment (par.img, img->comment, img->comment_size);
605 }
606
607 return (par.img);
608}
609
610int pfi_decode_bits_pri (pfi_img_t *img, unsigned mode, unsigned long rate, const char *fname)
611{
612 int r;
613 FILE *fp;
614 pri_img_t *dimg;
615
616 if ((dimg = pfi_decode_pri (img, mode, rate)) == NULL) {
617 return (1);
618 }
619
620 if ((fp = fopen (fname, "wb")) == NULL) {
621 pri_img_del (dimg);
622 return (1);
623 }
624
625 r = pri_img_save_fp (fp, dimg, PRI_FORMAT_PRI);
626
627 fclose (fp);
628
629 pri_img_del (dimg);
630
631 return (r);
632}
633
634
635int pfi_decode (pfi_img_t *img, const char *type, unsigned long rate, const char *fname)
636{
637 if (rate == 0) {
638 rate = 500000;
639 }
640 else if (rate <= 1000) {
641 rate *= 1000;
642 }
643
644 if (strcmp (type, "pri") == 0) {
645 return (pfi_decode_bits_pri (img, MODE_NONE, rate, fname));
646 }
647 else if (strcmp (type, "pri-mac") == 0) {
648 return (pfi_decode_bits_pri (img, MODE_MAC_DD_500, rate, fname));
649 }
650 else if (strcmp (type, "pri-mac-490") == 0) {
651 return (pfi_decode_bits_pri (img, MODE_MAC_DD_490, rate, fname));
652 }
653 else if (strcmp (type, "pri-mac-500") == 0) {
654 return (pfi_decode_bits_pri (img, MODE_MAC_DD_500, rate, fname));
655 }
656 else if (strcmp (type, "mfm-raw") == 0) {
657 return (pfi_decode_bits (img, type, rate, fname));
658 }
659 else if (strcmp (type, "gcr-raw") == 0) {
660 return (pfi_decode_bits (img, type, rate, fname));
661 }
662 else if (strcmp (type, "raw") == 0) {
663 return (pfi_decode_bits (img, type, rate, fname));
664 }
665 else if (strcmp (type, "text") == 0) {
666 return (pfi_decode_text (img, fname));
667 }
668
669 return (1);
670}