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 =-





Reply via email to