gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > "Strange" VBlankIntrWait behaviour ?

#46714 - hagen - Wed Jun 29, 2005 10:41 am

Hi!

I have the following "main" game loop:

forever:
ldr r1,=DATA_AREA+SLOW_CODE
ldr r0,[r1] @ r0 = function pointer
cmp r0,#0
bne slow
swi 0x50000 @ VBlWait (Low power usage)
b forever
slow:
mov lr,pc
bx r0 @ Call "slow" code funtion
b forever

I use "slow" code for code which takes more than one frame to complete.
If I insert a BIOS call to VBlankIntrWait, my vblank irq handler is not called every frame. Anyone knows why? I assume my irq handler is working as it should, because I only experience the problem when making a call to VBlankIntrWait... and yes - I acknowledge to the BIOS that I handled the VBLANK interrupt.

Can someone see what I am doing wrong?
_________________
Thomas Hagen

#46740 - hagen - Wed Jun 29, 2005 11:06 pm

I am going nuts over this... maybe I don't understand what VBlankIntrWait is doing? From GBATEK is read "Continues to wait in Halt status until a new V-Blank interrupt occurs."

If my previous posted sample was unclear - please consider this:

forever: swi 0x50000
delay: ldr r0,=150000
1: subs r0,r0,#1
bne 1b
b forever

If I don't call VBlankIntrWait, my game gets updated every time a vblank interrupt happens... but if I call VBlankIntrWait, my game gets delayed by the inserted delay in the sample above.

Anyone knows what I doing wrong?
_________________
Thomas Hagen

#46741 - Miked0801 - Wed Jun 29, 2005 11:13 pm

I believe there's a RAM bit you need to set to tell the handler that a VBlank has occured and is complete. I don't see your code doing this. Anyone remember which bit that was?

#46746 - tepples - Thu Jun 30, 2005 1:16 am

Code:

#define IF          (*(volatile u16 *)0x04000202)
#define BIOS_IF     (*(volatile u16 *)0x03fffff8)

void isr(void)
{
  unsigned int interrupts = IF;

  /* omit: handle each interrupt source */

  BIOS_IF |= interrupts;
  IF = interrupts;
}

_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#46768 - hagen - Thu Jun 30, 2005 9:29 am

Hey guys. Thank you very much for your replies - but as I wrote in my first message, I already does the BIOS acknowledge... here is my code.

ldr r0,=0x04000202
ldrh r1,[r0]
strh r1,[r0]

ldr r3,=0x3fffff8
ldrh r2,[r3]
orr r2,r2,r1
strh r2,[r3]

Everyone else must have this problem? ... how are you handling code that takes more than one frame? I have also tried to have my main game-loop only calling VBlankIntrWait and having "slow" code running in a timer interrupt... but the result is the same :-/

Hmm... frustrating this is...
_________________
Thomas Hagen

#46772 - hagen - Thu Jun 30, 2005 12:30 pm

Ok - I am puzzled ... If I make a call to Halt (swi 0x20000) instead of VBlankIntrWait (swi 0x50000) - my code runs as I supposed it should do.
Dunno why... wierd... or?
Anyways my main-game loop now eats a little less power, and makes my excellent NO$GBA DEBUGGER by Martin Korth happy :)
_________________
Thomas Hagen