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 | // DISKVIEW - lists contents of an 1130 system disk image file. Not finished yet.\r | |
13 | // needs LET/SLET listing routine.\r | |
14 | //\r | |
15 | // usage:\r | |
16 | // diskview -v diskfile\r | |
17 | \r | |
18 | #include <stdio.h>\r | |
19 | #include <stdlib.h>\r | |
20 | #include <string.h>\r | |
21 | #include <stdarg.h>\r | |
22 | #include "util_io.h"\r | |
23 | \r | |
24 | #define BETWEEN(v,a,b) (((v) >= (a)) && ((v) <= (b)))\r | |
25 | #define MIN(a,b) (((a) <= (b)) ? (a) : (b))\r | |
26 | #define MAX(a,b) (((a) >= (b)) ? (a) : (b))\r | |
27 | \r | |
28 | #ifndef TRUE\r | |
29 | # define TRUE 1\r | |
30 | # define FALSE 0\r | |
31 | # define BOOL int\r | |
32 | #endif\r | |
33 | \r | |
34 | #define NOT_DEF 0x0658 // defective cylinder table entry means no defect\r | |
35 | \r | |
36 | #define DSK_NUMWD 321 /* words/sector */\r | |
37 | #define DSK_NUMCY 203 /* cylinders/drive */\r | |
38 | #define DSK_SECCYL 8 /* sectors per cylinder */\r | |
39 | #define SECLEN 320 /* data words per sector */\r | |
40 | #define SLETLEN ((3*SECLEN)/4) /* length of slet in records */\r | |
41 | \r | |
42 | typedef unsigned short WORD;\r | |
43 | \r | |
44 | FILE *fp;\r | |
45 | WORD buf[DSK_NUMWD];\r | |
46 | WORD dcom[DSK_NUMWD];\r | |
47 | \r | |
48 | #pragma pack(2)\r | |
49 | struct tag_slet {\r | |
50 | WORD phid;\r | |
51 | WORD addr;\r | |
52 | WORD nwords;\r | |
53 | WORD sector;\r | |
54 | } slet[SLETLEN];\r | |
55 | \r | |
56 | #pragma pack()\r | |
57 | \r | |
58 | WORD dcyl[3];\r | |
59 | BOOL verbose = FALSE;\r | |
60 | \r | |
61 | void checksectors (void);\r | |
62 | void dump_id (void);\r | |
63 | void dump_dcom (void);\r | |
64 | void dump_resmon (void);\r | |
65 | void dump_slet (void);\r | |
66 | void dump_hdng (void);\r | |
67 | void dump_scra (void);\r | |
68 | void dump_let (void);\r | |
69 | void dump_flet (void);\r | |
70 | void dump_cib (void);\r | |
71 | void getsector (int sec, WORD *sbuf);\r | |
72 | void getdcyl (void);\r | |
73 | char *lowcase (char *str);\r | |
74 | \r | |
75 | void bail(char *fmt, ...);\r | |
76 | char *trim (char *s);\r | |
77 | \r | |
78 | int main (int argc, char **argv)\r | |
79 | {\r | |
80 | char *fname = NULL, *arg;\r | |
81 | static char usestr[] = "Usage: diskview [-v] filename";\r | |
82 | int i;\r | |
83 | \r | |
84 | for (i = 1; i < argc;) {\r | |
85 | arg = argv[i++];\r | |
86 | if (*arg == '-') {\r | |
87 | arg++;\r | |
88 | lowcase(arg);\r | |
89 | while (*arg) {\r | |
90 | switch (*arg++) {\r | |
91 | case 'v':\r | |
92 | verbose = TRUE;\r | |
93 | break;\r | |
94 | \r | |
95 | default:\r | |
96 | bail(usestr);\r | |
97 | }\r | |
98 | }\r | |
99 | }\r | |
100 | else if (fname == NULL)\r | |
101 | fname = arg;\r | |
102 | else\r | |
103 | bail(usestr);\r | |
104 | }\r | |
105 | \r | |
106 | if (fname == NULL)\r | |
107 | bail(usestr);\r | |
108 | \r | |
109 | if ((fp = fopen(fname, "rb")) == NULL) {\r | |
110 | perror(fname);\r | |
111 | return 2;\r | |
112 | }\r | |
113 | \r | |
114 | printf("%s:\n", fname);\r | |
115 | \r | |
116 | checksectors();\r | |
117 | getdcyl();\r | |
118 | \r | |
119 | dump_id(); // ID & coldstart\r | |
120 | dump_dcom(); // DCOM\r | |
121 | dump_resmon(); // resident image\r | |
122 | dump_slet(); // SLET\r | |
123 | dump_hdng(); // heading sector\r | |
124 | dump_scra();\r | |
125 | dump_flet();\r | |
126 | dump_cib();\r | |
127 | dump_let();\r | |
128 | \r | |
129 | fclose(fp);\r | |
130 | return 0;\r | |
131 | }\r | |
132 | \r | |
133 | // checksectors - verify that all sectors are properly numbered\r | |
134 | \r | |
135 | void checksectors ()\r | |
136 | {\r | |
137 | WORD sec = 0;\r | |
138 | \r | |
139 | fseek(fp, 0, SEEK_SET);\r | |
140 | \r | |
141 | for (sec = 0; sec < DSK_NUMCY*DSK_SECCYL; sec++) {\r | |
142 | if (fxread(buf, sizeof(WORD), DSK_NUMWD, fp) != DSK_NUMWD)\r | |
143 | bail("File read error or not a disk image file");\r | |
144 | \r | |
145 | if (buf[0] != sec)\r | |
146 | bail("Sector /%x is misnumbered, run checkdisk [-f]", sec);\r | |
147 | }\r | |
148 | }\r | |
149 | \r | |
150 | // get defective cylinder list\r | |
151 | \r | |
152 | void getdcyl (void)\r | |
153 | {\r | |
154 | fseek(fp, sizeof(WORD), SEEK_SET); // skip sector count\r | |
155 | if (fxread(dcyl, sizeof(WORD), 3, fp) != 3)\r | |
156 | bail("Unable to read defective cylinder table");\r | |
157 | }\r | |
158 | \r | |
159 | // getsector - read specified absolute sector\r | |
160 | \r | |
161 | void getsector (int sec, WORD *sbuf)\r | |
162 | {\r | |
163 | int i, cyl, ssec;\r | |
164 | \r | |
165 | sec &= 0x7FF; // mask of drive bits, if any\r | |
166 | \r | |
167 | cyl = sec / DSK_SECCYL; // get cylinder\r | |
168 | ssec = sec & ~(DSK_SECCYL-1); // mask to get starting sector of cylinder\r | |
169 | for (i = 0; i < 3; i++) { // map through defective cylinder table\r | |
170 | if (dcyl[i] == ssec) {\r | |
171 | sec &= (DSK_SECCYL-1); // mask to get base sector\r | |
172 | cyl = DSK_NUMCY-3+i; // replacements are last three on disk\r | |
173 | sec += cyl*DSK_SECCYL; // add new cylinder offset\r | |
174 | break;\r | |
175 | }\r | |
176 | }\r | |
177 | // read the sector\r | |
178 | if (fseek(fp, (sec*DSK_NUMWD+1)*sizeof(WORD), SEEK_SET) != 0)\r | |
179 | bail("File seek failed");\r | |
180 | \r | |
181 | if (fxread(sbuf, sizeof(WORD), DSK_NUMWD, fp) != DSK_NUMWD)\r | |
182 | bail("File read error or not a disk image file");\r | |
183 | }\r | |
184 | \r | |
185 | void dump (int nwords)\r | |
186 | {\r | |
187 | int i, nline = 0;\r | |
188 | \r | |
189 | for (i = 0; i < nwords; i++) {\r | |
190 | if (nline == 16) {\r | |
191 | putchar('\n');\r | |
192 | nline = 0;\r | |
193 | }\r | |
194 | \r | |
195 | printf("%04x", buf[i]);\r | |
196 | nline++;\r | |
197 | }\r | |
198 | putchar('\n');\r | |
199 | }\r | |
200 | \r | |
201 | void showmajor (char *label)\r | |
202 | {\r | |
203 | int i;\r | |
204 | \r | |
205 | printf("\n--- %s ", label);\r | |
206 | \r | |
207 | for (i = strlen(label); i < 40; i++)\r | |
208 | putchar('-');\r | |
209 | \r | |
210 | putchar('\n');\r | |
211 | putchar('\n');\r | |
212 | }\r | |
213 | \r | |
214 | void name (char *label)\r | |
215 | {\r | |
216 | printf("%-32.32s ", label);\r | |
217 | }\r | |
218 | \r | |
219 | void pbf (char *label, WORD *buf, int nwords)\r | |
220 | {\r | |
221 | int i, nout;\r | |
222 | \r | |
223 | name(label);\r | |
224 | \r | |
225 | for (i = nout = 0; i < nwords; i++, nout++) {\r | |
226 | if (nout == 8) {\r | |
227 | putchar('\n');\r | |
228 | name("");\r | |
229 | nout = 0;\r | |
230 | }\r | |
231 | printf(" %04x", buf[i]);\r | |
232 | }\r | |
233 | \r | |
234 | putchar('\n');\r | |
235 | }\r | |
236 | \r | |
237 | void prt (char *label, char *fmt, ...)\r | |
238 | {\r | |
239 | va_list args;\r | |
240 | \r | |
241 | name(label);\r | |
242 | \r | |
243 | putchar(' ');\r | |
244 | va_start(args, fmt);\r | |
245 | vprintf(fmt, args);\r | |
246 | va_end(args);\r | |
247 | \r | |
248 | putchar('\n');\r | |
249 | }\r | |
250 | \r | |
251 | void dump_id (void)\r | |
252 | {\r | |
253 | showmajor("Sector 0 - ID & coldstart");\r | |
254 | getsector(0, buf);\r | |
255 | \r | |
256 | pbf("DCYL def cyl table", buf+ 0, 3);\r | |
257 | pbf("CIDN cart id", buf+ 3, 1);\r | |
258 | pbf(" copy code", buf+ 4, 1);\r | |
259 | pbf("DTYP disk type", buf+ 7, 1);\r | |
260 | pbf(" diskz copy", buf+ 30, 8);\r | |
261 | pbf(" cold start pgm",buf+270, 8);\r | |
262 | }\r | |
263 | \r | |
264 | // EQUIVALENCES FOR DCOM PARAMETERS \r | |
265 | #define NAME 4 // NAME OF PROGRAM/CORE LOAD\r | |
266 | #define DBCT 6 // BLOCK CT OF PROGRAM/CORE LOAD\r | |
267 | #define FCNT 7 // FILES SWITCH\r | |
268 | #define SYSC 8 // SYSTEM/NON-SYSTEM CARTRIDGE INDR\r | |
269 | #define JBSW 9 // JOBT SWITCH\r | |
270 | #define CBSW 10 // CLB-RETURN SWITCH\r | |
271 | #define LCNT 11 // NO. OF LOCALS\r | |
272 | #define MPSW 12 // CORE MAP SWITCH\r | |
273 | #define MDF1 13 // NO. DUP CTRL RECORDS (MODIF)\r | |
274 | #define MDF2 14 // ADDR OF MODIF BUFFER\r | |
275 | #define NCNT 15 // NO. OF NOCALS\r | |
276 | #define ENTY 16 // RLTV ENTRY ADDR OF PROGRAM\r | |
277 | #define RP67 17 // 1442-5 SWITCH\r | |
278 | #define TODR 18 // OBJECT WORK STORAGE DRIVE CODE\r | |
279 | #define FHOL 20 // ADDR LARGEST HOLE IN FIXED AREA\r | |
280 | #define FSZE 21 // BLK CNT LARGEST HOLE IN FXA\r | |
281 | #define UHOL 22 // ADDR LAST HOLE IN USER AREA 2-10\r | |
282 | #define USZE 23 // BLK CNT LAST HOLE IN UA 2-10\r | |
283 | #define DCSW 24 // DUP CALL SWITCH\r | |
284 | #define PIOD 25 // PRINCIPAL I/O DEVICE INDICATOR\r | |
285 | #define PPTR 26 // PRINCIPAL PRINT DEVICE INDICATOR\r | |
286 | #define CIAD 27 // RLTV ADDR IN @STRT OF CIL ADDR\r | |
287 | #define ACIN 28 // AVAILABLE CARTRIDGE INDICATOR\r | |
288 | #define GRPH 29 // 2250 INDICATOR 2G2\r | |
289 | #define GCNT 30 // NO. G2250 RECORDS 2G2\r | |
290 | #define LOSW 31 // LOCAL-CALLS-LOCAL SWITCH 2-2\r | |
291 | #define X3SW 32 // SPECIAL ILS SWITCH 2-2\r | |
292 | #define ECNT 33 // NO. OF *EQUAT RCDS 2-4\r | |
293 | #define ANDU 35 // 1+BLK ADDR END OF UA (ADJUSTED)\r | |
294 | #define BNDU 40 // 1+BLK ADDR END OF UA (BASE)\r | |
295 | #define FPAD 45 // FILE PROTECT ADDR\r | |
296 | #define PCID 50 // CARTRIDGE ID, PHYSICAL DRIVE\r | |
297 | #define CIDN 55 // CARTRIDGE ID, LOGICAL DRIVE\r | |
298 | #define CIBA 60 // SCTR ADDR OF CIB\r | |
299 | #define SCRA 65 // SCTR ADDR OF SCRA\r | |
300 | #define FMAT 70 // FORMAT OF PROG IN WORKING STG\r | |
301 | #define FLET 75 // SCTR ADDR 1ST SCTR OF FLET\r | |
302 | #define ULET 80 // SCTR ADDR 1ST SCTR OF LET\r | |
303 | #define WSCT 85 // BLK CNT OF PROG IN WORKING STG\r | |
304 | #define CSHN 90 // NO. SCTRS IN CUSHION AREA\r | |
305 | \r | |
306 | struct tag_dcominfo {\r | |
307 | char *nm;\r | |
308 | int offset;\r | |
309 | char *descr;\r | |
310 | } dcominfo[] = {\r | |
311 | "NAME", 4, "NAME OF PROGRAM/CORE LOAD",\r | |
312 | "DBCT", 6, "BLOCK CT OF PROGRAM/CORE LOAD",\r | |
313 | "FCNT", 7, "FILES SWITCH",\r | |
314 | "SYSC", 8, "SYSTEM/NON-SYSTEM CARTRIDGE INDR",\r | |
315 | "JBSW", 9, "JOBT SWITCH",\r | |
316 | "CBSW", 10, "CLB-RETURN SWITCH",\r | |
317 | "LCNT", 11, "NO. OF LOCALS",\r | |
318 | "MPSW", 12, "CORE MAP SWITCH",\r | |
319 | "MDF1", 13, "NO. DUP CTRL RECORDS (MODIF)",\r | |
320 | "MDF2", 14, "ADDR OF MODIF BUFFER",\r | |
321 | "NCNT", 15, "NO. OF NOCALS",\r | |
322 | "ENTY", 16, "RLTV ENTRY ADDR OF PROGRAM",\r | |
323 | "RP67", 17, "1442-5 SWITCH",\r | |
324 | "TODR", 18, "OBJECT WORK STORAGE DRIVE CODE",\r | |
325 | "FHOL", 20, "ADDR LARGEST HOLE IN FIXED AREA",\r | |
326 | "FSZE", 21, "BLK CNT LARGEST HOLE IN FXA",\r | |
327 | "UHOL", 22, "ADDR LAST HOLE IN USER AREA",\r | |
328 | "USZE", 23, "BLK CNT LAST HOLE IN UA",\r | |
329 | "DCSW", 24, "DUP CALL SWITCH",\r | |
330 | "PIOD", 25, "PRINCIPAL I/O DEVICE INDICATOR",\r | |
331 | "PPTR", 26, "PRINCIPAL PRINT DEVICE INDICATOR",\r | |
332 | "CIAD", 27, "RLTV ADDR IN @STRT OF CIL ADDR",\r | |
333 | "ACIN", 28, "AVAILABLE CARTRIDGE INDICATOR",\r | |
334 | "GRPH", 29, "2250 INDICATOR",\r | |
335 | "GCNT", 30, "NO. G2250 RECORDS",\r | |
336 | "LOSW", 31, "LOCAL-CALLS-LOCAL SWITCH",\r | |
337 | "X3SW", 32, "SPECIAL ILS SWITCH",\r | |
338 | "ECNT", 33, "NO. OF *EQUAT RCDS",\r | |
339 | "ANDU", 35, "1+BLK ADDR END OF UA (ADJUSTED)",\r | |
340 | "BNDU", 40, "1+BLK ADDR END OF UA (BASE)",\r | |
341 | "FPAD", 45, "FILE PROTECT ADDR",\r | |
342 | "PCID", 50, "CARTRIDGE ID, PHYSICAL DRIVE",\r | |
343 | "CIDN", 55, "CARTRIDGE ID, LOGICAL DRIVE",\r | |
344 | "CIBA", 60, "SCTR ADDR OF CIB",\r | |
345 | "SCRA", 65, "SCTR ADDR OF SCRA",\r | |
346 | "FMAT", 70, "FORMAT OF PROG IN WORKING STG",\r | |
347 | "FLET", 75, "SCTR ADDR 1ST SCTR OF FLET",\r | |
348 | "ULET", 80, "SCTR ADDR 1ST SCTR OF LET",\r | |
349 | "WSCT", 85, "BLK CNT OF PROG IN WORKING STG",\r | |
350 | "CSHN", 90, "NO. SCTRS IN CUSHION AREA",\r | |
351 | NULL\r | |
352 | };\r | |
353 | \r | |
354 | void dump_dcom (void)\r | |
355 | {\r | |
356 | struct tag_dcominfo *d;\r | |
357 | char txt[50];\r | |
358 | \r | |
359 | showmajor("Sector 1 - DCOM");\r | |
360 | getsector(1, dcom);\r | |
361 | \r | |
362 | for (d = dcominfo; d->nm != NULL; d++) {\r | |
363 | sprintf(txt, "%-4.4s %s", d->nm, d->descr);\r | |
364 | pbf(txt, dcom+d->offset, 1);\r | |
365 | }\r | |
366 | }\r | |
367 | \r | |
368 | void dump_resmon (void)\r | |
369 | {\r | |
370 | showmajor("Sector 2 - Resident Image");\r | |
371 | getsector(2, buf);\r | |
372 | dump(verbose ? SECLEN : 32);\r | |
373 | }\r | |
374 | \r | |
375 | struct {\r | |
376 | int pfrom, pto;\r | |
377 | int printed;\r | |
378 | char *name;\r | |
379 | } sletinfo[] = {\r | |
380 | 0x01, 0x12, FALSE, "DUP",\r | |
381 | 0x1F, 0x39, FALSE, "Fortran",\r | |
382 | 0x51, 0x5C, FALSE, "Cobol",\r | |
383 | 0x6E, 0x74, FALSE, "Supervisor",\r | |
384 | 0x78, 0x84, FALSE, "Core Load Builder",\r | |
385 | 0x8C, 0x8C, FALSE, "Sys 1403 prt",\r | |
386 | 0x8D, 0x8D, FALSE, "Sys 1132 prt",\r | |
387 | 0x8E, 0x8E, FALSE, "Sys console prt",\r | |
388 | 0x8F, 0x8F, FALSE, "Sys 2501 rdr",\r | |
389 | 0x90, 0x90, FALSE, "Sys 1442 rdr/pun",\r | |
390 | 0x91, 0x91, FALSE, "Sys 1134 paper tape",\r | |
391 | 0x92, 0x92, FALSE, "Sys kbd",\r | |
392 | 0x93, 0x93, FALSE, "Sys 2501/1442 conv",\r | |
393 | 0x94, 0x94, FALSE, "Sys 1134 conv",\r | |
394 | 0x95, 0x95, FALSE, "Sys kbd conv",\r | |
395 | 0x96, 0x96, FALSE, "Sys diskz",\r | |
396 | 0x97, 0x97, FALSE, "Sys disk1",\r | |
397 | 0x98, 0x98, FALSE, "Sys diskn",\r | |
398 | 0x99, 0x99, FALSE, "(primary print)",\r | |
399 | 0x9A, 0x9A, FALSE, "(primary input)",\r | |
400 | 0x9B, 0x9B, FALSE, "(primary input excl kbd)",\r | |
401 | 0x9C, 0x9C, FALSE, "(primary sys conv)",\r | |
402 | 0x9D, 0x9D, FALSE, "(primary conv excl kbd)",\r | |
403 | 0xA0, 0xA1, FALSE, "Core Image Loader",\r | |
404 | 0xB0, 0xCC, FALSE, "RPG",\r | |
405 | 0xCD, 0xCE, FALSE, "Dup Part 2",\r | |
406 | 0xCF, 0xF6, FALSE, "Macro Assembler",\r | |
407 | 0\r | |
408 | };\r | |
409 | \r | |
410 | void dump_slet (void)\r | |
411 | {\r | |
412 | int i, j, iphase, nsecs, sec, max_sec = 0;\r | |
413 | char sstr[16], *smark;\r | |
414 | \r | |
415 | showmajor("Sectors 3-5 - SLET");\r | |
416 | for (i = 0; i < 3; i++) {\r | |
417 | getsector(3+i, buf);\r | |
418 | memmove(((WORD *) slet)+SECLEN*i, buf, SECLEN*sizeof(WORD));\r | |
419 | }\r | |
420 | \r | |
421 | printf("# PHID Addr Len Sector Secs\n");\r | |
422 | printf("------------------------------------------\n");\r | |
423 | for (i = 0; i < SLETLEN; i++) {\r | |
424 | if (slet[i].phid == 0)\r | |
425 | break;\r | |
426 | \r | |
427 | sec = slet[i].sector;\r | |
428 | iphase = (int) (signed short) slet[i].phid;\r | |
429 | nsecs = (slet[i].nwords + SECLEN-1)/SECLEN;\r | |
430 | \r | |
431 | if (sec & 0xF800) {\r | |
432 | smark = "*";\r | |
433 | sec &= 0x7FF;\r | |
434 | }\r | |
435 | else\r | |
436 | smark = " ";\r | |
437 | \r | |
438 | for (j = 0; sletinfo[j].pfrom != 0; j++)\r | |
439 | if (sletinfo[j].pfrom <= iphase && sletinfo[j].pto >= iphase)\r | |
440 | break;\r | |
441 | \r | |
442 | sprintf(sstr, "(%d.%d)", sec / DSK_SECCYL, slet[i].sector % DSK_SECCYL);\r | |
443 | \r | |
444 | printf("%3d %04x %4d %04x %04x %04x %s %-7s %3x",\r | |
445 | i, slet[i].phid, iphase, slet[i].addr, slet[i].nwords, slet[i].sector, smark, sstr, nsecs);\r | |
446 | \r | |
447 | if (iphase < 0)\r | |
448 | iphase = -iphase;\r | |
449 | \r | |
450 | if (sletinfo[j].pfrom == 0)\r | |
451 | printf(" ???");\r | |
452 | else if (! sletinfo[j].printed) {\r | |
453 | printf(" %s", sletinfo[j].name);\r | |
454 | sletinfo[j].printed = TRUE;\r | |
455 | }\r | |
456 | \r | |
457 | for (j = 0; j < i; j++) {\r | |
458 | if (sec == (slet[j].sector & 0x7FF)) {\r | |
459 | printf(" (same as %04x)", slet[j].phid);\r | |
460 | break;\r | |
461 | }\r | |
462 | }\r | |
463 | \r | |
464 | max_sec = MAX(max_sec, sec+nsecs-1); // find last sector used\r | |
465 | \r | |
466 | putchar('\n');\r | |
467 | \r | |
468 | if (i >= 15 && ! verbose) {\r | |
469 | printf("...\n");\r | |
470 | break;\r | |
471 | }\r | |
472 | }\r | |
473 | }\r | |
474 | \r | |
475 | int ascii_to_ebcdic_table[128] = \r | |
476 | {\r | |
477 | 0x00,0x01,0x02,0x03,0x37,0x2d,0x2e,0x2f, 0x16,0x05,0x25,0x0b,0x0c,0x0d,0x0e,0x0f,\r | |
478 | 0x10,0x11,0x12,0x13,0x3c,0x3d,0x32,0x26, 0x18,0x19,0x3f,0x27,0x1c,0x1d,0x1e,0x1f,\r | |
479 | 0x40,0x5a,0x7f,0x7b,0x5b,0x6c,0x50,0x7d, 0x4d,0x5d,0x5c,0x4e,0x6b,0x60,0x4b,0x61,\r | |
480 | 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, 0xf8,0xf9,0x7a,0x5e,0x4c,0x7e,0x6e,0x6f,\r | |
481 | \r | |
482 | 0x7c,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7, 0xc8,0xc9,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,\r | |
483 | 0xd7,0xd8,0xd9,0xe2,0xe3,0xe4,0xe5,0xe6, 0xe7,0xe8,0xe9,0xba,0xe0,0xbb,0xb0,0x6d,\r | |
484 | 0x79,0x81,0x82,0x83,0x84,0x85,0x86,0x87, 0x88,0x89,0x91,0x92,0x93,0x94,0x95,0x96,\r | |
485 | 0x97,0x98,0x99,0xa2,0xa3,0xa4,0xa5,0xa6, 0xa7,0xa8,0xa9,0xc0,0x4f,0xd0,0xa1,0x07,\r | |
486 | };\r | |
487 | \r | |
488 | int ebcdic_to_ascii (int ch)\r | |
489 | {\r | |
490 | int j;\r | |
491 | \r | |
492 | for (j = 32; j < 128; j++)\r | |
493 | if (ascii_to_ebcdic_table[j] == ch)\r | |
494 | return j;\r | |
495 | \r | |
496 | return '?';\r | |
497 | }\r | |
498 | \r | |
499 | #define HDR_LEN 120\r | |
500 | \r | |
501 | void dump_hdng(void)\r | |
502 | {\r | |
503 | int i;\r | |
504 | char str[HDR_LEN+1], *p = str;\r | |
505 | \r | |
506 | showmajor("Sector 7 - Heading");\r | |
507 | getsector(7, buf);\r | |
508 | \r | |
509 | for (i = 0; i < (HDR_LEN/2); i++) {\r | |
510 | *p++ = ebcdic_to_ascii((buf[i] >> 8) & 0xFF);\r | |
511 | *p++ = ebcdic_to_ascii( buf[i] & 0xFF);\r | |
512 | }\r | |
513 | \r | |
514 | *p = '\0';\r | |
515 | trim(str);\r | |
516 | printf("%s\n", str);\r | |
517 | }\r | |
518 | \r | |
519 | BOOL mget (int offset, char *name)\r | |
520 | {\r | |
521 | char title[80];\r | |
522 | \r | |
523 | if (dcom[offset] == 0)\r | |
524 | return FALSE;\r | |
525 | \r | |
526 | getsector(dcom[offset], buf);\r | |
527 | sprintf(title, "Sector %x - %s", dcom[offset], name);\r | |
528 | showmajor(title);\r | |
529 | return TRUE;\r | |
530 | }\r | |
531 | \r | |
532 | void dump_scra (void)\r | |
533 | {\r | |
534 | if (! mget(SCRA, "SCRA"))\r | |
535 | return;\r | |
536 | \r | |
537 | dump(verbose ? SECLEN : 32);\r | |
538 | }\r | |
539 | \r | |
540 | void dump_let (void)\r | |
541 | {\r | |
542 | if (! mget(ULET, "LET"))\r | |
543 | return;\r | |
544 | }\r | |
545 | \r | |
546 | void dump_flet (void)\r | |
547 | {\r | |
548 | if (! mget(FLET, "FLET"))\r | |
549 | return;\r | |
550 | }\r | |
551 | \r | |
552 | void dump_cib (void)\r | |
553 | {\r | |
554 | if (! mget(CIBA, "CIB"))\r | |
555 | return;\r | |
556 | \r | |
557 | dump(verbose ? SECLEN : 32);\r | |
558 | }\r | |
559 | \r | |
560 | #define LFHD 5 // WORD COUNT OF LET/FLET HEADER PMN09970\r | |
561 | #define LFEN 3 // NO OF WDS PER LET/FLET ENTRY PMN09980\r | |
562 | #define SCTN 0 // RLTY ADDR OF LET/FLET SCTR NO. PMN09990\r | |
563 | #define UAFX 1 // RLTV ADDR OF SCTR ADDR OF UA/FXA PMN10000\r | |
564 | #define WDSA 3 // RLTV ADDR OF WDS AVAIL IN SCTR PMN10010\r | |
565 | #define NEXT 4 // RLTV ADDR OF ADDR NEXT SCTR PMN10020\r | |
566 | #define LFNM 0 // RLTV ADDR OF LET/FLET ENTRY NAME PMN10030\r | |
567 | #define BLCT 2 // RLTV ADDR OF LET/FLET ENTRY DBCT PMN10040\r | |
568 | \r | |
569 | void bail (char *fmt, ...)\r | |
570 | {\r | |
571 | va_list args;\r | |
572 | \r | |
573 | va_start(args, fmt);\r | |
574 | fprintf(stderr, fmt, args);\r | |
575 | va_end(args);\r | |
576 | putchar('\n');\r | |
577 | \r | |
578 | exit(1);\r | |
579 | }\r | |
580 | \r | |
581 | // ---------------------------------------------------------------------------------\r | |
582 | // trim - remove trailing whitespace from string s\r | |
583 | // ---------------------------------------------------------------------------------\r | |
584 | \r | |
585 | char *trim (char *s)\r | |
586 | {\r | |
587 | char *os = s, *nb;\r | |
588 | \r | |
589 | for (nb = s-1; *s; s++)\r | |
590 | if (*s > ' ')\r | |
591 | nb = s;\r | |
592 | \r | |
593 | nb[1] = '\0';\r | |
594 | return os;\r | |
595 | }\r | |
596 | \r | |
597 | /* ------------------------------------------------------------------------ \r | |
598 | * lowcase - force a string to lowercase (ASCII)\r | |
599 | * ------------------------------------------------------------------------ */\r | |
600 | \r | |
601 | char *lowcase (char *str)\r | |
602 | {\r | |
603 | char *s;\r | |
604 | \r | |
605 | for (s = str; *s; s++) {\r | |
606 | if (*s >= 'A' && *s <= 'Z')\r | |
607 | *s += 32;\r | |
608 | } \r | |
609 | \r | |
610 | return str;\r | |
611 | }\r | |
612 | \r |