summaryrefslogtreecommitdiff
path: root/src/devices.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices.rs')
-rw-r--r--src/devices.rs384
1 files changed, 19 insertions, 365 deletions
diff --git a/src/devices.rs b/src/devices.rs
index 1d69cc7..2221152 100644
--- a/src/devices.rs
+++ b/src/devices.rs
@@ -1,366 +1,20 @@
-mod system;
-mod memory;
-mod math;
-mod clock;
-mod input;
-mod screen;
-mod stream;
-mod file;
+mod system_device;
+mod memory_device;
+mod math_device;
+mod clock_device;
+mod input_device;
+mod screen_device;
+mod local_device;
+mod remote_device;
+mod file_device;
+
+pub use system_device::SystemDevice;
+pub use memory_device::MemoryDevice;
+pub use math_device::MathDevice;
+pub use clock_device::ClockDevice;
+pub use input_device::InputDevice;
+pub use screen_device::ScreenDevice;
+pub use local_device::LocalDevice;
+pub use remote_device::RemoteDevice;
+pub use file_device::FileDevice;
-use bedrock_core::*;
-pub use system::ReadOnlyTextBuffer;
-pub use screen::{ScreenDimensions, ScreenPosition};
-
-const LEN_PROGRAM_MEMORY: u16 = 0xffff;
-const LEN_WORKING_STACK: u8 = 0xff;
-const LEN_RETURN_STACK: u8 = 0xff;
-const CONNECTED_DEVICES: u16 = 0b_1111_1100_1100_0000;
-
-
-pub struct StandardDevices {
- pub memory: memory::MemoryDevice,
- pub math: math::MathDevice,
- pub clock: clock::ClockDevice,
- pub input: input::InputDevice,
- pub screen: screen::ScreenDevice,
- pub stream: stream::StreamDevice,
- pub file: file::FileDevice,
-
- pub name: ReadOnlyTextBuffer,
-
- pub wake_mask: u16,
- pub wake_id: u8,
-}
-
-impl StandardDevices {
- pub fn new() -> Self {
- Self {
- memory: memory::MemoryDevice::new(),
- math: math::MathDevice::new(),
- clock: clock::ClockDevice::new(),
- input: input::InputDevice::new(),
- screen: screen::ScreenDevice::new(),
- stream: stream::StreamDevice::new(),
- file: file::FileDevice::new(),
-
- name: ReadOnlyTextBuffer::from_text("Bedrock for PC"),
-
- wake_mask: 0x0000,
- wake_id: 0x00,
- }
- }
-
- pub fn can_wake(&mut self) -> bool {
- macro_rules! test_wake {
- ($flag:expr, $id:expr, $mask:expr) => {
- if $flag && self.wake_mask & $mask != 0 {
- $flag = false; self.wake_id = $id; return true }
- };
- }
- self.clock.update_timers();
- // The order here is important. If clock comes first, a fast
- // enough recurring timer could block out all other events.
- // It might be preferable to implement a queue system, so that
- // the flags are tested in reverse order to how recently
- // they were matched.
- test_wake!(self.input.wake_flag, 0x4, 0x0800);
- test_wake!(self.screen.wake_flag, 0x5, 0x0400);
- test_wake!(self.stream.wake_flag, 0x8, 0x0080);
- test_wake!(self.clock.wake_flag, 0x3, 0x1000);
- return false;
- }
-}
-
-impl DeviceBus for StandardDevices {
- fn read_u8(&mut self, port: u8) -> u8 {
- macro_rules! read_hh { ($v:expr) => { ($v>>24) as u8 }; }
- macro_rules! read_hl { ($v:expr) => { ($v>>16) as u8 }; }
- macro_rules! read_lh { ($v:expr) => { ($v>>8) as u8 }; }
- macro_rules! read_ll { ($v:expr) => { $v as u8 }; }
- macro_rules! read_h { ($v:expr) => { ($v>>8) as u8 }; }
- macro_rules! read_l { ($v:expr) => { $v as u8 }; }
- macro_rules! read_b { ($b:expr) => { if $b { 0xff } else { 0x00 } }; }
- macro_rules! no_read { () => { 0x00 }; }
-
- match port {
- // System
- 0x00 => self.name.read_byte(),
- 0x01 => self.wake_id,
- 0x02 => no_read!(),
- 0x03 => no_read!(),
- 0x04 => 0x00,
- 0x05 => 0x00,
- 0x06 => 0x00,
- 0x07 => 0x00,
- 0x08 => read_h!(LEN_PROGRAM_MEMORY),
- 0x09 => read_l!(LEN_PROGRAM_MEMORY),
- 0x0A => LEN_WORKING_STACK,
- 0x0B => LEN_RETURN_STACK,
- 0x0C => read_h!(CONNECTED_DEVICES),
- 0x0D => read_l!(CONNECTED_DEVICES),
- 0x0E => no_read!(),
- 0x0F => no_read!(),
- // Memory
- 0x10 => read_h!(self.memory.page_1),
- 0x11 => read_l!(self.memory.page_1),
- 0x12 => read_h!(self.memory.address_1),
- 0x13 => read_l!(self.memory.address_1),
- 0x14 => self.memory.read_from_head_1(),
- 0x15 => self.memory.read_from_head_1(),
- 0x16 => read_h!(self.memory.page_limit),
- 0x17 => read_l!(self.memory.page_limit),
- 0x18 => read_h!(self.memory.page_2),
- 0x19 => read_l!(self.memory.page_2),
- 0x1A => read_h!(self.memory.address_2),
- 0x1B => read_l!(self.memory.address_2),
- 0x1C => self.memory.read_from_head_2(),
- 0x1D => self.memory.read_from_head_2(),
- 0x1E => no_read!(),
- 0x1F => no_read!(),
- // Math
- 0x20 => no_read!(),
- 0x21 => no_read!(),
- 0x22 => no_read!(),
- 0x23 => no_read!(),
- 0x24 => no_read!(),
- 0x25 => no_read!(),
- 0x26 => no_read!(),
- 0x27 => no_read!(),
- 0x28 => read_h!(self.math.multiply_high()),
- 0x29 => read_l!(self.math.multiply_high()),
- 0x2A => read_h!(self.math.multiply_low()),
- 0x2B => read_l!(self.math.multiply_low()),
- 0x2C => read_h!(self.math.divide()),
- 0x2D => read_l!(self.math.divide()),
- 0x2E => read_h!(self.math.modulo()),
- 0x2F => read_l!(self.math.modulo()),
- // Clock
- 0x30 => self.clock.year(),
- 0x31 => self.clock.month(),
- 0x32 => self.clock.day(),
- 0x33 => self.clock.hour(),
- 0x34 => self.clock.minute(),
- 0x35 => self.clock.second(),
- 0x36 => read_h!(self.clock.update_uptime()),
- 0x37 => read_l!(self.clock.uptime),
- 0x38 => read_h!(self.clock.update_timer_1()),
- 0x39 => read_l!(self.clock.timer_1),
- 0x3A => read_h!(self.clock.update_timer_2()),
- 0x3B => read_l!(self.clock.timer_2),
- 0x3C => read_h!(self.clock.update_timer_3()),
- 0x3D => read_l!(self.clock.timer_3),
- 0x3E => read_h!(self.clock.update_timer_4()),
- 0x3F => read_l!(self.clock.timer_4),
- // Input
- 0x40 => read_h!(self.input.pointer_position.x),
- 0x41 => read_l!(self.input.pointer_position.x),
- 0x42 => read_h!(self.input.pointer_position.y),
- 0x43 => read_l!(self.input.pointer_position.y),
- 0x44 => read_b!(self.input.pointer_active),
- 0x45 => self.input.pointer_buttons,
- 0x46 => self.input.read_horizontal_scroll(),
- 0x47 => self.input.read_vertical_scroll(),
- 0x48 => 0xff,
- 0x49 => self.input.text_queue.pop_front().unwrap_or(0),
- 0x4A => self.input.modifiers,
- 0x4B => self.input.navigation,
- 0x4C => self.input.controller_1,
- 0x4D => self.input.controller_2,
- 0x4E => self.input.controller_3,
- 0x4F => self.input.controller_4,
- // Screen
- 0x50 => read_h!(self.screen.cursor.x),
- 0x51 => read_l!(self.screen.cursor.x),
- 0x52 => read_h!(self.screen.cursor.y),
- 0x53 => read_l!(self.screen.cursor.y),
- 0x54 => read_h!(self.screen.dimensions.width),
- 0x55 => read_l!(self.screen.dimensions.width),
- 0x56 => read_h!(self.screen.dimensions.height),
- 0x57 => read_l!(self.screen.dimensions.height),
- 0x58 => no_read!(),
- 0x59 => no_read!(),
- 0x5A => no_read!(),
- 0x5B => no_read!(),
- 0x5C => no_read!(),
- 0x5D => no_read!(),
- 0x5E => no_read!(),
- 0x5F => no_read!(),
- // Stream
- // 0x80 => todo!(),
- // 0x81 => todo!(),
- // 0x82 => todo!(),
- // 0x83 => todo!(),
- // 0x84 => todo!(),
- // 0x85 => todo!(),
- // 0x86 => todo!(),
- // 0x87 => todo!(),
- // 0x88 => todo!(),
- // 0x89 => todo!(),
- // 0x8A => todo!(),
- // 0x8B => todo!(),
- // 0x8C => todo!(),
- // 0x8D => todo!(),
- // 0x8E => todo!(),
- // 0x8F => todo!(),
- // File
- 0x90 => read_b!(self.file.entry.is_some()),
- 0x91 => read_b!(self.file.success),
- 0x92 => self.file.name_buffer.read_byte(),
- 0x93 => read_b!(self.file.entry_type()),
- 0x94 => self.file.read_byte(),
- 0x95 => self.file.read_byte(),
- 0x96 => self.file.read_child_name(),
- 0x97 => read_b!(self.file.child_type()),
- 0x98 => read_hh!(self.file.pointer()),
- 0x99 => read_hl!(self.file.pointer()),
- 0x9A => read_lh!(self.file.pointer()),
- 0x9B => read_ll!(self.file.pointer()),
- 0x9C => read_hh!(self.file.length()),
- 0x9D => read_hl!(self.file.length()),
- 0x9E => read_lh!(self.file.length()),
- 0x9F => read_ll!(self.file.length()),
-
- _ => unimplemented!("Reading from device port 0x{port:02x}"),
- }
- }
-
- fn write_u8(&mut self, val: u8, port: u8) -> Option<Signal> {
- macro_rules! write_hh { ($v:expr) => { $v = $v & 0x00ffffff | ((val as u32) << 24) }; }
- macro_rules! write_hl { ($v:expr) => { $v = $v & 0xff00ffff | ((val as u32) << 16) }; }
- macro_rules! write_lh { ($v:expr) => { $v = $v & 0x00ff | ((val as u32) << 8) }; }
- macro_rules! write_ll { ($v:expr) => { $v = $v & 0xff00 | (val as u32) }; }
- macro_rules! write_h { ($v:expr) => { $v = $v & 0x00ff | ((val as u16) << 8) }; }
- macro_rules! write_l { ($v:expr) => { $v = $v & 0xff00 | (val as u16) }; }
- macro_rules! no_write { () => { () }; }
-
- match port {
- // System
- 0x00 => self.name.reset_pointer(),
- 0x01 => no_write!(),
- 0x02 => write_h!(self.wake_mask),
- 0x03 => { write_l!(self.wake_mask); return Some(Signal::Sleep) },
- 0x04 => no_write!(),
- 0x05 => no_write!(),
- 0x06 => no_write!(),
- 0x07 => no_write!(),
- 0x08 => no_write!(),
- 0x09 => no_write!(),
- 0x0A => no_write!(),
- 0x0B => no_write!(),
- 0x0C => no_write!(),
- 0x0D => no_write!(),
- 0x0E => no_write!(),
- 0x0F => no_write!(),
- // Memory
- 0x10 => write_h!(self.memory.page_1),
- 0x11 => write_l!(self.memory.page_1),
- 0x12 => write_h!(self.memory.address_1),
- 0x13 => write_l!(self.memory.address_1),
- 0x14 => self.memory.write_to_head_1(val),
- 0x15 => self.memory.write_to_head_1(val),
- 0x16 => no_write!(),
- 0x17 => no_write!(),
- 0x18 => write_h!(self.memory.page_2),
- 0x19 => write_l!(self.memory.page_2),
- 0x1A => write_h!(self.memory.address_2),
- 0x1B => write_l!(self.memory.address_2),
- 0x1C => self.memory.write_to_head_2(val),
- 0x1D => self.memory.write_to_head_2(val),
- 0x1E => write_h!(self.memory.copy_length),
- 0x1F => { write_l!(self.memory.copy_length); self.memory.copy() },
- // Math
- 0x20 => write_h!(self.math.operand_1),
- 0x21 => write_l!(self.math.operand_1),
- 0x22 => write_h!(self.math.operand_2),
- 0x23 => write_l!(self.math.operand_2),
- 0x24 => no_write!(),
- 0x25 => no_write!(),
- 0x26 => no_write!(),
- 0x27 => no_write!(),
- 0x28 => no_write!(),
- 0x29 => no_write!(),
- 0x2A => no_write!(),
- 0x2B => no_write!(),
- 0x2C => no_write!(),
- 0x2D => no_write!(),
- 0x2E => no_write!(),
- 0x2F => no_write!(),
- // Clock
- 0x30 => no_write!(),
- 0x31 => no_write!(),
- 0x32 => no_write!(),
- 0x33 => no_write!(),
- 0x34 => no_write!(),
- 0x35 => no_write!(),
- 0x36 => no_write!(),
- 0x37 => no_write!(),
- 0x38 => write_h!(self.clock.timer_1),
- 0x39 => { write_l!(self.clock.timer_1); self.clock.set_timer_1() },
- 0x3A => write_h!(self.clock.timer_2),
- 0x3B => { write_l!(self.clock.timer_2); self.clock.set_timer_2() },
- 0x3C => write_h!(self.clock.timer_3),
- 0x3D => { write_l!(self.clock.timer_3); self.clock.set_timer_3() },
- 0x3E => write_h!(self.clock.timer_4),
- 0x3F => { write_l!(self.clock.timer_4); self.clock.set_timer_4() },
- // Input
- 0x40 => no_write!(),
- 0x41 => no_write!(),
- 0x42 => no_write!(),
- 0x43 => no_write!(),
- 0x44 => no_write!(),
- 0x45 => no_write!(),
- 0x46 => no_write!(),
- 0x47 => no_write!(),
- 0x48 => no_write!(),
- 0x49 => self.input.text_queue.clear(),
- 0x4A => no_write!(),
- 0x4B => no_write!(),
- 0x4C => no_write!(),
- 0x4D => no_write!(),
- 0x4E => no_write!(),
- 0x4F => no_write!(),
- // Screen
- 0x50 => write_h!(self.screen.cursor.x),
- 0x51 => write_l!(self.screen.cursor.x),
- 0x52 => write_h!(self.screen.cursor.y),
- 0x53 => write_l!(self.screen.cursor.y),
- 0x54 => write_h!(self.screen.dimensions.width),
- 0x55 => { write_l!(self.screen.dimensions.width); self.screen.set_size() },
- 0x56 => write_h!(self.screen.dimensions.height),
- 0x57 => { write_l!(self.screen.dimensions.height); self.screen.set_size() },
- 0x58 => self.screen.set_palette_high(val),
- 0x59 => self.screen.set_palette_low(val),
- 0x5A => self.screen.sprite_buffer.set_colour_high(val),
- 0x5B => self.screen.sprite_buffer.set_colour_low(val),
- 0x5C => self.screen.sprite_buffer.push(val),
- 0x5D => self.screen.sprite_buffer.push(val),
- 0x5E => self.screen.draw(val),
- 0x5F => self.screen.shunt(val),
- // Stream
- 0x86 => self.stream.write_stdout(val),
- 0x87 => self.stream.write_stdout(val),
- // File
- 0x90 => self.file.write_to_open_port(val),
- 0x91 => self.file.write_to_move_port(val),
- 0x92 => self.file.set_name_pointer(val),
- 0x93 => self.file.ascend_to_parent(),
- 0x94 => self.file.write_byte(val),
- 0x95 => self.file.write_byte(val),
- 0x96 => self.file.set_child_name_pointer(val),
- 0x97 => self.file.descend_to_child(),
- 0x98 => write_hh!(self.file.pointer),
- 0x99 => write_hl!(self.file.pointer),
- 0x9A => write_lh!(self.file.pointer),
- 0x9B => { write_ll!(self.file.pointer); self.file.commit_pointer() },
- 0x9C => write_hh!(self.file.length),
- 0x9D => write_hl!(self.file.length),
- 0x9E => write_lh!(self.file.length),
- 0x9F => { write_ll!(self.file.length); self.file.commit_length() },
-
- _ => unimplemented!("Writing to device port 0x{port:02x}"),
- };
-
- return None;
-
- }
-}