6 #include <sys/select.h>
8 #include "hw_helpers.h"
11 #define CHAR_START 0x81
13 #define CHAR_END1 0223
14 #define CHAR_END2 0223
15 #define CHAR_END3 0223
16 #define MAX_BLOCK_SIZE 500
19 #define DEBUG_CHECKSUM
20 #define DEBUG_STRUCTURE
22 //#define IGNORE_CHECKSUM
23 #define HARDCORE_DEBUG
24 /********************************************************/
25 void output (char *string
, int length
);
26 datablock
*get_block ();
28 /********************************************************/
29 char ends
[3] = { CHAR_END1
, CHAR_END2
, CHAR_END3
};
30 int errflag
= 0; // Global error flag
39 /********************************************************/
42 /********************************************************/
43 void dump_data (void *data
, int count
)
45 int fd
= open ("dump", O_RDWR
| O_CREAT
| O_APPEND
, 0666);
47 write (fd
, data
, count
);
51 /********************************************************/
52 void endwarn (int ret
)
55 err ("Unexpected problem in input");
60 /********************************************************/
61 /* Small output things */
62 void err (char *string
)
64 printf ("Error: --> %s\n", string
);
68 void msg (char *string
)
71 printf ("** %s\n", string
);
75 void msgf (char *format
, ...)
78 va_start (ag
, format
);
80 vsprintf (ms
, format
, ag
);
85 void errf (char *format
, ...)
88 va_start (ag
, format
);
90 vsprintf (ms
, format
, ag
);
95 void say (char *string
)
97 if (!silent
) printf ("%s\n", string
);
100 void sayf (char *format
, ...)
103 va_start (ag
, format
);
105 vsprintf (ms
, format
, ag
);
111 /********************************************************/
112 /********************************************************/
114 /********************************************************/
115 /*Block input routines*/
117 unsigned char decode (unsigned char in
)
146 err ("decode(): Impossible case!!!\n");
158 /********************************************************/
159 /********************************************************/
161 void combine466 (unsigned char *raw
, unsigned char *data
)
163 hw16
*result
= (hw16
*) data
;
165 // result->tape.low = 077;
166 unsigned char r1
, r2
, r3
;
168 r1
= decode ((raw
)[0]) & 017;
169 r2
= decode ((raw
)[1]) & 077;
170 r3
= decode ((raw
)[2]) & 077;
172 result
->tape
.high
= r1
;
173 result
->tape
.mid
= r2
;
174 result
->tape
.low
= r3
;
177 msgf ("combine466 (data) : %02x %02x %02x",r1
,r2
,r3
, 6);
178 // msgf ("combine466 (rawmem) : %s%s", bin2str (data[1], 8),
179 // bin2str (data[0], 8));
180 msgf ("combine466 (structure): %s", bin2str (result
->value
, 16));
184 /*********************************************************************/
185 /*********************************************************************/
186 int checksum_error (hw16
* data
, int size
)
188 unsigned short int checksumme
= 0;
190 for (c
= 0; c
< (size
- 1); c
++) {
191 checksumme
^= data
[c
].value
;
192 #ifdef DEBUG_CHECKSUM
193 msgf ("checksum_error(): Gelesen:%04x Berechnet:%04x",
194 data
[c
+ 1].value
, checksumme
);
195 if (data
[c
+ 1].value
== checksumme
)
196 msg ("checksum_error (): Treffer.");
199 #ifdef DEBUG_CHECKSUM
200 msgf ("checksum_error(): Gelesen:%04x Berechnet:%04x",
201 data
[size
- 1].value
, checksumme
);
203 if (data
[size
- 1].value
!= checksumme
)
208 /********************************************************/
209 datablock
*get_block()
211 int blk_size
, round
, ret
, found
, complete
;
212 unsigned char buffer
[3];
214 unsigned char *raw_data
;
219 read_pos
+=ret
=read (inputfd
, buffer
, 1);
221 #ifdef HARDCORE_DEBUG
222 msgf ("READ : (hex)%02x (bin)%s (dec)%3i (oct)%3o",
223 buffer
[0], bin2str (buffer
[0], 8), buffer
[0], buffer
[0]);
226 msg ("get_block(): Nichts mehr zu lesen");
230 if (buffer
[0]==0x83){
231 datablock
*result
= (datablock
*) malloc (sizeof (datablock
));
232 result
->type
= BT_STOP
;
234 result
->raw_data
= NULL
;
239 } while (*buffer
!= (unsigned char) CHAR_START
);
242 msg ("get_block(): Blockstart erkannt");
244 // blk_data = (hw16 *) malloc (MAX_BLOCK_SIZE * sizeof (hw16));
252 ret
= read (inputfd
, buffer
+ round
, 1);
254 #ifdef HARDCORE_DEBUG
255 static int lochzahl
= 0;
256 char *bin
= bin2str (buffer
[round
], 8);
258 for (a
= 0; a
< 8; a
++)
261 msgf ("READ (round %i): (hex)%02x (bin)%s (dec)%3i "
262 " (oct)%3o Lochzahl:%4i",
263 round
, buffer
[round
], bin
, buffer
[round
], buffer
[round
], lochzahl
);
265 // msgf ("READ(round %i) (hex)%02x", round, buffer[round]);
270 if (buffer
[round
- 1] == CHAR_END1
)
272 if (buffer
[round
- 1] == CHAR_END2
)
279 //if (blk_size == MAX_BLOCK_SIZE) {
280 // err ("Blocküberlauf");
284 blk_data
= (hw16
*) realloc (blk_data
,(blk_size
+1)* sizeof (hw16
));
285 raw_data
= (unsigned char *) realloc (raw_data
,(blk_size
+1)*3);
286 memcpy(raw_data
+blk_size
*3,buffer
,3);
287 combine466 (buffer
, (unsigned char *) (blk_data
+ blk_size
));
293 while (complete
== 0);
295 msgf ("get_block(): Size: %i", blk_size
);
297 #ifdef DEBUG_STRUCTURE
299 hw16
*l2
= blk_data
+ 1;
300 head0
*head
= (head0
*) blk_data
;
301 msgf ("get_block(): HEAD: %s", bin2str (l1
->value
, 16));
302 msgf ("get_block(): HEAD: %s", bin2str (l2
->value
, 16));
303 msgf ("get_block(): head->T: %i", head
->T
);
304 msgf ("get_block(): head->S: %i", head
->S
);
305 msgf ("get_block(): head->N: %i", head
->N
);
309 if (checksum_error (blk_data
, blk_size
)) {
310 errf ("get_block(): Checksum error!\nBlock start: %i (0x%x), read address %i (0x%x).",
311 block_pos
,block_pos
,read_pos
,read_pos
);
315 dump_data (buffer
, 3);
316 read_pos
+=read (inputfd
, buffer
, 3);
317 dump_data (buffer
, 3);
330 msg ("get_block(): Checksumme OK");
332 datablock
*result
= (datablock
*) malloc (sizeof (datablock
));
333 result
->type
= BT_DATA
;
334 result
->data
= blk_data
;
335 result
->raw_data
= raw_data
;
336 result
->size
= blk_size
;
343 /********************************************************/
344 /**********************************************************************/
345 int main (int argc
, char **args
)
348 char *filename
= NULL
;
351 msg ("Verarbeite Kommandozeilenparameter:");
352 for (c
= 1; c
< argc
; c
++) {
353 if ((args
[c
][0] == '-') && (strlen (args
[c
]) > 1)) {
354 char action
= args
[c
][1];
355 //msgf ("Action %c, Arg dazu:%s", action, parm);
373 sayf ("%s [-t] [-S] [-n] [-I] [filename]", args
[0]);
375 sayf (" -t Tape mode. Uses tty device and stops on error.");
376 sayf (" -S Split library tape into separate numbered files");
377 sayf (" -s same as -S but no numbering");
378 sayf (" -I Ignore errors");
379 sayf (" -l be silent");
390 if (filename
!= NULL
) {
391 msgf ("Using file:%s", filename
);
392 inputfd
= open (filename
, O_RDWR
);
395 err ("Sorry, exiting.");
401 err ("Use of console as tape device not allowed! Please specify a suitable device!");
407 msg ("Tapemode aktiviert.");
408 if (!isatty (inputfd
)) {
409 err ("Input file doesn't seem to be a tty.\nNot using tape mode on files!\nQuit.");
414 datablock
*akt_block
;
416 /* Initialize read position */
420 msg ("********************************************************");
421 msgf ("Block no. %5i", blk_no
++);
423 akt_block
= get_block ();
424 if (akt_block
== NULL
) {
425 msg ("Ende der Verarbeitung.");
427 msgf ("Errflag:%i", errflag
);
429 sayf ("** Es gab Fehler.");
434 process_block (akt_block
);
435 if (dosplit
) split(akt_block
);
437 free (akt_block
->data
);
438 free (akt_block
->raw_data
);