Help in understanding 68K indexed indirect addressing

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
siudym
Newbie
Posts: 8
Joined: Thu Feb 24, 2022 9:26 am

Help in understanding 68K indexed indirect addressing

Post by siudym » Sat Oct 29, 2022 10:48 am

I go back to 68000 assembler and have a question about indexing.
Sample code in Z80,6502 and its equivalent from 68K:


I need help with 68K indexed (indirect) addressing.
Could someone help how to better / otherwise execute the code from the Z80 / 6502 but that it would work identically in 68K (as an example).

It is impossible to perform MOVE.W (A0, D0), D1, i.e. to read the address indexed by D0 to D1 in this way.

Code: Select all

variable0 = $C000
variable1 = $C001
variable2 = $C002
variable3 = $C003
variable4 = $C004
variable5 = $C005
variable6 = $C006
variable7 = $C007

Code: Select all

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6502:

	ldx $07
	stx variable_index

-------------

	ldx variable_index	; $07

	lda variable0,x		; load the value of variable0 into the accumulator indexed by the value x (i.e. variable7 will be read into A).
	ora %10000000		; do an ora on bit7.
	sta variable0,x		; write the result to variable0 indexed by x (i.e. again to variable7)


Code: Select all

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Z80:

	ld a,$07
	ld (variable_index),a

---------------

	ld hl,variable0		; load the address at which the variable0 is located in the memory.
	ld d,0
	ld a,(variable_index)
	ld e,a
	add hl,de		; add the contents of the index to the address.
	ld a,(hl)		; read the content from the address written in HL
	or %10000000		; do an ora on bit7.
	ld (hl),a		; write the contents of D0 to the address stored in HL.

Code: Select all

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 68K:

	move.w $07,variable_index
	move.w variable_index,d0

---------------

	lea variable0,a0	; load the address at which the variable0 is located in the memory.
	add.w d0,a0		; add the contents of the index to the address.		
	move.b (a0),d0		; read the content from the address written in A0.
	ori.b %10000000,d0	; do an ora on bit7.
	move.b d0,(a0)		; write the contents of D0 to the address stored in A0.
	
or..

	lea variable0,a0	; load the address at which the variable0 is located in the memory.
	add.w d0,a0		; add the contents of the index to the address.		
	ori.b %10000000,(a0)	; do an ora on bit7 at contents of A0.


Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Re: Help in understanding 68K indexed indirect addressing

Post by Chilly Willy » Sun Oct 30, 2022 4:01 pm

I think you want

Code: Select all

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 68K:

	move.w #$07,variable_index
	move.w variable_index,d0

---------------

	lea variable0,a0		; load the address at which the variable0 is located in the memory.
	move.b 0(a0,d0.w),d1		; read the indexed content from the address written in A0+D0.
	ori.b #%10000000,d1		; do an ora on bit7.
	move.b d1,0(a0,d0.w)		; write the contents of D1 to the address stored in A0+D0.
	
or..

	lea variable0,a0		; load the address at which the variable0 is located in the memory.
	ori.b #%10000000,0(a0,d0.w)	; do an ora on bit7 at contents of A0+D0.

siudym
Newbie
Posts: 8
Joined: Thu Feb 24, 2022 9:26 am

Re: Help in understanding 68K indexed indirect addressing

Post by siudym » Mon Oct 31, 2022 8:19 am

Thanks.

I have another question. Because I don't know if I'm doing it right. I would like to load A0 LoadLEVxxx address from TABLE which will be indexed with level number and jump to LABEL using JMP (A0).

Unfortunately, while the jump under LoadLEV000 works (without the index), the indexed LEV does not want to jump correctly where it needs to be.


Code: Select all


	MOVE.L	#$00,D0			; clear D0.
	MOVE.B	LEV_NR,D0		; load index (byte variable 00-FF level number)



	MOVE.L	LEV_TBL(PC),A0
	ASL.L	D0			; I have to multiply the number from LEV_NR by 4x because I have an array every 4 bytes (.L).
	ASL.L	D0
	ADD.L	D0,A0


	JMP	(A0)

