diff --git a/src/state.rs b/src/state.rs index 35e86d6..97fe804 100644 --- a/src/state.rs +++ b/src/state.rs @@ -15,6 +15,7 @@ pub struct EmuState { options: Options, fp_state: FrontpanelState, cards: Vec<(&'static Type, Box)>, + io_cache: Option<(u8, u8)> } impl EmuState { @@ -34,6 +35,7 @@ impl EmuState { options, fp_state: FrontpanelState::default(), cards, + io_cache: None, }; slf.apply_options(); slf @@ -125,8 +127,10 @@ impl EmuState { | MemCycle::Hlta => { self.fp_state.set_data(0xff); } - MemCycle::In(_) => { - self.fp_state.set_data(0); + MemCycle::In(a) => { + let data = self.read_io(a as u8); + self.io_cache = Some((a as u8, data)); + self.fp_state.set_data(data); } MemCycle::Inta(_) => todo!(), MemCycle::IntaHlt(_) => todo!(), @@ -141,8 +145,22 @@ impl EmuState { self.write_mem(a, d); 0 } - MemCycle::In(_) => 0, - MemCycle::Out(_, _) => 0, + MemCycle::In(a) => { + if let Some((cached_addr, cached_data)) = self.io_cache { + if cached_addr == a as u8 { + self.io_cache = None; + cached_data + } else { + self.read_io(a as u8) + } + } else { + self.read_io(a as u8) + } + }, + MemCycle::Out(a, d) => { + self.write_io(a as u8, d); + 0 + }, MemCycle::Inta(_) => todo!(), MemCycle::Hlta => { self.running = false; @@ -217,4 +235,12 @@ impl EmuState { fn write_mem(&mut self, address: u16, data: u8) { self.cards.iter_mut().find_map(|(_, card)| card.write_mem(address, data)); } + + fn read_io(&mut self, address: u8) -> u8 { + self.cards.iter_mut().find_map(|(_, card)| card.read_io(address)).unwrap_or(0xFF) + } + + fn write_io(&mut self, address: u8, data: u8) { + self.cards.iter_mut().find_map(|(_, card)| card.write_io(address, data)); + } }