2021-10-06 23:14:56 +00:00
|
|
|
|
2021-10-07 16:41:01 +00:00
|
|
|
use std::rc::Rc;
|
2021-10-06 23:14:56 +00:00
|
|
|
use std::cell::{RefCell, RefMut};
|
|
|
|
|
|
|
|
use crate::error::Error;
|
|
|
|
use crate::memory::{self, Address, Addressable, Bus};
|
|
|
|
|
|
|
|
|
|
|
|
pub type Clock = u64;
|
|
|
|
pub type DeviceNumber = u8;
|
|
|
|
|
|
|
|
|
2021-10-07 16:41:01 +00:00
|
|
|
pub trait Steppable {
|
2021-10-06 23:14:56 +00:00
|
|
|
fn step(&mut self, system: &System) -> Result<Clock, Error>;
|
|
|
|
}
|
|
|
|
|
2021-10-07 16:41:01 +00:00
|
|
|
pub trait Interruptable {
|
|
|
|
fn handle_interrupt(&mut self, system: &System, number: u8) -> Result<(), Error>;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait AddressableDevice: Addressable + Steppable { }
|
|
|
|
pub trait InterruptableDevice: Interruptable + Steppable { }
|
|
|
|
|
|
|
|
impl<T: Addressable + Steppable> AddressableDevice for T { }
|
|
|
|
impl<T: Interruptable + Steppable> InterruptableDevice for T { }
|
2021-10-06 23:14:56 +00:00
|
|
|
|
2021-10-07 16:41:01 +00:00
|
|
|
pub type AddressableDeviceBox = Rc<RefCell<Box<dyn AddressableDevice>>>;
|
|
|
|
pub type InterruptableDeviceBox = Rc<RefCell<Box<dyn InterruptableDevice>>>;
|
|
|
|
|
|
|
|
pub type AddressableDeviceRefMut<'a> = RefMut<'a, Box<dyn AddressableDevice>>;
|
|
|
|
|
|
|
|
pub fn wrap_addressable<T: AddressableDevice + 'static>(value: T) -> AddressableDeviceBox {
|
|
|
|
Rc::new(RefCell::new(Box::new(value)))
|
|
|
|
}
|
2021-10-06 23:14:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
pub struct System {
|
|
|
|
pub clock: Clock,
|
2021-10-07 16:41:01 +00:00
|
|
|
pub addressable_devices: Vec<AddressableDeviceBox>,
|
|
|
|
pub bus: RefCell<Bus>,
|
2021-10-06 23:14:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl System {
|
|
|
|
pub fn new() -> System {
|
|
|
|
System {
|
|
|
|
clock: 0,
|
2021-10-07 16:41:01 +00:00
|
|
|
addressable_devices: vec![],
|
|
|
|
bus: RefCell::new(Bus::new()),
|
2021-10-06 23:14:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-07 16:41:01 +00:00
|
|
|
pub fn get_bus(&self) -> RefMut<'_, Bus> {
|
|
|
|
self.bus.borrow_mut()
|
2021-10-06 23:14:56 +00:00
|
|
|
}
|
|
|
|
|
2021-10-07 16:41:01 +00:00
|
|
|
pub fn add_addressable_device(&mut self, addr: Address, device: AddressableDeviceBox) -> Result<(), Error> {
|
|
|
|
let length = device.borrow().len();
|
|
|
|
self.bus.borrow_mut().insert(addr, length, device.clone());
|
|
|
|
self.addressable_devices.push(device);
|
|
|
|
Ok(())
|
|
|
|
}
|
2021-10-06 23:14:56 +00:00
|
|
|
|
|
|
|
pub fn step(&mut self) -> Result<(), Error> {
|
|
|
|
self.clock += 1;
|
2021-10-07 16:41:01 +00:00
|
|
|
for dev in &self.addressable_devices {
|
2021-10-06 23:14:56 +00:00
|
|
|
dev.borrow_mut().step(&self)?;
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|