fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
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}