ca65 Need help loading nametables

Started by Arkanix38, July 28, 2017, 03:53:02 am

Previous topic - Next topic

Arkanix38

Hey guys, thought i'd ask here before making a NESDev account. I've been working on trying to teach myself some 6502 ASM but have been getting hung up on some of the NES' quirks. I'm starting with a small program with a moveable sprite and a background. Following the Nerdy Nights ca65 tutorials I can fill the first $FF blocks of data and have moved on to adapting code from a NESASM tutorial to fill a single nametable in memory.

Memory is being sufficiently allocated but the background sprites are garbled, with a majority of them choosing tile $00.

The below code is what I am using to load the nametable into VRAM

load_background:
lda PPU_STATUS
lda #$20
sta PPU_VRAM_ADDR2
lda #$00
sta PPU_VRAM_ADDR2
lda <background ;low byte, produces warning :(
sta $10
lda >background ;high byte, produces warning :(
sta $11
ldy #$00
ldx #$04
@loop:
lda ($10),y
sta PPU_VRAM_IO
iny
bne @loop
inc $11
dex
bne @loop

Here is an image of the garbled sprites (ignore the 1UP sprites as they are intentional controlled sprites and not part of the background)

P

I think lda <background should be typed as lda #<(background).

I'd also give labels to RAM registers $10 and $11. Like this:

;Variables:
.segment "ZEROPAGE"
pointer:        .res 2    ;general purpose pointer
;...

Then you can refer to each element in the pointer as pointer+0 and pointer+1 etc.

The reason there are lots of zeroes on the screen is probably because you have zero loaded as CHR number $00 and many emulators initializes VRAM (and all other RAM) to 0. On a real Famicom however, RAM registers can be anything so it's best to initialize all RAM to 0 and the nametables to whatever value you have as a white space character. The attribute table should be initialized to 0 though. The reason you have some weird colors on the screen could be because your nametable writing loop spilled over to the attribute table (each nametable's attribute table comes right after it in VRAM).

Arkanix38

The colors are fine, and as defined as my attribute table intends. I'll try asserting immediate mode for the > and < operators to see what happens, thanks!

P

I see.

If it just gives you a warning instead of syntax error it might assemble it correctly though (but I'd use a # anyway to be clear). What does the warning say?

Other than the lack of a #, the code looks correct to me.

Arkanix38

Just gave it a go and it works great, this was a little learning exercise for me as I wasn't sure how the .lobyte and .hibyte functions worked in parsing values. It makes sense that LDA would require the specification of reading the value of the ca65 lo/hibyte function in immediate mode.

working code follows...

load_background:
lda PPU_STATUS
lda #$20                          ;high byte
sta PPU_VRAM_ADDR2
lda #$00                          ;low byte
sta PPU_VRAM_ADDR2
lda #<background ;low byte
sta addrLO
lda #>background ;high byte
sta addrHI
ldy #$00                           ;init pointer, will decrement 256 times
ldx #$04                           ;init pointer, 256*4=1kbyte
@loop:
lda (addrLO),y
sta PPU_VRAM_IO
iny
bne @loop
inc addrHI
dex
bne @loop


PS thanks for the help!

P

Ah good that it works!

QuoteIt makes sense that LDA would require the specification of reading the value of the ca65 lo/hibyte function in immediate mode.

Yes since you want to store the address of "background" in your pointer you need to use LDA immediate addressing (which is indicated in CA65 assembly with a #).

I guess CA65 interpret "LDA <background" as a zero page addressing using the low byte in the "background" label's address as a zero page address. And it gives a warning because it understands that that's probably not what you wanted.