Test: ppu_read_buffer [VERIFICATION PENDING]

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Bisqwit
Posts: 248
Joined: Fri Oct 14, 2011 1:09 am

Test: ppu_read_buffer [VERIFICATION PENDING]

Post by Bisqwit » Fri Apr 27, 2012 2:15 pm

Here's another test I created. As usual, the ROM file, the readme, and the full source code are included.

http://bisqwit.iki.fi/src/nes_tests/ppu_read_buffer.zip

It is really a mammoth test suite, containing a whopping 78 tests in one.
The test topics mostly revolve around the PPU's $2007 read buffer, but a few ancillary topics are also tested, such as CHR-ROM write protection, PPU reading with the "ADC" instruction, $4014 DMA combined with RAM mirroring, and sprite-0 hit flag, with varying degree of intensity.
The test takes about 20 seconds, and either displays some graphics or plays a few audible tones during those sections where the user must just wait.

I would appreciate test results on the actual console before anyone cheers saying their emulator passes all tests. It is really hard to come up with tests that are failed by the best emulators, today, especially if you can only test on those very emulators.
From the set of Nintendulator, Nestopia, Rocknes and puNES, I only found that Nintendulator consistently fails when you pause / turbo during the DMA tests, but otherwise all four pass all tests.

The focus of this test suite is to catch a large set of typical beginner's mistakes in NES emulation coding. Because of this, the program actually executes as many tests as possible before reporting the results. Tests which depend on passing of an earlier test are not executed. Some tests contain a special workaround for a previously failed test, so that the actual topic can still be tested even if the PPU is broken in a predictable manner. The ROM also tries hard to catch and graciously handle any spuriously triggered BRKs and IRQs.

When the results are reported, the numeric list of all failed tests is shown, followed by the explanation of the first failed test. Tests are not always executed in numeric order. For example (FCEU):
Image

The ROM is a CNROM (iNES mapper 3) with 1 × 16 kB of PRG-ROM, 3 × 8 kB of CHR-ROM and horizontal mirroring. I had to actually implement some compression schemes to fit everything in the ROM that I wanted to fit.

tepples
Posts: 21979
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Fri Apr 27, 2012 2:30 pm

The result on my PowerPak changed on resets:

Failed #67
Failed #63
Failed #7

Bisqwit
Posts: 248
Joined: Fri Oct 14, 2011 1:09 am

Post by Bisqwit » Fri Apr 27, 2012 2:31 pm

Can you please include the list of failed tests, not just the last line?

The tests I would expect to have a chance of failing on the actual console are #67, and anything from #73 to #79.

#7 is: Sequential PALETTE reading with 1-byte increment does not work.
#63 is sprite-0 hit by poking data directly into $2003/$2004.
I'm rather surprised to hear fails at those two... Neither should also be sensitive to reset state. Sprite-0 hits may go wrong if CHR-ROM/mirroring does not work properly, or if a previously failed test changed nametable contents, but I cannot think of any explanation for #7. In #7, 32 bytes are written into the palette RAM (reprogramming PPUADDR before each byte), and then three bytes are read in sequence from a location that is not affected by mirroring in a conforming implementation. The read bytes are compared to the table data that was written earlier. But did it pass or fail #47 or #48 (TEST_PALETTE_READS and TEST_PALETTE_READS_UNRELIABLE respectively) when it failed #7?

Heh. Reversal of pass/fail status again, I guess :-) When emulators pass tests but the console fails them, it's really the emulators which fail the tests. But I would still appreciate understanding of why that happens.

tepples
Posts: 21979
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Fri Apr 27, 2012 2:59 pm

Failed tests: 67
Untested: 73 through 78

Failed tests: 67 63
Untested: 73 through 78

Failed tests: 53 52 51 50 7
Untested: 62 through 69 73 through 78

Feature request: When more than three sequential tests are untested (e.g. 73 74 75 76 77 78), display them with a dash between them (e.g. 73-78).

Bisqwit
Posts: 248
Joined: Fri Oct 14, 2011 1:09 am

Post by Bisqwit » Fri Apr 27, 2012 3:27 pm

tepples wrote:Feature request: When more than three sequential tests are untested (e.g. 73 74 75 76 77 78), display them with a dash between them (e.g. 73-78).
Implemented as requested.

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

Post by Zepper » Fri Apr 27, 2012 5:17 pm

It should give errors on RockNES 5.07x, since there's a sprite #0/overflow timing bug. Both flags are cleared one scanline later than expected. Version 5.08 (unreleased) fixes such problem though. I detected it with blargg's sprite timing tests.

Bisqwit
Posts: 248
Joined: Fri Oct 14, 2011 1:09 am

Post by Bisqwit » Sat Apr 28, 2012 1:46 am

Regarding the sprite-0 hits, this test only expects shed-size accuracy on the timings (about 60 scanlines). Timings are not the issue, it's whether the DMA uploaded correct data or not.

EDIT: I updated the test, removing the fail-barrier before test 73. So now it should be possible to get results for 73-79 on the actual console, even if previous tests failed.

tepples
Posts: 21979
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sat Apr 28, 2012 5:01 am

Results from new version, again depending on reset:

BRK?
BRK executed where should not!
01010100ar01011D7800000100

Failed tests: 67 62
Untested: 73-79

Failed tests: 67 63 62
Untested: 73-79

