diff options
Diffstat (limited to 'xexcat.c')
-rw-r--r-- | xexcat.c | 65 |
1 files changed, 59 insertions, 6 deletions
@@ -12,20 +12,51 @@ #endif #define SELF "xexcat" -#define OPTIONS "hvo:l:r:i:c" +#define OPTIONS "hvo:l:r:i:cf:a" char *usage = SELF " v" VERSION " - by B. Watson (WTFPL)\n" "Join one or more Atari 8-bit executables into one multi-segment file.\n" - "usage: " SELF " -[hvc] [-l address] [-i address] [-r address]\n" + "usage: " SELF " -[hvc] [-f 1|2 ] [-l address] [-i address] [-r address]\n" " [-o outfile.xex] [infile1.xex] [infile2.xex ...]\n" - " -h Print this help\n" " -o outfile.xex Output file (default: standard output)\n" + " -h Print this help\n" " -v Verbose operation\n" " -c Check only; no output (same as -v -o/dev/null)\n" " -l address Force first load address (decimal, $hex, or 0xhex)\n" " -i address Force first init address\n" - " -r address Force run address\n"; + " -r address Force run address\n" + " -a Force run address to load address of 1st segment.\n" + " -f 1|2 Input is DASM -f1 or -f2 format, not xex.\n"; + +int read_seg(xex_segment *seg, FILE *f, int type) { + int i, j; + + switch(type) { + /* byte 0 = LSB of load address, byte 1 = MSB, rest = data. */ + case 1: + if( (i = fgetc(f)) < 0 ) + return 0; + if( (j = fgetc(f)) < 0 ) + return 0; + seg->start_addr = i | (j << 8); + for(i = 0; (i < 65536) && ((j = fgetc(f)) >= 0); i++) { + seg->object[i] = j; + seg->len++; + } + seg->end_addr = seg->start_addr + seg->len - 1; + seg->has_ff_header = 1; + xex_print_seg_info(seg); + return (i != 0); + + case 2: + return 0; + + case 0: + default: + return xex_fread_seg(seg, f); + } +} int main(int argc, char **argv) { xex_segment seg; @@ -34,7 +65,8 @@ int main(int argc, char **argv) { int count = 1, c, errcount = 0; unsigned char buffer[65536]; /* be lazy: statically allocate large buffer */ int force_load = -1, force_run = -1, force_init = -1; - int read_stdin = 0; + int read_stdin = 0, run_1st_seg = 0; + int input_type = 0; /* 0 = xex, 1 and 2 are dasm -f1/-f2. */ /* parse args */ while( (c = getopt(argc, argv, OPTIONS)) > 0) { @@ -72,6 +104,18 @@ int main(int argc, char **argv) { exit(1); break; + case 'f': + input_type = atoi(optarg); + if(input_type < 1 || input_type > 2) { + fprintf(stderr, SELF ": invalid -f argument (must be 1 or 2).\n"); + exit(1); + } + break; + + case 'a': + run_1st_seg = 1; + break; + default: fprintf(stderr, usage); exit(1); @@ -122,13 +166,22 @@ int main(int argc, char **argv) { fprintf(stderr, SELF ": reading from file %s\n", infile); /* process every segment in current input file */ - while(xex_fread_seg(&seg, in)) { + while(read_seg(&seg, in, input_type)) { if(filecount++ == 1 && !seg.has_ff_header) { fprintf(stderr, SELF ": warning: '%s' first segment " "lacks $FFFF header (bad/partial XEX file?)\n", infile); } + if(run_1st_seg && (force_run == -1)) { + force_run = seg.start_addr; + if(xex_verbose) + fprintf(stderr, + SELF ": %s: setting run address to %04X " + "due to -a option\n", + infile, force_run); + } + /* normalize the $FFFF headers: only the first segment needs one */ seg.has_ff_header = (count == 1); |