Support arbitrary markers
This commit is contained in:
		
							parent
							
								
									841ded3bee
								
							
						
					
					
						commit
						8f9922473e
					
				| 
						 | 
				
			
			@ -300,7 +300,7 @@ extern "C" fn on_read(
 | 
			
		|||
extern "C" fn on_write(
 | 
			
		||||
    sim: *mut VB,
 | 
			
		||||
    address: u32,
 | 
			
		||||
    _type: VBDataType,
 | 
			
		||||
    typ_: VBDataType,
 | 
			
		||||
    value: *mut i32,
 | 
			
		||||
    _cycles: *mut u32,
 | 
			
		||||
    _cancel: *mut c_int,
 | 
			
		||||
| 
						 | 
				
			
			@ -317,6 +317,29 @@ extern "C" fn on_write(
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we have profiling enabled, track custom markers
 | 
			
		||||
    if data.monitor.enabled {
 | 
			
		||||
        let normalized_hw_address = address & 0x0700003f;
 | 
			
		||||
        if normalized_hw_address == 0x02000038 && matches!(typ_, VBDataType::S32) {
 | 
			
		||||
            assert!(data.monitor.queued_event.is_none());
 | 
			
		||||
            // The game has written the address of a null-terminated string
 | 
			
		||||
            // (whose length is at most 64 bytes). Read that string.
 | 
			
		||||
            let str_address = unsafe { *value } as u32;
 | 
			
		||||
            let mut bytes = [0u8; 64];
 | 
			
		||||
            let mut len = 0;
 | 
			
		||||
            for (dst, src_address) in bytes.iter_mut().zip(str_address..str_address + 64) {
 | 
			
		||||
                let char = unsafe { vb_read(sim, src_address, VBDataType::U8) } as u8;
 | 
			
		||||
                if char == 0 {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                *dst = char;
 | 
			
		||||
                len += 1;
 | 
			
		||||
            }
 | 
			
		||||
            let name = String::from_utf8_lossy(&bytes[..len]).into_owned();
 | 
			
		||||
            data.monitor.queued_event = Some(SimEvent::Marker(Cow::Owned(name)));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if let Some(start) = data.write_watchpoints.start_of_range_containing(address) {
 | 
			
		||||
        let watch = if data.read_watchpoints.contains(address) {
 | 
			
		||||
            VBWatchpointType::Access
 | 
			
		||||
| 
						 | 
				
			
			@ -465,6 +488,10 @@ impl VBState {
 | 
			
		|||
            || !self.read_watchpoints.is_empty()
 | 
			
		||||
            || !self.write_watchpoints.is_empty()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn needs_write_callback(&self) -> bool {
 | 
			
		||||
        self.stdout.is_some() || self.monitor.enabled || !self.write_watchpoints.is_empty()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub enum StopReason {
 | 
			
		||||
| 
						 | 
				
			
			@ -529,12 +556,18 @@ impl Sim {
 | 
			
		|||
            unsafe { vb_set_execute_callback(self.sim, Some(on_execute)) };
 | 
			
		||||
            unsafe { vb_set_exception_callback(self.sim, Some(on_exception)) };
 | 
			
		||||
            unsafe { vb_set_fetch_callback(self.sim, Some(on_fetch)) };
 | 
			
		||||
            unsafe { vb_set_write_callback(self.sim, Some(on_write)) };
 | 
			
		||||
        } else {
 | 
			
		||||
            if !state.needs_execute_callback() {
 | 
			
		||||
            let needs_execute = state.needs_execute_callback();
 | 
			
		||||
            let needs_write = state.needs_write_callback();
 | 
			
		||||
            if !needs_execute {
 | 
			
		||||
                unsafe { vb_set_execute_callback(self.sim, None) };
 | 
			
		||||
            }
 | 
			
		||||
            unsafe { vb_set_exception_callback(self.sim, None) };
 | 
			
		||||
            unsafe { vb_set_fetch_callback(self.sim, None) };
 | 
			
		||||
            if !needs_write {
 | 
			
		||||
                unsafe { vb_set_write_callback(self.sim, None) };
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -776,9 +809,10 @@ impl Sim {
 | 
			
		|||
    fn remove_write_watchpoint(&mut self, address: u32, length: usize) {
 | 
			
		||||
        let state = self.get_state();
 | 
			
		||||
        state.write_watchpoints.remove(address, length);
 | 
			
		||||
        let needs_write = state.needs_write_callback();
 | 
			
		||||
        let needs_execute = state.needs_execute_callback();
 | 
			
		||||
        if state.write_watchpoints.is_empty() {
 | 
			
		||||
            if state.stdout.is_none() {
 | 
			
		||||
            if !needs_write {
 | 
			
		||||
                unsafe { vb_set_write_callback(self.sim, None) };
 | 
			
		||||
            }
 | 
			
		||||
            if !needs_execute {
 | 
			
		||||
| 
						 | 
				
			
			@ -802,13 +836,16 @@ impl Sim {
 | 
			
		|||
        data.breakpoints.clear();
 | 
			
		||||
        data.read_watchpoints.clear();
 | 
			
		||||
        data.write_watchpoints.clear();
 | 
			
		||||
        let needs_write = data.stdout.is_some();
 | 
			
		||||
        let needs_write = data.needs_write_callback();
 | 
			
		||||
        let needs_execute = data.needs_execute_callback();
 | 
			
		||||
        unsafe { vb_set_read_callback(self.sim, None) };
 | 
			
		||||
        if !needs_write {
 | 
			
		||||
            unsafe { vb_set_write_callback(self.sim, None) };
 | 
			
		||||
        }
 | 
			
		||||
        if !needs_execute {
 | 
			
		||||
            unsafe { vb_set_execute_callback(self.sim, None) };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn watch_stdout(&mut self, watch: bool) {
 | 
			
		||||
        let data = self.get_state();
 | 
			
		||||
| 
						 | 
				
			
			@ -819,7 +856,7 @@ impl Sim {
 | 
			
		|||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            data.stdout.take();
 | 
			
		||||
            if data.write_watchpoints.is_empty() {
 | 
			
		||||
            if !data.needs_write_callback() {
 | 
			
		||||
                unsafe { vb_set_write_callback(self.sim, None) };
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue