Improve cartridge regions handling

This commit is contained in:
SimoneN64
2023-11-05 18:27:01 +01:00
parent b1f7659359
commit 4e6a3f2109
5 changed files with 381 additions and 117 deletions

View File

@@ -195,6 +195,8 @@ u8 Mem::Read8(n64::Registers &regs, u32 paddr) {
return mmio.rsp.dmem[BYTE_ADDRESS(mirrAddr)];
}
}
case REGION_CART:
return mmio.pi.BusRead8(*this, paddr);
case 0x04040000 ... 0x040FFFFF:
case 0x04100000 ... 0x041FFFFF:
case 0x04600000 ... 0x048FFFFF:
@@ -205,39 +207,15 @@ u8 Mem::Read8(n64::Registers &regs, u32 paddr) {
int offs = 3 - (paddr & 3);
return (w >> (offs * 8)) & 0xff;
}
case CART_REGION_1_2:
paddr = (paddr + 2) & ~2;
return rom.cart[BYTE_ADDRESS(paddr) & rom.mask];
case PIF_ROM_REGION:
return si.pif.bootrom[BYTE_ADDRESS(paddr) - PIF_ROM_REGION_START];
case PIF_RAM_REGION:
return si.pif.ram[paddr - PIF_RAM_REGION_START];
case 0x00800000 ... 0x03FFFFFF: // unused
case 0x04200000 ... 0x042FFFFF: // unused
case 0x04900000 ... 0x07FFFFFF: // unused
case 0x04900000 ... 0x04FFFFFF: // unused
case 0x1FC00800 ... 0xFFFFFFFF: // unused
return 0;
case CART_REGION_2_2:
switch (saveType) {
case SAVE_NONE:
Util::panic("Accessing cartridge backup with save type SAVE_NONE");
break;
case SAVE_EEPROM_4k:
case SAVE_EEPROM_16k:
Util::panic("Accessing cartridge backup with save type SAVE_EEPROM");
break;
case SAVE_FLASH_1m:
if(flash.flash.is_open()) {
return flash.Read8(paddr - CART_REGION_START_2_2);
} else {
Util::panic("Invalid backup Write8 if save data is not initialized");
}
case SAVE_SRAM_256k:
if(sram.is_open()) {
return sram[paddr - CART_REGION_START_2_2];
}
}
break;
default:
Util::panic("Unimplemented 8-bit read at address {:08X} (PC = {:016X})", paddr, (u64) regs.pc);
}
@@ -267,16 +245,15 @@ u16 Mem::Read16(n64::Registers &regs, u32 paddr) {
}
case MMIO_REGION:
return mmio.Read(paddr);
case CART_REGION_1_2:
paddr = (paddr + 2) & ~3;
return Util::ReadAccess<u16>(rom.cart, HALF_ADDRESS(paddr) & rom.mask);
case REGION_CART:
return mmio.pi.BusRead16(*this, paddr);
case PIF_ROM_REGION:
return Util::ReadAccess<u16>(si.pif.bootrom, HALF_ADDRESS(paddr) - PIF_ROM_REGION_START);
case PIF_RAM_REGION:
return be16toh(Util::ReadAccess<u16>(si.pif.ram, paddr - PIF_RAM_REGION_START));
case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x0FFFFFFF:
case 0x04900000 ... 0x04FFFFFF:
case 0x1FC00800 ... 0xFFFFFFFF:
return 0;
default:
@@ -308,24 +285,14 @@ u32 Mem::Read32(n64::Registers &regs, u32 paddr) {
}
case MMIO_REGION:
return mmio.Read(paddr);
case CART_REGION_1_2:
return Util::ReadAccess<u32>(rom.cart, paddr & rom.mask);
case CART_REGION_2_2:
if(saveType == SAVE_NONE) {
return 0;
} else if (saveType == SAVE_SRAM_256k) {
return 0xffff'ffff;
} else if (saveType == SAVE_FLASH_1m) {
return flash.Read32(paddr - CART_REGION_START_2_2);
} else {
Util::panic("Cartridge backup Read32 with unknown save type!");
}
case REGION_CART:
return mmio.pi.BusRead32(*this, paddr);
case PIF_ROM_REGION:
return Util::ReadAccess<u32>(si.pif.bootrom, paddr - PIF_ROM_REGION_START);
case PIF_RAM_REGION:
return be32toh(Util::ReadAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START));
case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x07FFFFFF: case 0x1FC00800 ... 0xFFFFFFFF: return 0;
case 0x04900000 ... 0x04FFFFFF: case 0x1FC00800 ... 0xFFFFFFFF: return 0;
default:
Util::panic("Unimplemented 32-bit read at address {:08X} (PC = {:016X})", paddr, (u64) regs.pc);
}
@@ -355,15 +322,15 @@ u64 Mem::Read64(n64::Registers &regs, u32 paddr) {
}
case MMIO_REGION:
return mmio.Read(paddr);
case CART_REGION_1_2:
return Util::ReadAccess<u64>(rom.cart, paddr & rom.mask);
case REGION_CART:
return mmio.pi.BusRead64(*this, paddr);
case PIF_ROM_REGION:
return Util::ReadAccess<u64>(si.pif.bootrom, paddr - PIF_ROM_REGION_START);
case PIF_RAM_REGION:
return be64toh(Util::ReadAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START));
case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x0FFFFFFF:
case 0x04900000 ... 0x04FFFFFF:
case 0x1FC00800 ... 0xFFFFFFFF:
return 0;
default:
@@ -397,7 +364,8 @@ void Mem::Write8(Registers& regs, u32 paddr, u32 val) {
} break;
case MMIO_REGION:
Util::panic("MMIO Write8!");
case CART_REGION_1_2:
case REGION_CART:
mmio.pi.BusWrite8(*this, paddr, val);
break;
case PIF_RAM_REGION:
val = val << (8 * (3 - (paddr & 3)));
@@ -405,32 +373,9 @@ void Mem::Write8(Registers& regs, u32 paddr, u32 val) {
Util::WriteAccess<u32>(si.pif.ram, paddr, htobe32(val));
si.pif.ProcessCommands(*this);
break;
case CART_REGION_2_2:
switch (saveType) {
case SAVE_NONE:
Util::panic("Accessing cartridge backup with save type SAVE_NONE");
break;
case SAVE_EEPROM_4k:
case SAVE_EEPROM_16k:
Util::panic("Accessing cartridge backup with save type SAVE_EEPROM");
break;
case SAVE_FLASH_1m:
if(flash.flash.is_open()) {
flash.Write8(paddr - CART_REGION_START_2_2, val);
} else {
Util::panic("Invalid backup Write8 if save data is not initialized");
}
break;
case SAVE_SRAM_256k:
if(sram.is_open()) {
sram[paddr - CART_REGION_START_2_2] = val;
}
break;
}
break;
case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x07FFFFFF:
case 0x04900000 ... 0x04FFFFFF:
case PIF_ROM_REGION:
case 0x1FC00800 ... 0x7FFFFFFF:
case 0x80000000 ... 0xFFFFFFFF:
@@ -467,19 +412,18 @@ void Mem::Write16(Registers& regs, u32 paddr, u32 val) {
} break;
case MMIO_REGION:
Util::panic("MMIO Write16!");
case CART_REGION_1_2:
break;
case PIF_RAM_REGION:
val = val << (16 * !(paddr & 2));
paddr &= ~3;
Util::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe32(val));
si.pif.ProcessCommands(*this);
break;
case CART_REGION_2_2:
Util::panic("Backup Write16!");
case REGION_CART:
mmio.pi.BusWrite16(*this, paddr, val);
break;
case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x07FFFFFF:
case 0x04900000 ... 0x04FFFFFF:
case PIF_ROM_REGION:
case 0x1FC00800 ... 0x7FFFFFFF:
case 0x80000000 ... 0xFFFFFFFF:
@@ -515,42 +459,18 @@ void Mem::Write32(Registers& regs, u32 paddr, u32 val) {
case MMIO_REGION:
mmio.Write(*this, regs, paddr, val);
break;
case 0x10000000 ... 0x13FF0013: break;
case 0x13FF0014: {
if(val < ISVIEWER_SIZE) {
char* message = (char*)calloc(val + 1, 1);
memcpy(message, isviewer, val);
fmt::print("{}", message);
free(message);
}
} break;
case 0x13FF0020 ... 0x13FFFFFF:
Util::WriteAccess<u32>(isviewer, paddr - 0x13FF0020, htobe32(val));
break;
case 0x14000000 ... 0x1FBFFFFF: break;
case PIF_RAM_REGION:
Util::WriteAccess<u32>(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe32(val));
si.pif.ProcessCommands(*this);
break;
case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x07FFFFFF:
case 0x04900000 ... 0x04FFFFFF:
case PIF_ROM_REGION:
case 0x1FC00800 ... 0x7FFFFFFF:
case 0x80000000 ... 0xFFFFFFFF: break;
case CART_REGION_2_2:
if (saveType == SAVE_FLASH_1m) {
if(flash.flash.is_open()) {
flash.Write32(paddr - CART_REGION_START_2_2, val);
} else {
Util::panic("Invalid write to cartridge backup if save data is not initialized!");
}
} else if (saveType == SAVE_SRAM_256k) {
break;
} else {
Util::panic("Invalid cartridge backup Write32 with save type {} (addr {:08X})", static_cast<int>(saveType),
paddr);
}
case REGION_CART:
mmio.pi.BusWrite32(*this, paddr, val);
break;
default: Util::panic("Unimplemented 32-bit write at address {:08X} with value {:0X} (PC = {:016X})", paddr, val, (u64)regs.pc);
}
@@ -581,20 +501,19 @@ void Mem::Write64(Registers& regs, u32 paddr, u64 val) {
} break;
case MMIO_REGION:
Util::panic("MMIO Write64!");
case CART_REGION_1_2:
break;
case PIF_RAM_REGION:
Util::WriteAccess<u64>(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe64(val));
si.pif.ProcessCommands(*this);
break;
case REGION_CART:
mmio.pi.BusWrite64(*this, paddr, val);
break;
case 0x00800000 ... 0x03FFFFFF:
case 0x04200000 ... 0x042FFFFF:
case 0x04900000 ... 0x07FFFFFF:
case 0x04900000 ... 0x04FFFFFF:
case 0x1FC00000 ... 0x1FC007BF:
case 0x1FC00800 ... 0x7FFFFFFF:
case 0x80000000 ... 0xFFFFFFFF: break;
case CART_REGION_2_2:
Util::panic("Backup Write64!");
default:
Util::panic("Unimplemented 64-bit write at address {:08X} with value {:0X} (PC = {:016X})", paddr, val,
(u64) regs.pc);
@@ -602,6 +521,93 @@ void Mem::Write64(Registers& regs, u32 paddr, u64 val) {
}
}
u32 Mem::BackupRead32(u32 addr) {
switch(saveType) {
case SAVE_NONE: return 0;
case SAVE_EEPROM_4k: case SAVE_EEPROM_16k:
Util::warn("Accessing cartridge backup type SAVE_EEPROM, returning 0 for word read");
return 0;
case SAVE_FLASH_1m:
if(flash.flash.is_open()) {
return flash.Read32(addr);
} else {
Util::panic("Invalid backup Read32 if save data is not initialized");
}
case SAVE_SRAM_256k:
return 0xFFFFFFFF;
default:
Util::panic("Backup read word with unknown save type");
}
}
void Mem::BackupWrite32(u32 addr, u32 val) {
switch(saveType) {
case SAVE_NONE:
Util::panic("Accessing cartridge with save type SAVE_NONE in write word");
case SAVE_EEPROM_4k: case SAVE_EEPROM_16k:
Util::panic("Accessing cartridge with save type SAVE_EEPROM in write word");
case SAVE_FLASH_1m:
if(flash.flash.is_open()) {
flash.Write32(addr, val);
} else {
Util::panic("Invalid backup Write32 if save data is not initialized");
}
break;
case SAVE_SRAM_256k:
break;
default:
Util::panic("Backup read word with unknown save type");
}
}
u8 Mem::BackupRead8(u32 addr) {
switch(saveType) {
case SAVE_NONE: return 0;
case SAVE_EEPROM_4k: case SAVE_EEPROM_16k:
Util::warn("Accessing cartridge backup type SAVE_EEPROM, returning 0 for word read");
return 0;
case SAVE_FLASH_1m:
if(flash.flash.is_open()) {
return flash.Read8(addr);
} else {
Util::panic("Invalid backup Read8 if save data is not initialized");
}
case SAVE_SRAM_256k:
if(sram.is_open()) {
return sram[addr & 0x8000];
} else {
Util::panic("Invalid backup Read8 if save data is not initialized");
}
default:
Util::panic("Backup read word with unknown save type");
}
}
void Mem::BackupWrite8(u32 addr, u8 val) {
switch(saveType) {
case SAVE_NONE:
Util::panic("Accessing cartridge with save type SAVE_NONE in write word");
case SAVE_EEPROM_4k: case SAVE_EEPROM_16k:
Util::panic("Accessing cartridge with save type SAVE_EEPROM in write word");
case SAVE_FLASH_1m:
if(flash.flash.is_open()) {
flash.Write8(addr, val);
} else {
Util::panic("Invalid backup Write8 if save data is not initialized");
}
break;
case SAVE_SRAM_256k:
if(sram.is_open()) {
sram[addr & 0x8000] = val;
} else {
Util::panic("Invalid backup Write8 if save data is not initialized");
}
break;
default:
Util::panic("Backup read word with unknown save type");
}
}
std::vector<u8> Mem::Serialize() {
std::vector<u8> res{};

View File

@@ -192,6 +192,11 @@ struct Mem {
void Write32(Registers&, u32, u32);
void Write64(Registers&, u32, u64);
u32 BackupRead32(u32);
void BackupWrite32(u32, u32);
u8 BackupRead8(u32);
void BackupWrite8(u32, u8);
MMIO mmio;
FORCE_INLINE void DumpRDRAM() const {

View File

@@ -16,6 +16,230 @@ void PI::Reset() {
wrLen = 0;
}
auto PI::BusRead8(Mem& mem, u32 addr) const -> u8 {
// TODO: Latch with CPU stall
switch (addr) {
case REGION_PI_UNKNOWN:
Util::warn("Reading byte from address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN - This is the N64DD, returning FF because it is not emulated", addr);
return 0xFF;
case REGION_PI_64DD_REG:
Util::warn("Reading byte from address 0x{:08X} in unsupported region: REGION_PI_64DD_REG - This is the N64DD, returning FF because it is not emulated", addr);
return 0xFF;
case REGION_PI_64DD_ROM:
Util::warn("Reading byte 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;
case REGION_PI_SRAM:
return mem.BackupRead8(addr - SREGION_PI_SRAM);
case REGION_PI_ROM: {
// round to nearest 4 byte boundary, keeping old LSB
addr = (addr + 2) & ~2;
u32 index = BYTE_ADDRESS(addr) - SREGION_PI_ROM;
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);
return 0xFF;
}
return mem.rom.cart[index];
}
default:
Util::panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr);
}
}
void PI::BusWrite8(Mem& mem, u32 addr, u32 val) {
switch (addr) {
case REGION_PI_UNKNOWN:
Util::warn("Writing byte 0x{:02X} to address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN", val, addr);
return;
case REGION_PI_64DD_REG:
if (addr == 0x05000020) {
fprintf(stderr, "%c", val);
} else {
Util::warn("Writing byte 0x{:02X} to address 0x{:08X} in region: REGION_PI_64DD_ROM, this is the 64DD, ignoring!", val, addr);
}
return;
case REGION_PI_64DD_ROM:
Util::warn("Writing byte 0x{:02X} to address 0x{:08X} in unsupported region: REGION_PI_64DD_ROM", val, addr);
return;
case REGION_PI_SRAM:
mem.BackupWrite8(addr - SREGION_PI_SRAM, val);
return;
case REGION_PI_ROM:
Util::warn("Writing byte 0x{:02X} to address 0x{:08X} in unsupported region: REGION_PI_ROM", val, addr);
return;
default:
Util::panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr);
}
}
auto PI::BusRead16(Mem& mem, u32 addr) const -> u16 {
// TODO: Latch with CPU stall
switch (addr) {
case REGION_PI_UNKNOWN:
Util::warn("Reading half from address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN - This is the N64DD, returning FF because it is not emulated", addr);
return 0xFF;
case REGION_PI_64DD_REG:
Util::warn("Reading half from address 0x{:08X} in unsupported region: REGION_PI_64DD_REG - This is the N64DD, returning FF because it is not emulated", addr);
return 0xFF;
case REGION_PI_64DD_ROM:
Util::warn("Reading half 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;
case REGION_PI_SRAM:
Util::panic("Reading half from address 0x{:08X} in unsupported region: REGION_PI_SRAM", addr);
case REGION_PI_ROM: {
// round to nearest 4 byte boundary, keeping old LSB
addr = (addr + 2) & ~3;
u32 index = HALF_ADDRESS(addr) - SREGION_PI_ROM;
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);
return 0xFFFF;
}
return Util::ReadAccess<u16>(mem.rom.cart, index);
}
default:
Util::panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr);
}
}
void PI::BusWrite16(Mem& mem, u32 addr, u16 val) {
switch (addr) {
case REGION_PI_UNKNOWN:
Util::warn("Writing half 0x{:04X} to address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN", val, addr);
return;
case REGION_PI_64DD_REG:
Util::warn("Writing half 0x{:04X} to address 0x{:08X} in region: REGION_PI_64DD_ROM, this is the 64DD, ignoring!", val, addr);
return;
case REGION_PI_64DD_ROM:
Util::warn("Writing half 0x{:04X} to address 0x{:08X} in unsupported region: REGION_PI_64DD_ROM", val, addr);
return;
case REGION_PI_SRAM:
Util::warn("Writing half 0x{:04X} to address 0x{:08X} in unsupported region: REGION_PI_SRAM", val, addr);
return;
case REGION_PI_ROM:
Util::warn("Writing half 0x{:04X} to address 0x{:08X} in unsupported region: REGION_PI_ROM", val, addr);
return;
default:
Util::panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr);
}
}
auto PI::BusRead32(Mem& mem, u32 addr) const -> u32 {
// TODO: Latch with CPU stall
switch (addr) {
case REGION_PI_UNKNOWN:
Util::warn("Reading word from address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN - This is the N64DD, returning FF because it is not emulated", addr);
return 0xFF;
case REGION_PI_64DD_REG:
Util::warn("Reading word from address 0x{:08X} in unsupported region: REGION_PI_64DD_REG - This is the N64DD, returning FF because it is not emulated", addr);
return 0xFF;
case REGION_PI_64DD_ROM:
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;
case REGION_PI_SRAM:
return mem.BackupRead32(addr - SREGION_PI_SRAM);
case REGION_PI_ROM: {
u32 index = addr - SREGION_PI_ROM;
if (index > mem.rom.size - 3) { // -3 because we're reading an entire word
switch (addr) {
case REGION_CART_ISVIEWER_BUFFER:
return htobe32(Util::ReadAccess<u32>(mem.isviewer, addr - SREGION_CART_ISVIEWER_BUFFER));
case CART_ISVIEWER_FLUSH:
Util::panic("Read from ISViewer flush!");
}
Util::warn("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM!", addr, index, index);
return 0;
} else {
return Util::ReadAccess<u32>(mem.rom.cart, index);
}
}
default:
Util::panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr);
}
}
void PI::BusWrite32(Mem& mem, u32 addr, u32 val) {
switch (addr) {
case REGION_PI_UNKNOWN:
Util::warn("Writing word 0x{:08X} to address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN", val, addr);
return;
case REGION_PI_64DD_REG:
Util::warn("Writing word 0x{:08X} to address 0x{:08X} in region: REGION_PI_64DD_ROM, this is the 64DD, ignoring!", val, addr);
return;
case REGION_PI_64DD_ROM:
Util::warn("Writing word 0x{:08X} to address 0x{:08X} in unsupported region: REGION_PI_64DD_ROM", val, addr);
return;
case REGION_PI_SRAM:
mem.BackupWrite32(addr - SREGION_PI_SRAM, val);
return;
case REGION_PI_ROM:
switch (addr) {
case REGION_CART_ISVIEWER_BUFFER:
Util::WriteAccess<u32>(mem.isviewer, addr - SREGION_CART_ISVIEWER_BUFFER, be32toh(val));
break;
case CART_ISVIEWER_FLUSH: {
if (val < CART_ISVIEWER_SIZE) {
char* message = (char*)malloc(val + 1);
memcpy(message, mem.isviewer, val);
message[val] = '\0';
printf("%s", message);
free(message);
} else {
Util::panic("ISViewer buffer size is emulated at {} bytes, but received a flush command for {} bytes!", CART_ISVIEWER_SIZE, val);
}
break;
}
default:
Util::warn("Writing word 0x{:08X} to address 0x{:08X} in unsupported region: REGION_PI_ROM", val, addr);
}
return;
default:
Util::panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr);
}
}
auto PI::BusRead64(Mem& mem, u32 addr) const -> u64 {
switch (addr) {
case REGION_PI_UNKNOWN:
Util::warn("Reading dword from address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN", addr);
return 0xFFFFFFFFFFFFFFFF;
case REGION_PI_64DD_REG:
Util::warn("Reading dword from address 0x{:08X} in unsupported region: REGION_PI_64DD_REG", addr);
return 0xFFFFFFFFFFFFFFFF;
case REGION_PI_64DD_ROM:
Util::warn("Reading dword from address 0x{:08X} in unsupported region: REGION_PI_64DD_ROM", addr);
return 0xFFFFFFFFFFFFFFFF;
case REGION_PI_SRAM:
Util::warn("Reading dword from address 0x{:08X} in unsupported region: REGION_PI_SRAM", addr);
return 0xFFFFFFFFFFFFFFFF;
case REGION_PI_ROM: {
u32 index = addr - SREGION_PI_ROM;
if (index > mem.rom.size - 7) { // -7 because we're reading an entire dword
Util::panic("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM!", addr, index, index);
}
return Util::ReadAccess<u64>(mem.rom.cart, index);
}
default:
Util::panic("Should never end up here! Access to address {:08X} which did not match any PI bus regions!", addr);
}
}
void PI::BusWrite64(Mem& mem, u32 addr, u64 val) {
switch (addr) {
case REGION_PI_UNKNOWN:
Util::panic("Writing dword 0x{:016X} to address 0x{:08X} in unsupported region: REGION_PI_UNKNOWN", val, addr);
case REGION_PI_64DD_REG:
Util::panic("Writing dword 0x{:016X} to address 0x{:08X} in unsupported region: REGION_PI_64DD_REG", val, addr);
case REGION_PI_64DD_ROM:
Util::panic("Writing dword 0x{:016X} to address 0x{:08X} in unsupported region: REGION_PI_64DD_ROM", val, addr);
case REGION_PI_SRAM:
Util::panic("Writing dword 0x{:016X} to address 0x{:08X} in unsupported region: REGION_PI_SRAM", val, addr);
case REGION_PI_ROM:
Util::warn("Writing dword 0x{:016X} to address 0x{:08X} in unsupported region: REGION_PI_ROM", val, addr);
break;
default:
Util::panic("Should never end up here! Access to address %08X which did not match any PI bus regions!", addr);
}
}
auto PI::Read(MI& mi, u32 addr) const -> u32 {
switch(addr) {
case 0x04600000: return dramAddr;
@@ -45,12 +269,12 @@ auto PI::Read(MI& mi, u32 addr) const -> u32 {
FORCE_INLINE u8 PIGetDomain(u32 address) {
switch (address) {
case 0x00000000 ... 0x04FFFFFF:
case CART_REGION_1_1:
case 0x10000000 ... 0xFFFFFFFF:
case REGION_PI_UNKNOWN:
case REGION_PI_64DD_ROM:
case REGION_PI_ROM:
return 1;
case CART_REGION_2_1:
case CART_REGION_2_2:
case REGION_PI_64DD_REG:
case REGION_PI_SRAM:
return 2;
default:
Util::panic("Unknown PI domain for address {:08X}!", address);
@@ -79,7 +303,7 @@ FORCE_INLINE u32 PIAccessTiming(PI& pi, u8 domain, u32 length) {
page_size = std::pow(2, (pi.pi_bsd_dom2_pgs + 2));
break;
default:
Util::panic("Unknown PI domain: %d\n", domain);
Util::panic("Unknown PI domain: {}\n", domain);
}
pages = ceil((double)length / page_size);

View File

@@ -12,6 +12,14 @@ struct PI {
void Reset();
auto Read(MI&, u32) const -> u32;
void Write(Mem&, Registers&, u32, u32);
auto BusRead8(Mem&, u32) const -> u8;
void BusWrite8(Mem&, u32, u32);
auto BusRead16(Mem&, u32) const -> u16;
void BusWrite16(Mem&, u32, u16);
auto BusRead32(Mem&, u32) const -> u32;
void BusWrite32(Mem&, u32, u32);
auto BusRead64(Mem&, u32) const -> u64;
void BusWrite64(Mem&, u32, u64);
bool dmaBusy{}, ioBusy{};
u32 dramAddr{}, cartAddr{}, dramAddrInternal{}, cartAddrInternal{};
u32 rdLen{}, wrLen{};