Skip to content

Commit

Permalink
Merge pull request #20 from linkmauve/better-println
Browse files Browse the repository at this point in the history
Reimplement println!() using __write_console()
  • Loading branch information
ProfElements authored Aug 16, 2022
2 parents 5af434a + 96b065c commit 8656459
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 10 deletions.
50 changes: 40 additions & 10 deletions luma_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
#![allow(unused_attributes)]
#![feature(asm_experimental_arch, box_into_boxed_slice, allocator_api)]

use core::arch::asm;

extern crate alloc;

use alloc::string::ToString;
use core::arch::asm;
use core::fmt;

// Broadway Processor Utilities
pub mod processor;

Expand All @@ -35,18 +37,46 @@ pub mod allocate;
// VI Subsystem
pub mod vi;

/// Do nothing, this is for Dolphin’s use until we get actual USB Gecko support.
///
/// This function must exist and its symbol must be kept in order to get HLE debugging in Dolphin.
///
/// Unlike puts(), it doesn’t require a null-terminated CStr, so in the optimal case we can pass a
/// &str’s pointer as is, without doing any extra allocation.
#[no_mangle]
#[inline(never)]
pub unsafe extern "C" fn puts(unused: u32, message: *const u8) {
// Do nothing, this is for Dolphin’s use until we get actual USB Gecko support.
asm!("/* {0} {1} */", in(reg) unused, in(reg) message);
unsafe extern "C" fn __write_console(_unused: u32, message: *const u8, size: *const u32) {
asm!("/* {0} {1} */", in(reg) message, in(reg) size);
}

/// Implements Write using Dolphin’s HLE.
pub struct DolphinHle;

impl fmt::Write for DolphinHle {
#[inline(always)]
fn write_str(&mut self, s: &str) -> fmt::Result {
let len = s.len() as u32;
unsafe { __write_console(0, s.as_ptr(), &len as *const u32) };
Ok(())
}

#[inline(always)]
fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
if let Some(s) = args.as_str() {
self.write_str(s)
} else {
self.write_str(&args.to_string())
}
}
}

/// Reimplementation of Rust’s println!(), using Dolphin’s HLE.
///
/// This macro requires luma_core and core::fmt::Write to be present in the callee’s environment.
#[macro_export]
macro_rules! println {
($fmt: expr, $($args: expr),*) => {{
// TODO: figure out a way to not have to import those crates with these names in user code.
let string = alloc::format!($fmt, $($args),*);
unsafe { luma_core::puts(0, string.as_ptr()) };
}}
($($arg:tt)*) => {{
use luma_core::DolphinHle;
write!(DolphinHle, $($arg)*).unwrap();
}};
}
1 change: 1 addition & 0 deletions luma_runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
extern crate alloc;

use core::arch::global_asm;
use core::fmt::Write;
use core::{alloc::Layout, panic::PanicInfo};
use linked_list_allocator::LockedHeap;
#[allow(unused_imports)]
Expand Down

0 comments on commit 8656459

Please sign in to comment.