diff options
author | B. Watson <urchlay@slackware.uk> | 2024-04-27 15:44:40 -0400 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2024-04-27 15:44:40 -0400 |
commit | d70164ccbb3846e2fbf5e73cb3b636b0c7aa0b8e (patch) | |
tree | f4355fea629b88416d3852607fd8fb897735c738 | |
parent | 5a64858554fb32d9b9833a2abaa1213d3e9084c2 (diff) | |
download | bw-atari8-tools-d70164ccbb3846e2fbf5e73cb3b636b0c7aa0b8e.tar.gz |
xexcat: implement -f2.
-rw-r--r-- | xexcat.c | 78 |
1 files changed, 62 insertions, 16 deletions
@@ -29,28 +29,74 @@ char *usage = " -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) { +static int readaddr(FILE *f) { int i, j; + if( (i = fgetc(f)) < 0 ) + return -1; + if( (j = fgetc(f)) < 0 ) + return -1; + + return i | (j << 8); +} + +/* byte 0 = LSB of load address, byte 1 = MSB, rest = data. */ +int read_f1(xex_segment *seg, FILE *f) { + int i, addr, c; + + addr = readaddr(f); + if(addr < 0) + return 0; + + seg->start_addr = addr; + for(i = 0; (i < 65536) && ((c = fgetc(f)) >= 0); i++) { + seg->object[i] = c; + seg->len++; + } + + /* guard against the file being >64K length */ + fseek(f, 0, SEEK_END); + + seg->end_addr = seg->start_addr + seg->len - 1; + seg->has_ff_header = 1; + + return (i != 0); +} + +/* -f2 is segmented, each segment starts with a 4-byte header: + 0/1 are LSB/MSB of start address, 2/3 are LSB/MSB of length. */ +int read_f2(xex_segment *seg, FILE *f) { + int i, addr, c; + + addr = readaddr(f); + if(addr < 0) + return 0; + + seg->start_addr = addr; + + addr = readaddr(f); + if(addr < 0) + return 0; + seg->len = addr; + + for(i = 0; (i < seg->len) && ((c = fgetc(f)) >= 0); i++) { + if(c < 0) return 0; + seg->object[i] = c; + } + + seg->end_addr = seg->start_addr + seg->len - 1; + seg->has_ff_header = 1; + xex_print_seg_info(seg); + return 1; +} + +int read_seg(xex_segment *seg, FILE *f, int type) { 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); + return read_f1(seg, f); case 2: - return 0; + return read_f2(seg, f); case 0: default: |