Merge pull request #2 from corwinkuiper/mgba-output

Mgba output
This commit is contained in:
Corwin 2021-03-09 00:14:51 +00:00 committed by GitHub
commit 2c5f706d20
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 84 additions and 21 deletions

View file

@ -20,12 +20,12 @@ out/release/%.gba: cargo-release-%
d-%: out/debug/%.gba d-%: out/debug/%.gba
@OUTNAME=$(patsubst d-%,%,$@) @OUTNAME=$(patsubst d-%,%,$@)
@mgba-qt $< @mgba-qt -l 31 -d -C logToStdout=1 $<
@rm -f out/debug/$${OUTNAME}.sav @rm -f out/debug/$${OUTNAME}.sav
r-%: out/release/%.gba r-%: out/release/%.gba
@OUTNAME=$(patsubst r-%,%,$@) @OUTNAME=$(patsubst r-%,%,$@)
@mgba-qt $< @mgba-qt -l 31 -d -C logToStdout=1 $<
@rm -f out/release/$${OUTNAME}.sav @rm -f out/release/$${OUTNAME}.sav
cargo-release-%: $(RUSTFILES) out/crt0.o cargo-release-%: $(RUSTFILES) out/crt0.o

26
examples/output.rs Normal file
View file

@ -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;
}
}

View file

@ -6,6 +6,7 @@ use video::Video;
pub mod bitmap3; pub mod bitmap3;
pub mod bitmap4; pub mod bitmap4;
pub mod tiled0;
pub mod vblank; pub mod vblank;
pub mod video; pub mod video;

25
src/display/tiled0.rs Normal file
View file

@ -0,0 +1,25 @@
use crate::memory_mapped::MemoryMapped1DArray;
use super::{set_graphics_mode, DisplayMode};
const PALETTE_BACKGROUND: MemoryMapped1DArray<u16, 256> =
unsafe { MemoryMapped1DArray::new(0x0500_0000) };
const PALETTE_SPRITE: MemoryMapped1DArray<u16, 256> =
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)
}
}

View file

@ -1,4 +1,4 @@
use super::{bitmap3::Bitmap3, bitmap4::Bitmap4}; use super::{bitmap3::Bitmap3, bitmap4::Bitmap4, tiled0::Tiled0};
#[non_exhaustive] #[non_exhaustive]
pub struct Video {} pub struct Video {}
@ -13,4 +13,8 @@ impl Video {
pub fn bitmap4(&mut self) -> Bitmap4 { pub fn bitmap4(&mut self) -> Bitmap4 {
unsafe { Bitmap4::new() } unsafe { Bitmap4::new() }
} }
pub fn tiled0(&mut self) -> Tiled0 {
unsafe { Tiled0::new() }
}
} }

View file

@ -8,7 +8,7 @@ pub mod input;
mod interrupt; mod interrupt;
mod memory_mapped; mod memory_mapped;
mod mgba; pub mod mgba;
mod single; mod single;
pub mod syscall; pub mod syscall;

View file

@ -1,7 +1,7 @@
use crate::memory_mapped::MemoryMapped; use crate::memory_mapped::{MemoryMapped, MemoryMapped1DArray};
use core::fmt::Write;
#[derive(Eq, PartialEq, Clone, Copy)] #[derive(Eq, PartialEq, Clone, Copy)]
#[repr(u16)]
#[allow(dead_code)] #[allow(dead_code)]
pub enum DebugLevel { pub enum DebugLevel {
Fatal = 0, Fatal = 0,
@ -11,8 +11,9 @@ pub enum DebugLevel {
Debug = 4, Debug = 4,
} }
const OUTPUT: *mut u8 = 0x04FF_F600 as *mut u8; const OUTPUT_STRING: MemoryMapped1DArray<u8, 256> =
const ENABLE: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x04FF_F780) }; unsafe { MemoryMapped1DArray::new(0x04FF_F600) };
const DEBUG_ENABLE: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x04FF_F780) };
const ENABLE_HANDSHAKE_IN: u16 = 0xC0DE; const ENABLE_HANDSHAKE_IN: u16 = 0xC0DE;
const ENABLE_HANDSHAKE_OUT: u16 = 0x1DEA; const ENABLE_HANDSHAKE_OUT: u16 = 0x1DEA;
@ -21,8 +22,8 @@ const DEBUG_LEVEL: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x04FF_F700) }
const DEBUG_FLAG_CODE: u16 = 0x0100; const DEBUG_FLAG_CODE: u16 = 0x0100;
fn is_running_in_mgba() -> bool { fn is_running_in_mgba() -> bool {
ENABLE.set(ENABLE_HANDSHAKE_IN); DEBUG_ENABLE.set(ENABLE_HANDSHAKE_IN);
ENABLE.get() == ENABLE_HANDSHAKE_OUT DEBUG_ENABLE.get() == ENABLE_HANDSHAKE_OUT
} }
pub struct Mgba { pub struct Mgba {
@ -37,6 +38,16 @@ impl Mgba {
None 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 { impl Mgba {
@ -48,20 +59,16 @@ impl Mgba {
impl core::fmt::Write for Mgba { impl core::fmt::Write for Mgba {
fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> { 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(); let mut str_iter = s.bytes();
while self.bytes_written < 255 { while self.bytes_written < 255 {
match str_iter.next() { match str_iter.next() {
Some(byte) => { Some(byte) => {
current_location.write(byte); OUTPUT_STRING.set(self.bytes_written, byte);
current_location = current_location.offset(1);
self.bytes_written += 1; self.bytes_written += 1;
} }
None => return Ok(()), None => return Ok(()),
} }
} }
}
Ok(()) Ok(())
} }
} }