core/sysbus: Get rid of memory_map! macro
While saving code re-use, it won't allow flexibility for special casing specific size bus accesses which are much needed in order to emulate open-bus and bios reads Former-commit-id: 952a30a130612d61b3f5047b1f1c3cbda9bd58a8 Former-commit-id: ad3a25c012853399591d79f4f1a4423ea9e6645e
This commit is contained in:
parent
24f6ad61c1
commit
90e492d81a
|
@ -180,64 +180,6 @@ pub struct SysBus {
|
||||||
|
|
||||||
pub type SysBusPtr = WeakPointer<SysBus>;
|
pub type SysBusPtr = WeakPointer<SysBus>;
|
||||||
|
|
||||||
macro_rules! memory_map {
|
|
||||||
(read($sb:ident, $read_fn:ident, $addr:expr)) => {
|
|
||||||
match $addr & 0xff000000 {
|
|
||||||
BIOS_ADDR => {
|
|
||||||
if $addr >= 0x4000 {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
$sb.bios.$read_fn($addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EWRAM_ADDR => $sb.onboard_work_ram.$read_fn($addr & 0x3_ffff),
|
|
||||||
IWRAM_ADDR => $sb.internal_work_ram.$read_fn($addr & 0x7fff),
|
|
||||||
IOMEM_ADDR => {
|
|
||||||
let addr = if $addr & 0xffff == 0x8000 {
|
|
||||||
0x800
|
|
||||||
} else {
|
|
||||||
$addr & 0x7ff
|
|
||||||
};
|
|
||||||
$sb.io.$read_fn(addr)
|
|
||||||
}
|
|
||||||
PALRAM_ADDR | VRAM_ADDR | OAM_ADDR => $sb.io.gpu.$read_fn($addr),
|
|
||||||
GAMEPAK_WS0_LO | GAMEPAK_WS0_HI | GAMEPAK_WS1_LO | GAMEPAK_WS1_HI | GAMEPAK_WS2_LO => {
|
|
||||||
$sb.cartridge.$read_fn($addr)
|
|
||||||
}
|
|
||||||
GAMEPAK_WS2_HI => $sb.cartridge.$read_fn($addr),
|
|
||||||
SRAM_LO | SRAM_HI => $sb.cartridge.$read_fn($addr),
|
|
||||||
_ => {
|
|
||||||
// warn!("trying to read invalid address {:#x}", $addr);
|
|
||||||
// TODO open bus
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
(write($sb:ident, $write_fn:ident, $addr:expr, $value:expr)) => {
|
|
||||||
match $addr & 0xff000000 {
|
|
||||||
BIOS_ADDR => {}
|
|
||||||
EWRAM_ADDR => $sb.onboard_work_ram.$write_fn($addr & 0x3_ffff, $value),
|
|
||||||
IWRAM_ADDR => $sb.internal_work_ram.$write_fn($addr & 0x7fff, $value),
|
|
||||||
IOMEM_ADDR => {
|
|
||||||
let addr = if $addr & 0xffff == 0x8000 {
|
|
||||||
0x800
|
|
||||||
} else {
|
|
||||||
$addr & 0x7ff
|
|
||||||
};
|
|
||||||
$sb.io.$write_fn(addr, $value)
|
|
||||||
}
|
|
||||||
PALRAM_ADDR | VRAM_ADDR | OAM_ADDR => $sb.io.gpu.$write_fn($addr, $value),
|
|
||||||
GAMEPAK_WS0_LO => $sb.cartridge.$write_fn($addr, $value),
|
|
||||||
GAMEPAK_WS2_HI => $sb.cartridge.$write_fn($addr, $value),
|
|
||||||
SRAM_LO | SRAM_HI => $sb.cartridge.$write_fn($addr, $value),
|
|
||||||
_ => {
|
|
||||||
// warn!("trying to write invalid address {:#x}", $addr);
|
|
||||||
// TODO open bus
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SysBus {
|
impl SysBus {
|
||||||
pub fn new(io: IoDevices, bios_rom: Box<[u8]>, cartridge: Cartridge) -> SysBus {
|
pub fn new(io: IoDevices, bios_rom: Box<[u8]>, cartridge: Cartridge) -> SysBus {
|
||||||
let mut luts = CycleLookupTables::default();
|
let mut luts = CycleLookupTables::default();
|
||||||
|
@ -245,8 +187,7 @@ impl SysBus {
|
||||||
luts.update_gamepak_waitstates(io.waitcnt);
|
luts.update_gamepak_waitstates(io.waitcnt);
|
||||||
|
|
||||||
SysBus {
|
SysBus {
|
||||||
io: io,
|
io,
|
||||||
|
|
||||||
bios: BoxedMemory::new(bios_rom),
|
bios: BoxedMemory::new(bios_rom),
|
||||||
onboard_work_ram: BoxedMemory::new(vec![0; WORK_RAM_SIZE].into_boxed_slice()),
|
onboard_work_ram: BoxedMemory::new(vec![0; WORK_RAM_SIZE].into_boxed_slice()),
|
||||||
internal_work_ram: BoxedMemory::new(vec![0; INTERNAL_RAM_SIZE].into_boxed_slice()),
|
internal_work_ram: BoxedMemory::new(vec![0; INTERNAL_RAM_SIZE].into_boxed_slice()),
|
||||||
|
@ -300,33 +241,181 @@ impl SysBus {
|
||||||
|
|
||||||
impl Bus for SysBus {
|
impl Bus for SysBus {
|
||||||
fn read_32(&self, addr: Addr) -> u32 {
|
fn read_32(&self, addr: Addr) -> u32 {
|
||||||
memory_map!(read(self, read_32, addr & !3))
|
match addr & 0xff000000 {
|
||||||
|
BIOS_ADDR => self.bios.read_32(addr),
|
||||||
|
EWRAM_ADDR => self.onboard_work_ram.read_32(addr & 0x3_fffc),
|
||||||
|
IWRAM_ADDR => self.internal_work_ram.read_32(addr & 0x7ffc),
|
||||||
|
IOMEM_ADDR => {
|
||||||
|
let addr = if addr & 0xfffc == 0x8000 {
|
||||||
|
0x800
|
||||||
|
} else {
|
||||||
|
addr & 0x7fc
|
||||||
|
};
|
||||||
|
self.io.read_32(addr)
|
||||||
|
}
|
||||||
|
PALRAM_ADDR | VRAM_ADDR | OAM_ADDR => self.io.gpu.read_32(addr),
|
||||||
|
GAMEPAK_WS0_LO | GAMEPAK_WS0_HI | GAMEPAK_WS1_LO | GAMEPAK_WS1_HI | GAMEPAK_WS2_LO => {
|
||||||
|
self.cartridge.read_32(addr)
|
||||||
|
}
|
||||||
|
GAMEPAK_WS2_HI => self.cartridge.read_32(addr),
|
||||||
|
SRAM_LO | SRAM_HI => self.cartridge.read_32(addr),
|
||||||
|
_ => {
|
||||||
|
// TODO open-bus
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_16(&self, addr: Addr) -> u16 {
|
fn read_16(&self, addr: Addr) -> u16 {
|
||||||
memory_map!(read(self, read_16, addr & !1))
|
match addr & 0xff000000 {
|
||||||
|
BIOS_ADDR => self.bios.read_16(addr),
|
||||||
|
EWRAM_ADDR => self.onboard_work_ram.read_16(addr & 0x3_fffe),
|
||||||
|
IWRAM_ADDR => self.internal_work_ram.read_16(addr & 0x7ffe),
|
||||||
|
IOMEM_ADDR => {
|
||||||
|
let addr = if addr & 0xfffe == 0x8000 {
|
||||||
|
0x800
|
||||||
|
} else {
|
||||||
|
addr & 0x7fe
|
||||||
|
};
|
||||||
|
self.io.read_16(addr)
|
||||||
|
}
|
||||||
|
PALRAM_ADDR | VRAM_ADDR | OAM_ADDR => self.io.gpu.read_16(addr),
|
||||||
|
GAMEPAK_WS0_LO | GAMEPAK_WS0_HI | GAMEPAK_WS1_LO | GAMEPAK_WS1_HI | GAMEPAK_WS2_LO => {
|
||||||
|
self.cartridge.read_16(addr)
|
||||||
|
}
|
||||||
|
GAMEPAK_WS2_HI => self.cartridge.read_16(addr),
|
||||||
|
SRAM_LO | SRAM_HI => self.cartridge.read_16(addr),
|
||||||
|
_ => {
|
||||||
|
// TODO open-bus
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_8(&self, addr: Addr) -> u8 {
|
fn read_8(&self, addr: Addr) -> u8 {
|
||||||
memory_map!(read(self, read_8, addr))
|
match addr & 0xff000000 {
|
||||||
|
BIOS_ADDR => self.bios.read_8(addr),
|
||||||
|
EWRAM_ADDR => self.onboard_work_ram.read_8(addr & 0x3_ffff),
|
||||||
|
IWRAM_ADDR => self.internal_work_ram.read_8(addr & 0x7fff),
|
||||||
|
IOMEM_ADDR => {
|
||||||
|
let addr = if addr & 0xffff == 0x8000 {
|
||||||
|
0x800
|
||||||
|
} else {
|
||||||
|
addr & 0x7ff
|
||||||
|
};
|
||||||
|
self.io.read_8(addr)
|
||||||
|
}
|
||||||
|
PALRAM_ADDR | VRAM_ADDR | OAM_ADDR => self.io.gpu.read_8(addr),
|
||||||
|
GAMEPAK_WS0_LO | GAMEPAK_WS0_HI | GAMEPAK_WS1_LO | GAMEPAK_WS1_HI | GAMEPAK_WS2_LO => {
|
||||||
|
self.cartridge.read_8(addr)
|
||||||
|
}
|
||||||
|
GAMEPAK_WS2_HI => self.cartridge.read_8(addr),
|
||||||
|
SRAM_LO | SRAM_HI => self.cartridge.read_8(addr),
|
||||||
|
_ => {
|
||||||
|
// TODO open-bus
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_32(&mut self, addr: Addr, value: u32) {
|
fn write_32(&mut self, addr: Addr, value: u32) {
|
||||||
memory_map!(write(self, write_32, addr & !3, value));
|
match addr & 0xff000000 {
|
||||||
|
BIOS_ADDR => {}
|
||||||
|
EWRAM_ADDR => self.onboard_work_ram.write_32(addr & 0x3_fffc, value),
|
||||||
|
IWRAM_ADDR => self.internal_work_ram.write_32(addr & 0x7ffc, value),
|
||||||
|
IOMEM_ADDR => {
|
||||||
|
let addr = if addr & 0xfffc == 0x8000 {
|
||||||
|
0x800
|
||||||
|
} else {
|
||||||
|
addr & 0x7fc
|
||||||
|
};
|
||||||
|
self.io.write_32(addr, value)
|
||||||
|
}
|
||||||
|
PALRAM_ADDR | VRAM_ADDR | OAM_ADDR => self.io.gpu.write_32(addr, value),
|
||||||
|
GAMEPAK_WS0_LO => self.cartridge.write_32(addr, value),
|
||||||
|
GAMEPAK_WS2_HI => self.cartridge.write_32(addr, value),
|
||||||
|
SRAM_LO | SRAM_HI => self.cartridge.write_32(addr, value),
|
||||||
|
_ => {
|
||||||
|
// warn!("trying to write invalid address {:#x}", addr);
|
||||||
|
// TODO open bus
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_16(&mut self, addr: Addr, value: u16) {
|
fn write_16(&mut self, addr: Addr, value: u16) {
|
||||||
memory_map!(write(self, write_16, addr & !1, value));
|
match addr & 0xff000000 {
|
||||||
|
BIOS_ADDR => {}
|
||||||
|
EWRAM_ADDR => self.onboard_work_ram.write_16(addr & 0x3_fffe, value),
|
||||||
|
IWRAM_ADDR => self.internal_work_ram.write_16(addr & 0x7ffe, value),
|
||||||
|
IOMEM_ADDR => {
|
||||||
|
let addr = if addr & 0xfffe == 0x8000 {
|
||||||
|
0x800
|
||||||
|
} else {
|
||||||
|
addr & 0x7fe
|
||||||
|
};
|
||||||
|
self.io.write_16(addr, value)
|
||||||
|
}
|
||||||
|
PALRAM_ADDR | VRAM_ADDR | OAM_ADDR => self.io.gpu.write_16(addr, value),
|
||||||
|
GAMEPAK_WS0_LO => self.cartridge.write_16(addr, value),
|
||||||
|
GAMEPAK_WS2_HI => self.cartridge.write_16(addr, value),
|
||||||
|
SRAM_LO | SRAM_HI => self.cartridge.write_16(addr, value),
|
||||||
|
_ => {
|
||||||
|
// warn!("trying to write invalid address {:#x}", addr);
|
||||||
|
// TODO open bus
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_8(&mut self, addr: Addr, value: u8) {
|
fn write_8(&mut self, addr: Addr, value: u8) {
|
||||||
memory_map!(write(self, write_8, addr, value));
|
match addr & 0xff000000 {
|
||||||
|
BIOS_ADDR => {}
|
||||||
|
EWRAM_ADDR => self.onboard_work_ram.write_8(addr & 0x3_ffff, value),
|
||||||
|
IWRAM_ADDR => self.internal_work_ram.write_8(addr & 0x7fff, value),
|
||||||
|
IOMEM_ADDR => {
|
||||||
|
let addr = if addr & 0xffff == 0x8000 {
|
||||||
|
0x800
|
||||||
|
} else {
|
||||||
|
addr & 0x7ff
|
||||||
|
};
|
||||||
|
self.io.write_8(addr, value)
|
||||||
|
}
|
||||||
|
PALRAM_ADDR | VRAM_ADDR | OAM_ADDR => self.io.gpu.write_8(addr, value),
|
||||||
|
GAMEPAK_WS0_LO => self.cartridge.write_8(addr, value),
|
||||||
|
GAMEPAK_WS2_HI => self.cartridge.write_8(addr, value),
|
||||||
|
SRAM_LO | SRAM_HI => self.cartridge.write_8(addr, value),
|
||||||
|
_ => {
|
||||||
|
// warn!("trying to write invalid address {:#x}", addr);
|
||||||
|
// TODO open bus
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DebugRead for SysBus {
|
impl DebugRead for SysBus {
|
||||||
fn debug_read_8(&self, addr: Addr) -> u8 {
|
fn debug_read_8(&self, addr: Addr) -> u8 {
|
||||||
memory_map!(read(self, debug_read_8, addr, u8)) as u8
|
match addr & 0xff000000 {
|
||||||
|
BIOS_ADDR => self.bios.debug_read_8(addr),
|
||||||
|
EWRAM_ADDR => self.onboard_work_ram.debug_read_8(addr & 0x3_ffff),
|
||||||
|
IWRAM_ADDR => self.internal_work_ram.debug_read_8(addr & 0x7fff),
|
||||||
|
IOMEM_ADDR => {
|
||||||
|
let addr = if addr & 0xffff == 0x8000 {
|
||||||
|
0x800
|
||||||
|
} else {
|
||||||
|
addr & 0x7ff
|
||||||
|
};
|
||||||
|
self.io.debug_read_8(addr)
|
||||||
|
}
|
||||||
|
PALRAM_ADDR | VRAM_ADDR | OAM_ADDR => self.io.gpu.debug_read_8(addr),
|
||||||
|
GAMEPAK_WS0_LO | GAMEPAK_WS0_HI | GAMEPAK_WS1_LO | GAMEPAK_WS1_HI | GAMEPAK_WS2_LO => {
|
||||||
|
self.cartridge.debug_read_8(addr)
|
||||||
|
}
|
||||||
|
GAMEPAK_WS2_HI => self.cartridge.debug_read_8(addr),
|
||||||
|
SRAM_LO | SRAM_HI => self.cartridge.debug_read_8(addr),
|
||||||
|
_ => {
|
||||||
|
// TODO open-bus
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue