diff options
author | Ben Bridle <bridle.benjamin@gmail.com> | 2024-04-16 10:51:13 +1200 |
---|---|---|
committer | Ben Bridle <bridle.benjamin@gmail.com> | 2024-04-16 10:51:26 +1200 |
commit | 6b3796c9a0d3a2f1422bcbde4790c43417659722 (patch) | |
tree | 6429a5fa2f8c4d3b26790775e07e46e6338b61d3 /src/devices/memory.rs | |
parent | 28101de56231252ca0cfa6a9f107b75112c9acad (diff) | |
download | bedrock-pc-6b3796c9a0d3a2f1422bcbde4790c43417659722.zip |
Update devices to match new specifications
Diffstat (limited to 'src/devices/memory.rs')
-rw-r--r-- | src/devices/memory.rs | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/devices/memory.rs b/src/devices/memory.rs new file mode 100644 index 0000000..1d33f64 --- /dev/null +++ b/src/devices/memory.rs @@ -0,0 +1,89 @@ +macro_rules! then_inc { ($v:expr) => {{ $v = $v.wrapping_add(1); $v as usize }}; } + +type Page = [u8; 65536]; +fn new_blank_page() -> [u8; 65536] { [0; 65536] } + + +pub struct MemoryDevice { + pages: Vec<Page>, + pub page_limit: u16, + pub page_1: u16, + pub address_1: u16, + pub page_2: u16, + pub address_2: u16, + pub copy_length: u16, +} + +impl MemoryDevice { + pub fn new() -> Self { + Self { + pages: Vec::new(), + page_limit: 0, + page_1: 0, + address_1: 0, + page_2: 0, + address_2: 0, + copy_length: 0, + } + } + + pub fn page_count(&self) -> u16 { + self.pages.len() as u16 + } + + pub fn copy(&mut self) { + // Return if at least one page is out-of-bounds + if self.page_1 as usize >= self.pages.len() + || self.page_2 as usize >= self.pages.len() { + return + } + let p1 = self.page_1 as usize; + let p2 = self.page_2 as usize; + let a1 = self.address_1; + let a2 = self.address_2; + + for i in 0..=self.copy_length { + let byte = self.pages[p2][a2.wrapping_add(i) as usize]; + self.pages[p1][a1.wrapping_add(i) as usize] = byte; + } + } + + pub fn expand_memory(&mut self) { + let size = std::cmp::max(self.page_1, self.page_2) as usize + 1; + if size < self.page_limit as usize { + self.pages.resize_with(size, new_blank_page); + } + } + + pub fn read_from_head_1(&mut self) -> u8 { + let address = then_inc!(self.address_1); + if let Some(page) = self.pages.get(self.page_1 as usize) { + page[address] + } else { + 0x00 + } + } + + pub fn read_from_head_2(&mut self) -> u8 { + let address = then_inc!(self.address_2); + if let Some(page) = self.pages.get(self.page_2 as usize) { + page[address] + } else { + 0x00 + } + } + + pub fn write_to_head_1(&mut self, byte: u8) { + let address = then_inc!(self.address_1); + if let Some(page) = self.pages.get_mut(self.page_1 as usize) { + page[address] = byte; + } + } + + pub fn write_to_head_2(&mut self, byte: u8) { + let address = then_inc!(self.address_2); + if let Some(page) = self.pages.get_mut(self.page_2 as usize) { + page[address] = byte; + } + } +} |