debugger: Fix/Improve Continue command

Former-commit-id: 8f64618a51c1805ccf5db0da9a2d0a2335928588
Former-commit-id: 180721c6aa6b7fe32a3afb23c01c048bcd9aa878
This commit is contained in:
Michel Heily 2020-05-21 22:08:49 +03:00 committed by MishMish
parent bccb31c142
commit 58c9d10360
2 changed files with 53 additions and 9 deletions

View file

@ -105,16 +105,23 @@ impl Debugger {
} }
println!("{}\n", self.gba.cpu); println!("{}\n", self.gba.cpu);
} }
Continue => loop { Continue => 'running: loop {
self.gba.key_poll(); self.gba.key_poll();
match self.gba.check_breakpoint() { if let Some(breakpoint) = self.gba.step_debugger() {
Some(addr) => { let mut bp_sym = None;
println!("Breakpoint reached! @{:x}", addr); if let Some(symbols) = self.gba.sysbus.cartridge.get_symbols() {
break; for s in symbols.keys() {
if symbols.get(s).unwrap() == &breakpoint {
bp_sym = Some(s.clone());
}
}
} }
_ => { if let Some(sym) = bp_sym {
self.gba.cpu.step(&mut self.gba.sysbus); println!("Breakpoint reached! @{}", sym);
} else {
println!("Breakpoint reached! @{:x}", breakpoint);
} }
break 'running;
} }
}, },
Frame(count) => { Frame(count) => {

View file

@ -174,8 +174,8 @@ impl GameBoyAdvance {
pub fn check_breakpoint(&self) -> Option<u32> { pub fn check_breakpoint(&self) -> Option<u32> {
let next_pc = self.cpu.get_next_pc(); let next_pc = self.cpu.get_next_pc();
for bp in &self.cpu.breakpoints { for bp in &self.cpu.breakpoints {
if *bp == next_pc { if (*bp & !1) == next_pc {
return Some(next_pc); return Some(*bp);
} }
} }
@ -249,6 +249,43 @@ impl GameBoyAdvance {
cycles cycles
} }
#[cfg(feature = "debugger")]
/// 'step' function that checks for breakpoints
/// TODO avoid code duplication
pub fn step_debugger(&mut self) -> Option<u32> {
// I hate myself for doing this, but rust left me no choice.
let io = unsafe {
let ptr = &mut *self.sysbus as *mut SysBus;
&mut (*ptr).io as &mut IoDevices
};
// clear any pending DMAs
let mut irqs = IrqBitmask(0);
while io.dmac.is_active() {
io.dmac.perform_work(&mut self.sysbus, &mut irqs);
}
io.intc.request_irqs(irqs);
let cycles = self.step_cpu(io);
let breakpoint = self.check_breakpoint();
irqs = IrqBitmask(0);
let mut _ignored = 0;
// update gpu & sound
io.timers.update(cycles, &mut self.sysbus, &mut irqs);
io.gpu.update(
cycles,
&mut irqs,
&mut _ignored,
self.sysbus.as_mut(),
&self.video_device,
);
io.sound.update(cycles, &mut _ignored, &self.audio_device);
io.intc.request_irqs(irqs);
breakpoint
}
/// Query the emulator for the recently drawn framebuffer. /// Query the emulator for the recently drawn framebuffer.
/// for use with implementations where the VideoInterface is not a viable option. /// for use with implementations where the VideoInterface is not a viable option.
pub fn get_frame_buffer(&self) -> &[u32] { pub fn get_frame_buffer(&self) -> &[u32] {