index outside of label (intentionally) asm

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
User avatar
nyanberrycake
Posts: 19
Joined: Mon Mar 30, 2020 4:35 pm

index outside of label (intentionally) asm

Post by nyanberrycake » Sun Sep 13, 2020 5:11 pm

I have palettes set up in ram one after another. For simplicity's sake I would like to fill them all with one loop while still keeping labels on them separately. Is there any harm to this (besides possibly being "bad style"

Code: Select all

backgroundPalette1: .res 3
backgroundPalette2: .res 3
backgroundPalette3: .res 3
backgroundPalette4: .res 3

	lda #$00
	tax
@fillPalette:
	lda (paletteData), x
	sta (backgroundPalette1, x
	inx
	cpx #12
	bne @fillPalette
Last edited by nyanberrycake on Sun Sep 13, 2020 6:34 pm, edited 1 time in total.

User avatar
nyanberrycake
Posts: 19
Joined: Mon Mar 30, 2020 4:35 pm

Re: index outside of label (intentionally) asm

Post by nyanberrycake » Sun Sep 13, 2020 6:34 pm

nyanberrycake wrote:
Sun Sep 13, 2020 5:11 pm
I have palettes set up in ram one after another. For simplicity's sake I would like to fill them all with one loop while still keeping labels on them separately. Is there any harm to this (besides possibly being "bad style"

Code: Select all

backgroundPalette1: .res 3
backgroundPalette2: .res 3
backgroundPalette3: .res 3
backgroundPalette4: .res 3

	lda #$00
	tax
@fillPalette:
	lda (paletteData), x
	sta (backgroundPalette1, x
	inx
	cpx #12
	bne @fillPalette
for those who search this question on the future, it is not possible, at least with my assembler ca65

lidnariq
Posts: 9891
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: index outside of label (intentionally) asm

Post by lidnariq » Sun Sep 13, 2020 6:36 pm

You can't get (zp),x addressing mode. Only (zp,x) or (zp),y exist.

User avatar
aa-dav
Posts: 120
Joined: Tue Apr 14, 2020 9:45 pm
Location: Russia

Re: index outside of label (intentionally) asm

Post by aa-dav » Sun Sep 13, 2020 8:11 pm

nyanberrycake wrote:
Sun Sep 13, 2020 5:11 pm
For simplicity's sake I would like to fill them all with one loop while still keeping labels on them separately.
It's totally ok to do so in asm, but don't forget about .align directive which can add padding bytes between arrays.
Also don't forget about zero slot of palettes - they have size of 4 bytes with zero byte phisically the same global transparent/background color.

Oziphantom
Posts: 988
Joined: Tue Feb 07, 2017 2:03 am

Re: index outside of label (intentionally) asm

Post by Oziphantom » Mon Sep 14, 2020 1:07 am

Code: Select all

backgroundPalette1: .res 4
backgroundPalette2: .res 4
backgroundPalette3: .res 4
backgroundPalette4: .res 4

	ldy #15
@fillPalette:
	lda (paletteData), y
	sta backgroundPalette1, y
	dey
	bpl  @fillPalette
but is paletteData a vector point to the data or just an address, because if its an address you can do

Code: Select all

	ldx #15
@fillPalette:
	lda paletteData,x
	sta backgroundPalette1, x
	dex
	bpl  @fillPalette

User avatar
tokumaru
Posts: 11909
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: index outside of label (intentionally) asm

Post by tokumaru » Mon Sep 14, 2020 3:14 am

nyanberrycake wrote:
Sun Sep 13, 2020 6:34 pm
for those who search this question on the future, it is not possible, at least with my assembler ca65
This information is not correct. You can definitely use indices past the end of tables/labels in any assembler, as long as you know what you're doing and are 100% sure that the data is stored in memory sequentially.

Your problem here is that you're trying to use an addressing mode that doesn't exist on the 6502: lda (zp), x doesn't exist. The only indirect addressing mode that uses the X register is (zp, x), where X is added to the address of the pointer itself, not the address that the pointer points to. You have to use the Y register for what your trying to do.

Assembler is different from high-level languages in that you can't just learn the syntax and use every addressing mode and operation with every register, each operation is physically implemented inside the CPU, and not all combinations of operations, addressing modes and registers are available. You have to consult the documentation in order to see if a particular combination you want to use exists. With time you get the hang of what exists and what doesn't.

User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: index outside of label (intentionally) asm

Post by Movax12 » Mon Sep 14, 2020 12:39 pm

I would do something like this:

Code: Select all

palette       .res 32

backgroundPalette   = palette       
spritePalette       = palette + 16
Rather than creating a label for each palette, I find it easier to use macros to access palette locations, something like:

Code: Select all

.macro staBGpal pal, entry
	sta backgroundPalette  + (pal * 4) + entry 
.endmacro

; example
lda #$29
staBGpal 1,1
In OP's example, you could also create another label above backgroundPalette1 if you don't like the look of accessing all palettes through that label.

Code: Select all

backgroundPalette:
backgroundPalette1: .res 4
backgroundPalette2: .res 4
backgroundPalette3: .res 4
backgroundPalette4: .res 4
You should consider starting at zero as well, they should be labelled 0 to 3.

User avatar
tokumaru
Posts: 11909
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: index outside of label (intentionally) asm

Post by tokumaru » Mon Sep 14, 2020 4:33 pm

Movax12 wrote:
Mon Sep 14, 2020 12:39 pm

Code: Select all

backgroundPalette:
backgroundPalette1: .res 4
backgroundPalette2: .res 4
backgroundPalette3: .res 4
backgroundPalette4: .res 4
This is the solution I use when I need to access multiple tables from one "master" label.

For palettes specifically I don't waste space with the unused colors though, so I have a variable for the global background color, and 8 sets of 3 colors (total of 25 colors, instead of 32). I don't see any point in pretending that NES palettes are 4 colors when they really aren't.

User avatar
Controllerhead
Posts: 177
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: index outside of label (intentionally) asm

Post by Controllerhead » Mon Sep 14, 2020 5:14 pm

tokumaru wrote:
Mon Sep 14, 2020 4:33 pm
For palettes specifically I don't waste space with the unused colors though, so I have a variable for the global background color, and 8 sets of 3 colors (total of 25 colors, instead of 32). I don't see any point in pretending that NES palettes are 4 colors when they really aren't.
Agreed. I just increment the PPU pointer with meaningless data in the first slot when loading palettes in a loop and store global BG after at $3F20.
Image

User avatar
tokumaru
Posts: 11909
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: index outside of label (intentionally) asm

Post by tokumaru » Mon Sep 14, 2020 7:54 pm

Controllerhead wrote:
Mon Sep 14, 2020 5:14 pm
I just increment the PPU pointer with meaningless data in the first slot when loading palettes in a loop and store global BG after at $3F20.
You can also increment the pointer by reading $2007 using the BIT instruction, which doesn't affect any registers, so you don't have to do the BG color last if you don't want to.

User avatar
nyanberrycake
Posts: 19
Joined: Mon Mar 30, 2020 4:35 pm

Re: index outside of label (intentionally) asm

Post by nyanberrycake » Mon Sep 14, 2020 9:07 pm

Oziphantom wrote:
Mon Sep 14, 2020 1:07 am

Code: Select all

backgroundPalette1: .res 4
backgroundPalette2: .res 4
backgroundPalette3: .res 4
backgroundPalette4: .res 4

	ldy #15
@fillPalette:
	lda (paletteData), y
	sta backgroundPalette1, y
	dey
	bpl  @fillPalette
yes I mistyped that example. I know that (address), y is for pointers, not arrays. Maybe that's why I got undefined behaviour when i tried it

but is paletteData a vector point to the data or just an address, because if its an address you can do

Code: Select all

	ldx #15
@fillPalette:
	lda paletteData,x
	sta backgroundPalette1, x
	dex
	bpl  @fillPalette

User avatar
nyanberrycake
Posts: 19
Joined: Mon Mar 30, 2020 4:35 pm

Re: index outside of label (intentionally) asm

Post by nyanberrycake » Mon Sep 14, 2020 9:09 pm

tokumaru wrote:
Mon Sep 14, 2020 4:33 pm
Movax12 wrote:
Mon Sep 14, 2020 12:39 pm

Code: Select all

backgroundPalette:
backgroundPalette1: .res 4
backgroundPalette2: .res 4
backgroundPalette3: .res 4
backgroundPalette4: .res 4
This is the solution I use when I need to access multiple tables from one "master" label.

For palettes specifically I don't waste space with the unused colors though, so I have a variable for the global background color, and 8 sets of 3 colors (total of 25 colors, instead of 32). I don't see any point in pretending that NES palettes are 4 colors when they really aren't.

Thank you this is the answer I was ultimately looking for

User avatar
nyanberrycake
Posts: 19
Joined: Mon Mar 30, 2020 4:35 pm

Re: index outside of label (intentionally) asm

Post by nyanberrycake » Mon Sep 14, 2020 9:11 pm

tokumaru wrote:
Mon Sep 14, 2020 3:14 am
nyanberrycake wrote:
Sun Sep 13, 2020 6:34 pm
for those who search this question on the future, it is not possible, at least with my assembler ca65
This information is not correct. You can definitely use indices past the end of tables/labels in any assembler, as long as you know what you're doing and are 100% sure that the data is stored in memory sequentially.

Your problem here is that you're trying to use an addressing mode that doesn't exist on the 6502: lda (zp), x doesn't exist. The only indirect addressing mode that uses the X register is (zp, x), where X is added to the address of the pointer itself, not the address that the pointer points to. You have to use the Y register for what your trying to do.

Assembler is different from high-level languages in that you can't just learn the syntax and use every addressing mode and operation with every register, each operation is physically implemented inside the CPU, and not all combinations of operations, addressing modes and registers are available. You have to consult the documentation in order to see if a particular combination you want to use exists. With time you get the hang of what exists and what doesn't.
Yeah I didn't mean to write the (), x
i just meant to do palettes, x
just a wee bit tired that day

Post Reply