SWI 0x00 — SoftReset¶
- Entry:
0x000000B4(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¶
Tears down the current program state and restarts execution at either the
external work-RAM entry point (0x02000000) or the cartridge ROM entry point
(0x08000000), selected by a one-byte flag the caller leaves in the top of
IWRAM. Re-initializes the supervisor/IRQ/system stack pointers to their BIOS
defaults, wipes the general-purpose registers, switches to System mode with
IRQ and FIQ enabled, and jumps. Never returns to the caller.
Parameters¶
| Reg | In | Meaning |
|---|---|---|
| (none in registers) | — | Return target is chosen from the byte at 0x03007FFA (see Algorithm). |
Returns¶
Does not return. Control transfers to the selected entry point with r0 = 0.
Clobbered registers¶
All of r0–r12 and lr are overwritten (loaded from the IWRAM mirror area,
effectively cleared if that area holds zero). CPSR is set to System mode,
IRQ+FIQ enabled. SP for SVC/IRQ/SYS modes is reset.
Algorithm¶
- Read a single flag byte from
0x03007FFA(accessed via the IWRAM mirror at0x03FFFFFA, i.e.[0x04000000 - 6]). - Re-initialize the mode stack pointers via the shared stack-setup routine
(
0x000000E0): SVC SP =0x03007FE0, IRQ SP =0x03007FA0, SYS/USR SP =0x03007F00. SPSR of SVC and IRQ modes is zeroed. - Load
r0–r3,r5–r12from the 13-word block ending at0x03007FFC(mirror0x03FFFFFC), which serves to clear those registers. - Choose the branch target:
- flag byte != 0 →
lr = 0x02000000(return into EWRAM), - flag byte == 0 →
lr = 0x08000000(return into ROM). - Set CPSR to System mode with IRQ+FIQ enabled (mode value
0x1F), setr0 = 0, andbx lrto the chosen entry point.
Real constants observed: flag address 0x03007FFA; RAM target 0x02000000;
ROM target 0x08000000; stack tops 0x03007FE0 / 0x03007FA0 / 0x03007F00.
Edge cases & known bugs¶
- The routine does not disable/acknowledge pending interrupts beyond the CPSR
mode switch; any IRQ source left enabled in hardware (IE/IME) plus a stale
handler pointer at
0x03007FFCcan fire immediately after the jump. Callers are expected to have quiesced hardware first. - The register "clear" is really a load from the IWRAM stack/scratch area, so the post-reset register contents depend on whatever was last written there.
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.
With the return-address flag byte 0x03007FFA set to 1, SoftReset restarted
the multiboot worker at 0x02000000 (the link re-synchronised to the fresh
handshake). Memory effects, sentinel-verified: 0x03007E00 was cleared to 0
while 0x03007DFE (2 bytes below) survived — the cleared window is exactly
0x03007E00–0x03007FFF; an EWRAM marker survived untouched. The flag=0
(jump to 0x08000000) path was not exercised (no cartridge present).
Cycle count¶
Not measurable with this harness (the CPU context, including the timers' observer, does not survive the reset).
Open questions (need hardware verification)¶
- Confirm the exact producer of the
0x03007FFAflag byte (typically written by a prior program) and that this BIOS revision does not additionally zero the last0x200bytes of IWRAM as some documentation implies.
GBATEK cross-reference¶
Matches GBATEK SWI 00h: flag at 3007FFA selects RAM vs ROM entry, stacks are
reset, System mode is entered. This doc pins down the concrete stack tops and
the register-clear mechanism (LDM from the IWRAM mirror).