Code: Select all


;----------------

LoadLEV000:

; LEV Data here...

	RTS

LoadLEV001:

; LEV Data here...

	RTS

(...)

LoadLEV255:

; LEV Data here...

	RTS

Code: Select all

;----------------

LEV_TBL:

	DC.L LoadLEV000,LoadLEV001,LoadLEV002,LoadLEV003,LoadLEV004,LoadLEV005,LoadLEV006,LoadLEV007
	DC.L LoadLEV008,LoadLEV009,LoadLEV010,LoadLEV011,LoadLEV012,LoadLEV013,LoadLEV014,LoadLEV015
	DC.L LoadLEV016,LoadLEV017,LoadLEV018,LoadLEV019,LoadLEV020,LoadLEV021,LoadLEV022,LoadLEV023
	DC.L LoadLEV024,LoadLEV025,LoadLEV026,LoadLEV027,LoadLEV028,LoadLEV029,LoadLEV030,LoadLEV031
	DC.L LoadLEV032,LoadLEV033,LoadLEV034,LoadLEV035,LoadLEV036,LoadLEV037,LoadLEV038,LoadLEV039
	DC.L LoadLEV040,LoadLEV041,LoadLEV042,LoadLEV043,LoadLEV044,LoadLEV045,LoadLEV046,LoadLEV047
	DC.L LoadLEV048,LoadLEV049,LoadLEV050,LoadLEV051,LoadLEV052,LoadLEV053,LoadLEV054,LoadLEV055
	DC.L LoadLEV056,LoadLEV057,LoadLEV058,LoadLEV059,LoadLEV060,LoadLEV061,LoadLEV062,LoadLEV063
	DC.L LoadLEV064,LoadLEV065,LoadLEV066,LoadLEV067,LoadLEV068,LoadLEV069,LoadLEV070,LoadLEV071
	DC.L LoadLEV072,LoadLEV073,LoadLEV074,LoadLEV075,LoadLEV076,LoadLEV077,LoadLEV078,LoadLEV079
	DC.L LoadLEV080,LoadLEV081,LoadLEV082,LoadLEV083,LoadLEV084,LoadLEV085,LoadLEV086,LoadLEV087
	DC.L LoadLEV088,LoadLEV089,LoadLEV090,LoadLEV091,LoadLEV092,LoadLEV093,LoadLEV094,LoadLEV095
	DC.L LoadLEV096,LoadLEV097,LoadLEV098,LoadLEV099,LoadLEV100,LoadLEV101,LoadLEV102,LoadLEV103
	DC.L LoadLEV104,LoadLEV105,LoadLEV106,LoadLEV107,LoadLEV108,LoadLEV109,LoadLEV110,LoadLEV111
	DC.L LoadLEV112,LoadLEV113,LoadLEV114,LoadLEV115,LoadLEV116,LoadLEV117,LoadLEV118,LoadLEV119
	DC.L LoadLEV120,LoadLEV121,LoadLEV122,LoadLEV123,LoadLEV124,LoadLEV125,LoadLEV126,LoadLEV127
	DC.L LoadLEV128,LoadLEV129,LoadLEV130,LoadLEV131,LoadLEV132,LoadLEV133,LoadLEV134,LoadLEV135
	DC.L LoadLEV136,LoadLEV137,LoadLEV138,LoadLEV139,LoadLEV140,LoadLEV141,LoadLEV142,LoadLEV143
	DC.L LoadLEV144,LoadLEV145,LoadLEV146,LoadLEV147,LoadLEV148,LoadLEV149,LoadLEV150,LoadLEV151
	DC.L LoadLEV152,LoadLEV153,LoadLEV154,LoadLEV155,LoadLEV156,LoadLEV157,LoadLEV158,LoadLEV159
	DC.L LoadLEV160,LoadLEV161,LoadLEV162,LoadLEV163,LoadLEV164,LoadLEV165,LoadLEV166,LoadLEV167
	DC.L LoadLEV168,LoadLEV169,LoadLEV170,LoadLEV171,LoadLEV172,LoadLEV173,LoadLEV174,LoadLEV175
	DC.L LoadLEV176,LoadLEV177,LoadLEV178,LoadLEV179,LoadLEV180,LoadLEV181,LoadLEV182,LoadLEV183
	DC.L LoadLEV184,LoadLEV185,LoadLEV186,LoadLEV187,LoadLEV188,LoadLEV189,LoadLEV190,LoadLEV191
	DC.L LoadLEV192,LoadLEV193,LoadLEV194,LoadLEV195,LoadLEV196,LoadLEV197,LoadLEV198,LoadLEV199
	DC.L LoadLEV200,LoadLEV201,LoadLEV202,LoadLEV203,LoadLEV204,LoadLEV205,LoadLEV206,LoadLEV207
	DC.L LoadLEV208,LoadLEV209,LoadLEV210,LoadLEV211,LoadLEV212,LoadLEV213,LoadLEV214,LoadLEV215
	DC.L LoadLEV216,LoadLEV217,LoadLEV218,LoadLEV219,LoadLEV220,LoadLEV221,LoadLEV222,LoadLEV223
	DC.L LoadLEV224,LoadLEV225,LoadLEV226,LoadLEV227,LoadLEV228,LoadLEV229,LoadLEV230,LoadLEV231
	DC.L LoadLEV232,LoadLEV233,LoadLEV234,LoadLEV235,LoadLEV236,LoadLEV237,LoadLEV238,LoadLEV239
	DC.L LoadLEV240,LoadLEV241,LoadLEV242,LoadLEV243,LoadLEV244,LoadLEV245,LoadLEV246,LoadLEV247
	DC.L LoadLEV248,LoadLEV249,LoadLEV250,LoadLEV251,LoadLEV252,LoadLEV253,LoadLEV254,LoadLEV255


