It is currently Mon Dec 11, 2017 11:33 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: PPU warmup is real
PostPosted: Fri Mar 07, 2008 11:06 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
I've been doing some power/reset research and have found justification for the "PPU warmup" code. I tested the following after power and reset to see if the PPU address was set to $1111. After power, it failed 50% of the time (10 trials). After reset, it failed 11% of the time (50 trials).
Code:
reset:  sei             ; Standard init
        cld
        ldx #$FF
        txs
        inx
        stx $2000
        stx $2001
:       bit $2002       ; wait for VBL flag
        bpl :-
:       bit $2002       ; wait for VBL flag again
        bpl :-
        lda #$11        ; VADDR=$1111
        sta $2006
        sta $2006

The VBL flag is set about half the time at power, and 11% of the time at reset (when reset is pressed while the flag is set, most likely). The VBL flag is next set at reset+27383 CPU clocks. Writes to $2006 are ignored until reset+29658 CPU clocks. So merely waiting until two $2002 reads have the high bit set isn't enough if you plan on writing to $2006 immediately after. Adding one more $2002 read makes it work every time after power and reset:
Code:
reset:  ...
        bit $2002       ; clear VBL flag (ADDED)
       
:       bit $2002       ; wait for VBL flag
        bpl :-
:       bit $2002       ; wait for VBL flag again
        bpl :-
        ...

$2006 isn't the only register I've found to be ignored like this, just one example that justifies this warmup wait.


Top
 Profile  
 
 Post subject: Re: PPU warmup is real
PostPosted: Fri Mar 07, 2008 12:34 pm 
Offline

Joined: Wed Mar 22, 2006 8:00 am
Posts: 354
blargg wrote:
The VBL flag is set about half the time at power, and 11% of the time at reset (when reset is pressed while the flag is set, most likely).

I thought there was a commercial game that required VBL to be set at power-up to boot, because it wrote $80 to $4017 to prevent frame IRQ's (which won't work if an IRQ is pending). Are you saying this game will fail to boot 50% of the time at power-up?

_________________
"Last version was better," says Floyd. "More bugs. Bugs make game fun."


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 07, 2008 12:59 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
$4017 controls the APU IRQ. That's unrelated to the PPU and the VBL flag.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 07, 2008 1:42 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
The game in question is either Ironsword, Time Lord, or something like that. The reason VBL status at powerup matters in that case is because the game does a warm up loop where it waits for it to be set twice before writing to $4017. Also it doesn't disable IRQs when it writes to $4017, it simply switches to the 5-step mode -- but since it doesn't disable or acknowledge them, if an IRQ tripped before it switched modes, that IRQ will be pending for the whole game which causes it to muck up.

If VBL is clear at powerup, then the game effectively waits two full frames at startup (or at least more than one full frame) which ensures a frame IRQ will trip. But if VBL is set, then it will only wait for one full frame (or less) making it still possible to slip the mode change in before the IRQ happens.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 07, 2008 1:42 pm 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2142
Location: Minneapolis, Minnesota, United States
Funny you should mention this, because when I started to really understand most things about NESdev, I decided to wait 3 Vblanks instead of 2 to be safe. So ever since then, I've waited 3 Vblanks, and now I know I should :) .


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 07, 2008 7:55 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19334
Location: NE Indiana, USA (NTSC)
Very interesting. I decided to convert those timings from CPU cycles to NTSC scanlines, and I saw some interesting correlations:
  • If power-on to first true vblank is 27383 cycles, that's close to 241 lines. This would be expected if the PPU starts at the top left pixel, going through all 240 active lines and the post-render line.
  • If power-on to first successful VRAM transaction is 29658 cycles, that's close to 261 lines, ending at the pre-render line.

