Read actual register values

This commit is contained in:
Simon Gellis 2025-01-01 21:48:33 -05:00
parent 8707a5196b
commit 82c3104ab9
4 changed files with 69 additions and 14 deletions

View File

@ -15,8 +15,8 @@ use anyhow::Result;
use egui_toast::{Toast, ToastKind, ToastOptions};
use crate::{audio::Audio, graphics::TextureSink};
pub use shrooms_vb_core::VBKey;
use shrooms_vb_core::{Sim, EXPECTED_FRAME_SIZE};
pub use shrooms_vb_core::{VBKey, VBRegister};
mod shrooms_vb_core;
@ -390,6 +390,13 @@ impl Emulator {
}
}
}
EmulatorCommand::ReadRegister(sim_id, register, done) => {
let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
return;
};
let value = sim.read_register(register);
let _ = done.send(value);
}
EmulatorCommand::SetAudioEnabled(p1, p2) => {
self.audio_on[SimId::Player1.to_index()].store(p1, Ordering::Release);
self.audio_on[SimId::Player2.to_index()].store(p2, Ordering::Release);
@ -447,6 +454,7 @@ pub enum EmulatorCommand {
StopSecondSim,
Pause,
Resume,
ReadRegister(SimId, VBRegister, oneshot::Sender<u32>),
SetAudioEnabled(bool, bool),
Link,
Unlink,

View File

@ -55,6 +55,13 @@ bitflags! {
}
}
#[derive(Clone, Copy, Debug)]
pub enum VBRegister {
Program(u32),
System(u32),
PC,
}
type OnFrame = extern "C" fn(sim: *mut VB) -> c_int;
#[link(name = "vb")]
@ -77,6 +84,10 @@ extern "C" {
right_stride_x: c_int,
right_stride_y: c_int,
);
#[link_name = "vbGetProgramCounter"]
fn vb_get_program_counter(sim: *mut VB) -> u32;
#[link_name = "vbGetProgramRegister"]
fn vb_get_program_register(sim: *mut VB, index: c_uint) -> i32;
#[link_name = "vbGetSamples"]
fn vb_get_samples(
sim: *mut VB,
@ -84,6 +95,8 @@ extern "C" {
capacity: *mut c_uint,
position: *mut c_uint,
) -> *mut c_void;
#[link_name = "vbGetSystemRegister"]
fn vb_get_system_register(sim: *mut VB, index: c_uint) -> i32;
#[link_name = "vbGetUserData"]
fn vb_get_user_data(sim: *mut VB) -> *mut c_void;
#[link_name = "vbInit"]
@ -291,6 +304,16 @@ impl Sim {
pub fn set_keys(&mut self, keys: VBKey) {
unsafe { vb_set_keys(self.sim, keys.bits()) };
}
pub fn read_register(&mut self, register: VBRegister) -> u32 {
match register {
VBRegister::Program(index) => unsafe {
vb_get_program_register(self.sim, index) as u32
},
VBRegister::System(index) => unsafe { vb_get_system_register(self.sim, index) as u32 },
VBRegister::PC => unsafe { vb_get_program_counter(self.sim) },
}
}
}
impl Drop for Sim {

View File

@ -227,12 +227,23 @@ impl GdbConnection {
self.client.send_command(EmulatorCommand::Resume);
// Don't send a response until we hit a breakpoint or get interrupted
} else if req.match_str("p") {
let Some(register) = req.match_hex::<u32>() else {
let mut read_register = || {
let register_index = req.match_hex::<usize>()?;
let register = REGISTERS.get(register_index)?.to_vb_register();
let (tx, rx) = ::oneshot::channel();
self.client.send_command(EmulatorCommand::ReadRegister(
self.sim_id,
register,
tx,
));
rx.recv().ok()
};
let Some(value) = read_register() else {
let res = self.response();
self.send(res).await?;
continue;
};
let res = self.response().write_hex(register);
let res = self.response().write_hex(value);
self.send(res).await?;
} else if req.match_str("m") {
let mut read_params = || {

View File

@ -1,5 +1,7 @@
use crate::emulator::VBRegister;
pub struct RegisterInfo {
index: usize,
dwarf: u32,
name: &'static str,
set: &'static str,
alt_name: Option<&'static str>,
@ -14,48 +16,59 @@ impl RegisterInfo {
}
string.push_str(&format!(
";bitsize:32;offset:{};encoding:uint;format:hex;set:{};dwarf:{}",
self.index * 4,
self.dwarf * 4,
self.set,
self.index
self.dwarf
));
if let Some(generic) = self.generic {
string.push_str(&format!(";generic:{}", generic));
}
string
}
pub fn to_vb_register(&self) -> VBRegister {
match self.dwarf {
0..32 => VBRegister::Program(self.dwarf),
32..40 => VBRegister::System(self.dwarf - 32),
40..42 => VBRegister::System(self.dwarf - 16),
42..45 => VBRegister::System(self.dwarf - 13),
45 => VBRegister::PC,
other => panic!("unexpected DWARF register {other}"),
}
}
}
macro_rules! register {
($set:expr, $index:expr, $name:expr) => {
($set:expr, $dwarf:expr, $name:expr) => {
RegisterInfo {
index: $index,
dwarf: $dwarf,
name: $name,
set: $set,
alt_name: None,
generic: None,
}
};
($set:expr, $index:expr, $name:expr, alt: $alt:expr) => {
($set:expr, $dwarf:expr, $name:expr, alt: $alt:expr) => {
RegisterInfo {
index: $index,
dwarf: $dwarf,
name: $name,
set: $set,
alt_name: Some($alt),
generic: None,
}
};
($set:expr, $index:expr, $name:expr, generic: $generic:expr) => {
($set:expr, $dwarf:expr, $name:expr, generic: $generic:expr) => {
RegisterInfo {
index: $index,
dwarf: $dwarf,
name: $name,
set: $set,
alt_name: None,
generic: Some($generic),
}
};
($set:expr, $index:expr, $name:expr, alt: $alt:expr, generic: $generic:expr) => {
($set:expr, $dwarf:expr, $name:expr, alt: $alt:expr, generic: $generic:expr) => {
RegisterInfo {
index: $index,
dwarf: $dwarf,
name: $name,
set: $set,
alt_name: Some($alt),