I was considering enhancing the wiki with some pseudocode to further the details on PPU sprite evaluation. But, there are 2 parts marked with question marks that I am unsure about:
Code:
readCycle = (scanlineCycle AND 1) == 1
if scanlineCycle == 0
if scanline == PRE_RENDER_SCANLINE and ((4 * primarySprite + primaryVar) AND $F8) != 0
copy OAM[primarySprite AND $FE][0..3] to OAM[0][0..3]
copy OAM[(primarySprite AND $FE) + 1][0..3] to OAM[1][0..3]
primarySprite = 0
primaryVar = 0
secondarySprite = 0
secondaryVar = 0
else if scanlineCycle <= 64
if readCycle
oamValue = $FF
else
SOAM[secondarySprite][secondaryVar] = oamValue
secondaryVar = secondaryVar + 1
if secondaryVar == 4
secondaryVar = 0
secondarySprite = secondarySprite + 1
if scanlineCycle == 64
secondarySprite = 0
secondaryVar = 0
state = STATE_COPY_Y
else if scanlineCycle <= 256
if readCycle
oamValue = OAM[primarySprite][primaryVar]
else
if state == STATE_COPY_Y
SOAM[secondarySprite][secondaryVar] = oamValue
if scanline >= oamValue and scanline <= (oamValue + spriteBottomOffset)
state = STATE_COPY_REMAINING
primaryVar = primaryVar + 1
if primaryVar == 4
primaryVar = 0
primarySprite = primarySprite + 1
if primarySprite == 64
primarySprite = 0
secondaryVar = secondaryVar + 1
if secondaryVar == 4
secondaryVar = 0
secondarySprite = secondarySprite + 1
if secondarySprite == 8
secondarySprite = 0
else
primarySprite = primarySprite + 1
if primarySprite == 64
primarySprite = 0
state = STATE_SPIN
else if state == STATE_COPY_REMAINING
SOAM[secondarySprite][secondaryVar] = oamValue
primaryVar = primaryVar + 1
if primaryVar == 4
primaryVar = 0
primarySprite = primarySprite + 1
if primarySprite == 64
primarySprite = 0
secondaryVar = secondaryVar + 1
if secondaryVar == 4
secondaryVar = 0
secondarySprite = secondarySprite + 1
if secondarySprite == 8
secondarySprite = 0
state = STATE_SPRITE_8_Y
else if primarySprite == 0
state = STATE_SPIN
else
state = STATE_COPY_Y
else if state == STATE_SPRITE_8_Y
if scanline >= oamValue and scanline <= (oamValue + spriteBottomOffset)
state = STATE_SPRITE_8_REMAINING
spriteOverflow = true
primaryVar = primaryVar + 1
if primaryVar == 4
primaryVar = 0
primarySprite = primarySprite + 1
if primarySprite == 64
primarySprite = 0
secondaryVar = 1
else
// ?? 1 ??
state = STATE_SPIN
else if state == STATE_SPRITE_8_REMAINING
primaryVar = primaryVar + 1
if primaryVar == 4
primaryVar = 0
primarySprite = primarySprite + 1
if primarySprite == 64
primarySprite = 0
secondaryVar = secondaryVar + 1
if secondaryVar == 4
secondaryVar = 0
secondarySprite = secondarySprite + 1
// ?? 2 ??
state = STATE_SPIN
else if state == STATE_SPIN
primarySprite = primarySprite + 1
if primarySprite == 64
primarySprite = 0
else if scanlineCycle <= 320
if scanlineCycle == 257
primarySprite = 0
primaryVar = 0
secondarySprite = 0
secondaryVar = 0
if ((scanlineCycle - 1) AND $04) < 4
secondaryVar = secondaryVar + 1
if secondaryVar == 4
secondaryVar = 0
secondarySprite = secondarySprite + 1
if secondarySprite == 8
secondarySprite = 0
if scanlineCycle == 0
if scanline == PRE_RENDER_SCANLINE and ((4 * primarySprite + primaryVar) AND $F8) != 0
copy OAM[primarySprite AND $FE][0..3] to OAM[0][0..3]
copy OAM[(primarySprite AND $FE) + 1][0..3] to OAM[1][0..3]
primarySprite = 0
primaryVar = 0
secondarySprite = 0
secondaryVar = 0
else if scanlineCycle <= 64
if readCycle
oamValue = $FF
else
SOAM[secondarySprite][secondaryVar] = oamValue
secondaryVar = secondaryVar + 1
if secondaryVar == 4
secondaryVar = 0
secondarySprite = secondarySprite + 1
if scanlineCycle == 64
secondarySprite = 0
secondaryVar = 0
state = STATE_COPY_Y
else if scanlineCycle <= 256
if readCycle
oamValue = OAM[primarySprite][primaryVar]
else
if state == STATE_COPY_Y
SOAM[secondarySprite][secondaryVar] = oamValue
if scanline >= oamValue and scanline <= (oamValue + spriteBottomOffset)
state = STATE_COPY_REMAINING
primaryVar = primaryVar + 1
if primaryVar == 4
primaryVar = 0
primarySprite = primarySprite + 1
if primarySprite == 64
primarySprite = 0
secondaryVar = secondaryVar + 1
if secondaryVar == 4
secondaryVar = 0
secondarySprite = secondarySprite + 1
if secondarySprite == 8
secondarySprite = 0
else
primarySprite = primarySprite + 1
if primarySprite == 64
primarySprite = 0
state = STATE_SPIN
else if state == STATE_COPY_REMAINING
SOAM[secondarySprite][secondaryVar] = oamValue
primaryVar = primaryVar + 1
if primaryVar == 4
primaryVar = 0
primarySprite = primarySprite + 1
if primarySprite == 64
primarySprite = 0
secondaryVar = secondaryVar + 1
if secondaryVar == 4
secondaryVar = 0
secondarySprite = secondarySprite + 1
if secondarySprite == 8
secondarySprite = 0
state = STATE_SPRITE_8_Y
else if primarySprite == 0
state = STATE_SPIN
else
state = STATE_COPY_Y
else if state == STATE_SPRITE_8_Y
if scanline >= oamValue and scanline <= (oamValue + spriteBottomOffset)
state = STATE_SPRITE_8_REMAINING
spriteOverflow = true
primaryVar = primaryVar + 1
if primaryVar == 4
primaryVar = 0
primarySprite = primarySprite + 1
if primarySprite == 64
primarySprite = 0
secondaryVar = 1
else
// ?? 1 ??
state = STATE_SPIN
else if state == STATE_SPRITE_8_REMAINING
primaryVar = primaryVar + 1
if primaryVar == 4
primaryVar = 0
primarySprite = primarySprite + 1
if primarySprite == 64
primarySprite = 0
secondaryVar = secondaryVar + 1
if secondaryVar == 4
secondaryVar = 0
secondarySprite = secondarySprite + 1
// ?? 2 ??
state = STATE_SPIN
else if state == STATE_SPIN
primarySprite = primarySprite + 1
if primarySprite == 64
primarySprite = 0
else if scanlineCycle <= 320
if scanlineCycle == 257
primarySprite = 0
primaryVar = 0
secondarySprite = 0
secondaryVar = 0
if ((scanlineCycle - 1) AND $04) < 4
secondaryVar = secondaryVar + 1
if secondaryVar == 4
secondaryVar = 0
secondarySprite = secondarySprite + 1
if secondarySprite == 8
secondarySprite = 0