Added option to ignore reads/writes to unmapped bus areas

This commit is contained in:
transistor 2021-12-25 16:30:07 -08:00
parent 4c99cbf240
commit 188717e228
4 changed files with 35 additions and 8 deletions

View File

@ -6,7 +6,7 @@ use crate::error::Error;
use crate::system::System; use crate::system::System;
use crate::signals::{Signal}; use crate::signals::{Signal};
use crate::memory::{MemoryBlock, Bus, BusPort}; use crate::memory::{MemoryBlock, Bus, BusPort};
use crate::devices::{wrap_transmutable, Address, Addressable}; use crate::devices::{wrap_transmutable, Address, Addressable, Debuggable};
use crate::cpus::m68k::{M68k, M68kType}; use crate::cpus::m68k::{M68k, M68kType};
use crate::cpus::z80::{Z80, Z80Type}; use crate::cpus::z80::{Z80, Z80Type};
@ -68,13 +68,15 @@ pub fn build_genesis<H: Host>(host: &mut H, options: SegaGenesisOptions) -> Resu
let coproc_register = wrap_transmutable(CoprocessorBankRegister::new(bank_register.clone())); let coproc_register = wrap_transmutable(CoprocessorBankRegister::new(bank_register.clone()));
let coproc_area = wrap_transmutable(CoprocessorBankArea::new(bank_register, system.bus.clone())); let coproc_area = wrap_transmutable(CoprocessorBankArea::new(bank_register, system.bus.clone()));
let coproc_bus = Rc::new(RefCell::new(Bus::new())); let mut coproc_bus = Rc::new(RefCell::new(Bus::new()));
coproc_bus.borrow_mut().set_ignore_unmapped(true);
coproc_bus.borrow_mut().insert(0x0000, coproc_ram.clone()); coproc_bus.borrow_mut().insert(0x0000, coproc_ram.clone());
coproc_bus.borrow_mut().insert(0x4000, coproc_ym_sound.clone()); coproc_bus.borrow_mut().insert(0x4000, coproc_ym_sound.clone());
coproc_bus.borrow_mut().insert(0x6000, coproc_register.clone()); coproc_bus.borrow_mut().insert(0x6000, coproc_register.clone());
coproc_bus.borrow_mut().insert(0x7f11, coproc_sn_sound.clone()); coproc_bus.borrow_mut().insert(0x7f11, coproc_sn_sound.clone());
coproc_bus.borrow_mut().insert(0x8000, coproc_area); coproc_bus.borrow_mut().insert(0x8000, coproc_area);
let coproc = Z80::new(Z80Type::Z80, 3_579_545, BusPort::new(0, 16, 8, coproc_bus.clone())); let mut coproc = Z80::new(Z80Type::Z80, 3_579_545, BusPort::new(0, 16, 8, coproc_bus.clone()));
coproc.set_debugging(true);
let mut reset = coproc.reset.clone(); let mut reset = coproc.reset.clone();
let mut bus_request = coproc.bus_request.clone(); let mut bus_request = coproc.bus_request.clone();
reset.set(true); reset.set(true);

View File

@ -118,16 +118,22 @@ pub struct Block {
} }
pub struct Bus { pub struct Bus {
ignore_unmapped: bool,
blocks: Vec<Block>, blocks: Vec<Block>,
} }
impl Bus { impl Bus {
pub fn new() -> Bus { pub fn new() -> Bus {
Bus { Bus {
ignore_unmapped: false,
blocks: vec!(), blocks: vec!(),
} }
} }
pub fn set_ignore_unmapped(&mut self, ignore_unmapped: bool) {
self.ignore_unmapped = ignore_unmapped;
}
pub fn clear_all_bus_devices(&mut self) { pub fn clear_all_bus_devices(&mut self) {
self.blocks.clear(); self.blocks.clear();
} }
@ -180,13 +186,27 @@ impl Addressable for Bus {
} }
fn read(&mut self, addr: Address, data: &mut [u8]) -> Result<(), Error> { fn read(&mut self, addr: Address, data: &mut [u8]) -> Result<(), Error> {
let (dev, relative_addr) = self.get_device_at(addr, data.len())?; let (dev, relative_addr) = match self.get_device_at(addr, data.len()) {
Ok(result) => result,
Err(err) if self.ignore_unmapped => {
info!("{:?}", err);
return Ok(())
},
Err(err) => return Err(err),
};
let result = dev.borrow_mut().as_addressable().unwrap().read(relative_addr, data); let result = dev.borrow_mut().as_addressable().unwrap().read(relative_addr, data);
result result
} }
fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> { fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> {
let (dev, relative_addr) = self.get_device_at(addr, data.len())?; let (dev, relative_addr) = match self.get_device_at(addr, data.len()) {
Ok(result) => result,
Err(err) if self.ignore_unmapped => {
info!("{:?}", err);
return Ok(())
},
Err(err) => return Err(err),
};
let result = dev.borrow_mut().as_addressable().unwrap().write(relative_addr, data); let result = dev.borrow_mut().as_addressable().unwrap().write(relative_addr, data);
result result
} }

View File

@ -50,6 +50,10 @@ impl System {
self.interrupt_controller.borrow_mut() self.interrupt_controller.borrow_mut()
} }
pub fn get_device(&self, name: &str) -> Result<TransmutableBox, Error> {
self.devices.get(name).cloned().ok_or_else(|| Error::new(&format!("system: no device named {}", name)))
}
pub fn add_device(&mut self, name: &str, device: TransmutableBox) -> Result<(), Error> { pub fn add_device(&mut self, name: &str, device: TransmutableBox) -> Result<(), Error> {
self.try_queue_device(device.clone()); self.try_queue_device(device.clone());
self.devices.insert(name.to_string(), device); self.devices.insert(name.to_string(), device);

View File

@ -1,12 +1,13 @@
* there is an issue with Mortal Kombat 2 where it will crash randomly at the start of a fight. The code is actually swapping
stacks a bunch of times, and at some point, the stack is corrupted or something and it `rts`s to the wrong address...
* for the line based hscroll, you need to add that extra cell cycle...
* there is still some kind of hscroll glitch, and it seems to entirely be caused by the horizontal scroll offset value. I could be calculating or adding/moding * there is still some kind of hscroll glitch, and it seems to entirely be caused by the horizontal scroll offset value. I could be calculating or adding/moding
it incorrectly somewhere somehow, or the data in the hscroll table could be incorrect due to the cpu impl it incorrectly somewhere somehow, or the data in the hscroll table could be incorrect due to the cpu impl
* go through the testcases and make sure they are decoded correctly * go through the testcases and make sure they are decoded correctly
* should you rename devices.rs traits.rs? * should you rename devices.rs traits.rs?
* add command line arguments to speed up or slow down either the frame rate limiter or the simulated time per frame * add command line arguments to speed up or slow down either the frame rate limiter or the simulated time per frame