NES repeats this sequence of reads:
* Read Nametable byte
* Read Attribute Table byte
* Read background tile graphics low byte
* Read background tile graphics high byte
Then when it's time for sprites:
* Read garbage Nametable byte
* Read garbage Nametable byte
* Read sprite Tile graphics (sprite) low byte
* Read sprite Tile graphics (sprite) high byte
-
The critical part of this pattern is that it's always an Attribute table byte before background tile graphics, and always a Nametable byte before sprite tile graphics.
Nametables are at 2000-23BF and repeating every 400 bytes later (appears four times).
Attribute tables are at 23C0-23FF and repeating every 400 bytes later (appears four times)
Distinguishing the two requires not much more than ANDing a bunch of address lines together.
So now, when you see a Nametable read:
- Save the low bit of column and low bit of row, use those to make a value 0-3.
- Bankswitch CHR-RAM to bank 4 for sprites
Then when you see an Attribute table read:
- Bankswitch CHR-RAM to your value 0-3 for the background tile read