Also for RSP, oops
This commit is contained in:
@@ -111,17 +111,75 @@ void RSP::WriteStatus(u32 value) {
|
|||||||
CLEAR_SET(spStatus.signal7, write.clearSignal7, write.setSignal7);
|
CLEAR_SET(spStatus.signal7, write.clearSignal7, write.setSignal7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <> void RSP::DMA<true>() {
|
||||||
|
u32 length = spDMALen.len + 1;
|
||||||
|
|
||||||
|
length = (length + 0x7) & ~0x7;
|
||||||
|
|
||||||
|
std::array<u8, DMEM_SIZE>& src = spDMASPAddr.bank ? imem : dmem;
|
||||||
|
|
||||||
|
u32 mem_address = spDMASPAddr.address & 0xFF8;
|
||||||
|
u32 dram_address = spDMADRAMAddr.address & 0xFFFFF8;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < spDMALen.count + 1; i++) {
|
||||||
|
for(u32 j = 0; j < length; j++) {
|
||||||
|
mem.mmio.rdp.WriteRDRAM<u8>(BYTE_ADDRESS(dram_address + j), src[(mem_address + j) & DMEM_DSIZE]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int skip = i == spDMALen.count ? 0 : spDMALen.skip;
|
||||||
|
|
||||||
|
dram_address += (length + skip);
|
||||||
|
dram_address &= 0xFFFFF8;
|
||||||
|
mem_address += length;
|
||||||
|
mem_address &= 0xFF8;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastSuccessfulSPAddr.address = mem_address;
|
||||||
|
lastSuccessfulSPAddr.bank = spDMASPAddr.bank;
|
||||||
|
lastSuccessfulDRAMAddr.address = dram_address;
|
||||||
|
spDMALen.raw = 0xFF8 | (spDMALen.skip << 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> void RSP::DMA<false>() {
|
||||||
|
u32 length = spDMALen.len + 1;
|
||||||
|
|
||||||
|
length = (length + 0x7) & ~0x7;
|
||||||
|
|
||||||
|
std::array<u8, DMEM_SIZE>& dst = spDMASPAddr.bank ? imem : dmem;
|
||||||
|
|
||||||
|
u32 mem_address = spDMASPAddr.address & 0xFF8;
|
||||||
|
u32 dram_address = spDMADRAMAddr.address & 0xFFFFF8;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < spDMALen.count + 1; i++) {
|
||||||
|
for(u32 j = 0; j < length; j++) {
|
||||||
|
dst[(mem_address + j) & DMEM_DSIZE] = mem.mmio.rdp.ReadRDRAM<u8>(BYTE_ADDRESS(dram_address + j));
|
||||||
|
}
|
||||||
|
|
||||||
|
int skip = i == spDMALen.count ? 0 : spDMALen.skip;
|
||||||
|
|
||||||
|
dram_address += (length + skip);
|
||||||
|
dram_address &= 0xFFFFF8;
|
||||||
|
mem_address += length;
|
||||||
|
mem_address &= 0xFF8;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastSuccessfulSPAddr.address = mem_address;
|
||||||
|
lastSuccessfulSPAddr.bank = spDMASPAddr.bank;
|
||||||
|
lastSuccessfulDRAMAddr.address = dram_address;
|
||||||
|
spDMALen.raw = 0xFF8 | (spDMALen.skip << 20);
|
||||||
|
}
|
||||||
|
|
||||||
void RSP::Write(u32 addr, u32 val) {
|
void RSP::Write(u32 addr, u32 val) {
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case 0x04040000: spDMASPAddr.raw = val & 0x1FF8; break;
|
case 0x04040000: spDMASPAddr.raw = val & 0x1FF8; break;
|
||||||
case 0x04040004: spDMADRAMAddr.raw = val & 0xFFFFF8; break;
|
case 0x04040004: spDMADRAMAddr.raw = val & 0xFFFFF8; break;
|
||||||
case 0x04040008: {
|
case 0x04040008: {
|
||||||
spDMALen.raw = val;
|
spDMALen.raw = val;
|
||||||
DMAtoRSP(mem.GetRDRAM());
|
DMA<false>();
|
||||||
} break;
|
} break;
|
||||||
case 0x0404000C: {
|
case 0x0404000C: {
|
||||||
spDMALen.raw = val;
|
spDMALen.raw = val;
|
||||||
DMAtoRDRAM(mem.GetRDRAM());
|
DMA<true>();
|
||||||
} break;
|
} break;
|
||||||
case 0x04040010: WriteStatus(val); break;
|
case 0x04040010: WriteStatus(val); break;
|
||||||
case 0x0404001C: ReleaseSemaphore(); break;
|
case 0x0404001C: ReleaseSemaphore(); break;
|
||||||
@@ -133,70 +191,4 @@ void RSP::Write(u32 addr, u32 val) {
|
|||||||
Util::panic("Unimplemented SP register write {:08X}, val: {:08X}", addr, val);
|
Util::panic("Unimplemented SP register write {:08X}, val: {:08X}", addr, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSP::DMAtoRDRAM(std::vector<u8>& rdram) {
|
|
||||||
u32 length = spDMALen.len + 1;
|
|
||||||
|
|
||||||
length = (length + 0x7) & ~0x7;
|
|
||||||
|
|
||||||
std::vector<u8>& dst = rdram;
|
|
||||||
std::array<u8, DMEM_SIZE>& src = spDMASPAddr.bank ? imem : dmem;
|
|
||||||
|
|
||||||
u32 mem_address = spDMASPAddr.address & 0xFF8;
|
|
||||||
u32 dram_address = spDMADRAMAddr.address & 0xFFFFF8;
|
|
||||||
|
|
||||||
for (u32 i = 0; i < spDMALen.count + 1; i++) {
|
|
||||||
for(u32 j = 0; j < length; j++) {
|
|
||||||
if((dram_address + j) < RDRAM_SIZE) {
|
|
||||||
dst[dram_address + j] = src[(mem_address + j) & DMEM_DSIZE];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int skip = i == spDMALen.count ? 0 : spDMALen.skip;
|
|
||||||
|
|
||||||
dram_address += (length + skip);
|
|
||||||
dram_address &= 0xFFFFF8;
|
|
||||||
mem_address += length;
|
|
||||||
mem_address &= 0xFF8;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastSuccessfulSPAddr.address = mem_address;
|
|
||||||
lastSuccessfulSPAddr.bank = spDMASPAddr.bank;
|
|
||||||
lastSuccessfulDRAMAddr.address = dram_address;
|
|
||||||
spDMALen.raw = 0xFF8 | (spDMALen.skip << 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RSP::DMAtoRSP(std::vector<u8>& rdram) {
|
|
||||||
u32 length = spDMALen.len + 1;
|
|
||||||
|
|
||||||
length = (length + 0x7) & ~0x7;
|
|
||||||
|
|
||||||
std::vector<u8>& src = rdram;
|
|
||||||
std::array<u8, DMEM_SIZE>& dst = spDMASPAddr.bank ? imem : dmem;
|
|
||||||
|
|
||||||
u32 mem_address = spDMASPAddr.address & 0xFF8;
|
|
||||||
u32 dram_address = spDMADRAMAddr.address & 0xFFFFF8;
|
|
||||||
|
|
||||||
for (u32 i = 0; i < spDMALen.count + 1; i++) {
|
|
||||||
for(u32 j = 0; j < length; j++) {
|
|
||||||
if((dram_address + j) < RDRAM_SIZE) {
|
|
||||||
dst[(mem_address + j) & DMEM_DSIZE] = src[dram_address + j];
|
|
||||||
} else {
|
|
||||||
dst[(mem_address + j) & DMEM_DSIZE] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int skip = i == spDMALen.count ? 0 : spDMALen.skip;
|
|
||||||
|
|
||||||
dram_address += (length + skip);
|
|
||||||
dram_address &= 0xFFFFF8;
|
|
||||||
mem_address += length;
|
|
||||||
mem_address &= 0xFF8;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastSuccessfulSPAddr.address = mem_address;
|
|
||||||
lastSuccessfulSPAddr.bank = spDMASPAddr.bank;
|
|
||||||
lastSuccessfulDRAMAddr.address = dram_address;
|
|
||||||
spDMALen.raw = 0xFF8 | (spDMALen.skip << 20);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -357,8 +357,8 @@ struct RSP {
|
|||||||
void mfc2(u32 instr);
|
void mfc2(u32 instr);
|
||||||
void mtc2(u32 instr);
|
void mtc2(u32 instr);
|
||||||
|
|
||||||
void DMAtoRDRAM(std::vector<u8>& rdram);
|
template <bool toRdram>
|
||||||
void DMAtoRSP(std::vector<u8>& rdram);
|
void DMA();
|
||||||
void WriteStatus(u32 value);
|
void WriteStatus(u32 value);
|
||||||
private:
|
private:
|
||||||
Registers& regs;
|
Registers& regs;
|
||||||
|
|||||||
@@ -426,7 +426,7 @@ u32 PI::AccessTiming(u8 domain, u32 length) const {
|
|||||||
// rdram -> cart
|
// rdram -> cart
|
||||||
template <> void PI::DMA<false>() {
|
template <> void PI::DMA<false>() {
|
||||||
s32 len = rdLen + 1;
|
s32 len = rdLen + 1;
|
||||||
Util::always("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);
|
||||||
|
|
||||||
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);
|
||||||
@@ -440,7 +440,6 @@ template <> void PI::DMA<false>() {
|
|||||||
cartAddr += len;
|
cartAddr += len;
|
||||||
if(cartAddr & 1) cartAddr += 1;
|
if(cartAddr & 1) cartAddr += 1;
|
||||||
|
|
||||||
Util::always("Addresses after: Cart: 0x{:08X}, Dram: 0x{:08X}", cartAddr, dramAddr);
|
|
||||||
dmaBusy = true;
|
dmaBusy = true;
|
||||||
scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), rdLen), PI_DMA_COMPLETE);
|
scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), rdLen), PI_DMA_COMPLETE);
|
||||||
}
|
}
|
||||||
@@ -448,7 +447,7 @@ template <> void PI::DMA<false>() {
|
|||||||
// cart -> rdram
|
// cart -> rdram
|
||||||
template <> void PI::DMA<true>() {
|
template <> void PI::DMA<true>() {
|
||||||
s32 len = wrLen + 1;
|
s32 len = wrLen + 1;
|
||||||
Util::always("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);
|
||||||
|
|
||||||
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);
|
||||||
@@ -462,9 +461,6 @@ template <> void PI::DMA<true>() {
|
|||||||
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;
|
||||||
scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE);
|
scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,11 +60,11 @@ FORCE_INLINE void SetCop0Reg(Registers& regs, Mem& mem, u8 index, u32 val) {
|
|||||||
case 1: rsp.spDMADRAMAddr.raw = val; break;
|
case 1: rsp.spDMADRAMAddr.raw = val; break;
|
||||||
case 2:
|
case 2:
|
||||||
rsp.spDMALen.raw = val;
|
rsp.spDMALen.raw = val;
|
||||||
rsp.DMAtoRSP(mem.GetRDRAM());
|
rsp.DMA<false>();
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
rsp.spDMALen.raw = val;
|
rsp.spDMALen.raw = val;
|
||||||
rsp.DMAtoRDRAM(mem.GetRDRAM());
|
rsp.DMA<true>();
|
||||||
break;
|
break;
|
||||||
case 4: rsp.WriteStatus(val); break;
|
case 4: rsp.WriteStatus(val); break;
|
||||||
case 7:
|
case 7:
|
||||||
|
|||||||
Reference in New Issue
Block a user