[SOLVED] MMC3 Scanline Mask + Sprite Shuffling = issues...

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
User avatar
Controllerhead
Posts: 241
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

[SOLVED] MMC3 Scanline Mask + Sprite Shuffling = issues...

Post by Controllerhead » Fri Mar 05, 2021 10:55 pm

I have been trying different sprite shuffling techniques in combination with an MMC3 scanline IRQ triggering at $E0 to cut off the bottom 16 pixels. The scanline mask works fine. The sprite shuffling also works fine. Whenever i combine them: OAM does not appreciate this. I get all kinds of graphical glitches on real hardware, sprites flickering in the wrong places; similar to the ones seen writing $2003. The emulators all seem to work fine...

It seems like rapid changes to OAM + a scanline mask cutting off the bottom of the screen = Trouble with OAM. Does this sound familiar to anyone? Any advice?

EDIT: SOLVED: Make sure your PPU_MASK background shutoff is in a very specific piece of hBlank.
Last edited by Controllerhead on Sat Mar 06, 2021 1:27 am, edited 2 times in total.
Image

Ti_
Posts: 42
Joined: Sat Aug 03, 2013 3:08 pm
Location: Russia
Contact:

Re: MMC3 Scanline Mask + Sprite Shuffling = issues...

Post by Ti_ » Fri Mar 05, 2021 11:17 pm

Does this happens in Somari on your hardware?
I made this record on famicom https://yadi.sk/i/NQgOpc603J8Akf

lidnariq
Posts: 10463
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: MMC3 Scanline Mask + Sprite Shuffling = issues...

Post by lidnariq » Fri Mar 05, 2021 11:24 pm

Are you turning off all rendering, or just sprites?
If the former, that's a known bug and requires very specific timing within the scanline to do so safely.

User avatar
Controllerhead
Posts: 241
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: MMC3 Scanline Mask + Sprite Shuffling = issues...

Post by Controllerhead » Fri Mar 05, 2021 11:32 pm

Ti_ wrote:
Fri Mar 05, 2021 11:17 pm
Does this happens in Somari on your hardware?
Nope. Somari is perfect. It's actually where i got the idea from! I play this version:
https://www.romhacking.net/hacks/5026/

lidnariq wrote:
Fri Mar 05, 2021 11:24 pm
that's a known bug and requires very specific timing within the scanline to do so safely.
Turning off backgrounds & sprites with PPU_MASK. I am also writing 0's into PPU_ADDR; i actually saw Somari do it. Anyway, i figured it was some hardware quirk. Details good sir?

I am already rewriting the palette because that drops out sometimes too.
Image

lidnariq
Posts: 10463
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: MMC3 Scanline Mask + Sprite Shuffling = issues...

Post by lidnariq » Fri Mar 05, 2021 11:36 pm

Here's the most ridiculously detailed version: viewtopic.php?t=19915

Wiki says
Turning rendering off in PPUMASK ($2001) before the PPU has finished evaluating sprites for that line (x=192 for lines with no sprites, x=240 for lines with at least one sprite) can corrupt OAM, leading to sprite flicker.
So you have to set your MMC3 IRQ a scanline early and busy-wait there before you disable rendering.

Note that Fiskbit's test in the first link above implies a different window, but it's always "not earlier than dot N and not after dot 255"

Fiskbit
Posts: 269
Joined: Sat Nov 18, 2017 9:15 pm

Re: MMC3 Scanline Mask + Sprite Shuffling = issues...

Post by Fiskbit » Sat Mar 06, 2021 12:24 am

TL;DR: If you're turning rendering off and on both mid-frame, the safe region to disable rendering is having your rendering-disable write land approximately in the range of dots 318-340 (as viewed in the Mesen event viewer; the effects of the write are delayed from the actual write time). I would not consider the bounds here 100% accurate and they may differ by alignment, so I'd suggest landing as close to the middle as possible.

If you're turning rendering off mid-frame and back on during vblank so that it starts at the normal time, then performing a rendering-disable write at approximately 62-253 should also be safe.

-----

There are 3 regions of the scanline on common PPU revisions where disabling rendering puts the PPU into a bad state where it will corrupt one row of OAM the next time rendering becomes enabled. This means that even if you perform OAM DMA between disabling rendering and enabling it again, the data will become corrupted because the corruption occurs at the next start of rendering. These regions cover almost the entirety of the scanline, leaving just a small window at the end of hblank where it's always safe. Having rendering-disable take effect (which is delayed a few dots from when the write is done) in the range of approximately dots 1-64, 65-256, and 257-320 will trigger this behavior.

The exact behavior depends on the range. The 1-64 and 257-320 ranges appear to set one OAM row (8 bytes) equal to row 0. Which row it is depends on when in the range rendering was disabled, though the selection behavior is not the same for both ranges. This corruption appears guaranteed to happen if you disable within these ranges. Mesen supports this behavior as best we understand with the Options -> Emulation -> Advanced -> "Enable PPU OAM row corruption emulation" option, but it's implemented based mostly on the results from one test arrangement, so it may not be completely accurate. The end of the 318-340 safe range estimate assumes that the first 2 dots of the 1-64 range will "corrupt" row 0 by setting it to itself.

The 65-256 range is weirder. This range will only corrupt OAM if you enable rendering again mid-frame, and will only do so on some CPU/PPU alignments; the other alignments are completely safe. The exact behavior is not understood and thus not emulated. It can result in sprites appearing in unexpected places.

