summaryrefslogtreecommitdiff
path: root/src/devices.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices.rs')
-rw-r--r--src/devices.rs319
1 files changed, 170 insertions, 149 deletions
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<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 => 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}"),
};