diff options
author | B. Watson <urchlay@slackware.uk> | 2024-04-29 18:37:04 -0400 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2024-04-29 18:37:04 -0400 |
commit | d592ce4834411a63c89670f7990e86ae5dbaf40f (patch) | |
tree | 9bad05fe6fcd1bf14b8ddef80329d66ecb36c16a | |
parent | e43fb619b7782f64fa5e8c68c7b49536a5180073 (diff) | |
download | bw-atari8-tools-d592ce4834411a63c89670f7990e86ae5dbaf40f.tar.gz |
xex.c: add xex_get_run_addr() and xex_get_init_addr().
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | xex.c | 22 | ||||
-rw-r--r-- | xex.h | 8 |
3 files changed, 32 insertions, 1 deletions
@@ -2,7 +2,8 @@ for now: These may need library (xex.c) changes: xexcat: handle run/init addresses embedded in a segment longer than 2 bytes. -xexcat: handle or at least detect DOS 1.0 executables. +xexcat: handle or at least detect DOS 1.0 executables. currently + xex_fread_seg_header() will warn about them, but that's all. xexcat: warn if an an init address occurs before the code it references. or at least if it occurs before *any* code! @@ -114,6 +114,10 @@ int xex_fread_seg_header(xex_segment *seg, FILE *file) { if(d == EOF) return 0; addr = XEX_ADDR(c, d); + if(addr == 0x0984) { + fprintf(stderr, "xex_fread_seg_header(): warning: this might be a DOS 1.0 file (not supported)\n"); + } + if(addr == 0xffff) { seg->has_ff_header = 1; c = read_char(file); @@ -289,6 +293,24 @@ int xex_check_seg(xex_segment *seg) { return ret; } +static int xex_get_addr_from(xex_segment *seg, int location) { + int i; + + if(seg->start_addr > location) return -1; + if(seg->end_addr <= location) return -1; + + i = location - seg->start_addr; + return XEX_ADDR(seg->object[i], seg->object[i + 1]); +} + +int xex_get_run_addr(xex_segment *seg) { + return xex_get_addr_from(seg, XEX_RUNAD); +} + +int xex_get_init_addr(xex_segment *seg) { + return xex_get_addr_from(seg, XEX_INITAD); +} + char *xex_strerror(int err) { if(err < 0 || err >= XERR_MAXERR) err = XERR_MAXERR; @@ -104,6 +104,14 @@ int xex_get_object(xex_segment *seg, unsigned char *data); Returns true if segment is OK. */ int xex_check_seg(xex_segment *seg); +/* Get run address from a segment, if there is one. This can handle the case + where the address is embedded in a larger segment (that doesn't just consist + of 2 bytes loaded at RUNAD). Returns -1 if there is no run address. */ +int xex_get_run_addr(xex_segment *seg); + +/* Same as above, for init address. */ +int xex_get_init_addr(xex_segment *seg); + /* Get human-readable error message. If xex_errno is XSYSCALL, the system's strerror() is called. */ char *xex_strerror(int err); |