fixed a lot of bugs with the emulator, instruction set and assembler

This commit is contained in:
2025-06-19 01:57:36 +01:00
parent e281bc2d1d
commit 6b58a17f03
13 changed files with 209 additions and 47 deletions
+29 -6
View File
@@ -27,10 +27,11 @@ pub fn run_emulator(
let mut running = Running::Paused;
let mut addr = 0u32;
let mut history = Vec::<(u32, Instruction)>::new();
let size = 256;
let memory_view = processor.memory.read_range(addr, size);
let initial_state = state(&mut processor, running, 0, memory_view);
let initial_state = state(&mut processor, running, 0, memory_view, &mut history);
let _ = state_tx.send(initial_state);
let mut instruction_count = 0;
@@ -79,7 +80,9 @@ pub fn run_emulator(
// Execute one cycle.
match processor.cycle() {
Ok(_) => {}
Ok((addr, instruction)) => {
history.push((addr, instruction.clone()));
}
Err(why) => {
let pcx = processor.get(Register::Pcx);
eprintln!(
@@ -103,7 +106,15 @@ pub fn run_emulator(
}
let memory_view = processor.memory.read_range(addr, size);
let state = state(&mut processor, running, instruction_count, memory_view);
let state = state(
&mut processor,
running,
instruction_count,
memory_view,
&mut history,
);
println!("state");
let _ = state_tx.send(state);
}
@@ -121,10 +132,12 @@ pub fn run_emulator(
}
};
history.push(instruction.clone());
// let instruction = match Instruction::decode(cpu_lock.get(Register::Cir))
// {};
if matches!(instruction, Instruction::Halt) {
if matches!(instruction.1, Instruction::Halt) {
running = Running::Halted;
update = true;
}
@@ -138,8 +151,13 @@ pub fn run_emulator(
if update {
let memory_view = processor.memory.read_range(addr, size);
let state =
state(&mut processor, running, instruction_count, memory_view);
let state = state(
&mut processor,
running,
instruction_count,
memory_view,
&mut history,
);
let _ = state_tx.send(state);
}
} else {
@@ -153,7 +171,11 @@ fn state(
running: Running,
instruction_count: usize,
memory_view: Vec<u8>,
history: &mut Vec<(u32, Instruction)>,
) -> State {
let hsclone = history.clone();
history.clear();
State {
// TODO: Replace with actual register access from your CPU.
reg_file: cpu_lock.registers,
@@ -163,5 +185,6 @@ fn state(
memory_view,
display_view: cpu_lock.display(),
error: None,
history: hsclone,
}
}
+2
View File
@@ -205,6 +205,7 @@ pub struct State {
pub stack_view: Vec<u8>,
pub memory_view: Vec<u8>,
pub display_view: Vec<u8>,
pub history: Vec<(u32, Instruction)>,
pub error: Option<String>,
}
@@ -217,6 +218,7 @@ impl Default for State {
stack_view: vec![],
memory_view: vec![],
display_view: vec![],
history: vec![],
error: None,
}
}
@@ -38,7 +38,7 @@ impl Processor {
self.memory.reset();
}
pub fn cycle(&mut self) -> Result<Instruction, InstructionDecodeError> {
pub fn cycle(&mut self) -> Result<(u32, Instruction), InstructionDecodeError> {
self.halted = false;
// Get value from PCX.
@@ -58,7 +58,7 @@ impl Processor {
instruction.execute(self);
Ok(instruction)
Ok((addr, instruction))
}
fn fetch(&self) -> u32 {
@@ -405,11 +405,11 @@ impl Executable for Instruction {
// mathematical and logical functions & other operations
const fn add(a: u32, b: u32) -> u32 {
a + b
a.wrapping_add(b)
}
const fn sub(a: u32, b: u32) -> u32 {
a - b
a.wrapping_sub(b)
}
const fn and(a: u32, b: u32) -> u32 {
@@ -417,11 +417,11 @@ const fn and(a: u32, b: u32) -> u32 {
}
const fn inc(a: u32) -> u32 {
a + 1
a.wrapping_add(1)
}
const fn dec(a: u32) -> u32 {
a - 1
a.wrapping_sub(1)
}
const fn shl(a: u32, amount: u8) -> u32 {
+95
View File
@@ -0,0 +1,95 @@
use std::{ffi::OsStr, path::PathBuf, sync::mpsc::Sender};
use common::prelude::Instruction;
use egui::{Align, Context, Key, Layout, Ui};
use rfd::FileDialog;
use dsa_editor::{CodeEditor, ColorTheme, Syntax};
use crate::emulator::{
system::model::{Command, State},
ui::interface::Component,
};
pub struct History {
visible: bool,
history: Vec<(u32, Instruction)>,
}
impl Component for History {
fn name(&self) -> &'static str {
"Instruction History"
}
fn visible(&mut self) -> &mut bool {
&mut self.visible
}
fn category(&self) -> super::interface::Category {
super::interface::Category::Control
}
fn render(&mut self, state: &mut State, ui: &mut Ui, ctx: &Context) {
self.update(state);
egui::ScrollArea::vertical()
.id_salt("output_scroll")
.max_width(400.0)
.show(ui, |ui| {
if self.history.is_empty() {
ui.label(
egui::RichText::new("No output data")
.font(egui::FontId::monospace(12.0))
.color(egui::Color32::GRAY),
);
return;
}
egui::Grid::new("output_grid")
.spacing([5.0, 2.0]) // Horizontal and vertical spacing
.num_columns(4)
.striped(false)
.show(ui, |ui| {
// Process bytes in chunks of 4
for (idx, instruction) in self.history.iter().enumerate() {
ui.label(format!("{}: ", idx));
// Hex column
let addr = instruction.0;
ui.label(
egui::RichText::new(format!("0x{addr:08X}"))
.font(egui::FontId::monospace(12.0))
.color(egui::Color32::from_rgb(255, 200, 200)),
);
ui.label(
egui::RichText::new(instruction.1.to_string())
.font(egui::FontId::monospace(12.0))
.color(egui::Color32::from_rgb(200, 255, 200)),
);
ui.end_row();
}
});
});
}
}
impl History {
#[must_use]
pub fn new() -> Self {
Self {
visible: false,
history: Vec::with_capacity(1000),
}
}
fn update(&mut self, state: &mut State) {
self.history.extend(state.history.clone());
state.history.clear();
if self.history.len() > 1000 {
let len = self.history.len() - 1000;
self.history.drain(..len);
}
}
}
+1
View File
@@ -1,6 +1,7 @@
pub mod control_unit;
pub mod display;
pub mod editor;
pub mod history;
pub mod interface;
pub mod memory_inspector;
pub mod menu;
+7 -2
View File
@@ -1,3 +1,5 @@
use std::io::Read;
use crate::emulator::{system::model::State, ui::interface::Component};
use common::instructions::Register;
@@ -47,11 +49,14 @@ impl Component for StackInspector {
ui.label("Value");
ui.end_row();
for (i, value) in (0u32..).zip(state.stack_view.iter().take(32)) {
for (i, value) in
state.stack_view.chunks(4).take(32).enumerate()
{
let value = u32::from_be_bytes(value.try_into().unwrap());
ui.label(format!(
"{} [{}]",
i,
state.reg_file.get(Register::Spr) - i * 4
state.reg_file.get(Register::Spr) - i as u32 * 4
));
ui.label(format!("0x{value:08X} ({value})"));
ui.end_row();
+3
View File
@@ -101,5 +101,8 @@ fn setup_ui(cmd_sender: Sender<Command>, state_reciever: Receiver<State>) -> Emu
let display = Display::new();
ui.add_component(Box::new(display));
let history = dsa_rs::emulator::ui::history::History::new();
ui.add_component(Box::new(history));
ui
}