File: gba.inc - Tab length: 1 2 4 8 - Lines: on off - No wrap: on off

@@@@@@@@@ CONTENTS @@@@@@@@@
@ 1. Key pad defines
@ 2. Display
@ 3. Sprites
@ 4. Background
@ 5. Sound
@ 6. DMA
@ 7. Interrupts
@ 8. BIOS Functions
@ 9. Timers

@@@@@@@@@ 1. KEY PAD DEFINES @@@@@@@@@
KEY_A     = 1
KEY_B     = 2
KEY_SELECT  = 4
KEY_START = 8
KEY_RIGHT = 16
KEY_LEFT  = 32
KEY_UP    = 64
KEY_DOWN  = 128
KEY_R   = 256
KEY_L   = 512
KEYS    = 0x04000130
KEYS_HIGH = 0x04000000
KEYS_LOW  = 0x00000130

@@@@@@@@@ 2. Display @@@@@@@@@
@ Tile modes
MODE_0 = 0x00 @ All 4 BG layers available, but no rotation/scaling
MODE_1 = 0x01 @ 3 BG layers (0-2), BG2 can rotate/scale
MODE_2 = 0x02 @ 2 BG layers (2-3), both can scale/rotate
@ Bitmap modes : BG2 only
MODE_3 = 0x03 @ 16 bit color bitmap, cuts into available sprite data area
MODE_4 = 0x04 @ Like Mode 3, but with 8-bit references (and palette)
MODE_5 = 0x05 @ 16 bit color bitmap, with backbuffer. Screen limited to 160x128

BACKBUFFER = 0x010
H_BLANK_OAM = 0x020

OBJ_MAP_2D = 0x000
OBJ_MAP_1D = 0x040

FORCE_BLANK = 0x080

BG0_ENABLE = 0x0100
BG1_ENABLE = 0x0200
BG2_ENABLE = 0x0400
BG3_ENABLE = 0x0800
OBJ_ENABLE = 0x01000    @ = SPRITES_ENABLE: enable sprites
WIN1_ENABLE = 0x02000
WIN2_ENABLE = 0x04000
WINOBJ_ENABLE = 0x08000
VRAM = 0x06000000
VPAL = 0x05000000
REG_DISPCNT = 0x04000000  @
REG_BASE = REG_DISPCNT
REG_VCOUNT  = 0x04000006

REG_BLDMOD  = 0x04000050
BLEND_BG0S  = 0x01      @ Source
BLEND_BG1S  = 0x02
BLEND_BG2S  = 0x04
BLEND_BG3S  = 0x08
BLEND_SRITES= 0x10
BLEND_BD  = 0x20      @ Blend backdrop
BLEND_ALPHA = 0b01000000
BLEND_LIGHT = 0b10000000
BLEND_DARK  = 0b11000000
BLEND_BG0T  = 0x0100    @ Target
BLEND_BG1T  = 0x0200
BLEND_BG2T  = 0x0400
BLEND_BG3T  = 0x0800

REG_COLEV = 0x4000052
REG_COLEY = 0x4000054

@@@@@@@@@ 3. SPRITES @@@@@@@@@

@*** Attribute 0 ***
@ F E D C  B A 9 8  7 6 5 4  3 2 1 0
@ S S A M  T T D R  J J J J  J J J J
@ 0-7 (J) = Y coordinate of the sprite (pixels)
@ 8   (R) = Rotation/Scaling on/off
@ 9   (D) = 0 - sprite is single sized;
@       1 - sprite is virtually double sized
@ A-B (T) = 00 - normal
@       01 - semi-transparent
@       10 - obj window
@ C   (M) = enables mosaic for this sprite.
@ D   (A) = 256 color if on, 16 color if off
@ E-F (S) = Size, MSB in attribute 0, LSB in attribute 1

@ Byte 1 = Y coordinate of the sprite, in pixels
@ Byte 2
ROTATION_FLAG =  0x100
SIZE_DOUBLE   =  0x200
MODE_NORMAL   =  0x000
MODE_TRANSPERANT=  0x400
MODE_WINDOWED =  0x800
MOSAIC      = 0x1000
COLOR_16    = 0x0000
COLOR_256   = 0x2000
SIZE_8      = 0x0000 @ Only valid for SQUARE
SIZE_16     = 0x4000
SIZE_32     = 0x8000
SIZE_64     = 0xC000

