Dr Jefyll wrote:
ulfalizer wrote:
I'm trying to figure out what's going on with a particular behavior in the NES at the hardware level (related to VBlank flag reading for those in the know
)
Hi, ulfalizer. Sometimes it's useful to pursue more than one line of thought. The Visual6502 simulator is an amazing tool, of course. Taking a broader approach, I wonder if it'd be helpful to share with us something about the "behavior" you mention.
Are you trying to determine
whether this VBlank flag gets read before or after the NMI from the graphics chip gets recognized, or is the question more complex than that? Dunno how many of us here are in the know about NES, but maybe we can ask a dumb question that'll spark something in your own mind!
-- Jeff
P.S.- As you may know, an interrupt can cause an opcode -- such as one that'll read VBlank ! -- to get fetched and then discarded. Following completion of the ISR, the exact same opcode will be fetched again. Can this possibly be pertinent?
Details here.
Unfortunately it's a bit tricky to explain, but I'll do my best for a basic overview. I'm currently working together with blargg, who has scope readings from an actual NES, which lets me match up my findings from the simulators with the messiness of the real world.
Basically, there's a flag (it happens to be related to VBlank in this case), which is tied to NMI generation and has special behavior when reading it. The flag is set automatically at a particular point in the frame (to indicate that VBlank has started), and reading the register (
$2002) that holds the flag does two things:
- Holds the value of the flag in a separate read buffer so it can be read (this is mentioned in the tutorial).
- Clears the flag. The purpose of the read buffer is to allow it to still be read.
The read behavior above happens during φ2 of the read cycle, but just to make things more complicated the duty cycle of the φ2 that comes out of the chip (called M2) has been modified in the NES; see
http://wiki.nesdev.com/w/index.php/CPU_ ... escription.
The flag is tied to the NMI line such that NMI will be asserted while the flag is set (if enabled).
The messy part comes with reading the register right around the point where the flag is set. Since the read will pull it to zero, you sometimes get cases where the NMI is missed, because it isn't asserted for long enough to be seen. You also get cases where the value is missed, because the read buffer is initialized before the value is set, but the overlapping of the read with the setting still causes the flag itself to be cleared. In addition, you want to know the earliest point where the flag will read as set for timing purposes (this isn't purely academic - some games require pretty strict timing).
The above isn't really enough information to be able to draw conclusions, but it should give a flavor at least. Basically, it's messy.