About half a year ago, nocash released his CHR-less Magic Floor, and verified it against his PAL NES. I recently tried to make a reproduction of it on my NTSC NES, and it haaaaates it. All the sprites are wrong, and the dot usually disappears immediately. (Which is because the PPU OAM readback is somewhat broken in the 2C02, but there's more).
Magic Floor originally moved the dot by doing something like
I shadowed away the reads from $2004; tried resetting $2003 to 0 at the end, and even tried replacing the $2003←3 with $2004←#Tile; $2004←0, but none of them really ever made it happy.
And despite the entire OAM being set on powerup (all #$EF or #$FF, I tried both), there's still garbage sprites appearing in the upper left corner (if I had to guess, somewhere around X=Y=16). And behavior still gets worse as the PPU gets warmer.
I finally switched the entire code to just use OAM DMA like everyone else, and it worked fine. So what's going on? Just how tricky is the OAM? Is it possible to do partial OAM updates on an NTSC NES? It seems silly to spend 513 or 514 cycles doing OAM DMA instead of ≈24.
Magic Floor originally moved the dot by doing something like
Code:
LDA #0
STA $2003
LDA $2004
CLC
ADC YdirectionAndVelocity
STA $2004
LDA #3
STA $2003
LDA $2004
CLC
ADC XdirectionAndVelocity
STA $2004
STA $2003
LDA $2004
CLC
ADC YdirectionAndVelocity
STA $2004
LDA #3
STA $2003
LDA $2004
CLC
ADC XdirectionAndVelocity
STA $2004
I shadowed away the reads from $2004; tried resetting $2003 to 0 at the end, and even tried replacing the $2003←3 with $2004←#Tile; $2004←0, but none of them really ever made it happy.
And despite the entire OAM being set on powerup (all #$EF or #$FF, I tried both), there's still garbage sprites appearing in the upper left corner (if I had to guess, somewhere around X=Y=16). And behavior still gets worse as the PPU gets warmer.
I finally switched the entire code to just use OAM DMA like everyone else, and it worked fine. So what's going on? Just how tricky is the OAM? Is it possible to do partial OAM updates on an NTSC NES? It seems silly to spend 513 or 514 cycles doing OAM DMA instead of ≈24.