aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.txt60
1 files changed, 42 insertions, 18 deletions
diff --git a/README.txt b/README.txt
index 189b886..6edc292 100644
--- a/README.txt
+++ b/README.txt
@@ -1,9 +1,29 @@
-How to do a self-relocating Atari 8-bit executable...
+Atari 8-Bit Self Relocator
+--------------------------
This is a modified form of a technique I saw in Bill Wilkinson's
Insight: Atari column in Compute! magazine (Issue 21, Feb 1982).
+To build the relocator and run the demo, you'll need:
+
+- cc65 from https://cc65.github.io/
+- axe from https://slackware.uk/~urchlay/repos/bw-atari8-tools
+
+...as well as standard Linux packages like make and perl.
+
+To build, just type "make". The result is "reloc.atr", which is
+an Atari disk image with DOS 2.0S and the relocatable program as
+AUTORUN.SYS. Boot the disk on an Atari or emulator to see it run.
+
+The demo just shows "Hello World" with changing colors. The important
+part is that it got relocated to MEMLO and run from there. The code
+isn't relocatable (see the souce, "hello.s"). The relocator adjusted
+all the absolute addresses on the fly (at load time).
+
+How it works
+------------
+
In the original scheme, you'd assemble the code twice, with the origin
(start address) one page apart. Say, assemble at address $4000, then
the 2nd time at $4100. Now, any bytes in the two object files that
@@ -60,26 +80,30 @@ The relocator has to know the load address and the length of the main
segment of the program (the part it's going to relocate). What it
does:
-1. Subtract the load address ($4000 in the example) from the contents
- of MEMLO. This gives us a negative number (we hope!) that is the
- amount each address in the program should have added to it.
+1. Subtract the contents of MEMLO from the load address ($4000 in the
+ example). This gives us a positive number (we hope!) that is the
+ amount each address in the program should have subtracted from it.
-2. Iterate over the two data tables, adding the offset. Each table entry
+2. Iterate over the two data tables, subtracting the offset. Each table entry
is the two-byte address of a byte that needs to be changed (an
absolute address that's "baked" into the program). The high and low
bytes of the addresses in the code are handled separately (hence
- the two tables). The low byte of the offset is added to the bytes
- at the addresses in the low-byte table, and the high byte of the
- offset for the high-byte table.
+ the two tables). The low byte of the offset is subtracted from the
+ bytes at the addresses in the low-byte table, and the high byte of
+ the offset for the high-byte table.
-3. Moves the main segment to MEMLO.
+3. Move the main segment to MEMLO.
4. Set MEMLO to point to the byte after the end of the program
to protect it from being overwritten by e.g. BASIC or ASM/ED.
-5. Add the offset to the contents of RUNAD, which is the run address
- of the program, and then do an RTS to hand control back to DOS.
- DOS will run the relocated code by jumping to the altered RUNAD.
+5. If the program has an init address, subtract the offset from it,
+ then jump to it. This runs the payload program's init routine.
+
+5. If the program has a run address, subtract the offset from it,
+ storing the result in RUNAD. Then do an RTS to hand control back
+ to DOS. DOS will run the relocated code by jumping to the altered
+ RUNAD, in the usual way.
Notes:
@@ -120,12 +144,12 @@ Notes:
cartridge would require 1522 bytes of data tables, if we were trying
to relocate it.
-- The original Wilkinson scheme was done entirely in Atari BASIC. I
- use a C program to create the relocation tables, and the relocator
- itself becomes part of the relocatable program, so BASIC is not
- required. The C program can be run on either the Atari or on
- a modern POSIX system, which is especially useful if you use a
- cross-assembler to write and assemble your Atari code.
+- The original Wilkinson scheme was done entirely in Atari BASIC.
+ I use a perl script to create the relocation tables and the
+ relocator itself becomes part of the relocatable program, so BASIC
+ is not required. The perl script will be rewritten in C at some
+ point, and the the C program will run on either the Atari or on
+ a modern POSIX system.
- Indirect JMP instructions should always be used with care on the
6502. The two operand bytes have to be in the same page, due to a