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 > Interrupt problem

#15835 - SmileyDude - Sat Jan 31, 2004 10:44 pm

Hello everybody,

I'm running into a problem that I haven't seen before, and I was wondering if anyone could help me out. I have an interrupt handler that works fine until I try accessing a variable defined in another file.

For example, in my main.c, I have the following:

Code:
u16 gOffset;


and in my interrupt.c, I try to access it like this:

Code:
int vcount = REG_VCOUNT;
REG_BG0HOFS = vcount + gOffset;


if I remove the reference to gOffset, everything works fine. With it, though, the program locks up almost immediately.

I'm sure that everything is initialised when the interrupt happens, because I don't even install the interrupt handler until the last part of my initialisation. I haven't tested this on hardware yet, only in VBA, but even if it did work on hardware, I need to be able to use VBA for debugging, etc. The main.c is compiled in Thumb, and the interrupt.c is compiled in ARM.

Any ideas?
_________________
dennis

#15836 - poslundc - Sun Feb 01, 2004 12:00 am

Can you post more of the code? Did you remember to declare the reference to your external variable (ie. extern u16 gOffset)? Do you set the REG_IF bits at the end of your interrupt handler (this is one of those things that can make your handler work sometimes but not all the time)?

There is nothing wrong in principle with what you are doing, but there could be other aspects of your code that seem unrelated but are causing the freeze-up.

Also, you may as well make gOffset an int/u32, since it will be padded to 4 bytes anyway. Only reason to keep it as a u16 is if you want the overflow properties.

(In my experience, stuff might work on VBA that doesn't work on hardware, but it rarely goes the other way around. If it's not working emulation you should stop and fix it there. :)

Dan.

#15838 - SmileyDude - Sun Feb 01, 2004 1:23 am

poslundc wrote:
Can you post more of the code? Did you remember to declare the reference to your external variable (ie. extern u16 gOffset)? Do you set the REG_IF bits at the end of your interrupt handler (this is one of those things that can make your handler work sometimes but not all the time)?


I had it at the top of the routine, but I just now moved it to the bottom, and it still doesn't work.

poslundc wrote:
There is nothing wrong in principle with what you are doing, but there could be other aspects of your code that seem unrelated but are causing the freeze-up.


Could be -- I'll probably start commenting out blocks of code until I get to a small example of it not working.

poslundc wrote:
Also, you may as well make gOffset an int/u32, since it will be padded to 4 bytes anyway. Only reason to keep it as a u16 is if you want the overflow properties.


Well, yes it will be padded -- but, if there are other u16s around it, the compiler should pack them together without the padding (I haven't looked at what gcc is doing -- I hope that's what it would be doing :) ) But, just to be sure, I tried it as a u32 with no difference.

I might just re-write my interrupt handler in assembly -- it isn't doing that much, so it certainly doesn't have to be C code. I might also try declaring my variables someplace else, instead of main. Just incase gcc and/or the linker is doing something funky.
_________________
dennis

#15886 - SmileyDude - Mon Feb 02, 2004 5:38 pm

Well, I ended up fixing my problem -- I'm not sure exactly what fixed it, but here are the changes I made:

    Moving the interrupt routine to IWRAM

    Disabling interrupts while in the handler

    Moving the externs to a .h file (shouldn't have made a difference, but makes it easier to work with :) )


I'm suspecting that either the IWRAM change might have helped with the accessing globals, but it doesn't really make sense. I'm sure that it does help with the other problem that I was having, which was the interrupt handler taking too long. Disabling the interrupts was just something I figured wouldn't hurt -- my code certainly isn't long enough to last until the next hblank, but without the IWRAM change, it was long enough to last until the vblank when on line 160.

Anyway, thanks for the suggestions --- even if it didn't help directly, I did end up implementing some of them anyway :)
_________________
dennis