@*** Atribute 1 ***
@ FEDC BA98 7654 3210
@ SSVH XXXI IIII IIII (standard sprites)
@ SSFF FFFI IIII IIII (rotation/scaling on)
@ 0-8 (I) = X coordinate of the sprite (pixels)
@ C   (H) = flip horizinal bit
@ D   (V) = flip vertical bit
@ 9-D (F) = rotation index (0-31). rotation/scaling data in OAM attribute 3
@ E-F (S) = Size of the sprite (LSB)
@     4-bit value which sets the size of the sprite in the following way:
@     00 00: 8  x 8   10 00: 8  x 16
@     00 01: 16 x 16    10 01: 8  x 32
@     00 10: 32 x 32    10 10: 16 x 32
@     00 11: 64 x 64    10 11: 32 x 64
@     01 00: 16 x 8   11 00: Not used
@     01 01: 32 x 8   11 01: Not used
@     01 10: 32 x 16    11 10: Not used
@     01 11: 64 x 32    11 11: Not used

@ Byte 3+1 bit = X coordinate of the sprite, in pixels (9-bit value)
@ Byte 4
SQUARE      = 0x0000
WIDE      = 0x4000
TALL      = 0x8000
HORIZONTAL_FLIP = 0x1000
VERTICAL_FLIP = 0x2000
OAM       = 0x07000000
OBJPAL      = 0x5000200
CHARMEM     = 0x6010000   @ SPRITE MEM
CHARMEM_MODE3 = 0x6012BFD

@*** Attribute 2 ***
@ FEDC BA98 7654 3210
@ LLLL PPTT TTTT TTTT
@
@ 0-9 (T) = Tile number
@ A-B (P) = Priority. Note thate sprites take precedence over backgrounds of the same priority.
@ C-F (L) = Palette number (16 color only)

SPRITE_P0 = 0x0000  @ Priority 0
SPRITE_P1 = 0x0004  @ Priority 1
SPRITE_P2 = 0x0008
SPRITE_P3 = 0x000C

@@@@@@@@@ 4. Background @@@@@@@@@
@ These four addresses handle the BG layers
REG_BG0CNT  = 0x4000008
REG_BG1CNT  = 0x400000A
REG_BG2CNT  = 0x400000C
REG_BG3CNT  = 0x400000E

REG_BG0HOFS = 0x4000010 @ Horizontal offset
REG_BG0VOFS = 0x4000012 @ Vertical offset
REG_BG1HOFS = 0x4000014
REG_BG1VOFS = 0x4000016
REG_BG2HOFS = 0x4000018
REG_BG2VOFS = 0x400001A
REG_BG3HOFS = 0x400001C
REG_BG3VOFS = 0x400001E
REG_BG2PA   = 0x4000020
REG_BG2PB   = 0x4000022
REG_BG2PC   = 0x4000024
REG_BG2PD   = 0x4000026
REG_BG2X    = 0x4000028
REG_BG2X_L  = 0x4000028
REG_BG2X_H  = 0x400002A
REG_BG2Y    = 0x400002C
REG_BG2Y_L  = 0x400002C
REG_BG2Y_H  = 0x400002E
REG_BG3PA   = 0x4000030
REG_BG3PB   = 0x4000032
REG_BG3PC   = 0x4000034
REG_BG3PD   = 0x4000036
REG_BG3X    = 0x4000038
REG_BG3X_L  = 0x4000038
REG_BG3X_H  = 0x400003A
REG_BG3Y    = 0x400003C
REG_BG3Y_L  = 0x400003C
REG_BG3Y_H  = 0x400003E

BG_COLOR_16   = 0x0
BG_MOSAIC_ENABLE = 0x40
BG_COLOR_256  = 0x80

TEXTBG_SIZE_256x256 = 0x0   @ 16x16 8*8 for text backgrounds
TEXTBG_SIZE_512x256 = 0x4000  @ 64x32
TEXTBG_SIZE_256x512 = 0x8000  @ 32x64
TEXTBG_SIZE_512x512 = 0xC000  @ 64x64

