Hey Steve,
Unfortunately it uses LXI D and DAD D (or LXI B and DAD B). I believe
those are all opcodes < 32 decimal. :( Plus your relative jump would
have values < 32 decimal for any jump distance that is less than 2020H.
So maybe not so useful after all.
It is still doable in a BASIC string, but it becomes costly in terms of
size and execution time due to the coding limitations:
PUSH PSW ; Only needed if relatvie branch
required (save condition flags)
XRA A ; Zero A
MOV D,A ; Zero D. For backward jumps, insert
a DCR A prior to MOV D,A
MVI A,forward_branch_dist ; Jump 32 to 255 forward (or
backwared if DCR A inserted).
MOV E,A ; Load jump into E (We can't use MVI
E because it is < 32d)
CALL WHEREAMI ; 31E9H or 3F3DH. HL now contains
address of CALL opcode on next line
CALL 21ACh ; Location in ROM with a DAD D followed by RET
XTHL ; Put return val on stack, restore
original HL
POP PSW ; Only needed for conditional return
below
RZ / RNZ / RET ; Return or conditional RETurn for
conditional branch
POP D ; Only for conditional. If RZ / RNZ
didn't jump,
we must pop the unused RET address
from stack
; A Whopping 16 bytes for a conditonal branch! Or 17 for backward
branch. Don't use to many of them!
If a lot of conditional branches are needed in BASIC strings / DATA
statements, it might be better to poke a routine similar to this into
the hidey hole I mentioned yesterday (at F6EBH) and call it. For
conditional, write that routine so it returns either to the next opcode
or the new relative branch location. To load the relative jump, easily
you could do:
XCHG
LXI H, branch_distance ; USE LXI H since it can be used in
BASIC string
CALL hidey_hole
Then the hidey_hole would perform the XCHG / XTHL/ PCHL / RZ magic.
There may be other ROM call magic to be found also.
Ken
On 6/1/18 5:01 AM, Stephen Adolph wrote:
this is quite useful; it applies specifically to (a) running code that
is buried in BASIC string variables and (b) running code that is
buried in DATA structures, because in those cases you really don't
know where the code is (easily), and the code can't adapt to being
moved around (easily). Now it can. Very useful!
Regarding .DO files - the contents of the .DO file survives being
loaded into M100 memory intact. One has to avoid EOF and 0A. One
does not need quotes either. So this is quite dense, and
On Fri, Jun 1, 2018 at 3:15 AM, Ken Pettit <[email protected]
<mailto:[email protected]>> wrote:
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 =-