fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 351 lines 6.4 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/utils/pfi/text.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 <stdio.h> 26#include <string.h> 27 28#include <lib/text.h> 29 30#include <drivers/pfi/pfi.h> 31 32 33typedef struct { 34 pce_text_t txt; 35 pfi_img_t *img; 36 pfi_trk_t *trk; 37 unsigned long version; 38 unsigned long pos; 39 char add; 40} pfi_text_t; 41 42 43static 44int pfi_decode_text_cb (pfi_img_t *img, pfi_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 45{ 46 unsigned col, row, idx; 47 uint32_t val, ofs; 48 unsigned long total, index; 49 FILE *fp; 50 51 fp = opaque; 52 53 fprintf (fp, "TRACK %lu %lu\n", c, h); 54 fprintf (fp, "CLOCK %lu\n\n", pfi_trk_get_clock (trk)); 55 56 pfi_trk_rewind (trk); 57 58 col = 0; 59 row = 0; 60 idx = 0; 61 62 total = 0; 63 index = 0; 64 65 while (pfi_trk_get_pulse (trk, &val, &ofs) == 0) { 66 if ((val == 0) || (ofs < val)) { 67 if (col > 0) { 68 fputc ('\n', fp); 69 col = 0; 70 } 71 72 idx += 1; 73 row = 0; 74 75 if (trk->index_cnt > idx) { 76 fprintf (fp, "\n; Revolution %u", idx); 77 } 78 79 fprintf (fp, "\n; %lu + %lu", total, (unsigned long) ofs); 80 fprintf (fp, "\nINDEX %lu\n\n", (unsigned long) ofs); 81 82 index = total + ofs; 83 } 84 85 if (val > 0) { 86 total += val; 87 88 if (col > 0) { 89 fputc (' ', fp); 90 } 91 92 fprintf (fp, "%3lu", (unsigned long) val); 93 94 if (++col >= 16) { 95 if (++row >= 8) { 96 fprintf (fp, "\t\t; %lu + %lu", 97 index, total - index 98 ); 99 row = 0; 100 } 101 fputc ('\n', fp); 102 col = 0; 103 } 104 } 105 } 106 107 if (col > 0) { 108 fputc ('\n', fp); 109 } 110 111 return (0); 112} 113 114int pfi_decode_text (pfi_img_t *img, const char *fname) 115{ 116 int r; 117 FILE *fp; 118 119 if ((fp = fopen (fname, "w")) == NULL) { 120 return (1); 121 } 122 123 fprintf (fp, "PFI 0\n\n"); 124 125 r = pfi_for_all_tracks (img, pfi_decode_text_cb, fp); 126 127 fclose (fp); 128 129 return (r); 130} 131 132 133static 134int txt_enc_clock (pfi_text_t *ctx) 135{ 136 unsigned long val; 137 138 if (txt_match_uint (&ctx->txt, 10, &val) == 0) { 139 return (1); 140 } 141 142 if (ctx->trk != NULL) { 143 pfi_trk_set_clock (ctx->trk, val); 144 } 145 146 return (0); 147} 148 149static 150int txt_enc_index (pfi_text_t *ctx) 151{ 152 unsigned long val; 153 154 if (txt_match_uint (&ctx->txt, 10, &val) == 0) { 155 return (1); 156 } 157 158 if (ctx->trk == NULL) { 159 return (1); 160 } 161 162 if (pfi_trk_add_index (ctx->trk, ctx->pos + val)) { 163 return (1); 164 } 165 166 return (0); 167} 168 169static 170int txt_enc_text (pfi_text_t *ctx) 171{ 172 unsigned cnt; 173 char str[256]; 174 175 if (txt_match (&ctx->txt, "INIT", 1)) { 176 pfi_img_set_comment (ctx->img, NULL, 0); 177 return (0); 178 } 179 180 if (txt_match_string (&ctx->txt, str, 256) == 0) { 181 return (1); 182 } 183 184 cnt = strlen (str); 185 186 if (cnt < 256) { 187 str[cnt++] = 0x0a; 188 } 189 190 if (pfi_img_add_comment (ctx->img, (unsigned char *) str, cnt)) { 191 return (1); 192 } 193 194 return (0); 195} 196 197static 198int txt_enc_track (pfi_text_t *ctx) 199{ 200 unsigned long c, h; 201 202 if (txt_match_uint (&ctx->txt, 10, &c) == 0) { 203 return (1); 204 } 205 206 if (txt_match_uint (&ctx->txt, 10, &h) == 0) { 207 return (1); 208 } 209 210 pfi_img_del_track (ctx->img, c, h); 211 212 if ((ctx->trk = pfi_img_get_track (ctx->img, c, h, 1)) == NULL) { 213 return (1); 214 } 215 216 ctx->pos = 0; 217 218 return (0); 219} 220 221static 222int txt_enc_pulse (pfi_text_t *ctx, unsigned base) 223{ 224 unsigned long val; 225 226 if (txt_match_uint (&ctx->txt, base, &val) == 0) { 227 return (1); 228 } 229 230 if (ctx->trk == NULL) { 231 return (1); 232 } 233 234 if (ctx->add) { 235 if (pfi_trk_inc_pulse (ctx->trk, val)) { 236 return (1); 237 } 238 } 239 else { 240 if (pfi_trk_add_pulse (ctx->trk, val)) { 241 return (1); 242 } 243 } 244 245 ctx->add = 0; 246 ctx->pos += val; 247 248 return (0); 249} 250 251static 252int txt_encode (pfi_text_t *ctx) 253{ 254 pce_text_t *txt; 255 256 ctx->trk = NULL; 257 ctx->version = 0; 258 ctx->pos = 0; 259 ctx->add = 0; 260 261 txt = &ctx->txt; 262 263 if (txt_match (txt, "PFI", 1)) { 264 if (txt_match_uint (txt, 10, &ctx->version) == 0) { 265 return (1); 266 } 267 } 268 269 while (1) { 270 txt_match_space (txt); 271 272 if (feof (txt->fp)) { 273 return (0); 274 } 275 276 if (txt_match (txt, "CLOCK", 1)) { 277 if (txt_enc_clock (ctx)) { 278 return (1); 279 } 280 } 281 else if (txt_match (txt, "END", 1)) { 282 return (0); 283 } 284 else if (txt_match (txt, "INDEX", 1)) { 285 if (txt_enc_index (ctx)) { 286 return (1); 287 } 288 } 289 else if (txt_match (txt, "PFI", 1)) { 290 if (txt_match_uint (txt, 10, &ctx->version) == 0) { 291 return (1); 292 } 293 294 ctx->trk = NULL; 295 ctx->pos = 0; 296 ctx->add = 0; 297 } 298 else if (txt_match (txt, "TEXT", 1)) { 299 if (txt_enc_text (ctx)) { 300 return (1); 301 } 302 } 303 else if (txt_match (txt, "TRACK", 1)) { 304 if (txt_enc_track (ctx)) { 305 return (1); 306 } 307 } 308 else if (txt_match (txt, "+", 1)) { 309 ctx->add = 1; 310 } 311 else if (txt_match (txt, "$", 1)) { 312 if (txt_enc_pulse (ctx, 16)) { 313 return (1); 314 } 315 } 316 else { 317 if (txt_enc_pulse (ctx, 10)) { 318 return (1); 319 } 320 } 321 } 322} 323 324int pfi_encode_text (pfi_img_t *img, const char *fname) 325{ 326 int r; 327 FILE *fp; 328 pfi_text_t ctx; 329 330 if ((fp = fopen (fname, "r")) == NULL) { 331 return (1); 332 } 333 334 txt_init (&ctx.txt, fp); 335 336 ctx.img = img; 337 ctx.trk = NULL; 338 ctx.pos = 0; 339 ctx.add = 0; 340 341 r = txt_encode (&ctx); 342 343 if (r) { 344 txt_error (&ctx.txt, "PFI"); 345 } 346 347 txt_free (&ctx.txt); 348 fclose (fp); 349 350 return (r); 351}