Read actual register values
This commit is contained in:
		
							parent
							
								
									8707a5196b
								
							
						
					
					
						commit
						82c3104ab9
					
				| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 = || {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue