Better separate DMA functions
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user