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 { // Hard limit on the number of pages which can be allocated pub page_limit: u16, // Pages which have actually been allocated pub pages: Vec, 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 { page_limit: 0, pages: Vec::new(), page_1: 0, address_1: 0, page_2: 0, address_2: 0, copy_length: 0, } } pub fn copy(&mut self) { let count = std::cmp::max(self.page_1, self.page_2) as usize + 1; if count <= self.page_limit as usize { if self.pages.len() < count { self.pages.resize_with(count, new_blank_page); } 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 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); let page = self.page_1 as usize; if self.page_limit as usize > page { if self.pages.len() <= page { self.pages.resize_with(page + 1, new_blank_page); } self.pages[page][address] = byte; } } pub fn write_to_head_2(&mut self, byte: u8) { let address = then_inc!(self.address_1); let page = self.page_2 as usize; if self.page_limit as usize > page { if self.pages.len() <= page { self.pages.resize_with(page + 1, new_blank_page); } self.pages[page][address] = byte; } } }