#55955 - Ultima2876 - Tue Oct 04, 2005 10:01 pm
Code: |
CODE_IN_IWRAM void hblank_select(void)
{
if(REG_VCOUNT < 40)
{
((u16*)0x070003E2)[0] = hsetting[REG_VCOUNT + GBA];
((u16*)0x070003EA)[0] = hsetting1[REG_VCOUNT + GBA];
((u16*)0x070003F2)[0] = hsetting2[REG_VCOUNT + GBA];
}
else if(REG_VCOUNT == 150)
{
if(frameclock != 1)
{
REG_BG3HOFS = message_scrollamount;
}
}
else if(REG_VCOUNT == 161)
{
REG_BG3HOFS = 0;
}
if(hblank_func == HBLANK_STARS)
{
REG_BG0HOFS = hoffset[REG_VCOUNT];
return;
}
return;
} |
Is there anything in here that would be particularly slow, and that I should steer away from in my hblank function? I say so, because at a seemingly random time, the REG_VCOUNT = 161 code doesn't execute, and the whole of BG3 scrolls for a frame, then fixes itself again, making it flash oddly every so often. Also, it only seems to do this on hardware... am I right that it could be a speed issue? Or any other suggestions?
Thanks =P
#55965 - poslundc - Wed Oct 05, 2005 12:25 am
There is nothing overtly wrong with it, but are you setting the interrupt acknowledge bit somewhere else? This is the kind of thing that might work okay on an emulator but not on hardware.
Also, any stuff done when REG_VCOUNT >= 160 should really be done as part of your VBlank routine rather than an HBlank ISR, as it's only increasing the size of your function unnecessarily.
Are you compiling it as ARM code?
Dan.
#56050 - Ultima2876 - Wed Oct 05, 2005 7:59 pm
I'm fairly sure I'm not setting that bit anywhere else, and it's compiling to ARM code.
About the REG_VCOUNT > 160... I did actually have it setting REB_BG0HOFS to 0 immidiately after my WaitForVsync();, but that didn't seem to fix it so I tried putting it explicitly in the Hblank function...
Any more ideas? =/
#56052 - poslundc - Wed Oct 05, 2005 8:18 pm
Ultima2876 wrote: |
I'm fairly sure I'm not setting that bit anywhere else, |
So... set it then.
Dan.
#56054 - Ultima2876 - Wed Oct 05, 2005 8:20 pm
Do I have to set it in more than one place? I thought you just set it in your interrupt handler then clear it when you're done.. unless I have it set up completely wrong. Cheers =P
#56056 - poslundc - Wed Oct 05, 2005 8:26 pm
You must set the HBlank bit in REG_IF at the end of your interrupt.
REG_IF = 2;
Dan.
#56130 - Ultima2876 - Thu Oct 06, 2005 2:09 pm
OH! I remember reading that in TONC. Thanks a lot for that... dunno if it'll solve the problem, as I can't seem to reproduce it reliably now. X_x;
#56139 - Cearn - Thu Oct 06, 2005 4:38 pm
if you're using tonc's or libgba's interrupt handler, acknowledging the interrupt is indeed done for you. This is probably not the issue, but have you checked whether the the routine is actually in iwram? I remember having some problems with that in the past when having ROM / IWRAM in the same file (or am I thinking about calling IWRAM from ROM when the routines are in the same file? oh well, check anyway).
What is going to matter, even if it is just a little, is that you have multiple references to REG_VCOUNT. All registers are volatile, which basically means that the optimiser should keep its hand off. which means that the thing is loaded every time you reference it, which is not something you want to do inside an HBlank interrupt. It's probably better to load it into a local variable and check that instead of using REG_VCOUNT directly. You're also wasting a few instructions (and registers) by accessing OAM in three casts. GCC constructs the addresses for each case rather than using offsets, even when you're accessing consecutive memory. Using structs instead would be a little faster and cleaner.
Can't see why the code as is would be slow enough for a misfire, even running all the cases would probably take less than a hundred cycles, and an hblank lasts 272. Of course, the overhead for the main isr reduces the amount you can use, but still.
Are you using DMA near the VBlank somewhere? Those could mess up interrupts too.
#56375 - Ultima2876 - Sat Oct 08, 2005 7:40 am
Ah. DMA in Vblank is a very good point. The only thing I use DMA for is the CopyOAM thing, and sure enough that happens right at the start of every Vblank. I'm pretty sure that'll be it. Excellent, I can sort that out fairly easily. =P
And thanks a lot for all those optimisation tips aswell. I'll be sure to use them.