/* Simple program to display a binary card-image file in ASCII. * We assume the deck was written with one card per 16-bit word, left-justified, * and written in PC little-endian order * * (C) Copyright 2002, Brian Knittel. * You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN * RISK basis, there is no warranty of fitness for any purpose, and the rest of the * usual yada-yada. Please keep this notice and the copyright in any distributions * or modifications. * * This is not a supported product, but I welcome bug reports and fixes. * Mail to sim@ibm1130.org */ #include #include #include "util_io.h" #define TRUE 1 #define FALSE 0 typedef int BOOL; int hollerith_to_ascii (unsigned short h); void bail (char *msg); void format_coldstart (unsigned short *buf); int main (int argc, char **argv) { FILE *fd; char *fname = NULL, line[82], *arg; BOOL coldstart = FALSE; unsigned short buf[80]; int i, lastnb; static char usestr[] = "Usage: viewdeck [-c] deckfile\n" "\n" "-c: convert cold start card to 16-bit format as a C array initializer\n"; for (i = 1; i < argc; i++) { // process command line arguments arg = argv[i]; if (*arg == '-') { arg++; while (*arg) { switch (*arg++) { case 'c': coldstart = TRUE; break; default: bail(usestr); } } } else if (fname == NULL) // first non-switch arg is file name fname = arg; else bail(usestr); // there can be only one name } if (fname == NULL) // there must be a name bail(usestr); if ((fd = fopen(fname, "rb")) == NULL) { perror(fname); return 1; } while (fxread(buf, sizeof(short), 80, fd) == 80) { if (coldstart) { format_coldstart(buf); break; } lastnb = -1; for (i = 0; i < 80; i++) { line[i] = hollerith_to_ascii(buf[i]); if (line[i] > ' ') lastnb = i; } line[++lastnb] = '\n'; line[++lastnb] = '\0'; fputs(line, stdout); } if (coldstart) { if (fxread(buf, sizeof(short), 1, fd) == 1) bail("Coldstart deck has more than one card"); } fclose(fd); return 0; } void format_coldstart (unsigned short *buf) { int i, nout = 0; unsigned short word; for (i = 0; i < 80; i++) { word = buf[i]; // expand 12-bit card data to 16-bit instruction word = (word & 0xF800) | ((word & 0x0400) ? 0x00C0 : 0x0000) | ((word & 0x03F0) >> 4); if (nout >= 8) { fputs(",\n", stdout); nout = 0; } else if (i > 0) fputs(", ", stdout); printf("0x%04x", word); nout++; } putchar('\n'); } typedef struct { unsigned short hollerith; char ascii; } CPCODE; static CPCODE cardcode_029[] = { 0x0000, ' ', 0x8000, '&', // + in 026 Fortran 0x4000, '-', 0x2000, '0', 0x1000, '1', 0x0800, '2', 0x0400, '3', 0x0200, '4', 0x0100, '5', 0x0080, '6', 0x0040, '7', 0x0020, '8', 0x0010, '9', 0x9000, 'A', 0x8800, 'B', 0x8400, 'C', 0x8200, 'D', 0x8100, 'E', 0x8080, 'F', 0x8040, 'G', 0x8020, 'H', 0x8010, 'I', 0x5000, 'J', 0x4800, 'K', 0x4400, 'L', 0x4200, 'M', 0x4100, 'N', 0x4080, 'O', 0x4040, 'P', 0x4020, 'Q', 0x4010, 'R', 0x3000, '/', 0x2800, 'S', 0x2400, 'T', 0x2200, 'U', 0x2100, 'V', 0x2080, 'W', 0x2040, 'X', 0x2020, 'Y', 0x2010, 'Z', 0x0820, ':', 0x0420, '#', // = in 026 Fortran 0x0220, '@', // ' in 026 Fortran 0x0120, '\'', 0x00A0, '=', 0x0060, '"', 0x8820, '\xA2', // cent, in MS-DOS encoding 0x8420, '.', 0x8220, '<', // ) in 026 Fortran 0x8120, '(', 0x80A0, '+', 0x8060, '|', 0x4820, '!', 0x4420, '$', 0x4220, '*', 0x4120, ')', 0x40A0, ';', 0x4060, '\xAC', // not, in MS-DOS encoding 0x2420, ',', 0x2220, '%', // ( in 026 Fortran 0x2120, '_', 0x20A0, '>', 0xB000, 'a', 0xA800, 'b', 0xA400, 'c', 0xA200, 'd', 0xA100, 'e', 0xA080, 'f', 0xA040, 'g', 0xA020, 'h', 0xA010, 'i', 0xD000, 'j', 0xC800, 'k', 0xC400, 'l', 0xC200, 'm', 0xC100, 'n', 0xC080, 'o', 0xC040, 'p', 0xC020, 'q', 0xC010, 'r', 0x6800, 's', 0x6400, 't', 0x6200, 'u', 0x6100, 'v', 0x6080, 'w', 0x6040, 'x', 0x6020, 'y', 0x6010, 'z', // these odd punch codes are used by APL: 0x1010, '\001', // no corresponding ASCII using ^A 0x0810, '\002', // SYN using ^B 0x0410, '\003', // no corresponding ASCII using ^C 0x0210, '\004', // PUNCH ON using ^D 0x0110, '\005', // READER STOP using ^E 0x0090, '\006', // UPPER CASE using ^F 0x0050, '\013', // EOT using ^K 0x0030, '\016', // no corresponding ASCII using ^N 0x1030, '\017', // no corresponding ASCII using ^O 0x0830, '\020', // no corresponding ASCII using ^P }; int hollerith_to_ascii (unsigned short h) { int i; h &= 0xFFF0; for (i = 0; i < sizeof(cardcode_029) / sizeof(CPCODE); i++) if (cardcode_029[i].hollerith == h) return cardcode_029[i].ascii; return '?'; } void bail (char *msg) { fprintf(stderr, "%s\n", msg); exit(1); }