2021-11-07 04:18:45 +00:00
|
|
|
|
2022-09-25 06:14:03 +00:00
|
|
|
use moa_core::{System, Error, Address, Debuggable};
|
2021-11-07 04:18:45 +00:00
|
|
|
|
2022-09-25 06:14:03 +00:00
|
|
|
use crate::state::Z80;
|
|
|
|
use crate::decode::Z80Decoder;
|
2021-11-07 04:18:45 +00:00
|
|
|
|
|
|
|
|
2023-05-10 04:50:42 +00:00
|
|
|
#[derive(Clone, Default)]
|
2021-11-07 04:18:45 +00:00
|
|
|
pub struct Z80Debugger {
|
2021-12-21 03:53:12 +00:00
|
|
|
pub enabled: bool,
|
2021-11-07 04:18:45 +00:00
|
|
|
pub breakpoints: Vec<u16>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Debuggable for Z80 {
|
2021-12-21 03:53:12 +00:00
|
|
|
fn debugging_enabled(&mut self) -> bool {
|
|
|
|
self.debugger.enabled
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_debugging(&mut self, enable: bool) {
|
|
|
|
self.debugger.enabled = enable;
|
|
|
|
}
|
|
|
|
|
2021-11-07 04:18:45 +00:00
|
|
|
fn add_breakpoint(&mut self, addr: Address) {
|
|
|
|
self.debugger.breakpoints.push(addr as u16);
|
2021-12-21 03:53:12 +00:00
|
|
|
self.debugger.enabled = true;
|
2021-11-07 04:18:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn remove_breakpoint(&mut self, addr: Address) {
|
|
|
|
if let Some(index) = self.debugger.breakpoints.iter().position(|a| *a == addr as u16) {
|
|
|
|
self.debugger.breakpoints.remove(index);
|
2021-12-21 03:53:12 +00:00
|
|
|
self.debugger.enabled = !self.debugger.breakpoints.is_empty();
|
2021-11-07 04:18:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-24 01:49:40 +00:00
|
|
|
fn print_current_step(&mut self, system: &System) -> Result<(), Error> {
|
|
|
|
self.decoder.decode_at(&mut self.port, system.clock, self.state.pc)?;
|
2021-11-07 04:18:45 +00:00
|
|
|
self.decoder.dump_decoded(&mut self.port);
|
2023-04-24 01:49:40 +00:00
|
|
|
self.dump_state(system.clock);
|
2021-11-07 04:18:45 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn print_disassembly(&mut self, addr: Address, count: usize) {
|
2023-03-06 04:19:49 +00:00
|
|
|
let mut decoder = Z80Decoder::default();
|
2021-11-10 21:28:31 +00:00
|
|
|
decoder.dump_disassembly(&mut self.port, addr as u16, count as u16);
|
2021-11-07 04:18:45 +00:00
|
|
|
}
|
|
|
|
|
2021-11-13 19:39:20 +00:00
|
|
|
fn execute_command(&mut self, _system: &System, args: &[&str]) -> Result<bool, Error> {
|
2021-11-10 21:28:31 +00:00
|
|
|
match args[0] {
|
|
|
|
"l" => {
|
|
|
|
use super::state::Register;
|
|
|
|
self.state.reg[Register::L as usize] = 0x05
|
|
|
|
},
|
|
|
|
_ => { return Ok(true); },
|
|
|
|
}
|
2021-11-07 04:18:45 +00:00
|
|
|
Ok(false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Z80 {
|
|
|
|
pub fn check_breakpoints(&mut self, system: &System) {
|
|
|
|
for breakpoint in &self.debugger.breakpoints {
|
|
|
|
if *breakpoint == self.state.pc {
|
|
|
|
println!("Breakpoint reached: {:08x}", *breakpoint);
|
|
|
|
system.enable_debugging();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|