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 > AAS, VBlank/HBlank/VCount interrupt, BIOS, etc.

#24631 - DiscoStew - Sun Aug 08, 2004 5:53 am

I've been working on interrupts and BIOS calls using the 2nd example of AAS, and I've got a few questions (pertaining to the emu no$gba). The VBlank interrupt is set, in which when it hits, it will disable the HBlank interrupt. The VCount interrupt is set for scanline 227, in which that will enable the HBlank interrupt (so that the HBlank interrupt doesn't run through VBlank). At the beginning of my main loop, I have the BIOS call swi 0x05, and at the end the BIOS call swi 0x02, which is deactivated when the VCount interrupts. All code from the 2nd AAS example is still there for testing with. It all seems to work except when I uncomment the swi 0x05 call. With that uncommented, it seems nothing in the main loop is executed. When commented, it does work, but it seems to be looping through the main loop more than once per frame (about 163 times, there really isn't much there). What should I do about it? Plus, is it bad to enable the VCount interrupt at scanline 227? The HBlank interrupt sets off once before the time I'd like it to. At 228, the HBlank interrupt doesn't even go, because it is enabled in the VCount interrupt, which is probably not going through. Here is both the interrupt.c and AAS_Example.c code.
Code:
interrupt.c
#ifndef _gba_INTERRUPT_C
#define _gba_INTERRUPT_C

#include "gba.h"
#include "AAS.h"

extern u16 Somevalue;
u16 value = 0;


void VBlankInterruptHandler()
{
   REG_IME = 0;
   //Disable the HBlank Interrupt
   REG_IE &= ~(1 << 1);

   //AAS Processing of audio
   AAS_DoWork();
   *((u32*)0x03005000) = Somevalue;
   Somevalue = 0;
   REG_IME = 1;
}

IN_IWRAM void HBlankInterruptHandler()
{
   //Just a simple shift of the background every scanline just to see if it works
   REG_BG0HOFS = ((REG_VCOUNT & 0x1) ? value : 0);
   
}

void VCountInterruptHandler()
{
   
   REG_IME = 0;
   ++value;
   if(value == 16) value = 0;
   //Enable the HBlank interrupt
   REG_IE |= (1 << 1);
   REG_IME = 1;
   
}

void UnusedInterruptHandler()
{
}

void (*AAS_IntrTable[13])(void) =
{
   VBlankInterruptHandler,      // VBlank Interrupt
   HBlankInterruptHandler,      // HBlank Interrupt
   VCountInterruptHandler,      // V Counter Interrupt
   UnusedInterruptHandler,      // Timer 0 Interrupt
   UnusedInterruptHandler,      // Timer 2 Interrupt
   UnusedInterruptHandler,      // Timer 3 Interrupt
   UnusedInterruptHandler,      // Serial Communication Interrupt
   UnusedInterruptHandler,      // DMA0 Interrupt
   UnusedInterruptHandler,      // DMA1 Interrupt
   UnusedInterruptHandler,      // DMA2 Interrupt
   UnusedInterruptHandler,      // DMA3 Interrupt
   UnusedInterruptHandler,      // Key Interrupt
   UnusedInterruptHandler       // Cart Interrupt
};

#endif
Code:
AAS_Example.c
// AAS Example for projects with other CPU intensive interrupts
// Notes:
//  + Specially modified crt0.s file included with the example must be set to use __AAS_MultipleInterrupts
//  + AAS_DoWork() must be called at least 50 times/sec. In this example, it's being called during VBlank.

#include "gba.h"
#include "AAS.h"
#include "AAS_Data.h"

u16 Somevalue = 0;


const u16 BG_Palette[] = {
   0x0000, 0x0000, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
};

const u16 BG_Tiles[] = {
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111, 0x1111,
   0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222, 0x2222,
};

const u16 BG_Maps[] = {
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
   0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
   0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
};



// Registers for GBA keys
#define   REG_KEY (*(volatile AAS_u16 *)0x04000130)
#define REG_KEY_A 0x0001
#define REG_KEY_B 0x0002