This corruption behavior was known by some NES developers and some games do indeed go out of their way to land there. For example, Micro Machines (on rev G+ PPUs) lands within the end-of-scanline safe region, and Bio Force Ape usually does (though is sometimes a little late, which should result in some sprite flicker on the map screen). Others, like Isolated Warrior, don't.
Last edited by Fiskbit on Sat Mar 06, 2021 12:28 am, edited 1 time in total.

User avatar
Controllerhead
Posts: 241
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: MMC3 Scanline Mask + Sprite Shuffling = issues...

Post by Controllerhead » Sat Mar 06, 2021 12:25 am

lidnariq wrote:
Fri Mar 05, 2021 11:36 pm
Fiskbit's test
Super helpful!

Wow, so, there are like "potholes" inside of hBlank that when you shut off rendering through PPU_MASK at a certain time it corrupts specific and predictable pieces of OAM. Furthermore, recopying OAM to attempt to correct it does not work. Wow... so this explains alot of what i've been seeing. ...In brighter news, i'm glad my NES isn't possessed by demons.
Fiskbit wrote:
Thu Apr 09, 2020 7:13 pm
I've attached a test ROM for the OAM flicker issue. I probably went way overboard on this test, but I guess I'd rather have too many features than not enough.
Thank you for writing this! What bizarre behavior... i'm happy to have a nice testable grasp on it.
http://forums.nesdev.com/viewtopic.php?p=248607#p248607

I should be able to play with it from here. Thanks for the links / info!
Image

lidnariq
Posts: 10463
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: MMC3 Scanline Mask + Sprite Shuffling = issues...

Post by lidnariq » Sat Mar 06, 2021 12:53 am

Fiskbit wrote:
Sat Mar 06, 2021 12:24 am
The 65-256 range is weirder. This range will only corrupt OAM if you enable rendering again mid-frame, and will only do so on some CPU/PPU alignments; the other alignments are completely safe. The exact behavior is not understood and thus not emulated. It can result in sprites appearing in unexpected places.
Hm, that's confusing. How did we previously come up with the the 192-240 range?

Here's tepples's reasoning, but: viewtopic.php?p=140414#p140414

User avatar
Controllerhead
Posts: 241
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: MMC3 Scanline Mask + Sprite Shuffling = issues...

Post by Controllerhead » Sat Mar 06, 2021 1:26 am

lidnariq wrote:
Sat Mar 06, 2021 12:53 am
Hm, that's confusing. How did we previously come up with the the 192-240 range?
It's pretty wild watching different parts of OAM get corrupted as you move the PPU shutoff around with the test. On my machine, the OAM corruption seems to be sequential through the table, but, i'm sure it would take one of you hardware wizards to nail it down.
Fiskbit wrote:
Sat Mar 06, 2021 12:24 am
the safe region to disable rendering is having your rendering-disable write land approximately in the range of dots 318-340
Gotcha. That seems to be the ticket, but, also worth testing whatever scanline you shoot for; hopefully on affected hardware. Thanks again for all of your help!

Here is a simple code snippet that hits a nice cutoff:

Code: Select all

; * * *MMC3 Simple Scanline Blanker * *
; * * Now with Less OAM Corruption! * *

IRQ:
	PHA
	
	; (other things besides spinning in a loop)
	
	; Wait for the golden window
	LDA #$11
	SEC
	-
	ADC #$FE
	BNE -
	
	; Turn off rendering
	STA PPU_ADDR
	STA PPU_ADDR
	STA PPU_MASK
	
	; Acknowledge Interrupt
	STA $E000			
	
	PLA
RTI
Image
Last edited by Controllerhead on Sat Mar 06, 2021 3:48 am, edited 1 time in total.
Image

Fiskbit
Posts: 269
Joined: Sat Nov 18, 2017 9:15 pm

Re: MMC3 Scanline Mask + Sprite Shuffling = issues...

Post by Fiskbit » Sat Mar 06, 2021 1:40 am

lidnariq wrote:
Sat Mar 06, 2021 12:53 am
Hm, that's confusing. How did we previously come up with the the 192-240 range?

Here's tepples's reasoning, but: viewtopic.php?p=140414#p140414
I unfortunately don't have a great idea of what's actually going on under the hood and am basing all of this on test results. Kitrinx was looking into this some, but I'm not sure that research has resulted in any useful results yet.

My understanding of the 65-256 range is really limited and it's possible there are portions of this that are safe or safe if sprites aren't present on the line. I hope someone is able to figure out what's going on from the transistor map, since I don't think testing will be sufficient for this.

Ti_
Posts: 42
Joined: Sat Aug 03, 2013 3:08 pm
Location: Russia
Contact:

Re: MMC3 Scanline Mask + Sprite Shuffling = issues...

Post by Ti_ » Sat Mar 06, 2021 4:25 am

Controllerhead wrote:
Fri Mar 05, 2021 11:32 pm
Ti_ wrote:
Fri Mar 05, 2021 11:17 pm
Does this happens in Somari on your hardware?
Nope. Somari is perfect. It's actually where i got the idea from! I play this version:
https://www.romhacking.net/hacks/5026/
Check original Somari, improvement vol.2 doesn't have this bug.

Post Reply