GBA development


Published: July 2008

Some time ago I worked a little bit on GBA programming. I'll share with you the process just in case you want to make games for your GBA.

The toolchain

The easy way is to download DevKitPro, but you know the easy way sucks. I'd link to a place with the hardway, but the link died, so I'll link to webarchive. You have a PDF with all the info too.

Web-Archive Link

PDF file

Last time I tried to compile using gcc 4.4 got an error whle compiling arm.c, the line DECL_RTL (sym) = new; needs to change into SET_DECL_RTL(sym,new); I suppose it did compile with older gcc versions but not anymore.

By using this toolchain (which is ARM generic) you'll need a linkerscript and a crt0.S suited for the GBA, which will set up everything and map the code and data into the correct memory addresses. You can load a gba binary without a flashcard just using a link cable (can be done using the parallel port to simulate the other GBA).  This linkscript arranges everything if that's the case (booting without flashcard uses another boot address). Have a look at this link, great site BTW. You can get the needed versions (or recommened) of the packages above at:

ftp://sources.redhat.com/pub/newlib/newlib-1.11.0.tar.gz

http://ftp.gnu.org/gnu/gcc/gcc-3.0.4/gcc-3.0.4.tar.gz

http://ftp.gnu.org/gnu/binutils/binutils-2.11.2.tar.gz

Understanding the ARM CPU

I'm not an expert in CPUs so what I say is basic and sometimes I'm wrong, so feel free to correct me. The ARM processor carried by the GBA has two operation modes: ARM and THUMB. The first one uses 32bit instructions and the second one uses 16bit instructions. And why are you telling me this? you may ask. Because GBA has only a 16bit bus (I'm talking about the ROM bus, there are some other buses), so ARM mode is slow (2 bus cycle time for an instruction fetch). So you must use -mcpu=arm7tdmi with the flags to produce THUMB instructions.

And what if you don't care about speed and just produce ARM code? It won't work. Just have a look at crt0.S, at the startup it does some set up like interruption handling, and other stuff like changing the processor to THUMB mode. So if you want to use ARM code instead of THUMB code you have two options: change the crt0.s and delete those lines (not recommened because next lines in the file are THUMB too (look at the .THUMB)! you'll have to translate or something) or just change back to ARM code at you application startup.

Typically you may use some ARM functions because ARM instructions are powerful. You can copy those functions to IWRAM (whichs is fast and has a 32bit bus) and then call them. But this is quite advanced because you'll need to learn some assembly and take care of code relocations (you can't just copy binary code and expect it to work, just think in jmp instruction with absolute address).

Compiling something

To compile for GBA you must use the arm gcc and ld provided by the toolchain. Compile as usual and you'll get an ELF file. This ELF file contains lot of shit for use under a Linux ARM OS (sections, relocation info, library link, etc.), so it will be useless unless you do something. If you have a look at the makefile of my demo you'll see:

arm-thumb-elf-objcopy -O binary exec.elf exec.gba

What this awesome tool does is to copy the raw code and data to the destination file without anything else. So you get a file similar to those hex files used, for example, in firmwares. It does only contain instructions (and the data of course).

Now you can use the file in your favourite flashcard (you'll need some rom patching depending on the cartridge) or just run it on an emulator.

Loading data

To load data you can use an easy way, as GBA is disk-less. The ROM is mapped at address 0x8000000, so in the first byte is your first instruction. You can add the data at the end of your program by just concatenating it. Now access the data using the address 0x8000000 plus the length of the file produced by objcopy. My trick is to use a fixed ROM size, for example, imagine my program is about 50KB. I just add some zeros to make it 128KB (to allow further expansion of the code and the the data) and to access the data I just do 0x8000000 + 128*1024 and I get the first byte of data. To create something like a "filesystem" use your imagination: a table with filenames, size and offsets, etc. If you don't enjoy thinking by yourself take a look at TONC's site, he has plenty of functions for those things in is his library.

The demo

Here is a demo with source so you can have a look at it.

Download demo source code

Download GBA file (ready to use)

As you can see I implemented some kind of tile editor and physics interactions.

Tile editor

Must visit links

GBA Tonc A very smart guy which knows a lot on GBA. Has his own library. http://gbadev.org

GBADev.org The center of all gba development.

Edit

I tried the demo again after three years because I was bored and found that I needed to delete the default ctr0.o created by the toolchain installation. I don't know how to avoid the linkage but it seems that ld tries to link with the first crt0.o file it found giving priority to the installatiion directory.

I also found some random screenshots of my old laptop while I was doing some of this. It looks pretty interesting, definitely brings some memories! I was probably testing horizontal scrolling at that moment, which can be non-trivial to get right. It also seems I didn't get the pixel format right at the first try :)

My old laptop screenshot

Another laptop screenshot

Downloads