gba/src/lib.rs

85 lines
2.3 KiB
Rust
Raw Normal View History

2018-11-15 13:49:00 +11:00
#![cfg_attr(not(test), no_std)]
2018-11-15 19:23:04 +11:00
#![feature(asm)]
#![warn(missing_docs)]
//! This crate helps you write GBA ROMs.
//!
//! # SAFETY POLICY
//!
//! Some parts of this crate are safe wrappers around unsafe operations. This is
//! good, and what you'd expect from a Rust crate.
//!
//! However, the safe wrappers all assume that you will _only_ attempt to
//! execute this crate on a GBA or in a GBA Emulator.
//!
//! **Do not** use this crate in programs that aren't running on the GBA. If you
//! do, it's a giant bag of Undefined Behavior.
2018-11-15 13:49:00 +11:00
//!
//! # TESTING POLICY
//!
//! It is the intent of the crate authors that as much of the crate as possible
//! be written so that you can use `cargo test` for at least some parts of your
//! code without everything exploding instantly. To that end, where possible we
//! attempt to use `cfg` flags to make things safe for `cargo test`. Hopefully
//! we got it all.
pub mod core_extras;
pub(crate) use crate::core_extras::*;
pub mod io_registers;
pub mod video_ram;
2018-11-15 19:23:04 +11:00
pub(crate) use crate::video_ram::*;
/// Combines the Red, Blue, and Green provided into a single color value.
pub const fn rgb16(red: u16, green: u16, blue: u16) -> u16 {
blue << 10 | green << 5 | red
}
2018-11-15 19:23:04 +11:00
/// BIOS Call: Div (GBA SWI 0x06).
///
2018-11-16 18:39:47 +11:00
/// Gives just the DIV output of `numerator / denominator`.
///
/// # Panics
///
/// If `denominator` is 0.
#[inline]
pub fn div(numerator: i32, denominator: i32) -> i32 {
div_modulus(numerator, denominator).0
}
/// BIOS Call: Div (GBA SWI 0x06).
///
/// Gives just the MOD output of `numerator / denominator`.
///
/// # Panics
///
/// If `denominator` is 0.
#[inline]
pub fn modulus(numerator: i32, denominator: i32) -> i32 {
div_modulus(numerator, denominator).1
}
/// BIOS Call: Div (GBA SWI 0x06).
///
/// Gives both the DIV and MOD output of `numerator / denominator`.
2018-11-15 19:23:04 +11:00
///
/// # Panics
///
/// If `denominator` is 0.
#[inline]
2018-11-16 18:39:47 +11:00
pub fn div_modulus(numerator: i32, denominator: i32) -> (i32, i32) {
2018-11-15 19:23:04 +11:00
assert!(denominator != 0);
let div_out: i32;
let mod_out: i32;
unsafe {
asm!(/* assembly template */ "swi 0x06"
:/* output operands */ "={r0}"(div_out), "={r1}"(mod_out)
:/* input operands */ "{r0}"(numerator), "{r1}"(denominator)
:/* clobbers */ "r3"
:/* options */
);
}
(div_out, mod_out)
}