Author |
Message |
|
DigiTan Unregistered HyperCam 2
Super Elite (Last Title)
Joined: 10 Nov 2003 Posts: 4468
|
Posted: 01 Dec 2003 10:07:00 pm Post subject: |
|
|
Part of the program I'm working on requires to I use jump tables for size optimization reasons. The trouble with this is that I can't seem to get the "jp (hl)" instruction to function without crashing. Not even the opcode ($E9) works. What gives?
This is what I have to use instead:
Code: ld hl,address ; Address to jump into
ld e,(hl) ; Low byte first
inc hl
ld d,(hl) ; High byte last
push de
ret ; Jump
address:
.dw the_beginning
|
|
Back to top |
|
|
Darth Android DragonOS Dev Team
Bandwidth Hog
Joined: 31 May 2003 Posts: 2104
|
Posted: 02 Dec 2003 01:46:19 pm Post subject: |
|
|
what about:
ld hl,address
push hl
pop ix
ld hl,(ix)
push hl
ret
address:
.dw the_beginning |
|
Back to top |
|
|
sgm
Calc Guru
Joined: 04 Sep 2003 Posts: 1265
|
Posted: 03 Dec 2003 05:18:56 pm Post subject: |
|
|
How about
Code: ld hl,address ; Address to jump into
bcall(_LdHLInd)
jp (hl) ; Jump
address:
.dw the_beginning
Last edited by Guest on 03 Dec 2003 05:19:54 pm; edited 1 time in total |
|
Back to top |
|
|
DigiTan Unregistered HyperCam 2
Super Elite (Last Title)
Joined: 10 Nov 2003 Posts: 4468
|
Posted: 03 Dec 2003 09:36:32 pm Post subject: |
|
|
Well, the replacement code seems to work enough, I'm just curious as to why "jp (hl)" doesn't seem to be supported.
BTW, what exactly does bcall(_LdHLInd) do? (I'm guessing it swaps both bytes at <address>). |
|
Back to top |
|
|
sic
Advanced Newbie
Joined: 28 Jul 2003 Posts: 62
|
Posted: 03 Dec 2003 11:05:09 pm Post subject: |
|
|
DigiTan wrote: BTW, what exactly does bcall(_LdHLInd) do? (I'm guessing it swaps both bytes at <address>).
wrong.. it's essentially this:
ld hl,(hl)
I'm pretty sure that if you dissasembled that ROM call the code would look something like this:
Code: push af
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
pop af
ret
And jp (hl) works essentially like this:
ld hl,myaddr
jp (hl) ; will jump to myaddr:
....
myaddr:
Last edited by Guest on 03 Dec 2003 11:06:23 pm; edited 1 time in total |
|
Back to top |
|
|
DigiTan Unregistered HyperCam 2
Super Elite (Last Title)
Joined: 10 Nov 2003 Posts: 4468
|
Posted: 14 Dec 2003 10:39:27 pm Post subject: |
|
|
I decided to do a little detective work and I found out the problem does involve swapped bytes. So a routine:
Code: ld hl,address
jp hl,(hl)
...
address:
.dw the_beginning
...could only work if the value "the_beginning" was an address like "$0000" or "$8282" where byte order doesn't matter. What still puzzles me is why it wouldn't work for TI82 while it's clearly supported on other models. But I guess that doesn't really matter.
Quote: wrong.. it's essentially this:
ld hl,(hl)
Actually, 'mostly right' since all it's really doing is swapping bytes in the pointer (low byte to H high byte to L. TI-82 uses a similar, unnamed routine called "ROM_CALL($0033-$1A)" (-$1A for ROM v19.0 only), so I'm using it for now as a low-speed alternative. |
|
Back to top |
|
|
Job the GameQuitter
Member
Joined: 04 Jun 2003 Posts: 102
|
Posted: 18 Dec 2003 09:54:18 am Post subject: |
|
|
DigiTan wrote: Part of the program I'm working on requires to I use jump tables for size optimization reasons. The trouble with this is that I can't seem to get the "jp (hl)" instruction to function without crashing. Not even the opcode ($E9) works. What gives?
This is what I have to use instead:
Code: ld hl,address ; Address to jump into
ld e,(hl) ; Low byte first
inc hl
ld d,(hl) ; High byte last
push de
ret ; Jump
address:
.dw the_beginning
You probably misinterpreted what JP (HL) did. I did that initially. JP (HL) doesn't jump to the value stored in (HL) and (HL+1), but to the value in HL. To give an example in code: Code: LD HL,adress
JP (HL) is effectively the same as Code: LD HL,adress
PUSH HL
RET Except that it's smaller and faster .
Although I don't know your code I doubt a jump table will be much of an optimization over using the regular CALL and JR/JP instruction. I can give you some code which might do what you had in mind though: Code: ;input: B = adress in the adress table, so B=3 means you'll get the third adress in the table
LD HL,adress_table-2
LD DE,2
find_adress_loop
ADD HL,DE
DJNZ find_adress_loop
Call HL_Ind
JP (HL)
...
HL_Ind:
LD A,(HL)
INC HL
LD H,(HL)
LD L,A
ret
adress_table:
.dw adress1
.dw adress2
.dw adress3
etc I made that up on the spot, with no Z80 reference or anything, so don't blame me if it doesn't work the way it should. That said, I think this code does pretty much exactly what you had in mind, although I don't see how it would be efficient in any circumstance. If you want more info on jump tables and such, try day 23 of sigma's 28-days tutorial.
EDIT: Thanks for the link, Randroid.
Last edited by Guest on 18 Dec 2003 06:41:57 pm; edited 1 time in total |
|
Back to top |
|
|
Darth Android DragonOS Dev Team
Bandwidth Hog
Joined: 31 May 2003 Posts: 2104
|
Posted: 18 Dec 2003 09:56:30 am Post subject: |
|
|
the tutorial is uploaded here |
|
Back to top |
|
|
DigiTan Unregistered HyperCam 2
Super Elite (Last Title)
Joined: 10 Nov 2003 Posts: 4468
|
Posted: 18 Dec 2003 05:05:21 pm Post subject: |
|
|
Quote: You probably misinterpreted what JP (HL) did. I did that initially. JP (HL) doesn't jump to the value stored in (HL) and (HL+1), but to the value in HL.
Ack! That explains everything! I guess the program was crashing because it was jumping into the table instead of the address at the table. I havent tested the new code yet, but I'm guessing its gonna work now that the mystery's solved. Thanks, guys. |
|
Back to top |
|
|
|