aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xexcat.c78
1 files changed, 62 insertions, 16 deletions
diff --git a/xexcat.c b/xexcat.c
index c4234bd..46f418e 100644
--- a/xexcat.c
+++ b/xexcat.c
@@ -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: