aboutsummaryrefslogtreecommitdiff
path: root/xexamine.c
diff options
context:
space:
mode:
Diffstat (limited to 'xexamine.c')
-rw-r--r--xexamine.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/xexamine.c b/xexamine.c
index fc600f1..d47993e 100644
--- a/xexamine.c
+++ b/xexamine.c
@@ -42,8 +42,7 @@ void crc32(const void *data, size_t n_bytes, uint32_t* crc) {
}
void usage(int status) {
- printf("Usage: " SELF " [-v] [-s segment] file.xex\n");
- if(status) fprintf(stderr, "Try '%s -h' for help\n", SELF);
+ printf("Usage: " SELF " [-h] [-d] [-v] [-s segment] file.xex\n");
exit(status);
}
@@ -310,11 +309,14 @@ int main(int argc, char **argv) {
xex_segment seg;
unsigned char buffer[65536];
char *filename;
- int opt, segcount = 0, only_segment = 0, header_printed = 0;
+ int opt, offset, segcount = 0, only_segment = 0, header_printed = 0, decimal = 0;
uint32_t crc;
- while((opt = getopt(argc, argv, "vhs:")) != -1) {
+ while((opt = getopt(argc, argv, "vhs:d")) != -1) {
switch(opt) {
+ case 'd':
+ decimal = 1;
+ break;
case 's':
if( (only_segment = get_address(SELF, optarg)) < 0 )
exit(1);
@@ -335,7 +337,13 @@ int main(int argc, char **argv) {
}
}
- if(optind >= argc || argv[optind + 1]) {
+ if(argv[optind + 1]) {
+ fprintf(stderr, SELF ": don't know what to do with excess argument '%s'.\n", argv[optind + 1]);
+ usage(1);
+ }
+
+ if(optind >= argc) {
+ fprintf(stderr, SELF ": no xex file argument.\n");
usage(1);
}
@@ -348,25 +356,36 @@ int main(int argc, char **argv) {
seg.object = buffer;
+ offset = 0;
while(xex_fread_seg(&seg, f)) {
segcount++;
- if(only_segment && (only_segment != segcount))
- continue;
- if(!header_printed) {
- printf("Seg | Start | End | Bytes | CRC32 | Type\n");
- header_printed++;
- }
+
crc = 0;
crc32(seg.object, seg.len, &crc);
- printf("%3d | $%04x | $%04x | %5d | %08x | ",
- segcount, seg.start_addr, seg.end_addr, seg.len, crc);
- if(seg.start_addr == XEX_RUNAD && seg.len > 1)
- printf("Run $%04x", (seg.object[0] | (seg.object[1] << 8)));
- else if(seg.start_addr == XEX_INITAD && seg.len > 1)
- printf("Init $%04x", (seg.object[0] | (seg.object[1] << 8)));
- else printf("%d%% code", classify_seg(seg));
-
- putchar('\n');
+
+ if(!only_segment || (only_segment == segcount)) {
+ if(!header_printed) {
+ printf("Seg | Offset | Start | End | Bytes | CRC32 | Type\n");
+ header_printed++;
+ }
+
+ printf((decimal ?
+ "%3d | %6d | %5d | %5d | %5d | %08x | " :
+ "%3d | %6d | $%04x | $%04x | %5d | %08x | "),
+ segcount, offset, seg.start_addr, seg.end_addr, seg.len, crc);
+
+ /* TODO: what if there's a >=4 byte segment that loads at RUNAD?
+ the next 2 bytes are INITAD, we would silently ignore that fact. */
+ if(seg.start_addr == XEX_RUNAD && seg.len > 1)
+ printf((decimal ? "Run %5d" : "Run $%04x"), (seg.object[0] | (seg.object[1] << 8)));
+ else if(seg.start_addr == XEX_INITAD && seg.len > 1)
+ printf((decimal ? "Init %5d" : "Run $%04x"), (seg.object[0] | (seg.object[1] << 8)));
+ else printf("%d%% code", classify_seg(seg));
+
+ putchar('\n');
+ }
+
+ offset = ftell(f);
}
if(only_segment && (segcount < only_segment)) {