Thanks @lidnariq and @koitsu for the replies.
lidnariq wrote:On what pixel does your emulator actually read the value from the register?
I am sorry but I am a bit confused on this question. The pixel? The rom that I am testing with is the "branch timing tests" (http://www.slack.net/~ant/nes-tests/bra ... _tests.zip
). This issue though happens with other test roms. It seems what the rom does is that it constantly polling the vblank flag (via BIT and BPL instructions). When I run the test rom against my emulator, it seems that the branch (via BPL) is occurring two instructions later than when it happens on Mesen.
koitsu wrote:No mention of what ROM you're testing (filename + MD5 checksum needed), can't go look at what's happening timing-wise without that.
I am testing with the "branch timing tests" ((http://www.slack.net/~ant/nes-tests/bra ... _tests.zip
), but this seems to also happen with other roms as well
Otherwise all I can ask is are you sure you have BIT implemented correctly (pretty easy opcode)? Are you sure you implemented reading from $2002 correctly? This might be what you're missing:
I am pretty sure my BIT is implemented correctly (or at least I think so). I was able to verify the correctness of this implementation using the "nes test" rom. My emulator passes all of "nes test" (http://nickmass.com/images/nestest.nes
It does not "magically" get updated. The value shown at the effective address part of BIT $2002 = $00 (i.e. the = $00 part) is not reliable/accurate for MMIO registers. In other words, the trace logger/debugger makes you think the read returns $00 because of what's shown, but internally to the PPU that is not the value that's actively returned -- what gets returned is $86. A lot of emulators are this way -- I think you're just learning it now. For PPU internal status, the emulator must accurately depict it somewhere. In Mesen, it's in the PPU Status section of the debugger.
Very interesting. Hmmm. So then it is returning $86 but I just can't see it
If this is the case, then my issue can just be the synchronization of my PPU and CPU. I wonder if maybe my emulator is doing this.
1) CPU executes BIT $2002 which reads $00 since vblank is not set yet.
2) PPU hits scanline = 241 and cycle = 1 to set vblank flag.
whereas it should go the other way around.
1) PPU hits scanline = 241 and cycle = 1 to set vblank flag.
2) CPU executes BIT $2002 which will show it read $00 but will have actually read $86.
Since in the Mesen trace, it was returning $00, this was throwing me off.
Don't believe me? Try this: load up Super Mario Bros. (W) [!].nes / 811B027EAF99C2DEF7B933C5208636DE in Mesen, open Debugger, then add this as a breakpoint: Address: Any, Condition: VerticalBlank (type the word in, no spaces). Now reload/reset the ROM with Ctrl-T and hit F5 to run it. It will break on lda $2002 at $800A, very close to the RESET vector. Now stop and look closely at the PPU Status section of the debugger: Vertical Blank is checked, which means bit 7 will technically be set in what's read from $2002 (but remember that upon read, the bit gets reset internal to the PPU). Now hit F11 ONCE to execute/step through the lda to the next instruction (bpl $800A/$AD). Note that the instruction clearly reads lda $2002 = $10, when in fact it returned $90 (see accumulator). The reason it reads $90 instead of $80 is explained on the wiki -- it has to do with the $10 that was written to $2000 prior.
Thanks for the explanation. I'll re-read the wiki again and see if I can understand this behavior better.