Implement writing registers
This commit is contained in:
		
							parent
							
								
									17d3811124
								
							
						
					
					
						commit
						0fff4d427f
					
				| 
						 | 
					@ -537,6 +537,12 @@ impl Emulator {
 | 
				
			||||||
                let value = sim.read_register(register);
 | 
					                let value = sim.read_register(register);
 | 
				
			||||||
                let _ = done.send(value);
 | 
					                let _ = done.send(value);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            EmulatorCommand::WriteRegister(sim_id, register, value) => {
 | 
				
			||||||
 | 
					                let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                sim.write_register(register, value);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            EmulatorCommand::ReadMemory(sim_id, start, length, mut buffer, done) => {
 | 
					            EmulatorCommand::ReadMemory(sim_id, start, length, mut buffer, done) => {
 | 
				
			||||||
                let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
 | 
					                let Some(sim) = self.sims.get_mut(sim_id.to_index()) else {
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
| 
						 | 
					@ -631,6 +637,7 @@ pub enum EmulatorCommand {
 | 
				
			||||||
    DebugContinue(SimId),
 | 
					    DebugContinue(SimId),
 | 
				
			||||||
    DebugStep(SimId),
 | 
					    DebugStep(SimId),
 | 
				
			||||||
    ReadRegister(SimId, VBRegister, oneshot::Sender<u32>),
 | 
					    ReadRegister(SimId, VBRegister, oneshot::Sender<u32>),
 | 
				
			||||||
 | 
					    WriteRegister(SimId, VBRegister, u32),
 | 
				
			||||||
    ReadMemory(SimId, u32, usize, Vec<u8>, oneshot::Sender<Vec<u8>>),
 | 
					    ReadMemory(SimId, u32, usize, Vec<u8>, oneshot::Sender<Vec<u8>>),
 | 
				
			||||||
    AddBreakpoint(SimId, u32),
 | 
					    AddBreakpoint(SimId, u32),
 | 
				
			||||||
    RemoveBreakpoint(SimId, u32),
 | 
					    RemoveBreakpoint(SimId, u32),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -145,6 +145,10 @@ extern "C" {
 | 
				
			||||||
    fn vb_set_option(sim: *mut VB, key: VBOption, value: c_int);
 | 
					    fn vb_set_option(sim: *mut VB, key: VBOption, value: c_int);
 | 
				
			||||||
    #[link_name = "vbSetPeer"]
 | 
					    #[link_name = "vbSetPeer"]
 | 
				
			||||||
    fn vb_set_peer(sim: *mut VB, peer: *mut VB);
 | 
					    fn vb_set_peer(sim: *mut VB, peer: *mut VB);
 | 
				
			||||||
 | 
					    #[link_name = "vbSetProgramCounter"]
 | 
				
			||||||
 | 
					    fn vb_set_program_counter(sim: *mut VB, value: u32) -> u32;
 | 
				
			||||||
 | 
					    #[link_name = "vbSetProgramRegister"]
 | 
				
			||||||
 | 
					    fn vb_set_program_register(sim: *mut VB, index: c_uint, value: i32) -> i32;
 | 
				
			||||||
    #[link_name = "vbSetReadCallback"]
 | 
					    #[link_name = "vbSetReadCallback"]
 | 
				
			||||||
    fn vb_set_read_callback(sim: *mut VB, callback: Option<OnRead>) -> Option<OnRead>;
 | 
					    fn vb_set_read_callback(sim: *mut VB, callback: Option<OnRead>) -> Option<OnRead>;
 | 
				
			||||||
    #[link_name = "vbSetSamples"]
 | 
					    #[link_name = "vbSetSamples"]
 | 
				
			||||||
| 
						 | 
					@ -154,6 +158,8 @@ extern "C" {
 | 
				
			||||||
        typ_: VBDataType,
 | 
					        typ_: VBDataType,
 | 
				
			||||||
        capacity: c_uint,
 | 
					        capacity: c_uint,
 | 
				
			||||||
    ) -> c_int;
 | 
					    ) -> c_int;
 | 
				
			||||||
 | 
					    #[link_name = "vbSetSystemRegister"]
 | 
				
			||||||
 | 
					    fn vb_set_system_register(sim: *mut VB, index: c_uint, value: u32) -> u32;
 | 
				
			||||||
    #[link_name = "vbSetUserData"]
 | 
					    #[link_name = "vbSetUserData"]
 | 
				
			||||||
    fn vb_set_user_data(sim: *mut VB, tag: *mut c_void);
 | 
					    fn vb_set_user_data(sim: *mut VB, tag: *mut c_void);
 | 
				
			||||||
    #[link_name = "vbSetWriteCallback"]
 | 
					    #[link_name = "vbSetWriteCallback"]
 | 
				
			||||||
| 
						 | 
					@ -447,6 +453,20 @@ impl Sim {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn write_register(&mut self, register: VBRegister, value: u32) {
 | 
				
			||||||
 | 
					        match register {
 | 
				
			||||||
 | 
					            VBRegister::Program(index) => unsafe {
 | 
				
			||||||
 | 
					                vb_set_program_register(self.sim, index, value as i32);
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            VBRegister::System(index) => unsafe {
 | 
				
			||||||
 | 
					                vb_set_system_register(self.sim, index, value);
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            VBRegister::PC => unsafe {
 | 
				
			||||||
 | 
					                vb_set_program_counter(self.sim, value);
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn read_memory(&mut self, start: u32, length: usize, into: &mut Vec<u8>) {
 | 
					    pub fn read_memory(&mut self, start: u32, length: usize, into: &mut Vec<u8>) {
 | 
				
			||||||
        let mut address = start;
 | 
					        let mut address = start;
 | 
				
			||||||
        for _ in 0..length {
 | 
					        for _ in 0..length {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -318,6 +318,32 @@ impl GdbConnection {
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                self.response()
 | 
					                self.response()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        } else if req.match_str("P") {
 | 
				
			||||||
 | 
					            let mut write_register = || {
 | 
				
			||||||
 | 
					                let register_index = req.match_hex::<usize>()?;
 | 
				
			||||||
 | 
					                let register = REGISTERS.get(register_index)?.to_vb_register();
 | 
				
			||||||
 | 
					                if !req.match_str("=") {
 | 
				
			||||||
 | 
					                    return None;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                let value = {
 | 
				
			||||||
 | 
					                    let mut buffer = [0; 4];
 | 
				
			||||||
 | 
					                    if !req.match_hex_bytes(&mut buffer) {
 | 
				
			||||||
 | 
					                        return None;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    u32::from_le_bytes(buffer)
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                self.client.send_command(EmulatorCommand::WriteRegister(
 | 
				
			||||||
 | 
					                    self.sim_id,
 | 
				
			||||||
 | 
					                    register,
 | 
				
			||||||
 | 
					                    value,
 | 
				
			||||||
 | 
					                ));
 | 
				
			||||||
 | 
					                Some(())
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            if let Some(()) = write_register() {
 | 
				
			||||||
 | 
					                self.response().write_str("OK")
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                self.response()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        } else if let Some(op) = req.match_some_str(["m", "x"]) {
 | 
					        } else if let Some(op) = req.match_some_str(["m", "x"]) {
 | 
				
			||||||
            let mut read_memory = || {
 | 
					            let mut read_memory = || {
 | 
				
			||||||
                let start = req.match_hex::<u64>()?;
 | 
					                let start = req.match_hex::<u64>()?;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,6 +60,20 @@ impl Request<'_> {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn match_hex_bytes(&mut self, buffer: &mut [u8]) -> bool {
 | 
				
			||||||
 | 
					        if self.buffer.len() < buffer.len() * 2 {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (i, item) in buffer.iter_mut().enumerate() {
 | 
				
			||||||
 | 
					            match u8::from_radix_16(&self.buffer[(i * 2)..(i * 2) + 2]) {
 | 
				
			||||||
 | 
					                (byte, 2) => *item = byte,
 | 
				
			||||||
 | 
					                _ => return false,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        self.buffer = self.buffer.split_at(buffer.len()).1;
 | 
				
			||||||
 | 
					        true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct RequestSource<R> {
 | 
					pub struct RequestSource<R> {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue