BIOS IRQ Dispatcher, Boot/Reset Path, and IWRAM State Area¶
- Status: draft (static analysis only)
This note documents the low-level machinery the reset/halt/wait SWIs interact with: the exception vectors, the IRQ dispatcher, the boot/reset entry, the SWI dispatcher, and the reserved IWRAM state region near the top of on-chip RAM.
Exception vectors (0x00–0x1C)¶
| Addr | Vector | Target |
|---|---|---|
| 0x00 | Reset | 0x68 |
| 0x04 | Undefined | 0x1C |
| 0x08 | SWI | 0x140 |
| 0x0C | Prefetch Abort | 0x1C |
| 0x10 | Data Abort | 0x1C |
| 0x14 | (reserved) | 0x1C |
| 0x18 | IRQ | 0x128 |
| 0x1C | FIQ | 0x1C |
IWRAM state area (top of on-chip WRAM)¶
On-chip WRAM is 0x03000000–0x03007FFF (32 KB) and is mirrored every 0x8000
bytes; the BIOS frequently reaches it via the mirror just below the I/O base
(0x04000000), e.g. [0x04000000 - 8] == 0x03007FF8. The reserved top 0x200
bytes hold:
| Address | Purpose |
|---|---|
0x03007F00 |
Default USER/SYSTEM stack top (grows down) |
0x03007FA0 |
Default IRQ stack top (grows down) |
0x03007FE0 |
Default SVC (supervisor) stack top (grows down) |
0x03007FF8 |
BIOS interrupt-flag word (16-bit). Polled and acknowledged by IntrWait/VBlankIntrWait; must be set by the user IRQ handler — the BIOS dispatcher does not write it. |
0x03007FFA |
SoftReset (SWI 00h) return-target flag byte: 0 → ROM 0x08000000, nonzero → RAM 0x02000000. |
0x03007FFC |
User IRQ handler pointer, invoked by the BIOS IRQ dispatcher. |
Boot / reset path (0x68, shared with HardReset 0x8C)¶
Reset vector branches to 0x68, which checks the low byte of POSTFLG
(0x04000300). If it reads 1 (post-boot / soft-reset marker), it masks IRQ+FIQ
in CPSR and diverts to the exception handler at 0x1C; otherwise it falls into
the cold-boot sequence at 0x8C (also reached as SWI 26h HardReset):
- Enter System mode, IRQ+FIQ disabled (CPSR mode value
0xDF). - Write
0toREG_IME(0x04000208). - Initialize the three mode stacks via the routine at
0xE0: SVC =0x03007FE0, IRQ =0x03007FA0, SYS/USR =0x03007F00. - Store a default IRQ handler pointer into
0x03007FFC. - Jump to the BIOS boot/post-boot routine at
0x00001929(intro + cartridge launch).
Exception handler (0x1C, Undefined/Abort/FIQ/reserved)¶
Saves state, then checks a marker byte in the cartridge header at 0x0800009C
for the value 0xA5. If present, it dispatches to a cartridge-supplied debug
exception handler (addresses 0x09FE2000 / 0x09FFC000 selected by a header
bit); otherwise it restores state and returns. This is a developer/debug hook,
not used by normal cartridges.
IRQ dispatcher (0x128)¶
- Push
{r0-r3, ip, lr}onto the IRQ stack. - Load the user handler pointer from
0x03007FFC(via mirror[0x04000000 - 4]) and jump to it with return address set. - On return, pop the saved registers and return from IRQ (
subs pc, lr, #4).
The dispatcher does not read/acknowledge REG_IF or update the
0x03007FF8 flag word — that is entirely the responsibility of the installed
user handler. This is why IntrWait/VBlankIntrWait only work when the game's
handler ORs serviced-interrupt bits into 0x03007FF8.
SWI dispatcher (0x140)¶
- Push
{fp, ip, lr}. - Read the SWI comment-field byte from
[lr - 2](bits 16–23 of the ARMSWIinstruction) to get the SWI numberN. - Index the jump table at
0x000001C8: handler =table[N]. Odd (low bit set) → THUMB entry, even → ARM. - Switch to System mode (preserving the caller's I flag from SPSR) so handlers run on the user stack and can be re-entered.
bxto the handler; on return, restore SVC mode, SPSR, and the saved registers, then return from the SWI (movs pc, lr).
Real constants: jump table base 0x000001C8; POSTFLG 0x04000300;
REG_IME 0x04000208; boot routine 0x00001929.
Open questions (need hardware verification)¶
- Exact behavior when
POSTFLG == 1at reset (diversion to0x1C). - Confirm the cartridge debug-handler hook addresses (
0x09FE2000/0x09FFC000) and the header marker semantics at0x0800009C/0x080000B4.