1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
/**
* @file bsp_irq_asm.S
*
* Intererrupt handler for GameBoy Advance.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#define __asm__
#include <asm_macros.h>
#include <gba_registers.h>
#include <arm_mode_bits.h>
/* @cond INCLUDE_ASM */
/**
* Execute interrupt handler
* function void ExecuteITHandler(void)
*
* Look at interrupt status register to determine source.
* From source, determine offset into expanded vector table
* and load handler address into r0.
* irq_vector_table is defined in linkcmds
*
*/
.align
/* .section .iwram */
PUBLIC_ARM_FUNCTION(ExecuteITHandler)
ldr r1, =GBA_REG_IE_ADDR
ldrh r1, [r1]
ldr r2, =GBA_REG_IF_ADDR
ldrh r2, [r2]
and r3, r1, r2 /* only look at interrupts which are enabled */
check_lcdv:
tst r3, #0x0001
beq check_lcdh
ldr r0, =(irq_vector_table + (4 * 0)) /* load the vector number */
ldr r3,=0x0001
b get_handler
check_lcdh:
tst r3, #0x0002
beq check_lcdvc
ldr r0, =(irq_vector_table + (4 * 1)) /* load the vector number */
ldr r3,=0x0002
b get_handler
check_lcdvc:
tst r3, #0x0004
beq check_t0
ldr r0, =(irq_vector_table + (4 * 2)) /* load the vector number */
ldr r3,=0x0004
b get_handler
check_t0:
tst r3, #0x0008
beq check_t1
ldr r0, =(irq_vector_table + (4 * 3)) /* load the vector number */
ldr r3,=0x0008
b get_handler
check_t1:
tst r3, #0x0010
beq check_t2
ldr r0, =(irq_vector_table + (4 * 4)) /* load the vector number */
ldr r3,=0x0010
b get_handler
check_t2:
tst r3, #0x0020
beq check_t3
ldr r0, =(irq_vector_table + (4 * 5)) /* load the vector number */
ldr r3,=0x0020
b get_handler
check_t3:
tst r3, #0x0040
beq check_ser
ldr r0, =(irq_vector_table + (4 * 6)) /* load the vector number */
ldr r3,=0x0040
b get_handler
check_ser:
tst r3, #0x0080
beq check_dma0
ldr r0, =(irq_vector_table + (4 * 7)) /* load the vector number */
ldr r3,=0x0080
b get_handler
check_dma0:
tst r3, #0x0100
beq check_dma1
ldr r0, =(irq_vector_table + (4 * 8)) /* load the vector number */
ldr r3,=0x0100
b get_handler
check_dma1:
tst r3, #0x0200
beq check_dma2
ldr r0, =(irq_vector_table + (4 * 9)) /* load the vector number */
ldr r3,=0x0200
b get_handler
check_dma2:
tst r3, #0x0400
beq check_dma3
ldr r0, =(irq_vector_table + (4 * 10)) /* load the vector number */
ldr r3,=0x0400
b get_handler
check_dma3:
tst r3, #0x0800
beq check_keypad
ldr r0, =(irq_vector_table + (4 * 11)) /* load the vector number */
ldr r3,=0x0800
b get_handler
check_keypad:
tst r3, #0x1000
beq check_gamepak
ldr r0, =(irq_vector_table + (4 * 12)) /* load the vector number */
ldr r3,=0x1000
b get_handler
check_gamepak:
tst r3, #0x2000
beq IRQ_NoInterrupt
ldr r0, =(irq_vector_table + (4 * 13)) /* load the vector number */
ldr r3,=0x2000
b get_handler
unknown_irq:
ldr r0, =(default_int_handler) /* Unknown Interrupt? */
ldr r3,=0x0000
get_handler:
ldr r0, [r0] /* extract the IT handler */
ldr r2, =GBA_REG_IF_ADDR /* Clear IF */
strh r3, [r2]
/*
* re-enable interrupts at processor level
*/
mrs r1, cpsr
bic r1, r1, #Int_Bits
msr cpsr, r1
stmdb sp!,{lr}
ldr lr, =IRQ_return /* prepare the return from handler */
mov pc, r0 /* EXECUTE INT HANDLER */
IRQ_return:
ldmia sp!,{lr}
/*
* disable interrupts_again
*/
mrs r0, cpsr
orr r0, r0, #Int_Bits
msr cpsr, r0
IRQ_NoInterrupt:
/* return to the "main" interrupt handler */
mov pc, lr
LABEL_END(ExecuteITHandler)
/* @endcond */
|