Wuerfel_21
Newbie
Posts: 6
Joined: Sat Feb 12, 2022 4:22 pm

Re: Help in understanding 68K indexed indirect addressing

Post by Wuerfel_21 » Tue Nov 01, 2022 1:41 am

JMP (A0) jumps to A0. You want to do something like

Code: Select all

	MOVE.L	LEV_TBL(PC),A0
	ASL.W	#2,D0			; I have to multiply the number from LEV_NR by 4x because I have an array every 4 bytes (.L).
	MOVE.L	0(A0,D0.W),A0
	JMP	(A0)

siudym
Newbie
Posts: 8
Joined: Thu Feb 24, 2022 9:26 am

Re: Help in understanding 68K indexed indirect addressing

Post by siudym » Tue Nov 01, 2022 9:47 am

It still doesn't work. I changed (A0,D0,L) because I probably need to add Index as L instead of W for 24bit ROM addressing? But it doesn't change anything.


Here is an example code 6502 and Z80 that I have with exactly the same use. The 6502 was very simple, the Z80 had some combination problems at the beginning:
6502:

Code: Select all


	LDX LEV_NR

	LDA LEV_TBL_LO,x
	STA LEV_Jumper+0
	LDA LEV_TBL_HI,x
	STA LEV_Jumper+1

	JMP [LevelJumper]

LEV_TBL_LO:

	.BYTE LOW(LoadLEV000),LOW(LoadLEV001),LOW(LoadLEV002),LOW(LoadLEV003)
(...)

LEV_TBL_HI:

	.BYTE HIGH(LoadLEV000),HIGH(LoadLEV001),HIGH(LoadLEV002),HIGH(LoadLEV003)
(...)



Z80:

Code: Select all


	LD DE,LEV_TBL
	LD A,(LEV_NR)
	LD H,0
	LD L,A
	ADD HL,HL
	ADD HL,DE

	LD E,(HL)
	INC HL
	LD D,(HL)
	EX DE,HL			; Exchanges two 16-bit values.

	JP (HL)




