2 * (C) Copyright 2002, Brian Knittel.
3 * You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN
4 * RISK basis, there is no warranty of fitness for any purpose, and the rest of the
5 * usual yada-yada. Please keep this notice and the copyright in any distributions
8 * This is not a supported product, but I welcome bug reports and fixes.
9 * Mail to sim@ibm1130.org
12 // ---------------------------------------------------------------------------------
13 // BINDUMP - dumps card deck files in assembler object format
16 /// bindump deckfile lists object header info & sector break cards
17 // bindump -v deckfile lists object data records as well
18 // bindump -p deckfile for system program, lists phase IDs in the deck
19 // bindump -s deckfile >outfile for system program, sorts the phases & writes to stdout
37 typedef enum {R_ABSOLUTE
= 0, R_RELATIVE
= 1, R_LIBF
= 2, R_CALL
= 3} RELOC
;
42 unsigned short card
[80], buf
[54], cardtype
;
44 // bindump - dump a binary (card format) deck to verify sbrks, etc
46 void bail (char *msg
);
47 void dump (char *fname
);
48 void dump_data (char *fname
);
49 void dump_phids (char *fname
);
50 char *getname (unsigned short *ptr
);
52 int hollerith_to_ascii (unsigned short h
);
53 void process (char *fname
);
54 void show_raw (char *name
);
55 void show_data (void);
56 void show_core (void);
57 void show_endc (void);
59 void show_main (void);
64 void sort_phases (char *fname
);
66 void unpack (unsigned short *card
, unsigned short *buf
);
67 void verify_checksum(unsigned short *buf
);
69 int main (int argc
, char **argv
)
72 static char usestr
[] = "Usage: bindump [-psv] filename...";
75 for (i
= 1; i
< argc
; i
++) {
85 phid
= TRUE
; // print only phase ID's
88 sort
= TRUE
; // sort deck by phases, writing to stdout
97 for (i
= 1; i
< argc
; i
++) {
105 void process (char *nm
)
112 if (strchr(nm
, '*') == NULL
&& strchr(nm
, '?') == NULL
)
115 else if ((hFind
= FindFirstFile(nm
, &fd
)) == INVALID_HANDLE_VALUE
)
116 fprintf(stderr
, "No files matching '%s'\n", nm
);
119 if ((c
= strrchr(nm
, '\\')) == NULL
)
120 c
= strrchr(nm
, ':');
123 if (fd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
130 strcpy(buf
+ (c
-nm
+1), fd
.cFileName
);
134 } while (FindNextFile(hFind
, &fd
));
139 dump(nm
); // on unices, sh globs for us
143 void dump (char *fname
)
155 unsigned short card
[80];
158 int cardcomp (const void *a
, const void *b
)
162 diff
= ((struct tag_card
*) a
)->phid
- ((struct tag_card
*) b
)->phid
;
164 return diff
? diff
: (((struct tag_card
*) a
)->seq
- ((struct tag_card
*) b
)->seq
);
167 void sort_phases (char *fname
)
169 int i
, ncards
, cardtype
, len
, seq
= 0, phid
;
170 struct tag_card
*deck
;
172 BOOL saw_sbrk
= TRUE
;
174 if ((fd
= fopen(fname
, "rb")) == NULL
) {
179 fseek(fd
, 0, SEEK_END
);
180 len
= ftell(fd
); // get length of file
181 fseek(fd
, 0, SEEK_SET
);
183 if (len
<= 0 || (len
% 160) != 0) {
184 fprintf(stderr
, "%s is not a binard deck image\n");
191 if ((deck
= (struct tag_card
*) malloc(ncards
*sizeof(struct tag_card
))) == NULL
) {
192 fprintf(stderr
, "%s: can't sort, insufficient memory\n");
198 for (i
= 0; i
< ncards
; i
++) {
199 if (fxread(deck
[i
].card
, sizeof(card
[0]), 80, fd
) != 80) {
201 fprintf(stderr
, "%s: error reading deck\n");
206 unpack(deck
[i
].card
, buf
);
210 verify_checksum(buf
);
212 cardtype
= (buf
[2] >> 8) & 0xFF;
214 if (cardtype
== 1 || cardtype
== 2) { // start of deck is same as sector break
217 else if (cardtype
== 0) {
218 fprintf(stderr
, "%s is a core image deck\n");
223 else if (cardtype
== 0x0A && saw_sbrk
) {
224 phid
= (int) (signed short) buf
[10];
228 deck
[i
].phid
= phid
; // this belongs to the new phase
229 deck
[i
-1].phid
= phid
; // as does previous card
235 qsort(deck
, ncards
, sizeof(struct tag_card
), cardcomp
); // sort the deck
238 _setmode(_fileno(stdout
), _O_BINARY
); // set standard output to binary mode
241 for (i
= 0; i
< ncards
; i
++) // write to stdout
242 fxwrite(deck
[i
].card
, sizeof(card
[0]), 80, stdout
);
247 void dump_phids (char *fname
)
251 BOOL saw_sbrk
= TRUE
, neg
;
254 if ((fp
= fopen(fname
, "rb")) == NULL
) {
259 printf("\n%s:\n", fname
);
261 while (fxread(card
, sizeof(card
[0]), 80, fp
) > 0) {
263 verify_checksum(buf
);
265 cardtype
= (buf
[2] >> 8) & 0xFF;
267 if (cardtype
== 1 && ! first
) { // sector break
274 printf(" This is a core image deck\n");
291 id
= -id
, neg
= TRUE
;
294 printf(" : %3d / %02x%s\n", id
, id
, neg
? " (neg)" : "");
310 void dump_data (char *fname
)
317 if ((fp
= fopen(fname
, "rb")) == NULL
) {
322 printf("\n%s:\n", fname
);
324 while (fxread(card
, sizeof(card
[0]), 80, fp
) > 0) {
326 verify_checksum(buf
);
328 cardtype
= (buf
[2] >> 8) & 0xFF;
330 if (cardtype
== 1 && ! first
) { // sector break
331 for (i
= 4; i
< 72; i
++)
332 str
[i
] = hollerith_to_ascii(card
[i
]);
336 printf("*SBRK %s\n", str
+4);
403 void show_data (void)
405 int i
, n
, jrel
, rflag
, nout
, ch
, reloc
;
410 printf("%04x: ", buf
[0]);
415 for (i
= 0; i
< n
; i
++) {
419 printf(" %s", getseq());
425 reloc
= (rflag
>> 14) & 0x03;
426 ch
= (reloc
== R_ABSOLUTE
) ? ' ' :
427 (reloc
== R_RELATIVE
) ? 'R' :
428 (reloc
== R_LIBF
) ? 'L' : '@';
430 printf("%04x%c ", buf
[9+i
], ch
);
437 void show_core (void)
444 printf("%04x: ", buf
[0]);
447 for (i
= 0; i
< n
; i
++) {
450 printf(" %s", getseq());
456 printf("%04x ", buf
[9+i
]);
462 void info (int i
, char *nm
, char type
)
469 printf("%d ", buf
[i
]);
473 printf("%04x ", buf
[i
]);
477 printf("%02x ", buf
[i
] & 0xFF);
481 printf("%s ", getname(buf
+i
));
489 void show_main (void)
492 info(2, "prec", 'b');
493 info(4, "common", 'd');
494 info(6, "work", 'd');
495 info(8, "files", 'd');
496 info(9, "name", 'n');
497 info(11, "pta", 'x');
506 info( 2, "prec", 'b');
509 for (i
= 0; i
< n
; i
++) {
510 info( 9+3*i
, "ent", 'n');
511 info(11+3*i
, NULL
, 'x');
520 info(12, "level", 'd');
527 info( 2, "prec", 'b');
528 info( 5, "nint6", 'd');
529 info( 9, "ent", 'n');
531 info(14, "nint", 'd');
532 info(15, "il1", 'd');
533 info(16, "il2", 'd');
540 info(0, "size", 'd');
548 info(52, "IX3", 'x');
549 info(53, "pta", 'x');
557 void show_raw (char *name
)
562 for (i
= 0; i
< 12; i
++)
563 printf(" %04x", buf
[i
]);
565 printf(" %s\n", getseq());
573 for (i
= 0; i
< 8; i
++)
574 seq
[i
] = hollerith_to_ascii(card
[72+i
]);
581 void bail (char *msg
)
583 fprintf(stderr
, "%s\n", msg
);
587 void unpack (unsigned short *icard
, unsigned short *obuf
)
590 unsigned short wd1
, wd2
, wd3
, wd4
;
592 for (i
= j
= 0; i
< 54; i
+= 3, j
+= 4) {
598 obuf
[i
] = (wd1
& 0xFFF0) | ((wd2
>> 12) & 0x000F);
599 obuf
[i
+1] = ((wd2
<< 4) & 0xFF00) | ((wd3
>> 8) & 0x00FF);
600 obuf
[i
+2] = ((wd3
<< 8) & 0xF000) | ((wd4
>> 4) & 0x0FFF);
604 void verify_checksum (unsigned short *obuf
)
606 // unsigned short sum;
608 if (obuf
[1] == 0) // no checksum
611 // if (sum != card[1])
612 // printf("Checksum %04x doesn't match card %04x\n", sum, card[1]);
616 unsigned short hollerith
;
620 static CPCODE cardcode_029
[] =
623 0x8000, '&', // + in 026 Fortran
663 0x0420, '#', // = in 026 Fortran
664 0x0220, '@', // ' in 026 Fortran
670 0x8220, '<', // ) in 026 Fortran
680 0x2820, 'x', // what?
682 0x2220, '%', // ( in 026 Fortran
688 int hollerith_to_ascii (unsigned short h
)
694 for (i
= 0; i
< sizeof(cardcode_029
) / sizeof(CPCODE
); i
++)
695 if (cardcode_029
[i
].hollerith
== h
)
696 return cardcode_029
[i
].ascii
;
701 // ---------------------------------------------------------------------------------
702 // trim - remove trailing whitespace from string s
703 // ---------------------------------------------------------------------------------
709 for (nb
= s
-1; *s
; s
++)
716 int ascii_to_ebcdic_table
[128] =
718 0x00,0x01,0x02,0x03,0x37,0x2d,0x2e,0x2f, 0x16,0x05,0x25,0x0b,0x0c,0x0d,0x0e,0x0f,
719 0x10,0x11,0x12,0x13,0x3c,0x3d,0x32,0x26, 0x18,0x19,0x3f,0x27,0x1c,0x1d,0x1e,0x1f,
720 0x40,0x5a,0x7f,0x7b,0x5b,0x6c,0x50,0x7d, 0x4d,0x5d,0x5c,0x4e,0x6b,0x60,0x4b,0x61,
721 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, 0xf8,0xf9,0x7a,0x5e,0x4c,0x7e,0x6e,0x6f,
723 0x7c,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7, 0xc8,0xc9,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,
724 0xd7,0xd8,0xd9,0xe2,0xe3,0xe4,0xe5,0xe6, 0xe7,0xe8,0xe9,0xba,0xe0,0xbb,0xb0,0x6d,
725 0x79,0x81,0x82,0x83,0x84,0x85,0x86,0x87, 0x88,0x89,0x91,0x92,0x93,0x94,0x95,0x96,
726 0x97,0x98,0x99,0xa2,0xa3,0xa4,0xa5,0xa6, 0xa7,0xa8,0xa9,0xc0,0x4f,0xd0,0xa1,0x07,
729 char *getname (unsigned short *ptr
)
735 v
= (ptr
[0] << 16L) | ptr
[1];
737 for (i
= 0; i
< 5; i
++) {
738 ch
= ((v
>> 24) & 0x3F) | 0xC0; // recover those lost two bits
743 for (j
= 0; j
< (sizeof(ascii_to_ebcdic_table
)/sizeof(ascii_to_ebcdic_table
[0])); j
++) {
744 if (ascii_to_ebcdic_table
[j
] == ch
) {