Help with even/odd frames PPU test

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Help with even/odd frames PPU test
by on (#8772)
- I cannot get this test ok. It fails at 3. Here's my logic:

Code:
int ppuCB = 341;

if(20 == scanline)
{
   int ppuXX = ppu_bg_on ? ppuCB: 341;
   ppuCB ^= 1; //toggles at every frame (340 or 341).
   ppucycle += numcycles;
   if(ppucycle >= ppuXX)
   {
       ppucycle -= ppuXX;
   }
}


Could someone give me a hand? ^_^;;

by on (#8782)
First, don't post cryptic code with useless variable names (ppuCB? ppucycle? numcycles? ppuXX?). What is your understanding of PPU frame length and when a frame is shorter? That might be in error. Did you verify that the two test ROMs before that passed? Which test of "3.even_odd_frames.nes" failed?

A good guide for improving general question-asking skill is covered in
How To Ask Questions The Smart Way
.

by on (#8786)
I'm sorry. Let me clear out...

- First, ppuCB stands for PPU color burst, mentioned somewhere in a Brad's doc. It holds 341 cycles (normal) or 340 (shorter, on odd frames).

- ppu_bg_on stands for ppu background on. Quite obvious the 2001h setting.

- ppucycle goes from 0 up to 340. It counts the amount of PPU cycles per scanline. When it reaches 341, it's reset and scanline increases.

- So, using words: if we're on scanline 20, the amount of cycles is selected (340 or 341), but only if background is enabled; else, always 341. I increase the PPU cycle counter with the respective amount of cycles (usually, CPU_cycles * 3). If the PPU cycles is greater than 341 (or 340), I reset it and do stuff. My emu uses precise cycle emulation.

- "3.even_odd_frames.nes" fails at 3.

by on (#8788)
The scanline 20 is 341 PPU cycles long on even frames, and 340 cycles long on odd frames *if* background is enabled, correct? I use a variable called ppuCB to hold this setting (341 or 340) as the maximum cycles for that scanline. I toggle it at every frame (ppuCB ^ 1) , but it gives error #3 on even_odd_frames.nes test ROM. For my best, a PPU frame has 341*262 cycles less 1 if on odd frames with BG enabled.

by on (#8796)
The scanline 20 handling looks correct. There must be some hidden behavior that test ROMs 1.frame_basics.nes and 2.vbl_timing.nes aren't finding when you run them and they pass on your emulator. How are you handling reads of $2002 around the time that the VBL occurs?

by on (#8821)
2.vbl_timing fails at test 8- Reading 1 PPU clock before VBL should suppress setting.

I have no clue yet how to fix this problem... -_-;;
EDIT- it seems only Nestopia pass OK all tests.

by on (#8827)
It this fucking rocket science? From the second paragraph of the readme that comes with the test ROMs: "It's best to run the tests in order, because later ROMs depend on things tested by earlier ROMs and will give erroneous results if any earlier ones failed."

Translation: the result of test ROM 3 is meaningless since test ROM 2 failed.

by on (#8828)
I see.
By the way, calm down, please. ^_^;;

by on (#8831)
Well, that's why he's called blargg; quietly sitting in the lava until Mario or someone else gets a bit too much on his nerves, and he'll try to take a bite. :wink:

by on (#8836)
These test ROMs are great stuff, something very neat. Since accuracy is target, I couldn't bypass them. Sometimes I misunderstand the things... and to make a bit difficult, english isn't my motherlanguage (portuguese). Thanks for tweaking me. :)

by on (#8840)
I hate it when I waste time solving a non-problem due to lack of effort on another person's part. For example, recently I wrote a game music plugin for a media player and had the team claiming that my plugin had a bug that cut some music tracks off a few seconds early. Fine, I don't mind fixing bugs in my code. I asked whether it also cuts off when recording to disk ("diskwriter"), which would help rule out the possibility of it being a bug in their player. After being fingered as the reason a new release was delayed (which even days after a fix has still not appeared), I find out that it does not cut off when using the diskwriter, that it's likely a bug in the player, and that my simple test would have saved a lot of time. Even worse, I brought up the possibility of the problem days before.

Ultimately the error can be put in my hands, for misjudging the seriousness of the other party I'm dealing with; if I could see that they were just doing it half-assed, I'd not waste my time with the matter at all. In other words, I form unrealistic expectations.

Regarding the test ROMs, they have to address the odd situation of depending on proper operation of some aspects of that very thing being tested. This is solved using a "bootstrap" approach where the first tests rely only on fundamentals in order to prove that some other features work; later tests then build on this to prove even more features work. There are so many ways an emulator can get things wrong that it's essential to reduce the possible causes as much as possible. The bootstrap approach helps, but it means that skipping a failed ROM will cause further tests to fail not because the particular feature being tested is erroneous, but because the prerequisite features don't work.

by on (#8841)
Useless to extend this but... Let's say it was my "fatal error" to have ignored the previous ROM test, I admit... but never "lack of effort", I'm tracing PPU like crazy, I wasted a lot of time studying the APU logs (previous APU tests) to finally get all tests OK. That's what I'm doing... tracing and studying the logs. I'm sorry for the inconvenience.

Let's rock'n roll for now. ^_^;;

by on (#8864)
Quote:
2.vbl_timing fails at test 8- Reading 1 PPU clock before VBL should suppress setting.


Here's the NesDevWiki page with the PPU details you'll need to know (it'd be a bit hard to get the tests passing without knowing this, and it's not documented anywhere else):

New PPU VBL/NMI Timing Information

by on (#8885)
blargg wrote:
Regarding the test ROMs, they have to address the odd situation of depending on proper operation of some aspects of that very thing being tested. This is solved using a "bootstrap" approach where the first tests rely only on fundamentals in order to prove that some other features work

Then could you put a test and its prereqs into one ROM? What blocks this?

by on (#8886)
The costs don't seem to outweigh the benefit from the user not having to remember to run them in order:

- Some ROMs use custom NMI and IRQ handlers
- Long asm source files are much more difficult to deal with
- Tests would take several seconds, making people think it's not working
- Total code size might exceed the 8K in my devcart

Overall you're still going to have multiple test ROMs, where some depend on others passing (for example, the CPU must pass basic tests before any of my ROMs will give meaningful results). It would be neat to have a comprehensive set of NES test ROM that tested everything, but the benefit over several sets would only be slight and the cost great.

by on (#8889)
blargg wrote:
The costs don't seem to outweigh the benefit from the user not having to remember to run them in order:

A growing number of developers have begun to recognize the benefits of automated regression testing.

Quote:
- Some ROMs use custom NMI and IRQ handlers

A 32 KB switching mapper such as Color Dreams, AOROM, GNROM, S*ROM, or BNROM might help with this.

Quote:
- Long asm source files are much more difficult to deal with

Then break it into smaller asm files and join them up at the linker. In fact, with a multipl

Quote:
- Tests would take several seconds, making people think it's not working

Unless you're testing audio, you could have it play music while it's testing.

Quote:
- Total code size might exceed the 8K in my devcart

I'll grant you that one.

Quote:
Overall you're still going to have multiple test ROMs, where some depend on others passing (for example, the CPU must pass basic tests before any of my ROMs will give meaningful results).

Could there be a way to have at least some of the test ROMs programmatically raise a Pass or Fail signal in such a way that the emulator could know to unload the ROM and load the next one?

by on (#8890)
still working on getting my ppu to work. at the moment i think it displays most games with out a mapper. blargg your test only shows a black screen. i was looking at the source and not sure where to start looking in my ppu for the problem.

my ppu is working but needs work still. any suggestions of why i dont get anything displayed ?

just looking for some clues to what is wrong with my ppu...

thanks

matt

by on (#8891)
I bet your VBlank flag has incorrect timing. Check it out.
I had a similar problem. Once I double-checked the PPU timing, it fixed the problem.

Plus, gathering all ROMs in a single might cause timing to break out.

by on (#8892)
also forgot to add that i dont have sprites coded yet.....

blargg... do your test depend on sprites ?

matt

by on (#8899)
tepples wrote:
Could there be a way to have at least some of the test ROMs programmatically raise a Pass or Fail signal in such a way that the emulator could know to unload the ROM and load the next one?


Automated testing would need to deal with multiple test ROMs, so the number doesn't matter much. The simplest way to detect the result of a test would be to monitor the nametable for the text printed on screen when a test completes. It'd be quite simple to write a scripting system that had primitives for checking for text on screen and sending joypad commands or loading new ROMs in response. This would accommodate all current test ROMs that print a result on screen. I might even whip this up and post it, if any actual interest is shown in automated testing.

I'll keep 32K mappers in mind (the non-switchability of the last bank for more complex mappers had been stuck in my mind). That would be fairly easy to use with very minimal changes to my current code; it'd just involve replacing the "forever: jmp forever" that all of them jump to with code to switch to the next bank. It would also solve the limited devcart space issue: just test each bank separately. Heck, I could even have it automatically receive the next bank over the serial link from the host PC. :)

Quote:
Unless you're testing audio, you could have it play music while it's testing.


Heh. But not really, because it would affect timing. No way I'd make them any more complex.

mattmatteh wrote:
blargg your test only shows a black screen.

Fx3 wrote:
I bet your VBlank flag has incorrect timing. Check it out. I had a similar problem. Once I double-checked the PPU timing, it fixed the problem.


I checked and Fx3's problem was with the Sprite 0 Hit test ROMs. I didn't see any code in the PPU VBL/NMI timing test ROMs that would cause a blank screen if the VBL timing was off (and it doesn't make any use of sprites). mattmatteh, reply with a precise description of what you did and what the result is, since it's unclear what you mean by "my test". I don't know if you mean "When 1.frame_basics.nes is run in your emulator, you get a black screen for a minute" or something else. This goes for everyone: post precise descriptions of the context of your problems so that others can avoid having to assume things to fill in the missing details. Did you let "1.frame_basics.nes" run for at least half a minute to be sure it never showed anything? It takes a while before the result is displayed.

by on (#8906)
blargg wrote:
Quote:
Unless you're testing audio, you could have it play music while it's testing.


Heh. But not really, because it would affect timing. No way I'd make them any more complex.

By "music" I just meant one note per test if the tests don't take more than about 3 seconds each. That's just 5 writes to registers in $4000 space.

Quote:
Did you let "1.frame_basics.nes" run for at least half a minute to be sure it never showed anything? It takes a while before the result is displayed.

For tests that are that long, you could at least give some sort of indication that something is going on. Would cycling color 0 work?

by on (#8907)
I really don't like adding anything extra to the test code that can be handled just as well in a readme (if someone can't be bothered to read it, then the level of accuracy my test ROMs verify is probably not their aim anyway). I'm sure the tests could be made really nice, but the effort and bugs due to unexpected effects make it not worth it in my opinion. I have improved the final reporting, but that runs after the test so there's no danger of it affecting things. Everything else is geared for making the tests as error-free and easy to write as possible. It's already a very time-consuming process.

Rather than put all the responsibility on the test ROM, why not develop some guidelines and frontend designs for emulators so that it's easy to add automated testing to one's emulator? When running tests, it wouldn't even show any PPU video on screen, just a console with the results of each test. The emulator could run at maximum speed, making the tests quite fast.

by on (#8920)
Ok, here's the entire thing... (2.vbl_timing.nes, test #8)

1. Yes, 2002h is read exactly 1 PPU cycle before VBlank.
2. There's a second 2002h read that occurs 56 PPU cycles after VBlank (1).

- That's what I traced carefully. Both reads should return 00. Mine was returning 80h on second one. I'd like an opinion about this "fix"...

a) On VBlank rising, if 1 PPU cycle has elapsed since the last 2002h read, a flag (M) is signed.

b) On second 2002h read, if (M) is set and 56 cycles have elapsed since VBlank, so 2002h returns bit #7 clear.

- It's clear to me about a)... but b) looks like an hack.

by on (#8926)
Fx3 wrote:
a) On VBlank rising, if 1 PPU cycle has elapsed since the last 2002h read, a flag (M) is signed.


I'm not sure what you mean "a flag (M) is signed". If you replace that with "bit 7 of $2002 is not set for that frame" then that is the correct handling. A simpler way to state this is: "On VBlank rising, bit 7 of $2002 is set unless $2002 was read 1 PPU clock earlier."

by on (#9012)
i started 1.frame_basics.nes and let it run for over a minute and all i get is a black screen. then i tested it with tuxnes and that starts grey and goes to black background with failed #4 after about a second. then i tried fceu and that was about the same but failed #6.

mine always starts grey and goes black soon as i start the game.

thanks

matt

by on (#9023)
Have you verified your CPU's operation thoroughly? Try making a log of the program counter before each instruction. It's probably getting hung in a loop, whose address you can post for me to find in my asm source.

by on (#9042)
blargg wrote:
Fx3 wrote:
a) On VBlank rising, if 1 PPU cycle has elapsed since the last 2002h read, a flag (M) is signed.


I'm not sure what you mean "a flag (M) is signed". If you replace that with "bit 7 of $2002 is not set for that frame" then that is the correct handling. A simpler way to state this is: "On VBlank rising, bit 7 of $2002 is set unless $2002 was read 1 PPU clock earlier."


During test 2, I logged 2 times a 2002h read 1 PPU cycle before VBlank, making the test to fail. PC at E0DF. It occurs at line 261, cycle 339 (0-340).

by on (#9045)
my emulator passes nestest. i was guessing its something in the ppu as that is still in the works.

here is a full ccpu dump of frame_basics.nes
compressed is 1.3 MB, uncompressed is 33 MB

http://icarus.cc.uic.edu/~mhull1/dump.c ... _basics.gz

here are the first few lines...

a:00 x:00 y:00 p:24 sp:fd
e15a 20 b8 e0 jsr $e0b8
a:00 x:00 y:00 p:24 sp:fb
e0b8 a9 00 lda#$00
a:00 x:00 y:00 p:26 sp:fb
e0ba 85 f8 sta $f8 = 00
a:00 x:00 y:00 p:26 sp:fb
e0bc a9 28 lda#$28
a:28 x:00 y:00 p:24 sp:fb
e0be 20 d7 e1 jsr $e1d7


here are the last few lines.....

a:00 x:e0 y:09 p:27 sp:fb
e580 8d 00 20 sta $2000 = 20
a:00 x:e0 y:09 p:27 sp:fb
e583 20 77 e5 jsr $e577
a:00 x:e0 y:09 p:27 sp:f9
e577 a9 00 lda#$00
a:00 x:e0 y:09 p:27 sp:f9
e579 8d f1 07 sta $07f1 = a5
a:00 x:e0 y:09 p:27 sp:f9
e57c 60 rts
a:00 x:e0 y:09 p:27 sp:fb
e586 4c 89 e5 jmp $e589
a:00 x:e0 y:09 p:27 sp:fb
e589 4c 89 e5 jmp $e589
a:00 x:e0 y:09 p:27 sp:fb



thanks

matt

by on (#9047)
I read the topic regarding 2002h thing... of making the read on 4th clock. Well, it might help but... Nintendulator still fails, so it's not an issue after all.

by on (#9048)
Fx3 wrote:
I read the topic regarding 2002h thing... of making the read on 4th clock. Well, it might help but... Nintendulator still fails, so it's not an issue after all.


Nintendulator isn't GOD or anything. Just because something fails on it doesn't make it wrong. If you read up on Nintendulators CPU timing you would see that it does nothing of the sort that WedNESday's does. Question for blargg, would WedNESday's perfect timing fix this issue? I assume that it would.

by on (#9059)
The only question is whether the code does the same thing on an emulator as it does on a NES. This is a question that can be answered in specific cases by running code on the NES and emulator and comparing results, and in general by examining the emulator's source code. Everything else is just hand-waving around the issue (cycle-accurate, bla bla).

by on (#9061)
Oh yes, no doubt. Plus, I've found a problem with my PPU core... :)

EDIT- Yes, I fixed. All tests are OK.