Idle skipping... maybe?
This commit is contained in:
@@ -5,91 +5,92 @@ namespace n64 {
|
||||
SI::SI() { Reset(); }
|
||||
|
||||
void SI::Reset() {
|
||||
status.raw = 0;
|
||||
dramAddr = 0;
|
||||
pifAddr = 0;
|
||||
toDram = false;
|
||||
pif.Reset();
|
||||
status.raw = 0;
|
||||
dramAddr = 0;
|
||||
pifAddr = 0;
|
||||
toDram = false;
|
||||
pif.Reset();
|
||||
}
|
||||
|
||||
auto SI::Read(u32 addr) const -> u32 {
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
switch (addr) {
|
||||
case 0x04800000:
|
||||
return dramAddr;
|
||||
case 0x04800004:
|
||||
case 0x04800010:
|
||||
return pifAddr;
|
||||
case 0x0480000C:
|
||||
return 0;
|
||||
case 0x04800018:
|
||||
{
|
||||
u32 val = 0;
|
||||
val |= status.dmaBusy;
|
||||
val |= (0 << 1);
|
||||
val |= (0 << 3);
|
||||
val |= (mem.mmio.mi.intr.si << 12);
|
||||
return val;
|
||||
n64::Mem &mem = n64::Core::GetMem();
|
||||
switch (addr) {
|
||||
case 0x04800000:
|
||||
return dramAddr;
|
||||
case 0x04800004:
|
||||
case 0x04800010:
|
||||
return pifAddr;
|
||||
case 0x0480000C:
|
||||
return 0;
|
||||
case 0x04800018:
|
||||
{
|
||||
Core::SetIdleSkippingStatus(true);
|
||||
u32 val = 0;
|
||||
val |= status.dmaBusy;
|
||||
val |= (0 << 1);
|
||||
val |= (0 << 3);
|
||||
val |= (mem.mmio.mi.intr.si << 12);
|
||||
return val;
|
||||
}
|
||||
default:
|
||||
panic("Unhandled SI[{:08X}] read", addr);
|
||||
}
|
||||
default:
|
||||
panic("Unhandled SI[{:08X}] read", addr);
|
||||
}
|
||||
}
|
||||
|
||||
// pif -> rdram
|
||||
template <>
|
||||
void SI::DMA<true>() {
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
pif.ProcessCommands();
|
||||
for (int i = 0; i < 64; i++) {
|
||||
mem.mmio.rdp.WriteRDRAM<u8>(dramAddr + i, pif.Read(pifAddr + i));
|
||||
}
|
||||
trace("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})", pifAddr, dramAddr);
|
||||
n64::Mem &mem = n64::Core::GetMem();
|
||||
pif.ProcessCommands();
|
||||
for (int i = 0; i < 64; i++) {
|
||||
mem.mmio.rdp.WriteRDRAM<u8>(dramAddr + i, pif.Read(pifAddr + i));
|
||||
}
|
||||
trace("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})", pifAddr, dramAddr);
|
||||
}
|
||||
|
||||
// rdram -> pif
|
||||
template <>
|
||||
void SI::DMA<false>() {
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
for (int i = 0; i < 64; i++) {
|
||||
pif.Write(pifAddr + i, mem.mmio.rdp.ReadRDRAM<u8>(dramAddr + i));
|
||||
}
|
||||
trace("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})", dramAddr, pifAddr);
|
||||
n64::Mem &mem = n64::Core::GetMem();
|
||||
for (int i = 0; i < 64; i++) {
|
||||
pif.Write(pifAddr + i, mem.mmio.rdp.ReadRDRAM<u8>(dramAddr + i));
|
||||
}
|
||||
trace("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})", dramAddr, pifAddr);
|
||||
}
|
||||
|
||||
void SI::DMA() {
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
status.dmaBusy = false;
|
||||
if (toDram)
|
||||
DMA<true>();
|
||||
else
|
||||
DMA<false>();
|
||||
mem.mmio.mi.InterruptRaise(MI::Interrupt::SI);
|
||||
n64::Mem &mem = n64::Core::GetMem();
|
||||
status.dmaBusy = false;
|
||||
if (toDram)
|
||||
DMA<true>();
|
||||
else
|
||||
DMA<false>();
|
||||
mem.mmio.mi.InterruptRaise(MI::Interrupt::SI);
|
||||
}
|
||||
|
||||
void SI::Write(u32 addr, u32 val) {
|
||||
n64::Mem& mem = n64::Core::GetMem();
|
||||
switch (addr) {
|
||||
case 0x04800000:
|
||||
dramAddr = val & RDRAM_DSIZE;
|
||||
break;
|
||||
case 0x04800004:
|
||||
pifAddr = val & 0x1FFFFFFF;
|
||||
status.dmaBusy = true;
|
||||
toDram = true;
|
||||
Scheduler::GetInstance().EnqueueRelative(SI_DMA_DELAY, SI_DMA);
|
||||
break;
|
||||
case 0x04800010:
|
||||
pifAddr = val & 0x1FFFFFFF;
|
||||
status.dmaBusy = true;
|
||||
toDram = false;
|
||||
Scheduler::GetInstance().EnqueueRelative(SI_DMA_DELAY, SI_DMA);
|
||||
break;
|
||||
case 0x04800018:
|
||||
mem.mmio.mi.InterruptLower(MI::Interrupt::SI);
|
||||
break;
|
||||
default:
|
||||
panic("Unhandled SI[{:08X}] write ({:08X})", addr, val);
|
||||
}
|
||||
n64::Mem &mem = n64::Core::GetMem();
|
||||
switch (addr) {
|
||||
case 0x04800000:
|
||||
dramAddr = val & RDRAM_DSIZE;
|
||||
break;
|
||||
case 0x04800004:
|
||||
pifAddr = val & 0x1FFFFFFF;
|
||||
status.dmaBusy = true;
|
||||
toDram = true;
|
||||
Scheduler::GetInstance().EnqueueRelative(SI_DMA_DELAY, SI_DMA);
|
||||
break;
|
||||
case 0x04800010:
|
||||
pifAddr = val & 0x1FFFFFFF;
|
||||
status.dmaBusy = true;
|
||||
toDram = false;
|
||||
Scheduler::GetInstance().EnqueueRelative(SI_DMA_DELAY, SI_DMA);
|
||||
break;
|
||||
case 0x04800018:
|
||||
mem.mmio.mi.InterruptLower(MI::Interrupt::SI);
|
||||
break;
|
||||
default:
|
||||
panic("Unhandled SI[{:08X}] write ({:08X})", addr, val);
|
||||
}
|
||||
}
|
||||
} // namespace n64
|
||||
|
||||
Reference in New Issue
Block a user