sprites and $2004, $2007 stuff

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

sprites and $2004, $2007 stuff

Post by Zepper »

Quote from the wiki page:
Writes to OAMDATA during rendering (on the pre-render line and the visible lines 0-239, provided either sprite or background rendering is enabled) do not modify values in OAM, but do perform a glitchy increment of OAMADDR, bumping only the high 6 bits (i.e., it bumps the [n] value in PPU sprite evaluation - it's plausible that it could bump the low bits instead depending on the current status of sprite evaluation). This extends to DMA transfers via OAMDMA, since that uses writes to $2004. For emulation purposes, it is probably best to completely ignore writes during rendering.
Nintendulator (and probably a few others) do extra stuff.
1. If the PPU is not rendering, the value written becomes $FF.
2. If $2003 (OAM_ADDR) ANDed with 3 results 2, then the value written is ANDed with $E3.
Why? (edited & fixed)

Next question is about the PPU register $2007. From the same source, it seems that any write outside the palette range does not take immediate effect, but "delayed" until the next PPU clock/operation. No, it's not about the 1st read buffer "problem", but a "phase state". There's nothing on the wiki about it.

Does writting to $2007 take immediate effect... or not?
Last edited by Zepper on Mon Jul 16, 2018 9:50 am, edited 1 time in total.
NewRisingSun
Posts: 1510
Joined: Thu May 19, 2005 11:30 am

Re: sprites and $2004, $2007 stuff

Post by NewRisingSun »

If the PPU is not rendering, the value written becomes $FF.
No, if the PPU is rendering, Nintendulator changes the written value to $FF. This is actually incorrect behavior and causes flickering sprites on Famicom Mukashibanashi: Yuu Yuu Ki's title screen. Correct is to ignore OAM writes while the PPU is rendering.
If $2003 ANDed with 3 results 2, then the value written is ORed with $E3.
No, it is ANDed with $E3, so that the unused bits 2-4 in each sprite's byte 2 read back as zero even if they had been previously set in the written value.

As for the delayed effect of PPU register writes, that is a territory that indeed needs further study. Mesen, for example, assumes that disabling/enabling rendering via $2001 bits 3 and 4 is delayed by 1 PPU cycle, but only for some actions during rendering, while writing an address via $2006 is delayed by 2-3 PPU Cycles. Trying to implement both in Nintendulator slightly improves Micro Machines while messing up the MMC3 scanline counter and test ROM performance. Don't know about $2007.

I also believe that some of these delays by emulators are only necessary because at least in Mesen and Nintendulator, PPU writes are handled asynchronously, basically between calls to the PPU emulation's RunCycle function. A more precise emulation would put the write data and address on the emulated PPU's address and data bus and have RunCycle interpret them and propagate them throughout the device.
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: sprites and $2004, $2007 stuff

Post by Zepper »

Thanks. 8-)
I fixed my 1st post, sorry for my confusion. :oops:
Sour
Posts: 891
Joined: Sun Feb 07, 2016 6:16 pm

Re: sprites and $2004, $2007 stuff

Post by Sour »

NewRisingSun wrote:Mesen, for example, assumes that disabling/enabling rendering via $2001 bits 3 and 4 is delayed by 1 PPU cycle, but only for some actions during rendering
IIRC, that was originally required to fix battletoads (unsure if it is still needed - it was done over 2 years ago), but it is completely unvalidated as far as hardware goes. The fact it's only applied to "some" portions was just me trying to limit the scope of the fix (I wouldn't really recommend applying this particular delay unless it fixes something)
NewRisingSun wrote:while writing an address via $2006 is delayed by 2-3 PPU Cycles. Trying to implement both in Nintendulator slightly improves Micro Machines while messing up the MMC3 scanline counter and test ROM performance.
This was to fix shaking in a couple of games, but I forgot which. There is a test rom for this (which was based on the Visual 2C02, iirc), but it looks like nobody ever actually tried running it on a NES to check the results: https://forums.nesdev.com/viewtopic.php ... 19#p189519

Mesen's current PPU implementation does have a couple of things that I'm not quite convinced are 100% correct (mostly stuff that's off by 1 PPU cycle vs what I would have expected it to be), but the current setup is the only way I have found that works in all games (at least, to my knowledge, I obviously haven't tested all of them) and passes all the tests (which by no means implies that they are correct - I'm pretty certain some of it is not)
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: sprites and $2004, $2007 stuff

Post by Zepper »

Sour wrote:This was to fix shaking in a couple of games, but I forgot which. There is a test rom for this (which was based on the Visual 2C02, iirc), but it looks like nobody ever actually tried running it on a NES to check the results: https://forums.nesdev.com/viewtopic.php ... 19#p189519
One game is KickMaster.
fred
Posts: 67
Joined: Fri Dec 30, 2011 7:15 am
Location: Sweden

Re: sprites and $2004, $2007 stuff

Post by fred »

Yes, I definitely still want to test this on real HW, and all the other PPU delays. I still don't own an NES though. I also really want to test some NMI stuff, since visual 2C02 and blargg disagrees there.
Post Reply