Register To Post



 Bottom   Previous Topic   Next Topic

#1
How to sync with the display
Posted on: 2010/11/6 13:33
Nintendoid!
Joined 2007/8/8
Great Britain
194 Posts
CoderContributorLong Time User (5 Years)HOTY09 EntryApp Coder
There seems to be a little bit of confusion about how to do this so I thought I'd post a couple of examples.

The program main loop should be executed once per game frame. A simple way to do this is to sync with the end of the VIP drawing process.

Examples:

1. Sync with end of drawing


#include "libgccvb.h"

int main()
{
  
int count0;

  
vbDisplayOn();
  
vbDisplayShow();

  
// main loop @ 50 Hz
  
while(1)
  {
    
// wait for the VIP to finish drawing
    
while(!(VIP_REGS[INTPND] & XPEND)); 
    
// clear flag
    
VIP_REGS[INTCLR]= XPEND;

    
// read controller

    // do stuff        

    
if((count%7)==0)
      
VIP_REGS[BKCOL] ^= 3;

    
count++;
  }

  return 
0;
}


2: As above but using a VIP interrupt


#include "libgccvb.h"

volatile int drawsync0;

void vip_isr()
{
  
VIP_REGS[INTENB]= 0;

  if(
VIP_REGS[INTPND] & XPEND)
  {
    
VIP_REGS[INTCLR]= XPEND;
    
drawsync1;
  }

  
VIP_REGS[INTENB]= XPEND;
}

int main()
{
  
int count0;

  
VPU_VECTOR= (u32)vip_isr;
  
VIP_REGS[INTENB]= XPEND;

  
vbDisplayOn();
  
vbDisplayShow();

  
// main loop @ 50 Hz
  
while(1)
  {
    
// wait for the VIP to finish drawing
    
while(!drawsync);
    
// clear flag
    
drawsync0;

    
// read controller

    // do stuff

    
if((count&15)==0)
      
VIP_REGS[BKCOL] ^= 3;

    
count++;
  }

  return 
0;
}
Top

#2
Re: How to sync with the display
Posted on: 2010/11/7 3:43
VUE(xpert)
Joined 2006/9/29
USA
267 Posts
CoderLong Time User (6 Years) PVBCC 2010 3rd
Makes sense... But why are you flipping BKCOL every 7 steps? Is that just demo code?
Top

#3
Re: How to sync with the display
Posted on: 2010/11/7 8:26
PVB Elite
Joined 2003/7/26
USA
967 Posts
PVBCC EntryCoderContributorSpecial AchievementTop10 PosterHOTY09 EntryLong Time User (9 Years) App Coder20+ Game Ratings
Quote:

Fwirt wrote:
Makes sense... But why are you flipping BKCOL every 7 steps? Is that just demo code?


It makes the screens blink to show that it's working without having to set up any graphics.
Top

#4
Re: How to sync with the display
Posted on: 2011/2/14 15:25
VUE(xpert)
Joined 2008/12/28
Slovenia
456 Posts
Highscore Top ScoreCoderContributorTop10 Poster10+ Game RatingsLong Time User (4 Years) App CoderPVBCC 2010 Entry

// wait for the VIP to finish drawing
while(!(VIP_REGS[REG_INTPND] & XPEND));
// clear flag
VIP_REGS[INTCLR]= XPEND;


I've just tried this code on Soviet Union 2010 and it makes everything really slow on emulators, even though I've disabled my slowdown loop. What should I do?
Top

#5
Re: How to sync with the display
Posted on: 2011/2/15 7:59
PVB Elite
Joined 2003/7/26
USA
967 Posts
PVBCC EntryCoderContributorSpecial AchievementTop10 PosterHOTY09 EntryLong Time User (9 Years) App Coder20+ Game Ratings
I think it may be due to less than 100% accurate VIP timing in the emulators. It's probably better to use the interrupt example; although, even then, it's probably more "proper" to use the display frame or game frame interrupt flags (no offense to dasi ).

If you don't want to use interrupts, you could sync to the actual screen refresh (which is always the same on hardware and, thus, easier to emulate) by using the DPSTTS register instead of XPSTTS. The relevant bits are the four least-significant. Each bit corresponds to a frame-buffer and represents which one is currently being read from (sent to the scanner). They're all cleared when the display is idle (between frames).
Top

#6
Re: How to sync with the display
Posted on: 2011/2/16 1:22
Nintendoid!
Joined 2007/8/8
Great Britain
194 Posts
CoderContributorLong Time User (5 Years)HOTY09 EntryApp Coder
The examples given above work correctly in Mednafen, Reality Boy, and on hardware.

