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.
This commit is contained in:
Ayke van Laethem
2020-01-06 11:50:41 +01:00
committed by Ron Evans
parent f14127be76
commit 8687f3f8f4
5 changed files with 77 additions and 6 deletions
@@ -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)
+1
View File
@@ -3,6 +3,7 @@
package runtime
import (
_ "runtime/interrupt" // make sure the interrupt handler is defined
"unsafe"
)