I'm fairly sure Acorn had an approach to relocating code at one point: I think the ROM image was followed by a list of patch-up addresses. I'm not sure though that there's any approach in Acorn land to run code where the load address is not known until load time - it would be useful if there were, because in Acorn land the free RAM, after OS use, can start (and end) at a variety of places. Sometimes an application might load at 400, or at E00, or 1900, or 8000, or B800, depending. Other places too.
What would be nice then, would be an approach and a format which will run anywhere, possibly relocating itself. At least two things are needed:
- an executable header which is position independent and able to discover its location
- a means of patching up absolute addresses in the code
and possibly
- a means of block-moving the loaded and patched code to a different location
For discovering location, I had this thought:
- Use a few bytes just below 0200, having first saved those values on the stack
- place a routine there, call it, and it will examine the stack and report back
For example, this code
Code:
PLA
TAX
PLA
TAY
PHA
TXA
PHA
RTS
would pick its own return address (-1) from the stack. Being 8 bytes, we'd place it at 01f8, and we'd need first to save those 8 bytes from the bottom of the stack, on the stack. Something like
Code:
LDX #7
LDA 01f8,x
PHA
DEX
BPL *-5
(Edit: we need first to be sure the stack is already at least 8 bytes deep! Maybe check S, or just subtract from S, or do a bunch of pushes.)
Then we'd need to store the code using immediate values
Code:
LDA #PLA
STA 01f8
STA 01fa
LDA #TAX
STA 01f9
LDA #TAY
STA 01fb
LDA #PHA
STA 01fc
STA 01fe
LDA #TXA
STA 01fd
LDA #RTS
STA 01ff
Now we can call the code, and then repair the stack.
(We will of course need some workspace: in Acorn land there are known areas of zero page available to applications. Possibly it's worth somehow parameterising which section of zero page we use. We can use the stack to save anything we might intend to trample on temporarily.)
How to patch up absolute addresses? One approach is to have a list of addresses to patch, or possibly delta-encode that list. Or possibly use a byte-stuffing tactic and have a special value to stand for each address MSB.
(If I've made any small mistakes, please let me know by PM and I'll correct them.)
But more interesting: have I missed some good way to tackle this, or not noticed some obstacle? Or prior art?