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
21 //#define IGNORE_CHECKSUM
22 #define HARDCORE_DEBUG
23 /********************************************************/
24 void output (char *string
, int length
);
25 datablock
*get_block ();
27 /********************************************************/
28 char ends
[3] = { CHAR_END1
, CHAR_END2
, CHAR_END3
};
29 int errflag
= 0; // Global error flag
36 /********************************************************/
39 /********************************************************/
40 void dump_data (void *data
, int count
)
42 int fd
= open ("dump", O_RDWR
| O_CREAT
| O_APPEND
, 0666);
44 write (fd
, data
, count
);
48 /********************************************************/
49 void endwarn (int ret
)
52 err ("Unexpected problem in input");
57 /********************************************************/
58 /* Small output things */
59 void err (char *string
)
61 printf ("Error: --> %s\n", string
);
65 void msg (char *string
)
68 printf ("** %s\n", string
);
72 void msgf (char *format
, ...)
75 va_start (ag
, format
);
77 vsprintf (ms
, format
, ag
);
82 void errf (char *format
, ...)
85 va_start (ag
, format
);
87 vsprintf (ms
, format
, ag
);
92 void say (char *string
)
94 if (!silent
) printf ("%s\n", string
);
97 void sayf (char *format
, ...)
100 va_start (ag
, format
);
102 vsprintf (ms
, format
, ag
);
108 /********************************************************/
109 /********************************************************/
111 /********************************************************/
112 /*Block input routines*/
114 unsigned char decode (unsigned char in
)
143 err ("decode(): Impossible case!!!\n");
155 /********************************************************/
156 /********************************************************/
158 void combine466 (unsigned char *raw
, unsigned char *data
)
160 hw16
*result
= (hw16
*) data
;
162 // result->tape.low = 077;
163 unsigned char r1
, r2
, r3
;
165 r1
= decode ((raw
)[0]) & 017;
166 r2
= decode ((raw
)[1]) & 077;
167 r3
= decode ((raw
)[2]) & 077;
169 result
->tape
.high
= r1
;
170 result
->tape
.mid
= r2
;
171 result
->tape
.low
= r3
;
174 msgf ("combine466 (data) : %s%s%s", bin2str (r1
, 4), bin2str (r2
, 6),
176 msgf ("combine466 (rawmem) : %s%s", bin2str (data
[1], 8),
177 bin2str (data
[0], 8));
178 msgf ("combine466 (structure): %s", bin2str (result
->value
, 16));
182 /*********************************************************************/
183 /*********************************************************************/
184 int checksum_error (hw16
* data
, int size
)
186 unsigned short int checksumme
= 0;
188 for (c
= 0; c
< (size
- 1); c
++) {
189 checksumme
^= data
[c
].value
;
190 #ifdef DEBUG_CHECKSUM
191 msgf ("checksum_error(): Gelesen:%04x Berechnet:%04x",
192 data
[c
+ 1].value
, checksumme
);
193 if (data
[c
+ 1].value
== checksumme
)
194 msg ("checksum_error (): Treffer.");
197 #ifdef DEBUG_CHECKSUM
198 msgf ("checksum_error(): Gelesen:%04x Berechnet:%04x",
199 data
[size
- 1].value
, checksumme
);
201 if (data
[size
- 1].value
!= checksumme
)
206 /********************************************************/
207 datablock
*get_block()
209 int blk_size
, round
, ret
, found
, complete
;
210 unsigned char buffer
[3];
212 unsigned char *raw_data
;
217 ret
= read (inputfd
, buffer
, 1);
218 #ifdef HARDCORE_DEBUG
219 msgf ("READ : (hex)%02x (bin)%s (dec)%3i (oct)%3o",
220 buffer
[0], bin2str (buffer
[0], 8), buffer
[0], buffer
[0]);
223 msg ("get_block(): Nichts mehr zu lesen");
227 if (buffer
[0]==0x83){
228 datablock
*result
= (datablock
*) malloc (sizeof (datablock
));
229 result
->type
= BT_STOP
;
231 result
->raw_data
= NULL
;
236 } while (*buffer
!= (unsigned char) CHAR_START
);
238 msg ("get_block(): Blockstart erkannt");
240 // blk_data = (hw16 *) malloc (MAX_BLOCK_SIZE * sizeof (hw16));
248 ret
= read (inputfd
, buffer
+ round
, 1);
249 #ifdef HARDCORE_DEBUG
250 static int lochzahl
= 0;
251 char *bin
= bin2str (buffer
[round
], 8);
253 for (a
= 0; a
< 8; a
++)
256 msgf ("READ (round %i): (hex)%02x (bin)%s (dec)%3i "
257 " (oct)%3o Lochzahl:%4i",
258 round
, buffer
[round
], bin
, buffer
[round
], buffer
[round
], lochzahl
);
260 // msgf ("READ(round %i) (hex)%02x", round, buffer[round]);
265 if (buffer
[round
- 1] == CHAR_END1
)
267 if (buffer
[round
- 1] == CHAR_END2
)
274 //if (blk_size == MAX_BLOCK_SIZE) {
275 // err ("Blocküberlauf");
279 blk_data
= (hw16
*) realloc (blk_data
,(blk_size
+1)* sizeof (hw16
));
280 raw_data
= (unsigned char *) realloc (raw_data
,(blk_size
+1)*3);
281 memcpy(raw_data
+blk_size
*3,buffer
,3);
282 combine466 (buffer
, (unsigned char *) (blk_data
+ blk_size
));
288 while (complete
== 0);
290 msgf ("get_block(): Size: %i", blk_size
);
292 #ifdef DEBUG_STRUCTURE
294 hw16
*l2
= blk_data
+ 1;
295 head0
*head
= (head0
*) blk_data
;
296 msgf ("get_block(): HEAD: %s", bin2str (l1
->value
, 16));
297 msgf ("get_block(): HEAD: %s", bin2str (l2
->value
, 16));
298 msgf ("get_block(): head->T: %i", head
->T
);
299 msgf ("get_block(): head->S: %i", head
->S
);
300 msgf ("get_block(): head->N: %i", head
->N
);
304 if (checksum_error (blk_data
, blk_size
)) {
305 err ("get_block(): Checksummenfehler");
309 dump_data (buffer
, 3);
310 read (inputfd
, buffer
, 3);
311 dump_data (buffer
, 3);
324 msg ("get_block(): Checksumme OK");
326 datablock
*result
= (datablock
*) malloc (sizeof (datablock
));
327 result
->type
= BT_DATA
;
328 result
->data
= blk_data
;
329 result
->raw_data
= raw_data
;
330 result
->size
= blk_size
;
337 /********************************************************/
338 /**********************************************************************/
339 int main (int argc
, char **args
)
342 char *filename
= NULL
;
345 msg ("Verarbeite Kommandozeilenparameter:");
346 for (c
= 1; c
< argc
; c
++) {
347 if ((args
[c
][0] == '-') && (strlen (args
[c
]) > 1)) {
348 char action
= args
[c
][1];
349 //msgf ("Action %c, Arg dazu:%s", action, parm);
367 sayf ("%s [-t] [-S] [-n] [-I] [filename]", args
[0]);
369 sayf (" -t Tape mode. Uses tty device and stops on error.");
370 sayf (" -S Split library tape into separate numbered files");
371 sayf (" -s same as -S but no numbering");
372 sayf (" -I Ignore errors");
373 sayf (" -l be silent");
384 if (filename
!= NULL
) {
385 msgf ("Using file:%s", filename
);
386 inputfd
= open (filename
, O_RDWR
);
389 err ("Sorry, exiting.");
395 err ("Use of console as tape device not allowed! Please specify a suitable device!");
401 msg ("Tapemode aktiviert.");
402 if (!isatty (inputfd
)) {
403 err ("Input file doesn't seem to be a tty.\nNot using tape mode on files!\nQuit.");
408 datablock
*akt_block
;
411 msg ("********************************************************");
412 msgf ("Block no. %5i", blk_no
++);
414 akt_block
= get_block ();
415 if (akt_block
== NULL
) {
416 msg ("Ende der Verarbeitung.");
418 msgf ("Errflag:%i", errflag
);
420 sayf ("** Es gab Fehler.");
425 process_block (akt_block
);
426 if (dosplit
) split(akt_block
);
428 free (akt_block
->data
);
429 free (akt_block
->raw_data
);