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
38 /********************************************************/
41 /********************************************************/
42 void dump_data (void *data
, int count
)
44 int fd
= open ("dump", O_RDWR
| O_CREAT
| O_APPEND
, 0666);
46 write (fd
, data
, count
);
50 /********************************************************/
51 void endwarn (int ret
)
54 err ("Unexpected problem in input");
59 /********************************************************/
60 /* Small output things */
61 void err (char *string
)
63 printf ("Error: --> %s\n", string
);
67 void msg (char *string
)
70 printf ("** %s\n", string
);
74 void msgf (char *format
, ...)
77 va_start (ag
, format
);
79 vsprintf (ms
, format
, ag
);
84 void errf (char *format
, ...)
87 va_start (ag
, format
);
89 vsprintf (ms
, format
, ag
);
94 void say (char *string
)
96 if (!silent
) printf ("%s\n", string
);
99 void sayf (char *format
, ...)
102 va_start (ag
, format
);
104 vsprintf (ms
, format
, ag
);
110 /********************************************************/
111 /********************************************************/
113 /********************************************************/
114 /*Block input routines*/
116 unsigned char decode (unsigned char in
)
145 err ("decode(): Impossible case!!!\n");
157 /********************************************************/
158 /********************************************************/
160 void combine466 (unsigned char *raw
, unsigned char *data
)
162 hw16
*result
= (hw16
*) data
;
164 // result->tape.low = 077;
165 unsigned char r1
, r2
, r3
;
167 r1
= decode ((raw
)[0]) & 017;
168 r2
= decode ((raw
)[1]) & 077;
169 r3
= decode ((raw
)[2]) & 077;
171 result
->tape
.high
= r1
;
172 result
->tape
.mid
= r2
;
173 result
->tape
.low
= r3
;
176 msgf ("combine466 (data) : %s%s%s", bin2str (r1
, 4), bin2str (r2
, 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
);