mirror of
https://github.com/transistorfet/moa.git
synced 2024-12-13 11:29:18 +00:00
Update naming
This commit is contained in:
parent
64571e45b8
commit
1686afe22b
@ -175,11 +175,11 @@ pub trait Inspectable {
|
|||||||
|
|
||||||
|
|
||||||
pub type DeviceId = u32;
|
pub type DeviceId = u32;
|
||||||
pub trait Resource: Any + 'static + Transmutable {}
|
pub trait DynDevice: Any + 'static + Transmutable {}
|
||||||
|
|
||||||
pub type Device = Rc<RefCell<dyn Resource>>;
|
pub type Device = Rc<RefCell<dyn DynDevice>>;
|
||||||
|
|
||||||
impl<T> Resource for T where T: Transmutable + 'static {}
|
impl<T> DynDevice for T where T: Transmutable + 'static {}
|
||||||
|
|
||||||
pub trait Transmutable {
|
pub trait Transmutable {
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -209,12 +209,12 @@ pub trait Transmutable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Taken from deno_core
|
// Taken from deno_core
|
||||||
fn is<T: Resource>(field: &dyn Resource) -> bool {
|
fn is<T: DynDevice>(field: &dyn DynDevice) -> bool {
|
||||||
field.type_id() == TypeId::of::<T>()
|
field.type_id() == TypeId::of::<T>()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Taken from deno_core
|
// Taken from deno_core
|
||||||
pub fn downcast_rc_refc<'a, T: Resource>(field: &'a Device) -> Option<&'a Rc<RefCell<T>>> {
|
pub fn downcast_rc_refc<'a, T: DynDevice>(field: &'a Device) -> Option<&'a Rc<RefCell<T>>> {
|
||||||
if is::<T>(field.borrow().deref()) {
|
if is::<T>(field.borrow().deref()) {
|
||||||
let ptr = field as *const Rc<RefCell<_>> as *const Rc<RefCell<T>>;
|
let ptr = field as *const Rc<RefCell<_>> as *const Rc<RefCell<T>>;
|
||||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
@ -232,54 +232,12 @@ pub fn wrap_transmutable<T: Transmutable + 'static>(value: T) -> TransmutableBox
|
|||||||
|
|
||||||
static NEXT_ID: AtomicU32 = AtomicU32::new(1);
|
static NEXT_ID: AtomicU32 = AtomicU32::new(1);
|
||||||
|
|
||||||
pub fn get_next_id() -> u32 {
|
pub fn get_next_device_id() -> u32 {
|
||||||
let next = NEXT_ID.load(Ordering::Acquire);
|
let next = NEXT_ID.load(Ordering::Acquire);
|
||||||
NEXT_ID.store(next + 1, Ordering::Release);
|
NEXT_ID.store(next + 1, Ordering::Release);
|
||||||
next
|
next
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
// pub struct DeviceId(usize);
|
|
||||||
|
|
||||||
// impl DeviceId {
|
|
||||||
// pub fn new() -> Self {
|
|
||||||
// let next = NEXT_ID.load(Ordering::Acquire);
|
|
||||||
// NEXT_ID.store(next + 1, Ordering::Release);
|
|
||||||
// Self(next)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl Default for DeviceId {
|
|
||||||
// fn default() -> Self {
|
|
||||||
// Self::new()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[derive(Clone)]
|
|
||||||
// pub struct Device(DeviceId, TransmutableBox);
|
|
||||||
|
|
||||||
// impl Device {
|
|
||||||
// pub fn new<T>(value: T) -> Self
|
|
||||||
// where
|
|
||||||
// T: Transmutable + 'static,
|
|
||||||
// {
|
|
||||||
// Self(DeviceId::new(), wrap_transmutable(value))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn id(&self) -> DeviceId {
|
|
||||||
// self.0
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn borrow_mut(&self) -> RefMut<'_, Box<dyn Transmutable>> {
|
|
||||||
// self.1.borrow_mut()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn try_borrow_mut(&self) -> Result<RefMut<'_, Box<dyn Transmutable>>, BorrowMutError> {
|
|
||||||
// self.1.try_borrow_mut()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct DeviceId(usize);
|
pub struct DeviceId(usize);
|
||||||
|
@ -7,7 +7,7 @@ mod memory;
|
|||||||
mod system;
|
mod system;
|
||||||
|
|
||||||
pub use crate::devices::{
|
pub use crate::devices::{
|
||||||
Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, Transmutable, TransmutableBox, Resource
|
Address, Addressable, Steppable, Interruptable, Debuggable, Inspectable, Transmutable, TransmutableBox, DynDevice
|
||||||
};
|
};
|
||||||
pub use crate::devices::{
|
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,
|
||||||
|
@ -3,7 +3,7 @@ use std::cell::{RefCell, RefMut};
|
|||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use femtos::{Instant, Duration};
|
use femtos::{Instant, Duration};
|
||||||
|
|
||||||
use crate::devices::{downcast_rc_refc, get_next_id, Device, DeviceId, Resource};
|
use crate::devices::{downcast_rc_refc, get_next_device_id, Device, DeviceId, DynDevice};
|
||||||
use crate::{Address, Bus, Error, InterruptController};
|
use crate::{Address, Bus, Error, InterruptController};
|
||||||
|
|
||||||
|
|
||||||
@ -47,6 +47,12 @@ pub struct DeviceSettings {
|
|||||||
|
|
||||||
impl Default for DeviceSettings {
|
impl Default for DeviceSettings {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeviceSettings {
|
||||||
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: None,
|
name: None,
|
||||||
address: None,
|
address: None,
|
||||||
@ -54,6 +60,26 @@ impl Default for DeviceSettings {
|
|||||||
queue: false,
|
queue: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn with_address(&mut self, addr: Address) -> &mut Self {
|
||||||
|
self.address = Some(addr);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_name(&mut self, name: String) -> &mut Self {
|
||||||
|
self.name = Some(name);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn debuggable(&mut self, debuggable: bool) -> &mut Self {
|
||||||
|
self.debuggable = debuggable;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn queue(&mut self, queue: bool) -> &mut Self {
|
||||||
|
self.queue = queue;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl System {
|
impl System {
|
||||||
@ -65,7 +91,11 @@ impl System {
|
|||||||
self.interrupt_controller.borrow_mut()
|
self.interrupt_controller.borrow_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_device<T: Resource>(&self, device: DeviceId) -> Result<Rc<RefCell<T>>, Error> {
|
pub fn get_id_from_name(&self, name: &str) -> Option<DeviceId> {
|
||||||
|
self.id_to_name.iter().find_map(|(key, &ref val)| if val == name { Some(*key)} else { None })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_device<T: DynDevice>(&self, device: DeviceId) -> Result<Rc<RefCell<T>>, Error> {
|
||||||
self.devices
|
self.devices
|
||||||
.get(&device)
|
.get(&device)
|
||||||
.and_then(|rc| downcast_rc_refc::<T>(rc))
|
.and_then(|rc| downcast_rc_refc::<T>(rc))
|
||||||
@ -73,10 +103,9 @@ impl System {
|
|||||||
.ok_or_else(|| Error::new(format!("system: bad device id {}", device)))
|
.ok_or_else(|| Error::new(format!("system: bad device id {}", device)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_device_by_name<T: Resource>(&self, name: &str) -> Result<Rc<RefCell<T>>, Error> {
|
pub fn get_device_by_name<T: DynDevice>(&self, name: &str) -> Result<Rc<RefCell<T>>, Error> {
|
||||||
let id = self.id_to_name.iter().find_map(|(key, &ref val)| if val == name { Some(key)} else { None });
|
if let Some(id) = self.get_id_from_name(name) {
|
||||||
if let Some(id) = id {
|
self.get_device(id)
|
||||||
self.get_device(*id)
|
|
||||||
} else {
|
} else {
|
||||||
Err(Error::new(format!("system: could not find device {}", name)))
|
Err(Error::new(format!("system: could not find device {}", name)))
|
||||||
}
|
}
|
||||||
@ -90,25 +119,24 @@ impl System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_dyn_device_by_name(&self, name: &str) -> Result<Device, Error> {
|
pub fn get_dyn_device_by_name(&self, name: &str) -> Result<Device, Error> {
|
||||||
let id = self.id_to_name.iter().find_map(|(key, &ref val)| if val == name { Some(key)} else { None });
|
if let Some(id) = self.get_id_from_name(name) {
|
||||||
if let Some(id) = id {
|
self.get_dyn_device(id)
|
||||||
self.get_dyn_device(*id)
|
|
||||||
} else {
|
} else {
|
||||||
Err(Error::new(format!("system: could not find device {}", name)))
|
Err(Error::new(format!("system: could not find device {}", name)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_device<T: Resource>(&mut self, device: T, settings: DeviceSettings) -> Result<DeviceId, Error> {
|
pub fn add_device<T: DynDevice>(&mut self, device: T, settings: DeviceSettings) -> Result<DeviceId, Error> {
|
||||||
self.add_device_rc_ref(Rc::new(RefCell::new(device)), settings)
|
self.add_device_rc_ref(Rc::new(RefCell::new(device)), settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_device_rc_ref<T: Resource>(&mut self, device: Rc<RefCell<T>>, settings: DeviceSettings) -> Result<DeviceId, Error> {
|
pub fn add_device_rc_ref<T: DynDevice>(&mut self, device: Rc<RefCell<T>>, settings: DeviceSettings) -> Result<DeviceId, Error> {
|
||||||
let device = device as Device;
|
let device = device as Device;
|
||||||
self.add_device_rc_dyn(device, settings)
|
self.add_device_rc_dyn(device, settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_device_rc_dyn(&mut self, device: Device, settings: DeviceSettings) -> Result<DeviceId, Error> {
|
pub fn add_device_rc_dyn(&mut self, device: Device, settings: DeviceSettings) -> Result<DeviceId, Error> {
|
||||||
let id = get_next_id();
|
let id = get_next_device_id();
|
||||||
self.id_to_name.insert(id, settings.name.unwrap_or_default());
|
self.id_to_name.insert(id, settings.name.unwrap_or_default());
|
||||||
|
|
||||||
self.devices.insert(id, device.clone());
|
self.devices.insert(id, device.clone());
|
||||||
@ -125,7 +153,7 @@ impl System {
|
|||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_named_device<T: Resource>(&mut self, name: &str, device: T) -> Result<DeviceId, Error> {
|
pub fn add_named_device<T: DynDevice>(&mut self, name: &str, device: T) -> Result<DeviceId, Error> {
|
||||||
self.add_device(device, DeviceSettings {
|
self.add_device(device, DeviceSettings {
|
||||||
name: Some(name.to_owned()),
|
name: Some(name.to_owned()),
|
||||||
queue: true,
|
queue: true,
|
||||||
@ -133,7 +161,7 @@ impl System {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_addressable_device<T: Resource>(&mut self, addr: Address, device: T) -> Result<DeviceId, Error> {
|
pub fn add_addressable_device<T: DynDevice>(&mut self, addr: Address, device: T) -> Result<DeviceId, Error> {
|
||||||
self.add_device(device, DeviceSettings {
|
self.add_device(device, DeviceSettings {
|
||||||
name: Some(format!("mem{:x}", addr)),
|
name: Some(format!("mem{:x}", addr)),
|
||||||
address: Some(addr),
|
address: Some(addr),
|
||||||
@ -142,7 +170,7 @@ impl System {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_peripheral<T: Resource>(&mut self, name: &str, addr: Address, device: T) -> Result<DeviceId, Error> {
|
pub fn add_peripheral<T: DynDevice>(&mut self, name: &str, addr: Address, device: T) -> Result<DeviceId, Error> {
|
||||||
self.add_device(device, DeviceSettings {
|
self.add_device(device, DeviceSettings {
|
||||||
name: Some(name.to_owned()),
|
name: Some(name.to_owned()),
|
||||||
address: Some(addr),
|
address: Some(addr),
|
||||||
@ -151,7 +179,7 @@ impl System {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_interruptable_device<T: Resource>(&mut self, name: &str, device: T) -> Result<DeviceId, Error> {
|
pub fn add_interruptable_device<T: DynDevice>(&mut self, name: &str, device: T) -> Result<DeviceId, Error> {
|
||||||
self.add_device(device, DeviceSettings {
|
self.add_device(device, DeviceSettings {
|
||||||
name: Some(name.to_owned()),
|
name: Some(name.to_owned()),
|
||||||
queue: true,
|
queue: true,
|
||||||
@ -194,7 +222,7 @@ impl System {
|
|||||||
loop {
|
loop {
|
||||||
self.step()?;
|
self.step()?;
|
||||||
|
|
||||||
if self.get_next_event_device() == device {
|
if self.get_next_event_device_id() == device {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,7 +234,7 @@ impl System {
|
|||||||
loop {
|
loop {
|
||||||
self.step()?;
|
self.step()?;
|
||||||
|
|
||||||
if self.get_dyn_device(self.get_next_event_device()).unwrap().borrow_mut().as_debuggable().is_some() {
|
if self.get_dyn_device(self.get_next_event_device_id()).unwrap().borrow_mut().as_debuggable().is_some() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,7 +272,7 @@ impl System {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_next_event_device(&self) -> DeviceId {
|
pub fn get_next_event_device_id(&self) -> DeviceId {
|
||||||
self.event_queue[self.event_queue.len() - 1].device
|
self.event_queue[self.event_queue.len() - 1].device
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user