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.

ASM > Stack/Mode Issue

#63222 - AkumaATR - Sat Dec 10, 2005 4:37 am

I am finding in my interrupt dispatcher code that I have to push LR to the system stack (and that I can't use the IRQ stack) before executing the user handler, and restore it after the user handler returns.

I had a version of the interrupt dispatacher code that I thought was finished/fully-working because it works correctly in VBA and NO$GBA. However, on hardware, the animated (falling) pixel I have stops about 1/4 of the screen down (freezes I guess). I find it very strange how long it works (in computing terms) before freezing (it's already handled the vblank int a number of times at this point)... It's page flipping on vblank int when a page is ready, and doing a vblankintrwait after the code to produce the next frame is done.

It pushed the regs I needed to preserve (including LR) to the IRQ stack, then switched to system mode, then returned to IRQ mode before popping those items off the IRQ stack. That's kinda how I would like to do it... it's only a total of four additional words (not enough to overrun the IRQ stack space), and there's no nesting going on now (I don't think this problem is from overrunning IRQ stack space).

My dispatcher code is very similar to the dispatcher code in libgba because I studied how that dispatcher worked before writing mine. Like I said, I can get it to work by pushing LR to the system stack, I just don't want to do that if I don't have to and would like to know why it's not working if I use IRQ stack space for that.

Works: http://www.rafb.net/paste/results/Dy1tLo18.html
Doesn't: http://www.rafb.net/paste/results/jRlou772.html

The only difference is that I save LR on the IRQ stack in the one that doesn't work, but to the system stack in the one that does.

The stuff in question begins around line 104.

Also there is a bug in the abort code (I need to ack. via IF there), but that's not causing this problem (abort code is never running for my current tests).

Here is a link to the main source file (not where the problem lies):
http://www.rafb.net/paste/results/CAPxLE39.html

Thanks a lot for any help with this... I've been working on this interrupts code way too long now :-/. And in case anyone is wondering I just wrote it as a learning exercise, it's no better than handlers than interrupt code that's currently available.

#63224 - DekuTree64 - Sat Dec 10, 2005 6:58 am

Yeah, pushing the system lr before calling the user handler is the way to do it. If you don't, then whatever code was running when the interrupt occurred will be left with a trashed lr.

EDIT: Just noticed you might not know this... When you switch CPU modes, some registers get swapped out internally. So when you push lr in SYS mode, it's an entirely different register from the one you would push in IRQ mode.

Normally it's only sp, lr, and spsr that get swapped depending on mode, but FIQ mode has its own r8-r12 as well. There's no way to generate an actual FIQ interrupt on the GBA though, but you can manually switch to FIQ mode and play with the extra registers for fun :)
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#63252 - AkumaATR - Sat Dec 10, 2005 3:41 pm

Thanks Deku... for some reason I guess I thought lr_irq was the one I needed...