ROTBG_SIZE_128x128 = 0x0    @ 16x16 8*8 tiles for rotational backgrounds
ROTBG_SIZE_256x256 = 0x4000   @ 32x32 tiles
ROTBG_SIZE_512x512 = 0x8000   @ 64x64 tiles
ROTBG_SIZE_1024x1024 = 0xC000 @ 128x128 tiles

BG_P0 = 0   @ Priority 0 (front/top)
BG_P1 = 1   @ Priority 1
BG_P2 = 2
BG_P3 = 3   @ Priority 3 (back/bottom)

WRAPAROUND = 0x2000

CHAR_SHIFT = 2    @ Used to shift the number over to the right place in REG_BGxCNT
SCREEN_SHIFT = 8

@ Defines for all 32 screen (map data) blocks and 4 character (bitmap data) blocks
@ Some of this might not be correct
CHAR_BLOCK_0  = 0x6000000   @ Note: this just happens to be the same address as VRAM
CHAR_BLOCK_1  = 0x6004000
CHAR_BLOCK_2  = 0x6008000
CHAR_BLOCK_3  = 0x600C000
SCREEN_BLOCK_0  = 0x6000000
SCREEN_BLOCK_1  = 0x6000800
SCREEN_BLOCK_2  = 0x6001000
SCREEN_BLOCK_3  = 0x6001800
SCREEN_BLOCK_4  = 0x6002000
SCREEN_BLOCK_5  = 0x6002800
SCREEN_BLOCK_6  = 0x6003000
SCREEN_BLOCK_7  = 0x6003800
SCREEN_BLOCK_8  = 0x6004000
SCREEN_BLOCK_9  = 0x6004800
SCREEN_BLOCK_10 = 0x6005000
SCREEN_BLOCK_11 = 0x6005800
SCREEN_BLOCK_12 = 0x6006000
SCREEN_BLOCK_13 = 0x6006800
SCREEN_BLOCK_14 = 0x6007000
SCREEN_BLOCK_15 = 0x6007800
SCREEN_BLOCK_16 = 0x6008000
SCREEN_BLOCK_17 = 0x6008800
SCREEN_BLOCK_18 = 0x6009000
SCREEN_BLOCK_19 = 0x6009800
SCREEN_BLOCK_20 = 0x600A000
SCREEN_BLOCK_21 = 0x600A800
SCREEN_BLOCK_22 = 0x600B000
SCREEN_BLOCK_23 = 0x600B800
SCREEN_BLOCK_24 = 0x600C000
SCREEN_BLOCK_25 = 0x600C800
SCREEN_BLOCK_26 = 0x600D000
SCREEN_BLOCK_27 = 0x600D800
SCREEN_BLOCK_28 = 0x600E000
SCREEN_BLOCK_29 = 0x600E800
SCREEN_BLOCK_30 = 0x600F000
SCREEN_BLOCK_31 = 0x600F800

@@@@@@@@@ 5. Sound @@@@@@@@@
@ To turn sound on:
@ ldr r1,=REG_SOUNDCNT_X
@ ldr r0,=0x0081
@ str r0,[r1]

