CowBite Virtual Hardware Specifications Unofficial documentation for the CowBite GBA emulator by Tom Happ Note that I am now mainting this doc in HTML format. The new version is at http://www.cs.rit.edu/~tjh8300/CowBite/CowBiteSpec.htm Please update your links. ------------------------------------------------------------------------ Table of Contents 1. Introduction 2. Memory 3. Video Modes 4. OAM/Sprites 5. Windowing 6. Hardware Interrupts 7. BIOS 8. Memory-Mapped Hardware Registers * Graphics Hardware Registers * Background Scaling/Rotation Registers * Sound Registers * Timer Registers * Keyboard Registers * DMA Registers * Interrupt Registers 9. Links 10. Thanks 1. Introduction This document began as a scratchpad of notes that I added onto "Agent Q's GBA Spec" as I came across new information and ideas while building the CowBite emulator. Agent Q is no longer able to maintain that document. Because there is so much additional information here, I thought it would be a shame to keep it to myself, and thus I'm releasing it again as a CowBite technical reference document. Though not all of the things in this doc have been implemented in CowBite, the information should still be more or less valid on a real GBA. All of this information has been obtained legally by piecing together information from the ARM docs, gbadev.org, the gbadev mailing list, public domain demos, and other information such as the debug info from various emulators. Since this was posted on gbadev.org, I've received a number of e-mails with updates and corrections. Thanks everyone! Send me mail (SorcererXIII@yahoo.com) with your comments. Tom Happ Revision 2.0 - Begun July 23, 2001 (Though updates are continuous) Revision 1.0 - (by Agent Q) 08/02/2001 Last update: Sat Dec 29 13:11:58 2001 I keep the most recent doc update at http://www.cs.rit.edu/~tjh8300/CowBite/CowBiteSpec.htm 2. Memory This section lists the general areas of memory as seen by the CPU, and what they are used for. System ROM: Location: 0x00000000 Size: 16kb 0x0 - 0x00003FFF contain the BIOS, which is executable but not readable. Any attempt to read in the area from 0x0 to 0x1FFFFFFF will result in failure; what you will see on a read is the current prefetched instruction (the instruction after the instruction used to view the memory area), thus giving the appearance that this area of memory consists of a repeating byte pattern. External Work RAM: Location: 0x02000000 Size: 256Kb This space is available for your game's data and code. Internal Work RAM: Location: 0x03000000 Size: 32Kb This space is also available for use. I'm not sure why the work RAM is split into two parts. IO Ram: Location: 0x04000000 Size: 1Kb This area contains all the memory-mapped IO registers which are used to control the graphics, sound, DMA, and other features. Palette: Location: 0x05000000 Size: 0x400 bytes This area specifies the 16-bit color values for the paletted modes. There are two areas of the palette: one for backgrounds (0x05000000) and another for sprites (0x05000200). Each of these is either indexed as a single, 256-color palette, or as 16 individual 16-color palettes, depending on the settings of a particular sprite or background. OAM: Location: 0x07000000 Size: 0x400 bytes This is the Object Attribute Memory, and is used to control the GBA's sprites. VRAM: Location: 0x06000000 Size: 0x20000 bytes The video RAM is used to store the frame buffer in bitmapped modes, and the tile data and tile maps for tile-based "text" and rotate/scale modes. ROM: Start: 0x08000000 Size: The size of the cartridge (0 - 32 megabytes) The ROM in the game cartridge appears in this area. ROM IMAGE 1: Start: 0x0A000000 Size: The size of the cartridge. This is a mirror of the ROM above. Used to allow multiple speed ROMs in a single game pak. ROM IMAGE 2: Start: 0x0C000000 Size: The size of the cartridge. This is a mirror of the ROM above. Used to allow multiple speed ROMs in a single game pak. CART RAM: Start: 0x0E000000 Size: 0 - 64 kb (Cowbite just allocates 64 kb at startup) This is either SRAM or Flash ROM. Used primarily for save games. 3. Video Modes The GBA has many graphics modes, including bitmapped modes, and tile based modes. The current video mode is set by the bottom three bits of REG_DISPCNT (see Hardware Registers section). Depending on the mode background data is handled differently. Backgrounds can be divided into the following three categories: "Text" Backgrounds: These are tile-based backgrounds that descend from the usage of tiles to display characters in text modes of a PC or workstation. They are made up of 8x8 tiles, the bitmaps of which are stored at the tile data address. The address of this data is set using registers REG_BG0 - REG_BG3. The SCX and SCY registers can be used to scroll around a larger area of up to 512x512 pixels (or 64 x 64 tiles). In text backgrounds, the data for each pixel is stored as an 8 or 4 bit palette index. In 8-bit mode, the palette is at 0x05000000 stores a 15-bit color value for each of the 256 palette entries. In 4-bit mode, the the map index contains a 4-bit value indicating which of 16 16-color palettes to use for each tile. Each of these palettes is 32 bytes long and can be found at 0x05000000, 0x05000020, etc. Scale/Rotate Backgrounds: These backgrounds are also tile-based, and operate similarly to Text Backgrounds. However, these backgrounds may also be scaled or rotated. Additionally they may only use 8-bit palettes, and can vary in size from 128 to 1024 pixels across. The palette is at 0x5000000, and contains 256 16-bit color entries Bitmapped Backgrounds: These backgrounds vary depending on the screen mode, but in all cases they rely on a single buffer upon which the image is drawn, either using an 8-bit palette or 16-bit color entries themsevles. For specific details on the format of background data and map entries, check out the section on REG_BG0 - REG_BG3 (addresses 0x04000008 - 0x0400000E). In all modes up to 128 sprites can be displayed as well as the 4 background layers. These use the second palette which is located at 0x05000200. See the OAM section for details on how to display sprites. Both background tiles and sprites use palette entry 0 as the transparent colour. Pixels in this colour will not be drawn, and allow other background layers and sprites to show through. The Game Boy Advance uses a uniform format for all palette entries and bitmap background colors. Color Format: All colors (both paletted and bitmapped) are represented as a 16 bit value, using 5 bits for red, green, and blue and ignoring bit 15. F E D C B A 9 8 7 6 5 4 3 2 1 0 X B B B B B G G G G G R R R R R R = Red, G = Green, B = Blue (unless it isn't obvious!) Mode 0: In this mode, four text background layers can be shown. In this mode backgrounds 0 - 3 all count as "text" backgrounds, and cannot be scaled or rotated. Check out the section on text backgrounds for details on this. Mode 1: This mode is similar in most respects to Mode 0, the main difference being that only 3 backgrounds are accessible -- 0, 1, and 2. Bgs 0 and 1 are text backgrounds, while bg 2 is a rotation/scaling backgrounds. Mode 2: Like modes 0 and 1, this uses tiled backgrounds. It uses backgrounds 1 and 2, both of which are rotate/scale backgrounds. Mode 3: Standard 16-bit bitmapped (non-paletted) 240x160 mode. The map starts at 0x06000000 and is 0x12C00 bytes long. See the Color Format table above for the format of these bytes. This allows the full colour range to be displayed at once. Unfortunately, the frame buffer in this mode is too large for page flipping to be possible. One option to get around this would be to copy a frame buffer from work RAM into VRAM during the retrace. I'm not sure whether the GBAs CPU is fast enough to do the transfer quickly enough though. Mode 4: 8-Bit paletted bitmapped mode at 240x160. The bitmap starts at either 0x06000000 or 0x0600A000, depending on bit 3 of REG_DSPCNT. Swapping the map and drawing in the one that isn't displayed allows for page flipping techniques to be used. The palette is at 0x5000000, and contains 256 16-bit color entries. Mode 5: This is another 16-bit bitmapped mode, but at a smaller resolution of 160x128. The display starts at the upper left hand corner of the screen, but can be shifted using the rotation and scaling registers for BG2. The advantage of using this mode is presumably that there are two frame buffers available, and this can be used to perform page flipping effects which cannot be done in mode 3 due to the smaller memory requirements of mode 5. Bit 3 of REG_DSPCNT sets the start of the frame buffer to 0x06000000 when bit 3 is zero, and 0x600A000 when bit 3 is one. Background Map Entry Format Text Background Map Format: The tile map, which stores the layout of the tiles on screen, begins at the tile map address found for a particular background, detrmined by REG_BG0 - REG_BG3. It has a selectable size up to 512x512. The tile map contains a 16-bit entry for each tile, with has the following format: F E D C B A 9 8 7 6 5 4 3 2 1 0 L L L L V H T T T T T T T T T T T = The tile number V = If this bit is set, the tile is flipped vertically upside down. H = If this bit is set, the tile is flipped horizontally left to right. L = Palette number For 256 x 256 and 256 x 512 backgrounds, the formula for calculating a map index is roughly, mapEntry = tileMapAddress[(tileY * 32) + tileX] For text mode sizes 512 x 256 and 512 x 512 backgrounds, however, the map is 64 tiles across, and these are stored in blocks of 32 * 32 tiles. This means that to calculate the map entry that would appear 33 tiles or more across the background, the following equation should be used: mapEntry = tileMap[(tileY * 32) + (tileX - 32) + 32*32] For entries 33 tiles or more down (in mode 11), use mapEntry = tileMap[( (tileY-32) * 32) + tileX + 2*32*32]; And for entries 33 tiles or more down and 33 tiles or more across, mapEntry = tileMap[( (tileY-32) * 32) + (tileX-32) + 3*32*32]; Rotational Background Map Format : A lot like bgs 0 and 1, but you only have 8 bits for each entry. The format for the tile map entries is 7 6 5 4 3 2 1 0 T T T T T T T T T = The tile number Rotational backgrounds do not divide tile maps into blocks. 4. OAM (sprites) The GBA supports 128 simultaneous sprites. These can be up to 64x64 pixels in size. The OAM, which starts at 0x07000000, has one entry for each of the 128 sprites. Intermixed with this data are the rotation/scaling attributes, of which there are 32 sets of 4 16 bit values. Each OAM entry is 8 bytes long and has the following format: Bytes 1 and 2 (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 J = Y co-ordinate of the sprite (pixels). Note that for regular sprites, this is the y coordinate of the upper left corner. For rotate/scale sprites, this is the y coordinate of the sprite's center. center . Note on Coordinates: The values actually wrap around: a -1 y is actually a y = 256. R = Rotation/Scaling on/off D = 0 - single fold, 1 - double angle. If D and R are 1 0, the sprite is turned off. TT = 00 - normal01 - semi-transparent (automatic blending as first source pixel) 10 - obj window 11 - illegal code M = enables mosaic for this sprite. A = 256 color if on, 16 color if off S = See below Bytes 3 and 4 (Attribute 1) F E D C B A 9 8 7 6 5 4 3 2 1 0 S S V H X X X I I I I I I I I I (standard sprites) S S F F F F F I I I I I I I I I (rotations/scaling on) I = X co-ordinate of the sprite (pixels). Note that for regular sprites, this is the x coordinate of the upper left corner. For rotate/scale sprites, this is the x coordinate of the sprite's center. Note on Coordinates: The values actually wrap around: a -1 x is actually an x = 512. H = The flip horizinal bit V = The flip vertical bit S = Size of the sprite. The top two bits of the size value are found in byte 1 and the bottom two bits are in byte 3. This forms a 4-bit value which sets the size of the sprite in the following way: 0000: 8 x 8 1000: 8 x 16 0001: 16 x 16 1001: 8 x 32 0010: 32 x 32 1010: 16 x 32 0011: 64 x 64 1011: 32 x 64 0100: 16 x 8 1100: Not used 0101: 32 x 8 1101: Not used 0110: 32 x 16 1110: Not used 0111: 64 x 32 1111: Not used F = For rotation scaling sprites, the index in into the rotation data to be used for that sprite. This index can be from 0 - 31. The rotation/scaling data is located in OAM attribute 3 (bytes 7 and 8). However, instead of the rotation and scaling data going with the corresponding sprite, it is separated accross four sequential sprites. This index can be thought of as referencing into an array of four-sprite blocks, 32 bytes each. Bytes 5 and 6 (Attribute 2) F E D C B A 9 8 7 6 5 4 3 2 1 0 L L L L P P T T T T T T T T T X L = Palette number. If you use 16 color palettes, this tells you which pallette number to use. P = Priority. This controls the priority of the sprite. Note thate sprites take precedence over backgrounds of the same priority. 11 : Back of screen 10 : Next layer up 01 : Next layer up 00 : Front of screen T = Tile number. This value indexes selects the bitmap of the tile to be displayed by indexing into the tile data area. (see below) Bytes 7 and 8 (Attribute 3) F E D C B A 9 8 7 6 5 4 3 2 1 0 S I I I I I I I F F F F F F F F S = Sign bit I = Integer F = Fraction. These bytes control sprite rotation and scaling. Instead of the rotation and scaling data going with the corresponding sprite, it is separated accross four sequential sprites. This is indexed by the F bits in attribute 2 (bytes 3 and 4). Note that these are all relative to the center of the sprite (background rotation/scaling is relative to the upper left). Starting with sprite 0 and repeating every 4 sprites, they appear in the following order: Sprite 0, Attribute 3 - DX/PA: Scales the sprite in the x direction by an amount equal to 1/(register value). Thus, a value of 1.0 results in the original image size, while a value of 2 is half as large, and a value of .5 is twice as large. Sprite 1, Attribute 3 - DMX/PB: Shears the x coordinates of the sprite over y. A value of 0 will result in no shearing, a value of 1.00 will make the image appear to be sheared left going down the screen, and a value of -1 will make the image appear sheared right going down the screen. Sprite 2, Attribute 3 - DY/PC: Shears the y coordinates of the sprite over x. A value of 0 will result in no shearing, a value of 1.00 will make the image appear to be sheared upwards to the right, and a value of -1 will make the image appear sheared downwards and to the right. Sprite 3, Attribute 3 - DMY/PD: Scales the image in the y direction by an amount equal to 1/(register value). Thus, a value of 1.0 results in the original image size, while a value of 2 is half as large, and a value of .5 is twice as large. To Make a Sprite Rotate and Scale: (Taken from PERN Tutorial Day 3) The basic form of the equations for rotating and scaling is as follows: pa = x_scale * cos(angle); pb = y_scale * sin(angle); pc = x_scale * -sin(angle); pd = y_scale * cos(angle); Sprite Tile Data The tile data area contains the actual bitmap for each tile. The sprites do not share tile data with the BG layers as on the Gameboy Color. The sprite tile data starts at 0x06010000. All tiles are 8x8 pixels large. Sprites use the second palette which begins at 0x05000200. For 256 color sprites, there are 64 bytes per tile, one byte per pixel. This is an 8-bit value which is an index into the 256 color palette. For 16-color sprites, attribute 2 (bytes 5 and 6) of the OAM data contains a 4 bit index into 16 16 color palettes, and sprites are 32 bytes per tile, with 4 bits per pixel. When the sprite is larger than 8x8 pixels, multiple tiles are glued together to make the sprite's width horizontally, and then vertically. How this is done depends on whether character data is stored in 2d or 1d mode (determined by bit 6 of DISPCNT). 1D Mapping: In 1D mode, tiles are stored sequentially. If you were to set up a 32x32 sprite, and set the tile number to 5, the sprite would be displayed as follows: --------------------- | 5 | 6 | 7 | 8 | | | | | | --------------------- | 9 | 10 | 11 | 12 | | | | | | --------------------- | 13 | 14 | 15 | 16 | | | | | | --------------------- | 17 | 18 | 19 | 20 | | | | | | --------------------- 2D Mapping: Tiles on each row of the sprite are stored 32 slots in. Using the same 32x32 sprite above, with a tile number of 5, the sprite would be displayed as: --------------------- | 5 | 6 | 7 | 8 | | | | | | --------------------- | 37 | 38 | 39 | 40 | | | | | | --------------------- | 69 | 70 | 71 | 72 | | | | | | --------------------- | 101| 102| 103| 104| | | | | | --------------------- 5. Windowing (As yet unimplemented in CowBite) Note that this section is entirely based on my (imperfect) understanding of windowing, based on what Mike/gbcft has discovered from his hardware tests, and I haven't really looked to closely at it myself. Windowing is a method of dividing the screen into subsections known as (surprise) windows. There are two windows, win0 and win1, which can be enabled in REG_DISPCNT. There is also the concept of "outside", "inside", and "sprite" windowing, the latter of which I don't know much about, but I might conjecture that it consists of the the regions of the screen occupied by sprites. The position and size of win0 and win1 are determined by REG_WIN0_H, REG_WIN1_H, REG_WIN0_V, and REG_WIN1_V (I/O offsets 0x40, 0x42, 0x44, 0x46). Exactly which characters and backgrounds appear within or without win0, win1, or the sprite window is determined by REG_WIN_IN and REG_WIN_OUT (0x48 and 0x4A). Here are some observations of Mike's which I have blatantly copied and pasted from one of his e-mails to me: - Window 0 is always on top of window 1. (Assuming window 0 is on) - BG windows appear on top of obj windows. Even if they have parts showing all the way through to the backdrop. - If a bg or the obj's are turned off in dispcnt, they're off in all windows regardless of the settings in win_in and win_out. - If only one window is on, win_out affects everything outside of it. (If both windows are on, win_out affects everything outside both of them. IE, it affects (!Win0)&&(!Win1) ) - If a window is on, but the effective display bits are all clear, the backdrop is displayed, and obj windows do not appear on it. - Everything in window 0 appears above window 1, and everything in windows 0 & 1 appears above win_out and obj windows. - If, fx, the right coordinate of window 0 is specified to be 130, the window is shown up to, but not including, pixel 130 (zero based). Same goes for the bottom. Left & Top pixels do include the specified pixel. 6. Hardware Interrupts Figuring out hardware interrupts was kind of painful. Everything below is what I have gleaned from reading ARM's docs, the list, the advice of other emulator and demo authors, and from various other emulator's debug info. I hope it is of some use to you. Key points: - All hardware interrupt vectors lie in the BIOS. You cannot handle interrupts directly, you must go through the BIOS. Thus, the instructions for exception handling in the ARM docs do not apply directly since we cannot handle the exceptions directly. - Interrupts are enabled by setting the flags in the REG_IE and hardware registers like REG_STAT, REG_KEYCNT, and REG_DMAXCNT. The flag must be set in both REG_IE and the corresponding hardware register for it to work. When the interrupt signal is sent, the appropriate flag is set in REG_IF. The program code unsets this flag (by writing a 1 to that bit) in order to keep track of what interrupts have been handled. - When an interrupt occurs, the CPU does the following: 1. Switches state to IRQ mode, bank-swaps the current stack register and link register (thus preserving their old values), saves the CPSR in SPSR_irq, and sets bit 7 (interrupt disable) in the CPSR. 2. Saves the address of the next instruction in LR_irq compensating for Thumb/ARM depending on the mode you are in. 3. Switches to ARM mode, executes code in BIOS at a hardware interrupt vector (which you, the programmer, never see) - The BIOS code picks up at the hardware interrupt vector and does the following: 4. Pushes registers 0 - 3, 12, LR_irq (which cointains the address following the instruction when the interrupt occrued) onto the stack 5. Places the address for the next instruction (in the BIOS, not in your code) in LR 6. Loads the address found at 0x03007FFC 7. Branches to that address. - The program code at that address is executed. 8. It is the responsiblity of the code at that address to return once finished, using BX LR_irq - The BIOS finishes up where your code leaves off: 9. It restores registers 0 - 3, 12, LR_irq 10. Branches to the intruction found in LR, using a SUBS PC, LR_irq, #4 - Upon receiving the SUBS PC, LR_irq, #4 instruction, the CPU 11. Copies the SPSR_irq back into the CPSR, restoring the status bits to their state when the interrupt occurred, and bank swaps back in the stack register and link register. The CPU will thus be placed in the correct state (ARM or Thumb) it was in when the exception occurred. So, the basic model for setting up interrupts is: 1. Place the address for your interrupt code at 0x03007FFC. 2. Turn on the interrupts you wish to use - 0x04000004 (REG_STAT) tells which interrupts the LCD will send - 0x04000200 (REG_IE) masks which interrupts the BIOS will actually service(?) I presume that both of REG_STAT and REG_IE must have the correct bits set for anything to work. - 0x04000208 (REG_IME) Turns all interrupts on or off. 3. When the interrupt is reached, the code at the address at 0x3007FFC gets loaded into the CPU. To prevent unwanted errors/behavior, the first thing this code should do is disable interrupts. 4. To determine what interrupt this is, check the flags in 0x04000202 (REG_IF). Unset the flag by writing a 1 to that bit. 5. Once finished with the service routine, reenable interrupts and execute a BX LR (*Not* a SUBS PC, LR #4, which is what the BIOS does). The BIOS will then take over and return your program to where execution left off. Types of Hardware Interrupts Enable these interrupts using REG_STAT, REG_TMXCNT, REG_KEYCNT, or REG_DMAXCNT, then setting the correct flags in REG_IE and REG_IME. V-Blank: Occurs when the vcount reaches 160, or 0xA0. (Enable in REG_STAT) H-Blank: Occurs at the end of every raster line, from 0 - 228. H-blank interrupts DO occur during v-blank, so write your code accordingly. Thanks to Mike for verifying this. (Enable in REG_STAT) Serial: I am unsure about this; I presume it has to do with the link cable. V-Count: Occurs when the vcount reaches the number specified in REG_STAT. Timer: These occur whenever one of the timer registers is set to cause an interrupt whenever it overflows. Enable in REG_TMXCNT. DMA: These occur according to the flags in the DMA_CNT registers and in REG_IE, either at vblank or hblank. Enable in REG_DMAXCNT. Key: Occurs when the user presses or releases the buttons specified in REG_KEYCNT. Cassette: Presumably occurs when the user yanks the cartridge out while the GBA is still running. Anyone care to verify? 7. BIOS (Software Interrupts) The BIOS calls are basically SWI instructions; the value passed into the instruction tells the CPU which interrupt to execute. There is very little public domain information on the BIOS. Marat Fayzullin has a listing of the BIOS calls on his VGBA website, and it is using this, in combination with observing how various emulators behave, that I was able to piece together what little I know. 0x00: SoftReset 0x01: RegisterRamReset 0x02: Halt 0x03: Stop 0x04: IntrWait 0x05: VBlankIntrWait --Waits for vblank to occur. Waits based on interrupt rather than polling in order to save battery power. 0x06: Div Input: r0 = numerator, r1 = denominator Output: r0 = numerator/denominator r1 = numerator % denominator; r3 = abs (numerator/denominator) 0x07: DivArm 0x08: Sqrt Input: r0 = number Output: r0 = sqrt(number) 0x09: ArcTan Input: r0 = angle Output: r0 = arctan(angle); 0x0A: ArcTan2 0x0B: CPUSet Input: r0 = source address r1 = dest address r2 (guess) - formatted like DMA transfer bit26 = 32 or 16 bit transfer bits 15 - 0 = number of transfers 0x0C: CPUFastSet Same as CPUSet. 0x0D: ???? 0x0E: BgAffineSet 0x0F: ObjAffineSet 0x10: BitUnPack 0x11: LZ77UnCompWRAM Input: r0 = source address r1 = dest address 0x12: LZ77UnCompVRAM Input: r0 = source address r1 = dest address 0x13: HuffUnComp Input: r0 = source address r1 = dest address 0x14: RLUnCompWRAM Input: r0 = source address r1 = dest address 0x15: RLUnCompVRAM Input: r0 = source address r1 = dest address 0x16: Diff8bitUnFilterWRAM 0x17: Diff8bitUnFilterVRAM 0x18: Diff16bitUnFilter 0x19: SoundBiasChange 0x1A: SoundDriverInit 0x1B: SoundDriverMode 0x1C: SoundDriverMain 0x1D: SoundDriverVSync 0x1E: SoundChannelClear 0x1F: MIDIKey2Freq Ox20: MusicPlayerOpen 0x21: MusicPlayerStart 0x22: MusicPlayerStop 0x23: MusicPlayerContinue 0x24: MusicPlayerFadeOut 0x25: MultiBoot 0x26: ?? 0x27: ?? 0x28: SoundDriverVSyncOff 0x29: SoundDriverVSyncOn ?: FIQMasterEnable 8. Memory-Mapped Hardware Registers The following section describes the function of each of the memory-mapped addresses in IO RAM. ------------------------------------------------------------------------ Addresses: 0x04000000 - 0x4000054 - Graphics Hardware Registers Address: 0x4000000 - REG_DISPCNT (The display control register) F E D C B A 9 8 7 6 5 4 3 2 1 0 W V U S L K J I F D B A C M M M M = The video mode. See video modes list above. C = Game Boy Color mode. Leave this at 0. A = This bit controls the starting address of the bitmap in bitmapped modes and is used for page flipping. See the description of the specific graphics mode for details. B = Whether the GBA will do OBJ processing during hblank. If set, it allows the GBA to render more sprites per scanline. Here is some simple math that shows how many tiles you can expect to be rendered with the bit on, provided by Shawn Freeman: Bit On: 308 dots /128 8x8 = 2.40625 dots per obj Bit Off: 240 dots / 2.40625 dots per obj = 99.7 objs D = Sets whether sprites stored in VRAM use 1 dimension or 2. 1 - 1d: tiles are are stored sequentially 0 - 2d: each row of tiles is stored 32 x 64 bytes in from the start of the previous row. F = Force the display to go blank when set. This can be used to save power when the display isn't needed, or to blank the screen when it is being built up (such as in mode 3, which has only one framebuffer). I = If set, enable display of BG0. J = If set, enable display of BG1. K = If set, enable display of BG2. L = If set, enable display of BG3. S = If set, enable display of OAM (sprites). U = Enable Window 0 V = Enable Window 1 W = Enable Sprite Windows Address: 0x4000004 - REG_STAT (Read-only) F E D C B A 9 8 7 6 5 4 3 2 1 0 T T T T T T T T X X Y H V Z G W W = V Refresh status. This will be 0 during VDraw, and 1 during VBlank. VDraw lasts for 160 scanlines; VBlank follows after that and lasts 68 scanlines. Checking this is one alternative to checking REG_VCOUNT (below). G = H Refresh status. This will be 0 during HDraw, and 1 during HBlank HDraw lasts for approximately 1004 cycles; HBlank follows, and lasts approximately 228 cycles, though the time and length of HBlank may in fact vary based on the number of sprites and on rotation/scaling/blending effects being performed on the current line. Z = VCount Triggered Status. This gets set to 1 when a Y trigger interrupt occurs. V = Enables LCD's VBlank IRQ. This interrupt goes off at the start of VBlank. H = Enables LCD's HBlank IRQ. This interrupt goes off at the start of HBlank. Y = Enable VCount trigger IRQ. This goes off when the VCount line trigger is reached. T = Vcount line trigger. Set this to the LCY/VCount value you wish to trigger an interrupt. Address: 0x4000006 - LCY / REG_VCOUNT This location stores the current y location of the LCD hardware. It is incremented as the lines are drawn. The 160 lines of display are followed by 68 lines of Vblank period, before the whole thing starts again for the next frame. Waiting for this register to reach 160 is one way to synchronize a program to 60Hz. Address: 0x4000008 - REG_BG0 Address: 0x400000A - REG_BG1 Address: 0x400000C - REG_BG2 Address: 0x400000E - REG_BG3 These addresses set up the four background layers. The format is: F E D C B A 9 8 7 6 5 4 3 2 1 0 Z Z V M M M M M A C 0 0 S S P P Z = Size of tile map For "text" backgrounds: 00 : 256x256 (32x32 tiles) 01 : 512x256 (64x32 tiles) 10 : 256x512 (32x64 tiles) 11 : 512x512 (64x64 tiles) For "rotational" backgrounds: 00 : 128x128 (16x16 tiles) 01 : 256x256 (32x32 tiles) 10 : 512x512 (64x64 tiles) 11 : 1024x1024 (128x128 tiles) M = Starting address of character tile map Address = 0x6000000 + M * 0x800 S = Starting address of character tile data Address = 0x6000000 + S * 0x4000 P = Priority - 00 highest, 11 lowest C = Mosiac effect - 1 on, 0 off A - Color palette type - 1 - standard 256 color pallete 0 - each tile uses one of 16 different 16 color palettes V - Area overflow. Used to determine whether rotational backgrounds get tiled repeatedly at the edges or are displayed as a single "tile" with the area outside transparent. Address: 0x4000010 - REG_BG0SCX Horizontal scroll co-ordinate for BG0 Address: 0x4000012 - REG_BG0SCY Vertical scroll co-ordinate for BG0 Address: 0x4000014 - REG_BG1SCX Horizontal scroll co-ordinate for BG1 Address: 0x4000016 - REG_BG1SCY Vertical scroll co-ordinate for BG1 Address: 0x4000018 - REG_BG2SCX Horizontal scroll co-ordinate for BG2 Address: 0x400001A - REG_BG2SCY Vertical scroll co-ordinate for BG2 Address: 0x400001C - REG_BG3SCX Horizontal scroll co-ordinate for BG3 Address: 0x400001E - REG_BG3SCY Vertical scroll co-ordinate for BG3 F E D C B A 9 8 7 6 5 4 3 2 1 0 X X X X X X S S S S S S S S S S S = Scroll value (pixels) These registers are only effective for text backgrounds; they set the pixel that is displayed in the top left hand corner of the GBA's display. In other words, a value of -5, -5 puts the upper left hand corner of your background at x=5,y=5. All four BG planes wrap when they reach their right or bottom edges. ------------------------------------------------------------------------ Addresses: 0x4000020 - 0x4000026 / 0x4000030 - 0x4000036 - Background Rotation/Scaling Registers (Tom: These are very hard to describe in words but easy to see the effects of on screen. I highly recommend checking out Stephen Stair's RSDemo - it lets you see the contents of the regs as you modify them as well as the effect they have on the background. Should also be somewhat useful for figuring out sprite rotation and scaling) F E D C B A 9 8 7 6 5 4 3 2 1 0 S I I I I I I I F F F F F F F F S = Sign bit I = Integer F = Fraction These registers apply only to Rotate/Scale backgrounds. Individual descriptions follow: Address: 0x4000020 - REG_BG2DX/PA Address: 0x4000030 - REG_BG3DX/PA The effect of these registers is to scale the background (relative to the upper left corner) in the x direction by an amount equal to 1/(register value). Address: 0x4000022 - REG_BG2DMX/PB Address: 0x4000032 - REG_BG3DMX/PB The effect of these registers is to shear the x coordinates of the background over y, relative to the upper left corner. A value of 0 will result in no shearing, a value of 1.00 will make the background appear to be sheared left as you go down the screen, and a value of -1 will make the background appear sheared right as you go down the screen. Address: 0x4000024 - REG_BG2DY/PC Address: 0x4000034 - REG_BG3DY/PC The effect of these registers is to shear the y coordinates of the background over x, relative to the upper left corner. A value of 0 will result in no shearing, a value of 1.00 will make the background appear to be sheared upwards to the right, and a value of -1 will make the background appear sheared downwards and to the right. Address: 0x4000026 - REG_BG2DMY/PD Address: 0x4000036 - REG_BG3DMY/PD The effect of these registers is to scale the background in the y direction (relative to the upper left corner) by an amount equal to 1/(register value). ------------------------------------------------------------------------ Address: 0x4000028 - REG_BG2X (X Coordinate for BG2 Rotational Background) Address: 0x4000038 - REG_BG3X (X Coordinate for BG3 Rotational Background) Address: 0x400002C - REG_BG2Y (Y Coordinate for BG2 Rotational Background) Address: 0x400003C - REG_BG3Y (Y Coordinate for BG3 Rotational Background) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 X X X X S I I I I I I I I I I I I I I I I I I I F F F F F F F S - Sign bit I - Integer F - Fraction These registers define the location of the pixel that appears at 0,0. They are very similar to the background scrolling registers, REG_SCX and REG_SCY, which become disabled when a rotate/ scale background is in use. Address: 0x4000040 - REG_WIN0_H (Window 0 X Coordinates) Address: 0x4000042 - REG_WIN1_H (Window 1 X Coordinates) F E D C B A 9 8 7 6 5 4 3 2 1 0 L L L L L L L L R R R R R R R R R = X coordinate for the rightmost side of the window L = X coordinate for the leftmost side of the window Address: 0x4000044 - REG_WIN0_V (Window 0 Y Coordinates) Address: 0x4000046 - REG_WIN1_V (Window 1 Y Coordinates) F E D C B A 9 8 7 6 5 4 3 2 1 0 T T T T T T T T B B B B B B B B B = Y coordinate for the bottom of the window T = Y coordinate for the top of the window Address: 0x4000048 - REG_WIN_IN (Inside Window Settings) F E D C B A 9 8 7 6 5 4 3 2 1 0 X X T S R Q P O X X L K J I H G G = BG0 in win0 H = BG1 in win0 I = BG2 in win0 J = BG3 in win0 K = Sprites in win0 L = Blends in win0 O = BG0 in win1 P = BG1 in win1 Q = BG2 in win1 R = BG3 in win1 S = Sprites in win1 T = Blends in win1 Address: 0x400004A - REG_WIN_OUT (Outside Window and Sprite Window) F E D C B A 9 8 7 6 5 4 3 2 1 0 X X T S R Q P O X X L K J I H G G = BG0 outside H = BG1 outside I = BG2 outside J = BG3 outside K = Sprites outside L = Blends outside O = BG0 in sprite win P = BG1 in sprite win Q = BG2 in sprite win R = BG3 in sprite win S = Sprites in sprite win T = Blends in sprite win Address: 0x400004C - REG_MOSAIC F E D C B A 9 8 7 6 5 4 3 2 1 0 V V V V U U U U J J J J I I I I I = BG X Size J = BG Y Size U = Sprite X Size V = Sprite Y Size Use this register to control the size of the mosaic on backgrounds/sprites. Address: 0x4000050 - REG_BLDCNT (As yet unimplemented in CowBite) F E D C B A 9 8 7 6 5 4 3 2 1 0 X X T S R Q P O M M L K J I H G G = Blend BG0 (1st source pixel) H = Blend Bg1 (1st source pixel) I = Blend BG2 (1st source pixel) K = Blend BG3 (1st source pixel) K = Blend sprites (1st source pixel) L = Blend backdrop (1st source pixel) M = Blend Mode There are four different modes: 00: All effects off 01: alpha blend 10: fade in 11: fade out O = Blend BG0 (2nd source pixel) P = Blend BG1 (2nd source pixel) Q = Blend BG2 (2nd source pixel) R = Blend BG3 (2nd source pixel) S = Blend sprites in alpha T = Blend backdrop in alpha The following examples are (roughly) from Nocturn's tutorial: For an alpha blend: BLDCNT = 0 | BIT06 | A1 | A2; Where A1 is the bits representing the layers you want to be the first source pixels, and A2 is the bits represeting the layers you wish to be the second source pixels. For a Fade: Darken: BLDCNT = 0 | BIT06 | BIT07 | A1; Lighten: BLDCNT = 0 | BIT07 | A1; Address: 0x4000052 - REG_BLDALPHA (As yet unimplemented in CowBite) F E D C B A 9 8 7 6 5 4 3 2 1 0 X X X B B B B B X X X A A A A A A = Coefficient A, the first source pixel B = Coefficient B, the second source pixel Use this in conjunction with REG_BLDCNT to determine the amount of blending between layers. I may be wrong on the size of A and B, but going on Nocturn's toturial, they each represent the fraction of the final result that each background contributes. Thus, if A is 12 and B is 4, the resulting image will appear to be 12/16 the color of A and 4/16 the color of B. Address: 0x4000054 - REG_BLDY (As yet unimplemented in CowBite) F E D C B A 9 8 7 6 5 4 3 2 1 0 X X X X X X X X X X X F F F F F F = The darken/lighten value This is the amount by which to fade into the pixel color specified in REG_BLDCNT. The higher the value, the greater the fade. ------------------------------------------------------------------------ Addresses 0x040000060 - 0x0400000A6 (Sound Controls: As yet unimplemented in CowBite) Note: I've obtained this info (much of it verbatim) from BeLogic's unofficial GBA sound info site, which gives a more thorough explanation as well as some sample source code and demos. Address: 0x04000060 - REG_SOUND1CNT_L (Sound 1 Sweep control.) Address: 0x04000062 - REG_SOUND1CNT_H (Sound 1 Length, wave duty and envelope control) Address: 0x04000064 - REG_SOUND1CNT_X (Sound 1 Frequency, reset and loop control) Address: 0x04000068 - REG_SOUND2CNT_L (Sound 2 Length, wave duty and envelope control) Address: 0x0400006C- REG_SOUND2CNT_H (Sound 2 Frequency, reset and loop control) I still don't know the functionality of these. Most likely I will have to wait for BeLogic to update their site with info before I can complete this section. Address: 0x04000070 - REG_SOUND3CNT_L (Sound 3 Enable and wave ram bank control) F E D C B A 9 8 7 6 5 4 3 2 1 0 X X X X X X X X N S M X X X X X M = Bank Mode (0 - 2 32 sample banks, 1 - 1 64 sample bank) S = Bank Select. Controls which bank is active for playing/reloading. If set to 0, samples are played from bank 0 and writing to the Wave Ram will store the data in Bank 1, and vice-versa. N = Sound Channel 3 output enable. When this is set and bit 15 from REG_SOUND3CNT_X is set, the sound starts to play. Sound channel 3 is a circuit that can produce an arbitrary wave pattern. Samples are 4 bit, 8 samples per word, and are located in Wave Ram registers from 0x400090 to 0x40009F. The Wave Ram is banked, providing the ability to play a 64 samples pattern or to select between two 32 samples patterns (Bit 5). Sound channel 3 always produces some audio artifacts (distortion) when sound is initialized. Fortunately, switching banks does not require re-initialisation during playback, thus allowing for dynamic reloading of the Wave Ram without generating any distortion. Both banks of Wave Ram are filled with zero upon initialization of the Gameboy, Bank 0 being selected. So writing to bank 0 implies setting bit 6 to 1 before loading Wave Ram then set it back to 0 to play it. Address: 0x04000072 - REG_SOUND3CNT_H (Sound 3 Sound length and output level control) F E D C B A 9 8 7 6 5 4 3 2 1 0 R R R X X X X X L L L L L L L L L = Sound length. The sound length is an 8 bit value obtained from the following formula: Register=Note length (in seconds)*256 Hence a 1 second maximum and a 3.9 millisecond minimum sound duration. After the sound length has be changed, the sound channel must be resetted via bit F of REG_SOUND3CNT_X. R = Output volume ratio: 000 - Mute 001 - 100% 100 - 75% 010 - 50% 011 - 25% Address: 0x04000074 - REG_SOUND3CNT_X (Sound 3 Frequency, reset and loop control) F E D C B A 9 8 7 6 5 4 3 2 1 0 R T X X X F F F F F F F F F F F F = Sound frequency. The minimum frequency is 64Hz and the maximum is 131Khz. Can be calculated from the following formula: F(hz)=4194304/(32*(2048-register value)). T = Timed sound. When set to 0, sound 3 is played continuously regardless of the length data in REG_SOUND3CNT_H. When set to 1, sound is played for that specified length and after that, bit 2 of REG_SOUNDCNT_X is reset. R = Sound reset. When set, sound resets and restarts at the specified frequency. Frequency and sound reset must be perfomed in a single write since both are write only. In continuous mode, frequency can be changed without resetting the sound channel. Address: 0x04000078 - REG_SOUND4CNT_L (Sound 4 Length, output level and envelope control) Address: 0x0400007C - REG_SOUND4CNT_H (Sound 4 Noise parameters, reset and loop control) As with Sound channels 1 and 2, I still don't know the functionality of these. Most likely I will have to wait for BeLogic to update their site with info before I can complete this section. Address: 0x04000080 - REG_SOUNDCNT_L (Sound 1-4 Output level and Stereo control) F E D C B A 9 8 7 6 5 4 3 2 1 0 R Q P O N M L K J I I I H G G G G = DMG Left Volume H = Vin Left on/off (?) - According to BeLogic, Vin on/off allowed the original GameBoy paks to provide their own sound source. It is unkown whether they still work on a GBA. I = DMG Right Volume J = Vin Right on/off (?) K = DMG Sound 1 to left output L = DMG Sound 2 to left output M = DMG Sound 3 to left output N = DMG Sound 4 to left output O = DMG Sound 1 to right output P = DMG Sound 2 to right output Q = DMG Sound 3 to right output R = DMG Sound 4 to right output This register controls only the DMG output amplifiers and have no effects on the individual sound channels' processing, or Direct Sound channels' volume. Address: 0x04000082 - REG_SOUNDCNT_H (Direct Sound control and Sound 1-4 output ratio) F E D C B A 9 8 7 6 5 4 3 2 1 0 Q P O N M L K J X X X X I H G G G = Output Sound Ratio for channels 1-4. 00 - 25% 01 - 50% 10 - 100% 11 - ?? H = Direct sound A output ratio (0 - 50%, 1 - 100%) I = Direct sound B output ratio (0 - 50%, 1 - 100%) J = Direct Sound A to right output K = Direct sound A to left output L = Direct sound A Sampling rate timer (timer 0 or 1). Use this to set which timer contorls the playback frequency. M = Direct sound A FIFO reset N = Direct sound B to right output O = Direct sound B to left output P = Direct sound B Sampling rate timer (timer 0 or 1). Use this to set which timer contorls the playback frequency. Q = Direct sound B FIFO reset This register is used in controlling Direct Sound on the GBA. Output ratios control the volume, in percentage, that gets output to the speakers. Address: 0x04000084 - REG_SOUNDCNT_X (Master sound enable and Sound 1-4 play status) F E D C B A 9 8 7 6 5 4 3 2 1 0 X X X X X X X X N X X X J I H G G = DMG Sound 1 Status (Read only). 0 - Stopped, 1 - Playing H = DMG Sound 2 Status (Read only). 0 - Stopped, 1 - Playing I = DMG Sound 3 Status (Read only). 0 - Stopped, 1 - Playing J = DMG Sound 4 Status (Read only). 0 - Stopped, 1 - Playing N = All Sound circuit enable This register is used to monitor the play status of sounds and to turn on or off all sound circuits. Turning the sound circuits off saves battery power, allowing them to last up to 10% longer. Address: 0x04000088 - REG_SOUNDBIAS (Sound bias and Amplitude resolution control) F E D C B A 9 8 7 6 5 4 3 2 1 0 R R X X X X X B B B B B B B B B B = PWM bias value, controlled by the BIOS. R = Amplitude resolutions 00 - 9 bit at 32768 hz 01 - 8 bit at 65536 hz 10 - 7 bit at 131072 hz 11 - 6 bit at 262144 hz The BIAS setting is used to offset the sound output and bring it back into a signed range. When the BIOS starts up, it runs a timing loop where it slowly raises the BIAS voltage from 0 to 512. This setting should not be changed. At best, the sound will become distorted. At worst the amplifier inside the GBA could be damaged. When accessing bits F-E, a read-modify-write is required. The default value for bits F-E is 00. Most if not all games use 01 for this setting. Address: 0x04000090 - REG_WAVE_RAM0_L (Sound 3 samples 0-3) Address: 0x04000092 - REG_WAVE_RAM0_H (Sound 3 samples 4-7) Address: 0x04000094 - REG_WAVE_RAM1_L (Sound 3 samples 8-11) Address: 0x04000096 - REG_WAVE_RAM1_H (Sound 3 samples 12-15) Address: 0x04000098 - REG_WAVE_RAM2_L (Sound 3 samples 16-19) Address: 0x0400009A - REG_WAVE_RAM2_H (Sound 3 samples 20-23) Address: 0x0400009C - REG_WAVE_RAM3_L (Sound 3 samples 23-27) Address: 0x0400009E - REG_WAVE_RAM3_H (Sound 3 samples 28-31) These registers together contain four (4 bytes each) 4-bit wave RAM samples for Sound channel 3. Address: 0x040000A0 - REG_FIFO_A_L (Direct Sound channel A samples 0-1) Address: 0x040000A2 - REG_FIFO_A_H (Direct Sound channel A samples 2-3) Address: 0x040000A4 - REG_FIFO_B_L (Direct Sound channel B samples 0-1) Address: 0x040000A6 - REG_FIFO_B_H (Direct Sound channel B samples 2-3) These are the locations of the Direct Sound 8-bit FIFO samples, from which Direct Sound pulls the music data to be played on the speakers. Note that there are only 8 bytes total for all your samples. You repeatedly fill these from a buffer of your own using DMA0 or DMA1, or by using timer interrupts. To fill them using DMA, first set Timer 0 or Timer 1 to refresh at the appropriate sample rate (for example, 16khz). Next, set the DMA source address to a sound sample in memory, and the destination address to one of these FIFO registers. Use REG_SOUNTCNT_H to reset FIFO and tell Direct Sound to get its sampling rate from Timer 0 or Timer 1. Finally, set the DMA control register to start on FIFO empty (start mode 11) and to repeat, then enable the timers. All of this will cause the hardware to play sound samples in FIFO at the rate specified in your timer, and automatically refill them using DMA. To fill these using interrupts, follow a similar process, but instead of using DMA, set the clock to interrupt on overflow. When using interrupts instead of DMA, BeLogic recommends setting the timer divider to 1024 and start the timer at 0x0000 order to get a sampling rate of 16.384 khz. This apparently causes less distortion than if you simply set the start time of the clock to 0xFFFF - (2^24/16000). Note that reading from these registers can yield unpredictable results. It might be interesting to see just how unpredictable... ------------------------------------------------------------------------ Addresses: 0x4000100 - 0x400010E (Timer registers: As yet unimplemented in CowBite) Address: 0x4000100 - REG_TM0DAT (Timer 0 Data) Address: 0x4000104 - REG_TM1DAT (Timer 1 Data) Address: 0x4000108 - REG_TM2DAT (Timer 2 Data) Address: 0x400010C - REG_TM3DAT (Timer 3 Data) F E D C B A 9 8 7 6 5 4 3 2 1 0 D D D D D D D D D D D D D D D D D=Current count of the timer. Note that thse registers are R/W. The default is to start counting from 0x0000, but if a value is written to this register, the timer will henceforth use that as a starting value. Thus the rate at which timers overflow and generate interrupts (see REG_TMXCNT, below) can be customized. Timer 0 and Timer 1 are used to control the rate of Direct Sound FIFO. When using DMA with start mode 11, they can automatically cause it to refill the FIFO. To set the rate of playback in hz, write the value 0xFFFF - (2^24/Plaback Freq in hz) to the register. This sets the start value such that the timer will overflow precisely when the next sound sample is needed, and cause the DMA to activate. When using interrupts, set the start value of these to 0, but use REG_TMXCNT to change the update frequency to 1024, thus causing an interrupt rate of 16.384khz. Address: 0x4000102 - REG_TM0CNT (Timer 0 Control) Address: 0x4000106 - REG_TM1CNT (Timer 1 Control) Address: 0x400010A - REG_TM2CNT (Timer 2 Control) Address: 0x400010E - REG_TM3CNT (Timer 3 Control) F E D C B A 9 8 7 6 5 4 3 2 1 0 X X X X X X X X E I X X X C F F F=Frequency at which the timer updates 00: Default frequency (full) - 16.78MHz (~17mlns ticks per second) 01: Every 64 clock pulses - ~262187.5KHz 10: Every 256 clock pulses - ~65546.875KHz 11: Every 1024 clock pulses - ~16386.71875KHz C=Cascade. When this bit is set, the frequency of this timer is ignored. Instead the timer increments when the timer below it overflows. For example, if timer 1 is set to cascade, it will increment whenever timer 0's value goes from 0xFFFF to 0x0000. I=Generate an interrupt on overflow E=Enable the timer. ------------------------------------------------------------------------ Addresses 0x4000130 - 0x4000132 - Keypad Input and Control Registers Address: 0x4000130 - REG_KEY (The input register) F E D C B A 9 8 7 6 5 4 3 2 1 0 X X X X X X J I D U L R S E B A A = A button B = B button E = Select button S = Start button R = D-pad Right L = D-pad Left U = D-pad Up D = D-pad Down I = Right shoulder button J = Left shoulder button This register stores the state of the GBA's buttons. Each of the inputs is active low. This means that a '0' bit indicates that the key is pressed, while a '1' bit indicates that the key is not pressed. In general a game which samples these (rather than using interrupts) should do so once every refresh (60hz), or more in the case of fast action fighting games (like Street Fighter). Address: 0x4000132 - REG_KEYCNT (Key Control Register - As yet unimplemented in CowBite) F E D C B A 9 8 7 6 5 4 3 2 1 0 T K X X X X J I D U L R S E B A A = A button B = B button E = Select button S = Start button R = D-pad Right L = D-pad Left U = D-pad Up D = D-pad Down I = Right shoulder button J = Left shoulder button K= generate interrupt on keypress G= interrupt "type" 0: "OR" operation -- interrupt will be generated if _any_ of specified keys (bits 0-9) is pressed 1: "AND" operation, interrupt will be generated if _all_ specified keys are pressed at the same time. Use this register to set which keypresses generate interrupts. The appropriate bits must also be set in REG_IE and REG_IME. ------------------------------------------------------------------------ Addresses: 0x40000B0, 0x40000BC, 0x40000C8, 0x40000D4 (DMA Source Registers) Address: 0x40000B0 - REG_DMA0SAD (DMA0 Source Address) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 X X X X X A A A A A A A A A A A A A A A A A A A A A A A A A A A A = 27-bit source address This is the source address for DMA channel 0 transfers. Note that it is 27-bit. Address: 0x40000BC - REG_DMA1SAD (DMA1 Source Address) Address: 0x40000C8 - REG_DMA2SAD (DMA2 Source Address) Address: 0x40000D4 - REG_DMA3SAD (DMA3 Source Address) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 X X X X X A A A A A A A A A A A A A A A A A A A A A A A A A A A A = 28-bit source address This is the source address for DMA channel 1, 2, or 3 transfers. Note that it is 28-bit. Addresses: 0x40000B4, 0x40000C0, 0x40000CC, 0x40000D8 (DMA Destination Registers) Address: 0x40000B4 - REG_DMA0DST (DMA0 Destination Address) Address: 0x40000C0 - REG_DMA1DST (DMA1 Destination Address) Address: 0x40000CC - REG_DMA2DST (DMA2 Destination Address) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 X X X X X A A A A A A A A A A A A A A A A A A A A A A A A A A A A = 27-bit destination address This is the dest address for DMA channel 0, 1, and 2 transfers. Note that it is 27-bit. Address: 0x40000D8 - REG_DMA3DST DMA3 Destination Address 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 X X X X X A A A A A A A A A A A A A A A A A A A A A A A A A A A A = 28-bit destination address This is the dest address for DMA channel 3 transfers. Note that it is 28-bit. Addresses: 0x40000B8, 0x40000C4, 0x40000D0, 0x40000DC (DMA Count Registers) Address: 0x40000B8 - REG_DMA0SIZE DMA0 Count Register Address: 0x40000C4 - REG_DMA1SIZE DMA1 Count Register Address: 0x40000D0 - REG_DMA2SIZE DMA2 Count Register Address: 0x40000DC - REG_DMA3SIZE DMA3 Count Register F E D C B A 9 8 7 6 5 4 3 2 1 0 X X L L L L L L L L L L L L L L (Note: In some places you will see the DMA control and DMA count registers depicted as a single 32-bit register. I opted to treat them as two 16-bit registers for sake of clarity.) L = Number of words or halfwords to copy Addresses: 0x40000BA, 0x40000C6, 0x40000D2, 0x40000DE (DMA Control Registers) Address: 0x40000BA - REG_DMA0CNT DMA0 Control Register Address: 0x40000C6 -REG_DMA1CNT DMA1 Control Register Address: 0x40000D2 - REG_DMA2CNT DMA2 Control Register Address: 0x40000DE - REG_DMA3CNT DMA3 Control Register F E D C B A 9 8 7 6 5 4 3 2 1 0 N I M M X S R A A B B X X X X X (Note: In some places you will see the DMA control and DMA count registers depicted as a single 32-bit register. I opted to treat them as two 16-bit registers for sake of clarity.) B = Type of increment applied to destination address. If enabled, the address will be incremented/decremented by 2 or 4 bytes, depending on the selected size. Writeback implies that the value in the address register will be updated after the transfer to point to the address following that of the last word/halfword transfered. 00: Increment and writeback after each copy 01: Decrement and writeback after each copy 10: Leave unchanged 11: Increment without writeback after each copy A = Type of increment applied to source address: 00: Increment and writeback after each copy 01: Decrement and writeback after each copy 10: Leave unchanged 11: Illegal Note: I am somewhat uncertain about option "11" for both of these. Can anyone confirm? R = Repeat. When in start modes 1 or 2, this bit causes the transfer to repeat for each interval. S = Size. If set, copy 32-bit quantities (words) If clear, copy 16-bit quantities (half words) M = Start Mode. 00: Transfer immediately 01: Transfer on vblank 10: Transfer on hblank 11: I have read various accounts of what this does, depending on what DMA channel is being used and what it's used for. For DMA 1 or 2: Instructs the DMA to repeat on FIFO-empty requests. Used for Direct Sound. For DMA 3: Apparently allows transfers to start at the beginning of a rendering line, copying data into a buffer as the line is being drawn on the screen. Useful for flicker-free transfers in mode 3, which has no backbuffer. I = IRQ. Setting this bit causes the DMA to generate an interrupt when it is done with the data transfer. N = Enable DMA operation This address controls a DMA transfer which allows large amounts of data to be transferred from one area of memory to another. It can also be used to clear memory to a constant value, if the source address is not incremented with each copy. Fist, set the DMASAD and DMADAD registers to point to the addresses you want. Writing to DMACNT address with a '1' in the N field and a '00' in the M field will start the transfer immediately. DMA transfers may occur on an interrupt if the start mode bits are set. DMAs have a priority ranking with 3 at the lowest and 0 at the highest. For most cases, program code will be using DMA3. Sound FIFO DMA (and I need some verification on this) requires DMA1 and DMA2, and if a your program is transfering data using DMA3, it gets interrupted by the sound DMA and thus the sound does not get out of sync. DMA0 is the highest priority, but is limited in that it may only be used for transfers to and from internal memory (thus, cannot be used for ROM transfers). It could be used for something higher priority, such as updating the rotate/scale registers every hblank. ------------------------------------------------------------------------ Addresses 0x4000200 - 0x4000208 - Interrupt Registers Address: 0x4000200 - REG_IE (Interrupt Enable Register) F E D C B A 9 8 7 6 5 4 3 2 1 0 X X T Y G F E D S L K J I C H V V = VBlank Interrupt H = HBlank Interrupt C = VCount Interrupt I = Timer 0 Interrupt J = Timer 1 Interrupt K = Timer 2 Interrupt L = Timer 3 Interrupt S = Serial Communication Interrupt D = DMA0 Interrupt E = DMA1 Interrupt F = DMA2 Interrupt G = DMA3 Interrupt Y = Key Interrupt T = Cassette Interrupt Use this register to mask out which interrupts are enabled or disabled. Address: 0x4000202 - REG_IF (Interrupt Flags Regster) F E D C B A 9 8 7 6 5 4 3 2 1 0 X X T Y G F E D S L K J I C H V V = VBlank Interrupt H = HBlank Interrupt C = VCount Interrupt I = Timer 0 Interrupt J = Timer 1 Interrupt K = Timer 2 Interrupt L = Timer 3 Interrupt S = Serial Communication Interrupt D = DMA0 Interrupt E = DMA1 Interrupt F = DMA2 Interrupt G = DMA3 Interrupt Y = Key Interrupt T = Cassette Interrupt This register will determine which interrupt is currently being serviced. When your interrupt service routine get scalled, check these flags to determine what called it. In order to keep yourself from servicing the wrong interrupt at a later time, you should reset the flags to 0 by writing a 1 to them. If you don't think you'll have multiple interrupts occuring at once, you can simply read this into one of your registers and then write it back again to unset all the bits. Address: 0x4000208 - REG_IME (Interrupt master enable) F E D C B A 9 8 7 6 5 4 3 2 1 0 X X X X X X X X X X X X X X X M M = Master interrupt enable. When this is on, interrupts on the GBA are enabled. When off, all interrupts are disabled. ------------------------------------------------------------------------ 9. Links The following are links to other documents which should prove useful to GBA developers: www.gbadev.org The Pern Project Mappy SDK ARM's Technical Reference Manuals The Audio Advance 10. Thanks Agent Q (For revision 1.0) All those GBA demo authors. You rock! Every other emu author www.gbadev.org The gbadev list on yahoo Dovoto and the PERN Project Nocturn and his tutorial The folks at BeLogic for all the great information on the GBA's sound! Nintendo Also, Kudos to the following for e-mailing me with info and corrections: Costis (A variety of new info/corrections) Grauw (Info on forced blanking, hblank lenghths, and on the BIOS wait function.) Max Mike/gbcft (LOTS of info on interrupts and on windowing) Otaku Yarpen (Almost all the information on the timer registers and the keyboard control register. Thanks!) GBA and game Boy Advance are registered trademarks of Nintendo. CowBite is copyright 2001 Thomas Happ