added step(n) feature to emulator, allowing for stepping n instructions at a time
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
|
||||
@@ -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!(
|
||||
|
||||
Reference in New Issue
Block a user