Relative offsets in jump tables

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
OrangyTang
Interested
Posts: 20
Joined: Tue Feb 23, 2016 4:45 pm

Relative offsets in jump tables

Post by OrangyTang » Thu Apr 12, 2018 11:28 pm

Hello!

I've got an odd jump table implementation in my disassembly that I'm trying to make less hardcoded. It basically looks like this:

Code: Select all

	MOVE.w	CurrentScreenState.w, D0
	LEA	jmpTable_000628AE(PC,D0.w), A0
	ADDA.w	(A0), A0
	JMP	(A0)
	
jmpTable_000628AE:
	dc.w	$0B02	; offset jmpTable_000628AE to loc_000633B0
	dc.w	$000C	; offset jmpTable_000628AE to loc_000628BC
	dc.w	$0050	; 
	dc.w	$00A4	; 
	dc.w	$00E6
	dc.w	$01BC
	dc.w	$0226
	
loc_000633B0:
	<code>
	
loc_000628BC:
	<code>
	
etc.
I've tracked down where it's jumping too, and have labels for those now but is there a way to fix the code so that it's not full of hardcoded numbers? I kinda want to do something like:

Code: Select all

jmpTable_000628AE:
	dc.w	(loc_000633B0-jmpTable_000628AE).w
	dc.w	(loc_000628BC-jmpTable_000628AE).w
	etc.
but my google-fu is failing me and the guesses at syntax I've tried aren't getting me anywhere. Anyone any hints?

I know I could turn it into a more normal jump table implementation, but I need to keep it compiling to the exact same bytes. Thanks

User avatar
Sik
Very interested
Posts: 705
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Relative offsets in jump tables

Post by Sik » Fri Apr 13, 2018 4:35 am

Remove the ( and ).w, that's already implied by the dc.w.
Sik is pronounced as "seek", not as "sick".

OrangyTang
Interested
Posts: 20
Joined: Tue Feb 23, 2016 4:45 pm

Re: Relative offsets in jump tables

Post by OrangyTang » Fri Apr 13, 2018 10:10 am

Aha! I did try that, but it didn't compile to identical code. Knowing that was the correct syntax I realised I need extra labels:

Code: Select all

; The animated 'Treasure' logo
TreasureScreen_00062892:
	MOVE.b	Pad1Buttons.w, D0
	OR.b	Pad2Buttons.w, D0
	BTST.l	#Pad_Start, D0
	BNE.w	SkipToTitleScreen_00062B36
	MOVE.w	CurrentScreenState.w, D0		; Screens from 0->C in incs of 2
	LEA	jmpTreasureSubState_000628AE(PC,D0.w), A0
	ADDA.w	(A0), A0						; adda src+dest -> dest.  word-contents of A0 added to A0, stored in A0.
	JMP	(A0)

jmpTreasureSubState_000628AE:
@stateA
	dc.w	TreasureSubA_000633B0-@stateA ; 0
@stateB
	dc.w	TreasureSubB_000628BC-@stateB ; 2
@stateC
	dc.w	TreasureSubC_00062902-@stateC ; 4 - offset to TreasureSubC_00062902 - unfold anim
@stateD	
	dc.w	TreasureSubD_00062958-@stateD ; 6 - offset to TreasureSubD_00062958 - unfold anim part 2
@stateE	
	dc.w	TreasureSubE_0006299C-@stateE ; 8 - offset to TreasureSubE_0006299C - single frame state
@stateF	
	dc.w	TreasureSubF_00062A74-@stateF ; A - offset to TreasureSubF_00062A74 - unfold anim part 3
@stateG	
	dc.w	TreasureSubG_00062AE0-@stateG ; C - offset to TreasureSubG_00062AE0 - unfold anim part 4 + detail appear
Feels like a weird way of doing it IMHO, when the regular way of doing jmp tables is much more readable. Any idea why it would be done like this? Performance can't be the reason as this is just the animated 'Treasure' logo at the beginning of the game.

User avatar
Sik
Very interested
Posts: 705
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Relative offsets in jump tables

Post by Sik » Fri Apr 13, 2018 10:55 am

To save on space, pretty much :​P (whether it's worth the effort is questionable, it may make more sense when the table is really large)
Sik is pronounced as "seek", not as "sick".

OrangyTang
Interested
Posts: 20
Joined: Tue Feb 23, 2016 4:45 pm

Re: Relative offsets in jump tables

Post by OrangyTang » Fri Apr 13, 2018 11:31 am

I guess that kinda makes sense - it's a 1Mb rom and only 176 bytes of spare padding at the end so things are pretty tight.

Having said that, there's also a massive 664 entry jump table (that I'm guessing is game object logic) that does things the long way. Nothing's perfect I guess. :)

User avatar
Miquel
Very interested
Posts: 318
Joined: Sat Jul 30, 2016 12:33 am

Re: Relative offsets in jump tables

Post by Miquel » Fri Apr 13, 2018 11:44 am

The only thing I can see is this way it uses one register less to calculate the jump.

This:
ADDA.w (A0), A0
is disturbing and ingenious at the same time.

User avatar
Sik
Very interested
Posts: 705
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Relative offsets in jump tables

Post by Sik » Fri Apr 13, 2018 9:13 pm

Probably worth noting that often the code is just whatever the programmer could think of first at that moment that was decent enough, not necessarily the best solution. No point changing things as long as they work and don't get in the way.
Sik is pronounced as "seek", not as "sick".

User avatar
Miquel
Very interested
Posts: 318
Joined: Sat Jul 30, 2016 12:33 am

Re: Relative offsets in jump tables

Post by Miquel » Tue Apr 24, 2018 4:10 pm

I have jumped to a similar problem.

the code you displayed:

Code: Select all

lea		case0(%pc,%d0.w), %a0	12cycles
add.w		(%a0), %a0			14cycles
jra		(%a0)				8cycles
solving the label mess:

Code: Select all

lea		case0(%pc), %a0		8cycles
add.w		table(%pc,%d0.w), %a0	18cycles
jra		(%a0)				8cycles
+2 bytes of code
the most efficient way:

Code: Select all

	move.w	CurrentScreenState.w, %d0
	add.w	%d0, %d0
	move.w	table(%pc,%d0.w), %d0	14cycles
	jra	case0(%pc,%d0.w)		14cycles

table:
.word case0-case0
.word case1-case0
.word case2-case0
.word case3-case0

case0:
	nop
	jra endcase
case1:
	nop
	nop
	jra endcase
case2:
	nop
	nop
	jra endcase
case3:
	nop
	nop
	nop
	jra endcase
	nop

endcase:
hope it helps.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest