use bedrock_core::*; pub struct SystemDevice { pub name: ReadBuffer, pub authors: ReadBuffer, pub can_wake: u16, pub wake_id: u8, pub asleep: bool, } impl SystemDevice { pub fn new() -> Self { let pkg_version = env!("CARGO_PKG_VERSION"); let pkg_name = env!("CARGO_PKG_NAME"); let pkg_authors = env!("CARGO_PKG_AUTHORS"); let name_str = format!("{pkg_name}, {pkg_version}"); let mut authors_str = String::new(); for author in pkg_authors.split(":") { authors_str.push_str(&format!("{author}, 2024\n")); } Self { name: ReadBuffer::from_str(&name_str), authors: ReadBuffer::from_str(&authors_str), can_wake: 0, wake_id: 0, asleep: false, } } pub fn can_wake(&self, dev_id: u8) -> bool { test_bit!(self.can_wake, 0x8000 >> dev_id) } } impl Device for SystemDevice { fn read(&mut self, port: u8) -> u8 { match port { 0x0 => self.name.read(), 0x1 => self.authors.read(), 0x2 => 0x00, 0x3 => 0x00, 0x4 => 0x00, 0x5 => 0x00, 0x6 => 0b1111_1100, 0x7 => 0b0000_0000, // TODO: Update when fs and stream implemented 0x8 => 0x00, 0x9 => 0x00, 0xa => self.wake_id, 0xb => 0x00, 0xc => 0x00, 0xd => 0x00, 0xe => 0x00, 0xf => 0x00, _ => unreachable!(), } } fn write(&mut self, port: u8, value: u8) -> Option { match port { 0x0 => self.name.pointer = 0, 0x1 => self.authors.pointer = 0, 0x2 => (), 0x3 => (), 0x4 => (), 0x5 => (), 0x6 => (), 0x7 => (), 0x8 => write_h!(self.can_wake, value), 0x9 => { write_l!(self.can_wake, value); self.asleep = true; return Some(Signal::Sleep); }, 0xa => (), 0xb => return Some(Signal::Fork), 0xc => (), 0xd => (), 0xe => (), 0xf => (), _ => unreachable!(), }; return None; } fn wake(&mut self) -> bool { true } } pub struct ReadBuffer { pub bytes: Vec, pub pointer: usize, } impl ReadBuffer { pub fn from_str(text: &str) -> Self { Self { bytes: text.bytes().collect(), pointer: 0, } } pub fn read(&mut self) -> u8 { let pointer = self.pointer; self.pointer += 1; match self.bytes.get(pointer) { Some(byte) => *byte, None => 0, } } }