REG_SOUND1CNT_L = 0x04000060 @ Sound 1 Sweep control
REG_SOUND1CNT_H = 0x04000062 @ Sound 1 Length, wave duty and envelope control
REG_SOUND1CNT_X = 0x04000064 @ Sound 1 Frequency, reset and loop control
REG_SOUND2CNT_L = 0x04000068 @ Sound 2 Length, wave duty and envelope control
REG_SOUND2CNT_H = 0x0400006C @ Sound 2 Frequency, reset and loop control
REG_SOUND3CNT_L = 0x04000070 @ Sound 3 Enable and wave ram bank control
REG_SOUND3CNT_H = 0x04000072 @ Sound 3 Sound Length and output level control
REG_SOUND3CNT_X = 0x04000074 @ Sound 3 Frequency, reset and loop control
REG_SOUND4CNT_L = 0x04000078 @ Sound 4 Length, output level and envelope control
REG_SOUND4CNT_H = 0x0400007C @ Sound 4 Noise parameters, reset and loop control
REG_SOUNDCNT_L  = 0x04000080 @ Sound 1-4 Output level and Stereo control
REG_SOUNDCNT_H  = 0x04000082 @ Direct Sound control and Sound 1-4 output ratio
REG_SOUNDCNT_X  = 0x04000084 @ Master sound enable and Sound 1-4 play status
REG_SOUNDBIAS = 0x04000088 @ Sound bias and Amplitude resolution control
REG_WAVE_RAM0_L = 0x04000090 @ Sound 3 samples 0-3
REG_WAVE_RAM0_H = 0x04000092 @ Sound 3 samples 4-7
REG_WAVE_RAM1_L = 0x04000094 @ Sound 3 samples 8-11
REG_WAVE_RAM1_H = 0x04000096 @ Sound 3 samples 12-15
REG_WAVE_RAM2_L = 0x04000098 @ Sound 3 samples 16-19
REG_WAVE_RAM2_H = 0x0400009A @ Sound 3 samples 20-23
REG_WAVE_RAM3_L = 0x0400009C @ Sound 3 samples 23-27
REG_WAVE_RAM3_H = 0x0400009E @ Sound 3 samples 28-31
REG_FIFO_A_L  = 0x040000A0 @ Direct Sound channel A samples 0-1
REG_FIFO_A_H  = 0x040000A2 @ Direct Sound channel A samples 2-3
REG_FIFO_B_L  = 0x040000A4 @ Direct Sound channel B samples 0-1
REG_FIFO_B_H  = 0x040000A6 @ Direct Sound channel B samples 2-3

@@@@@@@@@ 6. DMA @@@@@@@@@

DMA_ENABLE      = 0x80000000
DMA_INTERUPT_ENABLE = 0x40000000
DMA_TIMING_IMMEDIATE= 0x00000000
DMA_TIMING_VBLANK = 0x10000000
DMA_TIMING_HBLANK = 0x20000000
DMA_TIMING_SYNC_TO_DISPLAY  = 0x30000000
DMA_16        = 0x00000000
DMA_32        = 0x04000000
DMA_REPEAT      = 0x02000000
DMA_SOURCE_INCREMENT= 0x00000000
DMA_SOURCE_DECREMENT= 0x00800000
DMA_SOURCE_FIXED  = 0x01000000
DMA_DEST_INCREMENT  = 0x00000000
DMA_DEST_DECREMENT  = 0x00200000
DMA_DEST_FIXED    = 0x00400000
DMA_DEST_RELOAD   = 0x00600000

@ register defines, ripped from GBA.h from DevKitAdvanced
REG_DMA0SAD   = 0x40000B0
REG_DMA0SAD_L = 0x40000B0
REG_DMA0SAD_H = 0x40000B2
REG_DMA0DAD   = 0x40000B4
REG_DMA0DAD_L = 0x40000B4
REG_DMA0DAD_H = 0x40000B6
REG_DMA0CNT   = 0x40000B8
REG_DMA0CNT_L = 0x40000B8
REG_DMA0CNT_H = 0x40000BA
REG_DMA1SAD   = 0x40000BC
REG_DMA1SAD_L = 0x40000BC
REG_DMA1SAD_H = 0x40000BE
REG_DMA1DAD   = 0x40000C0
REG_DMA1DAD_L = 0x40000C0
REG_DMA1DAD_H = 0x40000C2
REG_DMA1CNT   = 0x40000C4
REG_DMA1CNT_L = 0x40000C4
REG_DMA1CNT_H = 0x40000C6
REG_DMA2SAD   = 0x40000C8
REG_DMA2SAD_L = 0x40000C8
REG_DMA2SAD_H = 0x40000CA
REG_DMA2DAD   = 0x40000CC
REG_DMA2DAD_L = 0x40000CC
REG_DMA2DAD_H = 0x40000CE
REG_DMA2CNT   = 0x40000D0
REG_DMA2CNT_L = 0x40000D0
REG_DMA2CNT_H = 0x40000D2
REG_DMA3SAD   = 0x40000D4
REG_DMA3SAD_L = 0x40000D4
REG_DMA3SAD_H = 0x40000D6
REG_DMA3DAD   = 0x40000D8
REG_DMA3DAD_L = 0x40000D8
REG_DMA3DAD_H = 0x40000DA
REG_DMA3CNT   = 0x40000DC
REG_DMA3CNT_L = 0x40000DC
REG_DMA3CNT_H = 0x40000DE

