Two separate things going on here:
1) Data table with indexed addressing.
In this sample code, `background` is the name of a table in memory. It's not a `variable`, because it's an address of ROM, which is not modifiable. Instead, this location in memory has a bunch of read-only data, and an amount of bytes equal to $80 is being read from that location and loaded into the PPU.
Let's say, for example, that `background` is pointing at the address $9123. Then the instruction:
LDA background,x
Will get the address at $9123+x and put it into the accumulator. The first time through the loop, X = 0, due to the LDX instead before the loop.
So:
LDA background,x
when X=0, loads A with the value in ROM at $9123
The next time through the loop, when X = 1,
LDA background,x
loads A with the value in ROM at $9124
and so on until X = $80.
This has nothing at all to do with sprite DMA, that's completely unrelated.
2) The high / low latch
The NES is an 8-bit machine, but its uses address spaces that are 16-bits, from $0000 to $ffff. In particular, the PPU has a 16-bit address space. This means that to create a pointer to the PPU's memory, addresses have to be created one byte at a time. When a byte is written to CPU's address $2006, this sets half of the PPU memory pointer. Which half it sets is based upon an internal flop called a "latch". When PPU_STATUS ($2002) is read, it resets the latch to "high", meaning the next write to $2006 will be the high byte of the ppu address, and this write will also flop the latch. The following write to $2006 will then be the low byte of the ppu address.
Stepping through this code a single instruction at a time:
Code: Select all
LDA $2002 - latch=0, ppu_pointer=????
LDA #$20 - latch=0, ppu_pointer=????
STA $2006 - latch=1, ppu_pointer=20??
LDA #$00 - latch=1, ppu_pointer=20??
STA $2006 - latch=0, ppu_pointer=2000