#game #intended #style #experience #managed #agb #build-std

gba

A crate for ‘raw’ style GBA development. If you want a ‘managed’ experience, try the agb crate instead.

33 releases

0.13.1 Oct 21, 2024
0.12.0 Aug 27, 2024
0.11.6 May 12, 2024
0.11.5 Mar 4, 2024
0.2.0 Nov 13, 2018

#117 in Game dev

Download history 33/week @ 2024-07-15 53/week @ 2024-07-29 2/week @ 2024-08-12 11/week @ 2024-08-19 239/week @ 2024-08-26 220/week @ 2024-09-02 24/week @ 2024-09-09 114/week @ 2024-09-16 165/week @ 2024-09-23 53/week @ 2024-09-30 29/week @ 2024-10-07 62/week @ 2024-10-14 252/week @ 2024-10-21 36/week @ 2024-10-28

381 downloads per month
Used in rustygba

Zlib OR Apache-2.0 OR MIT

150KB
2.5K SLoC

gba

Docs.rs Documentation

This crate is intended for working with the GBA.

To build for the GBA you'll need to use build-std and you'll also need to activate the compiler-builtins-weak-intrinsics feature.

The following should be somewhere in your .cargo/config.toml:

[unstable]
build-std = ["core"]
build-std-features = ["compiler-builtins-weak-intrinsics"]

lib.rs:

A crate for GBA development.

How To Make Your Own GBA Project Using This Crate

This will require the use of Nightly Rust. Any recent-ish version of Nightly should be fine.

  • Get The ARM Binutils: You'll need the ARM version of the GNU binutils in your path, specifically the linker (arm-none-eabi-ld). Linux folks can use the package manager. Mac and Windows folks can use the ARM Website.
  • Run rustup component add rust-src: This makes rustup keep the standard library source code on hand, which is necessary for build-std to work.
  • Create A .cargo/config.toml: You'll want to set up a file to provide all the right default settings so that a basic cargo build and cargo run will "just work". Something like the following is what you probably want.
[build]
target = "thumbv4t-none-eabi"

[unstable]
build-std = ["core"]

[target.thumbv4t-none-eabi]
runner = "mgba-qt" # sets the emulator to run bins/examples with
rustflags = [
  "-Clinker=arm-none-eabi-ld", # uses the ARM linker
  "-Clink-arg=-Tlinker_scripts/mono_boot.ld", # sets the link script
]
  • Make Your Executables: At this point you can make a bin or an example file. Every executable will need to be #![no_std] and #![no_main]. They will also need a #[panic_handler] defined, as well as a #[no_mangle] extern "C" fn main() -> ! {} function, which is what the assembly runtime will call to start your Rust program after it fully initializes the system. The C ABI must be used because Rust's own ABI is not stable.
#![no_std]
#![no_main]

#[panic_handler]
fn panic_handler(_: &core::panic::PanicInfo) -> ! {
  loop {}
}

#[no_mangle]
extern "C" fn main() -> ! {
  loop {}
}
  • Optional: Use objcopy and gbafix: The cargo build will produce ELF files, which mGBA can run directly. If you want to run your program on real hardware you'll need to first objcopy the raw binary out of the ELF into its own file, then Use gbafix to give an appropriate header to the file. objcopy is part of the ARM binutils you already installed, it should be named arm-none-eabi-objcopy. You can get gbafix through cargo: cargo install gbafix.

This crate provides an API to interact with the GBA that is safe, but with minimal restrictions on what components can be changed when. If you'd like an API where the borrow checker provides stronger control over component access then the agb crate might be what you want.

Safety

All safety considerations for the crate assume that you're building for the thumbv4t-none-eabi or armv4t-none-eabi targets, using the provided linker script, and then running the code on a GBA. While it's possible to break any of these assumptions, if you do that some or all of the code provided by this crate may become unsound.

Dependencies

~215–720KB
~13K SLoC