device/gba: add mostly complete hand-written register definitions
Signed-off-by: deadprogram <ron@hybridgroup.com>
Этот коммит содержится в:
родитель
833c91fceb
коммит
4f7864b757
1 изменённых файлов: 474 добавлений и 0 удалений
474
src/device/gba/gba.go
Обычный файл
474
src/device/gba/gba.go
Обычный файл
|
@ -0,0 +1,474 @@
|
|||
// Hand written file mostly derived from https://problemkaputt.de/gbatek.htm
|
||||
|
||||
//go:build gameboyadvance
|
||||
|
||||
package gba
|
||||
|
||||
import (
|
||||
"runtime/volatile"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Interrupt numbers.
|
||||
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
|
||||
)
|
||||
|
||||
// Peripherals
|
||||
var (
|
||||
// Display registers
|
||||
DISP = (*DISP_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0000)))
|
||||
|
||||
// Background control registers
|
||||
BGCNT0 = (*BGCNT_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0008)))
|
||||
BGCNT1 = (*BGCNT_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x000A)))
|
||||
BGCNT2 = (*BGCNT_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x000C)))
|
||||
BGCNT3 = (*BGCNT_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x000E)))
|
||||
|
||||
BG0 = (*BG_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0010)))
|
||||
BG1 = (*BG_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0014)))
|
||||
BG2 = (*BG_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0018)))
|
||||
BG3 = (*BG_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x001C)))
|
||||
|
||||
BGA2 = (*BG_AFFINE_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0020)))
|
||||
BGA3 = (*BG_AFFINE_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0030)))
|
||||
|
||||
WIN = (*WIN_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0040)))
|
||||
|
||||
GRAPHICS = (*GRAPHICS_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x004C)))
|
||||
|
||||
// GBA Sound Channel 1 - Tone & Sweep
|
||||
SOUND1 = (*SOUND_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0060)))
|
||||
|
||||
// GBA Sound Channel 2 - Tone
|
||||
SOUND2 = (*SOUND_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0068)))
|
||||
|
||||
// TODO: Sound channel 3 and 4
|
||||
|
||||
TM0 = (*TIMER_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0100)))
|
||||
TM1 = (*TIMER_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0104)))
|
||||
TM2 = (*TIMER_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0108)))
|
||||
TM3 = (*TIMER_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x010C)))
|
||||
|
||||
KEY = (*KEY_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0130)))
|
||||
|
||||
INTERRUPT = (*INTERRUPT_Type)(unsafe.Add(unsafe.Pointer(REG_BASE), uintptr(0x0200)))
|
||||
)
|
||||
|
||||
// Main memory sections
|
||||
const (
|
||||
// External work RAM
|
||||
MEM_EWRAM uintptr = 0x02000000
|
||||
|
||||
// Internal work RAM
|
||||
MEM_IWRAM uintptr = 0x03000000
|
||||
|
||||
// I/O registers
|
||||
MEM_IO uintptr = 0x04000000
|
||||
|
||||
// Palette. Note: no 8bit write !!
|
||||
MEM_PAL uintptr = 0x05000000
|
||||
|
||||
// Video RAM. Note: no 8bit write !!
|
||||
MEM_VRAM uintptr = 0x06000000
|
||||
|
||||
// Object Attribute Memory (OAM) Note: no 8bit write !!
|
||||
MEM_OAM uintptr = 0x07000000
|
||||
|
||||
// ROM. No write at all (duh)
|
||||
MEM_ROM uintptr = 0x08000000
|
||||
|
||||
// Static RAM. 8bit write only
|
||||
MEM_SRAM uintptr = 0x0E000000
|
||||
)
|
||||
|
||||
// Main section sizes
|
||||
const (
|
||||
EWRAM_SIZE uintptr = 0x40000
|
||||
IWRAM_SIZE uintptr = 0x08000
|
||||
PAL_SIZE uintptr = 0x00400
|
||||
VRAM_SIZE uintptr = 0x18000
|
||||
OAM_SIZE uintptr = 0x00400
|
||||
SRAM_SIZE uintptr = 0x10000
|
||||
)
|
||||
|
||||
// Sub section sizes
|
||||
const (
|
||||
// BG palette size
|
||||
PAL_BG_SIZE = 0x00200
|
||||
|
||||
// Object palette size
|
||||
PAL_OBJ_SIZE = 0x00200
|
||||
|
||||
// Charblock size
|
||||
CBB_SIZE = 0x04000
|
||||
|
||||
// Screenblock size
|
||||
SBB_SIZE = 0x00800
|
||||
|
||||
// BG VRAM size
|
||||
VRAM_BG_SIZE = 0x10000
|
||||
|
||||
// Object VRAM size
|
||||
VRAM_OBJ_SIZE = 0x08000
|
||||
|
||||
// Mode 3 buffer size
|
||||
M3_SIZE = 0x12C00
|
||||
|
||||
// Mode 4 buffer size
|
||||
M4_SIZE = 0x09600
|
||||
|
||||
// Mode 5 buffer size
|
||||
M5_SIZE = 0x0A000
|
||||
|
||||
// Bitmap page size
|
||||
VRAM_PAGE_SIZE = 0x0A000
|
||||
)
|
||||
|
||||
// Sub sections
|
||||
var (
|
||||
REG_BASE uintptr = MEM_IO
|
||||
|
||||
// Background palette address
|
||||
MEM_PAL_BG = MEM_PAL
|
||||
|
||||
// Object palette address
|
||||
MEM_PAL_OBJ = MEM_PAL + PAL_BG_SIZE
|
||||
|
||||
// Front page address
|
||||
MEM_VRAM_FRONT = MEM_VRAM
|
||||
|
||||
// Back page address
|
||||
MEM_VRAM_BACK = MEM_VRAM + VRAM_PAGE_SIZE
|
||||
|
||||
// Object VRAM address
|
||||
MEM_VRAM_OBJ = MEM_VRAM + VRAM_BG_SIZE
|
||||
)
|
||||
|
||||
// Display registers
|
||||
type DISP_Type struct {
|
||||
DISPCNT volatile.Register16
|
||||
_ [2]byte
|
||||
DISPSTAT volatile.Register16
|
||||
VCOUNT volatile.Register16
|
||||
}
|
||||
|
||||
// Background control registers
|
||||
type BGCNT_Type struct {
|
||||
CNT volatile.Register16
|
||||
}
|
||||
|
||||
// Regular background scroll registers. (write only!)
|
||||
type BG_Type struct {
|
||||
HOFS volatile.Register16
|
||||
VOFS volatile.Register16
|
||||
}
|
||||
|
||||
// Affine background parameters. (write only!)
|
||||
type BG_AFFINE_Type struct {
|
||||
PA volatile.Register16
|
||||
PB volatile.Register16
|
||||
PC volatile.Register16
|
||||
PD volatile.Register16
|
||||
X volatile.Register32
|
||||
Y volatile.Register32
|
||||
}
|
||||
|
||||
type WIN_Type struct {
|
||||
// win0 right, left (0xLLRR)
|
||||
WIN0H volatile.Register16
|
||||
|
||||
// win1 right, left (0xLLRR)
|
||||
WIN1H volatile.Register16
|
||||
|
||||
// win0 bottom, top (0xTTBB)
|
||||
WIN0V volatile.Register16
|
||||
|
||||
// win1 bottom, top (0xTTBB)
|
||||
WIN1V volatile.Register16
|
||||
|
||||
// win0, win1 control
|
||||
IN volatile.Register16
|
||||
|
||||
// winOut, winObj control
|
||||
OUT volatile.Register16
|
||||
}
|
||||
|
||||
type GRAPHICS_Type struct {
|
||||
// Mosaic control
|
||||
MOSAIC volatile.Register32
|
||||
|
||||
// Alpha control
|
||||
BLDCNT volatile.Register16
|
||||
|
||||
// Fade level
|
||||
BLDALPHA volatile.Register16
|
||||
|
||||
// Blend levels
|
||||
BLDY volatile.Register16
|
||||
}
|
||||
|
||||
type SOUND_Type struct {
|
||||
// Sweep register
|
||||
CNT_L volatile.Register16
|
||||
|
||||
// Duty/Len/Envelope
|
||||
CNT_H volatile.Register16
|
||||
|
||||
// Frequency/Control
|
||||
CNT_X volatile.Register16
|
||||
}
|
||||
|
||||
// TODO: DMA
|
||||
|
||||
// TIMER
|
||||
type TIMER_Type struct {
|
||||
DATA volatile.Register16
|
||||
CNT volatile.Register16
|
||||
}
|
||||
|
||||
// TODO: serial
|
||||
|
||||
// Keypad registers
|
||||
type KEY_Type struct {
|
||||
INPUT volatile.Register16
|
||||
CNT volatile.Register16
|
||||
}
|
||||
|
||||
// TODO: Joybus communication
|
||||
|
||||
// Interrupt / System registers
|
||||
type INTERRUPT_Type struct {
|
||||
IE volatile.Register16
|
||||
IF volatile.Register16
|
||||
WAITCNT volatile.Register16
|
||||
IME volatile.Register16
|
||||
PAUSE volatile.Register16
|
||||
}
|
||||
|
||||
// Constants for DISP: display
|
||||
const (
|
||||
// BGMODE: background mode.
|
||||
// Position of BGMODE field.
|
||||
DISPCNT_BGMODE_Pos = 0x0
|
||||
// Bit mask of BGMODE field.
|
||||
DISPCNT_BGMODE_Msk = 0x4
|
||||
// BG Mode 0.
|
||||
DISPCNT_BGMODE_0 = 0x0
|
||||
// BG Mode 1.
|
||||
DISPCNT_BGMODE_1 = 0x1
|
||||
// BG Mode 2.
|
||||
DISPCNT_BGMODE_2 = 0x2
|
||||
// BG Mode 3.
|
||||
DISPCNT_BGMODE_3 = 0x3
|
||||
// BG Mode 4.
|
||||
DISPCNT_BGMODE_4 = 0x4
|
||||
|
||||
// FRAMESELECT: frame select (mode 4 and 5 only).
|
||||
DISPCNT_FRAMESELECT_Pos = 0x4
|
||||
DISPCNT_FRAMESELECT_FRAME0 = 0x0
|
||||
DISPCNT_FRAMESELECT_FRAME1 = 0x1
|
||||
|
||||
// HBLANKINTERVAL: 1=Allow access to OAM during H-Blank
|
||||
DISPCNT_HBLANKINTERVAL_Pos = 0x5
|
||||
DISPCNT_HBLANKINTERVAL_NOALLOW = 0x0
|
||||
DISPCNT_HBLANKINTERVAL_ALLOW = 0x1
|
||||
|
||||
// OBJCHARVRAM: (0=Two dimensional, 1=One dimensional)
|
||||
DISPCNT_OBJCHARVRAM_Pos = 0x6
|
||||
DISPCNT_OBJCHARVRAM_2D = 0x0
|
||||
DISPCNT_OBJCHARVRAM_1D = 0x1
|
||||
|
||||
// FORCEDBLANK: (1=Allow FAST access to VRAM,Palette,OAM)
|
||||
DISPCNT_FORCEDBLANK_Pos = 0x7
|
||||
DISPCNT_FORCEDBLANK_NOALLOW = 0x0
|
||||
DISPCNT_FORCEDBLANK_ALLOW = 0x1
|
||||
|
||||
// Screen Display BG0
|
||||
DISPCNT_SCREENDISPLAY_BG0_Pos = 0x8
|
||||
DISPCNT_SCREENDISPLAY_BG0_ENABLE = 0x1
|
||||
DISPCNT_SCREENDISPLAY_BG0_DISABLE = 0x0
|
||||
|
||||
// Screen Display BG1
|
||||
DISPCNT_SCREENDISPLAY_BG1_Pos = 0x9
|
||||
DISPCNT_SCREENDISPLAY_BG1_ENABLE = 0x1
|
||||
DISPCNT_SCREENDISPLAY_BG1_DISABLE = 0x0
|
||||
|
||||
// Screen Display BG2
|
||||
DISPCNT_SCREENDISPLAY_BG2_Pos = 0xA
|
||||
DISPCNT_SCREENDISPLAY_BG2_ENABLE = 0x1
|
||||
DISPCNT_SCREENDISPLAY_BG2_DISABLE = 0x0
|
||||
|
||||
// Screen Display BG3
|
||||
DISPCNT_SCREENDISPLAY_BG3_Pos = 0xB
|
||||
DISPCNT_SCREENDISPLAY_BG3_ENABLE = 0x1
|
||||
DISPCNT_SCREENDISPLAY_BG3_DISABLE = 0x0
|
||||
|
||||
// Screen Display OBJ
|
||||
DISPCNT_SCREENDISPLAY_OBJ_Pos = 0xC
|
||||
DISPCNT_SCREENDISPLAY_OBJ_ENABLE = 0x1
|
||||
DISPCNT_SCREENDISPLAY_OBJ_DISABLE = 0x0
|
||||
|
||||
// Window 0 Display Flag (0=Off, 1=On)
|
||||
DISPCNT_WINDOW0_DISPLAY_Pos = 0xD
|
||||
DISPCNT_WINDOW0_DISPLAY_ENABLE = 0x1
|
||||
DISPCNT_WINDOW0_DISPLAY_DISABLE = 0x0
|
||||
|
||||
// Window 1 Display Flag (0=Off, 1=On)
|
||||
DISPCNT_WINDOW1_DISPLAY_Pos = 0xE
|
||||
DISPCNT_WINDOW1_DISPLAY_ENABLE = 0x1
|
||||
DISPCNT_WINDOW1_DISPLAY_DISABLE = 0x0
|
||||
|
||||
// OBJ Window Display Flag
|
||||
DISPCNT_WINDOWOBJ_DISPLAY_Pos = 0xF
|
||||
DISPCNT_WINDOWOBJ_DISPLAY_ENABLE = 0x1
|
||||
DISPCNT_WINDOWOBJ_DISPLAY_DISABLE = 0x0
|
||||
|
||||
// DISPSTAT: display status.
|
||||
// V-blank
|
||||
DISPSTAT_VBLANK_Pos = 0x0
|
||||
DISPSTAT_VBLANK_ENABLE = 0x1
|
||||
DISPSTAT_VBLANK_DISABLE = 0x0
|
||||
|
||||
// H-blank
|
||||
DISPSTAT_HBLANK_Pos = 0x1
|
||||
DISPSTAT_HBLANK_ENABLE = 0x1
|
||||
DISPSTAT_HBLANK_DISABLE = 0x0
|
||||
|
||||
// V-counter match
|
||||
DISPSTAT_VCOUNTER_Pos = 0x2
|
||||
DISPSTAT_VCOUNTER_MATCH = 0x1
|
||||
DISPSTAT_VCOUNTER_NOMATCH = 0x0
|
||||
|
||||
// V-blank IRQ
|
||||
DISPSTAT_VBLANK_IRQ_Pos = 0x3
|
||||
DISPSTAT_VBLANK_IRQ_ENABLE = 0x1
|
||||
DISPSTAT_VBLANK_IRQ_DISABLE = 0x0
|
||||
|
||||
// H-blank IRQ
|
||||
DISPSTAT_HBLANK_IRQ_Pos = 0x4
|
||||
DISPSTAT_HBLANK_IRQ_ENABLE = 0x1
|
||||
DISPSTAT_HBLANK_IRQ_DISABLE = 0x0
|
||||
|
||||
// V-counter IRQ
|
||||
DISPSTAT_VCOUNTER_IRQ_Pos = 0x5
|
||||
DISPSTAT_VCOUNTER_IRQ_ENABLE = 0x1
|
||||
DISPSTAT_VCOUNTER_IRQ_DISABLE = 0x0
|
||||
|
||||
// V-count setting
|
||||
DISPSTAT_VCOUNT_SETTING_Pos = 0x8
|
||||
)
|
||||
|
||||
// Constants for TIMER
|
||||
const (
|
||||
// PRESCALER: Prescaler Selection (0=F/1, 1=F/64, 2=F/256, 3=F/1024)
|
||||
// Position of PRESCALER field.
|
||||
TIMERCNT_PRESCALER_Pos = 0x0
|
||||
// Bit mask of PRESCALER field.
|
||||
TIMERCNT_PRESCALER_Msk = 0x2
|
||||
// 0=F/1
|
||||
TIMERCNT_PRESCALER_1 = 0x0
|
||||
// 1=F/64
|
||||
TIMERCNT_PRESCALER_64 = 0x1
|
||||
// 2=F/256
|
||||
TIMERCNT_PRESCALER_256 = 0x2
|
||||
// F/1024
|
||||
TIMERCNT_PRESCALER_1024 = 0x3
|
||||
|
||||
// COUNTUP: Count-up Timing (0=Normal, 1=See below) ;Not used in TM0CNT_H
|
||||
// Position of COUNTUP_TIMING field.
|
||||
TIMERCNT_COUNTUP_TIMING_Pos = 0x2
|
||||
TIMERCNT_COUNTUP_TIMING_NORMAL = 0x0
|
||||
TIMERCNT_COUNTUP_TIMING_ENABLED = 0x1
|
||||
|
||||
TIMERCNT_TIMER_IRQ_ENABLED_Pos = 0x06
|
||||
TIMERCNT_TIMER_IRQ_ENABLED = 0x01
|
||||
TIMERCNT_TIMER_IRQ_DISABLED = 0x00
|
||||
|
||||
TIMERCNT_TIMER_STARTSTOP_Pos = 0x07
|
||||
TIMERCNT_TIMER_START = 0x1
|
||||
TIMERCNT_TIMER_STOP = 0x0
|
||||
)
|
||||
|
||||
// Constants for KEY
|
||||
const (
|
||||
// KEYINPUT
|
||||
KEYINPUT_PRESSED = 0x0
|
||||
KEYINPUT_RELEASED = 0x1
|
||||
KEYINPUT_BUTTON_A_Pos = 0x0
|
||||
KEYINPUT_BUTTON_B_Pos = 0x1
|
||||
KEYINPUT_BUTTON_SELECT_Pos = 0x2
|
||||
KEYINPUT_BUTTON_START_Pos = 0x3
|
||||
KEYINPUT_BUTTON_RIGHT_Pos = 0x4
|
||||
KEYINPUT_BUTTON_LEFT_Pos = 0x5
|
||||
KEYINPUT_BUTTON_UP_Pos = 0x6
|
||||
KEYINPUT_BUTTON_DOWN_Pos = 0x7
|
||||
KEYINPUT_BUTTON_R_Pos = 0x8
|
||||
KEYINPUT_BUTTON_L_Pos = 0x9
|
||||
|
||||
// KEYCNT
|
||||
KEYCNT_IGNORE = 0x0
|
||||
KEYCNT_SELECT = 0x1
|
||||
KEYCNT_BUTTON_A_Pos = 0x0
|
||||
KEYCNT_BUTTON_B_Pos = 0x1
|
||||
KEYCNT_BUTTON_SELECT_Pos = 0x2
|
||||
KEYCNT_BUTTON_START_Pos = 0x3
|
||||
KEYCNT_BUTTON_RIGHT_Pos = 0x4
|
||||
KEYCNT_BUTTON_LEFT_Pos = 0x5
|
||||
KEYCNT_BUTTON_UP_Pos = 0x6
|
||||
KEYCNT_BUTTON_DOWN_Pos = 0x7
|
||||
KEYCNT_BUTTON_R_Pos = 0x8
|
||||
KEYCNT_BUTTON_L_Pos = 0x9
|
||||
)
|
||||
|
||||
// Constants for INTERRUPT
|
||||
const (
|
||||
// IE
|
||||
INTERRUPT_IE_ENABLED = 0x1
|
||||
INTERRUPT_IE_DISABLED = 0x0
|
||||
INTERRUPT_IE_VBLANK_Pos = 0x0
|
||||
INTERRUPT_IE_HBLANK_Pos = 0x1
|
||||
INTERRUPT_IE_VCOUNTER_MATCH_Pos = 0x2
|
||||
INTERRUPT_IE_TIMER0_OVERFLOW_Pos = 0x3
|
||||
INTERRUPT_IE_TIMER1_OVERFLOW_Pos = 0x4
|
||||
INTERRUPT_IE_TIMER2_OVERFLOW_Pos = 0x5
|
||||
INTERRUPT_IE_TIMER3_OVERFLOW_Pos = 0x6
|
||||
INTERRUPT_IE_SERIAL_Pos = 0x7
|
||||
INTERRUPT_IE_DMA0_Pos = 0x8
|
||||
INTERRUPT_IE_DMA1_Pos = 0x9
|
||||
INTERRUPT_IE_DMA2_Pos = 0xA
|
||||
INTERRUPT_IE_DMA3_Pos = 0xB
|
||||
INTERRUPT_IE_KEYPAD_Pos = 0xC
|
||||
INTERRUPT_IE_GAMPAK_Pos = 0xD
|
||||
|
||||
// IF
|
||||
INTERRUPT_IF_ENABLED = 0x1
|
||||
INTERRUPT_IF_DISABLED = 0x0
|
||||
INTERRUPT_IF_VBLANK_Pos = 0x0
|
||||
INTERRUPT_IF_HBLANK_Pos = 0x1
|
||||
INTERRUPT_IF_VCOUNTER_MATCH_Pos = 0x2
|
||||
INTERRUPT_IF_TIMER0_OVERFLOW_Pos = 0x3
|
||||
INTERRUPT_IF_TIMER1_OVERFLOW_Pos = 0x4
|
||||
INTERRUPT_IF_TIMER2_OVERFLOW_Pos = 0x5
|
||||
INTERRUPT_IF_TIMER3_OVERFLOW_Pos = 0x6
|
||||
INTERRUPT_IF_SERIAL_Pos = 0x7
|
||||
INTERRUPT_IF_DMA0_Pos = 0x8
|
||||
INTERRUPT_IF_DMA1_Pos = 0x9
|
||||
INTERRUPT_IF_DMA2_Pos = 0xA
|
||||
INTERRUPT_IF_DMA3_Pos = 0xB
|
||||
INTERRUPT_IF_KEYPAD_Pos = 0xC
|
||||
INTERRUPT_IF_GAMPAK_Pos = 0xD
|
||||
)
|
Загрузка…
Создание таблицы
Сослаться в новой задаче