Indirect referencing a banked location in CA65

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
team_disposable
Posts: 129
Joined: Sat Oct 15, 2016 8:52 am

Indirect referencing a banked location in CA65

Post by team_disposable »

Can anyone provide a code example of how you would reference a 3 byte (i.e. bank and then 16k address) location on the SNES using a pointer in CA65 ASM? Is this something that is commonly done or am I missing a trick?

The intention is to use nested lookup tables for scenes, palettes, and the suchlike. I can currently only get an indirect reference working for a single byte and a word however, which would seem to limit me to 16ks worth of addresses.

Where am I going wrong?

The lookup is like this:

Code: Select all

hello_palettes: 
.word palette_1, palette_2
pointing to palettes like this:

Code: Select all

palette_0:

.byte %00000011, %11111111
.byte %00011100, %00011111
.byte %11111111, %00000011
.byte %11110011, %01100011


palette_2:

.byte %00000011, %11111111
.byte %00000011, %11100000
.byte %01111111, %11111111
.byte %00000000, %00010100
and the look up routine looks like this:

Code: Select all

.pushseg

.ZEROPAGE

palette_pointer:
.res 2

.popseg

.proc load_palette
sta PPU_CG_ADDR
	
lda #2
asl a
;for 3 byte addresses, another asl a would be here
tax
lda hello_palettes,x	
sta palette_pointer
lda hello_palettes+1,x
sta palette_pointer +1
lda hello_palettes+ 2,x
sta palette_pointer + 2

ldy #0
@loop:
lda (palette_pointer),y
sta PPU_CG_DATA
iny
cpy #8
bmi @loop
rts
.endproc ;end of load_palette
If I increase the pointer reserve to 3, put in another asl, and change the lookup table to a faraddr, it doesn't seem to work.

I've been using bsnes debugger and it looks like the 65816 doesn't load a 3 byte address, only a two byte one.

What am I doing wrong? Is this the wrong way to address storage across banks?
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Indirect referencing a banked location in CA65

Post by tepples »

Have you tried using square brackets lda [dd],Y instead of round ones lda (dd),Y when using 24-bit addresses on direct page?
team_disposable
Posts: 129
Joined: Sat Oct 15, 2016 8:52 am

Re: Indirect referencing a banked location in CA65

Post by team_disposable »

That was it! Genius, thank you tepples! I was reading the docs as well, I don't know why that didn't click.

For anyone else trying to use three byte addresses, here's the working routine (this is for a 16 colour palette):

Code: Select all


.pushseg

.ZEROPAGE

palette_pointer:
.res 3

;this is used as a temp register
zp_reg_0:
.res 1

.popseg


.proc load_palette
sta PPU_CG_ADDR
	
lda #2  ;this is your palette number in the table, so you'll actually want to fill a register with this on entry in to the routine
sta zp_reg_0
asl a
clc   
adc zp_reg_0
tax
lda hello_palettes,x
	
sta palette_pointer 
lda hello_palettes+1,x
sta palette_pointer +1
lda hello_palettes+ 2,x
sta palette_pointer + 2
	
ldy #0
@loop:
lda [palette_pointer],y
sta PPU_CG_DATA
iny
cpy #32  ;16 colours
bmi @loop
rts
.endproc ;end of load_palette
Post Reply