nesdev.com
http://forums.nesdev.com/

How reliable is $2003?
http://forums.nesdev.com/viewtopic.php?f=2&t=16108
Page 1 of 1

Author:  tokumaru [ Sun Jun 18, 2017 3:57 am ]
Post subject:  How reliable is $2003?

With all the weirdness that exists related to the OAM, sprite evaluation and $2003/4, I'm wondering how reliable $2003 is under certain conditions.

For example, is it safe to set $2003 to a value other than 0 (but still a multiple of 4) before a sprite DMA? Can I expect to have all 256 bytes transferred from RAM to OAM without any sort of corruption? Do I need to set $2003 to 0 afterward or can it be left as is?

Some quirks of the PPU are hard to keep up with, so I figured I'd just come here and ask. Thanks.

Author:  Quietust [ Sun Jun 18, 2017 6:22 am ]
Post subject:  Re: How reliable is $2003?

From what I understand (and from some tests I performed a number of years ago), it might be safe to set $2003 to a nonzero value, perform a DMA, then immediately set it to zero afterwards. More tests would still be a great idea, though.

If you leave the address as-is, all 256 bytes will still be copied successfully, but sprites 0 and 1 are likely to get corrupted when rendering starts (a behavior which the Sachen game "Huge Insect" relies on).

Author:  lidnariq [ Sun Jun 18, 2017 12:01 pm ]
Post subject:  Re: How reliable is $2003?

My understanding is that with the 2C02G:

* At the end of normal rendering, $2003 will be set to 0
* If you change it via writes to $2003, regardless of what you change it to or from, it will corrupt OAM, and in a not particularly predictable fashion.
* If rendering is enabled normally, and it's more than 7 when rendering starts, it'll corrupt OAM in a predictable manner, copying the 8 bytes at (OAMADDR & $F8) to the first 8 bytes.

The only thing remaining question is whether delaying turning on rendering until a later scanline will change that final behavior.

We know that the 2C02E is different, but haven't quantified how. We know that the 2C07 is approximately bug-free, although it has a few obnoxious deliberate design decisions.

Author:  tokumaru [ Sun Jun 18, 2017 12:19 pm ]
Post subject:  Re: How reliable is $2003?

Thanks for the replies. So it looks like it should indeed be safe to use values other than 0 for OAMADDR before the DMA as long as you set if back to 0 afterwards. I was mostly thinking about alternate ways to implement sprite cycling, but these 2 registers ($2003 and $2004) are so odd that I'm not sure I should take the risk.

Author:  lidnariq [ Sun Jun 18, 2017 12:23 pm ]
Post subject:  Re: How reliable is $2003?

Er... that's not what I said at all.

In the 2C02G, writing to $2003 always causes corruption, regardless of what you're changing it to or from. It's basically never safe to write any value other than 0 to $2003, and even then you have to follow it with OAMDMA.

(edit) There is one very precise exception:
* If you write a non-zero multiple of 8 to $2003
* and you follow it with OAMDMA
* and you let rendering start normally, copying the 8 bytes at [OAMADDR]&$F8 to the beginning of the buffer
THEN the first eight bytes of the shadow OAM buffer will always end up being copied to sprites 0 and 1, and the remaining 62 sprites will rotate (of which two will be destroyed)

So ... in a roundabout way, it's safe to use, with the caveat that it will guarantee that there will always be something that looks like sprite dropout flicker.

Author:  Quietust [ Sun Jun 18, 2017 1:31 pm ]
Post subject:  Re: How reliable is $2003?

lidnariq wrote:
In the 2C02G, writing to $2003 always causes corruption, regardless of what you're changing it to or from. It's basically never safe to write any value other than 0 to $2003, and even then you have to follow it with OAMDMA.


Back about 3 years ago, when these problems were being identified, I wrote a test program to try out various special combinations of doing offset DMAs, modifying $2003 immediately afterwards, and possibly waiting a frame before reading it back, and what I personally found (on my CopyNES) is that writing $2003 only caused corruption with certain CPU/PPU clock alignments (in my case, it would always corrupt $20-$27), but for other alignments it was consistently safe to write to $2003 immediately after a DMA without causing any corruption.

Author:  tokumaru [ Sun Jun 18, 2017 7:14 pm ]
Post subject:  Re: How reliable is $2003?

lidnariq wrote:
Er... that's not what I said at all.

Oh crap, I totally overlooked the fact that writing 0 to OAMADDR after the DMA could also cause corruption.

Quietust wrote:
writing $2003 only caused corruption with certain CPU/PPU clock alignments (in my case, it would always corrupt $20-$27), but for other alignments it was consistently safe to write to $2003 immediately after a DMA without causing any corruption.

See, that's the problem right there... We're still debating what's safe and what's not, so until we finally reach a consensus, I guess it's better to leave OAMADDR as 0 at all times.

Author:  lidnariq [ Sun Jun 18, 2017 7:22 pm ]
Post subject:  Re: How reliable is $2003?

I mean, I trust Quietust's findings. I don't quite have the right hardware to put his program on a flashcart (i.e. I still only have that ridiculous m218 one).

I guess it's not really any worse than having to reboot your Tandy CoCo until the artifact colors are the right ones.

Page 1 of 1 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/