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 { 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(), } } }