fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 1022 lines 24 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/utils/pri/main.c * 7 * Created: 2012-01-31 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#include "pri-mac-gcr.h" 25 26#include <stdlib.h> 27#include <stdio.h> 28#include <string.h> 29 30#include <lib/getopt.h> 31#include <lib/sysdep.h> 32 33#include <drivers/psi/psi-img.h> 34#include <drivers/psi/psi.h> 35 36#include <drivers/pri/pri.h> 37#include <drivers/pri/pri-img.h> 38#include <drivers/pri/pri-enc-fm.h> 39#include <drivers/pri/pri-enc-mfm.h> 40 41 42const char *arg0 = NULL; 43 44int par_verbose = 0; 45 46int par_list = 0; 47int par_list_long = 0; 48int par_print_info = 0; 49 50unsigned par_fmt_inp = PRI_FORMAT_NONE; 51unsigned par_fmt_out = PRI_FORMAT_NONE; 52 53char par_invert = 0; 54 55char par_cyl_all = 1; 56unsigned long par_cyl[2]; 57 58char par_trk_all = 1; 59unsigned long par_trk[2]; 60 61unsigned long par_data_rate = 500000; 62unsigned long par_track_size = 0; 63 64pri_enc_fm_t par_enc_fm; 65 66pri_dec_mfm_t par_dec_mfm; 67pri_enc_mfm_t par_enc_mfm; 68 69unsigned par_mac_align = 0; 70char par_mac_no_slip = 0; 71char par_psi_dec_pos = 0; 72char par_text_align = 1; 73 74 75static pce_option_t opts[] = { 76 { '?', 0, "help", NULL, "Print usage information" }, 77 { 'c', 1, "cylinder", "c", "Select cylinders [all]" }, 78 { 'e', 2, "edit", "what val", "Edit image and track attributes" }, 79 { 'f', 0, "info", NULL, "Print image information [no]" }, 80 { 'h', 1, "head", "h", "Select heads [all]" }, 81 { 'i', 1, "input", "filename", "Load an input file" }, 82 { 'I', 1, "input-format", "format", "Set the input format [auto]" }, 83 { 'l', 0, "list-short", NULL, "List tracks (short) [no]" }, 84 { 'L', 0, "list-long", NULL, "List tracks (long) [no]" }, 85 { 'm', 1, "merge", "filename", "Merge an image" }, 86 { 'M', 1, "merge-overwrite", "filename", "Merge an image and overwrite tracks" }, 87 { 'o', 1, "output", "filename", "Set the output file name [none]" }, 88 { 'O', 1, "output-format", "format", "Set the output format [auto]" }, 89 { 'p', 1, "operation", "name [...]", "Perform an operation" }, 90 { 'r', 1, "data-rate", "rate", "Set the data rate [500000]" }, 91 { 's', 2, "set", "par val", "Set a paramter value" }, 92 { 't', 2, "track", "c h", "Select tracks [all]" }, 93 { 'v', 0, "verbose", NULL, "Verbose operation [no]" }, 94 { 'V', 0, "version", NULL, "Print version information" }, 95 { 'x', 0, "invert", NULL, "Invert the selection [no]" }, 96 { 'z', 0, "clear", NULL, "Clear the selection [yes]" }, 97 { -1, 0, NULL, NULL, NULL } 98}; 99 100static struct { 101 const char *name; 102 const char *opts; 103 const char *desc; 104} ops[] = { 105 { "comment-add", "text", "Add to the image comment" }, 106 { "comment-load", "filename", "Load the image comment from a file" }, 107 { "comment-print", "", "Print the image comment" }, 108 { "comment-save", "filename", "Save the image comment to a file" }, 109 { "comment-set", "text", "Set the image comment" }, 110 { "event-add", "type pos val", "Add an event on selected tracks" }, 111 { "event-clear", "", "Clear all events on selected tracks" }, 112 { "event-del", "type [@]range", "Delete events by position or index" }, 113 { "event-list", "type [@]range", "List events by position or index" }, 114 { "decode", "type file", "Decode tracks" }, 115 { "delete", "", "Delete tracks" }, 116 { "double-step", "", "Remove odd numbered tracks" }, 117 { "double-step-even", "", "Remove even numbered tracks" }, 118 { "encode", "type file", "Encode tracks" }, 119 { "half-rate", "", "Half the data rate by removing odd numbered bits" }, 120 { "half-step", "", "Duplicate all tracks" }, 121 { "info", "", "Print image information" }, 122 { "mac-align", "mode", "Align mac tracks" }, 123 { "mfm-align-am", "what number pos", "Align an address mark with pos" }, 124 { "new", "", "Create new tracks" }, 125 { "rotate-angle", "angle", "Rotate tracks by <angle> degrees" }, 126 { "rotate", "bits", "Rotate tracks left" }, 127 { "save", "filename", "Save raw tracks" }, 128 { "weak-clean", "", "Clean up weak bit events" }, 129 { "weak-close", "max", "Fill gaps up to <max> bits between weak bits" }, 130 { "weak-detect", "max", "Autodetect weak bits after <max> zero bits" }, 131 { "weak-expand", "left right", "Expand runs of weak bits" }, 132 { "weak-load", "file", "Load the weak bit mask" }, 133 { "weak-open", "max", "Remove runs of weak bits up to <max> bits long" }, 134 { "weak-save", "file", "Save the weak bit mask" }, 135 { "weak-set", "val", "Set weak bits (0|1|flip|random)" }, 136 { NULL, NULL, NULL } 137}; 138 139 140static 141void print_help_ops (void) 142{ 143 unsigned i, n, w; 144 145 n = 0; 146 147 i = 0; 148 while (ops[i].name != NULL) { 149 w = strlen (ops[i].name) + strlen (ops[i].opts); 150 151 if (w > n) { 152 n = w; 153 } 154 155 i += 1; 156 } 157 158 n += 2; 159 160 i = 0; 161 while (ops[i].name != NULL) { 162 w = strlen (ops[i].name) + strlen (ops[i].opts); 163 164 fprintf (stdout, " %s %s", ops[i].name, ops[i].opts); 165 166 while (w < n) { 167 fputc (' ', stdout); 168 w += 1; 169 } 170 171 fprintf (stdout, "%s\n", ops[i].desc); 172 173 i += 1; 174 } 175} 176 177static 178void print_help (void) 179{ 180 pce_getopt_help ( 181 "pri: convert and modify PCE raw image files", 182 "usage: pri [options] [input] [options] [output]", 183 opts 184 ); 185 186 fputs ("\noperations are:\n", stdout); 187 188 print_help_ops(); 189 190 fputs ( 191 "\n" 192 "parameters are:\n" 193 " fm-auto-gap3, fm-clock, fm-iam, fm-gap1, fm-gap3," 194 " fm-gap4a, fm-track-size,\n" 195 " mac-align, mac-no-slip,\n" 196 " mfm-auto-gap3, mfm-clock, mfm-iam, mfm-gap1, mfm-gap3," 197 " mfm-gap4a,\n" 198 " mfm-min-size, mfm-nopos, mfm-track-size\n" 199 " psi-pos, text-align\n" 200 "\n" 201 "decode types are:\n" 202 " auto, ibm-fm, ibm-mfm, mac-gcr,\n" 203 " text, text-fm, text-mfm, text-mac, text-raw\n" 204 "\n" 205 "encode types are:\n" 206 " auto, text, mac-gcr\n" 207 " ibm-fm, ibm-fm-sd-300,\n" 208 " ibm-mfm, ibm-mfm-dd-300, ibm-mfm-hd-300, ibm-mfm-hd-360\n" 209 "\n" 210 "file formats are:\n" 211 " pri, tc, woz, moof\n" 212 "\n" 213 "image attributes are:\n" 214 " readonly, woz-cleaned, woz-track-sync\n" 215 "\n" 216 "track attributes are:\n" 217 " clock, data, size\n", 218 stdout 219 ); 220 221 fflush (stdout); 222} 223 224static 225void print_version (void) 226{ 227 fputs ( 228 "pri version " PCE_VERSION_STR 229 "\n\n" 230 "Copyright (C) 2012-" PCE_YEAR " Hampa Hug <hampa@hampa.ch>\n", 231 stdout 232 ); 233 234 fflush (stdout); 235} 236 237 238int strcmp2 (const char *str, const char *str1, const char *str2) 239{ 240 if (strcmp (str, str1) == 0) { 241 return (0); 242 } 243 244 if (strcmp (str, str2) == 0) { 245 return (0); 246 } 247 248 return (1); 249} 250 251int pri_parse_range (const char *str, unsigned long *v1, unsigned long *v2, char *all) 252{ 253 *v1 = 0; 254 *v2 = 0; 255 *all = 0; 256 257 if (strcmp (str, "all") == 0) { 258 *all = 1; 259 return (0); 260 } 261 262 while ((*str >= '0') && (*str <= '9')) { 263 *v1 = 10 * *v1 + (*str - '0'); 264 str += 1; 265 } 266 267 if (*str == '-') { 268 str += 1; 269 270 if (*str == 0) { 271 *v2 = ~(unsigned long) 0; 272 return (0); 273 } 274 275 while ((*str >= '0') && (*str <= '9')) { 276 *v2 = 10 * *v2 + (*str - '0'); 277 str += 1; 278 } 279 } 280 else { 281 *v2 = *v1; 282 } 283 284 if (*str != 0) { 285 return (1); 286 } 287 288 return (0); 289} 290 291 292static 293int pri_sel_match_track (unsigned c, unsigned h) 294{ 295 if (!par_cyl_all && ((c < par_cyl[0]) || (c > par_cyl[1]))) { 296 return (par_invert); 297 } 298 299 if (!par_trk_all && ((h < par_trk[0]) || (h > par_trk[1]))) { 300 return (par_invert); 301 } 302 303 return (!par_invert); 304} 305 306int pri_for_all_tracks (pri_img_t *img, pri_trk_cb fct, void *opaque) 307{ 308 unsigned long c, h; 309 pri_cyl_t *cyl; 310 pri_trk_t *trk; 311 312 for (c = 0; c < img->cyl_cnt; c++) { 313 cyl = img->cyl[c]; 314 315 if (cyl == NULL) { 316 continue; 317 } 318 319 for (h = 0; h < cyl->trk_cnt; h++) { 320 trk = cyl->trk[h]; 321 322 if (trk == NULL) { 323 continue; 324 } 325 326 if (pri_sel_match_track (c, h) == 0) { 327 continue; 328 } 329 330 if (fct (img, trk, c, h, opaque)) { 331 return (1); 332 } 333 } 334 } 335 336 return (0); 337} 338 339 340static 341int pri_operation (pri_img_t **img, const char *op, int argc, char **argv) 342{ 343 int r; 344 char **optarg1, **optarg2, **optarg3; 345 346 if (*img == NULL) { 347 *img = pri_img_new(); 348 349 if (*img == NULL) { 350 return (1); 351 } 352 } 353 354 r = 1; 355 356 if (strcmp (op, "comment-add") == 0) { 357 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 358 return (1); 359 } 360 361 r = pri_comment_add (*img, optarg1[0]); 362 } 363 else if (strcmp (op, "comment-load") == 0) { 364 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 365 return (1); 366 } 367 368 r = pri_comment_load (*img, optarg1[0]); 369 } 370 else if (strcmp (op, "comment-print") == 0) { 371 r = pri_comment_show (*img); 372 } 373 else if (strcmp (op, "comment-save") == 0) { 374 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 375 return (1); 376 } 377 378 r = pri_comment_save (*img, optarg1[0]); 379 } 380 else if (strcmp (op, "comment-set") == 0) { 381 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 382 return (1); 383 } 384 385 r = pri_comment_set (*img, optarg1[0]); 386 } 387 else if (strcmp (op, "decode") == 0) { 388 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 389 fprintf (stderr, "%s: missing decode type\n", arg0); 390 return (1); 391 } 392 393 if (pce_getopt (argc, argv, &optarg2, NULL) != 0) { 394 fprintf (stderr, "%s: missing file name\n", arg0); 395 return (1); 396 } 397 398 r = pri_decode (*img, optarg1[0], optarg2[0]); 399 } 400 else if (strcmp (op, "delete") == 0) { 401 r = pri_delete_tracks (*img); 402 } 403 else if (strcmp (op, "double-step") == 0) { 404 r = pri_double_step (*img, 1); 405 } 406 else if (strcmp (op, "double-step-even") == 0) { 407 r = pri_double_step (*img, 0); 408 } 409 else if (strcmp (op, "double-step-odd") == 0) { 410 r = pri_double_step (*img, 1); 411 } 412 else if (strcmp (op, "encode") == 0) { 413 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 414 fprintf (stderr, "%s: missing encode type\n", arg0); 415 return (1); 416 } 417 418 if (pce_getopt (argc, argv, &optarg2, NULL) != 0) { 419 fprintf (stderr, "%s: missing file name\n", arg0); 420 return (1); 421 } 422 423 r = pri_encode (img, optarg1[0], optarg2[0]); 424 } 425 else if (strcmp (op, "event-add") == 0) { 426 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 427 fprintf (stderr, "%s: missing event type\n", arg0); 428 return (1); 429 } 430 431 if (pce_getopt (argc, argv, &optarg2, NULL) != 0) { 432 fprintf (stderr, "%s: missing event position\n", arg0); 433 return (1); 434 } 435 436 if (pce_getopt (argc, argv, &optarg3, NULL) != 0) { 437 fprintf (stderr, "%s: missing event value\n", arg0); 438 return (1); 439 } 440 441 r = pri_event_add (*img, optarg1[0], optarg2[0], optarg3[0]); 442 } 443 else if (strcmp (op, "event-clear") == 0) { 444 r = pri_event_clear (*img); 445 } 446 else if (strcmp (op, "event-del") == 0) { 447 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 448 fprintf (stderr, "%s: missing event type\n", arg0); 449 return (1); 450 } 451 452 if (pce_getopt (argc, argv, &optarg2, NULL) != 0) { 453 fprintf (stderr, "%s: missing event range\n", arg0); 454 return (1); 455 } 456 457 r = pri_event_del (*img, optarg1[0], optarg2[0]); 458 } 459 else if (strcmp (op, "event-list") == 0) { 460 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 461 fprintf (stderr, "%s: missing event type\n", arg0); 462 return (1); 463 } 464 465 if (pce_getopt (argc, argv, &optarg2, NULL) != 0) { 466 fprintf (stderr, "%s: missing event range\n", arg0); 467 return (1); 468 } 469 470 r = pri_event_list (*img, optarg1[0], optarg2[0]); 471 } 472 else if (strcmp (op, "mac-align") == 0) { 473 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 474 fprintf (stderr, "%s: missing mode\n", arg0); 475 return (1); 476 } 477 478 r = pri_mac_gcr_align (*img, optarg1[0]); 479 } 480 else if (strcmp (op, "mac-align-index") == 0) { 481 r = pri_mac_gcr_align_index (*img); 482 } 483 else if (strcmp (op, "mac-align-sector") == 0) { 484 r = pri_mac_gcr_align_sector (*img); 485 } 486 else if ((strcmp (op, "weak-clean") == 0)) { 487 r = pri_weak_clean (*img); 488 } 489 else if ((strcmp (op, "weak-close") == 0)) { 490 unsigned cnt; 491 492 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 493 fprintf (stderr, "%s: missing window size\n", arg0); 494 return (1); 495 } 496 497 cnt = strtoul (optarg1[0], NULL, 0); 498 499 r = pri_weak_close (*img, cnt); 500 } 501 else if ((strcmp (op, "weak-detect") == 0)) { 502 unsigned long max; 503 504 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 505 fprintf (stderr, "%s: missing weak bit detection limit\n", arg0); 506 return (1); 507 } 508 509 max = strtoul (optarg1[0], NULL, 0); 510 511 r = pri_weak_detect (*img, max); 512 } 513 else if ((strcmp (op, "weak-expand") == 0)) { 514 unsigned long left, right; 515 516 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 517 fprintf (stderr, "%s: value\n", arg0); 518 return (1); 519 } 520 521 left = strtoul (optarg1[0], NULL, 0); 522 523 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 524 fprintf (stderr, "%s: value\n", arg0); 525 return (1); 526 } 527 528 right = strtoul (optarg1[0], NULL, 0); 529 530 r = pri_weak_expand (*img, left, right); 531 } 532 else if (strcmp (op, "weak-load") == 0) { 533 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 534 fprintf (stderr, "%s: missing file name\n", arg0); 535 return (1); 536 } 537 538 r = pri_weak_load (*img, optarg1[0]); 539 } 540 else if (strcmp (op, "weak-open") == 0) { 541 unsigned cnt; 542 543 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 544 fprintf (stderr, "%s: missing window size\n", arg0); 545 return (1); 546 } 547 548 cnt = strtoul (optarg1[0], NULL, 0); 549 550 r = pri_weak_open (*img, cnt); 551 } 552 else if (strcmp (op, "weak-save") == 0) { 553 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 554 fprintf (stderr, "%s: missing file name\n", arg0); 555 return (1); 556 } 557 558 r = pri_weak_save (*img, optarg1[0]); 559 } 560 else if (strcmp (op, "weak-set") == 0) { 561 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 562 fprintf (stderr, "%s: missing weak bit value\n", arg0); 563 return (1); 564 } 565 566 if (strcmp (optarg1[0], "random") == 0) { 567 r = pri_weak_flip (*img, 1); 568 } 569 else if (strcmp (optarg1[0], "flip") == 0) { 570 r = pri_weak_flip (*img, 0); 571 } 572 else if (strcmp (optarg1[0], "0") == 0) { 573 r = pri_weak_set (*img, 0); 574 } 575 else if (strcmp (optarg1[0], "1") == 0) { 576 r = pri_weak_set (*img, 1); 577 } 578 else { 579 fprintf (stderr, "%s: unknown weak bit value (%s)\n", 580 arg0, optarg1[0] 581 ); 582 return (1); 583 } 584 } 585 else if (strcmp (op, "half-rate") == 0) { 586 r = pri_half_rate (*img); 587 } 588 else if (strcmp (op, "half-step") == 0) { 589 r = pri_half_step (*img); 590 } 591 else if (strcmp (op, "info") == 0) { 592 r = pri_print_info (*img); 593 } 594 else if (strcmp (op, "mfm-align-am") == 0) { 595 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 596 fprintf (stderr, "%s: missing address mark type\n", arg0); 597 return (1); 598 } 599 600 if (pce_getopt (argc, argv, &optarg2, NULL) != 0) { 601 fprintf (stderr, "%s: missing address mark number\n", arg0); 602 return (1); 603 } 604 605 if (pce_getopt (argc, argv, &optarg3, NULL) != 0) { 606 fprintf (stderr, "%s: missing position\n", arg0); 607 return (1); 608 } 609 610 r = pri_mfm_align_am (*img, optarg1[0], optarg2[0], optarg3[0]); 611 } 612 else if (strcmp (op, "new") == 0) { 613 r = pri_new (*img); 614 } 615 else if (strcmp (op, "rotate-angle") == 0) { 616 double val; 617 618 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 619 fprintf (stderr, "%s: missing angle\n", arg0); 620 return (1); 621 } 622 623 val = strtod (optarg1[0], NULL); 624 625 r = pri_rotate_tracks_angle (*img, val); 626 } 627 else if (strcmp (op, "rotate") == 0) { 628 long ofs; 629 630 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 631 fprintf (stderr, "%s: missing start position\n", arg0); 632 return (1); 633 } 634 635 ofs = strtol (optarg1[0], NULL, 0); 636 637 r = pri_rotate_tracks (*img, ofs); 638 } 639 else if (strcmp (op, "save") == 0) { 640 if (pce_getopt (argc, argv, &optarg1, NULL) != 0) { 641 fprintf (stderr, "%s: missing file name\n", arg0); 642 return (1); 643 } 644 645 r = pri_decode_raw (*img, optarg1[0]); 646 } 647 else { 648 fprintf (stderr, "%s: unknown operation (%s)\n", arg0, op); 649 return (1); 650 } 651 652 if (r) { 653 fprintf (stderr, "%s: operation failed (%s)\n", arg0, op); 654 } 655 656 return (r); 657} 658 659 660static 661pri_img_t *pri_load_image (const char *fname) 662{ 663 pri_img_t *img; 664 665 if (par_verbose) { 666 fprintf (stderr, "%s: loading image from %s\n", arg0, fname); 667 } 668 669 if (strcmp (fname, "-") == 0) { 670 img = pri_img_load_fp (stdin, par_fmt_inp); 671 } 672 else { 673 img = pri_img_load (fname, par_fmt_inp); 674 } 675 676 if (img == NULL) { 677 fprintf (stderr, "%s: loading failed (%s)\n", arg0, fname); 678 return (NULL); 679 } 680 681 if (par_list) { 682 par_list = 0; 683 pri_list_tracks (img); 684 } 685 686 if (par_print_info) { 687 par_print_info = 0; 688 pri_print_info (img); 689 } 690 691 return (img); 692} 693 694static 695int pri_save_image (const char *fname, pri_img_t **img) 696{ 697 int r; 698 699 if (*img == NULL) { 700 *img = pri_img_new(); 701 } 702 703 if (*img == NULL) { 704 return (1); 705 } 706 707 if (par_verbose) { 708 fprintf (stderr, "%s: save image to %s\n", arg0, fname); 709 } 710 711 if (strcmp (fname, "-") == 0) { 712 r = pri_img_save_fp (stdout, *img, par_fmt_out); 713 } 714 else { 715 r = pri_img_save (fname, *img, par_fmt_out); 716 } 717 718 if (r) { 719 fprintf (stderr, "%s: saving failed (%s)\n", 720 arg0, fname 721 ); 722 723 return (1); 724 } 725 726 return (0); 727} 728 729static 730int pri_set_parameter (const char *name, const char *val) 731{ 732 if (strcmp (name, "mac-no-slip") == 0) { 733 par_mac_no_slip = (strtoul (val, NULL, 0) != 0); 734 } 735 else if (strcmp (name, "mfm-auto-gap3") == 0) { 736 par_enc_mfm.auto_gap3 = (strtoul (val, NULL, 0) != 0); 737 } 738 else if (strcmp (name, "mfm-clock") == 0) { 739 par_enc_mfm.clock = strtoul (val, NULL, 0); 740 } 741 else if (strcmp (name, "mfm-iam") == 0) { 742 par_enc_mfm.enable_iam = (strtoul (val, NULL, 0) != 0); 743 } 744 else if (strcmp (name, "mfm-gap1") == 0) { 745 par_enc_mfm.gap1 = strtoul (val, NULL, 0); 746 } 747 else if (strcmp (name, "mfm-gap3") == 0) { 748 par_enc_mfm.gap3 = strtoul (val, NULL, 0); 749 } 750 else if (strcmp (name, "mfm-gap4a") == 0) { 751 par_enc_mfm.gap4a = strtoul (val, NULL, 0); 752 } 753 else if (strcmp (name, "mfm-min-size") == 0) { 754 par_dec_mfm.min_sct_size = strtoul (val, NULL, 0); 755 } 756 else if (strcmp (name, "mfm-nopos") == 0) { 757 par_enc_mfm.nopos = (strtoul (val, NULL, 0) != 0); 758 } 759 else if (strcmp (name, "mfm-track-size") == 0) { 760 par_enc_mfm.track_size = strtoul (val, NULL, 0); 761 } 762 else if (strcmp (name, "fm-auto-gap3") == 0) { 763 par_enc_fm.auto_gap3 = (strtoul (val, NULL, 0) != 0); 764 } 765 else if (strcmp (name, "fm-clock") == 0) { 766 par_enc_fm.clock = strtoul (val, NULL, 0); 767 } 768 else if (strcmp (name, "fm-iam") == 0) { 769 par_enc_fm.enable_iam = (strtoul (val, NULL, 0) != 0); 770 } 771 else if (strcmp (name, "fm-gap1") == 0) { 772 par_enc_fm.gap1 = strtoul (val, NULL, 0); 773 } 774 else if (strcmp (name, "fm-gap3") == 0) { 775 par_enc_fm.gap3 = strtoul (val, NULL, 0); 776 } 777 else if (strcmp (name, "fm-gap4a") == 0) { 778 par_enc_fm.gap4a = strtoul (val, NULL, 0); 779 } 780 else if (strcmp (name, "fm-track-size") == 0) { 781 par_enc_fm.track_size = strtoul (val, NULL, 0); 782 } 783 else if (strcmp (name, "mac-align") == 0) { 784 if (pri_mac_align_mode (val, &par_mac_align)) { 785 fprintf (stderr, "%s: unknown mode (%s)\n", arg0, val); 786 return (1); 787 } 788 } 789 else if (strcmp (name, "psi-pos") == 0) { 790 par_psi_dec_pos = (strtoul (val, NULL, 0) != 0); 791 } 792 else if (strcmp (name, "text-align") == 0) { 793 par_text_align = (strtoul (val, NULL, 0) != 0); 794 } 795 else if (strcmp (name, "track-size") == 0) { 796 par_track_size = strtoul (val, NULL, 0); 797 } 798 else { 799 fprintf (stderr, "%s: unknown parameter (%s)\n", arg0, name); 800 return (1); 801 } 802 803 return (0); 804} 805 806static 807int pri_set_format (const char *name, unsigned *val) 808{ 809 if (strcmp (name, "pbit") == 0) { 810 *val = PRI_FORMAT_PBIT; 811 } 812 else if (strcmp (name, "pri") == 0) { 813 *val = PRI_FORMAT_PRI; 814 } 815 else if (strcmp (name, "tc") == 0) { 816 *val = PRI_FORMAT_TC; 817 } 818 else if (strcmp (name, "woz") == 0) { 819 *val = PRI_FORMAT_WOZ; 820 } 821 else if (strcmp (name, "moof") == 0) { 822 *val = PRI_FORMAT_MOOF; 823 } 824 else { 825 fprintf (stderr, "%s: unknown format (%s)\n", arg0, name); 826 *val = PRI_FORMAT_NONE; 827 return (1); 828 } 829 830 return (0); 831} 832 833int main (int argc, char **argv) 834{ 835 int r; 836 char **optarg; 837 pri_img_t *img; 838 839 arg0 = argv[0]; 840 841 img = NULL; 842 843 pri_encode_fm_init (&par_enc_fm, 250000, 300); 844 845 pri_decode_mfm_init (&par_dec_mfm); 846 pri_encode_mfm_init (&par_enc_mfm, 500000, 300); 847 848 pce_srand (0); 849 850 while (1) { 851 r = pce_getopt (argc, argv, &optarg, opts); 852 853 if (r == GETOPT_DONE) { 854 break; 855 } 856 857 if (r < 0) { 858 return (1); 859 } 860 861 switch (r) { 862 case '?': 863 print_help(); 864 return (0); 865 866 case 'V': 867 print_version(); 868 return (0); 869 870 case 'c': 871 if (pri_parse_range (optarg[0], &par_cyl[0], &par_cyl[1], &par_cyl_all)) { 872 return (1); 873 } 874 break; 875 876 case 'e': 877 if (img != NULL) { 878 if (pri_edit (img, optarg[0], optarg[1])) { 879 return (1); 880 } 881 } 882 break; 883 884 case 'f': 885 if (img != NULL) { 886 pri_print_info (img); 887 } 888 else { 889 par_print_info = 1; 890 } 891 break; 892 893 case 'h': 894 if (pri_parse_range (optarg[0], &par_trk[0], &par_trk[1], &par_trk_all)) { 895 return (1); 896 } 897 break; 898 899 case 'i': 900 if (img != NULL) { 901 pri_img_del (img); 902 } 903 904 img = pri_load_image (optarg[0]); 905 906 if (img == NULL) { 907 return (1); 908 } 909 break; 910 911 case 'I': 912 if (pri_set_format (optarg[0], &par_fmt_inp)) { 913 return (1); 914 } 915 break; 916 917 case 'l': 918 case 'L': 919 par_list_long = (r == 'L'); 920 if (img != NULL) { 921 pri_list_tracks (img); 922 } 923 else { 924 par_list = 1; 925 } 926 break; 927 928 case 'm': 929 case 'M': 930 if (img != NULL) { 931 if (pri_merge_image (img, optarg[0], r == 'M')) { 932 fprintf (stderr, "%s: merge failed\n", arg0); 933 return (1); 934 } 935 } 936 else { 937 img = pri_load_image (optarg[0]); 938 939 if (img == NULL) { 940 fprintf (stderr, "%s: merge failed\n", arg0); 941 return (1); 942 } 943 } 944 break; 945 946 case 'o': 947 if (pri_save_image (optarg[0], &img)) { 948 return (1); 949 } 950 break; 951 952 case 'O': 953 if (pri_set_format (optarg[0], &par_fmt_out)) { 954 return (1); 955 } 956 break; 957 958 case 'p': 959 if (pri_operation (&img, optarg[0], argc, argv)) { 960 return (1); 961 } 962 break; 963 964 case 'r': 965 par_data_rate = strtoul (optarg[0], NULL, 0); 966 967 if (par_data_rate <= 1000) { 968 par_data_rate *= 1000; 969 } 970 break; 971 972 case 's': 973 if (pri_set_parameter (optarg[0], optarg[1])) { 974 return (1); 975 } 976 break; 977 978 case 't': 979 if (pri_parse_range (optarg[0], &par_cyl[0], &par_cyl[1], &par_cyl_all)) { 980 return (1); 981 } 982 if (pri_parse_range (optarg[1], &par_trk[0], &par_trk[1], &par_trk_all)) { 983 return (1); 984 } 985 break; 986 987 case 'v': 988 par_verbose = 1; 989 break; 990 991 case 'x': 992 par_invert = !par_invert; 993 break; 994 995 case 'z': 996 par_invert = 0; 997 par_cyl_all = 1; 998 par_trk_all = 1; 999 break; 1000 1001 case 0: 1002 if (img == NULL) { 1003 img = pri_load_image (optarg[0]); 1004 1005 if (img == NULL) { 1006 return (1); 1007 } 1008 } 1009 else { 1010 if (pri_save_image (optarg[0], &img)) { 1011 return (1); 1012 } 1013 } 1014 break; 1015 1016 default: 1017 return (1); 1018 } 1019 } 1020 1021 return (0); 1022}