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
35 /********************************************************/
38 /********************************************************/
39 void dump_data (void *data
, int count
)
41 int fd
= open ("dump", O_RDWR
| O_CREAT
| O_APPEND
, 0666);
43 write (fd
, data
, count
);
47 /********************************************************/
48 void endwarn (int ret
)
51 err ("Unexpected problem in input");
56 /********************************************************/
57 /* Small output things */
58 void err (char *string
)
60 printf ("Error: --> %s\n", string
);
64 void msg (char *string
)
67 printf ("** %s\n", string
);
71 void msgf (char *format
, ...)
74 va_start (ag
, format
);
76 vsprintf (ms
, format
, ag
);
81 void errf (char *format
, ...)
84 va_start (ag
, format
);
86 vsprintf (ms
, format
, ag
);
91 void say (char *string
)
93 printf ("%s\n", string
);
96 void sayf (char *format
, ...)
99 va_start (ag
, format
);
101 vsprintf (ms
, format
, ag
);
107 /********************************************************/
108 /********************************************************/
110 /********************************************************/
111 /*Block input routines*/
113 unsigned char decode (unsigned char in
)
142 err ("decode(): Impossible case!!!\n");
154 /********************************************************/
155 /********************************************************/
157 void combine466 (unsigned char *raw
, unsigned char *data
)
159 hw16
*result
= (hw16
*) data
;
161 // result->tape.low = 077;
162 unsigned char r1
, r2
, r3
;
164 r1
= decode ((raw
)[0]) & 017;
165 r2
= decode ((raw
)[1]) & 077;
166 r3
= decode ((raw
)[2]) & 077;
168 result
->tape
.high
= r1
;
169 result
->tape
.mid
= r2
;
170 result
->tape
.low
= r3
;
173 msgf ("combine466 (data) : %s%s%s", bin2str (r1
, 4), bin2str (r2
, 6),
175 msgf ("combine466 (rawmem) : %s%s", bin2str (data
[1], 8),
176 bin2str (data
[0], 8));
177 msgf ("combine466 (structure): %s", bin2str (result
->value
, 16));
181 /*********************************************************************/
182 /*********************************************************************/
183 int checksum_error (hw16
* data
, int size
)
185 unsigned short int checksumme
= 0;
187 for (c
= 0; c
< (size
- 1); c
++) {
188 checksumme
^= data
[c
].value
;
189 #ifdef DEBUG_CHECKSUM
190 msgf ("checksum_error(): Gelesen:%04x Berechnet:%04x",
191 data
[c
+ 1].value
, checksumme
);
192 if (data
[c
+ 1].value
== checksumme
)
193 msg ("checksum_error (): Treffer.");
196 #ifdef DEBUG_CHECKSUM
197 msgf ("checksum_error(): Gelesen:%04x Berechnet:%04x",
198 data
[size
- 1].value
, checksumme
);
200 if (data
[size
- 1].value
!= checksumme
)
205 /********************************************************/
206 datablock
*get_block()
208 int blk_size
, round
, ret
, found
, complete
;
209 unsigned char buffer
[3];
211 unsigned char *raw_data
;
216 ret
= read (inputfd
, buffer
, 1);
217 #ifdef HARDCORE_DEBUG
218 msgf ("READ : (hex)%02x (bin)%s (dec)%3i (oct)%3o",
219 buffer
[0], bin2str (buffer
[0], 8), buffer
[0], buffer
[0]);
222 msg ("get_block(): Nichts mehr zu lesen");
226 if (buffer
[0]==0x83){
227 datablock
*result
= (datablock
*) malloc (sizeof (datablock
));
228 result
->type
= BT_STOP
;
230 result
->raw_data
= NULL
;
235 } while (*buffer
!= (unsigned char) CHAR_START
);
237 msg ("get_block(): Blockstart erkannt");
239 // blk_data = (hw16 *) malloc (MAX_BLOCK_SIZE * sizeof (hw16));
247 ret
= read (inputfd
, buffer
+ round
, 1);
248 #ifdef HARDCORE_DEBUG
249 static int lochzahl
= 0;
250 char *bin
= bin2str (buffer
[round
], 8);
252 for (a
= 0; a
< 8; a
++)
255 msgf ("READ (round %i): (hex)%02x (bin)%s (dec)%3i "
256 " (oct)%3o Lochzahl:%4i",
257 round
, buffer
[round
], bin
, buffer
[round
], buffer
[round
], lochzahl
);
259 // msgf ("READ(round %i) (hex)%02x", round, buffer[round]);
264 if (buffer
[round
- 1] == CHAR_END1
)
266 if (buffer
[round
- 1] == CHAR_END2
)
273 //if (blk_size == MAX_BLOCK_SIZE) {
274 // err ("Blocküberlauf");
278 blk_data
= (hw16
*) realloc (blk_data
,(blk_size
+1)* sizeof (hw16
));
279 raw_data
= (unsigned char *) realloc (raw_data
,(blk_size
+1)*3);
280 memcpy(raw_data
+blk_size
*3,buffer
,3);
281 combine466 (buffer
, (unsigned char *) (blk_data
+ blk_size
));
287 while (complete
== 0);
289 msgf ("get_block(): Size: %i", blk_size
);
291 #ifdef DEBUG_STRUCTURE
293 hw16
*l2
= blk_data
+ 1;
294 head0
*head
= (head0
*) blk_data
;
295 msgf ("get_block(): HEAD: %s", bin2str (l1
->value
, 16));
296 msgf ("get_block(): HEAD: %s", bin2str (l2
->value
, 16));
297 msgf ("get_block(): head->T: %i", head
->T
);
298 msgf ("get_block(): head->S: %i", head
->S
);
299 msgf ("get_block(): head->N: %i", head
->N
);
303 if (checksum_error (blk_data
, blk_size
)) {
304 err ("get_block(): Checksummenfehler");
308 dump_data (buffer
, 3);
309 read (inputfd
, buffer
, 3);
310 dump_data (buffer
, 3);
323 msg ("get_block(): Checksumme OK");
325 datablock
*result
= (datablock
*) malloc (sizeof (datablock
));
326 result
->type
= BT_DATA
;
327 result
->data
= blk_data
;
328 result
->raw_data
= raw_data
;
329 result
->size
= blk_size
;
336 /********************************************************/
337 /**********************************************************************/
338 int main (int argc
, char **args
)
341 char *filename
= NULL
;
344 msg ("Verarbeite Kommandozeilenparameter:");
345 for (c
= 1; c
< argc
; c
++) {
346 if ((args
[c
][0] == '-') && (strlen (args
[c
]) > 1)) {
347 char action
= args
[c
][1];
348 //msgf ("Action %c, Arg dazu:%s", action, parm);
363 sayf ("%s [-t] [-S] [-n] [-I] [filename]", args
[0]);
365 sayf (" -t Tape mode. Uses tty device and stops on error.");
366 sayf (" -S Split library tape into separate numbered files");
367 sayf (" -s same as -S but no numbering");
368 sayf (" -I Ignore errors");
379 if (filename
!= NULL
) {
380 msgf ("Using file:%s", filename
);
381 inputfd
= open (filename
, O_RDWR
);
384 err ("Sorry, exiting.");
390 err ("Use of console as tape device not allowed! Please specify a suitable device!");
396 msg ("Tapemode aktiviert.");
397 if (!isatty (inputfd
)) {
398 err ("Input file doesn't seem to be a tty.\nNot using tape mode on files!\nQuit.");
403 datablock
*akt_block
;
406 msg ("********************************************************");
407 msgf ("Block no. %5i", blk_no
++);
409 akt_block
= get_block ();
410 if (akt_block
== NULL
) {
411 msg ("Ende der Verarbeitung.");
413 msgf ("Errflag:%i", errflag
);
415 sayf ("** Es gab Fehler.");
420 process_block (akt_block
);
421 if (dosplit
) split(akt_block
);
423 free (akt_block
->data
);
424 free (akt_block
->raw_data
);