PPU wait for ready in Donkey Kong

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

johnmph
Posts: 13
Joined: Fri Feb 28, 2020 8:17 am

PPU wait for ready in Donkey Kong

Post by johnmph » Fri Feb 28, 2020 9:23 am

Hello all, I started to programming a NES emulator and I have a little problem with Donkey Kong on the title screen.

Here is a screenshot :

Capture d’écran 2020-02-28 à 16.31.06.png

After debugging, it seems that the problem is caused by the way I initialize the PPU VBlank status at power up.

Conforming to this doc, I implemented the PPU warm up by having a reset flag which is set on reset and reset at scanline 261 pixel 1, as long as the reset flag is set, I call the reset method on each clock so even if the registers changes they are reset to their initial state.

Also I set the VBlank status flag to true (often set in the doc) at the powerUp method and I leave it unchanged on the reset method.

But in Donkey Kong, it seems that the game wait only for 1 VBlank (Debugged with Nintaco, this code is called only once) :

Code: Select all

C7A8 : LDA $2002
C7AB : AND #$80
C7AD : BEQ $C7A8
So if the VBlank status flag is set on the power up, this loop will quit immediately and the game will start to fill up VRAM (nametable starting at $2000) with $24 (the empty tile) but the problem is that when it set the VRAM address by writing to $2006, the write toggle will be reset because PPU is still in the warm up and so the VRAM address will be $0000 instead $2000 (upper byte overwritten by lower byte because of write toggle not set).

So the nametable will not be filled with $24 but stays filled with $00 (default value) and this is why I have this wrong title screen.

If I reset the VBlank status flag on the power up, Donkey Kong will wait correctly the warm up and everything is fine :

Capture d’écran 2020-02-28 à 16.30.37.png

But in real NES or other emulators, donkey kong works fine, and the doc says that this VBlank status flag is often set at the power up, so there is a big chance there is a problem elsewhere with my emulator.

But to be sure, can somebody tell me if donkey kong wait correctly the warm up ? or is it waiting incorrectly like mentioned above ? and if yes why the game works properly on real hardware ?

Thanks

User avatar
Dwedit
Posts: 4306
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: PPU wait for ready in Donkey Kong

Post by Dwedit » Fri Feb 28, 2020 3:15 pm

In FCEUX, you can make Donkey Kong boot on a VBL Set condition. Then you can run through FCEUX's debugger, you can watch what it does.

Example, FCEUX boots at vblank time, and Vblank flag is set.

Waits for Vblank flag to be set (no wait)

Code: Select all

 00:C7A8: AD 02 20  LDA PPU_STATUS = #$10
 00:C7AB: 29 80     AND #$80
 00:C7AD: F0 F9     BEQ $C7A8
Clears RAM

Code: Select all

 00:C7B7: A9 00     LDA #$00
>00:C7B9: 91 00     STA ($00),Y @ $07FF = #$FF
 00:C7BB: 88        DEY
 00:C7BC: D0 FB     BNE $C7B9
 00:C7BE: C6 01     DEC $01 = #$07
 00:C7C0: 10 F7     BPL $C7B9
Memory clear loop is pretty slow, and ends up finishing at CPU cycle 22624.

Then it reaches this code before Warmup has completed. FCEUX says that 27727 CPU cycles have passed at this time, smaller than the required 29658 cycles.

Code: Select all

 00:F1BE: A9 20     LDA #$20
>00:F1C0: 8D 06 20  STA PPU_ADDRESS = #$00
 00:F1C3: A9 00     LDA #$00
 00:F1C5: 8D 06 20  STA PPU_ADDRESS = #$00
If you sabotage the code here to simulate the PPU ignoring the first screen clear, you will get the title screen with zeroes everywhere.

It also says that powering off the NES and powering it on again will frequently cause the VBL flag to start out set, so maybe see if anyone has ever seen the glitched title screen with zeroes on it on a real NES?
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!

johnmph
Posts: 13
Joined: Fri Feb 28, 2020 8:17 am

Re: PPU wait for ready in Donkey Kong

