Hi John,
So based on Ron's research, the WHEREAMI function in ROM can be used as
another way to perform a relative branch without the need for a fixed
location in RAM:
LXI D, branch_offset ; Calculated relative to the DAD D opcode
below
CALL WHEREAMI ; 31E9H or 3F3DH. HL now contains address
of DAD D opcode on next line
DAD D ; Perform relative address calculation
POP D ; Pop old HL value from Stack
PCHL ; Jump to new relative location
And if you need a conditional relative jump, you can do:
LXI D, branch_offset ; Calculated relative to the DAD D opcode
below
CALL WHEREAMI ; 31E9H or 3F3DH. HL now contains address
of DAD D opcode on next line
DAD D ; Perform relative address calculation
POP D ; Pop old HL value from Stack
JZ (or JNZ, etc.) 0ED7H ; Conditional jump to a PCHL opcode
; Fall though if condition not met
Ken
On 5/31/18 12:49 PM, John R. Hogerhuis wrote:
Self-locating code.
Ron Wiesen did some research a long time ago to figure out code in the
ROM that could tell you where you are calling from.
This is a critical part of code that can efficiently relocate itself
to run-in-place or at a specific location.
-- John.
---------- Forwarded message ----------
From: *Ron Wiesen* <[email protected] <mailto:[email protected]>>
Date: Thu, Nov 9, 2006 at 2:25 AM
Subject: Reporting Breakthrough for "Run In Place" Operation -- Was
Re: Remem : relocatable ML codes.
To: Model 100 Listserve <[email protected]
<mailto:[email protected]>>
Previously I wrote:
> But your "relocatable ML codes" message has reminded me of some
progress I
> recently made on a mission that was placed on the "back burner" a long
time
> ago. So I'll review my mission notes and report my progress to this
list.
>
> The mission was to develop the means for software, operating in a
M10x or
> M200 laptop, to discovered the memory address of "Where I am Now". I've
> found four methods to do it, tested all four of them, and believe I've
> determined which is the "best" method of the four. Having the means to
> ascertain "Where I am Now" is a long sought after breakthrough. It's
> something that's essential in obtaining a substantial improvement in the
> "Run In Place" operation of binary objects; the improvement eliminates
need
> for the separate utility that launches said binary objects. "Run In
Place"
> operation of binary objects avoids need for a HIMEM area and avoids the
> double-consumption penalty that ordinary invocation of binary objects.
The "Self-Locate" snippet shown below is my report, which details the
"best"
method of the four methods that I found and tested. Details are given for
both the Model 10x laptop (CALL 31E9H and JMP 14EDH) and for the Model 200
laptop (CALL 3F3DH and JMP 1604H).
===== Self-Locate -- major milestone for run-in-place laptop executables
=====
WHEREAMI: EQU $
CALL 31E9H ;XTHL PCHL stacks HL, HL=rtn. Model 10x.
; CALL 3F3DH ;XTHL PCHL stacks HL, HL=rtn. Model 200.
IAMHERE: EQU $ ;I am HERE at this discovered return address
;which now is in HL
PUSH D
PUSH B
PUSH PSW
;All reg content stacked. JMP 14EDH is a handy unstack exit.
JMP 14EDH ;Pops PSW,B,D,H and then RET exit. Model 10x.
; JMP 1604H ;Pops PSW,B,D,H and then RET exit. Model 200.
Once it's discovered "Where I am Now" then inspection of "Where I was
Before" is done. The difference is the needed adjustment of wordAdrs.
Note, if difference is 0, adjustment isn't needed and time is saved --
often the case for code held within BASIC program files.
Via link-lists, locales of wordAdrs are found. Each is adjusted
according to the adjustment difference. If there are locales for
byteAdrs (unlikely), they have their own link-lists and also are
adjusted. Two link-list structures are considered: ByteAdvance and
BitsOfNext. In some cases a mix of both may minimize overhead cost.
ByteAdvance was done before in type .CE development and for ERL
development. It presumes all locales are adjacent in series by no more
than 256-spans. Worst case is two wordAdrs locales displaced by 256.
Example: locales of ?000h and ?100h are linked by link value of FFh
(255). Adjustment to ?000h increments beyond it to ?0001h (the
Hi-part), and relative to ?001h going further by FFh arrives at locale
?100h. Example: locale of ?000h and ?002h are linked by link value of
01h (1). Relative to ?001h going further by only 01h arrives at the
directly adjacent locale ?003h. Note that link value of 00h (0) can be
used as the delimiter of a link-list, although it could be used to
increase the maximum displacement for 257-spans. The overhead cost is
1 ByteAdvance link per wordAdrs locale. This can be a lot for code
with much internal reference and little Rom reference.
BitsOfNext has not been developed yet. <SNIP>
============================================================================
==
The method detailed above might also might be of particular interest
to John
Hoger and to Wilson Van Alst. In the November 8, 2006 in the "Re: Remem :
relocatable ML codes." message thread, John wrote:
> Wilson and I hashed out something similar: you can do this without
> much special other than taking back one of the traps.
>
> In your code you put a trap swi followed by a 16-bit signed offset.
> When the trap runs it looks at the stack to figure out where it jumped
> from, and patches up the trap and 16-bit offset to an absolute
> address.
>
> The flaws are that
>
> a) you need a trap (remem allows us to take back a trap,
potentially) and
> b) everything gets fixed on the first run and the code can't be moved
> without reload
> c) Also it won't work for code to run from read-only memory. But who
> cares since if you're running from ROM you won't be relocating anyway.
>
> There are slow techniques for truly position independent code that
> depend on some special thunk located somewhere. We should at least
> patch the rom to include the special thunk. I have a doc from Ron
> Balonis that shows how to do this.
>
> -- John.
Note: the operational constraint that John lists in flaw item b (.... code
can't be moved) might be overcome by use of the "Self-Locate" method that
I've reported herein.
-= Ron =-