It is currently Sun Aug 20, 2017 2:07 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: How reliable is $2003?
PostPosted: Sun Jun 18, 2017 3:57 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 9900
Location: Rio de Janeiro - Brazil
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.


Top
 Profile  
 
PostPosted: Sun Jun 18, 2017 6:22 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1385
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).

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.


Top
 Profile  
 
PostPosted: Sun Jun 18, 2017 12:01 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6040
Location: Seattle
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.


Top
 Profile  
 
PostPosted: Sun Jun 18, 2017 12:19 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 9900
Location: Rio de Janeiro - Brazil
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.


Top
 Profile  
 
PostPosted: Sun Jun 18, 2017 12:23 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6040
Location: Seattle
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.


Top
 Profile  
 
PostPosted: Sun Jun 18, 2017 1:31 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1385
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.

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.


Top
 Profile  
 
PostPosted: Sun Jun 18, 2017 7:14 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 9900
Location: Rio de Janeiro - Brazil
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.


Top
 Profile  
 
PostPosted: Sun Jun 18, 2017 7:22 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6040
Location: Seattle
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.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: Bing [Bot], Yahoo [Bot] 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