Fix PI DMA (fixes #108)

This commit is contained in:
SimoneN64
2023-11-08 23:05:34 +01:00
parent 2a77c1ab25
commit 91b0c33208
2 changed files with 25 additions and 14 deletions

View File

@@ -353,7 +353,7 @@ auto PI::Read(MI& mi, u32 addr) const -> u32 {
} }
} }
FORCE_INLINE u8 PIGetDomain(u32 address) { u8 PI::GetDomain(u32 address) {
switch (address) { switch (address) {
case REGION_PI_UNKNOWN: case REGION_PI_UNKNOWN:
case REGION_PI_64DD_ROM: case REGION_PI_64DD_ROM:
@@ -367,7 +367,7 @@ FORCE_INLINE u8 PIGetDomain(u32 address) {
} }
} }
FORCE_INLINE u32 PIAccessTiming(PI& pi, u8 domain, u32 length) { u32 PI::AccessTiming(u8 domain, u32 length) {
uint32_t cycles = 0; uint32_t cycles = 0;
uint32_t latency = 0; uint32_t latency = 0;
uint32_t pulse_width = 0; uint32_t pulse_width = 0;
@@ -377,16 +377,16 @@ FORCE_INLINE u32 PIAccessTiming(PI& pi, u8 domain, u32 length) {
switch (domain) { switch (domain) {
case 1: case 1:
latency = pi.pi_bsd_dom1_lat + 1; latency = pi_bsd_dom1_lat + 1;
pulse_width = pi.pi_bsd_dom1_pwd + 1; pulse_width = pi_bsd_dom1_pwd + 1;
release = pi.pi_bsd_dom1_rls + 1; release = pi_bsd_dom1_rls + 1;
page_size = std::pow(2, (pi.pi_bsd_dom1_pgs + 2)); page_size = std::pow(2, (pi_bsd_dom1_pgs + 2));
break; break;
case 2: case 2:
latency = pi.pi_bsd_dom2_lat + 1; latency = pi_bsd_dom2_lat + 1;
pulse_width = pi.pi_bsd_dom2_pwd + 1; pulse_width = pi_bsd_dom2_pwd + 1;
release = pi.pi_bsd_dom2_rls + 1; release = pi_bsd_dom2_rls + 1;
page_size = std::pow(2, (pi.pi_bsd_dom2_pgs + 2)); page_size = std::pow(2, (pi_bsd_dom2_pgs + 2));
break; break;
default: default:
Util::panic("Unknown PI domain: {}\n", domain); Util::panic("Unknown PI domain: {}\n", domain);
@@ -413,13 +413,16 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
len -= dramAddrInternal & 0x7; len -= dramAddrInternal & 0x7;
} }
rdLen = len; rdLen = len;
for (int i = 0; i < rdLen; i++) { if(dramAddrInternal >= 0x800000) {
Util::panic("PI DMA RDRAM->CART ADDRESS TOO HIGH");
}
for (int i = 0; i < len; i++) {
BusWrite8<true>(mem, cartAddrInternal + i, 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;
toCart = true; toCart = true;
scheduler.enqueueRelative(PIAccessTiming(*this, PIGetDomain(cartAddr), len), PI_DMA_COMPLETE); scheduler.enqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE);
} break; } break;
case 0x0460000C: { case 0x0460000C: {
u32 len = (val & 0x00FFFFFF) + 1; u32 len = (val & 0x00FFFFFF) + 1;
@@ -429,13 +432,18 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
len -= (dramAddrInternal & 0x7); len -= (dramAddrInternal & 0x7);
} }
wrLen = len; wrLen = len;
for(int i = 0; i < wrLen; i++) {
if(mem.saveType == SAVE_FLASH_1m && cartAddrInternal >= SREGION_PI_SRAM && cartAddrInternal < 0x08010000) {
cartAddrInternal = SREGION_PI_SRAM | ((cartAddrInternal & 0xFFFFF) << 1);
}
for(int i = 0; i < len; i++) {
mem.mmio.rdp.rdram[BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE] = BusRead8<true>(mem, cartAddrInternal + i); 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);
toCart = false; toCart = false;
scheduler.enqueueRelative(PIAccessTiming(*this, PIGetDomain(cartAddr), len), PI_DMA_COMPLETE); scheduler.enqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE);
} break; } break;
case 0x04600010: case 0x04600010:
if(val & 2) { if(val & 2) {

View File

@@ -24,6 +24,9 @@ struct PI {
void BusWrite64(Mem&, u32, u64); void BusWrite64(Mem&, u32, u64);
bool ReadLatch(); bool ReadLatch();
bool WriteLatch(u32 val); bool WriteLatch(u32 val);
static u8 GetDomain(u32 address);
u32 AccessTiming(u8 domain, u32 length);
bool dmaBusy{}, ioBusy{}, toCart{}; bool dmaBusy{}, ioBusy{}, toCart{};
u32 latch; u32 latch;
u32 dramAddr{}, cartAddr{}, dramAddrInternal{}, cartAddrInternal{}; u32 dramAddr{}, cartAddr{}, dramAddrInternal{}, cartAddrInternal{};