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 > IntrWait and VBlankIntrWait BIOS functions

#7860 - doragasu - Thu Jun 26, 2003 11:54 pm

I tried VBlankIntrWait BIOS function with this code:

Code:

#define VBlankIntrWait asm volatile("swi 0x50000")

..................
REG_IE = INT_VBLANK;
REG_DISPSTAT |= STAT_VB_ENABLE;
REG_IME = 1;
.................
while (1)
{
  VBlankIntrWait;
  .................
}


But doesn't work, when I call SWI 5, the system hangs up and never wakes up. I know VBLANK int es correctly enabled, but this doesn't work.

I tried to test IntrWait (SWI 4) with a similar program, but also didn't work for me.

Despite this, all other BIOS functions I tried (including Halt function (SWI 2)) worked for me, dunno why SWI 4 and 5 didn't work.

#7869 - tepples - Fri Jun 27, 2003 7:21 am

VblankIntrWait() calls IntrWait(). In order for IntrWait() to work properly, you have to have an ISR (interrupt service routine) installed first. An ISR must be compiled as ARM instructions and should have an entry point in IWRAM. If you don't install an ISR, or your ISR doesn't work, IntrWait() will hang the GBA.

Look at tutorials to see how to write an ISR. I've read that the crt0 packaged with a future beta of DevKit Advance will have enough of an ISR installed by default to get IntrWait() working: acknowledge interrupts to the hardware and to the BIOS, and then return.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#7876 - Quirky - Fri Jun 27, 2003 8:05 am

You have to let the bios know, in your interrupt service routine, that the vblank has occurred to tell the cpu to wake up. Something like this:

Code:

void interruptProcess(void) {
  // Disable interrupts
  REG_IME = 0x00;
  u16 Int_Flag;
  // Read the interrupt flag
  Int_Flag = REG_IF;
 
  if (Int_Flag == INT_VBLANK) {
    // let the bios know that vblank occurred
    (*(volatile u32*)0x03fffff8) = INT_VBLANK; 
  }
  // Enable interrupts
  REG_IME = 0x1;
  // Write back the interrupt flags 
  REG_IF = Int_Flag;
}


where you have previously set the interrupt address to point to this function. i.e. REG_INTERUPT = (u32)interruptProcess;