6 #include <sys/select.h>
8 #include "hw_helpers.h"
15 #define CHAR_START 0x81
17 #define CHAR_END1 0223
18 #define CHAR_END2 0223
19 #define CHAR_END3 0223
20 #define MAX_BLOCK_SIZE 500
23 #define DEBUG_CHECKSUM
24 #define DEBUG_STRUCTURE
26 //#define IGNORE_CHECKSUM
27 #define HARDCORE_DEBUG
28 /********************************************************/
29 void output (char *string
, int length
);
30 datablock
*get_block ();
32 /********************************************************/
33 char ends
[3] = { CHAR_END1
, CHAR_END2
, CHAR_END3
};
34 int errflag
= 0; // Global error flag
43 /********************************************************/
46 /********************************************************/
47 void dump_data (void *data
, int count
)
49 int fd
= open ("dump", O_RDWR
| O_CREAT
| O_APPEND
, 0666);
51 write (fd
, data
, count
);
55 /********************************************************/
56 void endwarn (int ret
)
59 err ("Unexpected problem in input");
64 /********************************************************/
65 /* Small output things */
66 void err (char *string
)
68 printf ("Error: --> %s\n", string
);
72 void msg (char *string
)
75 printf ("** %s\n", string
);
79 void msgf (char *format
, ...)
82 va_start (ag
, format
);
84 vsprintf (ms
, format
, ag
);
89 void errf (char *format
, ...)
92 va_start (ag
, format
);
94 vsprintf (ms
, format
, ag
);
99 void say (char *string
)
101 if (!silent
) printf ("%s\n", string
);
104 void sayf (char *format
, ...)
107 va_start (ag
, format
);
109 vsprintf (ms
, format
, ag
);
115 /********************************************************/
116 /********************************************************/
118 /********************************************************/
119 /*Block input routines*/
121 unsigned char decode (unsigned char in
)
150 err ("decode(): Impossible case!!!\n");
162 /********************************************************/
163 /********************************************************/
165 void combine466 (unsigned char *raw
, unsigned char *data
)
167 hw16
*result
= (hw16
*) data
;
169 // result->tape.low = 077;
170 unsigned char r1
, r2
, r3
;
172 r1
= decode ((raw
)[0]) & 017;
173 r2
= decode ((raw
)[1]) & 077;
174 r3
= decode ((raw
)[2]) & 077;
176 result
->tape
.high
= r1
;
177 result
->tape
.mid
= r2
;
178 result
->tape
.low
= r3
;
181 msgf ("combine466 (data) : %02x %02x %02x",r1
,r2
,r3
, 6);
182 // msgf ("combine466 (rawmem) : %s%s", bin2str (data[1], 8),
183 // bin2str (data[0], 8));
184 msgf ("combine466 (structure): %s", bin2str (result
->value
, 16));
188 /*********************************************************************/
189 /*********************************************************************/
190 int checksum_error (hw16
* data
, int size
)
192 unsigned short int checksumme
= 0;
194 for (c
= 0; c
< (size
- 1); c
++) {
195 checksumme
^= data
[c
].value
;
196 #ifdef DEBUG_CHECKSUM
197 msgf ("checksum_error(): Gelesen:%04x Berechnet:%04x",
198 data
[c
+ 1].value
, checksumme
);
199 if (data
[c
+ 1].value
== checksumme
)
200 msg ("checksum_error (): Treffer.");
203 #ifdef DEBUG_CHECKSUM
204 msgf ("checksum_error(): Gelesen:%04x Berechnet:%04x",
205 data
[size
- 1].value
, checksumme
);
207 if (data
[size
- 1].value
!= checksumme
)
212 /********************************************************/
213 datablock
*get_block()
215 int blk_size
, round
, ret
, found
, complete
;
216 unsigned char buffer
[3];
218 unsigned char *raw_data
;
223 read_pos
+=ret
=read (inputfd
, buffer
, 1);
225 #ifdef HARDCORE_DEBUG
226 msgf ("READ : (hex)%02x (bin)%s (dec)%3i (oct)%3o",
227 buffer
[0], bin2str (buffer
[0], 8), buffer
[0], buffer
[0]);
230 msg ("get_block(): Nichts mehr zu lesen");
234 if (buffer
[0]==0x83){
235 datablock
*result
= (datablock
*) malloc (sizeof (datablock
));
236 result
->type
= BT_STOP
;
238 result
->raw_data
= NULL
;
243 } while (*buffer
!= (unsigned char) CHAR_START
);
246 msg ("get_block(): Blockstart erkannt");
248 // blk_data = (hw16 *) malloc (MAX_BLOCK_SIZE * sizeof (hw16));
256 ret
= read (inputfd
, buffer
+ round
, 1);
258 #ifdef HARDCORE_DEBUG
259 static int lochzahl
= 0;
260 char *bin
= bin2str (buffer
[round
], 8);
262 for (a
= 0; a
< 8; a
++)
265 msgf ("READ (round %i): (hex)%02x (bin)%s (dec)%3i "
266 " (oct)%3o Lochzahl:%4i",
267 round
, buffer
[round
], bin
, buffer
[round
], buffer
[round
], lochzahl
);
269 // msgf ("READ(round %i) (hex)%02x", round, buffer[round]);
274 if (buffer
[round
- 1] == CHAR_END1
)
276 if (buffer
[round
- 1] == CHAR_END2
)
283 //if (blk_size == MAX_BLOCK_SIZE) {
284 // err ("Blocküberlauf");
288 blk_data
= (hw16
*) realloc (blk_data
,(blk_size
+1)* sizeof (hw16
));
289 raw_data
= (unsigned char *) realloc (raw_data
,(blk_size
+1)*3);
290 memcpy(raw_data
+blk_size
*3,buffer
,3);
291 combine466 (buffer
, (unsigned char *) (blk_data
+ blk_size
));
297 while (complete
== 0);
299 msgf ("get_block(): Size: %i", blk_size
);
301 #ifdef DEBUG_STRUCTURE
303 hw16
*l2
= blk_data
+ 1;
304 head0
*head
= (head0
*) blk_data
;
305 msgf ("get_block(): HEAD: %s", bin2str (l1
->value
, 16));
306 msgf ("get_block(): HEAD: %s", bin2str (l2
->value
, 16));
307 msgf ("get_block(): head->T: %i", head
->T
);
308 msgf ("get_block(): head->S: %i", head
->S
);
309 msgf ("get_block(): head->N: %i", head
->N
);
313 if (checksum_error (blk_data
, blk_size
)) {
314 errf ("get_block(): Checksum error!\nBlock start: %i (0x%x), read address %i (0x%x).",
315 block_pos
,block_pos
,read_pos
,read_pos
);
319 dump_data (buffer
, 3);
320 read_pos
+=read (inputfd
, buffer
, 3);
321 dump_data (buffer
, 3);
334 msg ("get_block(): Checksumme OK");
336 datablock
*result
= (datablock
*) malloc (sizeof (datablock
));
337 result
->type
= BT_DATA
;
338 result
->data
= blk_data
;
339 result
->raw_data
= raw_data
;
340 result
->size
= blk_size
;
347 /********************************************************/
348 /**********************************************************************/
349 int main (int argc
, char **args
)
352 char *filename
= NULL
;
355 msg ("Verarbeite Kommandozeilenparameter:");
356 for (c
= 1; c
< argc
; c
++) {
357 if ((args
[c
][0] == '-') && (strlen (args
[c
]) > 1)) {
358 char action
= args
[c
][1];
359 //msgf ("Action %c, Arg dazu:%s", action, parm);
377 sayf ("%s [-t] [-S] [-n] [-I] [filename]", args
[0]);
379 sayf (" -t Tape mode. Uses tty device and stops on error.");
380 sayf (" -S Split library tape into separate numbered files");
381 sayf (" -s same as -S but no numbering");
382 sayf (" -I Ignore errors");
383 sayf (" -l be silent");
394 if (filename
!= NULL
) {
395 msgf ("Using file:%s", filename
);
396 inputfd
= open (filename
, O_RDWR
);
399 err ("Sorry, exiting.");
405 err ("Use of console as tape device not allowed! Please specify a suitable device!");
411 msg ("Tapemode aktiviert.");
412 if (!isatty (inputfd
)) {
413 err ("Input file doesn't seem to be a tty.\nNot using tape mode on files!\nQuit.");
418 datablock
*akt_block
;
420 /* Initialize read position */
424 msg ("********************************************************");
425 msgf ("Block no. %5i", blk_no
++);
427 akt_block
= get_block ();
428 if (akt_block
== NULL
) {
429 msg ("Ende der Verarbeitung.");
431 msgf ("Errflag:%i", errflag
);
433 sayf ("** Es gab Fehler.");
438 process_block (akt_block
);
439 if (dosplit
) split(akt_block
);
441 free (akt_block
->data
);
442 free (akt_block
->raw_data
);