Better separate DMA functions

This commit is contained in:
SimoneN64
2024-07-07 23:40:15 +02:00
parent cdbb251be1
commit 37a0cf6c77
4 changed files with 73 additions and 45 deletions

View File

@@ -9,7 +9,6 @@ PI::PI(Mem& mem, Registers& regs) : mem(mem), regs(regs) {
} }
void PI::Reset() { void PI::Reset() {
toCart = false;
dmaBusy = false; dmaBusy = false;
ioBusy = false; ioBusy = false;
latch = 0; latch = 0;
@@ -424,14 +423,14 @@ u32 PI::AccessTiming(u8 domain, u32 length) const {
return cycles * 1.5; // Converting RCP clock speed to CPU clock speed return cycles * 1.5; // Converting RCP clock speed to CPU clock speed
} }
void PI::Write(u32 addr, u32 val) { // rdram -> cart
MI& mi = mem.mmio.mi; template <> void PI::DMA<false>() {
switch(addr) { s32 len = rdLen + 1;
case 0x04600000: dramAddr = val & 0x00FFFFFC; break; Util::always("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr);
case 0x04600004: cartAddr = val & 0xFFFFFFFE; break;
case 0x04600008: { if(mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < 0x08010000) {
rdLen = val & 0x00FFFFFF; cartAddr = SREGION_PI_SRAM | ((cartAddr & 0xFFFFF) << 1);
s32 len = val + 1; }
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
BusWrite<u8, true>(cartAddr + i, mem.mmio.rdp.ReadRDRAM<u8>(dramAddr + i)); BusWrite<u8, true>(cartAddr + i, mem.mmio.rdp.ReadRDRAM<u8>(dramAddr + i));
@@ -440,14 +439,16 @@ void PI::Write(u32 addr, u32 val) {
dramAddr = (dramAddr + 7) & ~7; dramAddr = (dramAddr + 7) & ~7;
cartAddr += len; cartAddr += len;
if(cartAddr & 1) cartAddr += 1; if(cartAddr & 1) cartAddr += 1;
Util::trace("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr);
Util::always("Addresses after: Cart: 0x{:08X}, Dram: 0x{:08X}", cartAddr, dramAddr);
dmaBusy = true; dmaBusy = true;
toCart = true; scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), rdLen), PI_DMA_COMPLETE);
scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE); }
} break;
case 0x0460000C: { // cart -> rdram
wrLen = val & 0x00FFFFFF; template <> void PI::DMA<true>() {
s32 len = val + 1; s32 len = wrLen + 1;
Util::always("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr);
if(mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < 0x08010000) { if(mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < 0x08010000) {
cartAddr = SREGION_PI_SRAM | ((cartAddr & 0xFFFFF) << 1); cartAddr = SREGION_PI_SRAM | ((cartAddr & 0xFFFFF) << 1);
@@ -460,10 +461,26 @@ void PI::Write(u32 addr, u32 val) {
dramAddr = (dramAddr + 7) & ~7; dramAddr = (dramAddr + 7) & ~7;
cartAddr += len; cartAddr += len;
if(cartAddr & 1) cartAddr += 1; if(cartAddr & 1) cartAddr += 1;
mem.DumpRDRAM();
Util::always("Addresses after: Cart: 0x{:08X}, Dram: 0x{:08X}", cartAddr, dramAddr);
dmaBusy = true; dmaBusy = true;
Util::trace("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr);
toCart = false;
scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE); scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE);
}
void PI::Write(u32 addr, u32 val) {
MI& mi = mem.mmio.mi;
switch(addr) {
case 0x04600000: dramAddr = val & 0x00FFFFFC; break;
case 0x04600004: cartAddr = val & 0xFFFFFFFE; break;
case 0x04600008: {
rdLen = val & 0x00FFFFFF;
DMA<false>();
} break;
case 0x0460000C: {
wrLen = val & 0x00FFFFFF;
DMA<true>();
} break; } break;
case 0x04600010: case 0x04600010:
if(val & 2) { if(val & 2) {

View File

@@ -25,7 +25,7 @@ struct PI {
static u8 GetDomain(u32 address); static u8 GetDomain(u32 address);
[[nodiscard]] u32 AccessTiming(u8 domain, u32 length) const; [[nodiscard]] u32 AccessTiming(u8 domain, u32 length) const;
bool dmaBusy{}, ioBusy{}, toCart{}; bool dmaBusy{}, ioBusy{};
u32 latch{}; u32 latch{};
u32 dramAddr{}, cartAddr{}; u32 dramAddr{}, cartAddr{};
u32 rdLen{}, wrLen{}; u32 rdLen{}, wrLen{};
@@ -34,6 +34,9 @@ struct PI {
u32 piBsdDom1Pgs{}, piBsdDom2Pgs{}; u32 piBsdDom1Pgs{}, piBsdDom2Pgs{};
u32 piBsdDom1Rls{}, piBsdDom2Rls{}; u32 piBsdDom1Rls{}, piBsdDom2Rls{};
private: private:
template <bool toDram>
void DMA();
Mem& mem; Mem& mem;
Registers& regs; Registers& regs;
}; };

View File

@@ -33,21 +33,27 @@ auto SI::Read(u32 addr) const -> u32 {
} }
} }
void SI::DMA() { // pif -> rdram
status.dmaBusy = false; template <> void SI::DMA<true>() {
if (toDram) {
pif.ProcessCommands(mem); pif.ProcessCommands(mem);
for(int i = 0; i < 64; i++) { for(int i = 0; i < 64; i++) {
mem.mmio.rdp.WriteRDRAM<u8>(dramAddr + i, pif.Read(pifAddr + i)); mem.mmio.rdp.WriteRDRAM<u8>(dramAddr + i, pif.Read(pifAddr + i));
} }
Util::trace("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})", pifAddr, dramAddr); Util::trace("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})", pifAddr, dramAddr);
} else { }
// rdram -> pif
template <> void SI::DMA<false>() {
for(int i = 0; i < 64; i++) { for(int i = 0; i < 64; i++) {
pif.Write(pifAddr + i, mem.mmio.rdp.ReadRDRAM<u8>(dramAddr + i)); pif.Write(pifAddr + i, mem.mmio.rdp.ReadRDRAM<u8>(dramAddr + i));
} }
Util::trace("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})", dramAddr, pifAddr); Util::trace("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})", dramAddr, pifAddr);
pif.ProcessCommands(mem); }
}
void SI::DMA() {
status.dmaBusy = false;
if (toDram) DMA<true>();
else DMA<false>();
mem.mmio.mi.InterruptRaise(MI::Interrupt::SI); mem.mmio.mi.InterruptRaise(MI::Interrupt::SI);
} }

View File

@@ -29,6 +29,8 @@ struct SI {
auto Read(u32) const -> u32; auto Read(u32) const -> u32;
void Write(u32, u32); void Write(u32, u32);
template <bool toDram>
void DMA();
void DMA(); void DMA();
PIF pif; PIF pif;
private: private: