Commit | Line | Data |
---|---|---|
196ba1fc PH |
1 | /*\r |
2 | * (C) Copyright 2002, Brian Knittel.\r | |
3 | * You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN\r | |
4 | * RISK basis, there is no warranty of fitness for any purpose, and the rest of the\r | |
5 | * usual yada-yada. Please keep this notice and the copyright in any distributions\r | |
6 | * or modifications.\r | |
7 | *\r | |
8 | * This is not a supported product, but I welcome bug reports and fixes.\r | |
9 | * Mail to sim@ibm1130.org\r | |
10 | */\r | |
11 | \r | |
12 | // ---------------------------------------------------------------------------------\r | |
13 | // BINDUMP - dumps card deck files in assembler object format\r | |
14 | //\r | |
15 | // Usage:\r | |
16 | /// bindump deckfile lists object header info & sector break cards\r | |
17 | // bindump -v deckfile lists object data records as well\r | |
18 | // bindump -p deckfile for system program, lists phase IDs in the deck\r | |
19 | // bindump -s deckfile >outfile for system program, sorts the phases & writes to stdout\r | |
20 | \r | |
21 | #include <stdio.h>\r | |
22 | #include <stdlib.h>\r | |
23 | #ifdef _WIN32\r | |
24 | # include <windows.h>\r | |
25 | # include <io.h>\r | |
26 | # include <fcntl.h>\r | |
27 | #endif\r | |
28 | \r | |
29 | #include "util_io.h"\r | |
30 | \r | |
31 | #ifndef TRUE\r | |
32 | #define BOOL int\r | |
33 | #define TRUE 1\r | |
34 | #define FALSE 0\r | |
35 | #endif\r | |
36 | \r | |
37 | typedef enum {R_ABSOLUTE = 0, R_RELATIVE = 1, R_LIBF = 2, R_CALL = 3} RELOC;\r | |
38 | \r | |
39 | BOOL verbose = FALSE;\r | |
40 | BOOL phid = FALSE;\r | |
41 | BOOL sort = FALSE;\r | |
42 | unsigned short card[80], buf[54], cardtype;\r | |
43 | \r | |
44 | // bindump - dump a binary (card format) deck to verify sbrks, etc\r | |
45 | \r | |
46 | void bail (char *msg);\r | |
47 | void dump (char *fname);\r | |
48 | void dump_data (char *fname);\r | |
49 | void dump_phids (char *fname);\r | |
50 | char *getname (unsigned short *ptr);\r | |
51 | char *getseq (void);\r | |
52 | int hollerith_to_ascii (unsigned short h);\r | |
53 | void process (char *fname);\r | |
54 | void show_raw (char *name);\r | |
55 | void show_data (void);\r | |
56 | void show_core (void);\r | |
57 | void show_endc (void);\r | |
58 | void show_81 (void);\r | |
59 | void show_main (void);\r | |
60 | void show_sub (void);\r | |
61 | void show_ils (void);\r | |
62 | void show_iss (void);\r | |
63 | void show_end (void);\r | |
64 | void sort_phases (char *fname);\r | |
65 | void trim (char *s);\r | |
66 | void unpack (unsigned short *card, unsigned short *buf);\r | |
67 | void verify_checksum(unsigned short *buf);\r | |
68 | \r | |
69 | int main (int argc, char **argv)\r | |
70 | {\r | |
71 | char *arg;\r | |
72 | static char usestr[] = "Usage: bindump [-psv] filename...";\r | |
73 | int i;\r | |
74 | \r | |
75 | for (i = 1; i < argc; i++) {\r | |
76 | arg = argv[i];\r | |
77 | if (*arg == '-') {\r | |
78 | arg++;\r | |
79 | while (*arg) {\r | |
80 | switch (*arg++) {\r | |
81 | case 'v':\r | |
82 | verbose = TRUE;\r | |
83 | break;\r | |
84 | case 'p':\r | |
85 | phid = TRUE; // print only phase ID's\r | |
86 | break;\r | |
87 | case 's':\r | |
88 | sort = TRUE; // sort deck by phases, writing to stdout\r | |
89 | break;\r | |
90 | default:\r | |
91 | bail(usestr);\r | |
92 | }\r | |
93 | }\r | |
94 | }\r | |
95 | }\r | |
96 | \r | |
97 | for (i = 1; i < argc; i++) {\r | |
98 | arg = argv[i];\r | |
99 | if (*arg != '-')\r | |
100 | process(arg);\r | |
101 | }\r | |
102 | return 0;\r | |
103 | }\r | |
104 | \r | |
105 | void process (char *nm)\r | |
106 | {\r | |
107 | #ifdef _WIN32\r | |
108 | WIN32_FIND_DATA fd;\r | |
109 | HANDLE hFind;\r | |
110 | char *c, buf[256];\r | |
111 | \r | |
112 | if (strchr(nm, '*') == NULL && strchr(nm, '?') == NULL)\r | |
113 | dump(nm);\r | |
114 | \r | |
115 | else if ((hFind = FindFirstFile(nm, &fd)) == INVALID_HANDLE_VALUE)\r | |
116 | fprintf(stderr, "No files matching '%s'\n", nm);\r | |
117 | \r | |
118 | else {\r | |
119 | if ((c = strrchr(nm, '\\')) == NULL)\r | |
120 | c = strrchr(nm, ':');\r | |
121 | \r | |
122 | do {\r | |
123 | if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)\r | |
124 | continue;\r | |
125 | \r | |
126 | if (c == NULL)\r | |
127 | dump(fd.cFileName);\r | |
128 | else {\r | |
129 | strcpy(buf, nm);\r | |
130 | strcpy(buf + (c-nm+1), fd.cFileName);\r | |
131 | dump(buf);\r | |
132 | }\r | |
133 | \r | |
134 | } while (FindNextFile(hFind, &fd));\r | |
135 | \r | |
136 | FindClose(hFind);\r | |
137 | }\r | |
138 | #else\r | |
139 | dump(nm); // on unices, sh globs for us\r | |
140 | #endif\r | |
141 | }\r | |
142 | \r | |
143 | void dump (char *fname)\r | |
144 | {\r | |
145 | if (sort)\r | |
146 | sort_phases(fname);\r | |
147 | else if (phid)\r | |
148 | dump_phids(fname);\r | |
149 | else\r | |
150 | dump_data(fname);\r | |
151 | }\r | |
152 | \r | |
153 | struct tag_card {\r | |
154 | int phid, seq;\r | |
155 | unsigned short card[80];\r | |
156 | };\r | |
157 | \r | |
158 | int cardcomp (const void *a, const void *b)\r | |
159 | {\r | |
160 | short diff;\r | |
161 | \r | |
162 | diff = ((struct tag_card *) a)->phid - ((struct tag_card *) b)->phid;\r | |
163 | \r | |
164 | return diff ? diff : (((struct tag_card *) a)->seq - ((struct tag_card *) b)->seq);\r | |
165 | }\r | |
166 | \r | |
167 | void sort_phases (char *fname)\r | |
168 | {\r | |
169 | int i, ncards, cardtype, len, seq = 0, phid;\r | |
170 | struct tag_card *deck;\r | |
171 | FILE *fd;\r | |
172 | BOOL saw_sbrk = TRUE;\r | |
173 | \r | |
174 | if ((fd = fopen(fname, "rb")) == NULL) {\r | |
175 | perror(fname);\r | |
176 | return;\r | |
177 | }\r | |
178 | \r | |
179 | fseek(fd, 0, SEEK_END);\r | |
180 | len = ftell(fd); // get length of file\r | |
181 | fseek(fd, 0, SEEK_SET);\r | |
182 | \r | |
183 | if (len <= 0 || (len % 160) != 0) {\r | |
184 | fprintf(stderr, "%s is not a binard deck image\n");\r | |
185 | fclose(fd);\r | |
186 | return;\r | |
187 | }\r | |
188 | \r | |
189 | ncards = len / 160;\r | |
190 | \r | |
191 | if ((deck = (struct tag_card *) malloc(ncards*sizeof(struct tag_card))) == NULL) {\r | |
192 | fprintf(stderr, "%s: can't sort, insufficient memory\n");\r | |
193 | fclose(fd);\r | |
194 | return;\r | |
195 | }\r | |
196 | \r | |
197 | phid = 0;\r | |
198 | for (i = 0; i < ncards; i++) {\r | |
199 | if (fxread(deck[i].card, sizeof(card[0]), 80, fd) != 80) {\r | |
200 | free(deck);\r | |
201 | fprintf(stderr, "%s: error reading deck\n");\r | |
202 | fclose(fd);\r | |
203 | return;\r | |
204 | }\r | |
205 | \r | |
206 | unpack(deck[i].card, buf);\r | |
207 | deck[i].seq = seq++;\r | |
208 | deck[i].phid = phid;\r | |
209 | \r | |
210 | verify_checksum(buf);\r | |
211 | \r | |
212 | cardtype = (buf[2] >> 8) & 0xFF;\r | |
213 | \r | |
214 | if (cardtype == 1 || cardtype == 2) { // start of deck is same as sector break\r | |
215 | saw_sbrk = TRUE;\r | |
216 | }\r | |
217 | else if (cardtype == 0) {\r | |
218 | fprintf(stderr, "%s is a core image deck\n");\r | |
219 | free(deck);\r | |
220 | fclose(fd);\r | |
221 | return;\r | |
222 | }\r | |
223 | else if (cardtype == 0x0A && saw_sbrk) {\r | |
224 | phid = (int) (signed short) buf[10];\r | |
225 | if (phid < 0)\r | |
226 | phid = -phid;\r | |
227 | \r | |
228 | deck[i].phid = phid; // this belongs to the new phase\r | |
229 | deck[i-1].phid = phid; // as does previous card\r | |
230 | saw_sbrk = FALSE;\r | |
231 | }\r | |
232 | }\r | |
233 | fclose(fd);\r | |
234 | \r | |
235 | qsort(deck, ncards, sizeof(struct tag_card), cardcomp); // sort the deck\r | |
236 | \r | |
237 | #ifdef _WIN32\r | |
238 | _setmode(_fileno(stdout), _O_BINARY); // set standard output to binary mode\r | |
239 | #endif\r | |
240 | \r | |
241 | for (i = 0; i < ncards; i++) // write to stdout\r | |
242 | fxwrite(deck[i].card, sizeof(card[0]), 80, stdout);\r | |
243 | \r | |
244 | free(deck);\r | |
245 | }\r | |
246 | \r | |
247 | void dump_phids (char *fname)\r | |
248 | {\r | |
249 | FILE *fp;\r | |
250 | BOOL first = TRUE;\r | |
251 | BOOL saw_sbrk = TRUE, neg;\r | |
252 | short id;\r | |
253 | \r | |
254 | if ((fp = fopen(fname, "rb")) == NULL) {\r | |
255 | perror(fname);\r | |
256 | return;\r | |
257 | }\r | |
258 | \r | |
259 | printf("\n%s:\n", fname);\r | |
260 | \r | |
261 | while (fxread(card, sizeof(card[0]), 80, fp) > 0) {\r | |
262 | unpack(card, buf);\r | |
263 | verify_checksum(buf);\r | |
264 | \r | |
265 | cardtype = (buf[2] >> 8) & 0xFF;\r | |
266 | \r | |
267 | if (cardtype == 1 && ! first) { // sector break\r | |
268 | saw_sbrk = TRUE;\r | |
269 | continue;\r | |
270 | }\r | |
271 | else {\r | |
272 | switch (cardtype) {\r | |
273 | case 0x00:\r | |
274 | printf(" This is a core image deck\n");\r | |
275 | goto done;\r | |
276 | break;\r | |
277 | case 0x01:\r | |
278 | case 0x02:\r | |
279 | case 0x03:\r | |
280 | case 0x04:\r | |
281 | case 0x05:\r | |
282 | case 0x06:\r | |
283 | case 0x07:\r | |
284 | case 0x0F:\r | |
285 | break;\r | |
286 | \r | |
287 | case 0x0A:\r | |
288 | if (saw_sbrk) {\r | |
289 | id = buf[10];\r | |
290 | if (id < 0)\r | |
291 | id = -id, neg = TRUE;\r | |
292 | else\r | |
293 | neg = FALSE;\r | |
294 | printf(" : %3d / %02x%s\n", id, id, neg ? " (neg)" : "");\r | |
295 | saw_sbrk = FALSE;\r | |
296 | }\r | |
297 | break;\r | |
298 | \r | |
299 | default:\r | |
300 | show_raw("??? ");\r | |
301 | }\r | |
302 | }\r | |
303 | done:\r | |
304 | first = FALSE;\r | |
305 | }\r | |
306 | \r | |
307 | fclose(fp);\r | |
308 | }\r | |
309 | \r | |
310 | void dump_data (char *fname)\r | |
311 | {\r | |
312 | FILE *fp;\r | |
313 | BOOL first = TRUE;\r | |
314 | char str[80];\r | |
315 | int i;\r | |
316 | \r | |
317 | if ((fp = fopen(fname, "rb")) == NULL) {\r | |
318 | perror(fname);\r | |
319 | return;\r | |
320 | }\r | |
321 | \r | |
322 | printf("\n%s:\n", fname);\r | |
323 | \r | |
324 | while (fxread(card, sizeof(card[0]), 80, fp) > 0) {\r | |
325 | unpack(card, buf);\r | |
326 | verify_checksum(buf);\r | |
327 | \r | |
328 | cardtype = (buf[2] >> 8) & 0xFF;\r | |
329 | \r | |
330 | if (cardtype == 1 && ! first) { // sector break\r | |
331 | for (i = 4; i < 72; i++)\r | |
332 | str[i] = hollerith_to_ascii(card[i]);\r | |
333 | \r | |
334 | str[i] = '\0';\r | |
335 | trim(str+4);\r | |
336 | printf("*SBRK %s\n", str+4);\r | |
337 | continue;\r | |
338 | }\r | |
339 | else {\r | |
340 | switch (cardtype) {\r | |
341 | case 0x00:\r | |
342 | if (first)\r | |
343 | show_raw("CORE");\r | |
344 | if (verbose)\r | |
345 | show_core();\r | |
346 | break;\r | |
347 | \r | |
348 | case 0x01:\r | |
349 | show_raw("ABS ");\r | |
350 | show_main();\r | |
351 | break;\r | |
352 | case 0x02:\r | |
353 | show_raw("REL ");\r | |
354 | show_main();\r | |
355 | break;\r | |
356 | case 0x03:\r | |
357 | show_raw("LIB ");\r | |
358 | show_sub();\r | |
359 | break;\r | |
360 | case 0x04:\r | |
361 | show_raw("SUB ");\r | |
362 | show_sub();\r | |
363 | break;\r | |
364 | case 0x05:\r | |
365 | show_raw("ISSL");\r | |
366 | show_iss();\r | |
367 | break;\r | |
368 | case 0x06:\r | |
369 | show_raw("ISSC");\r | |
370 | show_iss();\r | |
371 | break;\r | |
372 | case 0x07:\r | |
373 | show_raw("ILS ");\r | |
374 | show_ils();\r | |
375 | break;\r | |
376 | case 0x0F:\r | |
377 | show_raw("END ");\r | |
378 | show_end();\r | |
379 | break;\r | |
380 | case 0x80:\r | |
381 | show_raw("ENDC");\r | |
382 | show_endc();\r | |
383 | break;\r | |
384 | case 0x81:\r | |
385 | show_raw("81 ");\r | |
386 | show_81();\r | |
387 | break;\r | |
388 | case 0x0A:\r | |
389 | if (verbose)\r | |
390 | show_data();\r | |
391 | break;\r | |
392 | default:\r | |
393 | show_raw("??? ");\r | |
394 | }\r | |
395 | }\r | |
396 | \r | |
397 | first = FALSE;\r | |
398 | }\r | |
399 | \r | |
400 | fclose(fp);\r | |
401 | }\r | |
402 | \r | |
403 | void show_data (void)\r | |
404 | {\r | |
405 | int i, n, jrel, rflag, nout, ch, reloc;\r | |
406 | BOOL first = TRUE;\r | |
407 | \r | |
408 | n = buf[2] & 0x00FF;\r | |
409 | \r | |
410 | printf("%04x: ", buf[0]);\r | |
411 | \r | |
412 | jrel = 3;\r | |
413 | nout = 0;\r | |
414 | rflag = buf[jrel++];\r | |
415 | for (i = 0; i < n; i++) {\r | |
416 | if (nout >= 8) {\r | |
417 | rflag = buf[jrel++];\r | |
418 | if (first) {\r | |
419 | printf(" %s", getseq());\r | |
420 | first = FALSE;\r | |
421 | }\r | |
422 | printf("\n ");\r | |
423 | nout = 0;\r | |
424 | }\r | |
425 | reloc = (rflag >> 14) & 0x03;\r | |
426 | ch = (reloc == R_ABSOLUTE) ? ' ' :\r | |
427 | (reloc == R_RELATIVE) ? 'R' :\r | |
428 | (reloc == R_LIBF) ? 'L' : '@';\r | |
429 | \r | |
430 | printf("%04x%c ", buf[9+i], ch);\r | |
431 | rflag <<= 2;\r | |
432 | nout++;\r | |
433 | }\r | |
434 | putchar('\n');\r | |
435 | }\r | |
436 | \r | |
437 | void show_core (void)\r | |
438 | {\r | |
439 | int i, n, nout;\r | |
440 | BOOL first = TRUE;\r | |
441 | \r | |
442 | n = buf[2] & 0x00FF;\r | |
443 | \r | |
444 | printf("%04x: ", buf[0]);\r | |
445 | \r | |
446 | nout = 0;\r | |
447 | for (i = 0; i < n; i++) {\r | |
448 | if (nout >= 8) {\r | |
449 | if (first) {\r | |
450 | printf(" %s", getseq());\r | |
451 | first = FALSE;\r | |
452 | }\r | |
453 | printf("\n ");\r | |
454 | nout = 0;\r | |
455 | }\r | |
456 | printf("%04x ", buf[9+i]);\r | |
457 | nout++;\r | |
458 | }\r | |
459 | putchar('\n');\r | |
460 | }\r | |
461 | \r | |
462 | void info (int i, char *nm, char type)\r | |
463 | {\r | |
464 | if (nm)\r | |
465 | printf("%s ", nm);\r | |
466 | \r | |
467 | switch (type) {\r | |
468 | case 'd':\r | |
469 | printf("%d ", buf[i]);\r | |
470 | break;\r | |
471 | \r | |
472 | case 'x':\r | |
473 | printf("%04x ", buf[i]);\r | |
474 | break;\r | |
475 | \r | |
476 | case 'b':\r | |
477 | printf("%02x ", buf[i] & 0xFF);\r | |
478 | break;\r | |
479 | \r | |
480 | case 'n':\r | |
481 | printf("%s ", getname(buf+i));\r | |
482 | break;\r | |
483 | \r | |
484 | default:\r | |
485 | bail("BAD TYPE");\r | |
486 | }\r | |
487 | }\r | |
488 | \r | |
489 | void show_main (void)\r | |
490 | {\r | |
491 | printf(" ");\r | |
492 | info(2, "prec", 'b');\r | |
493 | info(4, "common", 'd');\r | |
494 | info(6, "work", 'd');\r | |
495 | info(8, "files", 'd');\r | |
496 | info(9, "name", 'n');\r | |
497 | info(11, "pta", 'x');\r | |
498 | putchar('\n');\r | |
499 | }\r | |
500 | \r | |
501 | void show_sub (void)\r | |
502 | {\r | |
503 | int i, n;\r | |
504 | \r | |
505 | printf(" ");\r | |
506 | info( 2, "prec", 'b');\r | |
507 | \r | |
508 | n = buf[5] / 3;\r | |
509 | for (i = 0; i < n; i++) {\r | |
510 | info( 9+3*i, "ent", 'n');\r | |
511 | info(11+3*i, NULL, 'x');\r | |
512 | }\r | |
513 | \r | |
514 | putchar('\n');\r | |
515 | }\r | |
516 | \r | |
517 | void show_iss (void)\r | |
518 | {\r | |
519 | printf(" ");\r | |
520 | info(12, "level", 'd');\r | |
521 | putchar('\n');\r | |
522 | }\r | |
523 | \r | |
524 | void show_ils (void)\r | |
525 | {\r | |
526 | printf(" ");\r | |
527 | info( 2, "prec", 'b');\r | |
528 | info( 5, "nint6", 'd');\r | |
529 | info( 9, "ent", 'n');\r | |
530 | info(11, NULL, 'x');\r | |
531 | info(14, "nint", 'd');\r | |
532 | info(15, "il1", 'd');\r | |
533 | info(16, "il2", 'd');\r | |
534 | putchar('\n');\r | |
535 | }\r | |
536 | \r | |
537 | void show_end (void)\r | |
538 | {\r | |
539 | printf(" ");\r | |
540 | info(0, "size", 'd');\r | |
541 | info(3, "pta", 'x');\r | |
542 | putchar('\n');\r | |
543 | }\r | |
544 | \r | |
545 | void show_endc(void)\r | |
546 | {\r | |
547 | printf(" ");\r | |
548 | info(52, "IX3", 'x');\r | |
549 | info(53, "pta", 'x');\r | |
550 | putchar('\n');\r | |
551 | }\r | |
552 | \r | |
553 | void show_81(void)\r | |
554 | {\r | |
555 | }\r | |
556 | \r | |
557 | void show_raw (char *name)\r | |
558 | {\r | |
559 | int i;\r | |
560 | printf("*%s", name);\r | |
561 | \r | |
562 | for (i = 0; i < 12; i++)\r | |
563 | printf(" %04x", buf[i]);\r | |
564 | \r | |
565 | printf(" %s\n", getseq());\r | |
566 | }\r | |
567 | \r | |
568 | char * getseq (void)\r | |
569 | {\r | |
570 | static char seq[10];\r | |
571 | int i;\r | |
572 | \r | |
573 | for (i = 0; i < 8; i++)\r | |
574 | seq[i] = hollerith_to_ascii(card[72+i]);\r | |
575 | \r | |
576 | seq[i] = '\0';\r | |
577 | return seq;\r | |
578 | }\r | |
579 | \r | |
580 | \r | |
581 | void bail (char *msg)\r | |
582 | {\r | |
583 | fprintf(stderr, "%s\n", msg);\r | |
584 | exit(1);\r | |
585 | }\r | |
586 | \r | |
587 | void unpack (unsigned short *icard, unsigned short *obuf)\r | |
588 | {\r | |
589 | int i, j;\r | |
590 | unsigned short wd1, wd2, wd3, wd4;\r | |
591 | \r | |
592 | for (i = j = 0; i < 54; i += 3, j += 4) {\r | |
593 | wd1 = icard[j];\r | |
594 | wd2 = icard[j+1];\r | |
595 | wd3 = icard[j+2];\r | |
596 | wd4 = icard[j+3];\r | |
597 | \r | |
598 | obuf[i ] = (wd1 & 0xFFF0) | ((wd2 >> 12) & 0x000F);\r | |
599 | obuf[i+1] = ((wd2 << 4) & 0xFF00) | ((wd3 >> 8) & 0x00FF);\r | |
600 | obuf[i+2] = ((wd3 << 8) & 0xF000) | ((wd4 >> 4) & 0x0FFF);\r | |
601 | }\r | |
602 | }\r | |
603 | \r | |
604 | void verify_checksum (unsigned short *obuf)\r | |
605 | {\r | |
606 | // unsigned short sum;\r | |
607 | \r | |
608 | if (obuf[1] == 0) // no checksum\r | |
609 | return;\r | |
610 | \r | |
611 | // if (sum != card[1])\r | |
612 | // printf("Checksum %04x doesn't match card %04x\n", sum, card[1]);\r | |
613 | }\r | |
614 | \r | |
615 | typedef struct {\r | |
616 | unsigned short hollerith;\r | |
617 | char ascii;\r | |
618 | } CPCODE;\r | |
619 | \r | |
620 | static CPCODE cardcode_029[] =\r | |
621 | {\r | |
622 | 0x0000, ' ',\r | |
623 | 0x8000, '&', // + in 026 Fortran\r | |
624 | 0x4000, '-',\r | |
625 | 0x2000, '0',\r | |
626 | 0x1000, '1',\r | |
627 | 0x0800, '2',\r | |
628 | 0x0400, '3',\r | |
629 | 0x0200, '4',\r | |
630 | 0x0100, '5',\r | |
631 | 0x0080, '6',\r | |
632 | 0x0040, '7',\r | |
633 | 0x0020, '8',\r | |
634 | 0x0010, '9',\r | |
635 | 0x9000, 'A',\r | |
636 | 0x8800, 'B',\r | |
637 | 0x8400, 'C',\r | |
638 | 0x8200, 'D',\r | |
639 | 0x8100, 'E',\r | |
640 | 0x8080, 'F',\r | |
641 | 0x8040, 'G',\r | |
642 | 0x8020, 'H',\r | |
643 | 0x8010, 'I',\r | |
644 | 0x5000, 'J',\r | |
645 | 0x4800, 'K',\r | |
646 | 0x4400, 'L',\r | |
647 | 0x4200, 'M',\r | |
648 | 0x4100, 'N',\r | |
649 | 0x4080, 'O',\r | |
650 | 0x4040, 'P',\r | |
651 | 0x4020, 'Q',\r | |
652 | 0x4010, 'R',\r | |
653 | 0x3000, '/',\r | |
654 | 0x2800, 'S',\r | |
655 | 0x2400, 'T',\r | |
656 | 0x2200, 'U',\r | |
657 | 0x2100, 'V',\r | |
658 | 0x2080, 'W',\r | |
659 | 0x2040, 'X',\r | |
660 | 0x2020, 'Y',\r | |
661 | 0x2010, 'Z',\r | |
662 | 0x0820, ':',\r | |
663 | 0x0420, '#', // = in 026 Fortran\r | |
664 | 0x0220, '@', // ' in 026 Fortran\r | |
665 | 0x0120, '\'',\r | |
666 | 0x00A0, '=',\r | |
667 | 0x0060, '"',\r | |
668 | 0x8820, 'c', // cent\r | |
669 | 0x8420, '.',\r | |
670 | 0x8220, '<', // ) in 026 Fortran\r | |
671 | 0x8120, '(',\r | |
672 | 0x80A0, '+',\r | |
673 | 0x8060, '|',\r | |
674 | 0x4820, '!',\r | |
675 | 0x4420, '$',\r | |
676 | 0x4220, '*',\r | |
677 | 0x4120, ')',\r | |
678 | 0x40A0, ';',\r | |
679 | 0x4060, 'n', // not\r | |
680 | 0x2820, 'x', // what?\r | |
681 | 0x2420, ',',\r | |
682 | 0x2220, '%', // ( in 026 Fortran\r | |
683 | 0x2120, '_',\r | |
684 | 0x20A0, '>',\r | |
685 | 0x2060, '>',\r | |
686 | };\r | |
687 | \r | |
688 | int hollerith_to_ascii (unsigned short h)\r | |
689 | {\r | |
690 | int i;\r | |
691 | \r | |
692 | h &= 0xFFF0;\r | |
693 | \r | |
694 | for (i = 0; i < sizeof(cardcode_029) / sizeof(CPCODE); i++)\r | |
695 | if (cardcode_029[i].hollerith == h)\r | |
696 | return cardcode_029[i].ascii;\r | |
697 | \r | |
698 | return '?';\r | |
699 | }\r | |
700 | \r | |
701 | // ---------------------------------------------------------------------------------\r | |
702 | // trim - remove trailing whitespace from string s\r | |
703 | // ---------------------------------------------------------------------------------\r | |
704 | \r | |
705 | void trim (char *s)\r | |
706 | {\r | |
707 | char *nb;\r | |
708 | \r | |
709 | for (nb = s-1; *s; s++)\r | |
710 | if (*s > ' ')\r | |
711 | nb = s;\r | |
712 | \r | |
713 | nb[1] = '\0';\r | |
714 | }\r | |
715 | \r | |
716 | int ascii_to_ebcdic_table[128] = \r | |
717 | {\r | |
718 | 0x00,0x01,0x02,0x03,0x37,0x2d,0x2e,0x2f, 0x16,0x05,0x25,0x0b,0x0c,0x0d,0x0e,0x0f,\r | |
719 | 0x10,0x11,0x12,0x13,0x3c,0x3d,0x32,0x26, 0x18,0x19,0x3f,0x27,0x1c,0x1d,0x1e,0x1f,\r | |
720 | 0x40,0x5a,0x7f,0x7b,0x5b,0x6c,0x50,0x7d, 0x4d,0x5d,0x5c,0x4e,0x6b,0x60,0x4b,0x61,\r | |
721 | 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, 0xf8,0xf9,0x7a,0x5e,0x4c,0x7e,0x6e,0x6f,\r | |
722 | \r | |
723 | 0x7c,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7, 0xc8,0xc9,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,\r | |
724 | 0xd7,0xd8,0xd9,0xe2,0xe3,0xe4,0xe5,0xe6, 0xe7,0xe8,0xe9,0xba,0xe0,0xbb,0xb0,0x6d,\r | |
725 | 0x79,0x81,0x82,0x83,0x84,0x85,0x86,0x87, 0x88,0x89,0x91,0x92,0x93,0x94,0x95,0x96,\r | |
726 | 0x97,0x98,0x99,0xa2,0xa3,0xa4,0xa5,0xa6, 0xa7,0xa8,0xa9,0xc0,0x4f,0xd0,0xa1,0x07,\r | |
727 | };\r | |
728 | \r | |
729 | char *getname (unsigned short *ptr)\r | |
730 | {\r | |
731 | static char str[6];\r | |
732 | int i, j, ch;\r | |
733 | long v;\r | |
734 | \r | |
735 | v = (ptr[0] << 16L) | ptr[1];\r | |
736 | \r | |
737 | for (i = 0; i < 5; i++) {\r | |
738 | ch = ((v >> 24) & 0x3F) | 0xC0; // recover those lost two bits\r | |
739 | v <<= 6;\r | |
740 | \r | |
741 | str[i] = ' ';\r | |
742 | \r | |
743 | for (j = 0; j < (sizeof(ascii_to_ebcdic_table)/sizeof(ascii_to_ebcdic_table[0])); j++) {\r | |
744 | if (ascii_to_ebcdic_table[j] == ch) {\r | |
745 | str[i] = j;\r | |
746 | break;\r | |
747 | }\r | |
748 | }\r | |
749 | }\r | |
750 | \r | |
751 | str[5] = '\0';\r | |
752 | return str;\r | |
753 | }\r | |
754 | \r | |
755 | \r |