SWI 0x27 — CustomHalt¶
- Entry:
0x000001AC(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¶
Writes a caller-supplied value directly to the low-power control register
HALTCNT (0x04000301). This is the shared tail used by both Halt (SWI 02h,
value 0x00) and Stop (SWI 03h, value 0x80); calling it directly lets the
program pick the HALTCNT byte itself.
Parameters¶
| Reg | In | Meaning |
|---|---|---|
| r2 | HALTCNT value | Byte stored to 0x04000301. 0x00 = Halt, 0x80 = Stop; other values are hardware-defined. |
Returns¶
Returns after the store.
Clobbered registers¶
ip (r12) is used as scratch (loaded with the I/O base 0x04000000).
Algorithm¶
- Load the I/O base
0x04000000intoip. - Store the byte in
r2to HALTCNT at0x04000301. - Return.
Real constants observed: HALTCNT byte address 0x04000301.
Edge cases & known bugs¶
- Note the parameter register is
r2, notr0. Because Halt and Stop reach this same code by pre-loadingr2, a direct CustomHalt caller must place the desired value inr2. - Same wake-source caveats as Halt/Stop apply depending on the value written.
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.
r2 = 0 (halt path) with the Halt fixture: slept 28,712,181 cycles
(~1711 ms) of a 4-second timer period and woke on the TM2 IRQ with IME = 0
— behavior identical to SWI 0x02 Halt (68 cycles when the interrupt was
already pending). The r2 = 0x80 (stop) path was not run separately; see SWI
0x03 for stop-mode behavior.
Cycle count¶
68 cycles (raw) for the pending-interrupt immediate return — 4 cycles less than Halt (0x02), consistent with the shorter dispatch path.
Open questions (need hardware verification)¶
- Enumerate the effect of HALTCNT values other than
0x00/0x80on real hardware.
GBATEK cross-reference¶
Matches GBATEK SWI 27h CustomHalt. This doc pins the parameter register as r2
and confirms it is the physical tail shared by Halt (02h) and Stop (03h).