Very nice.
Seems like this destroys DE and HL.
You have to sacrifice some register as the relative offset, I guess.
As a small improvement, since the code at WHEREAMI is
XTHL
PCHL
it is actually preserving the original HL on the stack before it "returns".
So, you could remove the POP D and instead have a POP H at the jump target,
so the jump target executes with the original HL value.
Then you can keep HL intact for program logic.
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
PCHL ; Jump to new relative location
TARGET:
POP H ; Pop old HL value from Stack
; ...
-- John.
On Fri, Jun 1, 2018 at 12:15 AM, Ken Pettit <[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
>
>