bigjt_2 wrote:So, just as a clue for later, when I get advanced enough to do scrolling and start wanting to shift nametables, does it work kind of like this, where there's a quick graphical update in NMI and the logic to shift into one nametable or another is handled in logic outside of NMI?
It's similar, but unfortunately Nintendo didn't include something to speed things up (like the DMA does for sprites), so we must do most of it ourselves.
Inside the game logic loop is where all the camera movement will be, and whenever the camera moves enough to show a new part of the level you have to read data from your level map (what format will be used to encode it is up to you) and feed some buffers with the tile and attribute data corresponding to the new part of the level. Then, inside the NMI, you copy that data to VRAM as fast as you can.
It's the same principle: compute all the data inside the game logic loop and in the NMI just upload the computed data to VRAM.
Note that to make a scrolling game you don't have to shift the whole background, as that would take too much time and would be impossible to update in a single VBlank. This is why the hardware scroll exists, to display different parts of the name tables based on the coordinates you give it. This means that each frame you only have to worry about new background elements that enter the game view from the edges of the camera.
Like I always recommend, play a scrolling game (preferably one that doesn't use 1-screen mirroring, because that's hard to see) in an emulator that has name table viewing (FCEUX(D), Nintendulator... even Nesticle!) and watch how the new things that enter the view replace old ones that are no longer visible.