mirror of
https://github.com/transistorfet/moa.git
synced 2024-10-10 18:23:36 +00:00
71 lines
2.0 KiB
Rust
71 lines
2.0 KiB
Rust
|
|
use std::rc::Rc;
|
|
use std::cell::{RefCell, RefMut};
|
|
|
|
use crate::error::Error;
|
|
use crate::interrupts::InterruptController;
|
|
use crate::memory::{Address, Addressable, Bus};
|
|
use crate::devices::{Device, Steppable, AddressableDeviceBox, InterruptableDeviceBox, Clock};
|
|
|
|
|
|
pub struct System {
|
|
pub clock: Clock,
|
|
pub devices: Vec<Device>,
|
|
pub bus: RefCell<Bus>,
|
|
pub interrupt_controller: RefCell<InterruptController>,
|
|
}
|
|
|
|
impl System {
|
|
pub fn new() -> System {
|
|
System {
|
|
clock: 0,
|
|
devices: vec![],
|
|
bus: RefCell::new(Bus::new()),
|
|
interrupt_controller: RefCell::new(InterruptController::new()),
|
|
}
|
|
}
|
|
|
|
pub fn get_bus(&self) -> RefMut<'_, Bus> {
|
|
self.bus.borrow_mut()
|
|
}
|
|
|
|
pub fn get_interrupt_controller(&self) -> RefMut<'_, InterruptController> {
|
|
self.interrupt_controller.borrow_mut()
|
|
}
|
|
|
|
|
|
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.devices.push(Device::Addressable(device));
|
|
Ok(())
|
|
}
|
|
|
|
pub fn add_interruptable_device(&mut self, device: InterruptableDeviceBox) -> Result<(), Error> {
|
|
self.interrupt_controller.borrow_mut().set_target(device.clone());
|
|
self.devices.push(Device::Interruptable(device));
|
|
Ok(())
|
|
}
|
|
|
|
pub fn step(&mut self) -> Result<(), Error> {
|
|
self.clock += 1;
|
|
for dev in &self.devices {
|
|
match dev {
|
|
Device::Addressable(dev) => dev.borrow_mut().step(&self),
|
|
Device::Interruptable(dev) => dev.borrow_mut().step(&self),
|
|
}?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub fn exit_error(&mut self) {
|
|
for dev in &self.devices {
|
|
match dev {
|
|
Device::Addressable(dev) => dev.borrow_mut().on_error(&self),
|
|
Device::Interruptable(dev) => dev.borrow_mut().on_error(&self),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|