Z80 jump table

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
Sik
Very interested
Posts: 939
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Z80 jump table

Post by Sik » Sun Mar 18, 2018 11:55 pm

Just noticed you can do this to get a jump table on the Z80 (probably an old trick and I'm being a newbie, but whatever):

Code: Select all

; a = index (0..42)
; b = spare

    ld      b, a            ; Multiply index by 3
    add     a, b
    add     a, b
    ld      ($+4), a        ; Overwrite the jump destination
    jr      $               ; Jump to the table
    
    jp      Routine1
    jp      Routine2
    jp      Routine3
    ...
This relies on self-modifying code (it overwrites a jump), so you need to run this off RAM, but that's usually the case on the Mega Drive so no biggie. Also the index is quite limited due to overflow (maximum that works is 42), but it still should be large enough for most purposes. Beats having to do 16-bit arithmetic on an address when you can't ensure a table will be within a 256 byte boundary.

I'm multiplying the index by 3 since that's how long a JP instruction is (I'm assuming that the targets may be anywhere). If you can really ensure that all target addresses are close enough (within around 127 bytes*) then it'd look more like this:

Code: Select all

; a = index (0..63)

    add     a, a            ; Multiply index by 2
    ld      ($+4), a        ; Overwrite the jump destination
    jr      $               ; Jump to the table
    
    jr      Routine1
    jr      Routine2
    jr      Routine3
    ...
By the way, the $ in that jump is just a placeholder (it'll be overwritten), I just picked something that would be within the allowed range so it can assemble.

*I say "around" since it needs to be 127 bytes away from the specific jump, so the actual maximum distance from the start of the code depends on which entry is being jumped to. Still should give a good idea of how far away it can afford to be.
Sik is pronounced as "seek", not as "sick".

HardWareMan
Very interested
Posts: 745
Joined: Sat Dec 15, 2007 7:49 am
Location: Kazakhstan, Pavlodar

Re: Z80 jump table

Post by HardWareMan » Mon Mar 19, 2018 6:35 am

Z80 have jp (hl). Just a hint.
Last edited by HardWareMan on Tue Mar 20, 2018 7:23 am, edited 1 time in total.

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Z80 jump table

Post by Stef » Mon Mar 19, 2018 9:09 am

What i'm doing in my XGM driver :

Code: Select all

    LD    A, (DE)             ; A = command           ' 7     |
    LD    (.ld_hl_xx + 1), A  ; set jump address      ' 13    |

.ld_hl_xx
    LD    HL, (JUMP_TABLE)    ; LD HL, (jt)           ' 16    |
    JP   (HL)                    ;             ' 4 |
Note that compiled XGM always encode command shifted by one (<<= 1) to save some cycles here but that reduce number of entries to 0x80.

Sik
Very interested
Posts: 939
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Z80 jump table

Post by Sik » Tue Mar 20, 2018 5:15 am

HardWareMan wrote:
Mon Mar 19, 2018 6:35 am
Z80 have jr (hl). Just a hint.
You mean JP :v

But anyway, using that would then require 16-bit operations to calculate the address which is like the whole thing I was trying to avoid (as it starts getting cumbersome). Either that or ensuring the table never crosses a 256 byte boundary (which is not always worth it, as you need to do lots of juggling regarding where you put those tables in the code, so better leave that for stuff you may need to access a lot or the like).
Stef wrote:
Mon Mar 19, 2018 9:09 am
Note that compiled XGM always encode command shifted by one (<<= 1) to save some cycles here but that reduce number of entries to 0x80.
Yeah, for speed critical stuff it may be better to store the index multiplied by the entry size already.
Sik is pronounced as "seek", not as "sick".

HardWareMan
Very interested
Posts: 745
Joined: Sat Dec 15, 2007 7:49 am
Location: Kazakhstan, Pavlodar

Re: Z80 jump table

Post by HardWareMan » Tue Mar 20, 2018 7:25 am

Sik wrote:
Tue Mar 20, 2018 5:15 am
HardWareMan wrote:
Mon Mar 19, 2018 6:35 am
Z80 have jr (hl). Just a hint.
You mean JP :v
I mean PCHL since I don't like Z80 mnemonics.

Post Reply