Post by johnmph » Fri Feb 28, 2020 4:52 pm

Thanks for the test, this is what I got also with my emulator (CPU cycle 27731 at the start of STA PPU_ADDRESS instead 27727, I don't know why there is 4 cycles difference, I need to investigate on that but I don't think it is relevant here).
Dwedit wrote:
Fri Feb 28, 2020 3:15 pm
If you sabotage the code here to simulate the PPU ignoring the first screen clear, you will get the title screen with zeroes everywhere.
By saying "sabotage the code to simulate the PPU ignoring the first screen clear", do you mean that forcing the VBlank loop to pass directly ?

I tried that with the Nintaco emulator but the title screen stay correct, maybe because Nintaco doesn't emulate the PPU warm up??
I will try with FCEUX later because I have only OSX here.

Thanks

User avatar
Dwedit
Posts: 4306
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: PPU wait for ready in Donkey Kong

Post by Dwedit » Fri Feb 28, 2020 5:58 pm

By "sabotage" I meant nopping out a write to 2006, or changing which value is written there. You get the screen with 0s everywhere if you NOP out either 2006 writes, or the 2007 write.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!

johnmph
Posts: 13
Joined: Fri Feb 28, 2020 8:17 am

Re: PPU wait for ready in Donkey Kong

Post by johnmph » Fri Feb 28, 2020 6:21 pm

Ok, this is expected since it can't write correctly to the VRAM.

