diff options
Diffstat (limited to 'src/debug.rs')
-rw-r--r-- | src/debug.rs | 127 |
1 files changed, 62 insertions, 65 deletions
diff --git a/src/debug.rs b/src/debug.rs index 6270948..a0746e7 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -1,86 +1,85 @@ -use bedrock_core::*; +use crate::*; -use std::path::Path; -use std::time::Instant; - - -const NORMAL: &str = "\x1b[0m"; -const BOLD: &str = "\x1b[1m"; -const DIM: &str = "\x1b[2m"; -const YELLOW: &str = "\x1b[33m"; -const BLUE: &str = "\x1b[34m"; +use inked::{ink, InkedString}; pub struct DebugState { pub enabled: bool, - pub verbose: bool, last_cycle: usize, - last_mark: Instant, + mark: Instant, symbols: DebugSymbols, } impl DebugState { - pub fn new<P: AsRef<Path>>(enabled: bool, verbose: bool, symbols_path: Option<P>) -> Self { + pub fn new<P: AsRef<Path>>(enabled: bool, symbols_path: Option<P>) -> Self { Self { enabled, - verbose, last_cycle: 0, - last_mark: Instant::now(), - symbols: DebugSymbols::from_path_opt(symbols_path), - } - } - - pub fn info(&self, string: &str) { - if self.verbose { - eprintln!("{BOLD}{BLUE}[INFO]{NORMAL}: {string}{NORMAL}"); + mark: Instant::now(), + symbols: DebugSymbols::from_path(symbols_path), } } - pub fn debug_summary(&mut self, core: &BedrockCore) { + pub fn debug_full(&mut self, core: &BedrockCore) { if self.enabled { let prev_pc = core.mem.pc.wrapping_sub(1); - eprintln!("\n PC: 0x{:04x} Cycles: {} (+{} in {:.2?})", - prev_pc, core.cycle, - core.cycle.saturating_sub(self.last_cycle), - self.last_mark.elapsed(), - ); - eprint!("WST: "); - debug_stack(&core.wst, 0x10); - eprint!("RST: "); - debug_stack(&core.rst, 0x10); - // Print information about the closest symbol. + let cycle = core.cycle; + let delta = core.cycle.saturating_sub(self.last_cycle); + let elapsed = self.mark.elapsed(); + + eprintln!(" PC: 0x{prev_pc:04x} Cycle: {cycle} (+{delta} in {elapsed:.2?})"); + eprint!("WST: "); debug_stack(&core.wst); + eprint!("RST: "); debug_stack(&core.rst); + // Print information about the nearest symbol. if let Some(symbol) = self.symbols.for_address(prev_pc) { let name = &symbol.name; let address = &symbol.address; - eprint!("SYM: {BLUE}@{name}{NORMAL} 0x{address:04x}"); + let mut string = InkedString::new(); + string.push(ink!("SYM: ")); + string.push(ink!("@{name}").blue()); + string.push(ink!(" 0x{address:04X}")); if let Some(location) = &symbol.location { - eprint!(" {DIM}{location}{NORMAL}"); + string.push(ink!(" ")); + string.push(ink!("{location}").dim()); } - eprintln!(); + string.eprintln(); } + eprintln!(); + } + self.last_cycle = core.cycle; + self.mark = Instant::now(); + } + + pub fn debug_timing(&mut self, core: &BedrockCore) { + if self.enabled { + let cycle = core.cycle; + let delta = core.cycle.saturating_sub(self.last_cycle); + let elapsed = self.mark.elapsed(); + + eprintln!("Cycle: {cycle} (+{delta} in {elapsed:.2?})"); } self.last_cycle = core.cycle; - self.last_mark = Instant::now(); + self.mark = Instant::now(); } } -fn debug_stack(stack: &Stack, len: usize) { - for i in 0..len { - if i == stack.sp as usize { eprint!("{YELLOW}"); } - eprint!("{:02x} ", stack.mem[i]); +fn debug_stack(stack: &Stack) { + for i in 0..(stack.sp as usize) { + eprint!("{:02X} ", stack.mem[i]); } - eprintln!("{NORMAL}"); + eprintln!(); } -struct DebugSymbols { - symbols: Vec<DebugSymbol> + +pub struct DebugSymbols { + pub symbols: Vec<DebugSymbol> } impl DebugSymbols { /// Load debug symbols from a symbols file. - pub fn from_path_opt<P: AsRef<Path>>(path: Option<P>) -> Self { + pub fn from_path<P: AsRef<Path>>(path: Option<P>) -> Self { let mut symbols = Vec::new(); if let Some(path) = path { if let Ok(string) = std::fs::read_to_string(path) { @@ -95,36 +94,34 @@ impl DebugSymbols { Self { symbols } } + /// Return the symbol matching a given program address. pub fn for_address(&self, address: u16) -> Option<&DebugSymbol> { if self.symbols.is_empty() { return None; } - let symbol = match self.symbols.binary_search_by_key(&address, |s| s.address) { - Ok(index) => self.symbols.get(index)?, - Err(index) => self.symbols.get(index.checked_sub(1)?)?, - }; - Some(&symbol) + match self.symbols.binary_search_by_key(&address, |s| s.address) { + Ok(index) => self.symbols.get(index), + Err(index) => self.symbols.get(index.checked_sub(1)?), + } } } -struct DebugSymbol { - address: u16, - name: String, - location: Option<String>, + +pub struct DebugSymbol { + pub address: u16, + pub name: String, + pub location: Option<String>, } impl DebugSymbol { pub fn from_line(line: &str) -> Option<Self> { - if let Some((address, line)) = line.split_once(' ') { - let address = u16::from_str_radix(address, 16).ok()?; - if let Some((name, location)) = line.split_once(' ') { - let name = name.to_string(); - let location = Some(location.to_string()); - Some( DebugSymbol { address, name, location } ) - } else { - let name = line.to_string(); - Some( DebugSymbol { address, name, location: None } ) - } + let (address, line) = line.split_once(' ')?; + let address = u16::from_str_radix(address, 16).ok()?; + if let Some((name, location)) = line.split_once(' ') { + let name = name.to_string(); + let location = Some(location.to_string()); + Some( DebugSymbol { address, name, location } ) } else { - None + let name = line.to_string(); + Some( DebugSymbol { address, name, location: None } ) } } } |