diff options
author | B. Watson <urchlay@slackware.uk> | 2025-04-29 05:03:09 -0400 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2025-04-29 05:03:09 -0400 |
commit | efc924ac9a62c65d32c8e11875bf5a1d7088a1f8 (patch) | |
tree | 19e49998fcb7ecdbe289ba4344ba0def098de142 | |
parent | 705f19cae38eb3e6a7e434979ec7a89dc8a1c732 (diff) | |
download | atari8-self-relocator-efc924ac9a62c65d32c8e11875bf5a1d7088a1f8.tar.gz |
mkreloc.c: added (will replace mkrelocxex.pl).
-rw-r--r-- | Makefile | 32 | ||||
-rw-r--r-- | autorun.sys | bin | 1151 -> 1148 bytes | |||
-rw-r--r-- | mkreloc.c | 298 |
3 files changed, 325 insertions, 5 deletions
@@ -1,19 +1,41 @@ -all: reloc.atr reloc25.atr +all: reloc.atr reloc25.atr native.atr reloc25.atr: reloc.atr cp dos25_4drives.atr reloc25.atr axe -w autorun.sys reloc25.atr -reloc.atr: reloc.xex hello40.xex hello41.xex mkrelocxex.pl autorun.sys +reloc.atr: reloc.xex hello40.xex hello41.xex autorun.sys cp dos_20s.atr reloc.atr axe -w autorun.sys reloc.atr -autorun.sys: reloc.xex hello40.xex hello41.xex - ./mkrelocxex.pl hello40.xex hello41.xex autorun.sys +native.atr: mkreloc.xex reloc.xex autorun.sys + cp dos_20s.atr native.atr + axe -w lo.xex native.atr + axe -w hi.xex native.atr + axe -w reloc.xex native.atr + axe -w mkreloc.xex native.atr + +autorun.sys: reloc.xex hello40.xex hello41.xex mkreloc + cp hello40.xex lo.xex + cp hello41.xex hi.xex + ./mkreloc reloc.xex: reloc.s mkrelocxex.pl cl65 -t none -o reloc.xex reloc.s +mkreloc.xex: mkreloc.c + cl65 -t atari -o mkreloc.xex mkreloc.c + +#reloc.atr: reloc.xex hello40.xex hello41.xex mkrelocxex.pl autorun.sys +# cp dos_20s.atr reloc.atr +# axe -w autorun.sys reloc.atr +# +#autorun.sys: reloc.xex hello40.xex hello41.xex +# ./mkrelocxex.pl hello40.xex hello41.xex autorun.sys +# +#reloc.xex: reloc.s mkrelocxex.pl +# cl65 -t none -o reloc.xex reloc.s + hello40.xex: hello.s cl65 -t none -o hello40.xex --asm-define start_addr=0x4000 hello.s @@ -21,4 +43,4 @@ hello41.xex: hello.s cl65 -t none -o hello41.xex --asm-define start_addr=0x4100 hello.s clean: - rm -f reloc.atr hello40.xex hello41.xex reloc.xex *.o + rm -f reloc.atr hello40.xex hello41.xex reloc.xex mkreloc mkreloc.xex native.atr reloc25.atr *.o diff --git a/autorun.sys b/autorun.sys Binary files differindex 848e3c3..3768f29 100644 --- a/autorun.sys +++ b/autorun.sys diff --git a/mkreloc.c b/mkreloc.c new file mode 100644 index 0000000..35c6cd7 --- /dev/null +++ b/mkreloc.c @@ -0,0 +1,298 @@ +/* this can be compiled for either POSIX or Atari 8-bit. + it's got some weird constructs because sizeof(int) is 16 bits + on the Atari. also, I've avoided printf() to keep the .xex + size down. */ + +#include <stdio.h> +#include <stdint.h> +#include <unistd.h> +#include <stdlib.h> + +#define u8 uint8_t +#define u16 uint16_t + +#ifdef __ATARI__ +#define low_infile "D:LO.XEX" +#define hi_infile "D:HI.XEX" +#define reloc_file "D:RELOC.XEX" +#define out_file "D:AUTORUN.SYS" +#else +#define low_infile "lo.xex" +#define hi_infile "hi.xex" +#define reloc_file "reloc.xex" +#define out_file "autorun.sys" +#endif + +#define MAX_SIZE 18880U +#define TBL_SIZE 2360 + +u8 bitmap[TBL_SIZE]; +u16 bitmap_idx = 0; + +void errexit(void) { +#ifdef __ATARI__ + fputs("Press Return to exit.", stdout); + getc(stdin); +#endif + exit(1); +} + +void errfile(const char *fn) { + fputs(fn, stderr); + fputc(':', stderr); + fputc(' ', stderr); +} + +void invalid_xex(const char *fn) { + errfile(fn); + fputs("not a valid XEX file.\n", stderr); + errexit(); +} + +void err_trunc(const char *fn) { + errfile(fn); + fputs("truncated.\n", stderr); + errexit(); +} + +void bad_diff(const char *fn) { + errfile(fn); + fputs("not $100 above.\n", stderr); + errexit(); +} + +void bad_length(const char *fn) { + errfile(fn); + fputs("length mismatch.\n", stderr); + errexit(); +} + +void too_long(const char *fn) { + errfile(fn); + fputs("code segment too long.\n", stderr); + errexit(); +} + +void bad_byte(const char *fn) { + errfile(fn); + fputs("bytes differ by other than 0 or 1.\n", stderr); + errexit(); +} + +void invalid_seg(const char *fn) { + errfile(fn); + fputs("only one code segment allowed.\n", stderr); + errexit(); +} + +u16 read_word(const char *fh, FILE *f) { + u16 word; + int c; + + c = fgetc(f); + if(c < 0) err_trunc(fh); + word = (u8)c; + + c = fgetc(f); + if(c < 0) err_trunc(fh); + word |= ((u8)c) << 8; + + return word; +} + +int read_header(FILE *f, u16 *s, u16 *e) { + u16 a; + int c; + + c = fgetc(f); + if(c < 0) return 0; + a = (u8)c; + + c = fgetc(f); + if(c < 0) return 0; + a |= ((u8)c) << 8; + + if(a == 0xffff) { + c = fgetc(f); + if(c < 0) return 0; + a = (u8)c; + + c = fgetc(f); + if(c < 0) return 0; + a |= ((u8)c) << 8; + } + + *s = a; + + c = fgetc(f); + if(c < 0) return 0; + a = (u8)c; + + c = fgetc(f); + if(c < 0) return 0; + a |= ((u8)c) << 8; + + *e = a; + + return 1; +} + +void write_word(FILE *f, u16 word) { + fputc(word & 0xff, f); + fputc(word >> 8, f); +} + +void add_bit(u8 bit) { + static u16 pos = 0; + u8 i; + + bitmap_idx = pos / 8; + i = 7 - (pos % 8); + bitmap[bitmap_idx] |= (bit * (1 << i)); + + pos++; +} + +void append_bitmap(FILE *f) { + fwrite(bitmap, bitmap_idx + 1, 1, f); +} + +void read_run_init(const char *fn, FILE *f, u16 *run, u16 *init) { + u16 s, e; + *run = *init = 0; + + while(read_header(f, &s, &e)) { + if(s == 0x02e0) { + if(e == 0x02e1) { + *run = read_word(fn, f); + } else if(e == 0x02e3) { + *run = read_word(fn, f); + *init = read_word(fn, f); + } else { + invalid_seg(fn); + } + } else if(s == 0x02e2 && e == 0x02e3) { + *init = read_word(fn, f); + } else { + invalid_seg(fn); + } + } +} + +FILE *open_file(const char *fn, const char *mode) { + FILE *fh = fopen(fn, mode); + if(!fh) { + errfile(fn); + perror(fn); + errexit(); + } + return fh; +} + +FILE *open_input(const char *fn) { + return open_file(fn, "rb"); +} + +FILE *open_output(const char *fn) { + return open_file(fn, "wb"); +} + +int main(int, char **) { + int c; + u8 a, b; + u16 hi_start, hi_end, lo_start, lo_end, lo_len; + u16 run_addr = 0, init_addr = 0; + FILE *lo, *hi, *rel, *out; + +#if 0 + /* if we were actually printing anything... */ +#ifdef __ATARI__ + *((char *)0x2be) = 0x40; /* enable caps lock */ + putchar(0x9c); /* delete line (cursor to left margin) */ +#endif +#endif + + /* open and check the two .xex input files */ + lo = open_input(low_infile); + hi = open_input(hi_infile); + + if(!read_header(lo, &lo_start, &lo_end)) { + invalid_xex(low_infile); + } + + if(!read_header(hi, &hi_start, &hi_end)) { + invalid_xex(hi_infile); + } + + if(hi_start != (lo_start + 0x100)) + bad_diff(hi_infile); + + lo_len = lo_end - lo_start + 1; + if(lo_len != (hi_end - hi_start + 1)) + bad_length(hi_infile); + + if(lo_len >= MAX_SIZE) + too_long(hi_infile); + + out = open_output(out_file); + + write_word(out, 0xffffU); + write_word(out, lo_start); + write_word(out, lo_end); + + /* read segment data, create bitmap */ + while(lo_len--) { + c = fgetc(lo); + if(c < 0) err_trunc(low_infile); + a = (u8)c; + fputc(a, out); + + c = fgetc(hi); + if(c < 0) err_trunc(hi_infile); + b = (u8)c; + + if(a == b) { + add_bit(0); + } else if(a == (b - 1)) { + add_bit(1); + } else { + bad_byte(hi_infile); + } + } + + fclose(hi); + + read_run_init(low_infile, lo, &run_addr, &init_addr); + + /* append the relocator */ + rel = open_input(reloc_file); + read_header(rel, &hi_start, &hi_end); + write_word(out, 0xffffU); + write_word(out, hi_start); + write_word(out, hi_end + bitmap_idx + 1 + 8); + + while((c = fgetc(rel)) >= 0) { + fputc(c & 0xff, out); + } + fclose(rel); + + /* append the address table */ + write_word(out, lo_start); + write_word(out, lo_end); + write_word(out, run_addr); + write_word(out, init_addr); + + /* append the bitmap */ + append_bitmap(out); + + /* append the init address */ + // write_word(out, 0xffffU); + write_word(out, 0x2e2); + write_word(out, 0x2e3); + write_word(out, 0x71c0); + + fclose(out); + + return 0; +} + |