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 > Interrupts suddenly not working

#23995 - dagamer34 - Mon Jul 26, 2004 4:11 am

Interrupts in my program suddenly don't work anymore and I don't know why! Here's what I do to set up an interrupt:


Code:

#define INT_VBLANK        0x0001
#define INT_HBLANK       0x0002   
#define INT_VCOUNT       0x0004   
#define INT_TIMER0       0x0008
#define INT_TIMER1       0x0010
#define INT_TIMER2       0x0020   
#define INT_TIMER3       0x0040
#define INT_SERIAL         0x0080
#define INT_DMA0       0x0100
#define INT_DMA1       0x0200
#define INT_DMA2       0x0400
#define INT_DMA3       0x0800
#define INT_KEYBOARD      0x1000
#define INT_CART       0x2000
#define INT_ALL       0x4000

// Dummy interrupt prototypes omitted for space, otherwise they would go here

/* Table of function pointers */
fp* IntrTable[]  =
{
   (fp*)VBLANK,
   (fp*)HBLANK,
   (fp*)VCOUNT,
   (fp*)TIMER0,
   (fp*)TIMER1,
   (fp*)TIMER2,
   (fp*)TIMER3,
   (fp*)SERIAL,
   (fp*)DMA0,
   (fp*)DMA1,
   (fp*)DMA2,
   (fp*)DMA3,
   (fp*)KEYBOARD,
   (fp*)CART
};

// Enables interupt calls
void EnableInterupts(u16 interupts)
{
   REG_IME = 0;  // Not a good idea to change interupt registers during an interupt

   if(interupts | INT_VBLANK)
      REG_DISPSTAT |= 0x8;

   if(interupts | INT_HBLANK)
      REG_DISPSTAT |= 0x10;
   
   if(interupts | INT_VCOUNT)
      REG_DISPSTAT |= BIT05;

   REG_IE |= interupts;

   REG_IME = 1;
}

// Starts an interupt handler
void StartIntHandler (u16 intno, void* funcpt)
{
   switch (intno)
   {
   case INT_VBLANK:
      {
         IntrTable [0] = (fp*)funcpt;
      }
      break;
   case INT_HBLANK:
      {
         IntrTable [1] = (fp*)funcpt;
      }
      break;
   case INT_VCOUNT:
      {
         IntrTable [2] = (fp*)funcpt;
      }
      break;
   case INT_TIMER0:
      {
         IntrTable [3] = (fp*)funcpt;
      }
      break;
   case INT_TIMER1:
      {
         IntrTable [4] = (fp*)funcpt;
      }
      break;
   case INT_TIMER2:
      {
         IntrTable [5] = (fp*)funcpt;
      }
      break;
   case INT_TIMER3:
      {
         IntrTable [6] = (fp*)funcpt;
      }
      break;
   case INT_SERIAL:
      {
         IntrTable [7] = (fp*)funcpt;
      }
      break;
   case INT_DMA0:
      {
         IntrTable [8] = (fp*)funcpt;
      }
      break;
   case INT_DMA1:
      {
         IntrTable [9] = (fp*)funcpt;
      }
      break;
   case INT_DMA2:
      {
         IntrTable [10] = (fp*)funcpt;
      }
      break;
   case INT_DMA3:
      {
         IntrTable [11] = (fp*)funcpt;
      }
      break;
   case INT_KEYBOARD:
      {
         IntrTable [12] = (fp*)funcpt;
      }
      break;
   case INT_CART:
      {
         IntrTable [13] = (fp*)funcpt;
      }
      break;
   default:
      break;
   }
}


And used like this:
Code:

// User-defined functions
void vbl ();

// Set up which function will be called on a certain interrupt
StartIntHandler (INT_VBLANK, (void*)&vbl);

// Enable interrupts
EnableInterupts (INT_VBLANK);


I cut and pasted most of it, it's not all in one file or in the same exact order, but I do know that it has to do with the set-up of my interrupts. Anybody know what's wrong?
_________________
Little kids and Playstation 2's don't mix. :(

#24008 - poslundc - Mon Jul 26, 2004 1:40 pm

What did you change in your code to make them stop working?

Dan.

#24019 - dagamer34 - Mon Jul 26, 2004 7:27 pm

poslundc wrote:
What did you change in your code to make them stop working?

Dan.


If only I knew. I really am starting to question whether it is the code in the first place as I tried to rebuild an old project with interupts and it also failed to work properly.

The odd thing though is that if I use the ctr0.s provided with AAS, and set it to AAS_MultipleInterrupts, create an interrupt table and then set up interrupts that way, it suddenly works. But switching crt0.s with another unmodified one didn't help.

I compiled it with the HAM toolchain without the hamLibs and also with DevKitadvance and still no change. I'm going around in circles trying to fix this.
_________________
Little kids and Playstation 2's don't mix. :(

#24023 - poslundc - Mon Jul 26, 2004 7:51 pm

Well, stupid but necessary question: in the crt0.S you are using, is the interrupt support set to the correct value? I can't check at work, but IIRC you can't use multiple interrupts with a jump table in the standard devkit's crt0.S; you need to either switch to single interrupts or write your own interrupt handler.

Dan.

#24024 - dagamer34 - Mon Jul 26, 2004 7:53 pm

The crt0.s that I am using supports multiple interrupts. I've used it plenty of times before with no problem.
_________________
Little kids and Playstation 2's don't mix. :(

#24026 - poslundc - Mon Jul 26, 2004 8:05 pm

OK, but the crt0.S I have doesn't use a jump table for multiple interrupts... it just branches to an interrupt handler you specify and code. It's the same as switching on "Fast Interrupt" support instead of using "Single Interrupts".

You might try seeing if your program works if you switch to single interrupts instead of multiple interrupts.

Dan.

#24030 - dagamer34 - Mon Jul 26, 2004 8:42 pm

I managed to fix my problem only after doing a complete re-install of my environment. I now later find out that I had conflicting versions of my library, with old and new defintions of my .a file and headers. I wish I had known that sooner.
_________________
Little kids and Playstation 2's don't mix. :(