void AgbMain()
{
   int keys, keys_changed;
   int prev_keys = 0;
   
   // Initialise AAS
   AAS_SetConfig( AAS_CONFIG_MIX_32KHZ, AAS_CONFIG_CHANS_8, AAS_CONFIG_SPATIAL_STEREO, AAS_CONFIG_DYNAMIC_OFF );
   
   // Show AAS Logo (required for non-commercial projects)
   AAS_ShowLogo();

   
   // Start playing MOD
   AAS_MOD_Play( AAS_DATA_MOD_CreamOfTheEarth );
   
   REG_DMA3SAD = (u32)(BG_Palette);
   REG_DMA3DAD = (u32)(BGPaletteMem);
   REG_DMA3CNT = (16) | DMA_16NOW;

   REG_DMA3SAD = (u32)(BG_Tiles);
   REG_DMA3DAD = (u32)(CharBaseBlock(0));
   REG_DMA3CNT = (48) | DMA_16NOW;

   REG_DMA3SAD = (u32)(BG_Maps);
   REG_DMA3DAD = (u32)(ScreenBaseBlock(7));
   REG_DMA3CNT = (32*32) | DMA_16NOW;

   REG_BG0CNT = (0 + (0 << 1) + (0 << 6) + (0 << 7) + (7 << 8) + (0 << 13) + (0 << 14));

   REG_BG0HOFS = 0;
   REG_BG0VOFS = 0;

   REG_DISPCNT = (MODE_0 |BG0_ENABLE);

   // Enable vblank, hblank, and vcount interrupts
   REG_DISPSTAT |= ((1 << 3) | (1 << 4) | (1 << 5) | (227 << 8));
   
   REG_IE |= (1 | (1 << 2));
   

   // Main loop
   while(1)
   {

      //Wait for VBlank. Other interrupts still occur, but no code beyond this point continues until the VBlank
      BIOS_VSync();
      ++Somevalue;
      // Work out which keys have just been pressed
      keys = ~REG_KEY;
      keys_changed = keys ^ prev_keys;
      prev_keys = keys;
      
      // Play looping ambulance sound effect out of left speaker if A button is pressed, stop when released
      if ( keys_changed & REG_KEY_A )
      {
         if ( keys & REG_KEY_A )
            AAS_SFX_Play( 0, 64, 16000, AAS_DATA_SFX_START_Ambulance, AAS_DATA_SFX_END_Ambulance, AAS_DATA_SFX_START_Ambulance );
         else
            AAS_SFX_Stop( 0 );
      }
      
      // Play explosion sound effect out of right speaker if B button is pressed
      if ( keys_changed & keys & REG_KEY_B )
         AAS_SFX_Play( 1, 64, 8000, AAS_DATA_SFX_START_Boom, AAS_DATA_SFX_END_Boom, AAS_NULL );

      //CPU is halted until an interrupt occurs, should disable with the VCount interrupt. Some power saving
      
      BIOS_Halt();
      
   }
   return;
}
Plus some swi ASM code taken from Cearn's examples
Code:
swi.s


   .file "swi.s"
   .text
   .align 2
   .code 16
   
   .global BIOS_Halt
   .thumb_func
BIOS_Halt:
   swi 0x02
   bx lr
   
   .global BIOS_VSync
   .thumb_func
BIOS_VSync:
   swi   0x05
   bx   lr
   

I checked Cearn's own examples of the swi VSync, and I think this code is very identical to that, but mine doesn't work. Can anyone see the problem? thx for any help given
_________________
DS - It's all about DiscoStew

#24643 - dagamer34 - Sun Aug 08, 2004 3:19 pm

I don't think the HBlank interrupt triggers during the VBlank period. All the pictures about the timing of that that I have seen show that HBlank only triggers the first 160 scanlines, the visible ones.
_________________
Little kids and Playstation 2's don't mix. :(

#24645 - DiscoStew - Sun Aug 08, 2004 4:55 pm

Actually, the HBlank interrupt does trigger during the VBlank. It is HDMA that doesn't. I checked through the forums about that, plus I made a test for checking which scanlines run the HBlank.

EDIT:
I think I may have found the problem. After searching for VBlankIntrWait in the forums, I came across this, which as Quirky pointed out that the BIOS must be told that the VBlank had occurred, which can be done as such in the VBlank interrupt function...
Code:
(*(volatile u32*)0x03fffff8) = INT_VBLANK;

Now my code works, with everything in the main loop only being called once per frame. I don't even need the BIOS_Halt function for this, since interrupts run if set and are not halted by my BIOS_VSync function.

I was wondering about whether I should set the VCount interrupt to 227, but after doing this and that, I found out something about the HBlank. At first I understood that for each scanline there is an HBlank period, and an HDraw period, in that order, but it seems to me that it is reversed, where the HBlank is after the HDraw for the same scanline. So I guess it is good for me to enable the VCount interrupt at scanline 227 because it sets me up for the next HDraw, which would be at scanline 0.
_________________
DS - It's all about DiscoStew