aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2024-04-29 18:37:04 -0400
committerB. Watson <urchlay@slackware.uk>2024-04-29 18:37:04 -0400
commitd592ce4834411a63c89670f7990e86ae5dbaf40f (patch)
tree9bad05fe6fcd1bf14b8ddef80329d66ecb36c16a
parente43fb619b7782f64fa5e8c68c7b49536a5180073 (diff)
downloadbw-atari8-tools-d592ce4834411a63c89670f7990e86ae5dbaf40f.tar.gz
xex.c: add xex_get_run_addr() and xex_get_init_addr().
-rw-r--r--TODO3
-rw-r--r--xex.c22
-rw-r--r--xex.h8
3 files changed, 32 insertions, 1 deletions
diff --git a/TODO b/TODO
index bb1f1a6..d656b9a 100644
--- a/TODO
+++ b/TODO
@@ -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!
diff --git a/xex.c b/xex.c
index e4b66ce..8584286 100644
--- a/xex.c
+++ b/xex.c
@@ -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;
diff --git a/xex.h b/xex.h
index 2300481..2b113fc 100644
--- a/xex.h
+++ b/xex.h
@@ -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);