minimal template project for gba-0.11.3
This commit is contained in:
commit
d250bb5c46
13
.cargo/config.toml
Normal file
13
.cargo/config.toml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[build]
|
||||||
|
target = "armv4t-none-eabi"
|
||||||
|
|
||||||
|
[unstable]
|
||||||
|
build-std = ["core"]
|
||||||
|
|
||||||
|
[target.thumbv4t-none-eabi]
|
||||||
|
runner = "mgba-qt"
|
||||||
|
rustflags = ["-Clink-arg=-Tlinker_scripts/mono_boot.ld"]
|
||||||
|
|
||||||
|
[target.armv4t-none-eabi]
|
||||||
|
runner = "mgba-qt"
|
||||||
|
rustflags = ["-Clink-arg=-Tlinker_scripts/mono_boot.ld"]
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
39
Cargo.lock
generated
Normal file
39
Cargo.lock
generated
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitfrob"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a96c7c818dc8807bb1982dd2cba4c7de0ed6eba4ffb5fc24321d1b38676a120"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bracer"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6559b8c3065745016f5cc2d1095273fe8a175e953c976426947ad828d6ba6fda"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gba"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7ab90d1de12c1323d80d9850c55d68931512ef7f0462a8c79e92b726f5037ad6"
|
||||||
|
dependencies = [
|
||||||
|
"bitfrob",
|
||||||
|
"bracer",
|
||||||
|
"voladdress",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gba-template"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"gba",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "voladdress"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fbf3fef7bc995d3f8350936bdd07966c7a1f96183d52e3f28c29d099d0b5ecc"
|
9
Cargo.toml
Normal file
9
Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[package]
|
||||||
|
name = "gba-template"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
gba = "0.11.3"
|
100
linker_scripts/mono_boot.ld
Normal file
100
linker_scripts/mono_boot.ld
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/* THIS LINKER SCRIPT FILE IS RELEASED TO THE PUBLIC DOMAIN (SPDX: CC0-1.0) */
|
||||||
|
|
||||||
|
ENTRY(__start)
|
||||||
|
|
||||||
|
MEMORY {
|
||||||
|
ewram (w!x) : ORIGIN = 0x2000000, LENGTH = 256K
|
||||||
|
iwram (w!x) : ORIGIN = 0x3000000, LENGTH = 32K
|
||||||
|
rom (rx) : ORIGIN = 0x8000000, LENGTH = 32M
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
.text : {
|
||||||
|
/* be sure that the ROM header is the very first */
|
||||||
|
*(.text.gba_rom_header);
|
||||||
|
*(.text .text.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >rom = 0x00
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata .rodata.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >rom = 0x00
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__iwram_position_in_rom = .;
|
||||||
|
.data : {
|
||||||
|
__iwram_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
*(.data .data.*);
|
||||||
|
*(.iwram .iwram.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
__iwram_end = ABSOLUTE(.);
|
||||||
|
} >iwram AT>rom = 0x00
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__ewram_position_in_rom = __iwram_position_in_rom + (__iwram_end - __iwram_start);
|
||||||
|
.ewram : {
|
||||||
|
__ewram_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
*(.ewram .ewram.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
__ewram_end = ABSOLUTE(.);
|
||||||
|
} >ewram AT>rom = 0x00
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_position_in_rom = __ewram_position_in_rom + (__ewram_end - __ewram_start);
|
||||||
|
.bss : {
|
||||||
|
__bss_start = ABSOLUTE(.);
|
||||||
|
|
||||||
|
*(.bss .bss.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
__bss_end = ABSOLUTE(.);
|
||||||
|
} >iwram
|
||||||
|
|
||||||
|
__iwram_word_copy_count = (__iwram_end - __iwram_start) / 4;
|
||||||
|
__ewram_word_copy_count = (__ewram_end - __ewram_start) / 4;
|
||||||
|
__bss_word_clear_count = (__bss_end - __bss_start) / 4;
|
||||||
|
|
||||||
|
/* rust-lld demands we keep the `section header string table` */
|
||||||
|
.shstrtab 0 : { *(.shstrtab) }
|
||||||
|
|
||||||
|
/* debugging sections */
|
||||||
|
/* Stabs */
|
||||||
|
.stab 0 : { *(.stab) }
|
||||||
|
.stabstr 0 : { *(.stabstr) }
|
||||||
|
.stab.excl 0 : { *(.stab.excl) }
|
||||||
|
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||||
|
.stab.index 0 : { *(.stab.index) }
|
||||||
|
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||||
|
.comment 0 : { *(.comment) }
|
||||||
|
/* DWARF 1 */
|
||||||
|
.debug 0 : { *(.debug) }
|
||||||
|
.line 0 : { *(.line) }
|
||||||
|
/* GNU DWARF 1 extensions */
|
||||||
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||||
|
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||||
|
/* DWARF 1.1 and DWARF 2 */
|
||||||
|
.debug_aranges 0 : { *(.debug_aranges) }
|
||||||
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||||
|
/* DWARF 2 */
|
||||||
|
.debug_info 0 : { *(.debug_info) }
|
||||||
|
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||||
|
.debug_line 0 : { *(.debug_line) }
|
||||||
|
.debug_frame 0 : { *(.debug_frame) }
|
||||||
|
.debug_str 0 : { *(.debug_str) }
|
||||||
|
.debug_loc 0 : { *(.debug_loc) }
|
||||||
|
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||||
|
/* SGI/MIPS DWARF 2 extensions */
|
||||||
|
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||||
|
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||||
|
.debug_typenames 0 : { *(.debug_typenames) }
|
||||||
|
.debug_varnames 0 : { *(.debug_varnames) }
|
||||||
|
|
||||||
|
/* discard anything not already mentioned */
|
||||||
|
/DISCARD/ : { *(*) }
|
||||||
|
}
|
||||||
|
|
98
src/main.rs
Normal file
98
src/main.rs
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
// from https://github.com/rust-console/gba/blob/main/examples/hello.rs
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use core::fmt::Write;
|
||||||
|
use gba::prelude::*;
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
if let Ok(mut logger) = MgbaBufferedLogger::try_new(MgbaMessageLevel::Fatal) {
|
||||||
|
writeln!(logger, "{info}").ok();
|
||||||
|
}
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[link_section = ".ewram"]
|
||||||
|
static FRAME_KEYS: GbaCell<KeyInput> = GbaCell::new(KeyInput::new());
|
||||||
|
|
||||||
|
#[link_section = ".iwram"]
|
||||||
|
extern "C" fn irq_handler(_: IrqBits) {
|
||||||
|
// We'll read the keys during vblank and store it for later.
|
||||||
|
FRAME_KEYS.write(KEYINPUT.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
extern "C" fn main() -> ! {
|
||||||
|
RUST_IRQ_HANDLER.write(Some(irq_handler));
|
||||||
|
DISPSTAT.write(DisplayStatus::new().with_irq_vblank(true));
|
||||||
|
IE.write(IrqBits::VBLANK);
|
||||||
|
IME.write(true);
|
||||||
|
|
||||||
|
if let Ok(mut logger) = MgbaBufferedLogger::try_new(MgbaMessageLevel::Debug) {
|
||||||
|
writeln!(logger, "hello!").ok();
|
||||||
|
|
||||||
|
let fx_u: Fixed<u32, 8> = Fixed::<u32, 8>::wrapping_from(7) + Fixed::<u32, 8>::from_raw(12);
|
||||||
|
writeln!(logger, "fixed unsigned: {fx_u:?}").ok();
|
||||||
|
|
||||||
|
let fx_i1: Fixed<i32, 8> =
|
||||||
|
Fixed::<i32, 8>::wrapping_from(8) + Fixed::<i32, 8>::from_raw(15);
|
||||||
|
writeln!(logger, "fixed signed positive: {fx_i1:?}").ok();
|
||||||
|
|
||||||
|
let fx_i2: Fixed<i32, 8> = Fixed::<i32, 8>::wrapping_from(0)
|
||||||
|
- Fixed::<i32, 8>::wrapping_from(3)
|
||||||
|
- Fixed::<i32, 8>::from_raw(17);
|
||||||
|
writeln!(logger, "fixed signed negative: {fx_i2:?}").ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// get our tile data into memory.
|
||||||
|
Cga8x8Thick.bitunpack_4bpp(CHARBLOCK0_4BPP.as_region(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// set up the tilemap
|
||||||
|
let tsb = TEXT_SCREENBLOCKS.get_frame(31).unwrap();
|
||||||
|
for y in 0..16 {
|
||||||
|
let row = tsb.get_row(y).unwrap();
|
||||||
|
for (x, addr) in row.iter().enumerate().take(16) {
|
||||||
|
let te = TextEntry::new().with_tile((y * 16 + x) as u16);
|
||||||
|
addr.write(te);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Set BG0 to use the tilemap we just made, and set it to be shown.
|
||||||
|
BG0CNT.write(BackgroundControl::new().with_screenblock(31));
|
||||||
|
DISPCNT.write(DisplayControl::new().with_show_bg0(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut x_off = 0_u32;
|
||||||
|
let mut y_off = 0_u32;
|
||||||
|
let mut backdrop_color = Color(0);
|
||||||
|
loop {
|
||||||
|
VBlankIntrWait();
|
||||||
|
// show current frame
|
||||||
|
BACKDROP_COLOR.write(backdrop_color);
|
||||||
|
BG0HOFS.write(x_off as u16);
|
||||||
|
BG0VOFS.write(y_off as u16);
|
||||||
|
|
||||||
|
// prep next frame
|
||||||
|
let k = FRAME_KEYS.read();
|
||||||
|
backdrop_color = Color(k.to_u16());
|
||||||
|
if k.up() {
|
||||||
|
y_off = y_off.wrapping_add(1);
|
||||||
|
}
|
||||||
|
if k.down() {
|
||||||
|
y_off = y_off.wrapping_sub(1);
|
||||||
|
}
|
||||||
|
if k.left() {
|
||||||
|
x_off = x_off.wrapping_add(1);
|
||||||
|
}
|
||||||
|
if k.right() {
|
||||||
|
x_off = x_off.wrapping_sub(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue