Modifying a Nametable's tile before loading it into the PPU?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Modifying a Nametable's tile before loading it into the PPU?
by on (#114235)
So, I'm trying to make a subroutine that can modify a given tile in a given nametable before it loads into the PPU using ASM6.

The code I have is as follows (the .org is just so I can find the subroutine in the fceuxd's debugger):
Code:

;*TODO: Implement a working version of this subroutine
.org $c500
switch_tile:
   lda nametableaddr_low
   clc
   adc tileswitch_low
   sta tileswitch_low
   lda nametableaddr_high
   adc tileswitch_high
   sta tileswitch_high
   lda newtile
   ldy #$2
   sta (tileswitch_low),y
rts


The most of the code works fine. In fact the only problem is at
Code:
sta (tileswitch_low),y


While the debugger's disassembly shows that (tileswitch_low),y points to the correct address ($d1a9), the address is never actually written to. Going through both the hex editor and the RAM filter show that $d1a9 is unchanged from before.

Why is this so? Is is because I am trying to change a value in ROM? If so, how can I go about changing a nametable's tile?

Thanks for any and all help!
Re: Modifying a Nametable's tile before loading it into the
by on (#114237)
Are you trying to store in the ROM at the location in the ()'s? If so, you're using an addressing mode not even related. It should be either $(location/label) or $location/label,Y if it's an array. If that's not it, please explain more clearly how this code works.
Re: Modifying a Nametable's tile before loading it into the
by on (#114241)
Sanchezman wrote:
Why is this so? Is is because I am trying to change a value in ROM? If so, how can I go about changing a nametable's tile?

It's not called Read Only Memory for nothing. :) Indeed, you can't modify the values in ROM.

If you copy your nametable to (CPU) RAM, you can modify it to your hearts content before uploading it to PPU. Or you could copy it to PPU unmodified, and then modify it. It all depends on what you're trying to do exactly.
Re: Modifying a Nametable's tile before loading it into the
by on (#114252)
There are two ways to build a nametable from parts.

You can copy things into RAM (at $0100-$01BF or $0200-$07FF), modify them there, and then copy them into video memory. Thwaite does this with 2-row chunks that make the hint area, house area, and score area, and Concentration Room does this with 4x4-tile areas around a card that's being turned over. And a lot of platformers do this with the area at the seam.

Or you can just turn off rendering, copy one item into video memory, and then copy another item into video memory on top of this. Nintendo games tend to do this with horizontal and vertical strips of tiles, and RBI Baseball does it with rectangles, as I discovered when reversing a subroutine to see what the heck it does.
Re: Modifying a Nametable's tile before loading it into the
by on (#114296)
tepples wrote:
Or you can just turn off rendering, copy one item into video memory, and then copy another item into video memory on top of this.


So to do this, if I wanted to change, say, tile #85, if my current nametable is at $2800, I could write $2855 to the $2006 register, and make my change through the $2007 register?

**Edit**
Thanks for the advice, tepples. The code that I now have which works is:
Code:
switch_tile:
   lda $2006
   lda ppuaddr_low
   clc
   adc tileswitch_low
   sta ppuaddr_low
   lda ppuaddr_high
   adc tileswitch_high
   sta $2006
   lda ppuaddr_low
   sta $2006
   lda newtile
   sta $2007
rts