fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 466 lines 9.6 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/utils/pti/ops.c * 7 * Created: 2020-04-30 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2020-2024 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 "comment.h" 25#include "ops.h" 26#include "space.h" 27 28#include <stdlib.h> 29#include <stdio.h> 30#include <string.h> 31 32#include <lib/getopt.h> 33 34#include <drivers/pti/pti.h> 35#include <drivers/pti/pti-io.h> 36 37 38static 39int pti_get_opt (int argc, char **argv, char ***optarg, unsigned cnt) 40{ 41 if (pce_getoptarg (argc, argv, optarg, cnt) != 0) { 42 fprintf (stderr, "%s: missing argument\n", arg0); 43 return (1); 44 } 45 46 return (0); 47} 48 49int pti_cat (pti_img_t **img, const char *fname) 50{ 51 unsigned long i; 52 unsigned long clk, rem; 53 int level; 54 pti_img_t *src; 55 56 if ((src = pti_load_image (fname)) == NULL) { 57 return (1); 58 } 59 60 if (*img == NULL) { 61 *img = src; 62 return (0); 63 } 64 65 rem = 0; 66 67 for (i = 0; i < src->pulse_cnt; i++) { 68 pti_pulse_get (src->pulse[i], &clk, &level); 69 70 clk = pti_pulse_convert (clk, (*img)->clock, src->clock, &rem); 71 72 if (pti_img_add_pulse ((*img), clk, level)) { 73 pti_img_del (src); 74 return (1); 75 } 76 } 77 78 pti_img_del (src); 79 80 return (0); 81} 82 83int pti_info (pti_img_t *img) 84{ 85 unsigned msc; 86 unsigned long min, sec, clk; 87 88 pti_img_get_length (img, &sec, &clk); 89 90 min = sec / 60; 91 sec = sec % 60; 92 msc = (unsigned) ((1000.0 * clk) / img->clock); 93 94 printf ("time: %02lu:%02lu.%03u\n", min, sec, msc); 95 printf ("clock: %lu\n", pti_img_get_clock (img)); 96 printf ("pulses: %lu\n", img->pulse_cnt); 97 98 if (img->comment_size > 0) { 99 fputs ("\n", stdout); 100 pti_comment_show (img); 101 } 102 103 return (0); 104} 105 106int pti_invert (pti_img_t *img) 107{ 108 unsigned long i; 109 unsigned long clk; 110 int level; 111 112 for (i = 0; i < img->pulse_cnt; i++) { 113 pti_pulse_get (img->pulse[i], &clk, &level); 114 pti_pulse_set (&img->pulse[i], clk, -level); 115 } 116 117 return (0); 118} 119 120int pti_new (pti_img_t **img) 121{ 122 pti_img_del (*img); 123 124 if ((*img = pti_img_new()) == NULL) { 125 return (1); 126 } 127 128 pti_img_set_clock (*img, par_default_clock); 129 130 return (0); 131} 132 133int pti_scale (pti_img_t **img, unsigned long dclk, int set) 134{ 135 unsigned long i; 136 unsigned long sclk, rem; 137 unsigned long clk; 138 int level; 139 pti_img_t *dst, *src; 140 141 src = *img; 142 143 if ((dst = pti_img_clone (src, 0)) == NULL) { 144 return (1); 145 } 146 147 sclk = pti_img_get_clock (src); 148 149 rem = 0; 150 151 for (i = 0; i < src->pulse_cnt; i++) { 152 pti_pulse_get (src->pulse[i], &clk, &level); 153 154 clk = pti_pulse_convert (clk, dclk, sclk, &rem); 155 156 if (pti_img_add_pulse (dst, clk, level)) { 157 pti_img_del (src); 158 return (1); 159 } 160 } 161 162 pti_img_del (src); 163 164 if (set) { 165 pti_img_set_clock (dst, dclk); 166 } 167 168 *img = dst; 169 170 return (0); 171} 172 173int pti_trim_left (pti_img_t *img, unsigned long sec, unsigned long clk) 174{ 175 unsigned long i, j; 176 unsigned long sec2, clk2; 177 int level; 178 179 for (i = 0; i < img->pulse_cnt; i++) { 180 pti_pulse_get (img->pulse[i], &clk2, &level); 181 182 sec2 = clk2 / img->clock; 183 clk2 = clk2 % img->clock; 184 185 if ((sec2 > sec) || ((sec2 == sec) && (clk2 > clk))) { 186 break; 187 } 188 189 if (clk2 > clk) { 190 sec -= 1; 191 clk += img->clock; 192 } 193 194 clk -= clk2; 195 sec -= sec2; 196 } 197 198 if (i >= img->pulse_cnt) { 199 img->pulse_cnt = 0; 200 return (0); 201 } 202 203 if (clk > clk2) { 204 sec2 -= 1; 205 clk2 += img->clock; 206 } 207 208 clk2 -= clk; 209 sec2 -= sec; 210 211 clk2 += img->clock * sec2; 212 213 pti_pulse_set (img->pulse + i, clk2, level); 214 215 j = 0; 216 while (i < img->pulse_cnt) { 217 img->pulse[j++] = img->pulse[i++]; 218 } 219 220 img->pulse_cnt = j; 221 222 return (0); 223} 224 225int pti_trim_right (pti_img_t *img, unsigned long sec, unsigned long clk) 226{ 227 unsigned long idx; 228 229 pti_img_get_index (img, &idx, sec, clk); 230 231 if (idx < img->pulse_cnt) { 232 img->pulse_cnt = idx; 233 } 234 235 return (0); 236} 237 238int pti_operation (pti_img_t **img, const char *op, int argc, char **argv) 239{ 240 int r; 241 char **optarg; 242 243 if (*img == NULL) { 244 if ((*img = pti_img_new()) == NULL) { 245 return (1); 246 } 247 248 pti_img_set_clock (*img, par_default_clock); 249 } 250 251 r = 1; 252 253 if (strcmp (op, "cat") == 0) { 254 if (pti_get_opt (argc, argv, &optarg, 1)) { 255 return (1); 256 } 257 258 r = pti_cat (img, optarg[0]); 259 } 260 else if (strcmp (op, "comment-add") == 0) { 261 if (pti_get_opt (argc, argv, &optarg, 1)) { 262 return (1); 263 } 264 265 r = pti_comment_add (*img, optarg[0]); 266 } 267 else if (strcmp (op, "comment-load") == 0) { 268 if (pti_get_opt (argc, argv, &optarg, 1)) { 269 return (1); 270 } 271 272 r = pti_comment_load (*img, optarg[0]); 273 } 274 else if (strcmp (op, "comment-print") == 0) { 275 r = pti_comment_show (*img); 276 } 277 else if (strcmp (op, "comment-save") == 0) { 278 if (pti_get_opt (argc, argv, &optarg, 1)) { 279 return (1); 280 } 281 282 r = pti_comment_save (*img, optarg[0]); 283 } 284 else if (strcmp (op, "comment-set") == 0) { 285 if (pti_get_opt (argc, argv, &optarg, 1)) { 286 return (1); 287 } 288 289 r = pti_comment_set (*img, optarg[0]); 290 } 291 else if (strcmp (op, "fix-clock") == 0) { 292 unsigned long clk; 293 294 if (pti_get_opt (argc, argv, &optarg, 1)) { 295 return (1); 296 } 297 298 if (pti_parse_freq (optarg[0], &clk)) { 299 return (1); 300 } 301 302 pti_img_set_clock (*img, clk); 303 304 r = 0; 305 } 306 else if (strcmp (op, "info") == 0) { 307 r = pti_info (*img); 308 } 309 else if (strcmp (op, "invert") == 0) { 310 r = pti_invert (*img); 311 } 312 else if (strcmp (op, "new") == 0) { 313 r = pti_new (img); 314 } 315 else if (strcmp (op, "save-inverted") == 0) { 316 int val; 317 318 if (pti_get_opt (argc, argv, &optarg, 1)) { 319 return (1); 320 } 321 322 if (pti_parse_bool (optarg[0], &val)) { 323 return (1); 324 } 325 326 pti_img_set_inverted (*img, val); 327 328 r = 0; 329 } 330 else if (strcmp (op, "scale") == 0) { 331 double fct; 332 333 if (pti_get_opt (argc, argv, &optarg, 1)) { 334 return (1); 335 } 336 337 if (pti_parse_double (optarg[0], &fct)) { 338 return (1); 339 } 340 341 r = pti_scale (img, (unsigned long) (fct * (*img)->clock), 0); 342 } 343 else if (strcmp (op, "set-clock") == 0) { 344 unsigned long clk; 345 346 if (pti_get_opt (argc, argv, &optarg, 1)) { 347 return (1); 348 } 349 350 if (pti_parse_freq (optarg[0], &clk)) { 351 return (1); 352 } 353 354 r = pti_scale (img, clk, 1); 355 } 356 else if (strcmp (op, "space-add-left") == 0) { 357 unsigned long sec, clk; 358 359 if (pti_get_opt (argc, argv, &optarg, 1)) { 360 return (1); 361 } 362 363 if (pti_parse_time_clk (optarg[0], &sec, &clk, (*img)->clock)) { 364 return (1); 365 } 366 367 r = pti_space_add_left (*img, (*img)->clock * sec + clk); 368 } 369 else if ((strcmp (op, "space-add-right") == 0) || (strcmp (op, "space") == 0)) { 370 unsigned long sec, clk; 371 372 if (pti_get_opt (argc, argv, &optarg, 1)) { 373 return (1); 374 } 375 376 if (pti_parse_time_clk (optarg[0], &sec, &clk, (*img)->clock)) { 377 return (1); 378 } 379 380 r = pti_space_add_right (*img, (*img)->clock * sec + clk); 381 } 382 else if (strcmp (op, "space-add") == 0) { 383 unsigned long sec, clk; 384 385 if (pti_get_opt (argc, argv, &optarg, 1)) { 386 return (1); 387 } 388 389 if (pti_parse_time_clk (optarg[0], &sec, &clk, (*img)->clock)) { 390 return (1); 391 } 392 393 r = pti_space_add (*img, (*img)->clock * sec + clk); 394 } 395 else if (strcmp (op, "space-auto") == 0) { 396 unsigned long sec, clk; 397 398 if (pti_get_opt (argc, argv, &optarg, 1)) { 399 return (1); 400 } 401 402 if (pti_parse_time_clk (optarg[0], &sec, &clk, (*img)->clock)) { 403 return (1); 404 } 405 406 r = pti_space_auto (*img, (*img)->clock * sec + clk); 407 } 408 else if (strcmp (op, "space-max") == 0) { 409 unsigned long sec, clk; 410 411 if (pti_get_opt (argc, argv, &optarg, 1)) { 412 return (1); 413 } 414 415 if (pti_parse_time_clk (optarg[0], &sec, &clk, (*img)->clock)) { 416 return (1); 417 } 418 419 r = pti_space_max (*img, (*img)->clock * sec + clk); 420 } 421 else if (strcmp (op, "space-trim-left") == 0) { 422 r = pti_space_trim_left (*img); 423 } 424 else if (strcmp (op, "space-trim-right") == 0) { 425 r = pti_space_trim_right (*img); 426 } 427 else if (strcmp (op, "space-trim") == 0) { 428 r = pti_space_trim (*img); 429 } 430 else if (strcmp (op, "trim-left") == 0) { 431 unsigned long sec, clk; 432 433 if (pti_get_opt (argc, argv, &optarg, 1)) { 434 return (1); 435 } 436 437 if (pti_parse_time_clk (optarg[0], &sec, &clk, (*img)->clock)) { 438 return (1); 439 } 440 441 r = pti_trim_left (*img, sec, clk); 442 } 443 else if (strcmp (op, "trim-right") == 0) { 444 unsigned long sec, clk; 445 446 if (pti_get_opt (argc, argv, &optarg, 1)) { 447 return (1); 448 } 449 450 if (pti_parse_time_clk (optarg[0], &sec, &clk, (*img)->clock)) { 451 return (1); 452 } 453 454 r = pti_trim_right (*img, sec, clk); 455 } 456 else { 457 fprintf (stderr, "%s: unknown operation (%s)\n", arg0, op); 458 return (1); 459 } 460 461 if (r) { 462 fprintf (stderr, "%s: operation failed (%s)\n", arg0, op); 463 } 464 465 return (r); 466}