Track HALT

This commit is contained in:
2025-08-27 22:49:44 -04:00
parent 7f819d080f
commit 8aab90f024
2 changed files with 80 additions and 34 deletions
+26 -4
View File
@@ -210,7 +210,7 @@ extern "C" fn on_execute(sim: *mut VB, address: u32, code: *const u16, length: c
}
}
let mut stopped = data.stop_reason.is_some();
let mut stopped = data.stop_reason.is_some() || data.monitor.event.is_some();
if data.step_from.is_some_and(|s| s != address) {
data.step_from = None;
data.stop_reason = Some(StopReason::Stepped);
@@ -247,7 +247,13 @@ extern "C" fn on_exception(sim: *mut VB, cause: *mut u16) -> c_int {
// There is no way for the userdata to be null or otherwise invalid.
let data: &mut VBState = unsafe { &mut *vb_get_user_data(sim).cast() };
data.monitor.event = data.monitor.queued_event.take();
data.monitor.queued_event = Some(SimEvent::Interrupt(unsafe { *cause }));
let cause = unsafe { *cause };
let pc = if cause == 0xff70 {
0xffffff60
} else {
(cause & 0xfff0) as u32 | 0xffff0000
};
data.monitor.queued_event = Some(SimEvent::Interrupt(cause, pc));
unsafe { vb_set_exception_callback(sim, None) };
unsafe { vb_set_fetch_callback(sim, Some(on_fetch)) };
if data.monitor.event.is_some() { 1 } else { 0 }
@@ -319,7 +325,8 @@ extern "C" fn on_write(
pub enum SimEvent {
Call(u32),
Return,
Interrupt(u16),
Halt,
Interrupt(u16, u32),
Reti,
}
@@ -327,6 +334,7 @@ struct EventMonitor {
enabled: bool,
event: Option<SimEvent>,
queued_event: Option<SimEvent>,
just_halted: bool,
}
impl EventMonitor {
@@ -335,6 +343,7 @@ impl EventMonitor {
enabled: false,
event: None,
queued_event: None,
just_halted: false,
}
}
@@ -343,7 +352,8 @@ impl EventMonitor {
self.queued_event.is_some()
}
fn do_detect_event(&self, sim: *mut VB, address: u32, code: &[u16]) -> Option<SimEvent> {
fn do_detect_event(&mut self, sim: *mut VB, address: u32, code: &[u16]) -> Option<SimEvent> {
const HALT_OPCODE: u16 = 0b011010;
const JAL_OPCODE: u16 = 0b101011;
const JMP_OPCODE: u16 = 0b000110;
const RETI_OPCODE: u16 = 0b011001;
@@ -359,6 +369,18 @@ impl EventMonitor {
let opcode = code[0] >> 10;
if opcode == HALT_OPCODE {
if !self.just_halted {
self.just_halted = true;
self.event = Some(SimEvent::Halt);
} else {
self.just_halted = false;
}
// Don't _return_ an event, we want to emit this right away.
// If the CPU is halting, no other callbacks will run for a long time.
return None;
}
if opcode == JAL_OPCODE {
let disp = format_iv_disp(code);
if disp != 4 {