@ These defines group common options to save typing
@ You may notice that I don't have to include the option to increment the source and address register as that is the default.
@ DMA_32NOW DMA_ENABLE|DMA_TIMEING_IMMEDIATE|DMA_32
@ DMA_16NOW DMA_ENABLE|DMA_TIMEING_IMMEDIATE|DMA_16
DMA_32NOW = 0x84000000
DMA_16NOW = 0x80000000

@@@@@@@@@ 7. INTERRUPTS @@@@@@@@@

INT_VBLANK    = 0x0001
INT_HBLANK    = 0x0002
INT_VCOUNT    = 0x0004    @ you can set the display to generate an interrupt when it reaches a particular line on the screen
INT_TIMER0    = 0x0008
INT_TIMER1    = 0x0010
INT_TIMER2    = 0x0020
INT_TIMER3    = 0x0040
INT_COMUNICATION  = 0x0080  @ Serial communication interupt
INT_DMA0    = 0x0100
INT_DMA1    = 0x0200
INT_DMA2    = 0x0400
INT_DMA3    = 0x0800
INT_KEYBOARD  = 0x1000
INT_CART    = 0x2000    @ The cart can actually generate an interupt

INT_ENABLE    = 0x1

@ "_OFF" suffix is added to calculate the offset from REG_BASE aka REG_DISPCNT (0x0400:0000)
REG_INTADDR   = 0x3007FFC
REG_INTADDR_OFF = -0x04

REG_INT_OFF   = 0x0200    @ Offset from REG_BASE (REG_DISPCNT) to start of interrupt registers
REG_IE      = 0x4000200   @ Interrupt Enable Register (note: REG_IE and REG_IF can fit in one register ;))
REG_IE_OFF    = 0x00      @ Offset from REG_IE (interrupt base)
REG_IF      = 0x4000202
REG_IF_OFF    = 0x02      @ Offset from REG_IE
REG_IME     = 0x4000208   @ Interrupt Master Enable Register
REG_IME_OFF   = 0x08      @ bit 0 = Enable interupts (1)/Disable all interrupts (0)
                @       if 1, it will look in REG_IE for interrupt type
REG_DISPSTAT  = 0x4000004   @ Display Status:
REG_DISPSTAT_OFF= 0x04      @ Offset from REG_BASE
STAT_VBLANK   = 1       @   bit 0 = V Refresh (0 = VDraw, 1 = VBlank)
STAT_HBLANK   = 2       @   bit 1 = H Refresh (0 = HDraw, 1 = HBlank)
                @   bit 2 = VCount Triggered Status (1 = Y trigger interrupt occured)
STAT_VBLANK_IRQ = 8       @   bit 3 = Enables LCD VBlank IRQ
STAT_HBLANK_IRQ = 16      @   bit 4 = Enables LCD HBlank IRQ
                @   bit 5 = Enables VCount trigger
                @   bit 8-F = VCount line trigger: Vcount value you wish to trigger an interrupt

@@@@@@@@@ 8. BIOS FUNCTIONS @@@@@@@@@