LEV_TBL:

	.DW LoadLEV000,LoadLEV001,LoadLEV002,LoadLEV003,LoadLEV004,LoadLEV005,LoadLEV006,LoadLEV007
(...)

Wuerfel_21
Newbie
Posts: 6
Joined: Sat Feb 12, 2022 4:22 pm

Re: Help in understanding 68K indexed indirect addressing

Post by Wuerfel_21 » Tue Nov 01, 2022 10:14 am

Oh, brain farted there, the first one has to be LEA

Code: Select all

	LEA	LEV_TBL(PC),A0
	ASL.W	#2,D0			; I have to multiply the number from LEV_NR by 4x because I have an array every 4 bytes (.L).
	MOVE.L	0(A0,D0.W),A0
	JMP	(A0)
Note that if LEV_TBL is close to the code (d8 displacement), it can also be (if I remember the syntax for that addressing mode right)

Code: Select all

	ASL.W	#2,D0			; I have to multiply the number from LEV_NR by 4x because I have an array every 4 bytes (.L).
	MOVE.L	LEV_TBL(D0.W,PC),A0
	JMP	(A0)
Using D0.W is correct, unless you need to index into a structure larger than 64K

siudym
Newbie
Posts: 8
Joined: Thu Feb 24, 2022 9:26 am

Re: Help in understanding 68K indexed indirect addressing

Post by siudym » Tue Nov 01, 2022 10:17 am

Actually: D I just noticed it ... Yes, everything goes beyond 64KB that is 24BIT ROM addressing.

Now works, second code have error:

Error : Missing or misplaced ')' in operand move.l lev_tbl(d0.l,pc),a0

Wuerfel_21
Newbie
Posts: 6
Joined: Sat Feb 12, 2022 4:22 pm

Re: Help in understanding 68K indexed indirect addressing

Post by Wuerfel_21 » Tue Nov 01, 2022 12:20 pm

I think some assemblers want (lev_tbl,d0.l,pc)

No, only if the value in D0 ever grows larger than 64K do you need to use D0.L in the index mode.

siudym
Newbie
Posts: 8
Joined: Thu Feb 24, 2022 9:26 am

Re: Help in understanding 68K indexed indirect addressing

Post by siudym » Wed Nov 02, 2022 10:06 am

I use ASM68K (SN 68k version 2.53).

The earlier code also works, the only thing missing was to copy (A0) to A0:

LEA LEV_TBL(PC),A0
ASL.L #2,D0
ADD.L D0,A0
MOVE.L (A0),A0
JMP (A0)

But of course, this solution is more correct:
MOVE.L LEV_TBL(PC),A0
ASL.W #2,D0
MOVE.L 0(A0,D0.W),A0
JMP (A0)

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Re: Help in understanding 68K indexed indirect addressing

Post by Chilly Willy » Wed Nov 02, 2022 9:02 pm

You probably want

Code: Select all

	MOVEQ	#$00,D0			; clear D0.
	MOVE.B	LEV_NR,D0		; load index (byte variable 00-FF level number)

	LEA	LEV_TBL(PC),A0
	ADD.W	D0,D0
	ADD.W	D0,D0
	MOVEA.L	0(A0,D0.w),A0
	JMP	(A0)
Adding d0 to itself is faster than shifting, but only works for left shifts, and only up to 3 or 4 shifts. Use moveq for any number that fits (-128 to +127); it's smaller and faster. Use add.w instead of add.l when you know the displacement fits in a word.

Or maybe you want

Code: Select all

	MOVEQ	#$00,D0			; clear D0.
	MOVE.B	LEV_NR,D0		; load index (byte variable 00-FF level number)

	ADD.W	D0,D0
	ADD.W	D0,D0
	MOVEA.L	LEV_TBL(PC,D0.w),A0
	JMP	(A0)
The second only works if you're close to the jump table.

Post Reply