Added stack tracer and fixed bug with CMPA instruction

This commit is contained in:
transistor 2021-10-04 11:13:10 -07:00
parent 2f54c18fcf
commit e561c533ef
4 changed files with 57 additions and 6 deletions

View File

@ -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<u32>,
}
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<u32>,
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);

View File

@ -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) => {

View File

@ -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) {

View File

@ -143,7 +143,7 @@ impl AddressSpace {
pub fn read(&mut self, addr: Address, count: usize) -> Result<Vec<u8>, 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))