George, there are multiple ways to do this, which I have been doing a deep
dive on recently for my "Supercharged BASIC" book in progress. Some
background first, but stay till the end, I have what should be a perfect
solution for you.

First, there is the RELJMP.PDF that you may or may not have. Attached. You
need a 4 byte hidey hole. Probably somewhere in the RST 7 table would work.
Clobbers HL, DE, flags. Can do conditional/unconditional jumps.  It's a a
"Call" in form but really it's a relative jump. You cannot use it directly
to do a subroutine.

I think the real downside here is all the pushing and popping. Imagine a
loop that just copies bytes from one place to another. You probably need HL
and DE, plus the flags preserved across the jump, minimum. So you're going
to have to do all that. Every jump.

Second, at 12777 in the Model 100 is the code XTHL / PCHL. This code simply
answers the question "Where Am I?" You can use this as a building block to
do a relative jump. Steve Adolph and I went down this rabbit hole and it
seems pretty expensive at least if you preserve registers. But it also
works.

What came up from this collaboration is what I think is the perfect
technology for more BASIC embedded ML that requires branching. By the way,
there's a lot you can do to augment BASIC code without branching. If you
can, short sequential routines that optimize your code is the way to go.

Anyway, the perfect solution... basically this idea is a 2-byte relative
branch or call encoded as data following a RST 7 / 197 instruction:

RST 7 / .db 197 / opcode / signed 8-bit offset

In the RST 7 / .db 197 table we put a small routine that rewrites the whole
4 bytes as your opcode,the 8-bit signed offset converted to a fixed address
relative to the final position of the opcode, followed by a NOP.

opcode / 2-byte target / nop

Advantages? You can do jumps, calls, conditionals no limitations on the
opcode. It's fast, there's overhead the first time to rewrite the jump, but
after that it's at max speed, every iteration. Well, other than the NOP
that pads out to the 4 bytes.

Disadvantages: it rewrites code. You cannot use this in literal strings
since it will corrupt your tokenized program text with control characters,
" and DEL. But all characters are allowed in dynamic strings... So
A$="BLAH" is no but A$="BLAH"+"" is OK.

It might not be the best tech for a single branch. RELJMP, or CALL 12777
may be best. But if you're looping over data, I think you're going to win
this way.

I've attached a sample program with the RST7 self-relocator installer and a
test program that shows BASIC-only versus an ML CALL subroutine to print
the full M100 character set.

The CALL string program does this:

 mvi a,33
 rst 4
 inr a
 rz
 mvi h,126
 inr h
 cmp h
 rst 7 / .db 197 / .db jz / .db  -5
 rst 7 /.db 197 / .db jmp / .db -11


My self-relocator installer source... note that this is specially crafted
code that is embedded in a BASIC literal string, so it doesn't use the full
8085 instruction set. This means I can write it in a string without any
conversions, special construction +CHR$( or POKEs. If you list SRELC2.BA
you will see what I mean.

rst 7 / index / rel-offset / opcode

gets replaced with

opcode / address / nop


 ; store FIXUP @ ERRLIN (64415) - "hook 99" = postbyte 197
 ; Use CALL to the start of the string.
 ; HL contains the address of the string body

 push h
 lxi h,64415
 xthl ; stack the hook slot for later, hl gets the installer base
 mvi a,-18 ; calculate the address of the rst 7 handler based on length of
installer
 cma
 mov e,a
 xra a
 mov d,a
 call 0x21AC ; dad d / ret
 ; now hl has the rst 7 handler to install
 pop d ; get back the 64415 slot address
 shli ; store the vector
 ret

21 bytes


rst 7 ndx opcode rel-offset

xthl ; save-hl, hl gets the return address (points at opcode)
push psw
push d
xchg
lhli ; fetch opcode & rel-offset to hl
xchg ; now opcode & rel-offset in de
dcx h ; now pointing where the jump target goes
push h ; save the jump-target position
dcx h ; hl points at start of instruction
mov m,e ; place jump/call opcode
mov a,d ; sign extend the 8-bit offset
mov e,a
add a
sbb a ;
mov d,a ; de now has sign-extended offset
mov a,e
; dad d: hl = hl + de... now has the computed jump target
call 0x21AC ; main rom has DAD D/ RET. We need it since DAD D too low for
literal string
pop d ; retrieve the jump target position
shli  ; instruction is complete, except for the NUL
xchg ; back into h
inx h
inx h
xra a ; nop code
mov m,a ; set nop
dcx h ; at nop, so 3 decrements to again point at opcode
dcx h
dcx h
pop d ; restore caller's de
pop psw ; restore caller's psw
xthl ; stack the patched-up instruction, restore caller's hl
ret ; invoke the patched-in jump/call


-- John.



On Tue, Mar 7, 2023 at 4:45 AM grima...@gmail.com <grima...@gmail.com>
wrote:

> Hi all,
>
> One of the things I struggled with in trying to build 8085 subroutines for
> BASIC program was the lack of a relative jump command.
>
> So far, the approach I have taken to embed ML programs into BASIC has been
> to poke them into arrays, thus allowing BASIC to manage the routines within
> memory. However, I then have to use BASIC to get VARPTR of the array and
> update all JMP locations before calling the subroutine, just in case BASIC
> has moved the array.
>
> The other thought I had was, can I have the ML program modify itself when
> it runs? I was racking my brain reading the Inten 8085 documentation, and
> as far as I can tell there is no easy way to read the program counter into
> any of the register pairs, which I would want to do in order to calculate
> offsets and update JMP locations.
>
> However I had one thought. It seems that both CALL and RST instructions
> push the program counter onto the stack. Is it possible to leverage either
> of these and then RET to return to my program, and then immediately
> decrement the stack pointer and to retrieve the previous value.
>
> Then I can use that value to calculate all the offsets and update the JMP
> locations.
>
> Does anyone have any constructive input here?
>
> -George
>

Attachment: RelJMP.pdf
Description: Adobe PDF document

Attachment: SRELC2.BA
Description: Binary data

Attachment: SRELC2.DO
Description: Binary data

Reply via email to