#IFDEF ARM
_SoftReset      = 0x000000
_RegisterRamReset = 0x010000
_Halt       = 0x020000
_Stop_Sleep     = 0x030000
_IntrWait     = 0x040000
_VBlankIntrWait   = 0x050000
_Div          = 0x060000
_DivArm       = 0x070000
_Sqrt       = 0x080000
_ArcTan       = 0x090000
_ArcTan2        = 0x0A0000
_CpuSet       = 0x0B0000
_CpuFastSet     = 0x0C0000
_GetBiosChecksum    = 0x0D0000
_BgAffineSet      = 0x0E0000
_ObjAffineSet   = 0x0F0000
_BitUnPack      = 0x100000
_LZ77UnCompWram   = 0x110000
_LZ77UnCompVram   = 0x120000
_HuffUnComp     = 0x130000
_RLUnCompWram   = 0x140000
_RLUnCompVram   = 0x150000
_Diff8bitUnFilterWram = 0x160000
_Diff8bitUnFilterVram = 0x170000
_Diff16bitUnFilter  = 0x180000
_SoundBias      = 0x190000
_SoundDriverInit    = 0x1A0000
_SoundDriverMode    = 0x1B0000
_SoundDriverMain    = 0x1C0000
_SoundDriverVSync = 0x1D0000
_SoundChannelClear  = 0x1E0000
_MidiKey2Freq   = 0x1F0000
_SoundWhatever0   = 0x200000
_SoundWhatever1   = 0x210000
_SoundWhatever2   = 0x220000
_SoundWhatever3   = 0x230000
_SoundWhatever4   = 0x240000
_MultiBoot      = 0x250000
_HardReset      = 0x260000
_CustomHalt     = 0x270000
_SoundDriverVSyncOff  = 0x280000
_SoundDriverVSyncOn = 0x290000
_SoundGetJumpList = 0x2A0000
#ELSE
_SoftReset      = 0x00
_RegisterRamReset = 0x01
_Halt       = 0x02
_Stop_Sleep     = 0x03
_IntrWait     = 0x04
_VBlankIntrWait   = 0x05
_Div          = 0x06
_DivArm       = 0x07
_Sqrt       = 0x08
_ArcTan       = 0x09
_ArcTan2        = 0x0A
_CpuSet       = 0x0B
_CpuFastSet     = 0x0C
_GetBiosChecksum    = 0x0D
_BgAffineSet      = 0x0E
_ObjAffineSet   = 0x0F
_BitUnPack      = 0x10
_LZ77UnCompWram   = 0x11
_LZ77UnCompVram   = 0x12
_HuffUnComp     = 0x13
_RLUnCompWram   = 0x14
_RLUnCompVram   = 0x15
_Diff8bitUnFilterWram = 0x16
_Diff8bitUnFilterVram = 0x17
_Diff16bitUnFilter  = 0x18
_SoundBias      = 0x19
_SoundDriverInit    = 0x1A
_SoundDriverMode    = 0x1B
_SoundDriverMain    = 0x1C
_SoundDriverVSync = 0x1D
_SoundChannelClear  = 0x1E
_MidiKey2Freq   = 0x1F
_SoundWhatever0   = 0x20
_SoundWhatever1   = 0x21
_SoundWhatever2   = 0x22
_SoundWhatever3   = 0x23
_SoundWhatever4   = 0x24
_MultiBoot      = 0x25
_HardReset      = 0x26
_CustomHalt     = 0x27
_SoundDriverVSyncOff  = 0x28
_SoundDriverVSyncOn = 0x29
_SoundGetJumpList = 0x2A
#ENDIF

@@@@@@@@@ 9. TIMERS @@@@@@@@@
@ There are four timers, TM0-3.
@ Timers 0 and 1 are used to control the rate of Direct Sound FIFO (first in first out)
REG_TM0D    = 0x4000100   @ Data, holds current value of timer (2-byte number, 0-65535)
REG_TM0CNT  = 0x4000102   @ Controller
REG_TM1D    = 0x4000104
REG_TM1CNT  = 0x4000106
REG_TM2D    = 0x4000108
REG_TM2CNT  = 0x400010A
REG_TM3D    = 0x400010C
REG_TM3CNT  = 0x400010E
@ Controller values
TIME_FREQUENCY_SYSTEM = 0x0 @ Bits 0-1 = timer speed
TIME_FREQUENCY_64   = 0x1
TIME_FREQUENCY_256    = 0x2
TIME_FREQUENCY_1024   = 0x3
TIME_OVERFLOW     = 0x4 @ Bit 2
TIME_IRQ_ENABLE     = 0x40  @ Bit 6: Generate interrupt on overflow
TIME_ENABLE       = 0x80  @ Bit 7: Enable