I'd like to disable rendering for the first 16 scanlines to do pattern table updates, but I'm concerned about OAM corruption and Battletoad's dot crawl pattern.
I have heard that the way to prevent the dot crawl problem is to enable rendering for the first scanline after vblank and disable it right after, but I have also heard that doing so causes OAM corruption which is a much bigger issue than dot crawl.
Now, I've heard it said that OAM corruption won't occur when rendering is disabled between dots 176 and 256, but is that true? Do I have to worry about the placement of sprites at all? In that thread, Bananmos and Tokumaru both made it seem as though OAM corruption was unavoidable, even with carefully timed writes.
My current code is as follows. I would appreciate if others would look it over.
Does this look like it will work?
I don't own an NES and so I have no way of testing this on real hardware.
I have heard that the way to prevent the dot crawl problem is to enable rendering for the first scanline after vblank and disable it right after, but I have also heard that doing so causes OAM corruption which is a much bigger issue than dot crawl.
Now, I've heard it said that OAM corruption won't occur when rendering is disabled between dots 176 and 256, but is that true? Do I have to worry about the placement of sprites at all? In that thread, Bananmos and Tokumaru both made it seem as though OAM corruption was unavoidable, even with carefully timed writes.
My current code is as follows. I would appreciate if others would look it over.
Code:
; Do OAM DMA.
lda #.hibyte(CPU_OAM)
sta OAMDMA
; Enable rendering
lda #PPUMASK_BG_ON
sta PPUMASK
; Wait for the end of vblank.
waitForSprite0Clear:
bit PPUSTATUS
bvs waitForSprite0Clear
; Draw the first scanline with rendering enabled, then turn rendering off.
lda #157
jsr delay_A_plus_25_cycles
lda #0
sta PPUMASK ; This write happens after dot 176 but before dot 256
; Animation frames run in a fixed amount of cycles.
bankswitch_to anim_frames_lo
jsr jumpToAnimationPtr
lda #88
jsr delay_A_plus_25_cycles
; Turn rendering back on
lda #PPUMASK_SPR_ON | PPUMASK_BG_ON
sta PPUMASK ; This write happens after dot 256
lda #.hibyte(CPU_OAM)
sta OAMDMA
; Enable rendering
lda #PPUMASK_BG_ON
sta PPUMASK
; Wait for the end of vblank.
waitForSprite0Clear:
bit PPUSTATUS
bvs waitForSprite0Clear
; Draw the first scanline with rendering enabled, then turn rendering off.
lda #157
jsr delay_A_plus_25_cycles
lda #0
sta PPUMASK ; This write happens after dot 176 but before dot 256
; Animation frames run in a fixed amount of cycles.
bankswitch_to anim_frames_lo
jsr jumpToAnimationPtr
lda #88
jsr delay_A_plus_25_cycles
; Turn rendering back on
lda #PPUMASK_SPR_ON | PPUMASK_BG_ON
sta PPUMASK ; This write happens after dot 256
Does this look like it will work?
I don't own an NES and so I have no way of testing this on real hardware.