diff --git a/emulator/core/src/devices.rs b/emulator/core/src/devices.rs index 50b6872..c4e364c 100644 --- a/emulator/core/src/devices.rs +++ b/emulator/core/src/devices.rs @@ -29,64 +29,73 @@ pub trait Interruptable { /// A device that can be addressed to read data from or write data to the device. pub trait Addressable { - #[inline] fn size(&self) -> usize; fn read(&mut self, clock: ClockTime, addr: Address, data: &mut [u8]) -> Result<(), Error>; fn write(&mut self, clock: ClockTime, addr: Address, data: &[u8]) -> Result<(), Error>; + #[inline] fn read_u8(&mut self, clock: ClockTime, addr: Address) -> Result { let mut data = [0; 1]; self.read(clock, addr, &mut data)?; Ok(data[0]) } + #[inline] fn read_beu16(&mut self, clock: ClockTime, addr: Address) -> Result { let mut data = [0; 2]; self.read(clock, addr, &mut data)?; Ok(read_beu16(&data)) } + #[inline] fn read_leu16(&mut self, clock: ClockTime, addr: Address) -> Result { let mut data = [0; 2]; self.read(clock, addr, &mut data)?; Ok(read_leu16(&data)) } + #[inline] fn read_beu32(&mut self, clock: ClockTime, addr: Address) -> Result { let mut data = [0; 4]; self.read(clock, addr, &mut data)?; Ok(read_beu32(&data)) } + #[inline] fn read_leu32(&mut self, clock: ClockTime, addr: Address) -> Result { let mut data = [0; 4]; self.read(clock, addr, &mut data)?; Ok(read_leu32(&data)) } + #[inline] fn write_u8(&mut self, clock: ClockTime, addr: Address, value: u8) -> Result<(), Error> { let data = [value]; self.write(clock, addr, &data) } + #[inline] fn write_beu16(&mut self, clock: ClockTime, addr: Address, value: u16) -> Result<(), Error> { let mut data = [0; 2]; write_beu16(&mut data, value); self.write(clock, addr, &data) } + #[inline] fn write_leu16(&mut self, clock: ClockTime, addr: Address, value: u16) -> Result<(), Error> { let mut data = [0; 2]; write_leu16(&mut data, value); self.write(clock, addr, &data) } + #[inline] fn write_beu32(&mut self, clock: ClockTime, addr: Address, value: u32) -> Result<(), Error> { let mut data = [0; 4]; write_beu32(&mut data, value); self.write(clock, addr, &data) } + #[inline] fn write_leu32(&mut self, clock: ClockTime, addr: Address, value: u32) -> Result<(), Error> { let mut data = [0; 4]; write_leu32(&mut data, value); @@ -94,19 +103,19 @@ pub trait Addressable { } } -#[inline(always)] +#[inline] pub fn read_beu16(data: &[u8]) -> u16 { (data[0] as u16) << 8 | (data[1] as u16) } -#[inline(always)] +#[inline] pub fn read_leu16(data: &[u8]) -> u16 { (data[1] as u16) << 8 | (data[0] as u16) } -#[inline(always)] +#[inline] pub fn read_beu32(data: &[u8]) -> u32 { (data[0] as u32) << 24 | (data[1] as u32) << 16 | @@ -114,7 +123,7 @@ pub fn read_beu32(data: &[u8]) -> u32 { (data[3] as u32) } -#[inline(always)] +#[inline] pub fn read_leu32(data: &[u8]) -> u32 { (data[3] as u32) << 24 | (data[2] as u32) << 16 | @@ -124,21 +133,21 @@ pub fn read_leu32(data: &[u8]) -> u32 { -#[inline(always)] +#[inline] pub fn write_beu16(data: &mut [u8], value: u16) -> &mut [u8] { data[0] = (value >> 8) as u8; data[1] = value as u8; data } -#[inline(always)] +#[inline] pub fn write_leu16(data: &mut [u8], value: u16) -> &mut [u8] { data[0] = value as u8; data[1] = (value >> 8) as u8; data } -#[inline(always)] +#[inline] pub fn write_beu32(data: &mut [u8], value: u32) -> &mut [u8] { data[0] = (value >> 24) as u8; data[1] = (value >> 16) as u8; @@ -147,7 +156,7 @@ pub fn write_beu32(data: &mut [u8], value: u32) -> &mut [u8] { data } -#[inline(always)] +#[inline] pub fn write_leu32(data: &mut [u8], value: u32) -> &mut [u8] { data[0] = value as u8; data[1] = (value >> 8) as u8; diff --git a/emulator/core/src/system.rs b/emulator/core/src/system.rs index b971188..64075b9 100644 --- a/emulator/core/src/system.rs +++ b/emulator/core/src/system.rs @@ -19,6 +19,7 @@ pub struct System { pub debug_enabled: Cell, pub debugger: RefCell, + pub debuggables: Vec, pub bus: Rc>, pub buses: HashMap>>, @@ -36,6 +37,7 @@ impl Default for System { debug_enabled: Cell::new(false), debugger: RefCell::new(Debugger::default()), + debuggables: Vec::new(), bus: Rc::new(RefCell::new(Bus::default())), buses: HashMap::new(), @@ -60,6 +62,7 @@ impl System { } pub fn add_device(&mut self, name: &str, device: Device) -> Result<(), Error> { + self.try_add_debuggable(device.clone()); self.try_queue_device(device.clone()); self.devices.insert(name.to_string(), device); Ok(()) @@ -71,12 +74,14 @@ impl System { pub fn add_peripheral(&mut self, name: &str, addr: Address, device: Device) -> Result<(), Error> { self.bus.borrow_mut().insert(addr, device.clone()); + self.try_add_debuggable(device.clone()); self.try_queue_device(device.clone()); self.devices.insert(name.to_string(), device); Ok(()) } pub fn add_interruptable_device(&mut self, name: &str, device: Device) -> Result<(), Error> { + self.try_add_debuggable(device.clone()); self.try_queue_device(device.clone()); self.devices.insert(name.to_string(), device); Ok(()) @@ -84,7 +89,9 @@ impl System { pub fn enable_debugging(&self) { self.debug_enabled.set(true); - self.devices.get("cpu").map(|result| result.try_borrow_mut().map(|mut borrow| borrow.as_debuggable().map(|debug| debug.set_debugging(true)))); + for device in &self.debuggables { + device.borrow_mut().as_debuggable().map(|device| device.set_debugging(true)); + } self.debugger.borrow_mut().breakpoint_occurred(); } @@ -161,6 +168,12 @@ impl System { } } + fn try_add_debuggable(&mut self, device: Device) { + if device.borrow_mut().as_debuggable().is_some() { + self.debuggables.push(device); + } + } + fn check_debugger(&mut self) { if self.debug_enabled.get() { let top = self.event_queue[self.event_queue.len() - 1].device.clone();