summaryrefslogtreecommitdiff
path: root/src/devices/system_device.rs
diff options
context:
space:
mode:
authorBen Bridle <bridle.benjamin@gmail.com>2025-07-03 15:26:07 +1200
committerBen Bridle <ben@derelict.engineering>2025-07-03 21:24:07 +1200
commit2accc78948fa4a18e37ab0bc405f9b2758acaa3e (patch)
tree2551180ef7fb8f67bfc826de4ad3daf2dd24942e /src/devices/system_device.rs
downloadbedrock-pc-2accc78948fa4a18e37ab0bc405f9b2758acaa3e.zip
Initial commit
Diffstat (limited to 'src/devices/system_device.rs')
-rw-r--r--src/devices/system_device.rs119
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(),
+ }
+ }
+}