1 /* tape_block.h: individual tape block types
2    Copyright (c) 2003-2008 Philip Kendall
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License along
15    with this program; if not, write to the Free Software Foundation, Inc.,
16    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 
18    Author contact information:
19 
20    E-mail: philip-fuse@shadowmagic.org.uk
21 
22 */
23 
24 #ifndef LIBSPECTRUM_TAPE_BLOCK_H
25 #define LIBSPECTRUM_TAPE_BLOCK_H
26 
27 #ifndef LIBSPECTRUM_INTERNALS_H
28 #include "internals.h"
29 #endif				/* #ifndef LIBSPECTRUM_INTERNALS_H */
30 
31 /*
32  * The individual block types
33  */
34 
35 /* A standard ROM loading block */
36 typedef struct libspectrum_tape_rom_block {
37 
38   size_t length;		/* How long is this block */
39   libspectrum_byte *data;	/* The actual data */
40   libspectrum_dword pause;	/* Pause after block (milliseconds) */
41   libspectrum_dword pause_tstates; /* Pause after block (tstates) */
42 
43 } libspectrum_tape_rom_block;
44 
45 typedef struct libspectrum_tape_rom_block_state {
46 
47   /* Private data */
48 
49   libspectrum_tape_state_type state;
50 
51   size_t edge_count;		/* Number of pilot pulses to go */
52 
53   size_t bytes_through_block;
54   size_t bits_through_byte;	/* How far through the data are we? */
55 
56   libspectrum_byte current_byte; /* The current data byte; gets shifted out
57 				    as we read bits from it */
58   libspectrum_dword bit_tstates; /* How long is an edge for the current bit */
59 
60 } libspectrum_tape_rom_block_state;
61 
62 /* A turbo loading block */
63 typedef struct libspectrum_tape_turbo_block {
64 
65   size_t length;		/* Length of data */
66   size_t bits_in_last_byte;	/* How many bits are in the last byte? */
67   libspectrum_byte *data;	/* The actual data */
68   libspectrum_dword pause;	/* Pause after data (in ms) */
69   libspectrum_dword pause_tstates; /* Pause after block (tstates) */
70 
71   libspectrum_dword pilot_length; /* Length of pilot pulse (in tstates) */
72   size_t pilot_pulses;		/* Number of pilot pulses */
73 
74   libspectrum_dword sync1_length, sync2_length; /* Length of the sync pulses */
75   libspectrum_dword bit0_length, bit1_length; /* Length of (re)set bits */
76 
77 } libspectrum_tape_turbo_block;
78 
79 typedef struct libspectrum_tape_turbo_block_state {
80 
81   /* Private data */
82 
83   libspectrum_tape_state_type state;
84 
85   size_t edge_count;		/* Number of pilot pulses to go */
86 
87   size_t bytes_through_block;
88   size_t bits_through_byte;	/* How far through the data are we? */
89 
90   libspectrum_byte current_byte; /* The current data byte; gets shifted out
91 				    as we read bits from it */
92   libspectrum_dword bit_tstates; /* How long is an edge for the current bit */
93 
94 } libspectrum_tape_turbo_block_state;
95 
96 /* A pure tone block */
97 typedef struct libspectrum_tape_pure_tone_block {
98 
99   libspectrum_dword length;
100   size_t pulses;
101 
102 } libspectrum_tape_pure_tone_block;
103 
104 typedef struct libspectrum_tape_pure_tone_block_state {
105 
106   /* Private data */
107 
108   size_t edge_count;
109 
110 } libspectrum_tape_pure_tone_block_state;
111 
112 /* A list of pulses of different lengths */
113 typedef struct libspectrum_tape_pulses_block {
114 
115   size_t count;
116   libspectrum_dword *lengths;
117 
118 } libspectrum_tape_pulses_block;
119 
120 typedef struct libspectrum_tape_pulses_block_state {
121 
122   /* Private data */
123 
124   size_t edge_count;
125 
126 } libspectrum_tape_pulses_block_state;
127 
128 /* A block of just of data */
129 typedef struct libspectrum_tape_pure_data_block {
130 
131   size_t length;		/* Length of data */
132   size_t bits_in_last_byte;	/* How many bits are in the last byte? */
133   libspectrum_byte *data;	/* The actual data */
134   libspectrum_dword pause;	/* Pause after data (in ms) */
135   libspectrum_dword pause_tstates; /* Pause after block (tstates) */
136 
137   libspectrum_dword bit0_length, bit1_length; /* Length of (re)set bits */
138 
139 } libspectrum_tape_pure_data_block;
140 
141 typedef struct libspectrum_tape_pure_data_block_state {
142 
143   /* Private data */
144 
145   libspectrum_tape_state_type state;
146 
147   size_t bytes_through_block;
148   size_t bits_through_byte;	/* How far through the data are we? */
149 
150   libspectrum_byte current_byte; /* The current data byte; gets shifted out
151 				    as we read bits from it */
152   libspectrum_dword bit_tstates; /* How long is an edge for the current bit */
153 
154 } libspectrum_tape_pure_data_block_state;
155 
156 /* A raw data block */
157 typedef struct libspectrum_tape_raw_data_block {
158 
159   size_t length;		/* Length of data */
160   size_t bits_in_last_byte;	/* How many bits are in the last byte? */
161   libspectrum_byte *data;	/* The actual data */
162   libspectrum_dword pause;	/* Pause after data (in ms) */
163   libspectrum_dword pause_tstates; /* Pause after block (tstates) */
164 
165   libspectrum_dword bit_length; /* Bit length. *Not* pulse length! */
166 
167 } libspectrum_tape_raw_data_block;
168 
169 typedef struct libspectrum_tape_raw_data_block_state {
170 
171   /* Private data */
172 
173   libspectrum_tape_state_type state;
174 
175   size_t bytes_through_block;
176   size_t bits_through_byte;	/* How far through the data are we? */
177 
178   libspectrum_byte last_bit;	/* The last bit which was read */
179   libspectrum_dword bit_tstates; /* How long is an edge for the current bit */
180 
181 } libspectrum_tape_raw_data_block_state;
182 
183 struct libspectrum_tape_generalised_data_symbol {
184 
185   libspectrum_tape_generalised_data_symbol_edge_type edge_type;
186   libspectrum_word *lengths;
187 
188 };
189 
190 struct libspectrum_tape_generalised_data_symbol_table {
191 
192   libspectrum_dword symbols_in_block;
193   libspectrum_byte max_pulses;
194   libspectrum_word symbols_in_table;
195 
196   libspectrum_tape_generalised_data_symbol *symbols;
197 
198 };
199 
200 typedef struct libspectrum_tape_generalised_data_block {
201 
202   libspectrum_dword pause;	/* Pause after data (in ms) */
203   libspectrum_dword pause_tstates; /* Pause after block (tstates) */
204 
205   libspectrum_tape_generalised_data_symbol_table pilot_table, data_table;
206 
207   libspectrum_byte *pilot_symbols;
208   libspectrum_word *pilot_repeats;
209 
210   size_t bits_per_data_symbol;
211   libspectrum_byte *data;
212 
213 } libspectrum_tape_generalised_data_block;
214 
215 typedef struct libspectrum_tape_generalised_data_block_state {
216 
217   /* Private data */
218 
219   libspectrum_tape_state_type state;
220 
221   libspectrum_dword run;
222   libspectrum_word symbols_through_run;
223   libspectrum_byte edges_through_symbol;
224 
225   libspectrum_byte current_symbol;
226   size_t symbols_through_stream;
227 
228   libspectrum_byte current_byte;
229   size_t bits_through_byte;
230   size_t bytes_through_stream;
231 
232 } libspectrum_tape_generalised_data_block_state;
233 
234 /* A pause block - some formats use pause in ms, some use tstates. Fuse uses
235    tstates but wants to be able to write back the original value to a file
236    if re-saved so store both */
237 typedef struct libspectrum_tape_pause_block {
238 
239   libspectrum_dword length;
240   libspectrum_dword length_tstates;
241   int level; /* 0/1 for low and high, anything else for not specified */
242 
243 } libspectrum_tape_pause_block;
244 
245 /* A group start block */
246 typedef struct libspectrum_tape_group_start_block {
247 
248   char *name;
249 
250 } libspectrum_tape_group_start_block;
251 
252 /* No group end block needed as it contains no data */
253 
254 /* A jump block */
255 typedef struct libspectrum_tape_jump_block {
256 
257   int offset;
258 
259 } libspectrum_tape_jump_block;
260 
261 /* A loop start block */
262 typedef struct libspectrum_tape_loop_start_block {
263 
264   int count;
265 
266 } libspectrum_tape_loop_start_block;
267 
268 /* No loop end block needed as it contains no data */
269 
270 /* A select block */
271 typedef struct libspectrum_tape_select_block {
272 
273   /* Number of selections */
274   size_t count;
275 
276   /* Offset of each selection, and a description of each */
277   int *offsets;
278   char **descriptions;
279 
280 } libspectrum_tape_select_block;
281 
282 /* No `stop tape if in 48K mode' block as it contains no data */
283 
284 /* A set signal level block */
285 typedef struct libspectrum_tape_set_signal_level_block {
286 
287   int level;			/* Mic level 0/1 */
288 
289 } libspectrum_tape_set_signal_level_block;
290 
291 /* A comment block */
292 typedef struct libspectrum_tape_comment_block {
293 
294   char *text;
295 
296 } libspectrum_tape_comment_block;
297 
298 /* A message block */
299 typedef struct libspectrum_tape_message_block {
300 
301   int time;
302   int time_tstates;
303   char *text;
304 
305 } libspectrum_tape_message_block;
306 
307 /* An archive info block */
308 typedef struct libspectrum_tape_archive_info_block {
309 
310   /* Number of strings */
311   size_t count;
312 
313   /* ID for each string */
314   int *ids;
315 
316   /* Text of each string */
317   char **strings;
318 
319 } libspectrum_tape_archive_info_block;
320 
321 /* A hardware info block */
322 typedef struct libspectrum_tape_hardware_block {
323 
324   /* Number of entries */
325   size_t count;
326 
327   /* For each entry, a type, an ID and a value */
328   int *types, *ids, *values;
329 
330 } libspectrum_tape_hardware_block;
331 
332 /* A custom block */
333 typedef struct libspectrum_tape_custom_block {
334 
335   /* Description of this block */
336   char *description;
337 
338   /* And the data for it; currently, no attempt is made to interpret
339      this data */
340   size_t length; libspectrum_byte *data;
341 
342 } libspectrum_tape_custom_block;
343 
344 /* No block needed for concatenation block, as it isn't stored */
345 
346 /* Block types not present in the TZX format follow here */
347 
348 /* A Z80Em or CSW audio block */
349 typedef struct libspectrum_tape_rle_pulse_block {
350 
351   size_t length;
352   libspectrum_byte *data;
353   long scale;
354 
355 } libspectrum_tape_rle_pulse_block;
356 
357 typedef struct libspectrum_tape_rle_pulse_block_state {
358 
359   /* Private data */
360 
361   size_t index;
362 
363 } libspectrum_tape_rle_pulse_block_state;
364 
365 /* A PZX pulse sequence block */
366 typedef struct libspectrum_tape_pulse_sequence_block {
367 
368   size_t count;
369   libspectrum_dword *lengths; /* Length of pulse (in tstates) */
370   size_t *pulse_repeats;      /* Number of pulses */
371 
372 } libspectrum_tape_pulse_sequence_block;
373 
374 typedef struct libspectrum_tape_pulse_sequence_block_state {
375 
376   /* Private data */
377 
378   size_t index;
379   size_t pulse_count;		/* Number of pulses to go */
380   int level;			/* Mic level 0/1 */
381 
382 } libspectrum_tape_pulse_sequence_block_state;
383 
384 /* A PZX data block */
385 typedef struct libspectrum_tape_data_block {
386 
387   size_t count;			   /* Length of data in bits */
388   int initial_level;		   /* Mic level 0/1 */
389   libspectrum_byte *data;	   /* The actual data */
390   libspectrum_dword tail_length;   /* Length of tail pulse (in tstates) */
391 
392   size_t bit0_pulse_count, bit1_pulse_count; /* Pulse count in (re)set bits */
393   libspectrum_word *bit0_pulses;   /* Reset bits pulses */
394   libspectrum_word *bit1_pulses;   /* Set bits pulses */
395 
396   size_t length;		/* Length of data in bytes */
397   size_t bits_in_last_byte;	/* How many bits are in the last byte? */
398 
399 } libspectrum_tape_data_block;
400 
401 typedef struct libspectrum_tape_data_block_state {
402 
403   /* Private data */
404 
405   libspectrum_tape_state_type state;
406 
407   int bit0_flags;		 /* Any flags to be set when bit0 is returned */
408   int bit1_flags;		 /* Any flags to be set when bit1 is returned */
409 
410   size_t bytes_through_block;
411   size_t bits_through_byte;	/* How far through the data are we? */
412 
413   libspectrum_byte current_byte; /* The current data byte; gets shifted out
414 				    as we read bits from it */
415   size_t pulse_count;		 /* Pulse count in current bit */
416   libspectrum_word *bit_pulses;  /* Current bit pulses */
417   int bit_flags;		 /* Any flags to be set when this bit is
418 				    returned */
419   int level;			 /* Mic level 0/1 */
420 
421   size_t index;			 /* Location in active pulse sequence */
422 
423 } libspectrum_tape_data_block_state;
424 
425 /*
426  * The generic tape block
427  */
428 
429 struct libspectrum_tape_block {
430 
431   libspectrum_tape_type type;
432 
433   union {
434     libspectrum_tape_rom_block rom;
435     libspectrum_tape_turbo_block turbo;
436     libspectrum_tape_pure_tone_block pure_tone;
437     libspectrum_tape_pulses_block pulses;
438     libspectrum_tape_pure_data_block pure_data;
439     libspectrum_tape_raw_data_block raw_data;
440 
441     libspectrum_tape_generalised_data_block generalised_data;
442 
443     libspectrum_tape_pause_block pause;
444     libspectrum_tape_group_start_block group_start;
445     /* No group end block needed as it contains no data */
446     libspectrum_tape_jump_block jump;
447     libspectrum_tape_loop_start_block loop_start;
448     /* No loop end block needed as it contains no data */
449 
450     libspectrum_tape_select_block select;
451 
452     /* No `stop tape if in 48K mode' block as it contains no data */
453 
454     libspectrum_tape_set_signal_level_block set_signal_level;
455     libspectrum_tape_comment_block comment;
456     libspectrum_tape_message_block message;
457     libspectrum_tape_archive_info_block archive_info;
458     libspectrum_tape_hardware_block hardware;
459 
460     libspectrum_tape_custom_block custom;
461 
462     libspectrum_tape_rle_pulse_block rle_pulse;
463 
464     libspectrum_tape_pulse_sequence_block pulse_sequence;
465     libspectrum_tape_data_block data_block;
466 
467   } types;
468 
469 };
470 
471 struct libspectrum_tape_block_state {
472 
473   /* The current block */
474   libspectrum_tape_iterator current_block;
475 
476   /* Where to return to after a loop, and how many iterations of the loop
477      to do */
478   GSList* loop_block;
479   size_t loop_count;
480 
481   union {
482     libspectrum_tape_rom_block_state rom;
483     libspectrum_tape_turbo_block_state turbo;
484     libspectrum_tape_pure_tone_block_state pure_tone;
485     libspectrum_tape_pulses_block_state pulses;
486     libspectrum_tape_pure_data_block_state pure_data;
487     libspectrum_tape_raw_data_block_state raw_data;
488     libspectrum_tape_generalised_data_block_state generalised_data;
489     libspectrum_tape_rle_pulse_block_state rle_pulse;
490     libspectrum_tape_pulse_sequence_block_state pulse_sequence;
491     libspectrum_tape_data_block_state data_block;
492 
493   } block_state;
494 
495 };
496 
497 /* Functions needed by both tape.c and tape_block.c */
498 libspectrum_error
499 libspectrum_tape_pure_data_next_bit( libspectrum_tape_pure_data_block *block,
500                              libspectrum_tape_pure_data_block_state *state );
501 void
502 libspectrum_tape_raw_data_next_bit( libspectrum_tape_raw_data_block *block,
503                              libspectrum_tape_raw_data_block_state *state );
504 libspectrum_byte
505 get_generalised_data_symbol( libspectrum_tape_generalised_data_block *block,
506                         libspectrum_tape_generalised_data_block_state *state );
507 libspectrum_error
508 generalised_data_edge( libspectrum_tape_generalised_data_block *block,
509                        libspectrum_tape_generalised_data_block_state *state,
510 		       libspectrum_dword *tstates, int *end_of_block,
511 		       int *flags );
512 libspectrum_error
513 libspectrum_tape_data_block_next_bit( libspectrum_tape_data_block *block,
514                                     libspectrum_tape_data_block_state *state );
515 
516 
517 #endif				/* #ifndef LIBSPECTRUM_TAPE_BLOCK_H */
518