diff options
author | Ayke van Laethem <[email protected]> | 2020-01-06 11:50:41 +0100 |
---|---|---|
committer | Ron Evans <[email protected]> | 2020-01-27 21:56:17 +0100 |
commit | 8687f3f8f40f69bea64e8a1a836a5eb49b72de92 (patch) | |
tree | a3b48b641bf7c4803d88018a6237d820854fd71c /src/runtime | |
parent | f14127be7629eb131add86f97acadc1840ecc926 (diff) | |
download | tinygo-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.go | 36 | ||||
-rw-r--r-- | src/runtime/runtime_arm7tdmi.go | 1 |
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" ) |