Idle skipping... maybe?

This commit is contained in:
2026-05-21 17:16:43 +02:00
parent 609fa2fb08
commit 366637aba3
7 changed files with 604 additions and 580 deletions
+1
View File
@@ -20,6 +20,7 @@ vgcore.*
*.data *.data
disasm.txt disasm.txt
*log*.txt *log*.txt
*.log
CMakeSettings.json CMakeSettings.json
compile_commands.json compile_commands.json
*.diagsession *.diagsession
+14
View File
@@ -110,6 +110,15 @@ void Core::Run(const float volumeL, const float volumeR) {
} }
while (cycles < mem->mmio.vi.cyclesPerHalfline) { while (cycles < mem->mmio.vi.cyclesPerHalfline) {
if (IsAnythingSkippable()) {
const u32 taken = Scheduler::GetInstance().events.top().time - Scheduler::GetInstance().ticks;
cycles += taken;
frameCycles += taken;
Scheduler::GetInstance().Tick(taken);
isReadingAnyIO = false;
continue;
}
const u32 taken = StepCPU(); const u32 taken = StepCPU();
cycles += taken; cycles += taken;
@@ -141,4 +150,9 @@ void Core::Run(const float volumeL, const float volumeR) {
if (broken) if (broken)
pause = true; pause = true;
} }
bool Core::IsAnythingSkippable() {
MMIO &mmio = mem->mmio;
return (mmio.si.status.dmaBusy || mmio.pi.dmaBusy || mmio.pi.ioBusy) && isReadingAnyIO;
}
} // namespace n64 } // namespace n64
+5
View File
@@ -19,6 +19,8 @@ struct Core {
return instance; return instance;
} }
static void SetIdleSkippingStatus(bool v) { GetInstance().isReadingAnyIO = v; }
static Registers &GetRegs() { return GetInstance().regs; } static Registers &GetRegs() { return GetInstance().regs; }
static Mem &GetMem() { return *GetInstance().mem; } static Mem &GetMem() { return *GetInstance().mem; }
@@ -57,5 +59,8 @@ struct Core {
#endif #endif
Interpreter interpreter; Interpreter interpreter;
ParallelRDP parallel; ParallelRDP parallel;
bool isReadingAnyIO = false;
bool IsAnythingSkippable();
}; };
} // namespace n64 } // namespace n64
+7 -3
View File
@@ -186,7 +186,8 @@ auto PI::BusRead<u16, false>(u32 addr) -> u16 {
addr = (addr + 2) & ~3; addr = (addr + 2) & ~3;
const u32 index = HALF_ADDRESS(addr) - SREGION_PI_ROM; const u32 index = HALF_ADDRESS(addr) - SREGION_PI_ROM;
if (index > mem.rom.cart.size() - 1) { if (index > mem.rom.cart.size() - 1) {
panic("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM!", addr, index, index); panic("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM!", addr, index,
index);
} }
return ircolib::ReadAccess<u16>(mem.rom.cart, index); return ircolib::ReadAccess<u16>(mem.rom.cart, index);
} }
@@ -260,7 +261,8 @@ auto PI::BusRead<u32, false>(u32 addr) -> u32 {
if (index > mem.rom.cart.size() - 3) { // -3 because we're reading an entire word if (index > mem.rom.cart.size() - 3) { // -3 because we're reading an entire word
switch (addr) { switch (addr) {
case REGION_CART_ISVIEWER_BUFFER: case REGION_CART_ISVIEWER_BUFFER:
return std::byteswap<u32>(ircolib::ReadAccess<u32>(mem.isviewer, addr - SREGION_CART_ISVIEWER_BUFFER)); return std::byteswap<u32>(
ircolib::ReadAccess<u32>(mem.isviewer, addr - SREGION_CART_ISVIEWER_BUFFER));
case CART_ISVIEWER_FLUSH: case CART_ISVIEWER_FLUSH:
panic("Read from ISViewer flush!"); panic("Read from ISViewer flush!");
default: default:
@@ -367,7 +369,8 @@ auto PI::BusRead<u64, false>(u32 addr) -> u64 {
{ {
const u32 index = addr - SREGION_PI_ROM; const u32 index = addr - SREGION_PI_ROM;
if (index > mem.rom.cart.size() - 7) { // -7 because we're reading an entire dword if (index > mem.rom.cart.size() - 7) { // -7 because we're reading an entire dword
panic("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM!", addr, index, index); panic("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM!", addr, index,
index);
} }
return ircolib::ReadAccess<u64>(mem.rom.cart, index); return ircolib::ReadAccess<u64>(mem.rom.cart, index);
} }
@@ -422,6 +425,7 @@ auto PI::Read(u32 addr) const -> u32 {
return wrLen; return wrLen;
case 0x04600010: case 0x04600010:
{ {
Core::SetIdleSkippingStatus(true);
u32 value = 0; u32 value = 0;
value |= (dmaBusy << 0); // Is PI DMA active? value |= (dmaBusy << 0); // Is PI DMA active?
value |= (ioBusy << 1); // Is PI IO busy? value |= (ioBusy << 1); // Is PI IO busy?
+1
View File
@@ -24,6 +24,7 @@ auto SI::Read(u32 addr) const -> u32 {
return 0; return 0;
case 0x04800018: case 0x04800018:
{ {
Core::SetIdleSkippingStatus(true);
u32 val = 0; u32 val = 0;
val |= status.dmaBusy; val |= status.dmaBusy;
val |= (0 << 1); val |= (0 << 1);
+10 -11
View File
@@ -4,8 +4,16 @@
#include <core/mmio/PIF.hpp> #include <core/mmio/PIF.hpp>
namespace n64 { namespace n64 {
struct SI {
SI();
void Reset();
[[nodiscard]] auto Read(u32) const -> u32;
void Write(u32, u32);
template <bool toDram>
void DMA();
void DMA();
union SIStatus { union Status {
u32 raw{}; u32 raw{};
struct { struct {
unsigned dmaBusy : 1; unsigned dmaBusy : 1;
@@ -17,17 +25,8 @@ union SIStatus {
}; };
}; };
struct SI {
SI();
void Reset();
[[nodiscard]] auto Read(u32) const -> u32;
void Write(u32, u32);
template <bool toDram>
void DMA();
void DMA();
bool toDram = false; bool toDram = false;
SIStatus status{}; Status status{};
u32 dramAddr{}; u32 dramAddr{};
u32 pifAddr{}; u32 pifAddr{};
PIF pif; PIF pif;