diff options
Diffstat (limited to 'src/devices/system_device.rs')
-rw-r--r-- | src/devices/system_device.rs | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/devices/system_device.rs b/src/devices/system_device.rs new file mode 100644 index 0000000..097c616 --- /dev/null +++ b/src/devices/system_device.rs @@ -0,0 +1,119 @@ +use crate::*; + + +pub struct SystemDevice { + /// Name and version of this system. + pub name: StringBuffer, + /// Authors of this system. + pub authors: StringBuffer, + /// Mask of all devices permitted to wake from sleep. + pub wake_mask: u16, + /// Slot number of device that most recently woke the system. + pub wake_slot: u8, + /// True if the system has been put to sleep. + pub asleep: bool, + /// Mask of all connected devices. + pub connected_devices: u16, + /// Name of the first custom device. + pub custom1: StringBuffer, + /// Name of the second custom device. + pub custom2: StringBuffer, + /// Name of the third custom device. + pub custom3: StringBuffer, + /// Name of the fourth custom device. + pub custom4: StringBuffer, +} + + +impl Device for SystemDevice { + fn read(&mut self, port: u8) -> u8 { + match port { + 0x0 => 0x00, + 0x1 => 0x00, + 0x2 => self.wake_slot, + 0x3 => 0x00, + 0x4 => self.custom1.read(), + 0x5 => self.custom2.read(), + 0x6 => self.custom3.read(), + 0x7 => self.custom4.read(), + 0x8 => self.name.read(), + 0x9 => self.authors.read(), + 0xA => 0x00, + 0xB => 0x00, + 0xC => 0x00, + 0xD => 0x00, + 0xE => read_h!(self.connected_devices), + 0xF => read_l!(self.connected_devices), + _ => unreachable!(), + } + } + + fn write(&mut self, port: u8, value: u8) -> Option<Signal> { + match port { + 0x0 => write_h!(self.wake_mask, value), + 0x1 => { + write_l!(self.wake_mask, value); + self.asleep = true; + return Some(Signal::Sleep); + } + 0x2 => (), + 0x3 => match value { + 0 => return Some(Signal::Reset), + _ => return Some(Signal::Fork), + } + 0x4 => self.custom1.restart(), + 0x5 => self.custom2.restart(), + 0x6 => self.custom3.restart(), + 0x7 => self.custom4.restart(), + 0x8 => self.name.restart(), + 0x9 => self.authors.restart(), + 0xA => (), + 0xB => (), + 0xC => (), + 0xD => (), + 0xE => (), + 0xF => (), + _ => unreachable!(), + }; + return None; + } + + fn wake(&mut self) -> bool { + true + } + + fn reset(&mut self) { + self.wake_mask = 0; + self.wake_slot = 0; + self.custom1.restart(); + self.custom2.restart(); + self.custom3.restart(); + self.custom4.restart(); + self.name.restart(); + self.authors.restart(); + } +} + + +impl SystemDevice { + pub fn new(connected_devices: u16) -> Self { + let pkg_name = env!("CARGO_PKG_NAME"); + let pkg_version = env!("CARGO_PKG_VERSION"); + let pkg_authors = env!("CARGO_PKG_AUTHORS"); + let name = format!("{pkg_name}/{pkg_version}"); + let authors = pkg_authors.replace(':', "\n"); + + Self { + name: StringBuffer::from_str(&name), + authors: StringBuffer::from_str(&authors), + wake_mask: 0, + wake_slot: 0, + asleep: false, + connected_devices, + custom1: StringBuffer::new(), + custom2: StringBuffer::new(), + custom3: StringBuffer::new(), + custom4: StringBuffer::new(), + } + } +} |