aboutsummaryrefslogtreecommitdiffstats
path: root/src/irs.s
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-18 16:40:24 +0200
committerBad Diode <bd@badd10de.dev>2021-05-18 16:40:24 +0200
commit0c7265cf0de9d4ec95d28c5e103c00a63f4a1697 (patch)
tree4a1145e849e078395430a8d718c4bd69a06fb29f /src/irs.s
downloaduxngba-0c7265cf0de9d4ec95d28c5e103c00a63f4a1697.tar.gz
uxngba-0c7265cf0de9d4ec95d28c5e103c00a63f4a1697.zip
Proof of concept of UXN on the GBA
Diffstat (limited to 'src/irs.s')
-rw-r--r--src/irs.s89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/irs.s b/src/irs.s
new file mode 100644
index 0000000..5cccb6e
--- /dev/null
+++ b/src/irs.s
@@ -0,0 +1,89 @@
1 .file "irs.s"
2 .extern irs_table;
3 .section .iwram, "ax", %progbits
4 .arm
5 .align
6 .global irs_main
7
8irs_main:
9 @ Get the contents of IRQ_ENABLE, IRQ_ACK, and IRQ_CTRL
10 ldr ip, mem_irq_base_reg @ ip = (IRQ_ENABLE << 16) | IRQ_ACK
11 ldr r0, [ip] @ r0 = irq_enable
12 and r1, r0, r0, lsr #16 @ r1 = irq_enable & irq_ack
13
14 @ Disable IRQ_CTRL for now.
15 mov r3, #0 @ r3 = 0
16 strh r3, [ip, #8] @ *(ip + 0x8) = r3
17
18 @ r0 = irs_table address pointer
19 @ r2 = tmp
20 @ r3 = 0 (for r3; r3 < 14; r3++)
21 ldr r0, = irs_table
22irs_main_fp_search:
23 @ Check that the current index is an active IRQ.
24 mov r2, #1
25 and r2, r1, r2, lsl r3
26 cmp r2, #0
27 beq irs_main_fp_search_not_enabled
28
29 @ Extract the function pointer for this IRS if available.
30 ldr r2, [r0]
31 cmp r2, #0
32 bne irs_main_handle_irs
33
34irs_main_fp_search_not_enabled:
35 add r0, r0, #4
36 add r3, #1
37 cmp r3, #14
38 bne irs_main_fp_search
39 b irs_main_exit
40
41irs_main_handle_irs:
42 @ r2: Contains IRQ function pointer.
43 @ r3: Stores the IRQ index.
44
45 @ Acknowledge that we are handling this interrupt writing to IRQ_ACK and
46 @ IRQ_ACK_BIOS.
47 mov r0, #1
48 lsl r0, r0, r3
49 strh r0, [ip, #2]
50 ldr r1, mem_irq_ack_bios @ r1 = IRQ_ACK_BIOS
51 str r0, [r1]
52
53 @ Store the SPSR in one of the free registers and save it along with the
54 @ return pointer.
55 mrs r3, spsr
56 stmfd sp!, {r3, lr}
57
58 @ Set CPU to system mode
59 mrs r3, cpsr
60 bic r3, r3, #0xDF
61 orr r3, r3, #0x1F
62 msr cpsr, r3
63
64 @ Call isr function pointer
65 stmfd sp!, {lr}
66 mov lr, pc
67 bx r2
68 ldmfd sp!, {lr}
69
70 @ Set CPU to irq mode
71 mrs r3, cpsr
72 bic r3, r3, #0xDF
73 orr r3, r3, #0x92
74 msr cpsr, r3
75
76 @ Restore the SPSR and the registers.
77 ldmfd sp!, {r3, lr}
78 msr spsr, r3
79
80irs_main_exit:
81 @ Restore IRQ_CTRL.
82 mov r3, #1 @ r3 = 0
83 strh r3, [ip, #8] @ *(ip + 0x8) = r3
84 bx lr
85
86mem_irq_base_reg:
87 .word 0x04000200 @ IRQ_ENABLE
88mem_irq_ack_bios:
89 .word 0x03007FF8 @ IRQ_ACK_BIOS