It is currently Mon Dec 18, 2017 11:41 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: Sat Jun 04, 2016 2:55 am 
Offline
User avatar

Joined: Thu Mar 31, 2016 11:15 am
Posts: 221
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.

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

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.


Top
 Profile  
 
PostPosted: Sat Jun 04, 2016 3:17 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2983
Location: Tampere, Finland
Unfortunately, I don't think the sprite corruption details have been nailed down, so testing on hardware feels mandatory.

One idea that came to mind, although I haven't tested this, would be to do OAM DMA in forced blanking, just before rendering is re-enabled. That way, it wouldn't matter if the earlier disabling of rendering corrupted them. I'm pretty sure there are one or two games which do OAM DMA midscreen, so at least the concept should work.

BTW, to folks familiar with Visual2C02: can it simulate the OAM corruption correctly?

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Sat Jun 04, 2016 8:13 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10173
Location: Rio de Janeiro - Brazil
thefox wrote:
One idea that came to mind, although I haven't tested this, would be to do OAM DMA in forced blanking, just before rendering is re-enabled. That way, it wouldn't matter if the earlier disabling of rendering corrupted them.

The thing is, it's not disabling rendering that corrupts sprites, it's re-enabling that does it! (Relevant link) This quirk is nastier than most people make it out to be.

The moment at which you disable rendering is important because it defines what the PPU will do when rendering is re-enabled, which is when the corruption may actually take place, so doing the DMA during forced blanking doesn't solve anything.


Top
 Profile  
 
PostPosted: Sat Jun 04, 2016 9:30 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2983
Location: Tampere, Finland
tokumaru wrote:
The moment at which you disable rendering is important because it defines what the PPU will do when rendering is re-enabled, which is when the corruption may actually take place, so doing the DMA during forced blanking doesn't solve anything.

Ah, so when it's disabled the PPU is left in a certain state and then resumes in a glitched way when rendering is re-enabled?

Anyways, I'm pretty sure there are some games that do OAM DMA during forced blanking midscreen, so it must be doable with proper timing, but I can't remember the name(s) of the game(s).

EDIT: Skull & Crossbones (Tengen, unlicensed) was the game I was thinking of. It has two player split screen and does OAM DMA in the middle. It's hard to say if it suffers from sprite corruption though.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Last edited by thefox on Sat Jun 04, 2016 9:39 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Sat Jun 04, 2016 9:32 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5899
Location: Canada
tokumaru wrote:
thefox wrote:
One idea that came to mind, although I haven't tested this, would be to do OAM DMA in forced blanking, just before rendering is re-enabled. That way, it wouldn't matter if the earlier disabling of rendering corrupted them.

The thing is, it's not disabling rendering that corrupts sprites, it's re-enabling that does it! (Relevant link) This quirk is nastier than most people make it out to be.

The moment at which you disable rendering is important because it defines what the PPU will do when rendering is re-enabled, which is when the corruption may actually take place, so doing the DMA during forced blanking doesn't solve anything.

If rendering was disabled during vblank, it's not a problem, though. What thefox suggested should work, as it solves the problem that OAM decays if not refreshed (or rendered) for longer than roughly the vblank period. (I don't know what the "battletoads dot crawl" issue is, though, so if you were trying to solve that, I dunno.)

When that thread you linked came up I tried to make sure the Wiki had warnings about it in PPU $2001 documentation, and Sprite Errata. I think the rule was that if you're disabling rendering outside of vblank, you must do it after pixel 192, or there's a chance of corrupting sprites on the next frame.

...and yes, testing on hardware is mandatory. You're in dark territory. I'd suggest to "do what Battletoads does" but apparently you want to try something even crazier. ;)


Top
 Profile  
 
PostPosted: Sat Jun 04, 2016 9:46 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2983
Location: Tampere, Finland
rainwarrior wrote:
I don't know what the "battletoads dot crawl" issue is, though, so if you were trying to solve that, I dunno.

It refers to the skipped tick at (0,0) from http://wiki.nesdev.com/w/index.php/File:Ntsc_timing.png. If rendering is kept disabled at that point, the tick is never skipped, thus producing a different dot crawl pattern than normally. In Battletoads the screen is visibly more "crawly" than in other games when the screen is not scrolling.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Sat Jun 04, 2016 10:35 am 
Offline
User avatar

Joined: Thu Mar 31, 2016 11:15 am
Posts: 221
Thanks for the replies.

Let's say I ignore the dot crawl issue and keep rendering turned off from vblank to the 10th scanline. OAM DMA would be done less than 20 scanlines before rendering is turned on.

There wouldn't be any OAM corruption in this case, correct?

I want to know so that I'll have a backup plan when I test on real hardware and all hell breaks loose :)


Top
 Profile  
 
PostPosted: Sat Jun 04, 2016 10:53 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10173
Location: Rio de Janeiro - Brazil
rainwarrior wrote:
If rendering was disabled during vblank, it's not a problem, though.

The OP does want to disable rendering shortly after rendering starts though, to avoid the alternate dot crawl pattern.


Top
 Profile  
 
PostPosted: Sat Jun 04, 2016 11:48 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5899
Location: Canada
pubby wrote:
Let's say I ignore the dot crawl issue and keep rendering turned off from vblank to the 10th scanline. OAM DMA would be done less than 20 scanlines before rendering is turned on.

There wouldn't be any OAM corruption in this case, correct?

In my testing, I found the OAM only remains stable for just over 20 scanlines. The minimum thing it needed to be able to do was survive a vblank, and as it turns out that's all it can do. If you start DMA within 20 scanlines of turning rendering on I think you'll be okay. (Give it a good hardware test though.)


Top
 Profile  
 
PostPosted: Sat Jun 04, 2016 11:52 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10173
Location: Rio de Janeiro - Brazil
Oops, missed the post about ignoring the alternate dot crawl pattern!


Top
 Profile  
 
PostPosted: Mon Jun 20, 2016 11:13 pm 
Offline
User avatar

Joined: Thu Mar 31, 2016 11:15 am
Posts: 221
I haven't had any luck sourcing a cheap NES and so I haven't been able to test on real hardware.

So...

Would any NTSC person be willing to 5-minute-test a ROM or two for me? If so, PM me.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group