Contents | Contents | Hardware |
TONC consists of three parts: a text section, the actual tutorial, a code section, which contains all the source code and makefiles of the various demos, and a bin section that contains binaries of the demo. Though they are separate zip files, they work best when used together. You can find the zip files further down this page. If you unzip them in one directory, say tonc, you'll get the structure depicted in fig ii.1.
The text section covers the principles of GBA programming in detail. The focus here is not so much on how to get something done, but how things actually work, and why it's done the way it's done. After that the how often comes naturally. Every chapter has one of more demonstrations of the covered theory, and a brief discussion of the demo itself. Please, do not make the mistake of only reading the demo discussion: to properly understand how things work you need to read the text in full. While there are optional parts, and whole pages of boring text that seem to have little to do with actual GBA coding, they are there for a reason, usually there's extra conceptual information or gotchas.
At first, the text part had only very little code in it, because I figured the demo code would be at hand and flicking between them would not be annoying. Well, I've realized that I figured wrong and am in the process of including more of the code into these pages; maybe not quite enough to copy-paste and get a clean compile, but enough to go with the explanations of the demos.
The main language will be C, and a smidgeon of assembly. These are the two main languages used in GBA programming even though there are others around. Since the basics of programming are independent of language, it should be possible to adapt them for your chosen language easily.
GBA programming is done close to the hardware, so I hope you know your pointers, hexadecimal numbers and boolean algebra/bit-operations. There's also a fair amount of math here, mostly vector and matrix stuff so I hope your linear algebra is up to speed. Lastly, I am assuming your intellectual capacities exceed those of a random lab monkey, so I won't elaborate on what I consider trivial matters too much.
Aside from the introduction and appendices, the text is divided into 3 parts. First there's ‘basics’, which explains the absolute essentials for getting anything done. This includes setting up the development environment, basic use of graphics and buttons. It also contains text on what it means to do low level programming and programming efficiently; items that in my view you'd better learn sooner rather than later. The second part covers most of the other items of the GBA like special graphic effects, timers and interrupts. The final section covers more advanced items that uses elements from all chapters.This includes writing text (yes, that's an advanced topic on the GBA), mode 7 graphics and a chapter on ARM assembly.
Individual html:
tonc-text.zip (663 kb)
Compiled html (CHM, v1.4 version):
tonc.chm (1.2 MB).
PDF:
tonc.pdf (3.1 MB)
The source code to all the demos mentioned in the text can be found in the code directory. Like the text, the code is divided into 3 main parts: basic, extended and advanced. The basic projects are (hopefully) pretty newbie friendly. They're completely self-contained so you can toy with them and not worry about screwing up other parts. The extended projects take their GBA-related code from tonclib, a library with all my #defines and important functions. The advanced demos also use tonclib liberally and will use some assembly files, even if it is just for data. There is also a lab directory with a few interesting projects, but which might not be quite ready. Still interesting to look at, though.
Unlike most GBA tutorials, tonc uses makefiles rather than batchfiles to build the projects, because they're just Plain Better than batchfiles. However, as a lot of you will probably never seen them before, these also come in three stages of difficulty. There is a master makefile, tonc.mak, in the code root directory that can drive the projects, and the vc6 directory has a Visual C++ project that you can use if you're on Windows and have Visual Studio version.
Pretty much all of the general functions used in tonc can be found in tonclib. This includes text writers for all modes, BIOS routines, a pretty advanced interrupt dispatcher, safe and fast memory copy and fill routines and much more. It's well worth stealing from.
Download tonc-code.zip (198 kb).
The bin directory contains the binaries of the demos. Each of them has been tested on a number of emulators, and on hardware using a homemade Xboo communication cable (see www.devkitpro.org for instructions on how to make one). In most instances they behave exactly the same. The readme tonc_bins.txt indicates when and where hardware and emulators disagree.
Download tonc-bin.zip (167 kb).
I wrote Tonc for two reasons. Firstly, as a way to organize my own thoughts. You often see things in a different light when you write things down and learn from that experience. Secondly, there is a lot of very bad information in other tutorials out there (the only exceptions I know of are the new PERN and Deku's sound tutorial[b0rked]). Yes, I am aware of how that sounds, but unfortunately it happens to be true. A number of examples:
If you are new and have followed the other tutorials, everything will seem to work fine, so what's the problem? Well, that's part of the problem actually. Everything will seem fine, until you start bigger projects, at which time you'll find hidden errors and that slow code really bogs things down and you'll have unlearn all the bad habits you picked up and redo everything from the start. The GBA is one of the few platforms where efficient coding still means something, and sometimes all it takes is a change of datatype or compiler switch. These things are better done right from the start.
I've tried to go for completeness first, simplicity second. As a certain wild-haired scientist once said: “Make things as simple as possible, but no simpler.” This means things can seem a little technical at times, but that's only because things are pretty technical at times, and there's no sense in pretending they're not.
In short, Tonc is not “GBA Programming for Dummies”, never was, never will be. There's far too much of stuff for Dummies already anyway. If you consider yourself a dummy (and I do mean dummy, not newbie), maybe Tonc isn't the right place. If you're serious about learning GBA programming, however, accept no substitute.
I'm a physicist by training which means that I know my math and its notational conventions. I use both quite often in Tonc, as well as a number of html-tag conventions. To make sure we're all on the same page here's a list:
Type | notation | example |
---|---|---|
bit n in a foo | foo {n}
| REG_DISPCNT{4} (active page bit)
|
code | <code> tag | sx
|
command/file | <tt> tag | vid.h |
matrix | bold, uppercase | P |
memory | hex + code | 0400:002eh
|
new term | bold, italic | charblock |
variable | italics | x |
vector | bold, lowercase | v |
I also use some non-ASCII symbols that may not show up properly depending on how old your browser is. These are:
symbol | description |
---|---|
α, β, γ | Greek letters |
≈ | approximately |
½ | one half |
¼ | one quarter |
¾ | three quarters |
≥ | greater or equal |
↔ | double-sided arrow |
∈ | is in (an interval) |
〈 〉 | ‘bra’ & ‘ket’ |
→ | right arrow |
² | superscript 2 |
× | times |
I also make liberal use of shorthand for primitive C types
like char
and int
and such. These are
typedefs that better indicate the size of the variable that's used.
Since this is very important in console programming, they're
quite common. Anyway, here's a list.
base type | alt name | unsigned | signed | volatile |
---|---|---|---|---|
char | byte | u8 | s8 | vu8 / vs8 |
short | halfword | u16 | s16 | vu16 / vs16 |
int | word | u32 | s32 | vu32 / vs32 |
Finally, there are a number of different notations for hex that I will switch between, depending on the situation. The C notation (‘0x’ prefix, 0x0400) is common for normal numbers, but I'll also use the assembly affix at times (‘h’, 0400:0000h). The colon here is merely for ease of reading. It's hard to tell the number of zeros without it.
Getting the GBA to do things often involves the use of the so-called IO registers. Certain bits at certain addresses of memory can be used as switches for the various effects that the GBA is capable of. Each register is aliased as a normal variable, and you need to set/clear bits using bit operations. We'll get to where these registers are and what bit does what later; right now I want to show you how I will present these, and refer to them in the text.
Each register (or register-like address) is mapped to a dereferenced pointer, usually 16bits long. For example, the display status register is
#define REG_DISPSTAT *(u16*)0x04000004
Every time I introduce a register I will give an overview of the bits like this:
F E D C B A 9 8 | 7 6 | 5 | 4 | 3 | 2 | 1 | 0 |
VcT | - | VcI | HbI | VbI | VcS | HbS | VbS |
The table lists the register's name (REG_DISPSTAT
, its
address (0400:0000h) and the individual bits or bitfields. Sometimes,
bits or entire registers are read- or write-only. Read-only
is indicated with a red overbar (as used here). Write-only uses
a blue underbar. After it will be a list that describes the various bits,
and also gives the #define or #defines I use for that bit:
bits | name | define | description |
---|---|---|---|
0 | VbS | DSTAT_IN_VBL | VBlank status, read only. Will be set inside VBlank, clear in VDraw. |
other fields | |||
8-F | VcT | DSTAT_VCT# | VCount trigger value. If the current scanline is at this value, bit 2 is set and an interrupt is fired if requested. |
The full list of REG_DISPSTAT can be found
here.
The #defines are usually specific to tonc, by the way. Each site and
API has its own terminology here. This is possible because it's not
the names that are important, but the numbers they stand for. That
goes for the names of the registers themselves too, of course.
One last point on the #defines: some of the ones listed have a
hash (‘#’) affix. This is a shorthand notation to indicate
that that field has foo_SHIFT
and
foo_MASK
#defines, and a foo()
macro. For example, the display register has an 8-bit trigger VCount
field, which has ‘DSTAT_VCT#’ listed in the define
column. This means that the following three things exist in the tonc
headers:
#define DSTAT_VCT_MASK 0xFF00 #define DSTAT_VCT_SHIFT 8 #define DSTAT_VCT(_n) ((_n)<<DSTAT_VCT_SHIFT)
Lastly, as shorthand for a specific bit in a register, I will use accolades. The number will be a hexadecimal number. For example, REG_DISPCNT{0} is the VBlank status bit (VbS above), and REG_DISPCNT{8-F} would be the whole byte for the VCount trigger.
The text and code have been created and found to work under the following conditions. If you find you have a problem, show me yours and maybe we can find and fix it.
To write and manage my code I use Visual C++ 6.0, but I am not using its native make tool (NMAKE), because it's not very portable and seems to be pretty weak as well. Instead, I use GNU make, which usually comes with any of the devkits.
As much as I've tried to weed out things like spelling/grammar errors and broken links, I'm sure some have slipped by. If you find some, mail me about it. That's right, I'm actually asking for spell-flames. Currently, I'm refitting the pages to fit my HTML auto-numbering tool, but it's a lot stuff to go through (over 1M in plain text), and I may miss something; if you see things like [[ref:foo]] in unfinished sections, those probably shouldn't be there. Of course, if things are unclear or *gasp* incorrect, or if you have suggestions, I'd like to know that as well.
20130324, ADDENDUM. Since it's now been over half a decade since all of this was written, I'm fairly certain many of the links are dead by now. I'll try to clean them up when I can, but I'm not sure it's worth the trouble. You have been warned.
And, of course:
This distribution is provided as is, without warranty of any kind. I cannot be held liable for any damage arising out of the use or inability to use this distribution. Code has been tested on emulator and real hardware as well as I could, but I can't guarantee 100% correctness.
The code may be used and/or modified as you see fit. The text and code were intended to go together; if you have to separate the text from the code, at least provide a link to where both originated (i.e., this site).
Both text and code can be modified by me at any time. Check in once in a while to see if anything's changed. Time stamps are at the bottom of every page, and at the top of all source-files. There is also a log in the appendices.
OK that's it. Have fun.
Prev | Contents | Next |
Contents | Hardware |