Große Umstellung. Viel hinzugefügt.
[h316.git] / pc-tools / ldc / ldc.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <fcntl.h>
5 #include <stdarg.h>
6 #include <sys/select.h>
7 #include "hw_types.h"
8 #include "hw_helpers.h"
9 #define XON 0x11
10 #define XOFF 0x13
11 #define CHAR_START 0x81
12 // 0x93
13 #define CHAR_END1 0223
14 #define CHAR_END2 0223
15 #define CHAR_END3 0223
16 #define MAX_BLOCK_SIZE 500
17
18 //#define DEBUG
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 ();
26
27 /********************************************************/
28 char ends[3] = { CHAR_END1, CHAR_END2, CHAR_END3 };
29 int errflag = 0; // Global error flag
30 int tapemode = 0;
31 int inputfd;
32 int ignore = 0;
33 int dosplit = 0;
34 int splitnum = 0;
35 /********************************************************/
36
37
38 /********************************************************/
39 void dump_data (void *data, int count)
40 {
41 int fd = open ("dump", O_RDWR | O_CREAT | O_APPEND, 0666);
42 write (fd, "***", 3);
43 write (fd, data, count);
44 close (fd);
45 }
46
47 /********************************************************/
48 void endwarn (int ret)
49 {
50 if (ret < 1) {
51 err ("Unexpected problem in input");
52 exit (3);
53 }
54 }
55
56 /********************************************************/
57 /* Small output things */
58 void err (char *string)
59 {
60 printf ("Error: --> %s\n", string);
61 errflag++;
62 }
63
64 void msg (char *string)
65 {
66 #ifdef DEBUG
67 printf ("** %s\n", string);
68 #endif
69 }
70
71 void msgf (char *format, ...)
72 {
73 va_list ag;
74 va_start (ag, format);
75 char ms[100];
76 vsprintf (ms, format, ag);
77 msg (ms);
78 va_end (ag);
79 }
80
81 void errf (char *format, ...)
82 {
83 va_list ag;
84 va_start (ag, format);
85 char ms[100];
86 vsprintf (ms, format, ag);
87 err (ms);
88 va_end (ag);
89 }
90
91 void say (char *string)
92 {
93 printf ("%s\n", string);
94 }
95
96 void sayf (char *format, ...)
97 {
98 va_list ag;
99 va_start (ag, format);
100 char ms[100];
101 vsprintf (ms, format, ag);
102 say (ms);
103 va_end (ag);
104 }
105
106
107 /********************************************************/
108 /********************************************************/
109
110 /********************************************************/
111 /*Block input routines*/
112
113 unsigned char decode (unsigned char in)
114 {
115 if (in & 64)
116 switch (in) {
117 case 0174:
118 return 05;
119 break;
120 case 0374:
121 return 045;
122 break;
123 case 0175:
124 return 012;
125 break;
126 case 0375:
127 return 052;
128 break;
129 case 0176:
130 return 021;
131 break;
132 case 0376:
133 return 061;
134 break;
135 case 0177:
136 return 023;
137 break;
138 case 0377:
139 return 063;
140 break;
141 default:
142 err ("decode(): Impossible case!!!\n");
143 return 0;
144 break;
145 } else {
146 if (in & 128)
147 in |= 32;
148 return in;
149 }
150
151 return 0;
152 }
153
154 /********************************************************/
155 /********************************************************/
156
157 void combine466 (unsigned char *raw, unsigned char *data)
158 {
159 hw16 *result = (hw16 *) data;
160
161 // result->tape.low = 077;
162 unsigned char r1, r2, r3;
163
164 r1 = decode ((raw)[0]) & 017;
165 r2 = decode ((raw)[1]) & 077;
166 r3 = decode ((raw)[2]) & 077;
167
168 result->tape.high = r1;
169 result->tape.mid = r2;
170 result->tape.low = r3;
171
172 #ifdef DEBUG_COMBINE
173 msgf ("combine466 (data) : %s%s%s", bin2str (r1, 4), bin2str (r2, 6),
174 bin2str (r3, 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));
178 #endif
179 }
180
181 /*********************************************************************/
182 /*********************************************************************/
183 int checksum_error (hw16 * data, int size)
184 {
185 unsigned short int checksumme = 0;
186 int c;
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.");
194 #endif
195 }
196 #ifdef DEBUG_CHECKSUM
197 msgf ("checksum_error(): Gelesen:%04x Berechnet:%04x",
198 data[size - 1].value, checksumme);
199 #endif
200 if (data[size - 1].value != checksumme)
201 return 1;
202 return 0;
203 }
204
205 /********************************************************/
206 datablock *get_block()
207 {
208 int blk_size, round, ret, found, complete;
209 unsigned char buffer[3];
210 hw16 *blk_data;
211 unsigned char *raw_data;
212
213 if (tapemode)
214 tapestart ();
215 do {
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]);
220 #endif
221 if (ret < 1) {
222 msg ("get_block(): Nichts mehr zu lesen");
223 return NULL;
224 }
225
226 if (buffer[0]==0x83){
227 datablock *result = (datablock *) malloc (sizeof (datablock));
228 result->type = BT_STOP;
229 result->data = NULL;
230 result->raw_data = NULL;
231 result->size = 0;
232 return result;
233 }
234
235 } while (*buffer != (unsigned char) CHAR_START);
236
237 msg ("get_block(): Blockstart erkannt");
238
239 // blk_data = (hw16 *) malloc (MAX_BLOCK_SIZE * sizeof (hw16));
240 blk_data=NULL;
241 raw_data=NULL;
242 round = 0;
243 blk_size = 0;
244
245 do {
246 complete = 0;
247 ret = read (inputfd, buffer + round, 1);
248 #ifdef HARDCORE_DEBUG
249 static int lochzahl = 0;
250 char *bin = bin2str (buffer[round], 8);
251 int a;
252 for (a = 0; a < 8; a++)
253 if (bin[a] == '1')
254 lochzahl++;
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);
258
259 // msgf ("READ(round %i) (hex)%02x", round, buffer[round]);
260 #endif
261 endwarn (ret);
262 round++;
263 found = 0;
264 if (buffer[round - 1] == CHAR_END1)
265 found++;
266 if (buffer[round - 1] == CHAR_END2)
267 found++;
268
269 if (found) {
270 complete++;
271 } else {
272 if (round == 3) {
273 //if (blk_size == MAX_BLOCK_SIZE) {
274 // err ("Blocküberlauf");
275 // free (blk_data);
276 // exit (4);
277 //}
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));
282 blk_size++;
283 round = 0;
284 }
285 }
286 }
287 while (complete == 0);
288
289 msgf ("get_block(): Size: %i", blk_size);
290
291 #ifdef DEBUG_STRUCTURE
292 hw16 *l1 = blk_data;
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);
300 #endif
301
302
303 if (checksum_error (blk_data, blk_size)) {
304 err ("get_block(): Checksummenfehler");
305
306
307 #ifdef CHECKSUM_DUMP
308 dump_data (buffer, 3);
309 read (inputfd, buffer, 3);
310 dump_data (buffer, 3);
311 #endif
312
313 if (tapemode) {
314 tapestop ();
315 sleep (15);
316 tapestart ();
317 } else {
318 if (!ignore)
319 exit (4);
320 }
321
322 } else
323 msg ("get_block(): Checksumme OK");
324
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;
330
331 if (tapemode)
332 tapestop ();
333 return result;
334 }
335
336 /********************************************************/
337 /**********************************************************************/
338 int main (int argc, char **args)
339 {
340 int c;
341 char *filename = NULL;
342 int blk_no = 0;
343
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);
349 switch (action) {
350 case 'I':
351 ignore++;
352 break;
353 case 't':
354 tapemode++;
355 break;
356 case 'S':
357 splitnum++;
358 case 's':
359 dosplit++;
360 break;
361 default:
362 say ("Usage:\n");
363 sayf ("%s [-t] [-S] [-n] [-I] [filename]", args[0]);
364 sayf ("");
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");
369 sayf ("");
370 exit (1);
371 break;
372 }
373 } else {
374 filename = args[c];
375 }
376 }
377
378 //Use file?
379 if (filename != NULL) {
380 msgf ("Using file:%s", filename);
381 inputfd = open (filename, O_RDWR);
382 if (inputfd < 0) {
383 perror ("File");
384 err ("Sorry, exiting.");
385 exit (3);
386 }
387 } else {
388 inputfd = 0;
389 if (tapemode) {
390 err ("Use of console as tape device not allowed! Please specify a suitable device!");
391 exit(1);
392 }
393 }
394
395 if (tapemode) {
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.");
399 exit (1);
400 }
401 tapeinit (inputfd);
402 }
403 datablock *akt_block;
404
405 while (1) {
406 msg ("********************************************************");
407 msgf ("Block no. %5i", blk_no++);
408
409 akt_block = get_block ();
410 if (akt_block == NULL) {
411 msg ("Ende der Verarbeitung.");
412
413 msgf ("Errflag:%i", errflag);
414 if (errflag)
415 sayf ("** Es gab Fehler.");
416 exit (0);
417 }
418 // Verarbeitung hier
419
420 process_block (akt_block);
421 if (dosplit) split(akt_block);
422
423 free (akt_block->data);
424 free (akt_block->raw_data);
425 free (akt_block);
426 } // Endlosschleife
427 } //main();
428
429 // end.