Hello Gameboy Advance

Last weekend while digging around on one of my USB sticks, I found some old test code I wrote for the GBA over 10 years ago. I though the files were lost forever, so I was quite happy that I found them. The code itself was written in an obscure assembler for Windows, so my first goal was to port it to a more modern tool that preferably could cross assemble on both my PC and Mac. I decided to give the vasm a try. After some initial problems with strange syntax and me not understanding what the error messages meant, I got it to assemble into a binary file. To my surprise, the resulting binary could be loaded into the emulator and it worked the way it should! From there I cleaned up the code, removing stuff I didn’t need for the Hello World Project and added the result to the repository.

The code

This is by far the shortest example to date. The video mode I chose made it very easy to draw graphics on screen, and the setup required is minimal. A short note before we continue; the semantics of the data types are not the same as on the 68k processor. On Arm, a word is 32-bit, while on the 68k it’s 16-bit. This can occasionally cause some confusion, at least it has for me when my focus was not high enough.

At the beginning we tell the assembler to use the arm instruction set (which is 32 bit, as opposed to the thumb instruction set that has 16 bit instructions). Then we tell it that the following code will be executed at position 0x08000000, which is where the GBA ROM entry point is.

The first instruction we run makes a jump (branch) over the ROM header. After the branch, we define the GBA header. I have no idea why the values in the header are what they are or if they are correct, but this is what my old code did, and the emulators I’ve tried haven’t complained yet.

Lets begin by setting the display mode. By setting Mode 4, we get 256 colour chunky graphics mode, i.e. each byte in the graphics memory corresponds to the color at that position in the palette. In Mode 4, only background 4 is used, so we need to enabled that background layer.

Time to setup the palette. Since the graphics only consists of two colours, we read both colours from the palette data in one go and writes them to the palette memory. Each entry in the palette consists of two bytes, with packed RGB data, 5 bits per channel. The least significant bits are the red channel, the next 5 bits are green and finally 5 bits representing the blue channel. The most significant bit is ignored.

Time to update the screen with some pixels. Here we setup two nested loops, on for row and one for column. For each pixel on each row, a color entry is read from the pixel data and written to screen. To optimize a bit, we handle four pixels at a time, and also, it is not possible to write just one byte to the VRAM; doing so will result in the same value being written to the other byte in the other half of the 16-bit location.

There is one thing in the loop above that might be hard to understand without further explanation. I’m thinking about the [r4,#4]! syntax. What is does is access the data pointed to by r4 + 4 bytes; the exclamation mark at the end indicates that the r4 register will be updated with the same offset that was used in the access. So, 4 will be added to r4 after the data access. r3 and r4 will therefore increase after each read/write, so the source and destination addresses will be updated for every iteration in the loop.

We have reached the end of the executable code and here we just enter an infinite loop by jumping to the same location forever.

Now all code is done and we reach the data. First we have two entries of colour data; black and white. These are the values that are written to the palette register.

And finally the graphics data. Same graphics as the other examples, except here we have indexed colour mode, so 0 means colour 0 in palette, and 1 means colour 1 in palette. Simple as that.

That is it. I’m quite fond of the ARM assembly language, it’s quite readable compared to, oh say PowerPC assembler code.


There are many site on the internet dedicated to programming Gameboy and Gameboy Advance. Here are a few links that might be useful. Since the original version of my code was written over 10 years ago, I can’t give links to the resources I used initially, but I hope the links below fill your needs.

2 thoughts on “Hello Gameboy Advance

  1. DanielG

    on Arm, a word is 32-bit, while on the 68k it’s 32-bit.
    I can see how that will be a problem.


Leave a Reply

Your email address will not be published. Required fields are marked *