diff options
author | Ben Bridle <bridle.benjamin@gmail.com> | 2024-09-30 12:28:24 +1300 |
---|---|---|
committer | Ben Bridle <bridle.benjamin@gmail.com> | 2024-09-30 15:00:01 +1300 |
commit | f4f129a75208ccf5d6a19b1cb81c56d4d95fd61f (patch) | |
tree | b3b95f78edeb2cc48ccf207069631468b2705d55 /src/device_bus.rs | |
parent | f5986d0a37dd8c2526432e5e5e3af7083840447d (diff) | |
download | bedrock-core-f4f129a75208ccf5d6a19b1cb81c56d4d95fd61f.zip |
Make Bedrock parametric over devices
The core Bedrock struct is now parametric over individual Device
structs, rather than over a single DeviceBus. This change was made so
that devices can be implemented separately to one another.
The implementation of the evaluate method has also been changed to make
it potentially slightly more efficient, by replacing pop-then-push
combinations with get operations.
Diffstat (limited to 'src/device_bus.rs')
-rw-r--r-- | src/device_bus.rs | 85 |
1 files changed, 74 insertions, 11 deletions
diff --git a/src/device_bus.rs b/src/device_bus.rs index 38a1a24..aaa0717 100644 --- a/src/device_bus.rs +++ b/src/device_bus.rs @@ -1,19 +1,82 @@ use crate::*; -pub trait DeviceBus { - fn read_u8(&mut self, port: u8) -> u8; - fn write_u8(&mut self, value: u8, port: u8) -> Option<Signal>; +pub trait Device { + fn read(&mut self, port: u8) -> u8; + fn write(&mut self, port: u8, value: u8) -> Option<Signal>; + fn wake(&mut self) -> bool; +} + +impl Device for () { + fn read(&mut self, _: u8) -> u8 { 0 } + fn write(&mut self, _: u8, _: u8) -> Option<Signal> { None } + fn wake(&mut self) -> bool { false } +} + + +pub struct DeviceBus<D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,DA,DB,DC,DD,DE,DF> { + pub dev_0: D0, + pub dev_1: D1, + pub dev_2: D2, + pub dev_3: D3, + pub dev_4: D4, + pub dev_5: D5, + pub dev_6: D6, + pub dev_7: D7, + pub dev_8: D8, + pub dev_9: D9, + pub dev_a: DA, + pub dev_b: DB, + pub dev_c: DC, + pub dev_d: DD, + pub dev_e: DE, + pub dev_f: DF, +} - fn read_u16(&mut self, port: u8) -> u16 { - let high = self.read_u8(port); - let low = self.read_u8(port.wrapping_add(1)); - u16::from_be_bytes([high, low]) +impl<D0:Device, D1:Device, D2:Device, D3:Device, D4:Device, D5:Device, D6:Device, D7:Device, + D8:Device, D9:Device, DA:Device, DB:Device, DC:Device, DD:Device, DE:Device, DF:Device> +DeviceBus<D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,DA,DB,DC,DD,DE,DF> { + pub fn read_u8(&mut self, port: u8) -> u8 { + match port & 0xf0 { + 0x00 => self.dev_0.read(port & 0x0f), + 0x10 => self.dev_1.read(port & 0x0f), + 0x20 => self.dev_2.read(port & 0x0f), + 0x30 => self.dev_3.read(port & 0x0f), + 0x40 => self.dev_4.read(port & 0x0f), + 0x50 => self.dev_5.read(port & 0x0f), + 0x60 => self.dev_6.read(port & 0x0f), + 0x70 => self.dev_7.read(port & 0x0f), + 0x80 => self.dev_8.read(port & 0x0f), + 0x90 => self.dev_9.read(port & 0x0f), + 0xA0 => self.dev_a.read(port & 0x0f), + 0xB0 => self.dev_b.read(port & 0x0f), + 0xC0 => self.dev_c.read(port & 0x0f), + 0xD0 => self.dev_d.read(port & 0x0f), + 0xE0 => self.dev_e.read(port & 0x0f), + 0xF0 => self.dev_f.read(port & 0x0f), + _ => unreachable!(), + } } - fn write_u16(&mut self, value: u16, port: u8) -> Option<Signal> { - let [h, l] = value.to_be_bytes(); - self.write_u8(h, port); - self.write_u8(l, port.wrapping_add(1)) + pub fn write_u8(&mut self, port: u8, value: u8) -> Option<Signal> { + match port & 0xf0 { + 0x00 => self.dev_0.write(port & 0x0f, value), + 0x10 => self.dev_1.write(port & 0x0f, value), + 0x20 => self.dev_2.write(port & 0x0f, value), + 0x30 => self.dev_3.write(port & 0x0f, value), + 0x40 => self.dev_4.write(port & 0x0f, value), + 0x50 => self.dev_5.write(port & 0x0f, value), + 0x60 => self.dev_6.write(port & 0x0f, value), + 0x70 => self.dev_7.write(port & 0x0f, value), + 0x80 => self.dev_8.write(port & 0x0f, value), + 0x90 => self.dev_9.write(port & 0x0f, value), + 0xA0 => self.dev_a.write(port & 0x0f, value), + 0xB0 => self.dev_b.write(port & 0x0f, value), + 0xC0 => self.dev_c.write(port & 0x0f, value), + 0xD0 => self.dev_d.write(port & 0x0f, value), + 0xE0 => self.dev_e.write(port & 0x0f, value), + 0xF0 => self.dev_f.write(port & 0x0f, value), + _ => unreachable!(), + } } } |