diff --git a/src/backplane.rs b/src/backplane.rs index 576264c..7806a91 100644 --- a/src/backplane.rs +++ b/src/backplane.rs @@ -151,7 +151,7 @@ impl Backplane { .cmd(cmd) } - pub fn read_word(&self, address: u32) -> Result { + pub fn read_word(&self, address: u32, supervisor: bool) -> Result { self.mem_helper( address, |address, mut card| card.read_word(address), @@ -159,10 +159,11 @@ impl Backplane { |address| self.read_word_io(address as u8), false, false, + supervisor, ) } - pub fn read_byte(&self, address: u32) -> Result { + pub fn read_byte(&self, address: u32, supervisor: bool) -> Result { self.mem_helper( address, |address, mut card| card.read_byte(address), @@ -170,10 +171,11 @@ impl Backplane { |address| self.read_byte_io(address as u8), false, false, + supervisor, ) } - pub fn write_word(&self, address: u32, data: u16) -> Result<(), BusError> { + pub fn write_word(&self, address: u32, data: u16, supervisor: bool) -> Result<(), BusError> { self.mem_helper( address, |address, mut card| card.write_word(address, data), @@ -181,10 +183,11 @@ impl Backplane { |address| self.write_word_io(address as u8, data), false, true, + supervisor, ) } - pub fn write_byte(&self, address: u32, data: u8) -> Result<(), BusError> { + pub fn write_byte(&self, address: u32, data: u8, supervisor: bool) -> Result<(), BusError> { self.mem_helper( address, |address, mut card| card.write_byte(address, data), @@ -192,6 +195,7 @@ impl Backplane { |address| self.write_byte_io(address as u8, data), false, true, + supervisor, ) } @@ -203,6 +207,7 @@ impl Backplane { |address| self.read_word_io(address as u8), true, false, + true, ) } @@ -215,6 +220,7 @@ impl Backplane { |address| self.read_byte_io(address as u8), true, false, + true, ) } @@ -227,6 +233,7 @@ impl Backplane { |address| self.write_word_io(address as u8, data), true, true, + true, ) } @@ -239,6 +246,7 @@ impl Backplane { |address| self.write_byte_io(address as u8, data), true, true, + true, ) } @@ -250,6 +258,7 @@ impl Backplane { mut backplane_io_func: B, bypass_mmu: bool, write: bool, + supervisor: bool, ) -> Result where M: FnMut(u32, RefMut<'_, dyn Card>) -> NullableResult, @@ -263,7 +272,7 @@ impl Backplane { .borrow_mut() .try_as_mmu() .unwrap() - .translate_address(self, address, write) + .translate_address(self, address, write, supervisor) { NullableResult::Ok(address) => address, NullableResult::Err(e) => return Err(e), diff --git a/src/card.rs b/src/card.rs index e7dd331..3643580 100644 --- a/src/card.rs +++ b/src/card.rs @@ -146,6 +146,7 @@ pub trait Mmu: Debug { backplane: &Backplane, address: u32, write: bool, + supervisor: bool, ) -> NullableResult; } diff --git a/src/m68k.rs b/src/m68k.rs index 803efe9..1933e18 100644 --- a/src/m68k.rs +++ b/src/m68k.rs @@ -1483,7 +1483,7 @@ impl M68K { self.store_mem_cycles = true; } } - let result = self.bus.read_byte(address).map_err(|_| DetailedBusError { + let result = self.bus.read_byte(address, self.is_supervisor()).map_err(|_| DetailedBusError { address, cause: BusErrorCause::ReadingByte, }); @@ -1518,7 +1518,7 @@ impl M68K { } let result = self .bus - .write_byte(address, data) + .write_byte(address, data, self.is_supervisor()) .map_err(|_| DetailedBusError { address, cause: BusErrorCause::WritingByte, @@ -1553,7 +1553,7 @@ impl M68K { self.store_mem_cycles = true; } } - let result = self.bus.read_word(address).map_err(|_| DetailedBusError { + let result = self.bus.read_word(address, self.is_supervisor()).map_err(|_| DetailedBusError { address, cause: BusErrorCause::ReadingWord, }); @@ -1592,7 +1592,7 @@ impl M68K { } let result = self .bus - .write_word(address, data) + .write_word(address, data, self.is_supervisor()) .map_err(|_| DetailedBusError { address, cause: BusErrorCause::WritingWord, diff --git a/src/main.rs b/src/main.rs index 32786df..dbc0108 100644 --- a/src/main.rs +++ b/src/main.rs @@ -294,11 +294,11 @@ fn main() -> Result<(), anyhow::Error> { } else { for i in 0..count { match size { - peek::Size::Byte => data.push(u32::from(bus.read_byte(addr + i)?)), - peek::Size::Word => data.push(u32::from(bus.read_word(addr + (i * 2))?)), + peek::Size::Byte => data.push(u32::from(bus.read_byte(addr + i, true)?)), + peek::Size::Word => data.push(u32::from(bus.read_word(addr + (i * 2), true)?)), peek::Size::LongWord => data.push( - u32::from(bus.read_word(addr + (i * 4))?) << 16 - | u32::from(bus.read_word(addr + (i * 4) + 2)?), + u32::from(bus.read_word(addr + (i * 4), true)?) << 16 + | u32::from(bus.read_word(addr + (i * 4) + 2, true)?), ), } } @@ -335,10 +335,10 @@ fn main() -> Result<(), anyhow::Error> { return Err(anyhow!("Cannot poke a word to a non-aligned address")); } let data = parse::(args.get_one::("data").unwrap())?; - state.cpu.bus_mut().write_word(address, data)?; + state.cpu.bus_mut().write_word(address, data, true)?; } else { let data = parse::(args.get_one::("data").unwrap())?; - state.cpu.bus_mut().write_byte(address, data)?; + state.cpu.bus_mut().write_byte(address, data, true)?; } Ok(None) } diff --git a/src/mmu.rs b/src/mmu.rs index 187b232..6a4959e 100644 --- a/src/mmu.rs +++ b/src/mmu.rs @@ -161,6 +161,7 @@ impl Mmu for MmuCard { backplane: &Backplane, address: u32, write: bool, + supervisor: bool, ) -> NullableResult { let print_debug = self.print_debug; if self.enabled { @@ -198,6 +199,12 @@ impl Mmu for MmuCard { mapping }; if mapping & MAPPING_FLAG_PRESENT > 0 { + if !supervisor && (mapping & MAPPING_FLAG_USER == 0) { + if print_debug { + println!("Page not user accessible"); + } + return NullableResult::Err(BusError); + } if write && (mapping & MAPPING_FLAG_WRITABLE == 0) { if print_debug { println!("Page not writable"); diff --git a/src/storage.rs b/src/storage.rs index e415408..e68568c 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -156,7 +156,7 @@ impl Card for Storage { // Closure is used to drop the mutex guard // between pop calls to prevent deadlock while let Some(data) = (|| self.read_data.pop_front())() { - backplane.write_byte(address, data).unwrap(); + backplane.write_byte(address, data, true).unwrap(); address += 1; } self.transfer = false;