summaryrefslogtreecommitdiff
path: root/src/debug.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/debug.rs')
-rw-r--r--src/debug.rs127
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 } )
}
}
}