Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

BIOS Functions

The GBA BIOS provides built-in routines accessible through software interrupts (SWI). stdgba wraps these in C++ functions, some of which are constexpr - the compiler evaluates them at compile time when possible and falls back to the BIOS call at runtime.

Common functions

Halting and waiting

#include <gba/bios>

// Wait for VBlank interrupt (most common - used every frame)
gba::VBlankIntrWait();

// Halt CPU until any interrupt
gba::Halt();

// Halt CPU until a specific interrupt
gba::IntrWait(true, { .vblank = true });

Math

// Square root (constexpr when argument is known at compile time)
auto root = gba::Sqrt(144u);  // 12

// Arc tangent
auto angle = gba::ArcTan2(dx, dy);

// Division (avoid - the compiler's division is usually better)
auto [quot, rem] = gba::Div(100, 7);

Memory copy

// CpuSet: 32-bit word copy/fill via BIOS
gba::CpuSet(src, dst, { .count = 256, .set_32bit = true });

// CpuFastSet: 32-bit copy in 8-word chunks (must be aligned, count multiple of 8)
gba::CpuFastSet(src, dst, { .count = 256 });

Note: For general memory copying, prefer standard memcpy/memset - stdgba’s optimised ARM assembly implementations are faster than the BIOS routines in most cases.

Decompression

// Decompress LZ77 data to work RAM (byte writes)
gba::LZ77UnCompWram(compressed_data, dest);

// Decompress LZ77 data to video RAM (halfword writes)
gba::LZ77UnCompVram(compressed_data, dest);

// Huffman decompression
gba::HuffUnCompReadNormal(compressed_data, dest);

// Run-length decompression
gba::RLUnCompReadNormalWrite8bit(compressed_data, dest);

Reset

// Soft reset (restart the ROM)
gba::SoftReset();  // [[noreturn]]

// Clear specific memory regions
gba::RegisterRamReset({
    .ewram = true,
    .iwram = true,
    .palette = true,
    .vram = true,
    .oam = true,
});

Constexpr BIOS functions

Several BIOS math functions are constexpr in stdgba. When called with compile-time arguments, the compiler evaluates them directly and embeds the result:

// Evaluated at compile time - no SWI at runtime
constexpr auto root = gba::Sqrt(256u);  // 16

// Evaluated at runtime - SWI 0x08
volatile unsigned int x = 256;
auto root2 = gba::Sqrt(x);  // BIOS call

This is possible because stdgba provides constexpr implementations of the algorithms alongside the SWI wrappers. The compiler chooses the appropriate path automatically.

tonclib comparison

stdgbatonclib
gba::VBlankIntrWait()VBlankIntrWait()
gba::Sqrt(n)Sqrt(n)
gba::CpuSet(s, d, cfg)CpuSet(s, d, mode)
gba::SoftReset()SoftReset()
gba::ArcTan2(x, y)ArcTan2(x, y)

The API names match the BIOS function names from the community documentation. The main difference is type safety: stdgba uses structs with named fields for configuration instead of raw integers with magic bit patterns.