added step(n) feature to emulator, allowing for stepping n instructions at a time

This commit is contained in:
2025-06-24 18:07:11 +01:00
parent 4ef8bbdf46
commit d2c1492dca
4 changed files with 59 additions and 30 deletions
+29 -21
View File
@@ -27,6 +27,7 @@ pub fn run_emulator(
println!("INFO: Starting emulator.");
let mut running = Running::Paused;
let mut step = 0;
let mut addr;
let mut history = Vec::<(u32, Instruction)>::new();
let size = 256;
@@ -39,7 +40,7 @@ pub fn run_emulator(
let mut update = false;
loop {
let cmd = if running == Running::Running {
let cmd = if running == Running::Running || step > 0 {
match cmd_rx.try_recv() {
Ok(cmd) => Some(cmd),
Err(mpsc::TryRecvError::Empty) => {
@@ -96,26 +97,8 @@ pub fn run_emulator(
processor.reset();
}
Command::Step => {
update = true;
running = Running::Paused;
// Execute one cycle.
match processor.cycle() {
Ok((addr, instruction)) => {
history.push((addr, instruction));
}
Err(why) => {
let pcx = processor.get(Register::Pcx);
eprintln!(
"Could not decode instruction at {pcx:x}. Reason: {why}"
);
continue;
}
}
instruction_count += 1;
Command::Step(x) => {
step = x;
}
Command::Write(offset, data) => {
update = true;
@@ -200,6 +183,31 @@ pub fn run_emulator(
}
}
if step > 0 {
step -= 1;
update = true;
running = Running::Paused;
// Execute one cycle.
match processor.cycle() {
Ok((addr, instruction)) => {
history.push((addr, instruction));
}
Err(why) => {
let pcx = processor.get(Register::Pcx);
report_err(
state_tx,
&format!(
"Could not decode instruction at {pcx:x}. Reason: {why}"
),
&mut processor,
);
}
}
instruction_count += 1;
continue;
}
if running == Running::Running {
update = true;
+1 -1
View File
@@ -21,7 +21,7 @@ pub enum Command {
// set emulator state.
Start,
Stop,
Step,
Step(usize),
Reset(usize),
Interrupt(Interrupt),
Write(Address, Vec<u8>),
@@ -64,10 +64,7 @@ impl Processor {
let instruction = Instruction::decode(val)
.map_err(|_| ProcessorError::InvalidInstruction(val))?;
log(&instruction.to_string());
instruction.execute(self)?;
Ok((addr, instruction))
}
+29 -5
View File
@@ -7,12 +7,18 @@ use common::{instructions::Register, prelude::Instruction};
pub struct ControlPanel {
visible: bool,
step_amount_input: String,
step_amount: usize,
}
impl ControlPanel {
#[allow(clippy::must_use_candidate)]
pub const fn new() -> Self {
Self { visible: false }
pub fn new() -> Self {
Self {
visible: false,
step_amount_input: String::from("1"),
step_amount: 1,
}
}
}
@@ -59,9 +65,12 @@ impl Component for ControlPanel {
// Step
if ui.button("Step").clicked() {
state.cmd_sender.send(Command::Step).unwrap_or_else(|_| {
state.error_log.push("Failed to send command".to_string());
});
state
.cmd_sender
.send(Command::Step(self.step_amount))
.unwrap_or_else(|_| {
state.error_log.push("Failed to send command".to_string());
});
}
// Resets the emulator and all attached devices
@@ -98,6 +107,21 @@ impl Component for ControlPanel {
state.send(Command::RegisterRequest);
state.send(Command::RunningRequest);
state.send(Command::InstructionCountRequest);
if ui
.text_edit_singleline(&mut self.step_amount_input)
.changed()
{
self.step_amount = if let Ok(amount) = self.step_amount_input.parse() {
amount
} else {
state
.error_log
.push("Unable to parse step amount".to_string());
1
}
}
// Status info
ui.label(format!(