Thanks for the info Ken.

That does seem more expensive as you will be executing the relative jump
routine every time you want to JMP. In my case, I will likely be using JMP
as a way to loop. so it would likely impact performance.

My initial thought was rather than do a relative jump in the program
itself, have the first step of the program modify all of the JMP addresses
used in that program specifically. Is that something you have tried at all?

-George

On Tue, Mar 7, 2023 at 9:42 AM Kenneth Pettit <petti...@gmail.com> wrote:

> Hi George,
>
> Yes, using CALL is the way to perform relative jumps in your ML
> program.  The idea is this:
>
> Poke a helper function into a hidey hole (on M100 there is a nice 52
> byte location you can use for this that I will explain).  So the way to
> do a relative jump is to add your jump distance as a data byte after the
> CALL:
>
>     CALL myRelJump     ; Relative jump the distance in the next two
> bytes (or one if you want)
>     DW  0xFFE5             ; Jump -27 (signed jump)
>
> Then at myRelJump you would do something like (not tested, you will have
> to play with it):
>
>     PUSH H         ; Save HL.  Also modifies SP
>     PUSH D         ; Save DE.
>     PUSH B
>     LXI  H,FFFAH   ; Load HL with -8
>     DAD SP         ; HL now has the Stack location of the return address
> (i.e. points to your relative jump distance)
>     MOV E,L        ; Save stack location in DE
>     MOV D,H
>     LHLX           ; Undocumented opcode to load HL from (DE) ... HL now
> points to your ML program
>     MOV C,M        ; Get LSB of the relative jump distance
>     INX H          ; Point to MSB
>     MOV B,M        ; Get MSB of relative jump distance
>     DAD B          ; Add the offset to the PC location (in HL) of the
> program
>     SHLX           ; Undocumentd opcode to save HL at (DE) ... save new
> return address to stack
>     POP B
>     POP D
>     POP H
>     RET            ; This now returns to the new location you just
> calculated
>
> Note that is will be SLOWER ... you are executing 17 opcodes for each
> jump instead of one!!
>
> The hidey hole I was talking about is an array used only by the TEXT
> application.  It saves 26 2-byte pointers (one for each line of the LCD
> / DVI, plus an extra containing 0xFFFF) to indicate the location in the
> edited .DO file of the start of that line.  I call it the "line starts
> array".  When runing BASIC, this memory region is unused and can be
> poked with any ML you want.  On M100, this is at address F6EBH.
>
> Hope this helps.  Again, this is UNTESTED code, but should give you the
> idea.
> Ken
>
> On 3/7/23 4:44 AM, 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
>
>

Reply via email to