Obviously, use the new PI bus read/write functions for the DMA as well 🤦 Fixes saving in Paper Mario (supposedly, can't test it because now it crashes on a TLB LOAD exception 🤬)
This commit is contained in:
@@ -197,7 +197,7 @@ u8 Mem::Read8(n64::Registers ®s, u32 paddr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case REGION_CART:
|
case REGION_CART:
|
||||||
return mmio.pi.BusRead8(*this, paddr);
|
return mmio.pi.BusRead8<false>(*this, paddr);
|
||||||
case 0x04040000 ... 0x040FFFFF:
|
case 0x04040000 ... 0x040FFFFF:
|
||||||
case 0x04100000 ... 0x041FFFFF:
|
case 0x04100000 ... 0x041FFFFF:
|
||||||
case 0x04600000 ... 0x048FFFFF:
|
case 0x04600000 ... 0x048FFFFF:
|
||||||
@@ -365,7 +365,7 @@ void Mem::Write8(Registers& regs, u32 paddr, u32 val) {
|
|||||||
} break;
|
} break;
|
||||||
case REGION_CART:
|
case REGION_CART:
|
||||||
Util::debug("BusWrite8 @ {:08X} = {:02X}", paddr, val);
|
Util::debug("BusWrite8 @ {:08X} = {:02X}", paddr, val);
|
||||||
mmio.pi.BusWrite8(*this, paddr, val);
|
mmio.pi.BusWrite8<false>(*this, paddr, val);
|
||||||
break;
|
break;
|
||||||
case MMIO_REGION:
|
case MMIO_REGION:
|
||||||
Util::panic("MMIO Write8!");
|
Util::panic("MMIO Write8!");
|
||||||
|
|||||||
@@ -48,10 +48,13 @@ bool PI::ReadLatch() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<bool isDma>
|
||||||
auto PI::BusRead8(Mem& mem, u32 addr) -> u8 {
|
auto PI::BusRead8(Mem& mem, u32 addr) -> u8 {
|
||||||
|
if constexpr (!isDma) {
|
||||||
if (!ReadLatch()) [[unlikely]] {
|
if (!ReadLatch()) [[unlikely]] {
|
||||||
return latch >> 24;
|
return latch >> 24;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case REGION_PI_UNKNOWN:
|
case REGION_PI_UNKNOWN:
|
||||||
@@ -67,7 +70,9 @@ auto PI::BusRead8(Mem& mem, u32 addr) -> u8 {
|
|||||||
return mem.BackupRead8(addr - SREGION_PI_SRAM);
|
return mem.BackupRead8(addr - SREGION_PI_SRAM);
|
||||||
case REGION_PI_ROM: {
|
case REGION_PI_ROM: {
|
||||||
// round to nearest 4 byte boundary, keeping old LSB
|
// round to nearest 4 byte boundary, keeping old LSB
|
||||||
|
if constexpr (!isDma) {
|
||||||
addr = (addr + 2) & ~2;
|
addr = (addr + 2) & ~2;
|
||||||
|
}
|
||||||
u32 index = BYTE_ADDRESS(addr) - SREGION_PI_ROM;
|
u32 index = BYTE_ADDRESS(addr) - SREGION_PI_ROM;
|
||||||
if (index > mem.rom.size) {
|
if (index > mem.rom.size) {
|
||||||
//Util::warn("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM! ({}/0x{:016X})", addr, index, index, mem.rom.size, mem.rom.size);
|
//Util::warn("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM! ({}/0x{:016X})", addr, index, index, mem.rom.size, mem.rom.size);
|
||||||
@@ -80,12 +85,18 @@ auto PI::BusRead8(Mem& mem, u32 addr) -> u8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template auto PI::BusRead8<true>(Mem& mem, u32 addr) -> u8;
|
||||||
|
template auto PI::BusRead8<false>(Mem& mem, u32 addr) -> u8;
|
||||||
|
|
||||||
|
template<bool isDma>
|
||||||
void PI::BusWrite8(Mem& mem, u32 addr, u32 val) {
|
void PI::BusWrite8(Mem& mem, u32 addr, u32 val) {
|
||||||
|
if constexpr (!isDma) {
|
||||||
int latch_shift = 24 - (addr & 1) * 8;
|
int latch_shift = 24 - (addr & 1) * 8;
|
||||||
|
|
||||||
if (!WriteLatch(val << latch_shift) && addr != 0x05000020) [[unlikely]] {
|
if (!WriteLatch(val << latch_shift) && addr != 0x05000020) [[unlikely]] {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case REGION_PI_UNKNOWN:
|
case REGION_PI_UNKNOWN:
|
||||||
@@ -105,13 +116,16 @@ void PI::BusWrite8(Mem& mem, u32 addr, u32 val) {
|
|||||||
mem.BackupWrite8(addr - SREGION_PI_SRAM, val);
|
mem.BackupWrite8(addr - SREGION_PI_SRAM, val);
|
||||||
return;
|
return;
|
||||||
case REGION_PI_ROM:
|
case REGION_PI_ROM:
|
||||||
//Util::warn("Writing byte 0x{:02X} to address 0x{:08X} in unsupported region: REGION_PI_ROM", val, addr);
|
Util::warn("Writing byte 0x{:02X} to address 0x{:08X} in unsupported region: REGION_PI_ROM", val, addr);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
Util::panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr);
|
Util::panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template void PI::BusWrite8<true>(Mem& mem, u32 addr, u32 val);
|
||||||
|
template void PI::BusWrite8<false>(Mem& mem, u32 addr, u32 val);
|
||||||
|
|
||||||
auto PI::BusRead16(Mem& mem, u32 addr) -> u16 {
|
auto PI::BusRead16(Mem& mem, u32 addr) -> u16 {
|
||||||
if (!ReadLatch()) [[unlikely]] {
|
if (!ReadLatch()) [[unlikely]] {
|
||||||
return latch >> 16;
|
return latch >> 16;
|
||||||
@@ -133,8 +147,7 @@ auto PI::BusRead16(Mem& mem, u32 addr) -> u16 {
|
|||||||
addr = (addr + 2) & ~3;
|
addr = (addr + 2) & ~3;
|
||||||
u32 index = HALF_ADDRESS(addr) - SREGION_PI_ROM;
|
u32 index = HALF_ADDRESS(addr) - SREGION_PI_ROM;
|
||||||
if (index > mem.rom.size - 1) {
|
if (index > mem.rom.size - 1) {
|
||||||
//Util::warn("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM! ({}/0x{:016X})", addr, index, index, mem.rom.size, mem.rom.size);
|
Util::panic("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM!", addr, index, index);
|
||||||
return 0xFFFF;
|
|
||||||
}
|
}
|
||||||
return Util::ReadAccess<u16>(mem.rom.cart, index);
|
return Util::ReadAccess<u16>(mem.rom.cart, index);
|
||||||
}
|
}
|
||||||
@@ -185,7 +198,7 @@ auto PI::BusRead32(Mem& mem, u32 addr) -> u32 {
|
|||||||
//Util::warn("Reading word from address 0x{:08X} in unsupported region: REGION_PI_64DD_ROM - This is the N64DD, returning FF because it is not emulated", addr);
|
//Util::warn("Reading word from address 0x{:08X} in unsupported region: REGION_PI_64DD_ROM - This is the N64DD, returning FF because it is not emulated", addr);
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
case REGION_PI_SRAM:
|
case REGION_PI_SRAM:
|
||||||
return mem.BackupRead32(addr - SREGION_PI_SRAM);
|
return mem.BackupRead32();
|
||||||
case REGION_PI_ROM: {
|
case REGION_PI_ROM: {
|
||||||
u32 index = addr - SREGION_PI_ROM;
|
u32 index = addr - SREGION_PI_ROM;
|
||||||
if (index > mem.rom.size - 3) { // -3 because we're reading an entire word
|
if (index > mem.rom.size - 3) { // -3 because we're reading an entire word
|
||||||
@@ -401,7 +414,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
|||||||
}
|
}
|
||||||
rdLen = len;
|
rdLen = len;
|
||||||
for (int i = 0; i < rdLen; i++) {
|
for (int i = 0; i < rdLen; i++) {
|
||||||
mem.rom.cart[BYTE_ADDRESS(cartAddrInternal + i) & mem.rom.mask] = mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE];
|
BusWrite8<true>(mem, cartAddrInternal + i, mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE]);
|
||||||
}
|
}
|
||||||
Util::trace("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr);
|
Util::trace("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr);
|
||||||
dmaBusy = true;
|
dmaBusy = true;
|
||||||
@@ -417,7 +430,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
|||||||
}
|
}
|
||||||
wrLen = len;
|
wrLen = len;
|
||||||
for(int i = 0; i < wrLen; i++) {
|
for(int i = 0; i < wrLen; i++) {
|
||||||
mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE] = mem.rom.cart[BYTE_ADDRESS(cartAddrInternal + i) & mem.rom.mask];
|
mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE] = BusRead8<true>(mem, cartAddrInternal + i);
|
||||||
}
|
}
|
||||||
dmaBusy = true;
|
dmaBusy = true;
|
||||||
Util::trace("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr);
|
Util::trace("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr);
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ struct PI {
|
|||||||
void Reset();
|
void Reset();
|
||||||
auto Read(MI&, u32) const -> u32;
|
auto Read(MI&, u32) const -> u32;
|
||||||
void Write(Mem&, Registers&, u32, u32);
|
void Write(Mem&, Registers&, u32, u32);
|
||||||
|
template<bool isDma>
|
||||||
auto BusRead8(Mem&, u32) -> u8;
|
auto BusRead8(Mem&, u32) -> u8;
|
||||||
|
template<bool isDma>
|
||||||
void BusWrite8(Mem&, u32, u32);
|
void BusWrite8(Mem&, u32, u32);
|
||||||
auto BusRead16(Mem&, u32) -> u16;
|
auto BusRead16(Mem&, u32) -> u16;
|
||||||
void BusWrite16(Mem&, u32, u16);
|
void BusWrite16(Mem&, u32, u16);
|
||||||
|
|||||||
Reference in New Issue
Block a user