Loopy's doc really covers it quite well... although i found it a little hard to follow at first too. Once I realized how he set it up, though, it became really obvious.
Your emu will need to track the following:
- PPU Address (sometimes called "Loopy_V") - at least 16 bit
- A temporary Address (sometimes called "Loopy_T") - at least 16 bit
- X fine-scroll value - at least 8 bit
The PPU Address is the same address that's set by writes to $2006. For example... when a game writes $3F then $10 to $2006 in order to access palette information, it's setting the PPU address (Loopy_V) to $3F10.
To look back at loopy's doc:
2005 first write:
2005 second write:
2006 first write:
2006 second write:
scanline start (if background and sprites are enabled):
frame start (line 0) (if background and sprites are enabled):
t = the temporary address (Loopy_T)
v = the real PPU address (Loopy_V)
x = X fine-scroll
d = the value being written
Look specifically at the $2006 writes. On the first $2006 write:
t:0011111100000000=d:00111111 <--- that's basically saying that the low 6 bits of the value written are moved to bits 8-13 of Loopy_T.
t:1100000000000000=0 <--- that's saying the high 2 bits of Loopy_T are cleared
To put this in the form of C code:
Loopy_T = (Loopy_T & 0xC0FF) | ( (Value_Written & 0x3F) << 8 ); /* have the low 6 bits of the value written replace the appropriate bits in Loopy_T */
Loopy_T &= 0x3FFF; /* clear upper 2 bits of Loopy_T */
Then on the second write to $2006, the low 8 bits of Loopy_T are replaced with the value written... and Loopy_V (the real ppu address) is set to Loopy_T.
When drawing... you simply pull tiles from the name table at the address specified by Loopy_V.