Failed tests: 67 62 52 51 50 7
Untested: 73-79

Are you making sure to wait for $2002 bit 7 to be set a couple times? If you don't, reset might cause the PPU to ignore writes for a frame.


EDIT: I got a new one

Failed tests: 67 62 52 51 50 49
Untested: 8 73-79

Bisqwit
Posts: 248
Joined: Fri Oct 14, 2011 1:09 am

Post by Bisqwit » Sat Apr 28, 2012 5:14 am

tepples wrote:Results from new version, again depending on reset:

BRK?
BRK executed where should not!
01010100ar01011D7800000100
[...]
Are you making sure to wait for $2002 bit 7 to be set a couple times? If you don't, reset might cause the PPU to ignore writes for a frame.
I'm using Blargg's framework, which indeed does wait for two frames in the beginning.

Code: Select all

        jsr init_wait_vbl     ; waits for VBL once here,
        jsr wait_vbl_optional ; so only need to wait once more
And I print text on the screen before running any PPU related tests. Each text line waits for a new vblank (and it wouldn't even be shown if this was the issue.)

Is there something I should know about $2007 and delays? Is it possible that under some situations $2007 might not respond as quickly as it should and might skip a read? When rendering is disabled, that is.

I can only predict three possible reasons for getting a BRK.
- Code that is copied from VROM into RAM and then executed was not perfectly copied.
- Code that is copied from ROM into RAM and then executed was not perfectly copied.
- Stack overflow (portions of the RAM-copied code are executed from memory page $100). But this should not happen either. S is set to $FF at reset, and the program's recursion stack is rather shallow. There should be overflow only if natural use of the stack consumes 0xA0 bytes or more.
Well, four:
- CPU does not honor RAM mirroring when fetching opcodes.
But I don't think that's a likely problem on the real CPU.

Hmm, after the "BRK executed where should not", shoud come a listing of CPU registers, but it should be in plain text, not some gibberish code. Turns out that was my mistake, a wrong polarity in a branch instruction. Can you please try it again, so I can at least get useful debugging information?

tepples
Posts: 21979
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sat Apr 28, 2012 6:20 am

Still the same gibberish:

BRK executed where should not!
01010100ar01011D7800000100

Bisqwit
Posts: 248
Joined: Fri Oct 14, 2011 1:09 am

Post by Bisqwit » Sat Apr 28, 2012 6:44 am

What.

Code: Select all

  534  cd source/
  535  git commit . -m 'Fix BRK debugging'
  536  cd ..
  537  cd ..
  538  git archive HEAD ppu_read_buffer > test.tar
  539  cd t
  540  tar xvf ../test.tar
  541  kzip -r /WWW/src/nes_tests/ppu_read_buffer.zip `find -type f|sed 's/^..//'`
  542  zip -9 /WWW/src/nes_tests/ppu_read_buffer.zip `find -type d`
What did I do wrong...?

Ah, I see. Commit in wrong directory. Did not include updated ROM.
Updated now. Sorry about that.

tepples
Posts: 21979
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sat Apr 28, 2012 10:42 am

BRK executed where should not!
PC=1B00, AXYSP=00/00/05/FB/37

Failed tests: 67 63 62
Untested: 73-79

Failed tests: 67 62
Untested: 73-79

Failed tests: 67 62 52 51 50 49
Untested: 8 73-79

You mentioned VROM. Three CHR banks are not a power of two; might that have something to do with it?

Bisqwit
Posts: 248
Joined: Fri Oct 14, 2011 1:09 am

Post by Bisqwit » Sat Apr 28, 2012 12:13 pm

tepples wrote:BRK executed where should not!
PC=1B00, AXYSP=00/00/05/FB/37
So it failed immediately upon landing in the supposedly VROM-loaded code.
tepples wrote:You mentioned VROM. Three CHR banks are not a power of two; might that have something to do with it?
I know it's not a power of two. Does PowerPak have a problem coping with that fact?

However, before loading and executing any code from the ROM, the ROM executes test 70 (TEST_CHRROM_READ_BANKED), which verifies that each of the three VROM banks can be read pr...
Oh, I see. There is a possibility for a false positive. Bank 0 contains the same material in the same position that is tested from bank 2. Oops. It wasn't that way in a prior phase of the development, but became so later.
So, PowerPak cannot cope with CNROM, or it cannot cope with three CHR-ROM banks in particular? Should I make this four-banked just to make PowerPak happy?

User avatar
thefox
Posts: 3141
Joined: Mon Jan 03, 2005 10:36 am
Location: Tampere, Finland
Contact:

Post by thefox » Sat Apr 28, 2012 12:24 pm

Bisqwit wrote:Should I make this four-banked just to make PowerPak happy?
Yes, it doesn't like non power of two bank sizes. It calculates the CHR size mask by taking the bank size and subtracting 1, that'll produce some funky results with non power of twos.

tepples
Posts: 21979
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sat Apr 28, 2012 12:41 pm

Bisqwit wrote:So, PowerPak cannot cope with CNROM
PowerPak plays every regular CNROM game I've thrown at it, and recent mapper sets even support oversize CNROM workalikes such as the board used in Bubble Bath Babes.
or it cannot cope with three CHR-ROM banks in particular? Should I make this four-banked just to make PowerPak happy?
That and make it four-banked just to make burning-it-onto-an-EPROM happy.

Post Reply