OAMADDR ($2003) at end of frame

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
OAMADDR ($2003) at end of frame
by on (#95693)
Hey all.

Looking at the OAM outline here:
http://wiki.nesdev.com/w/index.php/PPU_ ... evaluation

I don't see anything that would suggest the OAM addr is explicitly reset to 0 at the end of the frame (although this has been observed in some games -- notably Akira, which does not reset $2003 before doing a DMA).

What I do see is the OAM addr being reset to zero if all 64 sprites have been evaluated, because then it falls through to step 4:

Quote:
4. Attempt (and fail) to copy OAM[n][0] into the next free slot in secondary OAM, and increment n (repeat until HBLANK is reached)


(note: here, n=0 always, which effectively means $2003=0)

However, if not all 64 sprites have been evaluated... the OAM address seems to be left garbled at the end of the frame. This might happen if there are 8+ sprites found on scanline 239. Although this seems very unlikely that a game would put lots of sprites on that line.

Does anyone know if this behavior has been tested?

by on (#95697)
The worst case I can see is if sprites 56-63 lie on line 239.
  • Dots 0-63: Clear secondary OAM.
  • Dots 64-175 (112 dots for 56 sprites at 2 cycles each): Reject sprites 0-55 as out of range.
  • Dots 176-239 (64 dots for 8 sprites at 8 cycles each): Accept Sprites 56-63.
  • Dots 240-255: Rest.

Can you think of a scenario that wouldn't come to rest on or before 240?

by on (#95710)
mmm... now i see why battletoads hangs and keep waiting for a sprite hit.
Anyway all SpriteHit "timming" blargg's test fail in my emu.

The things i never understood that doc Disch, i will read it again, and again and again, but im stucked with "2A03 reference" for sprite evaluation. A bad thing i think.

by on (#95711)
Yes:

Dots 0-63: Clear secondary OAM
Dots 64-127: Accept sprites 0-7
Dots 128-255: keep accepting thrash data as in range sprites


Again, very unlikely. I'm just wondering.

by on (#95716)
Disch wrote:
Dots 128-255: keep accepting thrash data as in range sprites

Accepting trash data stops after the trash data from sprite 63 is read.
  • Dots 128-239 (112 dots for 56 sprites at 2 cycles each): Reject sprites 8-63 as over limit, after which point "n overflows to 0".
  • Dots 240-255: Rest.

In each case, the sprite unit reaches "4. Attempt (and fail) to copy OAM[n][0] into the next free slot" by 240.

by on (#95718)
Quote:
3a. If the value is in range, set the sprite overflow flag in $2002 and read the next 3 entries of OAM (incrementing 'm' after each byte and incrementing 'n' when 'm' overflows); if m = 3, increment n


If thrash data is in range, it reads the full 4 bytes (8 dots). If it's doing that for every sprite, it won't even get to sprite 63.

by on (#95721)
Oh wait, you're right: If 11 sprites on line 239 are considered in range, it won't get to the end of OAM. This is likely to happen under old guidance to use $EF as the offscreen value. That's why I use $FF now.