Fix PI DMA (fixes #108)
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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{};
|
||||||
|
|||||||
Reference in New Issue
Block a user