File tree Expand file tree Collapse file tree 5 files changed +77
-6
lines changed Expand file tree Collapse file tree 5 files changed +77
-6
lines changed Original file line number Diff line number Diff line change @@ -8,6 +8,25 @@ import (
8
8
"unsafe"
9
9
)
10
10
11
+ // Interrupt numbers as used on the GameBoy Advance. Register them with
12
+ // runtime/interrupt.New.
13
+ const (
14
+ IRQ_VBLANK = 0
15
+ IRQ_HBLANK = 1
16
+ IRQ_VCOUNT = 2
17
+ IRQ_TIMER0 = 3
18
+ IRQ_TIMER1 = 4
19
+ IRQ_TIMER2 = 5
20
+ IRQ_TIMER3 = 6
21
+ IRQ_COM = 7
22
+ IRQ_DMA0 = 8
23
+ IRQ_DMA1 = 9
24
+ IRQ_DMA2 = 10
25
+ IRQ_DMA3 = 11
26
+ IRQ_KEYPAD = 12
27
+ IRQ_GAMEPAK = 13
28
+ )
29
+
11
30
// Make it easier to directly write to I/O RAM.
12
31
var ioram = (* [0x400 ]volatile.Register8 )(unsafe .Pointer (uintptr (0x04000000 )))
13
32
Original file line number Diff line number Diff line change
1
+ // +build gameboyadvance
2
+
3
+ package interrupt
4
+
5
+ import (
6
+ "runtime/volatile"
7
+ "unsafe"
8
+ )
9
+
10
+ var (
11
+ regInterruptEnable = (* volatile .Register16 )(unsafe .Pointer (uintptr (0x4000200 )))
12
+ regInterruptRequestFlags = (* volatile .Register16 )(unsafe .Pointer (uintptr (0x4000202 )))
13
+ regInterruptMasterEnable = (* volatile .Register16 )(unsafe .Pointer (uintptr (0x4000208 )))
14
+ )
15
+
16
+ // Enable enables this interrupt. Right after calling this function, the
17
+ // interrupt may be invoked if it was already pending.
18
+ func (irq Interrupt ) Enable () {
19
+ regInterruptEnable .SetBits (1 << uint (irq .num ))
20
+ }
21
+
22
+ //export handleInterrupt
23
+ func handleInterrupt () {
24
+ flags := regInterruptRequestFlags .Get ()
25
+ for i := 0 ; i < 14 ; i ++ {
26
+ if flags & (1 << uint (i )) != 0 {
27
+ regInterruptRequestFlags .Set (1 << uint (i )) // acknowledge interrupt
28
+ callInterruptHandler (i )
29
+ }
30
+ }
31
+ }
32
+
33
+ // callInterruptHandler is a compiler-generated function that calls the
34
+ // appropriate interrupt handler for the given interrupt ID.
35
+ //go:linkname callInterruptHandler runtime.callInterruptHandler
36
+ func callInterruptHandler (id int )
Original file line number Diff line number Diff line change 3
3
package runtime
4
4
5
5
import (
6
+ _ "runtime/interrupt" // make sure the interrupt handler is defined
6
7
"unsafe"
7
8
)
8
9
Original file line number Diff line number Diff line change 1
1
OUTPUT_ARCH (arm)
2
2
ENTRY(_start)
3
3
4
+ /* Note: iwram is reduced by 96 bytes because the last part of that RAM
5
+ * (starting at 0x03007FA0) is used for interrupt handling.
6
+ */
4
7
MEMORY {
5
- ewram : ORIGIN = 0x02000000 , LENGTH = 256K /* on-board work RAM (2 wait states) */
6
- iwram : ORIGIN = 0x03000000 , LENGTH = 32K /* in-chip work RAM (faster) */
7
- rom : ORIGIN = 0x08000000 , LENGTH = 32M /* flash ROM */
8
+ ewram : ORIGIN = 0x02000000 , LENGTH = 256K /* on-board work RAM (2 wait states) */
9
+ iwram : ORIGIN = 0x03000000 , LENGTH = 32K- 96 /* in-chip work RAM (faster) */
10
+ rom : ORIGIN = 0x08000000 , LENGTH = 32M /* flash ROM */
8
11
}
9
12
10
13
__stack_size_irq = 1K;
Original file line number Diff line number Diff line change @@ -17,17 +17,29 @@ _start:
17
17
. byte 0x00 , 0x00 // Checksum ( 80000BEh )
18
18
19
19
start_vector:
20
- mov r0 , # 0x4000000 // REG_BASE
21
- str r0 , [ r0 , # 0x208 ]
22
-
20
+ // Configure stacks
23
21
mov r0 , # 0x12 // Switch to IRQ Mode
24
22
msr cpsr , r0
25
23
ldr sp , =_stack_top_irq // Set IRQ stack
26
24
mov r0 , # 0x1f // Switch to System Mode
27
25
msr cpsr , r0
28
26
ldr sp , =_stack_top // Set user stack
29
27
28
+ // Configure interrupt handler
29
+ mov r0 , # 0x4000000 // REG_BASE
30
+ ldr r1 , =handleInterruptARM
31
+ str r1 , [ r0 , # - 4 ] // actually storing to 0x03007FFC due to mirroring
32
+
33
+ // Enable interrupts
34
+ mov r1 , # 1
35
+ str r1 , [ r0 , # 0x208 ] // 0x04000208 Interrupt Master Enable
36
+
30
37
// Jump to user code (switching to Thumb mode)
31
38
ldr r3 , =main
32
39
bx r3
33
40
41
+ // Small interrupt handler th at immediately jumps to a function defined in the
42
+ // program ( in Thumb) for further processing.
43
+ handleInterruptARM:
44
+ ldr r0 , =handleInterrupt
45
+ bx r0
You can’t perform that action at this time.
0 commit comments