diff --git a/emulator/core/src/devices.rs b/emulator/core/src/devices.rs index 28fb24c..89790f2 100644 --- a/emulator/core/src/devices.rs +++ b/emulator/core/src/devices.rs @@ -179,6 +179,10 @@ pub trait DynDevice: Any + 'static + Transmutable {} pub type Device = Rc>; +pub fn wrap_device(value: T) -> Device { + Rc::new(RefCell::new(value)) +} + impl DynDevice for T where T: Transmutable + 'static {} pub trait Transmutable { diff --git a/emulator/core/src/lib.rs b/emulator/core/src/lib.rs index 9db26dc..26dc8c8 100644 --- a/emulator/core/src/lib.rs +++ b/emulator/core/src/lib.rs @@ -7,10 +7,10 @@ mod memory; mod system; pub use crate::devices::{ - Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, Transmutable, TransmutableBox, DynDevice + Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, Transmutable, TransmutableBox, DynDevice, Device, }; pub use crate::devices::{ - read_beu16, read_beu32, read_leu16, read_leu32, write_beu16, write_beu32, write_leu16, write_leu32, wrap_transmutable, + read_beu16, read_beu32, read_leu16, read_leu32, write_beu16, write_beu32, write_leu16, write_leu32, wrap_transmutable, wrap_device }; pub use crate::error::Error; pub use crate::interrupts::InterruptController; diff --git a/emulator/core/src/system.rs b/emulator/core/src/system.rs index e2ea657..9c60c3e 100644 --- a/emulator/core/src/system.rs +++ b/emulator/core/src/system.rs @@ -4,7 +4,7 @@ use std::collections::{BTreeMap, HashMap}; use femtos::{Instant, Duration}; use crate::devices::{downcast_rc_refc, get_next_device_id, Device, DeviceId, DynDevice}; -use crate::{Address, Bus, Error, InterruptController}; +use crate::{wrap_device, Address, Bus, Error, InterruptController}; pub struct System { @@ -127,12 +127,7 @@ impl System { } pub fn add_device(&mut self, device: T, settings: DeviceSettings) -> Result { - self.add_device_rc_ref(Rc::new(RefCell::new(device)), settings) - } - - pub fn add_device_rc_ref(&mut self, device: Rc>, settings: DeviceSettings) -> Result { - let device = device as Device; - self.add_device_rc_dyn(device, settings) + self.add_device_rc_dyn(wrap_device(device), settings) } pub fn add_device_rc_dyn(&mut self, device: Device, settings: DeviceSettings) -> Result { @@ -154,7 +149,11 @@ impl System { } pub fn add_named_device(&mut self, name: &str, device: T) -> Result { - self.add_device(device, DeviceSettings { + self.add_named_device_rc_dyn(name, wrap_device(device)) + } + + pub fn add_named_device_rc_dyn(&mut self, name: &str, device: Device) -> Result { + self.add_device_rc_dyn(device, DeviceSettings { name: Some(name.to_owned()), queue: true, ..Default::default() @@ -162,16 +161,25 @@ impl System { } pub fn add_addressable_device(&mut self, addr: Address, device: T) -> Result { - self.add_device(device, DeviceSettings { + self.add_addressable_device_rc_dyn(addr, wrap_device(device)) + } + + pub fn add_addressable_device_rc_dyn(&mut self, addr: Address, device: Device) -> Result { + self.add_device_rc_dyn(device, DeviceSettings { name: Some(format!("mem{:x}", addr)), address: Some(addr), queue: true, ..Default::default() }) } + pub fn add_peripheral(&mut self, name: &str, addr: Address, device: T) -> Result { - self.add_device(device, DeviceSettings { + self.add_peripheral_rc_dyn(name, addr, wrap_device(device)) + } + + pub fn add_peripheral_rc_dyn(&mut self, name: &str, addr: Address, device: Device) -> Result { + self.add_device_rc_dyn(device, DeviceSettings { name: Some(name.to_owned()), address: Some(addr), queue: true, @@ -180,7 +188,11 @@ impl System { } pub fn add_interruptable_device(&mut self, name: &str, device: T) -> Result { - self.add_device(device, DeviceSettings { + self.add_interruptable_device_rc_dyn(name, wrap_device(device)) + } + + pub fn add_interruptable_device_rc_dyn(&mut self, name: &str, device: Device) -> Result { + self.add_device_rc_dyn(device, DeviceSettings { name: Some(name.to_owned()), queue: true, ..Default::default()