fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 436 lines 8.7 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/utils/pri/decode.c * 7 * Created: 2013-12-19 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2013-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 <stdio.h> 26#include <string.h> 27 28#include <drivers/psi/psi-img.h> 29#include <drivers/psi/psi.h> 30 31#include <drivers/pri/pri.h> 32#include <drivers/pri/pri-img.h> 33#include <drivers/pri/pri-enc-fm.h> 34#include <drivers/pri/pri-enc-gcr.h> 35#include <drivers/pri/pri-enc-mfm.h> 36 37 38struct pri_decode_psi_s { 39 psi_img_t *img; 40 pri_dec_mfm_t mfm; 41}; 42 43 44extern pri_dec_mfm_t par_dec_mfm; 45 46 47static 48int pri_decode_fm_raw_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 49{ 50 FILE *fp; 51 unsigned outbuf, outcnt; 52 unsigned val, clk; 53 unsigned long bit; 54 55 fp = opaque; 56 57 pri_trk_set_pos (trk, 0); 58 59 val = 0; 60 clk = 0xffff; 61 62 outbuf = 0; 63 outcnt = 0; 64 65 while (trk->wrap == 0) { 66 pri_trk_get_bits (trk, &bit, 1); 67 68 val = ((val << 1) | (bit & 1)) & 0xffff; 69 clk = (clk << 1) | (~clk & val & 1); 70 71 if ((val == 0xf57e) || (val == 0xf56f) || (val == 0xf56a)) { 72 clk = 0xaaaa; 73 74 if (outcnt > 0) { 75 outbuf = outbuf << (8 - outcnt); 76 outcnt = 8; 77 } 78 } 79 else if ((clk & 0x8000) == 0) { 80 outbuf = (outbuf << 1) | ((val >> 15) & 1); 81 outcnt += 1; 82 } 83 84 if (outcnt >= 8) { 85 fputc (outbuf & 0xff, fp); 86 outbuf = 0; 87 outcnt = 0; 88 } 89 } 90 91 return (0); 92} 93 94static 95int pri_decode_fm_raw (pri_img_t *img, const char *fname) 96{ 97 int r; 98 FILE *fp; 99 100 if ((fp = fopen (fname, "wb")) == NULL) { 101 return (1); 102 } 103 104 r = pri_for_all_tracks (img, pri_decode_fm_raw_cb, fp); 105 106 fclose (fp); 107 108 return (r); 109} 110 111 112static 113int pri_decode_gcr_raw_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 114{ 115 FILE *fp; 116 unsigned val; 117 unsigned long bit; 118 119 fp = opaque; 120 121 pri_trk_set_pos (trk, 0); 122 123 val = 0; 124 125 while (trk->wrap == 0) { 126 pri_trk_get_bits (trk, &bit, 1); 127 128 val = (val << 1) | (bit & 1); 129 130 if (val & 0x80) { 131 fputc (val, fp); 132 val = 0; 133 } 134 } 135 136 return (0); 137} 138 139static 140int pri_decode_gcr_raw (pri_img_t *img, const char *fname) 141{ 142 int r; 143 FILE *fp; 144 145 fp = fopen (fname, "wb"); 146 147 if (fp == NULL) { 148 return (1); 149 } 150 151 r = pri_for_all_tracks (img, pri_decode_gcr_raw_cb, fp); 152 153 fclose (fp); 154 155 return (r); 156} 157 158 159static 160int pri_decode_mfm_raw_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 161{ 162 FILE *fp; 163 unsigned outbuf, outcnt; 164 unsigned val, clk; 165 unsigned long bit; 166 167 fp = opaque; 168 169 pri_trk_set_pos (trk, 0); 170 171 val = 0; 172 clk = 0; 173 174 outbuf = 0; 175 outcnt = 0; 176 177 while (trk->wrap == 0) { 178 pri_trk_get_bits (trk, &bit, 1); 179 180 val = (val << 1) | (bit & 1); 181 clk = (clk << 1) | (~clk & 1); 182 183 if ((clk & 1) == 0) { 184 outbuf = (outbuf << 1) | (val & 1); 185 outcnt += 1; 186 } 187 188 if ((val & 0xffff) == 0x4489) { 189 outbuf = 0xa1; 190 outcnt = 8; 191 clk = 0; 192 } 193 194 if (outcnt >= 8) { 195 fputc (outbuf & 0xff, fp); 196 outbuf = 0; 197 outcnt = 0; 198 } 199 } 200 201 return (0); 202} 203 204static 205int pri_decode_mfm_raw (pri_img_t *img, const char *fname) 206{ 207 int r; 208 FILE *fp; 209 210 fp = fopen (fname, "wb"); 211 212 if (fp == NULL) { 213 return (1); 214 } 215 216 r = pri_for_all_tracks (img, pri_decode_mfm_raw_cb, fp); 217 218 fclose (fp); 219 220 return (r); 221} 222 223 224static 225int pri_decode_raw_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 226{ 227 FILE *fp; 228 229 fp = opaque; 230 231 if (fwrite (trk->data, (trk->size + 7) / 8, 1, fp) != 1) { 232 return (1); 233 } 234 235 return (0); 236} 237 238int pri_decode_raw (pri_img_t *img, const char *fname) 239{ 240 int r; 241 FILE *fp; 242 243 fp = fopen (fname, "wb"); 244 245 if (fp == NULL) { 246 return (1); 247 } 248 249 r = pri_for_all_tracks (img, pri_decode_raw_cb, fp); 250 251 fclose (fp); 252 253 return (r); 254} 255 256 257static 258int pri_decode_psi_auto_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 259{ 260 psi_trk_t *dtrk; 261 struct pri_decode_psi_s *dec; 262 263 dec = opaque; 264 265 if ((dtrk = pri_decode_mfm_trk (trk, c, h, &dec->mfm)) == NULL) { 266 return (1); 267 } 268 269 if (dtrk->sct_cnt == 0) { 270 psi_trk_del (dtrk); 271 272 if ((dtrk = pri_decode_fm_trk (trk, h)) == NULL) { 273 return (1); 274 } 275 } 276 277 if (dtrk->sct_cnt == 0) { 278 psi_trk_del (dtrk); 279 280 if ((dtrk = pri_decode_gcr_trk (trk, h)) == NULL) { 281 return (1); 282 } 283 } 284 285 if (psi_img_set_track (dec->img, dtrk, c, h)) { 286 psi_trk_del (dtrk); 287 return (1); 288 } 289 290 return (0); 291} 292 293static 294int pri_decode_psi_mfm_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 295{ 296 psi_trk_t *dtrk; 297 struct pri_decode_psi_s *dec; 298 299 dec = opaque; 300 301 if ((dtrk = pri_decode_mfm_trk (trk, c, h, &dec->mfm)) == NULL) { 302 return (1); 303 } 304 305 if (psi_img_set_track (dec->img, dtrk, c, h)) { 306 psi_trk_del (dtrk); 307 return (1); 308 } 309 310 return (0); 311} 312 313static 314int pri_decode_psi_fm_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 315{ 316 psi_trk_t *dtrk; 317 struct pri_decode_psi_s *dec; 318 319 dec = opaque; 320 321 if ((dtrk = pri_decode_fm_trk (trk, h)) == NULL) { 322 return (1); 323 } 324 325 if (psi_img_set_track (dec->img, dtrk, c, h)) { 326 psi_trk_del (dtrk); 327 return (1); 328 } 329 330 return (0); 331} 332 333static 334int pri_decode_psi_gcr_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 335{ 336 psi_trk_t *dtrk; 337 struct pri_decode_psi_s *dec; 338 339 dec = opaque; 340 341 if ((dtrk = pri_decode_gcr_trk (trk, h)) == NULL) { 342 return (1); 343 } 344 345 if (psi_img_set_track (dec->img, dtrk, c, h)) { 346 psi_trk_del (dtrk); 347 return (1); 348 } 349 350 return (0); 351} 352 353static 354int pri_decode_psi (pri_img_t *img, const char *type, const char *fname) 355{ 356 int r; 357 pri_trk_cb fct; 358 struct pri_decode_psi_s dec; 359 360 dec.mfm = par_dec_mfm; 361 362 if (strcmp2 (type, "auto", "mfm-fm") == 0) { 363 fct = pri_decode_psi_auto_cb; 364 } 365 else if (strcmp2 (type, "ibm-fm", "fm") == 0) { 366 fct = pri_decode_psi_fm_cb; 367 } 368 else if (strcmp2 (type, "mac-gcr", "gcr") == 0) { 369 fct = pri_decode_psi_gcr_cb; 370 } 371 else if (strcmp2 (type, "ibm-mfm", "mfm") == 0) { 372 fct = pri_decode_psi_mfm_cb; 373 } 374 else { 375 fprintf (stderr, "%s: unknown decode type (%s)\n", arg0, type); 376 return (1); 377 } 378 379 if ((dec.img = psi_img_new()) == NULL) { 380 return (1); 381 } 382 383 if (pri_for_all_tracks (img, fct, &dec)) { 384 psi_img_del (dec.img); 385 return (1); 386 } 387 388 if (img->comment_size > 0) { 389 psi_img_set_comment (dec.img, img->comment, img->comment_size); 390 } 391 392 if (par_psi_dec_pos == 0) { 393 psi_img_clear_position (dec.img); 394 } 395 396 r = psi_save (fname, dec.img, PSI_FORMAT_NONE); 397 398 psi_img_del (dec.img); 399 400 return (r); 401} 402 403 404int pri_decode (pri_img_t *img, const char *type, const char *fname) 405{ 406 if (strcmp (type, "fm-raw") == 0) { 407 return (pri_decode_fm_raw (img, fname)); 408 } 409 else if (strcmp (type, "gcr-raw") == 0) { 410 return (pri_decode_gcr_raw (img, fname)); 411 } 412 else if (strcmp (type, "mfm-raw") == 0) { 413 return (pri_decode_mfm_raw (img, fname)); 414 } 415 else if (strcmp (type, "text") == 0) { 416 return (pri_decode_text (img, fname, PRI_TEXT_AUTO)); 417 } 418 else if (strcmp (type, "text-fm") == 0) { 419 return (pri_decode_text (img, fname, PRI_TEXT_FM)); 420 } 421 else if (strcmp (type, "text-mac") == 0) { 422 return (pri_decode_text (img, fname, PRI_TEXT_MAC)); 423 } 424 else if (strcmp (type, "text-mfm") == 0) { 425 return (pri_decode_text (img, fname, PRI_TEXT_MFM)); 426 } 427 else if (strcmp (type, "text-raw") == 0) { 428 return (pri_decode_text (img, fname, PRI_TEXT_RAW)); 429 } 430 else if (strcmp (type, "raw") == 0) { 431 return (pri_decode_raw (img, fname)); 432 } 433 else { 434 return (pri_decode_psi (img, type, fname)); 435 } 436}