diff --git a/src/cpus/m68k/debugger.rs b/src/cpus/m68k/debugger.rs index f6fd331..215c545 100644 --- a/src/cpus/m68k/debugger.rs +++ b/src/cpus/m68k/debugger.rs @@ -5,19 +5,43 @@ use crate::memory::{Address, AddressSpace}; use super::execute::{MC68010}; use super::decode::{Instruction, Target, Size, Direction, Condition, ControlRegister, RegisterType}; +pub struct StackTracer { + pub calls: Vec, +} + +impl StackTracer { + pub fn new() -> StackTracer { + StackTracer { + calls: vec![], + } + } + + pub fn push_return(&mut self, addr: u32) { + self.calls.push(addr); + } + + pub fn pop_return(&mut self) { + self.calls.pop(); + } +} + + pub struct M68kDebugger { pub breakpoints: Vec, pub use_tracing: bool, pub use_debugger: bool, + pub step_until_return: bool, + pub stack_tracer: StackTracer, } - impl M68kDebugger { pub fn new() -> M68kDebugger { M68kDebugger { breakpoints: vec!(), use_tracing: false, use_debugger: false, + step_until_return: false, + stack_tracer: StackTracer::new(), } } } @@ -45,6 +69,17 @@ impl MC68010 { pub fn run_debugger(&mut self, space: &mut AddressSpace) { self.dump_state(space); + if self.debugger.step_until_return { + match self.decoder.instruction { + Instruction::RTS | Instruction::RTE | Instruction::RTR => { + self.debugger.step_until_return = false; + } + _ => { + return; + }, + } + } + loop { let mut buffer = String::new(); std::io::stdin().read_line(&mut buffer).unwrap(); @@ -83,6 +118,16 @@ impl MC68010 { space.dump_memory(self.state.msp as Address, 0x40 as Address); } }, + "ds" | "stack" | "dumpstack" => { + println!("Stack:"); + for addr in &self.debugger.stack_tracer.calls { + println!(" {:08x}", space.read_beu32(*addr as Address)?); + } + }, + "so" | "stepout" => { + self.debugger.step_until_return = true; + return Ok(true); + }, "c" | "continue" => { self.debugger.use_debugger = false; return Ok(true); diff --git a/src/cpus/m68k/execute.rs b/src/cpus/m68k/execute.rs index 91728fa..718e0de 100644 --- a/src/cpus/m68k/execute.rs +++ b/src/cpus/m68k/execute.rs @@ -227,6 +227,8 @@ impl MC68010 { }, Instruction::BSR(offset) => { self.push_long(space, self.state.pc)?; + let sp = *self.get_stack_pointer_mut(); + self.debugger.stack_tracer.push_return(sp); self.state.pc = (self.decoder.start + 2).wrapping_add(offset as u32); }, Instruction::BTST(bitnum, target, size) => { @@ -267,10 +269,10 @@ impl MC68010 { self.set_compare_flags(result, size, carry, get_overflow(existing, value, result, size)); }, Instruction::CMPA(src, reg, size) => { - let value = self.get_target_value(space, src, size)?; - let existing = sign_extend_to_long(*self.get_a_reg_mut(reg), size) as u32; + let value = sign_extend_to_long(self.get_target_value(space, src, size)?, size) as u32; + let existing = *self.get_a_reg_mut(reg); let (result, carry) = overflowing_sub_sized(existing, value, Size::Long); - self.set_compare_flags(result, size, carry, get_overflow(existing, value, result, Size::Long)); + self.set_compare_flags(result, Size::Long, carry, get_overflow(existing, value, result, Size::Long)); }, Instruction::DBcc(cond, reg, offset) => { let condition_true = self.get_current_condition(cond); @@ -326,6 +328,8 @@ impl MC68010 { }, Instruction::JSR(target) => { self.push_long(space, self.state.pc)?; + let sp = *self.get_stack_pointer_mut(); + self.debugger.stack_tracer.push_return(sp); self.state.pc = self.get_target_address(target)?; }, Instruction::LEA(target, reg) => { @@ -493,6 +497,7 @@ impl MC68010 { //Instruction::RTR => { //}, Instruction::RTS => { + self.debugger.stack_tracer.pop_return(); self.state.pc = self.pop_long(space)?; }, Instruction::Scc(cond, target) => { diff --git a/src/main.rs b/src/main.rs index 090e731..d1325a5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,7 +30,8 @@ fn main() { //cpu.enable_tracing(); //cpu.add_breakpoint(0x0c94); - cpu.add_breakpoint(0x103220); + //cpu.add_breakpoint(0x103234); + //cpu.add_breakpoint(0x106e6a); while cpu.is_running() { match cpu.step(&mut space) { diff --git a/src/memory.rs b/src/memory.rs index f57f5a6..9e537f0 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -143,7 +143,7 @@ impl AddressSpace { pub fn read(&mut self, addr: Address, count: usize) -> Result, Error> { let mut seg = self.get_segment_mut(addr)?; let relative_addr = addr - seg.base; - if relative_addr as usize + count >= seg.contents.len() { + if relative_addr as usize + count > seg.contents.len() { Err(Error::new(&format!("Error reading address {:#010x}", addr))) } else { Ok(seg.contents.read(relative_addr, count))