fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 179 lines 4.4 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/utils/aym/decode.c * 7 * Created: 2015-05-21 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2015-2016 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 <stdlib.h> 26#include <stdio.h> 27#include <string.h> 28 29 30static 31int aym_decode_fp (FILE *inp, FILE *out, unsigned long th, unsigned long mark) 32{ 33 unsigned i; 34 int c1, c2; 35 unsigned long vers; 36 unsigned long long delay; 37 unsigned long long total; 38 unsigned char v1, v2; 39 unsigned char buf[8]; 40 unsigned char reg[16]; 41 42 if (fread (buf, 1, 8, inp) != 8) { 43 return (1); 44 } 45 46 if (aym_get_uint32_be (buf, 0) != AYM_MAGIC) { 47 fprintf (stderr, "%s: not a aym file\n", arg0); 48 return (1); 49 } 50 51 vers = aym_get_uint32_be (buf, 4); 52 53 if (vers != 0) { 54 fprintf (stderr, "%s: unknown aym version (%lu)\n", arg0, vers); 55 return (1); 56 } 57 58 fprintf (out, "AYM %lu\n\n", vers); 59 60 for (i = 0; i < 16; i++) { 61 reg[i] = 0; 62 } 63 64 delay = 0; 65 total = 0; 66 67 while (1) { 68 c1 = fgetc (inp); 69 c2 = fgetc (inp); 70 71 if ((c1 == EOF) || (c2 == EOF)) { 72 fprintf (stderr, "%s: premature end of file\n", arg0); 73 return (0); 74 } 75 76 v1 = c1 & 0xff; 77 v2 = c2 & 0xff; 78 79 switch ((v1 >> 4) & 0x0f) { 80 case 0: 81 if ((mark > 0) && (total <= mark) && ((total + delay) > mark)) { 82 fprintf (out, "\n# MARK %lu.%06lu\n", 83 mark / 1000000, mark % 1000000 84 ); 85 86 for (i = 0; i < 14; i++) { 87 fprintf (out, "# REG %02X %02X\n", i, reg[i]); 88 } 89 90 fputs ("\n", out); 91 } 92 93 if ((delay > 0) && (delay >= th)) { 94 total += delay; 95 fprintf (out, "\n# %llu.%06llu + %llu.%06llu = %llu.%06llu\n", 96 (total - delay) / 1000000, (total - delay) % 1000000, 97 delay / 1000000, delay % 1000000, 98 total / 1000000, total % 1000000 99 ); 100 fprintf (out, "DEL %llu\n\n", delay); 101 delay = 0; 102 } 103 104 reg[v1 & 0x0f] = v2; 105 106 fprintf (out, "REG %02X %02X\n", v1 & 0x0f, v2); 107 break; 108 109 case 1: 110 delay += ((v1 & 0x0f) << 8) | v2; 111 break; 112 113 case 2: 114 delay += (((unsigned long long) (v1 & 0x0f) << 8) | v2) << 12; 115 break; 116 117 case 3: 118 delay += (((unsigned long long) (v1 & 0x0f) << 8) | v2) << 24; 119 break; 120 121 case 8: 122 fprintf (out, "TXT %u ", v1 & 0x0f); 123 while (v2 > 0) { 124 if ((c1 = fgetc (inp)) == EOF) { 125 return (1); 126 } 127 128 fputc (c1, out); 129 130 v2 -= 1; 131 } 132 fputs ("\n\n", out); 133 break; 134 135 case 15: 136 if ((v1 == 0xff) && (v2 == 0xff)) { 137 fprintf (out, "END\n"); 138 } 139 return (0); 140 } 141 } 142 143 return (0); 144} 145 146int aym_decode (const char *inp, const char *out, unsigned long th, unsigned long mark) 147{ 148 int r; 149 FILE *finp, *fout; 150 151 if (inp == NULL) { 152 finp = stdin; 153 } 154 else if ((finp = fopen (inp, "rb")) == NULL) { 155 fprintf (stderr, "%s: can't open input file (%s)\n", arg0, inp); 156 return (1); 157 } 158 159 if (out == NULL) { 160 fout = stdout; 161 } 162 else if ((fout = fopen (out, "w")) == NULL) { 163 fprintf (stderr, "%s: can't open output file (%s)\n", arg0, out); 164 fclose (finp); 165 return (1); 166 } 167 168 r = aym_decode_fp (finp, fout, th, mark); 169 170 if (fout != stdout) { 171 fclose (fout); 172 } 173 174 if (finp != stdin) { 175 fclose (finp); 176 } 177 178 return (r); 179}