diff --git a/Makefile b/Makefile index fc104f84..1145fe26 100644 --- a/Makefile +++ b/Makefile @@ -20,12 +20,12 @@ out/release/%.gba: cargo-release-% d-%: out/debug/%.gba @OUTNAME=$(patsubst d-%,%,$@) - @mgba-qt $< + @mgba-qt -l 31 -d -C logToStdout=1 $< @rm -f out/debug/$${OUTNAME}.sav r-%: out/release/%.gba @OUTNAME=$(patsubst r-%,%,$@) - @mgba-qt $< + @mgba-qt -l 31 -d -C logToStdout=1 $< @rm -f out/release/$${OUTNAME}.sav cargo-release-%: $(RUSTFILES) out/crt0.o diff --git a/examples/output.rs b/examples/output.rs new file mode 100644 index 00000000..3ba6d1f9 --- /dev/null +++ b/examples/output.rs @@ -0,0 +1,26 @@ +#![no_std] +#![feature(start)] + +use gba::display::vblank; + +extern crate gba; +#[start] +fn main(_argc: isize, _argv: *const *const u8) -> isize { + let mut gba = gba::Gba::new(); + let mut mgba = gba::mgba::Mgba::new().unwrap(); + + let vblank = gba.display.vblank.get(); + + let mut count = 0; + loop { + vblank.wait_for_VBlank(); + + mgba.print( + format_args!("Hello, world, frame = {}", count), + gba::mgba::DebugLevel::Info, + ) + .unwrap(); + + count += 1; + } +} diff --git a/src/display/mod.rs b/src/display/mod.rs index 4b20cacd..9265b2de 100644 --- a/src/display/mod.rs +++ b/src/display/mod.rs @@ -6,6 +6,7 @@ use video::Video; pub mod bitmap3; pub mod bitmap4; +pub mod tiled0; pub mod vblank; pub mod video; diff --git a/src/display/tiled0.rs b/src/display/tiled0.rs new file mode 100644 index 00000000..68df3afb --- /dev/null +++ b/src/display/tiled0.rs @@ -0,0 +1,25 @@ +use crate::memory_mapped::MemoryMapped1DArray; + +use super::{set_graphics_mode, DisplayMode}; + +const PALETTE_BACKGROUND: MemoryMapped1DArray = + unsafe { MemoryMapped1DArray::new(0x0500_0000) }; +const PALETTE_SPRITE: MemoryMapped1DArray = + unsafe { MemoryMapped1DArray::new(0x0500_0200) }; + +#[non_exhaustive] +pub struct Tiled0 {} + +impl Tiled0 { + pub(crate) unsafe fn new() -> Self { + set_graphics_mode(DisplayMode::Tiled0); + Tiled0 {} + } + + pub fn set_sprite_palette(&mut self, index: u8, colour: u16) { + PALETTE_SPRITE.set(index as usize, colour) + } + pub fn set_background_palette(&mut self, index: u8, colour: u16) { + PALETTE_BACKGROUND.set(index as usize, colour) + } +} diff --git a/src/display/video.rs b/src/display/video.rs index 2006379b..3c7974a2 100644 --- a/src/display/video.rs +++ b/src/display/video.rs @@ -1,4 +1,4 @@ -use super::{bitmap3::Bitmap3, bitmap4::Bitmap4}; +use super::{bitmap3::Bitmap3, bitmap4::Bitmap4, tiled0::Tiled0}; #[non_exhaustive] pub struct Video {} @@ -13,4 +13,8 @@ impl Video { pub fn bitmap4(&mut self) -> Bitmap4 { unsafe { Bitmap4::new() } } + + pub fn tiled0(&mut self) -> Tiled0 { + unsafe { Tiled0::new() } + } } diff --git a/src/lib.rs b/src/lib.rs index 38ddb6cb..85a6ba3a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,7 @@ pub mod input; mod interrupt; mod memory_mapped; -mod mgba; +pub mod mgba; mod single; pub mod syscall; diff --git a/src/mgba.rs b/src/mgba.rs index c16cb53e..ae881222 100644 --- a/src/mgba.rs +++ b/src/mgba.rs @@ -1,7 +1,7 @@ -use crate::memory_mapped::MemoryMapped; +use crate::memory_mapped::{MemoryMapped, MemoryMapped1DArray}; +use core::fmt::Write; #[derive(Eq, PartialEq, Clone, Copy)] -#[repr(u16)] #[allow(dead_code)] pub enum DebugLevel { Fatal = 0, @@ -11,8 +11,9 @@ pub enum DebugLevel { Debug = 4, } -const OUTPUT: *mut u8 = 0x04FF_F600 as *mut u8; -const ENABLE: MemoryMapped = unsafe { MemoryMapped::new(0x04FF_F780) }; +const OUTPUT_STRING: MemoryMapped1DArray = + unsafe { MemoryMapped1DArray::new(0x04FF_F600) }; +const DEBUG_ENABLE: MemoryMapped = unsafe { MemoryMapped::new(0x04FF_F780) }; const ENABLE_HANDSHAKE_IN: u16 = 0xC0DE; const ENABLE_HANDSHAKE_OUT: u16 = 0x1DEA; @@ -21,8 +22,8 @@ const DEBUG_LEVEL: MemoryMapped = unsafe { MemoryMapped::new(0x04FF_F700) } const DEBUG_FLAG_CODE: u16 = 0x0100; fn is_running_in_mgba() -> bool { - ENABLE.set(ENABLE_HANDSHAKE_IN); - ENABLE.get() == ENABLE_HANDSHAKE_OUT + DEBUG_ENABLE.set(ENABLE_HANDSHAKE_IN); + DEBUG_ENABLE.get() == ENABLE_HANDSHAKE_OUT } pub struct Mgba { @@ -37,6 +38,16 @@ impl Mgba { None } } + + pub fn print( + &mut self, + output: core::fmt::Arguments, + level: DebugLevel, + ) -> Result<(), core::fmt::Error> { + write!(self, "{}", output)?; + self.set_level(level); + Ok(()) + } } impl Mgba { @@ -48,18 +59,14 @@ impl Mgba { impl core::fmt::Write for Mgba { fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> { - unsafe { - let mut current_location = OUTPUT.add(self.bytes_written); - let mut str_iter = s.bytes(); - while self.bytes_written < 255 { - match str_iter.next() { - Some(byte) => { - current_location.write(byte); - current_location = current_location.offset(1); - self.bytes_written += 1; - } - None => return Ok(()), + let mut str_iter = s.bytes(); + while self.bytes_written < 255 { + match str_iter.next() { + Some(byte) => { + OUTPUT_STRING.set(self.bytes_written, byte); + self.bytes_written += 1; } + None => return Ok(()), } } Ok(())