> What should I do?

It's likely you will need to restructure or rewrite your main loop.

> If you don't want to use interrupts, you
> could sync to the actual screen refresh
> by using the DPSTTS [DPBSY flags]...

The reason for syncing to XPEND or using the XPEND interrupt is to avoid writing to VRAM, the world attributes, OAM, the parameter tables, etc, during the VIP drawing process. Syncing to GAMESTART is fine too, but means you need to use an interrupt:


#include "libgccvb.h"

void vip_isr()
{
  
VIP_REGS[INTENB]= 0;

  if(
VIP_REGS[INTPND] & XPEND)
  {
    
VIP_REGS[INTCLR]= XPEND;

    
// drawing finished, write to VRAM, OAM, etc, here!
  
}

  
VIP_REGS[INTENB]= XPEND;
}

int main()
{
  
int count0;

  
VPU_VECTOR= (u32)vip_isr;
  
VIP_REGS[INTENB]= XPEND;

  
vbDisplayOn();
  
vbDisplayShow();

  
// main loop @ 50 Hz
  
while(1)
  {
    
// sync with start of gameframe
    
while(!(VIP_REGS[INTPND] & GAMESTART));
    
// clear flag
    
VIP_REGS[INTCLR]= GAMESTART

    
// read controller

    // do stuff

    
if((count&15)==0)
      
VIP_REGS[BKCOL] ^= 3;

    
count++;
  }

  return 
0;
}
Edited by dasi on 2011/2/16 1:38
Top

#7
Re: How to sync with the display
Posted on: 2011/2/18 19:18
PVB Elite
Joined 2010/1/5
Sweden
507 Posts
Highscore Top10Long Time User (3 Years)Top10 PosterDonator30+ Game Ratings
Quote:

I've just tried this code on Soviet Union 2010 and it makes everything really slow on emulators, even though I've disabled my slowdown loop. What should I do?


You should send it to me so I can try it out with my FlashBoy Plus and finally play it like it should be played. ;-)
Top

#8
Re: How to sync with the display
Posted on: 2011/7/13 0:29
VUE(xpert)
Joined 2008/12/28
Slovenia
456 Posts
Highscore Top ScoreCoderContributorTop10 Poster10+ Game RatingsLong Time User (4 Years) App CoderPVBCC 2010 Entry
I'm trying to solve this problem again. I've done a number of improvements to the code, including doing all the changes to OBJs at once (but only if they need to be changed) after they've been drawn. However, it's still not fast enough. Then I came across this in the vbSetWorld of my world.h:

while (VIP_REGS[XPSTTS] & XPBSYR);    // Wait for the screen to stop updating.

This seems to be much faster. However, I can't test it on hardware. How does that work? The Nintendo VB development manual describes XPSTTS simply as "drawing control". According to vip.h, it contains a number of flags. Is XPBSYR clear when it's safe to write to the screen?
Top

#9
Re: How to sync with the display
Posted on: 2011/7/13 8:26
VB Gamer
Joined 2007/12/14
48 Posts
Long Time User (5 Years)
Quote:

HorvatM wrote:

while (VIP_REGS[XPSTTS] & XPBSYR);    // Wait for the screen to stop updating.

This seems to be much faster. However, I can't test it on hardware. How does that work? The Nintendo VB development manual describes XPSTTS simply as "drawing control". According to vip.h, it contains a number of flags. Is XPBSYR clear when it's safe to write to the screen?


I think "XPSTTS" is an abbreviation for "piXel Processor STaTuS" and yes, it's a register full of flags. XPBSYR is defined as 0x0C, which is 1100b. In that code snippet, XPBSYR is used as a mask for the bits XPBSY0 (0100b) and XPBSY1 (1000b) which are set when the first and second framebuffers are being drawn, respectively. However when both of those bits are clear, the XP is idle, (VIP_REGS[XPSTTS] & XPBSYR) == 0, and thus the do-nothing while loop exits at a point when it is safe to update the areas in RAM that the XP will read from at the top of the next frame.
Top

#10
Re: How to sync with the display
Posted on: 2011/7/13 13:10
Nintendoid!
Joined 2007/8/8
Great Britain
194 Posts
CoderContributorLong Time User (5 Years)HOTY09 EntryApp Coder
HorvatM, blitter has also written a clear and detailed description of the VIP drawing process in his wiki article on direct screen drawing which you may find useful.
Edited by dasi on 2011/7/13 13:21
Top

 Top   Previous Topic   Next Topic


Register To Post

You are not logged in.
Lost Password?
Register Resend Activation