OAM and sprites (wiki related)

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
OAM and sprites (wiki related)
by on (#232690)
Quick recap. In my emulator, the game RC Pro AM II hangs on race start (black screen). Ages later, I've found the problem relying on copying and replacing the first 8 bytes of sprites before rendering starts. Well, for this game, if I push such copy to be triggered around PPU cycle 108, it works.

Conditions: cycle 0 of the pre-rendered scanline (-1), and OAMADDR is greater than 8, or simply (0 != (OAMADDR & $F8)).

After an easy look at Mesen PPU source code, I've found a nugget - must occur only if rendering is enabled (subject to make oam_stress test to fail), so I added such info to the wiki. A few moments later, lidnariq did a rollback & rewrote the text to something... unclear?

1. "The process of starting sprite evaluation triggers the copy". Well, sprite evaluation starts at cycle 0 of the pre-rendered scanline (-1) if rendering is enabled, correct? A direct "translation".

2. It says "if the sprite address is not zero", but it conflicts with the info OAMADDR & $F8 (greater than 8). What's the correct after all?

3. What happens to the OAMADDR? Is it "manually" cleared? Under which conditions? Should I set OAMADDR to zero if the copy of 8 bytes of OAM is triggered?
Re: OAM and sprites (wiki related)
by on (#232702)
I thought that adding additional conditions after the rest had already been stated was less clear.

I combined
"at the beginning of the pre-render scanline, [results]"
and
"This should only be done if rendering is enabled (otherwise oam_stress test fails immediately)."

and rewrote it as
"process of starting sprite evaluation"


re: 3- It is the act of the hardware setting OAMADDR to 0 that causes the copy. This is a DRAM controller bug.
Re: OAM and sprites (wiki related)
by on (#232708)
lidnariq wrote:
re: 3- It is the act of the hardware setting OAMADDR to 0 that causes the copy. This is a DRAM controller bug.

Not clear yet. "The act of the hardware" how? If OAMADDR is non-zero (even less than 8?) and rendering is enabled ($2001), the copy of 8 bytes from OAM is triggered, then OAMADDR=0. Well, if OAMADDR is already zero, the copy does not happen.
Is this correct?

What happens if rendering is disabled at that time? Is OAMADDR set to zero or leave it untouched?
Re: OAM and sprites (wiki related)
by on (#232711)
Zepper wrote:
the copy of 8 bytes from OAM is triggered, then OAMADDR=0. Well, if OAMADDR is already zero, the copy does not happen.
What's the difference between copying the eight bytes starting at 0 to 0 ... and not doing the copy?

Quote:
What happens if rendering is disabled at that time? Is OAMADDR set to zero or leave it untouched?
None of my edit was stating that you were wrong. Just that your phrasing was unclear and could be made better.
Re: OAM and sprites (wiki related)
by on (#232716)
lidnariq wrote:
Zepper wrote:
the copy of 8 bytes from OAM is triggered, then OAMADDR=0. Well, if OAMADDR is already zero, the copy does not happen.
What's the difference between copying the eight bytes starting at 0 to 0 ... and not doing the copy?

From a software point of view?
Code:
if(0 != OAMADDR) memcpy(OAM,&OAM[OAMADDR&0xF8],8);

I don't know how memcpy() would act / be compiled if OAMADDR == 0.

Quote:
Quote:
What happens if rendering is disabled at that time? Is OAMADDR set to zero or leave it untouched?
None of my edit was stating that you were wrong. Just that your phrasing was unclear and could be made better.

Credit to Mesen guy, not me. ^_^;;
My question is still open.
Re: OAM and sprites (wiki related)
by on (#232718)
Zepper wrote:
From a software point of view?
I mean, pedantiically, this very concept is a software problem not a hardware problem.
Quote:
I don't know how memcpy() would act / be compiled if OAMADDR == 0.
Well, that's a part of what C defines. Officially, memcpy can fail if source and destination overlap, but memmove can't.

Quote:
What happens if rendering is disabled at that time? Is OAMADDR set to zero or leave it untouched?
OAMADDR is set to zero by sprite evaluation starting.
On the 2C02, Sprite evaluation can only start when rendering is enabled.
On the 2C02G and 2C02H there's a bug when OAMADDR is set to zero that smears/copies the data from one row of DRAM over another.