vbl_nmi_timing / frame basics test

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
vbl_nmi_timing / frame basics test
by on (#19754)
I've started to add better timings in my emulator and I've tried blaargs ROMs (great work by the way). However I get error #2 when trying the ROM mentioned in the topic. So it means that vblank flag isn't set.
I set this at scanline 240, is it wrong?

by on (#19770)
If you could visible scanlines as 0-239, then the VBLANK bit gets set at scanline 241.

by on (#19772)
Doesn't seem to help, obviously I'm doing something else wrong. I'm not emulating additional clockcycles for page-crossing if that could cause trouble...
The sourcecode for the test isn't helping me much. I'm a guy, I need diagrams and drawings to understand this kind of stuff. :)

by on (#19775)
oRBIT2002 wrote:
Doesn't seem to help, obviously I'm doing something else wrong.


Well that error is indicating that the VBlank flag is not being set at all. Double check to make sure you're actually setting it and that it's being returned in bit 7 of $2002 reads.

In times like this, it really helps to have a 6502 tracer built into your emu so that you can make a big log of what the ROM is doing to find out where your emu is going wrong.

Quote:
I'm not emulating additional clockcycles for page-crossing if that could cause trouble...


For this paticular test I doubt it matters, but it might for later tests when it gets into timing.

I would not trust ANY PPU/APU/mapper timing test ROM until you have your CPU timed right (I believe blargg made CPU timing test ROMs you can use -- make sure you pass all of those first before fine-tuning your timing in other areas)

Quote:
I'm a guy, I need diagrams and drawings to understand this kind of stuff. :)



The NTSC frame:
Code:

-------------------------------------
1 "idle" scanline
-------------------------------------   <--- VBl flag set here

20 scanlines of VBlank

-------------------------------------   <--- VBl flag (and all $2002 flags) cleared here
1 "pre-render" scanline
-------------------------------------


240 rendered scanlines


-------------------------------------


Of course the frame is circular -- so you can start it anywhere (if you start with VBlank, it will end with the idle scanline -- if you start with rendering, it'll end with the pre-render, etc)

by on (#19776)
Many many ROMs actually run fine and I'm sure I'm setting this bit, perhaps at the wrong time then.

I can't run any of his tests almost cause I get something like "basic frame timing wrong" or similar and I bet it's because of the problem mentioned.

When does the test expects this bit? I mean, on which scanline does it run the test (if everything should work properly of course)? Scanline 241 when the vblank occurs?

by on (#19805)
oRBIT2002 wrote:
I can't run any of his tests almost cause I get something like "basic frame timing wrong" or similar and I bet it's because of the problem mentioned.


Yeah that's a problem. Have you tried nestest.nes? Perhaps there's a weird CPU bug in your emu causing this to happen in these test ROMs.

Maybe it's not that you're not setting the flag, but rather you're clearing it too soon. From a quick glance at the source, this test ROM seems to just wait a moderately long time for the flag to set, then checks it once (as opposed to most commercial games which poll it constantly). Perhaps your emu is setting it and clearing it before the ROM checks it? If you're automatically clearing the flag at any time other than a $2002 read, try removing that and see if you get past that error -- that'll give you a better idea of what might be causing the problem (note: this is not a solution! You are supposed to automatically clear the flag at a certain time -- I'm only recommending this for diagnostic purposes)

But it's really hard for me to speculate what the problem could be. The best way to go about solving this problem would be to dump a trace log of your emu running this log and have it display information relevant to the problem (timestamps, $2002 status, etc). This will help you see where the ROM is going wrong, and will give you a better idea of what it's expecting (so you can know what needs to be done to fix the problem).

Believe me, if you put a tracer in your emu, it's an unbelievably valuable debugging tool. This won't be the last time you'll have a use for it.


Quote:
When does the test expects this bit? I mean, on which scanline does it run the test (if everything should work properly of course)? Scanline 241 when the vblank occurs?


EDIT -- oh whoops, I totally misunderstood what you were asking before

*checks*

edit again:

from the source:

Code:
      jsr   wait_vbl
      ldy   #25         ; 29800 delay
      lda   #237       
      jsr   delay_ya8
      lda   #2;) VBL flag isn't being set
      lda   $2002
      and   #$80
      jsr   error_if_eq


So the test is:

- waiting for VBlank (probably by polling $2002? oddly I couldn't find a 'wait_vbl' label in the source anywhere)
- doing nothing for about 29800 CPU cycles (roughly 1 frame)
- checking VBlank flag once and erroring if it's not set


A full NTSC frame is roughly 29780.667 CPU cycles:

341 PPU cycles per scanline
* 262 scanlines per frame
= 89342 PPU cycles per frame
/ 3 PPU cycles per CPU cycle
= 29780.667

so if the ROM is waiting 29800 cycles, it is checking the flag roughly 20 cycles into VBlank (so almost a fourth of the way through the very first scanline of VBlank)

by on (#19808)
Disch wrote:
* 262 scanlines per frame

In what country?

oRBIT2002 wrote:
Location: Gothenburg/Sweden


Countries and territories that use PAL B, G, D or K [include] Sweden


So for PAL NES, the cycle stoichiometry becomes the following:

341 PPU cycles per scanline
* 312 scanlines per frame
= 106392 PPU cycles per frame
/ 3.2 PPU cycles per CPU cycle
= 33247.5 CPU cycles per frame

EDIT: Corrected for the record. Thanks Quietust.

by on (#19810)
tepples wrote:
341 PPU cycles per scanline
* 322 scanlines per frame
= 109802 PPU cycles per frame
/ 3.2 PPU cycles per CPU cycle
= 34313.125 CPU cycles per frame


Minor correction - PAL is 312 scanlines per frame, not 322. This works out to 33247.5 CPU cycles per frame.

by on (#19814)
I'm doing NES NTSC emulation so...
My CPU core passes the nestest.nes actually so that's not the problem.
If I am not mistaken, isn't bit 7 of $2002 cleared when read? Wonder if this might cause the problem.. Have to do further investigation obviously...

I have myself to blame but I don't have any kind of tracer in my emulator. The emulator is overriding the OS (more or less) for better performance (Remember I code this thing on a 50Mhz Amiga :)) and implementing tracers/Debuggers in 68000 assembler wasnt to tempting back then when I started it. But it would have been a good idea. :)

by on (#19820)
tepples wrote:
In what country?


Ahem:

Disch wrote:
A full NTSC frame is roughly 29780.667 CPU cycles:

341 PPU cycles per scanline
* 262 scanlines per frame


I assume NTSC because the test ROMs in question would be virtually worthless in PAL emulation mode.

Quote:
If I am not mistaken, isn't bit 7 of $2002 cleared when read?


yes -- although I don't think that omission that would cause this paticular test to fail.

I would wager your frame is too long and the test ROM is checking the VBlank flag before your emu has set it. Either that or a few of your instructions are too short (don't take enough CPU cycles) and so blargg's timed code isn't waiting as long as it thinks it is.

Or -- your frame could be way too short and the vblank flag is being cleared before the test ROM reads it -- although since the test ROM checks it near the start of VBlank, your emu would have to have the frame 19 scanlines too short for it to fail -- whereas it would only need it to be 1 scanline too long for it to fail.


If you don't feel like (or can't) code a full tracer -- at least try and make it so you can dump quick information to a .txt file at key times (like say, at $2002 reads). This will let you know when the ROM is reading $2002, when in the frame it's reading it, and what value it's getting when it reads it.

by on (#19821)
Yes, you need to trace the emulated code from the PC address where the test effectively begins. Quite easy to do if your emu has a disassembler (viewer), plus the test ROM source. If you don't trace it, nobody will guess your problem.

In fact, I HAD this exact problem too... I don't remember what was causing it, have to dig my files here... -_-;;;

by on (#19831)
I think I've located the problem.. When the testprogram does the "critical" LDA $2002, it's only on row 189 in my emulator, so obviously the cpu-timing is somewhat off.
As I mentioned before I'm not emulating additional cycles with page-crossing but it shouldn't differ this much I think(?)

EDIT: My bne/beq's etc was only coded for 2 clockcycles when it should be 3 as a minimum. Now the test pass! Well I get a error #5 anyway :)

EDIT #2: Blargg I love your testROMs, but I sure miss some more information about the errorcodes and what they actually mean. A more detailed information about each test in the ROM would be great. Thanks!

by on (#19836)
oRBIT2002 wrote:
EDIT: My bne/beq's etc was only coded for 2 clockcycles when it should be 3 as a minimum. Now the test pass! Well I get a error #5 anyway :)


2 cycles if the branch is not taken
3 cycles if the branch is taken
4 cycles if the branch is taken and it crosses a page boundary

of course for timed loops -- most of the time the branch will be taken, so I suppose defaulting to 3 cycles would be better than defaulting to 2.


Glad to hear you got that solved!

by on (#19844)
Anyone knows exactly what error #5 means? :)
"PPU frame with BG enabled is too long"

by on (#19845)
It means what it says, frames last too long in your emulator. 1 NTSC frame lasts 89342 PPU cycles (29780 2/3 CPU cycles, don't round that number), or 89341 PPU cycles on odd frames with PPU rendering enabled.

*edit* woops, corrected, thanks blargg

by on (#19847)
Man, you should build a tracer (logger) that shows the amount of emulated cycles per frame and the main events (VBlank flag rising, 2002 clearing, frame start etc). This way, you will see where your emu is failing, or else, it's hard.

by on (#19854)
When rendering is disabled, every frame is 341*262 PPU clocks long. Read the Nesdev wiki page I had written about frame timing a while back: http://nesdevwiki.ath.cx/index.php/PPU_Frame_Timing