First Commit of my working state
[simh.git] / Ibm1130 / utils / viewdeck.c
1 /* Simple program to display a binary card-image file in ASCII.
2 * We assume the deck was written with one card per 16-bit word, left-justified,
3 * and written in PC little-endian order
4 *
5 * (C) Copyright 2002, Brian Knittel.
6 * You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN
7 * RISK basis, there is no warranty of fitness for any purpose, and the rest of the
8 * usual yada-yada. Please keep this notice and the copyright in any distributions
9 * or modifications.
10 *
11 * This is not a supported product, but I welcome bug reports and fixes.
12 * Mail to sim@ibm1130.org
13 */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include "util_io.h"
18
19 #define TRUE 1
20 #define FALSE 0
21 typedef int BOOL;
22
23 int hollerith_to_ascii (unsigned short h);
24 void bail (char *msg);
25 void format_coldstart (unsigned short *buf);
26
27 int main (int argc, char **argv)
28 {
29 FILE *fd;
30 char *fname = NULL, line[82], *arg;
31 BOOL coldstart = FALSE;
32 unsigned short buf[80];
33 int i, lastnb;
34 static char usestr[] =
35 "Usage: viewdeck [-c] deckfile\n"
36 "\n"
37 "-c: convert cold start card to 16-bit format as a C array initializer\n";
38
39 for (i = 1; i < argc; i++) { // process command line arguments
40 arg = argv[i];
41
42 if (*arg == '-') {
43 arg++;
44 while (*arg) {
45 switch (*arg++) {
46 case 'c':
47 coldstart = TRUE;
48 break;
49 default:
50 bail(usestr);
51 }
52 }
53 }
54 else if (fname == NULL) // first non-switch arg is file name
55 fname = arg;
56 else
57 bail(usestr); // there can be only one name
58 }
59
60 if (fname == NULL) // there must be a name
61 bail(usestr);
62
63 if ((fd = fopen(fname, "rb")) == NULL) {
64 perror(fname);
65 return 1;
66 }
67
68 while (fxread(buf, sizeof(short), 80, fd) == 80) {
69 if (coldstart) {
70 format_coldstart(buf);
71 break;
72 }
73
74 lastnb = -1;
75 for (i = 0; i < 80; i++) {
76 line[i] = hollerith_to_ascii(buf[i]);
77 if (line[i] > ' ')
78 lastnb = i;
79 }
80 line[++lastnb] = '\n';
81 line[++lastnb] = '\0';
82 fputs(line, stdout);
83 }
84
85 if (coldstart) {
86 if (fxread(buf, sizeof(short), 1, fd) == 1)
87 bail("Coldstart deck has more than one card");
88 }
89
90 fclose(fd);
91
92 return 0;
93 }
94
95 void format_coldstart (unsigned short *buf)
96 {
97 int i, nout = 0;
98 unsigned short word;
99
100 for (i = 0; i < 80; i++) {
101 word = buf[i]; // expand 12-bit card data to 16-bit instruction
102 word = (word & 0xF800) | ((word & 0x0400) ? 0x00C0 : 0x0000) | ((word & 0x03F0) >> 4);
103
104 if (nout >= 8) {
105 fputs(",\n", stdout);
106 nout = 0;
107 }
108 else if (i > 0)
109 fputs(", ", stdout);
110
111 printf("0x%04x", word);
112 nout++;
113 }
114
115 putchar('\n');
116 }
117
118 typedef struct {
119 unsigned short hollerith;
120 char ascii;
121 } CPCODE;
122
123 static CPCODE cardcode_029[] =
124 {
125 0x0000, ' ',
126 0x8000, '&', // + in 026 Fortran
127 0x4000, '-',
128 0x2000, '0',
129 0x1000, '1',
130 0x0800, '2',
131 0x0400, '3',
132 0x0200, '4',
133 0x0100, '5',
134 0x0080, '6',
135 0x0040, '7',
136 0x0020, '8',
137 0x0010, '9',
138 0x9000, 'A',
139 0x8800, 'B',
140 0x8400, 'C',
141 0x8200, 'D',
142 0x8100, 'E',
143 0x8080, 'F',
144 0x8040, 'G',
145 0x8020, 'H',
146 0x8010, 'I',
147 0x5000, 'J',
148 0x4800, 'K',
149 0x4400, 'L',
150 0x4200, 'M',
151 0x4100, 'N',
152 0x4080, 'O',
153 0x4040, 'P',
154 0x4020, 'Q',
155 0x4010, 'R',
156 0x3000, '/',
157 0x2800, 'S',
158 0x2400, 'T',
159 0x2200, 'U',
160 0x2100, 'V',
161 0x2080, 'W',
162 0x2040, 'X',
163 0x2020, 'Y',
164 0x2010, 'Z',
165 0x0820, ':',
166 0x0420, '#', // = in 026 Fortran
167 0x0220, '@', // ' in 026 Fortran
168 0x0120, '\'',
169 0x00A0, '=',
170 0x0060, '"',
171 0x8820, '\xA2', // cent, in MS-DOS encoding
172 0x8420, '.',
173 0x8220, '<', // ) in 026 Fortran
174 0x8120, '(',
175 0x80A0, '+',
176 0x8060, '|',
177 0x4820, '!',
178 0x4420, '$',
179 0x4220, '*',
180 0x4120, ')',
181 0x40A0, ';',
182 0x4060, '\xAC', // not, in MS-DOS encoding
183 0x2420, ',',
184 0x2220, '%', // ( in 026 Fortran
185 0x2120, '_',
186 0x20A0, '>',
187 0xB000, 'a',
188 0xA800, 'b',
189 0xA400, 'c',
190 0xA200, 'd',
191 0xA100, 'e',
192 0xA080, 'f',
193 0xA040, 'g',
194 0xA020, 'h',
195 0xA010, 'i',
196 0xD000, 'j',
197 0xC800, 'k',
198 0xC400, 'l',
199 0xC200, 'm',
200 0xC100, 'n',
201 0xC080, 'o',
202 0xC040, 'p',
203 0xC020, 'q',
204 0xC010, 'r',
205 0x6800, 's',
206 0x6400, 't',
207 0x6200, 'u',
208 0x6100, 'v',
209 0x6080, 'w',
210 0x6040, 'x',
211 0x6020, 'y',
212 0x6010, 'z', // these odd punch codes are used by APL:
213 0x1010, '\001', // no corresponding ASCII using ^A
214 0x0810, '\002', // SYN using ^B
215 0x0410, '\003', // no corresponding ASCII using ^C
216 0x0210, '\004', // PUNCH ON using ^D
217 0x0110, '\005', // READER STOP using ^E
218 0x0090, '\006', // UPPER CASE using ^F
219 0x0050, '\013', // EOT using ^K
220 0x0030, '\016', // no corresponding ASCII using ^N
221 0x1030, '\017', // no corresponding ASCII using ^O
222 0x0830, '\020', // no corresponding ASCII using ^P
223 };
224
225 int hollerith_to_ascii (unsigned short h)
226 {
227 int i;
228
229 h &= 0xFFF0;
230
231 for (i = 0; i < sizeof(cardcode_029) / sizeof(CPCODE); i++)
232 if (cardcode_029[i].hollerith == h)
233 return cardcode_029[i].ascii;
234
235 return '?';
236 }
237
238 void bail (char *msg)
239 {
240 fprintf(stderr, "%s\n", msg);
241 exit(1);
242 }
243