Gameboy Advance

From SizeCoding
Jump to: navigation, search

Game Boy Advance

The Game Boy Advance uses an ARM7TDMI Processor running at 16.7 MHz, 384kb of memory and a 240x160 pixel resolution. The ARM7TDMI supports both the 32-bit ARM instruction set (where every instruction is 32 bits wide) and the original Thumb 1 instruction set (16 bits wide except for jumps, and does not support every instruction in 32-bit ARM). Registers are always still 32-bit. The CPU also has a fast multiplier.

While the CPU is 32-bit, most of the system buses are only 16 bits wide. All IO is memory-mapped, and the instruction set is a load-store architecture.

Setting up

Setting up your development platform for the Gameboy Advance:

  • Assembler: GNU Assembler (easiest is to use the devkitARM toolchain), VASM
  • Emulator(s): mGBA, NanoBoyAdvance, NO$GBA

Video display

The Game Boy Advance has many graphics modes to play in both 256 colors as well as 15-bit direct RGB access, as well as support for tilemaps and 128 hardware sprites with a max 64x64 resolution.

Getting something on screen

Easiest way to get something on-screen is to use the "direct" bitmap RGB mode. This can be done by writing 0x0403 (mode 3, enable BG2 only) to the DISPCNT register (at 0x04000000). The bitmap memory can then be written to in VRAM (0x06000000). Note that VRAM must be written to using 16-bit writes, 8-bit writes will be ignored!

Some prods use multiple backgrounds with scrolling or sprites as well. See GBATEK on how to use these.

Vsync can be implemented by polling the DISPSTAT register (0x04000004)

Sound

The Game Boy Advance has 4 channel sound + 2 x DMA for digital audio.

Make some noise

To be added soon.

Compression

The GBA bootROM/BIOS contains RLE, LZ77, Huffman and "bit unpack" decompression routines. These can be called using the swi 0xXX instruction (where XX is the SWI number, see GBATEK). If your code is large enough, it can benefit from this. It is best to load the decompressed code into (fast) IWRAM at 0x03000000, as it has a very fast access time and is one of the few memories with a 32-bit-wide bus. devkitARM contains tools to compress your data in the correct format, and vl4d has written a small decompression stub. This prod can be used as an example.

ROM Header

The Game Boy Advance ROM header is 192 bytes in size, where 156 bytes are reserved for the Nintendo logo. The first 4 bytes in the ROM header is a ARM-branch instruction to the actual code. The following 156 bytes are the mandatory Nintendo Logo. At offset 0x00A0 the header expects a game title in maximum 12 bytes. These 12 bytes can be reused by inserting instructions instead of a game title. Following the game title, the next 4 bytes are the game code, which can also be used for instructions. After the game code, 2 bytes for the maker code are reserved, which can be used, when already changed into THUMB-Mode. The next byte is fixed and has to be always 0x96. The next byte is free, but hardly to make usage of. One could try to create a useful instruction using the byte before or in general here could be stored some value. After this, another 8 bytes can be used for instructions from offset 0x00B4. At offset 0x00BD a complementary check for the header has to be calculated. If the calculated checksum is different than the stored value, the ROM won't boot. Since some values in the header are fixed, which normaly should be jumped over, one can analyse the resulting instructions created by that fixed bytes and decide whether just slide through it.

Note that some parties do not count the 156 byte logo towards the total file size, see for example these three prods.

Additional Resources