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 > Wierd thing

#19325 - Gopher - Sat Apr 17, 2004 7:15 am

I'm working on a project that's implementing an hblank trick to draw up to 1,024 sprites at once. At present it's enabling only one interrupt (hblank) and so I wrote the handler to assume any interrupt is a hblank interrupt. Originally it worked only on VBA, not on actual hardware. Here was the code:
Code:

void InterruptHandler(void)
{
    hword f=REG_IF;
    static int index=0;
    //we just assume it's vcount, since that's the only one we enable
    //if this is the line we're waiting for...
    if (REG_VCOUNT==batches[index].MaxY)
    {
        //if we haven't drawn the last set yet..
        if (index<(NumTribbles>>5)-4)
        {
            //copy in the replacement for me (the guy 4 later)
           gbadMemCpy(batches[index+4].sprites,(gbasSpriteData +       ((index&0x3)<<5)),32*4);
            index++;
        }
        else  //if we're really at the end...
        {
            //reset the index to 0
            index=0;
        }
    }
    REG_IF|=f;
}


All I changed was eliminating the variable f at the begining and changing the last line to
Code:

REG_IF |= REGI_F;

and now it works on HW.

Can anyone tell me /why/ this fixed the problem? I don't even know what made me try it, it was basicly a shot in the dark.

thx
_________________
"Only two things are infinite: the universe, and human stupidity. The first is debatable." -Albert Einstein

#19339 - Miked0801 - Sat Apr 17, 2004 7:00 pm

You didn't declare f as a volatile var for starters. This means that the later assignment may not work right if your compiler "Optimizes" this for you. Also, I'd check and see how REG_IF is declared. Make sure it is alos declared as volatile for the same reason. That's my guess.

#19370 - Gopher - Sun Apr 18, 2004 2:35 am

REG_IF is declared volatile. F shouldn't need to be volatile since hblank was the only enabled interrupt? How could it change otherwise?
_________________
"Only two things are infinite: the universe, and human stupidity. The first is debatable." -Albert Einstein

#19371 - sajiimori - Sun Apr 18, 2004 3:48 am

I was going to reply with the obvious, but now that I think of it, it would seem strange for the compiler to optimize away the |= operation.

I mean, if REG_IF is volatile, saving its value at the beginning of the function and or'ing it with the old value at the end should be assumed significant. REG_IF could have been zeroed during the function's execution for all the compiler knows.

Anyway, I'd say declare f volatile. It couldn't hurt, and if it works like that, maybe it's an optimizer bug.

#19383 - torne - Sun Apr 18, 2004 8:39 pm

f shouldn't need to be volatile; the optimiser will generally not reorder memory accesses.

#19385 - Lord Graga - Sun Apr 18, 2004 9:03 pm

Try this:

Code:
void Intr_Flag(void)
{
   u16 flags;
   REG_IME = 0;
   flags = REG_IF;
   if(flags&2)
   {
      //HBLANK
   }
   if(flags&IRQ_VBLANK)
   {
      //VBLANK
   }

   REG_IF = flags;
   REG_IME |= BIT00;
}