Sync memory between emulator thread and UI
This commit is contained in:
+30
-2
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user