Another thing you might want to check out: Spinning on $2002 might miss a vblank if the start of vblank and the $2002 read happen on exactly the same CPU cycle. Does NMI (lda #$80 sta $2000) work predictably before 30,000 CPU cycles? Or must programs spin on $2002 and potentially miss several vblanks in a row?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 08, 2008 7:29 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
This code sometimes allowed an IRQ through at power. It didn't at reset if the APU mode was $80 before reset, so a game with this sort of code at reset that used mode $80 exclusively would reset reliably, even if it failed at power. I used an APU-based timer to find out how long the two VBL loops waited total and it was usually ~27331 clocks, only occasionally ~57113.
Code:
reset:
:   bit $2002   ; wait for VBL flag
    bpl :-
:   bit $2002   ; wait for VBL flag again
    bpl :-
    lda #$80
    sta $4017
    cli
    sei

For whatever reason, the VBL flag was set most of the time at power today. Does the game in question sometimes fail to work on a NES until reset is pressed?

Quote:
Does NMI (lda #$80 sta $2000) work predictably before 30,000 CPU cycles? Or must programs spin on $2002 and potentially miss several vblanks in a row?

A $2002 spin loop will never wait more than VBL period*2, since it can never suppress two VBL flag settings in a row. Writes to $2000 before +29658 are also ignored, so NMI can't be used immediately either. $2007 works immediately, just $2006 doesn't. So you can begin accessing VRAM $0001 upwards immediately (what PPUADDR powers up with).


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 08, 2008 8:15 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7312
Location: Chexbres, VD, Switzerland
Quote:
For whatever reason, the VBL flag was set most of the time at power today. Does the game in question sometimes fail to work on a NES until reset is pressed?

Anyway, if you have ever played real games with a real nes and an unmodified cartridge connector, you have to reset the system and re-inster the cartridge so many times before getting the game to work that it would be impossible to tell if this is due to hardware or software fault.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 08, 2008 8:52 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3076
Location: Brazil
...or even if you need to (re)blow it. :)

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 08, 2008 9:11 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19334
Location: NE Indiana, USA (NTSC)
blargg wrote:
Writes to $2000 before +29658 are also ignored, so NMI can't be used immediately either.

So much for commercial games that write 0 to $2000 in their init code. It's a good thing you're discovering this now before I start propagating half-truths in the tutorial that I've been working on. Thanks again for this research.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 08, 2008 9:31 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Quote:
So much for commercial games that write 0 to $2000 in their init code.

Initializing these things is a good idea if one wants the code to be more compatible with NES clones (including inaccurate NES emulators). SEI, CLD, writing $00 to $2000, $2001, $4010, and $4015, $40 to $4017, and reading $4015 afterwards are all good ideas along these lines.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 08, 2008 10:32 am 
Offline

Joined: Wed Mar 22, 2006 8:00 am
Posts: 354
Does the VRAM address start out at $0001 after reset, or just after power?

Are any registers besides $2002 and $2007 usable before the end of the first VBlank period?

What is the initial state of the other $2002 bits (sprite hit and overflow)?

In short, how are all of the PPU registers set at power and/or reset?

Incidentally, some commercial games I looked at write zero to $2000 and $2001 repeatedly within the $2002 warmup loop(s). Also, one of the MMC5 games I examined watied much longer at this time (around 16 VBlanks IIRC). Writing to $2000 and $2001 is probably more important with the Famicom than with the NES, since its state after reset is more volatile (I'm not sure if the Famicom PPU gets reset at all).

_________________
"Last version was better," says Floyd. "More bugs. Bugs make game fun."


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 10, 2008 12:39 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7312
Location: Chexbres, VD, Switzerland
At least Dragon Warrior tries to write to $2006 possibly only one frame after powerup (however, I don't know big the issue is if the write fail). The game seems to write to pattern tables, even tough the game uses CHRROM, which has no effect, since /WR isn't even connected to cartridges with CHRROM. Weird.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 10, 2008 2:55 pm 
Offline

Joined: Wed Mar 09, 2005 9:08 am
Posts: 348
Hmm... I wonder if the PowerPak suffers from this as well, since it will often fail at power-up, just showing a single-colored screen.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 11, 2008 11:57 am 
Offline

Joined: Wed Mar 22, 2006 8:00 am
Posts: 354
Bananmos wrote:
Hmm... I wonder if the PowerPak suffers from this as well, since it will often fail at power-up, just showing a single-colored screen.

No, the PowerPak waits three VBlanks in the reset code. It also initializes the FPGA before doing anything with the PPU, which adds further delay.

_________________
"Last version was better," says Floyd. "More bugs. Bugs make game fun."


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: Revenant, Yahoo [Bot] and 10 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group