Slightly better PI DMA behaviour
This commit is contained in:
@@ -14,8 +14,6 @@ void PI::Reset() {
|
|||||||
latch = 0;
|
latch = 0;
|
||||||
dramAddr = 0;
|
dramAddr = 0;
|
||||||
cartAddr = 0;
|
cartAddr = 0;
|
||||||
dramAddrInternal = 0;
|
|
||||||
cartAddrInternal = 0;
|
|
||||||
rdLen = 0;
|
rdLen = 0;
|
||||||
wrLen = 0;
|
wrLen = 0;
|
||||||
piBsdDom1Lat = 0;
|
piBsdDom1Lat = 0;
|
||||||
@@ -271,7 +269,7 @@ template <> void PI::BusWrite<u32, false>(u32 addr, u32 val) {
|
|||||||
if (val < CART_ISVIEWER_SIZE) {
|
if (val < CART_ISVIEWER_SIZE) {
|
||||||
std::string message(val + 1, 0);
|
std::string message(val + 1, 0);
|
||||||
std::copy(mem.isviewer.begin(), mem.isviewer.begin() + val, message.begin());
|
std::copy(mem.isviewer.begin(), mem.isviewer.begin() + val, message.begin());
|
||||||
Util::always("{}", message);
|
Util::print<Util::Always>("{}", message);
|
||||||
} else {
|
} else {
|
||||||
Util::panic("ISViewer buffer size is emulated at {} bytes, but received a flush command for {} bytes!", CART_ISVIEWER_SIZE, val);
|
Util::panic("ISViewer buffer size is emulated at {} bytes, but received a flush command for {} bytes!", CART_ISVIEWER_SIZE, val);
|
||||||
}
|
}
|
||||||
@@ -353,10 +351,10 @@ template <> void PI::BusWrite<true>(u32 addr, u64 val) {
|
|||||||
|
|
||||||
auto PI::Read(u32 addr) const -> u32 {
|
auto PI::Read(u32 addr) const -> u32 {
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
case 0x04600000: return dramAddr;
|
case 0x04600000: return dramAddr & 0x00FFFFFE;
|
||||||
case 0x04600004: return cartAddr;
|
case 0x04600004: return cartAddr & 0xFFFFFFFE;
|
||||||
case 0x04600008: return rdLen;
|
case 0x04600008: return 0x7F;
|
||||||
case 0x0460000C: return wrLen;
|
case 0x0460000C: return 0x7F;
|
||||||
case 0x04600010: {
|
case 0x04600010: {
|
||||||
u32 value = 0;
|
u32 value = 0;
|
||||||
value |= (dmaBusy << 0); // Is PI DMA active? No, because it's instant
|
value |= (dmaBusy << 0); // Is PI DMA active? No, because it's instant
|
||||||
@@ -428,50 +426,56 @@ u32 PI::AccessTiming(u8 domain, u32 length) const {
|
|||||||
void PI::Write(u32 addr, u32 val) {
|
void PI::Write(u32 addr, u32 val) {
|
||||||
MI& mi = mem.mmio.mi;
|
MI& mi = mem.mmio.mi;
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
case 0x04600000: dramAddr = val & 0xFFFFFF; break;
|
case 0x04600000: dramAddr = val & 0x00FFFFFE; break;
|
||||||
case 0x04600004: cartAddr = val; break;
|
case 0x04600004: cartAddr = val & 0xFFFFFFFE; break;
|
||||||
case 0x04600008: {
|
case 0x04600008: {
|
||||||
u32 len = (val & 0x00FFFFFF) + 1;
|
rdLen = val & 0x00FFFFFF;
|
||||||
cartAddrInternal = cartAddr & 0xFFFFFFFE;
|
s32 len = val + 1;
|
||||||
dramAddrInternal = dramAddr & 0x007FFFFE;
|
|
||||||
if (dramAddrInternal & 0x7) {
|
s32 misalign = dramAddr & 7;
|
||||||
len -= dramAddrInternal & 0x7;
|
s32 distEndOfRow = 0x800-(dramAddr&0x7ff);
|
||||||
}
|
s32 blockLen = std::min(128-misalign, distEndOfRow);
|
||||||
rdLen = len;
|
s32 curLen = std::min(len, blockLen);
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
u32 addr = BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE;
|
u32 addr = BYTE_ADDRESS(dramAddr + i) & RDRAM_DSIZE;
|
||||||
if (addr < RDRAM_SIZE) {
|
if (addr < RDRAM_SIZE) {
|
||||||
BusWrite<u8, true>(cartAddrInternal + i, mem.mmio.rdp.rdram[addr]);
|
BusWrite<u8, true>(cartAddr + i, mem.mmio.rdp.rdram[addr]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BusWrite<u8, true>(cartAddrInternal + i, 0);
|
BusWrite<u8, true>(cartAddr + i, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dramAddr += len;
|
||||||
|
dramAddr = (dramAddr + 7) & ~7;
|
||||||
|
for(s32 i = 0; i < curLen; i+=2) cartAddr += 2;
|
||||||
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(AccessTiming(GetDomain(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;
|
wrLen = val & 0x00FFFFFF;
|
||||||
cartAddrInternal = cartAddr & 0xFFFFFFFE;
|
s32 len = wrLen + 1;
|
||||||
dramAddrInternal = dramAddr & 0x007FFFFE;
|
|
||||||
if (dramAddrInternal & 0x7) {
|
|
||||||
len -= (dramAddrInternal & 0x7);
|
|
||||||
}
|
|
||||||
wrLen = len;
|
|
||||||
|
|
||||||
if(mem.saveType == SAVE_FLASH_1m && cartAddrInternal >= SREGION_PI_SRAM && cartAddrInternal < 0x08010000) {
|
s32 misalign = dramAddr & 7;
|
||||||
cartAddrInternal = SREGION_PI_SRAM | ((cartAddrInternal & 0xFFFFF) << 1);
|
s32 distEndOfRow = 0x800-(dramAddr&0x7ff);
|
||||||
|
s32 blockLen = std::min(128-misalign, distEndOfRow);
|
||||||
|
s32 curLen = std::min(len, blockLen);
|
||||||
|
|
||||||
|
if(mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < 0x08010000) {
|
||||||
|
cartAddr = SREGION_PI_SRAM | ((cartAddr & 0xFFFFF) << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(u32 i = 0; i < len; i++) {
|
for(u32 i = 0; i < len; i++) {
|
||||||
u32 addr = BYTE_ADDRESS(dramAddrInternal + i) & RDRAM_DSIZE;
|
u32 addr = BYTE_ADDRESS(dramAddr + i) & RDRAM_DSIZE;
|
||||||
if (addr < RDRAM_SIZE) {
|
if (addr < RDRAM_SIZE) {
|
||||||
mem.mmio.rdp.rdram[addr] = BusRead<u8, true>(cartAddrInternal + i);
|
mem.mmio.rdp.rdram[addr] = BusRead<u8, true>(cartAddr + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dramAddr += len;
|
||||||
|
dramAddr = (dramAddr + 7) & ~7;
|
||||||
|
for(s32 i = 0; i < curLen; i+=2) cartAddr += 2;
|
||||||
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;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ struct PI {
|
|||||||
[[nodiscard]] u32 AccessTiming(u8 domain, u32 length) const;
|
[[nodiscard]] u32 AccessTiming(u8 domain, u32 length) const;
|
||||||
bool dmaBusy{}, ioBusy{}, toCart{};
|
bool dmaBusy{}, ioBusy{}, toCart{};
|
||||||
u32 latch{};
|
u32 latch{};
|
||||||
u32 dramAddr{}, cartAddr{}, dramAddrInternal{}, cartAddrInternal{};
|
u32 dramAddr{}, cartAddr{};
|
||||||
u32 rdLen{}, wrLen{};
|
u32 rdLen{}, wrLen{};
|
||||||
u32 piBsdDom1Lat{}, piBsdDom2Lat{};
|
u32 piBsdDom1Lat{}, piBsdDom2Lat{};
|
||||||
u32 piBsdDom1Pwd{}, piBsdDom2Pwd{};
|
u32 piBsdDom1Pwd{}, piBsdDom2Pwd{};
|
||||||
|
|||||||
Reference in New Issue
Block a user