Implement execute breakpoints
This commit is contained in:
+42
-8
@@ -18,7 +18,7 @@ use bytemuck::NoUninit;
|
||||
use egui_toast::{Toast, ToastKind, ToastOptions};
|
||||
|
||||
use crate::{audio::Audio, graphics::TextureSink};
|
||||
use shrooms_vb_core::{Sim, EXPECTED_FRAME_SIZE};
|
||||
use shrooms_vb_core::{Sim, StopReason, EXPECTED_FRAME_SIZE};
|
||||
pub use shrooms_vb_core::{VBKey, VBRegister};
|
||||
|
||||
mod shrooms_vb_core;
|
||||
@@ -302,6 +302,9 @@ impl Emulator {
|
||||
}
|
||||
|
||||
fn stop_debugging(&mut self, sim_id: SimId) {
|
||||
if let Some(sim) = self.sims.get_mut(sim_id.to_index()) {
|
||||
sim.clear_breakpoints();
|
||||
}
|
||||
self.debuggers.remove(&sim_id);
|
||||
if self.debuggers.is_empty() {
|
||||
let _ = self.state.compare_exchange(
|
||||
@@ -314,17 +317,17 @@ impl Emulator {
|
||||
}
|
||||
|
||||
fn debug_interrupt(&mut self, sim_id: SimId) {
|
||||
self.debug_stop(sim_id, DebugStopReason::Trapped);
|
||||
}
|
||||
|
||||
fn debug_stop(&mut self, sim_id: SimId, reason: DebugStopReason) {
|
||||
let Some(debugger) = self.debuggers.get_mut(&sim_id) else {
|
||||
self.stop_debugging(sim_id);
|
||||
return;
|
||||
};
|
||||
if !matches!(debugger.stop_reason, Some(DebugStopReason::Trapped)) {
|
||||
debugger.stop_reason = Some(DebugStopReason::Trapped);
|
||||
if debugger
|
||||
.sender
|
||||
.send(DebugEvent::Stopped(DebugStopReason::Trapped))
|
||||
.is_err()
|
||||
{
|
||||
if debugger.stop_reason != Some(reason) {
|
||||
debugger.stop_reason = Some(reason);
|
||||
if debugger.sender.send(DebugEvent::Stopped(reason)).is_err() {
|
||||
self.stop_debugging(sim_id);
|
||||
}
|
||||
}
|
||||
@@ -389,6 +392,21 @@ impl Emulator {
|
||||
self.sims[SimId::Player2.to_index()].emulate();
|
||||
}
|
||||
|
||||
// Debug state
|
||||
if state == EmulatorState::Debugging {
|
||||
for sim_id in SimId::values() {
|
||||
let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
|
||||
continue;
|
||||
};
|
||||
if let Some(reason) = sim.stop_reason() {
|
||||
let stop_reason = match reason {
|
||||
StopReason::Breakpoint => DebugStopReason::Breakpoint,
|
||||
};
|
||||
self.debug_stop(sim_id, stop_reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Video
|
||||
for sim_id in SimId::values() {
|
||||
let Some(renderer) = self.renderers.get_mut(&sim_id) else {
|
||||
@@ -493,6 +511,18 @@ impl Emulator {
|
||||
sim.read_memory(addresses, &mut buffer);
|
||||
let _ = done.send(buffer);
|
||||
}
|
||||
EmulatorCommand::AddBreakpoint(sim_id, address) => {
|
||||
let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
|
||||
return;
|
||||
};
|
||||
sim.add_breakpoint(address);
|
||||
}
|
||||
EmulatorCommand::RemoveBreakpoint(sim_id, address) => {
|
||||
let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
|
||||
return;
|
||||
};
|
||||
sim.remove_breakpoint(address);
|
||||
}
|
||||
EmulatorCommand::SetAudioEnabled(p1, p2) => {
|
||||
self.audio_on[SimId::Player1.to_index()].store(p1, Ordering::Release);
|
||||
self.audio_on[SimId::Player2.to_index()].store(p2, Ordering::Release);
|
||||
@@ -556,6 +586,8 @@ pub enum EmulatorCommand {
|
||||
DebugContinue(SimId),
|
||||
ReadRegister(SimId, VBRegister, oneshot::Sender<u32>),
|
||||
ReadMemory(SimId, Range<u32>, Vec<u8>, oneshot::Sender<Vec<u8>>),
|
||||
AddBreakpoint(SimId, u32),
|
||||
RemoveBreakpoint(SimId, u32),
|
||||
SetAudioEnabled(bool, bool),
|
||||
Link,
|
||||
Unlink,
|
||||
@@ -584,6 +616,8 @@ type DebugSender = tokio::sync::mpsc::UnboundedSender<DebugEvent>;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum DebugStopReason {
|
||||
// We hit a breakpoint
|
||||
Breakpoint,
|
||||
// The debugger told us to pause
|
||||
Trapped,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user