incrementing a 16-bit address

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
ReverendSA
Posts: 36
Joined: Wed Mar 23, 2016 12:27 pm

incrementing a 16-bit address

Post by ReverendSA »

hello,

I am just wondering if I am doing this the right way, or if there is some secret way to do it that I am missing lol.

in this example, just pretend that:

BACKGROUND_MANSION is an incbin'd nametable 3C0 bytes wide, not 400.

BACKGROUND_LOADING_ADDRESS is 2 bytes in ram meant to be a 16 bit address (hi/lo byte of background mansion nametable incbin).

my goal was to fill the PPU with all 3C0 bytes in 4 loops of #$F0 times but I found that going through the ram address #$F0 amount of times was difficult because no matter how many times I added #$F0 to the LOW byte, it was never incrementing the HIGH byte (i.e $20E0 becomes $10E0 instead of $10E1).

It's a lot easier if you are just doing it in 4 loops for all 400 bytes, since you just add #$1 to the high byte (i.e, $20E0 becomes $20E1 in the next loop). Or just INC address holding the high byte.

the bottom code was the only way I could figure out how to do this

Code: Select all

	LDA #LOW(BACKGROUND_MANSION)	
	STA BACKGROUND_LOADING_ADDRESS
	LDA #HIGH(BACKGROUND_MANSION)
	STA BACKGROUND_LOADING_ADDRESS+1
	LDX #$00
LOOP:
	LDA BACKGROUND_LOADING_ADDRESS
	CLC
	ADC #$F0
	BPL INC16P
	STA BACKGROUND_LOADING_ADDRESS
	JMP CONT
INC16P:
	STA BACKGROUND_LOADING_ADDRESS
	INC BACKGROUND_LOADING_ADDRESS+1
	INX
	CPX #$02
	BNE LOOP
CONT:
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: incrementing a 16-bit address

Post by rainwarrior »

Just FYI, even though the numbers may be stored in little endian, they are always written out in big-endian. $E021 is the byte after $E020. In memory they might look like $20 followed by $E0 though.

If you want to load a byte from a 16-bit pointer stored at BACKGROUND_LOADING_ADDRESS, you need to use the indirect indexed addressing mode, which looks like this:

Code: Select all

LDA (BACKGROUND_LOADING_ADDRESS), Y
This loads a byte from the 16-bit point at BACKGROUND_LOADING_ADDRESS plus Y.

How to increment a 16-bit number:

Code: Select all

    INC BLA+0 ; increment low byte
    BNE SKIP ; 255+1 rolls over to 0, so increment high byte too:
    INC BLA+1
SKIP:
Alternative way to add to a 16-bit number. A little bit slower, but a pattern that works for any number you want to add, not just 1.

Code: Select all

    LBA BLA+0 ; low byte
    CLC
    ADC #1
    STA BLA+0
    LDA BLA+1 ; high byte
    ADC #0 ; this includes any carry from the low-byte add
    STA BLA+1
Another alternative: if your data is a multiple of 256 bytes, you could use Y to keep track of the low byte potion and only increment the high byte:

Code: Select all

    LDX #4 ; count 4 times 256 bytes
    LDY #0
LOOP:
    LDA (BLA), Y
    STA $2007
    INY
    BNE LOOP ; loop until the 256th byte
    INC BLA+1 ; increment the high byte when Y rolls over
    DEX
    BNE LOOP ; outer loop X times
Post Reply