tinygo/src/machine/machine_gameboyadvance.go
Ayke van Laethem 8687f3f8f4 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.
2020-01-27 21:56:17 +01:00

63 строки
1,4 КиБ
Go

// +build gameboyadvance
package machine
import (
"image/color"
"runtime/volatile"
"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)))
type PinMode uint8
// Set has not been implemented.
func (p Pin) Set(value bool) {
// do nothing
}
var Display = FramebufDisplay{(*[160][240]volatile.Register16)(unsafe.Pointer(uintptr(0x06000000)))}
type FramebufDisplay struct {
port *[160][240]volatile.Register16
}
func (d FramebufDisplay) Configure() {
// Write into the I/O registers, setting video display parameters.
ioram[0].Set(0x03) // Use video mode 3 (in BG2, a 16bpp bitmap in VRAM)
ioram[1].Set(0x04) // Enable BG2 (BG0 = 1, BG1 = 2, BG2 = 4, ...)
}
func (d FramebufDisplay) Size() (x, y int16) {
return 240, 160
}
func (d FramebufDisplay) SetPixel(x, y int16, c color.RGBA) {
d.port[y][x].Set(uint16(c.R)&0x1f | uint16(c.G)&0x1f<<5 | uint16(c.B)&0x1f<<10)
}
func (d FramebufDisplay) Display() error {
// Nothing to do here.
return nil
}