aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/runtime
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2020-01-06 11:50:41 +0100
committerRon Evans <[email protected]>2020-01-27 21:56:17 +0100
commit8687f3f8f40f69bea64e8a1a836a5eb49b72de92 (patch)
treea3b48b641bf7c4803d88018a6237d820854fd71c /src/runtime
parentf14127be7629eb131add86f97acadc1840ecc926 (diff)
downloadtinygo-8687f3f8f40f69bea64e8a1a836a5eb49b72de92.tar.gz
tinygo-8687f3f8f40f69bea64e8a1a836a5eb49b72de92.zip
targets/gba: implement interrupt handler
Thanks to Kyle Lemons for the inspiration and original design. The implementation in this commit is very different however, building on top of the software vectoring needed in RISC-V. The result is a flexible interrupt handler that does not take up any RAM for configuration.
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/interrupt/interrupt_gameboyadvance.go36
-rw-r--r--src/runtime/runtime_arm7tdmi.go1
2 files changed, 37 insertions, 0 deletions
diff --git a/src/runtime/interrupt/interrupt_gameboyadvance.go b/src/runtime/interrupt/interrupt_gameboyadvance.go
new file mode 100644
index 000000000..c25afc14b
--- /dev/null
+++ b/src/runtime/interrupt/interrupt_gameboyadvance.go
@@ -0,0 +1,36 @@
+// +build gameboyadvance
+
+package interrupt
+
+import (
+ "runtime/volatile"
+ "unsafe"
+)
+
+var (
+ regInterruptEnable = (*volatile.Register16)(unsafe.Pointer(uintptr(0x4000200)))
+ regInterruptRequestFlags = (*volatile.Register16)(unsafe.Pointer(uintptr(0x4000202)))
+ regInterruptMasterEnable = (*volatile.Register16)(unsafe.Pointer(uintptr(0x4000208)))
+)
+
+// Enable enables this interrupt. Right after calling this function, the
+// interrupt may be invoked if it was already pending.
+func (irq Interrupt) Enable() {
+ regInterruptEnable.SetBits(1 << uint(irq.num))
+}
+
+//export handleInterrupt
+func handleInterrupt() {
+ flags := regInterruptRequestFlags.Get()
+ for i := 0; i < 14; i++ {
+ if flags&(1<<uint(i)) != 0 {
+ regInterruptRequestFlags.Set(1 << uint(i)) // acknowledge interrupt
+ callInterruptHandler(i)
+ }
+ }
+}
+
+// callInterruptHandler is a compiler-generated function that calls the
+// appropriate interrupt handler for the given interrupt ID.
+//go:linkname callInterruptHandler runtime.callInterruptHandler
+func callInterruptHandler(id int)
diff --git a/src/runtime/runtime_arm7tdmi.go b/src/runtime/runtime_arm7tdmi.go
index 150ecdaa7..cff5bca36 100644
--- a/src/runtime/runtime_arm7tdmi.go
+++ b/src/runtime/runtime_arm7tdmi.go
@@ -3,6 +3,7 @@
package runtime
import (
+ _ "runtime/interrupt" // make sure the interrupt handler is defined
"unsafe"
)