fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

pfi: Add read support for Applesauce A2R files

+478
+7
Makefile.dep
··· 2394 2394 src/drivers/pfi/pfi.h \ 2395 2395 src/drivers/pfi/track.h 2396 2396 2397 + src/drivers/pfi/pfi-a2r.o: src/drivers/pfi/pfi-a2r.c \ 2398 + src/drivers/pfi/pfi-a2r.h \ 2399 + src/drivers/pfi/pfi-io.h \ 2400 + src/drivers/pfi/pfi.h \ 2401 + src/drivers/pfi/track.h 2402 + 2397 2403 src/drivers/pfi/pfi-io.o: src/drivers/pfi/pfi-io.c \ 2404 + src/drivers/pfi/pfi-a2r.h \ 2398 2405 src/drivers/pfi/pfi-io.h \ 2399 2406 src/drivers/pfi/pfi-kryo.h \ 2400 2407 src/drivers/pfi/pfi-pfi.h \
+2
src/drivers/pfi/Makefile.inc
··· 7 7 8 8 DEV_PFI_BAS := \ 9 9 decode-bits \ 10 + pfi-a2r \ 10 11 pfi-io \ 11 12 pfi-kryo \ 12 13 pfi-pfi \ ··· 23 24 DIST += $(DEV_PFI_SRC) $(DEV_PFI_HDR) 24 25 25 26 $(rel)/decode-bits.o: $(rel)/decode-bits.c 27 + $(rel)/pfi-a2r.o: $(rel)/pfi-a2r.c 26 28 $(rel)/pfi-io.o: $(rel)/pfi-io.c 27 29 $(rel)/pfi-kryo.o: $(rel)/pfi-kryo.c 28 30 $(rel)/pfi-pfi.o: $(rel)/pfi-pfi.c
+422
src/drivers/pfi/pfi-a2r.c
··· 1 + /***************************************************************************** 2 + * pce * 3 + *****************************************************************************/ 4 + 5 + /***************************************************************************** 6 + * File name: src/drivers/pfi/pfi-a2r.c * 7 + * Created: 2019-06-18 by Hampa Hug <hampa@hampa.ch> * 8 + * Copyright: (C) 2019 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 <stdlib.h> 24 + #include <stdio.h> 25 + #include <string.h> 26 + 27 + #include "pfi.h" 28 + #include "pfi-io.h" 29 + #include "pfi-a2r.h" 30 + 31 + 32 + #ifndef DEBUG_A2R 33 + #define DEBUG_A2R 0 34 + #endif 35 + 36 + 37 + #define A2R_CLOCK 8000000 38 + 39 + #define A2R_MAGIC_A2R2 0x32523241 40 + #define A2R_MAGIC_2 0x0a0d0aff 41 + #define A2R_MAGIC_INFO 0x4f464e49 42 + #define A2R_MAGIC_STRM 0x4d525453 43 + #define A2R_MAGIC_META 0x4154454d 44 + 45 + 46 + typedef struct { 47 + FILE *fp; 48 + pfi_img_t *img; 49 + pfi_trk_t *trk; 50 + 51 + unsigned long c; 52 + unsigned long h; 53 + unsigned long loop; 54 + 55 + char have_info; 56 + unsigned char disk_type; 57 + unsigned char write_protected; 58 + unsigned char synchronized; 59 + char creator[33]; 60 + } a2r_load_t; 61 + 62 + 63 + static 64 + void a2r_get_string (char *dst, const unsigned char *src, unsigned max) 65 + { 66 + unsigned i; 67 + 68 + for (i = 0; i < max; i++) { 69 + if ((dst[i] = src[i]) == 0) { 70 + break; 71 + } 72 + } 73 + 74 + while ((i > 0) && (dst[i - 1] == 0x20)) { 75 + i -= 1; 76 + } 77 + 78 + dst[i] = 0; 79 + } 80 + 81 + static 82 + int a2r_load_header (a2r_load_t *a2r) 83 + { 84 + unsigned char buf[8]; 85 + 86 + if (pfi_read (a2r->fp, buf, 8)) { 87 + return (1); 88 + } 89 + 90 + if (pfi_get_uint32_le (buf, 0) != A2R_MAGIC_A2R2) { 91 + fprintf (stderr, "a2r: bad magic 1\n"); 92 + return (1); 93 + } 94 + 95 + if (pfi_get_uint32_le (buf, 4) != A2R_MAGIC_2) { 96 + fprintf (stderr, "a2r: bad magic 2\n"); 97 + return (1); 98 + } 99 + 100 + return (0); 101 + } 102 + 103 + static 104 + int a2r_load_meta (a2r_load_t *a2r, unsigned long size) 105 + { 106 + unsigned n; 107 + unsigned char buf[256]; 108 + 109 + while (size > 0) { 110 + n = (size < 256) ? size : 256; 111 + 112 + if (pfi_read (a2r->fp, buf, n)) { 113 + return (1); 114 + } 115 + 116 + if (pfi_img_add_comment (a2r->img, buf, n)) { 117 + return (1); 118 + } 119 + 120 + size -= n; 121 + } 122 + 123 + return (0); 124 + } 125 + 126 + static 127 + int a2r_load_info (a2r_load_t *a2r, unsigned long size) 128 + { 129 + unsigned char buf[36]; 130 + 131 + if (size < 36) { 132 + return (1); 133 + } 134 + 135 + if (pfi_read (a2r->fp, buf, 36)) { 136 + return (1); 137 + } 138 + 139 + if (buf[0] < 1) { 140 + fprintf (stderr, "a2r: bad info version (%u)\n", buf[0]); 141 + return (1); 142 + } 143 + 144 + a2r_get_string (a2r->creator, buf + 1, 32); 145 + 146 + a2r->disk_type = buf[33]; 147 + a2r->write_protected = buf[34]; 148 + a2r->synchronized = buf[34]; 149 + 150 + #if DEBUG_A2R >= 1 151 + fprintf (stderr, "a2r: creator = '%s'\n", a2r->creator); 152 + fprintf (stderr, "a2r: disk type = %u\n", a2r->disk_type); 153 + fprintf (stderr, "a2r: write protected = %u\n", a2r->write_protected); 154 + fprintf (stderr, "a2r: synchronized = %u\n", a2r->synchronized); 155 + #endif 156 + 157 + if (pfi_skip (a2r->fp, size - 36)) { 158 + return (1); 159 + } 160 + 161 + return (0); 162 + } 163 + 164 + static 165 + int a2r_load_capture (a2r_load_t *a2r, unsigned long size) 166 + { 167 + unsigned i, n; 168 + unsigned long pulse, index, total; 169 + unsigned char buf[256]; 170 + 171 + pulse = 0; 172 + total = 0; 173 + index = 0; 174 + 175 + i = 0; 176 + n = 0; 177 + 178 + while (size > 0) { 179 + if (total >= index) { 180 + if (pfi_trk_add_index (a2r->trk, total)) { 181 + return (1); 182 + } 183 + 184 + index += a2r->loop; 185 + } 186 + 187 + if (i >= n) { 188 + i = 0; 189 + n = (size < 256) ? size : 256; 190 + 191 + if (pfi_read (a2r->fp, buf, n)) { 192 + return (1); 193 + } 194 + } 195 + 196 + if (buf[i] < 255) { 197 + pulse += buf[i]; 198 + 199 + if (pulse > 0) { 200 + if (pfi_trk_add_pulse (a2r->trk, pulse)) { 201 + return (1); 202 + } 203 + } 204 + 205 + total += pulse; 206 + pulse = 0; 207 + } 208 + else { 209 + pulse += 255; 210 + } 211 + 212 + i += 1; 213 + size -= 1; 214 + } 215 + 216 + pfi_trk_clean (a2r->trk); 217 + 218 + return (0); 219 + } 220 + 221 + static 222 + int a2r_load_strm (a2r_load_t *a2r, unsigned long size) 223 + { 224 + unsigned long cnt; 225 + unsigned char buf[10]; 226 + 227 + while (size > 0) { 228 + if (pfi_read (a2r->fp, buf, 1)) { 229 + return (1); 230 + } 231 + 232 + size -= 1; 233 + 234 + if (buf[0] == 0xff) { 235 + break; 236 + } 237 + 238 + if (size < 9) { 239 + return (1); 240 + } 241 + 242 + if (pfi_read (a2r->fp, buf + 1, 9)) { 243 + return (1); 244 + } 245 + 246 + size -= 9; 247 + 248 + if (a2r->disk_type == 1) { 249 + a2r->c = buf[0]; 250 + a2r->h = 0; 251 + } 252 + else { 253 + a2r->c = buf[0] >> 1; 254 + a2r->h = buf[0] & 1; 255 + } 256 + 257 + cnt = pfi_get_uint32_le (buf, 2); 258 + 259 + if (cnt > size) { 260 + return (1); 261 + } 262 + 263 + a2r->loop = pfi_get_uint32_le (buf, 6); 264 + 265 + #if DEBUG_A2R >= 2 266 + fprintf (stderr, "a2r: %lu/%lu TYPE=%u SIZE=%lu LOOP=%lu\n", 267 + a2r->c, a2r->h, buf[1], cnt, a2r->loop 268 + ); 269 + #endif 270 + 271 + if ((buf[1] == 1) || (buf[1] == 3)) { 272 + a2r->trk = pfi_img_get_track (a2r->img, a2r->c, a2r->h, 1); 273 + 274 + if (a2r->trk == NULL) { 275 + return (1); 276 + } 277 + 278 + pfi_trk_reset (a2r->trk); 279 + pfi_trk_set_clock (a2r->trk, A2R_CLOCK); 280 + 281 + if (a2r_load_capture (a2r, cnt)) { 282 + return (1); 283 + } 284 + } 285 + else { 286 + fprintf (stderr, 287 + "a2r: warning: unsupported capture type (%u)\n", 288 + buf[1] 289 + ); 290 + 291 + if (pfi_skip (a2r->fp, cnt)) { 292 + return (1); 293 + } 294 + } 295 + 296 + size -= cnt; 297 + } 298 + 299 + if (size > 0) { 300 + fprintf (stderr, 301 + "a2r: warning: %lu extra bytes in STRM chunk\n", 302 + size 303 + ); 304 + 305 + if (pfi_skip (a2r->fp, size)) { 306 + return (1); 307 + } 308 + } 309 + 310 + return (0); 311 + } 312 + 313 + static 314 + int a2r_load_image (a2r_load_t *a2r) 315 + { 316 + unsigned long type, size; 317 + unsigned char buf[8]; 318 + 319 + if (a2r_load_header (a2r)) { 320 + return (1); 321 + } 322 + 323 + a2r->have_info = 0; 324 + 325 + while (pfi_read (a2r->fp, buf, 8) == 0) { 326 + type = pfi_get_uint32_le (buf, 0); 327 + size = pfi_get_uint32_le (buf, 4); 328 + 329 + #if DEBUG_A2R >= 2 330 + fprintf (stderr, "chunk %08lX + %08lX\n", type, size); 331 + #endif 332 + 333 + if (type == A2R_MAGIC_INFO) { 334 + if (a2r_load_info (a2r, size)) { 335 + return (1); 336 + } 337 + 338 + a2r->have_info = 1; 339 + } 340 + else if (type == A2R_MAGIC_STRM) { 341 + if (a2r->have_info == 0) { 342 + return (1); 343 + } 344 + 345 + if (a2r_load_strm (a2r, size)) { 346 + return (1); 347 + } 348 + } 349 + else if (type == A2R_MAGIC_META) { 350 + if (a2r_load_meta (a2r, size)) { 351 + return (1); 352 + } 353 + } 354 + else { 355 + fprintf (stderr, "a2r: unknown chunck type (%08lX)\n", 356 + type 357 + ); 358 + 359 + if (pfi_skip (a2r->fp, size)) { 360 + return (1); 361 + } 362 + } 363 + } 364 + 365 + return (0); 366 + } 367 + 368 + pfi_img_t *pfi_load_a2r (FILE *fp) 369 + { 370 + a2r_load_t a2r; 371 + 372 + a2r.fp = fp; 373 + a2r.img = NULL; 374 + a2r.trk = NULL; 375 + a2r.have_info = 0; 376 + 377 + if ((a2r.img = pfi_img_new()) == NULL) { 378 + return (NULL); 379 + } 380 + 381 + if (a2r_load_image (&a2r)) { 382 + pfi_img_del (a2r.img); 383 + return (NULL); 384 + } 385 + 386 + return (a2r.img); 387 + } 388 + 389 + int pfi_probe_a2r_fp (FILE *fp) 390 + { 391 + unsigned char buf[8]; 392 + 393 + if (pfi_read (fp, buf, 8)) { 394 + return (0); 395 + } 396 + 397 + if (pfi_get_uint32_le (buf, 0) != A2R_MAGIC_A2R2) { 398 + return (0); 399 + } 400 + 401 + if (pfi_get_uint32_le (buf, 4) != A2R_MAGIC_2) { 402 + return (0); 403 + } 404 + 405 + return (1); 406 + } 407 + 408 + int pfi_probe_a2r (const char *fname) 409 + { 410 + int r; 411 + FILE *fp; 412 + 413 + if ((fp = fopen (fname, "rb")) == NULL) { 414 + return (0); 415 + } 416 + 417 + r = pfi_probe_a2r_fp (fp); 418 + 419 + fclose (fp); 420 + 421 + return (r); 422 + }
+38
src/drivers/pfi/pfi-a2r.h
··· 1 + /***************************************************************************** 2 + * pce * 3 + *****************************************************************************/ 4 + 5 + /***************************************************************************** 6 + * File name: src/drivers/pfi/pfi-a2r.h * 7 + * Created: 2019-06-18 by Hampa Hug <hampa@hampa.ch> * 8 + * Copyright: (C) 2019 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 + #ifndef PFI_IMG_A2R_H 24 + #define PFI_IMG_A2R_H 1 25 + 26 + 27 + #include <drivers/pfi/pfi.h> 28 + 29 + 30 + pfi_img_t *pfi_load_a2r (FILE *fp); 31 + 32 + int pfi_save_a2r (FILE *fp, const pfi_img_t *img); 33 + 34 + int pfi_probe_a2r_fp (FILE *fp); 35 + int pfi_probe_a2r (const char *fname); 36 + 37 + 38 + #endif
+8
src/drivers/pfi/pfi-io.c
··· 25 25 #include <string.h> 26 26 27 27 #include "pfi-io.h" 28 + #include "pfi-a2r.h" 28 29 #include "pfi-pfi.h" 29 30 #include "pfi-kryo.h" 30 31 #include "pfi-scp.h" ··· 233 234 else if (strcasecmp (ext, ".scp") == 0) { 234 235 return (PFI_FORMAT_SCP); 235 236 } 237 + else if (strcasecmp (ext, ".a2r") == 0) { 238 + return (PFI_FORMAT_A2R); 239 + } 236 240 237 241 return (PFI_FORMAT_PFI); 238 242 } ··· 255 259 256 260 case PFI_FORMAT_SCP: 257 261 img = pfi_load_scp (fp); 262 + break; 263 + 264 + case PFI_FORMAT_A2R: 265 + img = pfi_load_a2r (fp); 258 266 break; 259 267 } 260 268
+1
src/drivers/pfi/pfi-io.h
··· 31 31 #define PFI_FORMAT_PFI 1 32 32 #define PFI_FORMAT_KRYOFLUX 2 33 33 #define PFI_FORMAT_SCP 3 34 + #define PFI_FORMAT_A2R 4 34 35 35 36 36 37 unsigned pfi_get_uint16_be (const void *buf, unsigned idx);