Disabling rendering during OAM evaluation

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
Sour
Posts: 891
Joined: Sun Feb 07, 2016 6:16 pm

Disabling rendering during OAM evaluation

Post by Sour »

In the ROM pubby originally posted in this thread (the ROM is no longer available there), there was a bug that did not occur on any emulator, but was visible on PowerPak/Everdrive (see the youtube video in that thread).
After a building a small test case and doing some testing with Visual NES, it turns out that disabling rendering during OAM evaluation has a side effect, which was causing the visual glitches in pubby's video.

Essentially, disabling rendering when OAM evaluation is on-going (e.g between cycles 65 and 256) will cause the current OAM address to be (unexpectedly) incremented by 1. In the game's specific case, rendering was disabled around cycle 200, after all visible sprites had been found and the OAM address had rolled around to about $10, incrementing by 4 every other PPU cycle (like it does when the sprite isn't in range). Disabling rendering at this point will cause the next odd PPU cycle to increment by an additional 1.

e.g:
-If disabled on an even cycle, the next cycle will increment by 5 (the normal 4, plus 1)
-If disabled on an odd cycle (e.g the address just got increment by 4 already), the next (even) cycle runs normally and the next (odd) cycle after that will increment the address by 1.

So, in this case, it causes the address to jump from, for example, $10 to $11. Since $4014 was written to without writing to $2003 first, the sprite DMA was starting at $11, meaning all the data was offset by 1 byte, causing a ton of unexpected sprites to be shown on the screen.

Something I haven't tested is what would happen when disabling OAM evaluation while a sprite that's visible on the next line is being read byte-by-byte (would it increment by 2 instead of 1 (unlikely?), or would it trigger both the +4 increment and +1 increments at once, like it does in other known scenarios).

This is a pretty minor thing that would normally go unnoticed (e.g because usually $2003 is written to right before $4014), but without emulating this behavior, the contents of OAM are shifted by a multiple of 4 (e.g because DMA writes will start at $10), which means that, while the order of sprites in OAM are wrong for a frame, it doesn't actually cause any visible issues on the screen.

Unfortunately, I don't really have a test rom to share for this one at the moment (the one I made was purely to check the behavior in Visual NES and is essentially worthless in an actual emulator). I've attached a screenshot of my observations in Visual NES (testing at various points during the scanline how the PPU reacts to a $2001 write that disables rendering). Implementing this behavior in Mesen causes glitches identical to the ones seen in the Youtube video.
Attachments
oamaddrtests.png
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Disabling rendering during OAM evaluation

Post by tepples »

Sour wrote:This is a pretty minor thing that would normally go unnoticed (e.g because usually $2003 is written to right before $4014), but without emulating this behavior, the contents of OAM are shifted by a multiple of 4 (e.g because DMA writes will start at $10), which means that, while the order of sprites in OAM are wrong for a frame, it doesn't actually cause any visible issues on the screen.
Except for lockups when sprite 0 misses, or perhaps massive background flickering in games with an anti-lockup failsafe.

But thanks for following up on the issue I brought up ten years ago. It'll help us work toward figuring out when it's safe to force blank at the bottom for extra VRAM access time, particularly now that modern TVs have a zoom mode that crops the top and bottom 36 or so lines anyway.
Sour
Posts: 891
Joined: Sun Feb 07, 2016 6:16 pm

Re: Disabling rendering during OAM evaluation

Post by Sour »

Bump.

Someone reported graphical glitches during the intro of TMNT (https://github.com/SourMesen/Mesen/issues/737) and it was caused by the glitch I described in the first post. When the glitch is not emulated, the intro has no graphical issues. Fiskbit tested this on a NES with his TMNT cartridge and the same glitches were visible, so TMNT is the first licensed game I am aware of that is affected by this issue.
Alyosha_TAS
Posts: 173
Joined: Wed Jun 15, 2016 11:49 am

Re: Disabling rendering during OAM evaluation

Post by Alyosha_TAS »

This glitch also effects the game T&C Surf Designs. I captured the following images from a front loader NES. The stray sprites on the left side of the screen are a result of this glitch.

Due to sprite zero timing, this glitch is actually important for the TAS of this game, as it breaks console sync because the glitch was not emulated on the version of NESHawk that the TAS was made on.

spr_addr_glitch.png
Post Reply