mirror of
https://github.com/transistorfet/moa.git
synced 2024-12-23 03:29:24 +00:00
Added stack tracer and fixed bug with CMPA instruction
This commit is contained in:
parent
2f54c18fcf
commit
e561c533ef
@ -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);
|
||||
|
@ -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) => {
|
||||
|
@ -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) {
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user