diff --git a/src/machine/machine_gameboyadvance.go b/src/machine/machine_gameboyadvance.go index 7c6ffcb8..6913205f 100644 --- a/src/machine/machine_gameboyadvance.go +++ b/src/machine/machine_gameboyadvance.go @@ -8,6 +8,25 @@ import ( "unsafe" ) +// Interrupt numbers as used on the GameBoy Advance. Register them with +// runtime/interrupt.New. +const ( + IRQ_VBLANK = 0 + IRQ_HBLANK = 1 + IRQ_VCOUNT = 2 + IRQ_TIMER0 = 3 + IRQ_TIMER1 = 4 + IRQ_TIMER2 = 5 + IRQ_TIMER3 = 6 + IRQ_COM = 7 + IRQ_DMA0 = 8 + IRQ_DMA1 = 9 + IRQ_DMA2 = 10 + IRQ_DMA3 = 11 + IRQ_KEYPAD = 12 + IRQ_GAMEPAK = 13 +) + // Make it easier to directly write to I/O RAM. var ioram = (*[0x400]volatile.Register8)(unsafe.Pointer(uintptr(0x04000000))) diff --git a/src/runtime/interrupt/interrupt_gameboyadvance.go b/src/runtime/interrupt/interrupt_gameboyadvance.go new file mode 100644 index 00000000..c25afc14 --- /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<