From 6b3796c9a0d3a2f1422bcbde4790c43417659722 Mon Sep 17 00:00:00 2001 From: Ben Bridle Date: Tue, 16 Apr 2024 10:51:13 +1200 Subject: Update devices to match new specifications --- src/devices.rs | 319 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 170 insertions(+), 149 deletions(-) (limited to 'src/devices.rs') diff --git a/src/devices.rs b/src/devices.rs index e1a00f7..e191746 100644 --- a/src/devices.rs +++ b/src/devices.rs @@ -1,69 +1,67 @@ -use bedrock_core::*; - +mod system; +mod memory; mod math; mod clock; mod input; mod screen; -mod scratch; mod stream; mod file; -pub use math::*; -pub use clock::*; -pub use input::*; -pub use screen::*; -pub use scratch::*; -pub use stream::*; -pub use file::*; +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 math: MathDevice, - pub clock: ClockDevice, - pub input: InputDevice, - pub screen: ScreenDevice, - pub scratch: ScratchDevice, - pub stream: StreamDevice, - pub file: FileDevice, + 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_device: u8, + pub wake_id: u8, } impl StandardDevices { pub fn new() -> Self { - let mut screen = ScreenDevice::new(); - screen.resize(ScreenDimensions::new(256, 192)); - Self { - math: MathDevice::new(), - clock: ClockDevice::new(), - input: InputDevice::new(), - screen, - scratch: ScratchDevice::new(), - stream: StreamDevice::new(), - file: FileDevice::new(), + 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_device: 0x00, + wake_id: 0x00, } } pub fn can_wake(&mut self) -> bool { macro_rules! test_wake { - ($flag:expr, $mask:expr, $index:expr) => { + ($flag:expr, $id:expr, $mask:expr) => { if $flag && self.wake_mask & $mask != 0 { - $flag = false; self.wake_device = $index; return true; - } + $flag = false; self.wake_id = $id; return true } }; } - self.clock.update_timer_1(); - self.clock.update_timer_2(); - self.clock.update_timer_3(); - self.clock.update_timer_4(); - test_wake!(self.clock.wake_flag, 0x1000, 0x03); - test_wake!(self.input.wake_flag, 0x0800, 0x04); - test_wake!(self.screen.wake_flag, 0x0400, 0x05); - test_wake!(self.stream.wake_flag, 0x0040, 0x09); + self.clock.update_timers(); + test_wake!(self.clock.wake_flag, 0x3, 0x1000); + test_wake!(self.input.wake_flag, 0x4, 0x0800); + test_wake!(self.screen.wake_flag, 0x5, 0x0400); + test_wake!(self.stream.wake_flag, 0x8, 0x0080); return false; } } @@ -77,27 +75,43 @@ impl DeviceBus for StandardDevices { 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 => no_read!(), - 0x01 => no_read!(), - 0x02 => self.wake_device, + 0x00 => self.name.read_byte(), + 0x01 => self.wake_id, + 0x02 => no_read!(), 0x03 => no_read!(), - 0x04 => no_read!(), - 0x05 => no_read!(), - 0x06 => no_read!(), - 0x07 => no_read!(), - 0x08 => 0xFF, - 0x09 => 0xFF, - 0x0A => 0xFF, - 0x0B => 0xFF, - 0x0C => 0xBC, - 0x0D => 0x80, - 0x0E => 0xBC, - 0x0F => 0x80, + 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_count()), + 0x17 => read_l!(self.memory.page_count()), + 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!(), @@ -107,14 +121,14 @@ impl DeviceBus for StandardDevices { 0x25 => no_read!(), 0x26 => no_read!(), 0x27 => no_read!(), - 0x28 => { self.math.multiply(); read_h!(self.math.product_high) }, - 0x29 => { self.math.multiply(); read_l!(self.math.product_high) }, - 0x2A => { self.math.multiply(); read_h!(self.math.product_low) }, - 0x2B => { self.math.multiply(); read_l!(self.math.product_low) }, - 0x2C => { self.math.divide(); read_h!(self.math.quotient) }, - 0x2D => { self.math.divide(); read_l!(self.math.quotient) }, - 0x2E => { self.math.modulo(); read_h!(self.math.remainder) }, - 0x2F => { self.math.modulo(); read_l!(self.math.remainder) }, + 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(), @@ -122,8 +136,8 @@ impl DeviceBus for StandardDevices { 0x33 => self.clock.hour(), 0x34 => self.clock.minute(), 0x35 => self.clock.second(), - 0x36 => read_h!(self.clock.update_cumulative_timer()), - 0x37 => read_l!(self.clock.cumulative_timer), + 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()), @@ -133,27 +147,31 @@ impl DeviceBus for StandardDevices { 0x3E => read_h!(self.clock.update_timer_4()), 0x3F => read_l!(self.clock.timer_4), // Input - 0x40 => read_h!(self.input.mouse_position.x), - 0x41 => read_l!(self.input.mouse_position.x), - 0x42 => read_h!(self.input.mouse_position.y), - 0x43 => read_l!(self.input.mouse_position.y), - 0x44 => read_h!(self.input.horizontal_scroll_value), - 0x45 => read_l!(self.input.horizontal_scroll_value), - 0x46 => read_h!(self.input.vertical_scroll_value), - 0x47 => read_l!(self.input.vertical_scroll_value), - 0x48 => self.input.character_queue.pop_front().unwrap_or(0), - 0x49 => self.input.modifier_state, - 0x4A => self.input.mouse_button_state, - 0x4B => self.input.navigation_state, + 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.dimensions.width), - 0x51 => read_l!(self.screen.dimensions.width), - 0x52 => read_h!(self.screen.dimensions.height), - 0x53 => read_l!(self.screen.dimensions.height), - 0x54 => read_h!(self.screen.cursor.x), - 0x55 => read_l!(self.screen.cursor.x), - 0x56 => read_h!(self.screen.cursor.y), - 0x57 => read_l!(self.screen.cursor.y), + 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!(), @@ -162,25 +180,23 @@ impl DeviceBus for StandardDevices { 0x5D => no_read!(), 0x5E => no_read!(), 0x5F => no_read!(), - // Scratch - 0x80 => no_read!(), - 0x81 => no_read!(), - 0x82 => no_read!(), - 0x83 => no_read!(), - 0x84 => no_read!(), - 0x85 => no_read!(), - 0x86 => no_read!(), - 0x87 => no_read!(), - 0x88 => self.scratch.read_head_1(), - 0x89 => self.scratch.read_head_1(), - 0x8A => self.scratch.read_head_2(), - 0x8B => self.scratch.read_head_2(), - 0x8C => read_hh!(self.scratch.max_capacity), - 0x8D => read_hl!(self.scratch.max_capacity), - 0x8E => read_lh!(self.scratch.max_capacity), - 0x8F => read_ll!(self.scratch.max_capacity), // 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 0xA0 => read_b!(self.file.entry.is_some()), 0xA1 => read_b!(self.file.move_success), @@ -204,22 +220,20 @@ impl DeviceBus for StandardDevices { } fn write_u8(&mut self, val: u8, port: u8) -> Option { - 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 => write_h!(self.wake_mask), - 0x01 => { write_l!(self.wake_mask); return Some(Signal::Pause) }, - 0x02 => no_write!(), - 0x03 => no_write!(), + 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!(), @@ -232,6 +246,23 @@ impl DeviceBus for StandardDevices { 0x0D => no_write!(), 0x0E => no_write!(), 0x0F => no_write!(), + // Memory + 0x10 => { write_h!(self.memory.page_1); self.memory.expand_memory() }, + 0x11 => { write_l!(self.memory.page_1); self.memory.expand_memory() }, + 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 => write_h!(self.memory.page_limit), + 0x17 => write_l!(self.memory.page_limit), + 0x18 => { write_h!(self.memory.page_2); self.memory.expand_memory() }, + 0x19 => { write_l!(self.memory.page_2); self.memory.expand_memory() }, + 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), @@ -250,6 +281,14 @@ impl DeviceBus for StandardDevices { 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), @@ -267,8 +306,8 @@ impl DeviceBus for StandardDevices { 0x45 => no_write!(), 0x46 => no_write!(), 0x47 => no_write!(), - 0x48 => self.input.character_queue.clear(), - 0x49 => no_write!(), + 0x48 => no_write!(), + 0x49 => self.input.text_queue.clear(), 0x4A => no_write!(), 0x4B => no_write!(), 0x4C => no_write!(), @@ -276,39 +315,25 @@ impl DeviceBus for StandardDevices { 0x4E => no_write!(), 0x4F => no_write!(), // Screen - 0x50 => write_h!(self.screen.dimensions.width), - 0x51 => { write_l!(self.screen.dimensions.width); self.screen.set_size(self.screen.dimensions) }, - 0x52 => write_h!(self.screen.dimensions.height), - 0x53 => { write_l!(self.screen.dimensions.height); self.screen.set_size(self.screen.dimensions) }, - 0x54 => write_h!(self.screen.cursor.x), - 0x55 => write_l!(self.screen.cursor.x), - 0x56 => write_h!(self.screen.cursor.y), - 0x57 => write_l!(self.screen.cursor.y), - 0x58 => self.screen.draw(val), - 0x59 => self.screen.shunt(val), - 0x5A => self.screen.sprite_data.push(val), - 0x5B => self.screen.sprite_data.push(val), - 0x5C => self.screen.set_palette_high(val), - 0x5D => self.screen.set_palette_low(val), - 0x5E => self.screen.set_sprite_colour_high(val), - 0x5F => self.screen.set_sprite_colour_low(val), - // Scratch - 0x80 => write_hh!(self.scratch.pointer_1), - 0x81 => write_hl!(self.scratch.pointer_1), - 0x82 => write_lh!(self.scratch.pointer_1), - 0x83 => write_ll!(self.scratch.pointer_1), - 0x84 => write_hh!(self.scratch.pointer_2), - 0x85 => write_hl!(self.scratch.pointer_2), - 0x86 => write_lh!(self.scratch.pointer_2), - 0x87 => write_ll!(self.scratch.pointer_2), - 0x88 => self.scratch.write_head_1(val), - 0x89 => self.scratch.write_head_1(val), - 0x8A => self.scratch.write_head_2(val), - 0x8B => self.scratch.write_head_2(val), - 0x8C => no_write!(), - 0x8D => no_write!(), - 0x8E => no_write!(), - 0x8F => no_write!(), + 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 0xA0 => self.file.write_to_open_port(val), 0xA1 => self.file.write_to_move_port(val), @@ -327,10 +352,6 @@ impl DeviceBus for StandardDevices { 0xAE => write_lh!(self.file.new_length), 0xAF => { write_ll!(self.file.new_length); self.file.commit_length() }, - // Bytestreams - 0x96 => self.stream.write_stdout(val), - 0x97 => self.stream.write_stdout(val), - _ => unimplemented!("Writing to device port 0x{port:02x}"), }; -- cgit v1.2.3-70-g09d2