I tried on FCEUX, Nintaco and Mesen to pass directly the VBlank wait loop (By changing Accumulator to 80 just before the AND #$80).
On each emulator, the title screen stay correct.

Maybe because these emulators doesn't implement the PPU warm up ? But that doesn't explain why real hardware doesn't have this bug. Unless Vblank status flag is always false on power up / reset ? Or write toggle is not reset in warm up ?

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

Re: PPU wait for ready in Donkey Kong

Post by tepples » Fri Feb 28, 2020 7:01 pm

As I understand it, the "unacknowledged vblank NMI" bit of $2002 is false on powerup and unchanged on reset. But on 12 out of 13 resets it'll be false anyway because NMI to end of vblank is only 20 lines tall on a Famicom, NTSC NES, Vs. System, PlayChoice, or Dendy. And if the in-game NMI handler acknowledges NMI fairly early by reading $2002, it'll be even more rare. (I don't own a copy of Donkey Kong with which to test whether or not it acks NMI.)

PAL NES has a longer period from NMI to end of vblank: 70 out of 312 lines. So maybe 2 out of 9 resets might cause a problem, again provided that the game doesn't ack the NMI.

Sour
Posts: 807
Joined: Sun Feb 07, 2016 6:16 pm

Re: PPU wait for ready in Donkey Kong

Post by Sour » Fri Feb 28, 2020 7:22 pm

johnmph wrote:
Fri Feb 28, 2020 6:21 pm
Maybe because these emulators doesn't implement the PPU warm up ?
I don't recall seeing any emulator that implemented this (one might very well exist, though.) As far as Mesen goes it's mostly because I keep forgetting about it (and there is no proper test rom for the behavior, so I'd have to guess the values and hope it doesn't break some random game :p)

johnmph
Posts: 13
Joined: Fri Feb 28, 2020 8:17 am

Re: PPU wait for ready in Donkey Kong

Post by johnmph » Fri Feb 28, 2020 7:31 pm

Thanks, if it is false on power up and almost on almost every reset, that explains why there is no problem on real hardware.

And since the reset doesn't clear VRAM, if the reset happen on the title screen, even if the VBlank wait loop passed directly the title screen will be correct.

johnmph
Posts: 13
Joined: Fri Feb 28, 2020 8:17 am

Re: PPU wait for ready in Donkey Kong

Post by johnmph » Fri Feb 28, 2020 7:38 pm

Sour wrote:
Fri Feb 28, 2020 7:22 pm
I don't recall seeing any emulator that implemented this (one might very well exist, though.) As far as Mesen goes it's mostly because I keep forgetting about it (and there is no proper test rom for the behavior, so I'd have to guess the values and hope it doesn't break some random game :p)
Yes and anyway that doesn't matter if it is not implemented since the emulation stay correct.

I am very far to have the accuracy of Mesen or the other emulators :)

lidnariq
Posts: 9379
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: PPU wait for ready in Donkey Kong

Post by lidnariq » Fri Feb 28, 2020 7:41 pm

The relevant reason for the bit on [nesdevwiki:PPU power up state] is from this post from Blargg from forever ago: viewtopic.php?p=31514#p31514

Unfortunately, I'm not really clear on what his methodology was that led a "usually set" result on cold boot; as far as I can tell it should more often be clear. None-the-less, even with the 1/9th chance, it should be still seen to happen in hardware.

Sour wrote:
Fri Feb 28, 2020 7:22 pm
(and there is no proper test rom for the behavior, so I'd have to guess the values and hope it doesn't break some random game :p)
What would a test ROM even do? As far as I can tell, this is just "is VBL set when the VM is turned on"... right?

Looking at the relevant section in Visual2C02 ("vbl_flag"), the two halves of the storage element are fairly comparable in area and pull-up cross-section, so I'd expect cold boot behavior to depend on a huge pile of analog effects.

Sour
Posts: 807
Joined: Sun Feb 07, 2016 6:16 pm

Re: PPU wait for ready in Donkey Kong

Post by Sour » Fri Feb 28, 2020 9:25 pm

lidnariq wrote:
Fri Feb 28, 2020 7:41 pm
What would a test ROM even do? As far as I can tell, this is just "is VBL set when the VM is turned on"... right?
I wasn't referring to the VBL flag bit, sorry. I meant the part where half of the registers are supposed to be ignored for "~29658 CPU cycles" after power on/reset, which seems kind of arbitrary, but the post you linked by blargg sounds like he was pretty confident on the cycle count, rather than it being some approximate value?

lidnariq
Posts: 9379
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: PPU wait for ready in Donkey Kong

Post by lidnariq » Fri Feb 28, 2020 9:33 pm

Oh, yes, that. Yes, the PPU comes out of reset exactly at the top of the active frame (after vblanking), and several registers are explicitly ignored (or more accurately, continuously reset) from then until the start of the next active frame. Same timing as the bits in $2002 are cleared.

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

Re: PPU wait for ready in Donkey Kong

Post by tepples » Sat Feb 29, 2020 8:03 am

And the timing isn't arbitrary. On NTSC, 261 lines is the time from the top of one picture to the start of the next pre-render scanline. At 341/3 = 113.667 cycles per scanline, this is 29667 cycles. The missing 9 are about how long it takes for the CPU to complete its own reset.

Sour
Posts: 807
Joined: Sun Feb 07, 2016 6:16 pm

Re: PPU wait for ready in Donkey Kong

Post by Sour » Sat Feb 29, 2020 6:23 pm

Ah, that makes a lot more sense, thanks!
So the logic is that the registers stay "locked" until pre-scanline (-1) on dot 0? That's easy to implement then (and a lot easier to understand than some number of CPU cycles)
Do we know if the PAL PPU works the same way (or have any reason to think it would behave differently?)

lidnariq
Posts: 9379
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: PPU wait for ready in Donkey Kong

Post by lidnariq » Sat Feb 29, 2020 6:29 pm

PAL PPU does appear to behave identically:
nesdevwiki:PPU power up state wrote:Preliminary testing on a PAL NES shows that writes are ignored until ~33132 CPU clocks after power and reset, 9 clocks less than 311 scanlines.
(edit) The specific behavior divides things into what Visual2C02 calls node _res (things that are reset while the external /RESET pin is pulled low) and _res2 (things that are reset for the entire first N-1 scanlines). The nodes reset by _res2 include what we call T, W, and X, all bits in PPUMASK, the upper 6 bits in PPUCTRL, and the storage element that holds values values read by the PPU for the CPU. _res is what resets the H/V counters, the even/odd frame, the twisted-ring counter for chroma generation, the clock divider for the pixel clock, and what serves as the S/R latch to generate _res2.

Post Reply