SWI 0x05 — VBlankIntrWait¶
- Entry:
0x00000328(ARM) - Status: verified (hardware-checked 2026-07-08: fixture-driven runs on real GBA via the worker's no-blacklist opcode; see Hardware verification section)
Summary¶
Convenience wrapper around IntrWait (SWI 04h) that waits for the next VBlank
interrupt. It simply preloads the IntrWait parameters and falls through into the
IntrWait code, so all of IntrWait's behavior (BIOS flag word at 0x03007FF8,
acknowledge-by-clear, dependency on the user IRQ handler) applies.
Parameters¶
None from the caller. Internally sets: | Reg | Value | Meaning | |-----|-------|---------| | r0 | 1 | discard already-pending flags; wait for a new interrupt | | r1 | 1 | interrupt mask = bit0 = VBlank |
Returns¶
Returns after the next VBlank interrupt has been serviced and acknowledged.
Clobbered registers¶
Same as IntrWait: r0–r4, ip (r12); r4 restored.
Algorithm¶
- Set
r0 = 1(discard old flags → wait for a fresh VBlank). - Set
r1 = 1(VBlank bit). - Fall through directly into IntrWait at
0x00000330. Seeswi_04_intrwait.mdfor the full Halt/poll/acknowledge loop.
Real constants observed: VBlank mask 0x0001; shares IntrWait's 0x03007FF8,
REG_IME 0x04000208, HALTCNT 0x04000301.
Edge cases & known bugs¶
- Requires the VBlank interrupt to be enabled and the user IRQ handler to set
0x03007FF8. Specifically:DISPSTATVBlank IRQ enable (0x04000004bit3),REG_IEbit0, andREG_IMEmust be configured, and the installed handler at0x03007FFCmust OR bit0 into0x03007FF8. Otherwise VBlankIntrWait hangs. - Because
r0 = 1, it always waits for a new VBlank even if one just occurred.
Hardware verification (2026-07-08)¶
Fixture-driven runs via the worker's no-blacklist opcode (swf), with
wake sources / handlers installed through CpuSet pokes. Raw data:
results/blacklist_fixtures1.csv.
Fixture: DISPSTAT bit3 (VBlank IRQ enable) + IE bit0 + the minimal user
handler. Three runs returned after 1.94 ms, 7.34 ms, and 13.55 ms — always
within one frame (16.74 ms), landing on the next VBlank edge (phase-dependent,
as expected). Forced blank (DISPCNT.7) does not suppress VBlank IRQs.
Cycle count¶
Phase-dependent: 32,552 / 123,218 / 227,255 raw cycles observed — uniformly distributed within one 280,896-cycle frame.
Open questions (need hardware verification)¶
- None specific beyond those noted for IntrWait.
GBATEK cross-reference¶
Matches GBATEK SWI 05h VBlankIntrWait, documented as IntrWait(1, 1).
Confirmed here as a literal fall-through into the IntrWait entry.