Sync memory between emulator thread and UI

This commit is contained in:
2025-02-15 18:33:18 -05:00
parent a461faf89d
commit ebe444870f
3 changed files with 149 additions and 127 deletions
+30 -2
View File
@@ -7,7 +7,7 @@ use std::{
sync::{
atomic::{AtomicBool, Ordering},
mpsc::{self, RecvError, TryRecvError},
Arc,
Arc, Weak,
},
};
@@ -17,7 +17,11 @@ use bytemuck::NoUninit;
use egui_toast::{Toast, ToastKind, ToastOptions};
use tracing::{error, warn};
use crate::{audio::Audio, graphics::TextureSink};
use crate::{
audio::Audio,
graphics::TextureSink,
memory::{MemoryRange, MemoryRegion},
};
use shrooms_vb_core::{Sim, StopReason, EXPECTED_FRAME_SIZE};
pub use shrooms_vb_core::{VBKey, VBRegister, VBWatchpointType};
@@ -165,8 +169,10 @@ pub struct Emulator {
renderers: HashMap<SimId, TextureSink>,
messages: HashMap<SimId, mpsc::Sender<Toast>>,
debuggers: HashMap<SimId, DebugInfo>,
watched_regions: HashMap<MemoryRange, Weak<MemoryRegion>>,
eye_contents: Vec<u8>,
audio_samples: Vec<f32>,
buffer: Vec<u8>,
}
impl Emulator {
@@ -189,8 +195,10 @@ impl Emulator {
renderers: HashMap::new(),
messages: HashMap::new(),
debuggers: HashMap::new(),
watched_regions: HashMap::new(),
eye_contents: vec![0u8; 384 * 224 * 2],
audio_samples: Vec::with_capacity(EXPECTED_FRAME_SIZE),
buffer: vec![],
})
}
@@ -367,6 +375,10 @@ impl Emulator {
}
}
fn watch_memory(&mut self, range: MemoryRange, region: Weak<MemoryRegion>) {
self.watched_regions.insert(range, region);
}
pub fn run(&mut self) {
loop {
let idle = self.tick();
@@ -391,6 +403,18 @@ impl Emulator {
}
}
}
self.watched_regions.retain(|range, region| {
let Some(region) = region.upgrade() else {
return false;
};
let Some(sim) = self.sims.get_mut(range.sim.to_index()) else {
return false;
};
self.buffer.clear();
sim.read_memory(range.start, range.length, &mut self.buffer);
region.update(&self.buffer);
true
});
}
}
@@ -557,6 +581,9 @@ impl Emulator {
sim.write_memory(start, &buffer);
let _ = done.send(buffer);
}
EmulatorCommand::WatchMemory(range, region) => {
self.watch_memory(range, region);
}
EmulatorCommand::AddBreakpoint(sim_id, address) => {
let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
return;
@@ -647,6 +674,7 @@ pub enum EmulatorCommand {
WriteRegister(SimId, VBRegister, u32),
ReadMemory(SimId, u32, usize, Vec<u8>, oneshot::Sender<Vec<u8>>),
WriteMemory(SimId, u32, Vec<u8>, oneshot::Sender<Vec<u8>>),
WatchMemory(MemoryRange, Weak<MemoryRegion>),
AddBreakpoint(SimId, u32),
RemoveBreakpoint(SimId, u32),
AddWatchpoint(SimId, u32, usize, VBWatchpointType),