-
Notifications
You must be signed in to change notification settings - Fork 0
GBA sleep tech reference
The Gameboy Advance originally featured a hardware low power sleep mode that needed to be triggered by the game. This is called SWI 03h STOP. Games that supported it had a "sleep mode" menu option. If the game didn't support it there was no way to put your GBA into sleep mode, even tho the hardware did.
Back in the day we just lived with the fact that closing the SP's lid did nothing. The game just kept running, no sleep mode was triggered. So in fact there was no way to put your GBA (SP) into sleep mode outside of games that supported that.
Today that seems unreasonable, we just take it for granted that we can put any handheld device to sleep whenever we feel like it. And more recent handhelds, be them gaming consoles or smartphones, satisfy such demands.
open_agb_firm allows you to run GBA games on your 3DS natively and that's awesome. That's possible, because, put simply, the 3DS comes with builtin GBA hardware. It doesn't need to emulate GBA, it can boot into ARM7 mode and just run dem games. Yay!
But open_agb_firm, just like the OG GBA, doesn't include a switch to toggle SWI 03h STOP. Meaning if the game supports it, we can use it on the 3DS as well, but not in any other way.
People came up with the idea to patch that SWI 03h STOP trigger option into game roms, basically enabling sleep mode in games that didn't originally support it. But unfortunately this didn't work with every game.
I mean wouldn't it be so cool if we could trigger SWI 03h STOP just by closing the lid of the thing regardless of the game we are playing? Just like you would with any modern device? Right? Well that's exactly what this is about.
open_agb_firm already brings everything we need. To make things short:
- Load a rom into memory
- Depending on the roms layout dynamically place our own gbaSleepIrqHandler in there (memory, not the actual rom file!)
- Pass the gbaSleepIrqHandler address down to ARM9
- Persist the LGY ARM7 vector override and its runtime writability, instead of disabling it right after boot. Thus keeping a transparent vector table in place and using the IRQ vector as a persistent, game-independent pre-BIOS hook.
- Pass the gbaSleepIrqHandler address down to ARM7 and make it load it utilizing the BIOS vector override.
- gbaSleepIrqHandler will trigger
SWI 03h STOPdirectly if it detects the L + SELECT key combo. - ARM11's KEY_SHELL (lid close) signal will translate to ARM7 L + SELECT and also trigger
SWI 03h STOP - ARM11 will then also enter its low power sleep state
So this enables us to trigger SWI 03h STOP anytime we want with virtually any game. Yay!