An interrupt is a mechanism for some other portion of Mappy VM to interrupt the current program flow, so the program can attend to what caused the interruption. The main subsystems of Mappy VM (video hardware, DMA, timers, and networking) can generate interrupt requests (IRQs) if configured to do so. These IRQs are evaluated against the IME and IE registers explained below to set flags in the IF register and generate the IRQ input to the CPU. For even more flexibility, the CPU itself can ignore IRQs indefinitely when the I bit in the CPSR is set.
Interrupts and other CPU exceptions force the CPU to resume execution at exception vectors that are within the BIOS. Since the BIOS deals with the interrupt and the special conditions that the CPU requires to return from exceptions, writing an interrupt handler is simplified and can even be done purely in C or C++.
The BIOS handler loads an address from 0x03007FFC
and branches to it after preserving r0-r3, r12, and lr. This is the normal ARM calling convention, and your interrupt handler should return using a BX LR
. After this, the BIOS restores the saved registers and returns to the previously interrupted code. There is a predefined macro INTR_ADDRESS to store the address of the user interrupt handler in 0x03007FFC
.
Thus, the order of events looks like:
0x18
in ARM mode, and the BIOS saves important registers0x03007FFC
) is called in ARM modeBX LR
Offset | Name | Type | F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
$208 | IME | Read Write |   | Enabled |
Offset | Name | Type | F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
$200 | IE | Read Write |   | Cartridge | Joypad | DMA 3 | DMA 2 | DMA 1 | DMA 0 | Network | Timer 3 | Timer 2 | Timer 1 | Timer 0 | Y-trigger | H-blank | V-blank |
IRQ_VBLANK, IRQ_HBLANK, IRQ_YTRIGGER, IRQ_TIMER0, IRQ_TIMER1, IRQ_TIMER2, IRQ_TIMER3, IRQ_NETWORK, IRQ_DMA0, IRQ_DMA1, IRQ_DMA2, IRQ_DMA3, IRQ_JOYPAD, and IRQ_CARTRIDGE
Offset | Name | Type | F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
$202 | IF | Read Write* |   | Cartridge | Joypad | DMA 3 | DMA 2 | DMA 1 | DMA 0 | Network | Timer 3 | Timer 2 | Timer 1 | Timer 0 | Y-trigger | H-blank | V-blank |
IF |= IF
Example: A very simple interrupt handler.
void vblankHandler(void) { dprintf("This code was called by an interrupt!\n"); // Clear the v-blank IRQ bit in IF IF |= IRQ_VBLANK; } void configureInterrupts(void) { DISP_SR |= DISP_SR_VBLANK_IRQ; IE |= IRQ_VBLANK; INTR_ADDRESS = vblankHandler; IME = 1; } // Note that although the handler is called vblankHandler, there can only be // one interrupt handler for all interrupts. You can determine which interrupts // have occured by looking at the IF register.
Copyright © 2001 to 2002, Bottled Light, Inc.