From 87e2d388670b29a51142b1a029925213f46a9957 Mon Sep 17 00:00:00 2001 From: Alessio Cosenza Date: Sun, 6 Nov 2022 16:56:52 +0100 Subject: [PATCH] UI: Add `MemoryInspector` --- emu/src/arm7tdmi.rs | 7 +++- emu/src/cpu.rs | 7 ++++ ui/src/dashboard.rs | 9 +++-- ui/src/lib.rs | 1 + ui/src/memory_inspector.rs | 73 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 ui/src/memory_inspector.rs diff --git a/emu/src/arm7tdmi.rs b/emu/src/arm7tdmi.rs index 7de2a49d..a66f96f2 100644 --- a/emu/src/arm7tdmi.rs +++ b/emu/src/arm7tdmi.rs @@ -1,4 +1,4 @@ -use std::cell::RefCell; +use std::cell::{Ref, RefCell}; use std::convert::TryInto; use std::rc::Rc; @@ -57,6 +57,7 @@ const OPCODE_ARM_SIZE: usize = 4; impl Cpu for Arm7tdmi { type OpCodeType = ArmModeOpcode; + type Memory = InternalMemory; fn fetch(&self) -> u32 { let instruction_index = self.registers.program_counter(); @@ -110,6 +111,10 @@ impl Cpu for Arm7tdmi { fn registers(&self) -> Vec { self.registers.to_vec() } + + fn get_memory(&self) -> Ref<'_, InternalMemory> { + self.memory.borrow() + } } impl Arm7tdmi { diff --git a/emu/src/cpu.rs b/emu/src/cpu.rs index 97ad797b..dabd023a 100644 --- a/emu/src/cpu.rs +++ b/emu/src/cpu.rs @@ -1,6 +1,11 @@ +use std::cell::Ref; + +use crate::memory::io_device::IoDevice; + pub trait Cpu { /// Size of Opcode: it can be changed type OpCodeType; + type Memory: IoDevice
; /// It generally takes the next instruction from PC fn fetch(&self) -> u32; @@ -17,4 +22,6 @@ pub trait Cpu { /// Get the value of all registers fn registers(&self) -> Vec; + + fn get_memory(&self) -> Ref<'_, Self::Memory>; } diff --git a/ui/src/dashboard.rs b/ui/src/dashboard.rs index 964ff617..37fbec31 100644 --- a/ui/src/dashboard.rs +++ b/ui/src/dashboard.rs @@ -3,7 +3,10 @@ use emu::{arm7tdmi::Arm7tdmi, cartridge_header::CartridgeHeader, gba::Gba}; use super::about::About; use super::cpu_inspector::CpuInspector; -use crate::{gba_display::GbaDisplay, palette_visualizer::PaletteVisualizer, ui_traits::UiTool}; +use crate::{ + gba_display::GbaDisplay, memory_inspector::MemoryInspector, + palette_visualizer::PaletteVisualizer, ui_traits::UiTool, +}; use std::{ collections::BTreeSet, @@ -40,7 +43,8 @@ impl UiTools { Box::new(About::default()), Box::new(CpuInspector::new(arc_gba.clone())), Box::new(GbaDisplay::new(arc_gba.clone())), - Box::new(PaletteVisualizer::new(arc_gba)), + Box::new(PaletteVisualizer::new(arc_gba.clone())), + Box::new(MemoryInspector::new(arc_gba)), ]) } @@ -51,6 +55,7 @@ impl UiTools { open.insert(tools[1].name().to_owned()); open.insert(tools[2].name().to_owned()); open.insert(tools[3].name().to_owned()); + open.insert(tools[4].name().to_owned()); Self { tools, open } } diff --git a/ui/src/lib.rs b/ui/src/lib.rs index c2de22e9..25157921 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -3,5 +3,6 @@ pub mod app; pub mod cpu_inspector; pub mod dashboard; pub mod gba_display; +pub mod memory_inspector; pub mod palette_visualizer; pub mod ui_traits; diff --git a/ui/src/memory_inspector.rs b/ui/src/memory_inspector.rs new file mode 100644 index 00000000..ef8dd353 --- /dev/null +++ b/ui/src/memory_inspector.rs @@ -0,0 +1,73 @@ +use emu::{cpu::Cpu, gba::Gba, memory::io_device::IoDevice}; + +use crate::ui_traits::{UiTool, View}; + +use std::{ + borrow::Borrow, + sync::{Arc, Mutex}, +}; + +pub struct MemoryInspector { + address_string: String, + value: u8, + base: Base, + gba: Arc>>, +} + +impl MemoryInspector { + pub fn new(gba: Arc>>) -> Self { + Self { + gba, + address_string: String::from("0"), + value: 0, + base: Base::Dec, + } + } +} + +impl UiTool for MemoryInspector { + fn name(&self) -> &'static str { + "Memory Inspector" + } + + fn show(&mut self, ctx: &egui::Context, open: &mut bool) { + egui::Window::new(self.name()) + .default_width(320.0) + .open(open) + .show(ctx, |ui| { + use View as _; + self.ui(ui); + }); + } +} + +#[derive(PartialEq)] +enum Base { + Dec, + Hex, +} + +impl View for MemoryInspector { + fn ui(&mut self, ui: &mut egui::Ui) { + ui.radio_value(&mut self.base, Base::Dec, "Dec"); + ui.radio_value(&mut self.base, Base::Hex, "Hex"); + + ui.horizontal(|ui| { + ui.label("Memory address:"); + ui.text_edit_singleline(&mut self.address_string); + if ui.button("Read").clicked() { + if let Ok(gba) = self.gba.lock() { + let radix = match self.base { + Base::Dec => 10, + Base::Hex => 16, + }; + + let address = u32::from_str_radix(&self.address_string, radix).unwrap(); + self.value = gba.borrow().cpu.get_memory().borrow().read_at(address); + } + } + }); + + ui.label(format!("Value: {}", self.value)); + } +}