It is currently Mon Oct 23, 2017 4:48 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: Thu Apr 23, 2015 12:55 am 
Offline
User avatar

Joined: Wed Apr 07, 2010 1:14 am
Posts: 484
Location: Iran
Someone on the Nesdev IRC Channel said : "Don't spin around $2002, because it is unrealabe and there is a chance to miss a frame"
Someone else said : "My code is very fishy!" :

****************************************************

Here is my warm up routine :

Code:
   LDX #$04            ; 4 Times vblank period will come and go

warmup_loop:           ; Do loop until vblank starts
   BIT $2002           ; It is not vblank period / 7th bit of $2002 is 0 / BIT, Clear the negative sign
   BPL warmup_loop     ; The result is Plus / BPL, Continue the loop!

; Vblank period has just started / 7th bit of $2002 is 1 / BIT, Set the negative sign / The result is Negative / BPL, Don't continue the loop!

vbend_loop:            ; Do loop until current vblank ends
   BIT $2002           ; It is vblank period / 7th bit of $2002 is 1 / BIT, Set the negative sign
   BMI vbend_loop      ; The result is Negative / BMI, Continue the loop!

; Vblank period has just ended / 7th bit of $2002 is 0 / BIT, Clear the negative sign / The result is Plus / BMI, Don't continue the loop!

   DEX
   BNE warmup_loop


****************************************************

Here is my vblank wait routine :

Code:
vblank_wait:           ; Do loop until current vblank ends
   BIT $2002           ; It is vblank period by sheer chance! / 7th bit of $2002 is 1 / BIT, Set the negative sign
   BMI vblank_wait     ; The result is Negative / BMI, Continue the loop!

; Vblank period has just ended / 7th bit of $2002 is 0 / BIT, Clear the negative sign / The result is Plus / BMI, Don't continue the loop!

vbstart_loop:          ; Do loop until a new vblank starts
   BIT $2002           ; It is not vblank period / 7th bit of $2002 is 0 / BIT, Clear the negative sign
   BPL vbstart_loop    ; The result is Plus / BPL, Continue the loop!      

; Vblank period has just started / 7th bit of $2002 is 1 / BIT, Set the negative sign / The result is Negative / BPL, Don't continue the loop!

   RTS                  ; Now the screen can be updated!


****************************************************

So, is it really fishy?! Or will I miss any frame?! :?


Top
 Profile  
 
PostPosted: Thu Apr 23, 2015 1:15 am 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3471
Location: Indianapolis
A BIT $2002 / BMI loop is never useful. Use BPL only. It's fine to use it during warm-up. But using it for timing will always result in some frames being missed. Reading the flag resets it, and the NES also resets it at a certain time every frame. If the register is read at the same time the NES resets it, then you'll miss that frame. Whenever correct timing is needed, you must enable NMI and set a flag there, then check that flag in your wait loop.

Read this:
http://wiki.nesdev.com/w/index.php/NMI


Top
 Profile  
 
PostPosted: Thu Apr 23, 2015 3:48 am 
Offline
User avatar

Joined: Wed Apr 07, 2010 1:14 am
Posts: 484
Location: Iran
I put that BIT $2002 / BMI in the vblank wait routine to skip any vblanks which is on its halfway and then wait for a new vblank to get a full vblank period.
Is it useless for that purpose?
Also NMI is disabled all the time.


Top
 Profile  
 
PostPosted: Thu Apr 23, 2015 4:56 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7235
Location: Chexbres, VD, Switzerland
Quote:
Is it useless for that purpose?

Yes. Just a bit $2002 with no BMI will have the same purpose.


Top
 Profile  
 
PostPosted: Thu Apr 23, 2015 5:47 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2963
Location: Tampere, Finland
FARID wrote:
I put that BIT $2002 / BMI in the vblank wait routine to skip any vblanks which is on its halfway and then wait for a new vblank to get a full vblank period.
Is it useless for that purpose?
Also NMI is disabled all the time.

To rephrase what was said already: BIT $2002 / BMI is useless because reading $2002 has the side-effect of clearing the vblank flag. So, if the BIT $2002 happened to return the vblank flag as set, it would also clear it at the same time, and the next iteration of loop would return it as unset, exiting the loop. And if BIT $2002 returned the vblank flag as already being cleared, then of course the BMI branch would never be taken. In any case, the end result is the same, the vblank flag is cleared.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Thu Apr 23, 2015 6:15 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19116
Location: NE Indiana, USA (NTSC)
Memblers wrote:

I was the one reviewing Farid's code. He's using it for a multicart, and the NMI handler is that of one of the games. In order to use NMI, he'd have to understand what variables the NMI handler uses and how to disable their game-related function so that it doesn't interfere.


Top
 Profile  
 
PostPosted: Thu Apr 23, 2015 7:10 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3944
Trying to avoid NMI for a menu? Try putting sprite 0 at the bottom of the screen, then you can wait for a sprite 0 hit, then delay some cycles after that so you know you're in vblank time.

Before you display your first frame though, you'll probably need to do repeated 2002 polling for vblank, which can miss frames. Then you can display a frame with the correct scroll values and sprite contents, then sprite 0 hit will work after that.

But if the intent isn't true 60FPS, and is just to wait for vblank to update a menu or something, then does it really matter if you miss frames?

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Thu Apr 23, 2015 7:48 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7235
Location: Chexbres, VD, Switzerland
For a menu I wouldn't bother to miss frames. The game Portopia, which is entirely menu based, relies on $2002 polling only and doesn't use interrupts ever.


Top
 Profile  
 
PostPosted: Thu Apr 23, 2015 8:07 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10067
Location: Rio de Janeiro - Brazil
Bregalad wrote:
For a menu I wouldn't bother to miss frames.

Unless you have music/sound, right?


Top
 Profile  
 
PostPosted: Thu Apr 23, 2015 11:14 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5734
Location: Canada
If you are concerned about the missed frames, you can dramatically decrease their frequency by adding more cycles to your wait loop.

Code:
; 7-cycle loop has 1/7 chance of waiting an extra frame
:
    bit $2002
    bpl :-

; 13-cycle loop has 1/13 chance of waiting an extra frame
:
    nop
    nop
    nop
    bit $2002
    bpl :-


Like, the naive loop has 14% slowdown because of the missed frames, but every cycle you add to the loop decreases your chances. If your loop had 100 cycles in it (and this is not unreasonable to do), it would go down to 1% slowdown.


Top
 Profile  
 
PostPosted: Thu Apr 23, 2015 11:47 am 
Offline
User avatar

Joined: Wed Apr 07, 2010 1:14 am
Posts: 484
Location: Iran
Thanks for everyone for the great info.
So BIT $2002 clears Negative sign, and as a result BMI will never branch, so it is useless.
But what about the BIT $2002, I feel that it is needed for skipping any halfway vblank periods, no?

Image


Top
 Profile  
 
PostPosted: Thu Apr 23, 2015 12:04 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5734
Location: Canada
Yes, an extra BIT $2002 before you enter your wait loop will clear the bit if you are already within vblank. Very useful if you need to avoid accidentally exiting the wait loop in mid-vblank (but not important if you don't).


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: samwise970 and 6 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