diff options
Diffstat (limited to 'src/devices.rs')
-rw-r--r-- | src/devices.rs | 384 |
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; - - } -} |