This repository has been archived on 2024-06-01. You can view files and clone it, but cannot push or open issues or pull requests.
rustboyadvance-ng/core/src/mgba_debug.rs
Michel Heily efb1cdb4b6 core: Fix 8bit accesses to mgba log
Former-commit-id: 780e6b58b265ad5d586fe605f143e6c9d8b26c63
Former-commit-id: 5d2514c9a45d2f5c698272c9324575d7bddec4ac
2020-10-24 09:35:03 -07:00

102 lines
2.7 KiB
Rust

/// mGBA 0.8.1 Debug peripheral support
use std::str;
use log::log;
use log::Level;
use super::bus::Bus;
use super::iodev::consts::{REG_DEBUG_ENABLE, REG_DEBUG_FLAGS, REG_DEBUG_STRING};
pub const DEBUG_STRING_SIZE: usize = 0x100;
#[derive(Clone, Serialize, Deserialize)]
pub struct DebugPort {
enable: bool,
flags: DebugFlags,
debug_string: Box<[u8]>,
}
impl DebugPort {
pub fn new() -> DebugPort {
DebugPort {
enable: false,
flags: DebugFlags(0),
debug_string: vec![0; DEBUG_STRING_SIZE].into_boxed_slice(),
}
}
#[inline]
pub fn is_debug_access(x: u32) -> bool {
x == REG_DEBUG_ENABLE
|| x == REG_DEBUG_FLAGS
|| (x >= REG_DEBUG_STRING && x <= REG_DEBUG_STRING + (DEBUG_STRING_SIZE as u32))
}
pub fn read(&mut self, addr: u32) -> u16 {
if !self.enable {
return 0;
}
match addr {
REG_DEBUG_ENABLE => 0x1DEA,
REG_DEBUG_FLAGS => self.flags.0,
x if x >= REG_DEBUG_STRING && x <= REG_DEBUG_STRING + (DEBUG_STRING_SIZE as u32) => {
self.debug_string.read_16(addr - REG_DEBUG_STRING)
}
_ => 0,
}
}
pub fn write(&mut self, addr: u32, value: u16) {
match addr {
REG_DEBUG_ENABLE => {
self.enable = value == 0xC0DE;
info!("mGBA log enabled: {}", self.enable);
}
REG_DEBUG_FLAGS => {
if self.enable {
self.flags.0 = value;
self.debug();
}
}
x if x >= REG_DEBUG_STRING && x <= REG_DEBUG_STRING + (DEBUG_STRING_SIZE as u32) => {
if self.enable {
self.debug_string.write_16(addr - REG_DEBUG_STRING, value);
}
}
_ => unreachable!(),
}
}
fn debug(&mut self) {
if self.flags.send() {
let message = str::from_utf8(&self.debug_string)
.expect("Failed to parse log message to valid utf8");
let level: Level = match self.flags.level() {
0 | 1 => Level::Error,
2 => Level::Warn,
3 => Level::Info,
4 => Level::Debug,
_ => panic!("invalid log level"),
};
log!(level, "[mGBA mLOG]: {}", message);
for i in self.debug_string.iter_mut() {
*i = 0;
}
self.flags.set_send(false);
}
}
}
bitfield! {
#[derive(Clone, Serialize, Deserialize)]
pub struct DebugFlags(u16);
impl Debug;
u16;
pub into usize, level, _: 3, 0;
pub send, set_send: 8;
}