diff options
author | Bad Diode <bd@badd10de.dev> | 2021-06-02 20:20:23 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-06-02 20:20:23 +0200 |
commit | 215465df74a6065f4b0fdf199b8b04454520a398 (patch) | |
tree | f979791df1ae25bf7da9644ce4a0d55d3b8f8fb4 /src/gba/interrupts.c | |
parent | f6686f1e86927f038086023362251ebe78ce5ad6 (diff) | |
download | stepper-215465df74a6065f4b0fdf199b8b04454520a398.tar.gz stepper-215465df74a6065f4b0fdf199b8b04454520a398.zip |
Update the renderer to support a text layer
Diffstat (limited to 'src/gba/interrupts.c')
-rw-r--r-- | src/gba/interrupts.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/gba/interrupts.c b/src/gba/interrupts.c new file mode 100644 index 0000000..3b11335 --- /dev/null +++ b/src/gba/interrupts.c | |||
@@ -0,0 +1,91 @@ | |||
1 | #include "gba.h" | ||
2 | |||
3 | IrsFunc irs_table[] = { | ||
4 | [IRQ_VBLANK ] = NULL, | ||
5 | [IRQ_HBLANK ] = NULL, | ||
6 | [IRQ_VCOUNT ] = NULL, | ||
7 | [IRQ_TIMER_0] = NULL, | ||
8 | [IRQ_TIMER_1] = NULL, | ||
9 | [IRQ_TIMER_2] = NULL, | ||
10 | [IRQ_TIMER_3] = NULL, | ||
11 | [IRQ_SERIAL ] = NULL, | ||
12 | [IRQ_DMA_0 ] = NULL, | ||
13 | [IRQ_DMA_1 ] = NULL, | ||
14 | [IRQ_DMA_2 ] = NULL, | ||
15 | [IRQ_DMA_3 ] = NULL, | ||
16 | [IRQ_KEYPAD ] = NULL, | ||
17 | [IRQ_GAMEPAK] = NULL, | ||
18 | }; | ||
19 | |||
20 | // External irs_main function, has to be written in ARM assembly. | ||
21 | void irs_main(void); | ||
22 | #define IRS_MAIN *(IrsFunc*)(0x03007FFC) | ||
23 | |||
24 | void | ||
25 | irq_enable(IrqIndex idx) { | ||
26 | switch (idx) { | ||
27 | case IRQ_VBLANK: { DISP_STATUS |= DISP_VBLANK_IRQ; } break; | ||
28 | case IRQ_HBLANK: { DISP_STATUS |= DISP_HBLANK_IRQ; } break; | ||
29 | case IRQ_VCOUNT: { DISP_STATUS |= DISP_VCOUNT_IRQ; } break; | ||
30 | case IRQ_TIMER_0: { TIMER_CTRL_0 |= TIMER_CTRL_IRQ; } break; | ||
31 | case IRQ_TIMER_1: { TIMER_CTRL_1 |= TIMER_CTRL_IRQ; } break; | ||
32 | case IRQ_TIMER_2: { TIMER_CTRL_2 |= TIMER_CTRL_IRQ; } break; | ||
33 | case IRQ_TIMER_3: { TIMER_CTRL_3 |= TIMER_CTRL_IRQ; } break; | ||
34 | case IRQ_SERIAL: { /* TODO: Set REG_SERIAL? */ } break; | ||
35 | case IRQ_DMA_0: { DMA_CTRL(0) |= DMA_IRQ; } break; | ||
36 | case IRQ_DMA_1: { DMA_CTRL(1) |= DMA_IRQ; } break; | ||
37 | case IRQ_DMA_2: { DMA_CTRL(2) |= DMA_IRQ; } break; | ||
38 | case IRQ_DMA_3: { DMA_CTRL(3) |= DMA_IRQ; } break; | ||
39 | case IRQ_KEYPAD: { KEY_CTRL |= KEY_IRQ; } break; | ||
40 | case IRQ_GAMEPAK: { /* Nothing to do here...*/ } break; | ||
41 | } | ||
42 | IRQ_ENABLE |= (1 << idx); | ||
43 | } | ||
44 | |||
45 | void | ||
46 | irq_disable(IrqIndex idx) { | ||
47 | switch (idx) { | ||
48 | case IRQ_VBLANK: { DISP_STATUS &= ~DISP_VBLANK_IRQ; } break; | ||
49 | case IRQ_HBLANK: { DISP_STATUS &= ~DISP_HBLANK_IRQ; } break; | ||
50 | case IRQ_VCOUNT: { DISP_STATUS &= ~DISP_VCOUNT_IRQ; } break; | ||
51 | case IRQ_TIMER_0: { TIMER_CTRL_0 &= ~TIMER_CTRL_IRQ; } break; | ||
52 | case IRQ_TIMER_1: { TIMER_CTRL_1 &= ~TIMER_CTRL_IRQ; } break; | ||
53 | case IRQ_TIMER_2: { TIMER_CTRL_2 &= ~TIMER_CTRL_IRQ; } break; | ||
54 | case IRQ_TIMER_3: { TIMER_CTRL_3 &= ~TIMER_CTRL_IRQ; } break; | ||
55 | case IRQ_SERIAL: { /* TODO: Set REG_SERIAL? */ } break; | ||
56 | case IRQ_DMA_0: { DMA_CTRL(0) &= ~DMA_IRQ; } break; | ||
57 | case IRQ_DMA_1: { DMA_CTRL(1) &= ~DMA_IRQ; } break; | ||
58 | case IRQ_DMA_2: { DMA_CTRL(2) &= ~DMA_IRQ; } break; | ||
59 | case IRQ_DMA_3: { DMA_CTRL(3) &= ~DMA_IRQ; } break; | ||
60 | case IRQ_KEYPAD: { KEY_CTRL &= ~KEY_IRQ; } break; | ||
61 | case IRQ_GAMEPAK: { /* Nothing to do here...*/ } break; | ||
62 | } | ||
63 | IRQ_ENABLE &= ~(1 << idx); | ||
64 | } | ||
65 | |||
66 | void | ||
67 | irs_set(IrqIndex idx, IrsFunc func) { | ||
68 | // Store IRQ_CTRL status and disable interrupts for now. | ||
69 | u16 irq_ctrl = IRQ_CTRL; | ||
70 | IRQ_CTRL = 0; | ||
71 | |||
72 | // Update the IRS table and enable/disable the given IRQ. | ||
73 | irs_table[idx] = func; | ||
74 | if (func == NULL) { | ||
75 | irq_disable(idx); | ||
76 | } else { | ||
77 | irq_enable(idx); | ||
78 | } | ||
79 | |||
80 | // Restore previous irq_ctrl. | ||
81 | IRQ_CTRL = irq_ctrl; | ||
82 | } | ||
83 | |||
84 | void | ||
85 | irq_init(void) { | ||
86 | IRS_MAIN = irs_main; | ||
87 | IRQ_CTRL = 1; | ||
88 | } | ||
89 | |||
90 | void | ||
91 | irs_stub(void) {} | ||