mirror of
https://github.com/transistorfet/moa.git
synced 2025-01-10 13:30:05 +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::execute::{MC68010};
|
||||||
use super::decode::{Instruction, Target, Size, Direction, Condition, ControlRegister, RegisterType};
|
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 struct M68kDebugger {
|
||||||
pub breakpoints: Vec<u32>,
|
pub breakpoints: Vec<u32>,
|
||||||
pub use_tracing: bool,
|
pub use_tracing: bool,
|
||||||
pub use_debugger: bool,
|
pub use_debugger: bool,
|
||||||
|
pub step_until_return: bool,
|
||||||
|
pub stack_tracer: StackTracer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl M68kDebugger {
|
impl M68kDebugger {
|
||||||
pub fn new() -> M68kDebugger {
|
pub fn new() -> M68kDebugger {
|
||||||
M68kDebugger {
|
M68kDebugger {
|
||||||
breakpoints: vec!(),
|
breakpoints: vec!(),
|
||||||
use_tracing: false,
|
use_tracing: false,
|
||||||
use_debugger: 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) {
|
pub fn run_debugger(&mut self, space: &mut AddressSpace) {
|
||||||
self.dump_state(space);
|
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 {
|
loop {
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
std::io::stdin().read_line(&mut buffer).unwrap();
|
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);
|
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" => {
|
"c" | "continue" => {
|
||||||
self.debugger.use_debugger = false;
|
self.debugger.use_debugger = false;
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
|
@ -227,6 +227,8 @@ impl MC68010 {
|
|||||||
},
|
},
|
||||||
Instruction::BSR(offset) => {
|
Instruction::BSR(offset) => {
|
||||||
self.push_long(space, self.state.pc)?;
|
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);
|
self.state.pc = (self.decoder.start + 2).wrapping_add(offset as u32);
|
||||||
},
|
},
|
||||||
Instruction::BTST(bitnum, target, size) => {
|
Instruction::BTST(bitnum, target, size) => {
|
||||||
@ -267,10 +269,10 @@ impl MC68010 {
|
|||||||
self.set_compare_flags(result, size, carry, get_overflow(existing, value, result, size));
|
self.set_compare_flags(result, size, carry, get_overflow(existing, value, result, size));
|
||||||
},
|
},
|
||||||
Instruction::CMPA(src, reg, size) => {
|
Instruction::CMPA(src, reg, size) => {
|
||||||
let value = self.get_target_value(space, src, size)?;
|
let value = sign_extend_to_long(self.get_target_value(space, src, size)?, size) as u32;
|
||||||
let existing = sign_extend_to_long(*self.get_a_reg_mut(reg), size) as u32;
|
let existing = *self.get_a_reg_mut(reg);
|
||||||
let (result, carry) = overflowing_sub_sized(existing, value, Size::Long);
|
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) => {
|
Instruction::DBcc(cond, reg, offset) => {
|
||||||
let condition_true = self.get_current_condition(cond);
|
let condition_true = self.get_current_condition(cond);
|
||||||
@ -326,6 +328,8 @@ impl MC68010 {
|
|||||||
},
|
},
|
||||||
Instruction::JSR(target) => {
|
Instruction::JSR(target) => {
|
||||||
self.push_long(space, self.state.pc)?;
|
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)?;
|
self.state.pc = self.get_target_address(target)?;
|
||||||
},
|
},
|
||||||
Instruction::LEA(target, reg) => {
|
Instruction::LEA(target, reg) => {
|
||||||
@ -493,6 +497,7 @@ impl MC68010 {
|
|||||||
//Instruction::RTR => {
|
//Instruction::RTR => {
|
||||||
//},
|
//},
|
||||||
Instruction::RTS => {
|
Instruction::RTS => {
|
||||||
|
self.debugger.stack_tracer.pop_return();
|
||||||
self.state.pc = self.pop_long(space)?;
|
self.state.pc = self.pop_long(space)?;
|
||||||
},
|
},
|
||||||
Instruction::Scc(cond, target) => {
|
Instruction::Scc(cond, target) => {
|
||||||
|
@ -30,7 +30,8 @@ fn main() {
|
|||||||
//cpu.enable_tracing();
|
//cpu.enable_tracing();
|
||||||
|
|
||||||
//cpu.add_breakpoint(0x0c94);
|
//cpu.add_breakpoint(0x0c94);
|
||||||
cpu.add_breakpoint(0x103220);
|
//cpu.add_breakpoint(0x103234);
|
||||||
|
//cpu.add_breakpoint(0x106e6a);
|
||||||
|
|
||||||
while cpu.is_running() {
|
while cpu.is_running() {
|
||||||
match cpu.step(&mut space) {
|
match cpu.step(&mut space) {
|
||||||
|
@ -143,7 +143,7 @@ impl AddressSpace {
|
|||||||
pub fn read(&mut self, addr: Address, count: usize) -> Result<Vec<u8>, Error> {
|
pub fn read(&mut self, addr: Address, count: usize) -> Result<Vec<u8>, Error> {
|
||||||
let mut seg = self.get_segment_mut(addr)?;
|
let mut seg = self.get_segment_mut(addr)?;
|
||||||
let relative_addr = addr - seg.base;
|
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)))
|
Err(Error::new(&format!("Error reading address {:#010x}", addr)))
|
||||||
} else {
|
} else {
|
||||||
Ok(seg.contents.read(relative_addr, count))
|
Ok(seg.contents.read(relative_addr, count))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user