Refactor Scheduler
This commit is contained in:
@@ -91,7 +91,7 @@ void Core::Run(float volumeL, float volumeR) {
|
|||||||
|
|
||||||
cycles += taken;
|
cycles += taken;
|
||||||
frameCycles += taken;
|
frameCycles += taken;
|
||||||
scheduler.tick(taken, mem, regs);
|
scheduler.Tick(taken, mem, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
cycles -= mmio.vi.cyclesPerHalfline;
|
cycles -= mmio.vi.cyclesPerHalfline;
|
||||||
@@ -102,7 +102,7 @@ void Core::Run(float volumeL, float volumeR) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mmio.ai.Step(cpu->mem, regs, frameCycles, volumeL, volumeR);
|
mmio.ai.Step(cpu->mem, regs, frameCycles, volumeL, volumeR);
|
||||||
scheduler.tick(frameCycles, mem, regs);
|
scheduler.Tick(frameCycles, mem, regs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,15 @@
|
|||||||
|
|
||||||
Scheduler scheduler;
|
Scheduler scheduler;
|
||||||
|
|
||||||
void Scheduler::enqueueRelative(u64 t, const EventType type) {
|
void Scheduler::EnqueueRelative(u64 t, const EventType type) {
|
||||||
enqueueAbsolute(t + ticks, type);
|
EnqueueAbsolute(t + ticks, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::enqueueAbsolute(u64 t, const EventType type) {
|
void Scheduler::EnqueueAbsolute(u64 t, const EventType type) {
|
||||||
events.push({t, type});
|
events.push({t, type});
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 Scheduler::remove(EventType type) {
|
u64 Scheduler::Remove(EventType type) {
|
||||||
for (auto& e : events) {
|
for (auto& e : events) {
|
||||||
if(e.type == type) {
|
if(e.type == type) {
|
||||||
u64 ret = e.time - ticks;
|
u64 ret = e.time - ticks;
|
||||||
@@ -25,7 +25,7 @@ u64 Scheduler::remove(EventType type) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::tick(u64 t, n64::Mem& mem, n64::Registers& regs) {
|
void Scheduler::Tick(u64 t, n64::Mem& mem, n64::Registers& regs) {
|
||||||
ticks += t;
|
ticks += t;
|
||||||
n64::MI& mi = mem.mmio.mi;
|
n64::MI& mi = mem.mmio.mi;
|
||||||
n64::SI& si = mem.mmio.si;
|
n64::SI& si = mem.mmio.si;
|
||||||
|
|||||||
@@ -47,13 +47,13 @@ public:
|
|||||||
|
|
||||||
struct Scheduler {
|
struct Scheduler {
|
||||||
Scheduler() {
|
Scheduler() {
|
||||||
enqueueAbsolute(std::numeric_limits<u64>::max(), IMPOSSIBLE);
|
EnqueueAbsolute(std::numeric_limits<u64>::max(), IMPOSSIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enqueueRelative(u64, EventType);
|
void EnqueueRelative(u64, EventType);
|
||||||
void enqueueAbsolute(u64, EventType);
|
void EnqueueAbsolute(u64, EventType);
|
||||||
u64 remove(EventType);
|
u64 Remove(EventType);
|
||||||
void tick(u64 t, n64::Mem&, n64::Registers&);
|
void Tick(u64 t, n64::Mem&, n64::Registers&);
|
||||||
|
|
||||||
IterableEvents events;
|
IterableEvents events;
|
||||||
u64 ticks = 0;
|
u64 ticks = 0;
|
||||||
|
|||||||
@@ -18,14 +18,14 @@ void PI::Reset() {
|
|||||||
cartAddrInternal = 0;
|
cartAddrInternal = 0;
|
||||||
rdLen = 0;
|
rdLen = 0;
|
||||||
wrLen = 0;
|
wrLen = 0;
|
||||||
pi_bsd_dom1_lat = 0;
|
piBsdDom1Lat = 0;
|
||||||
pi_bsd_dom2_lat = 0;
|
piBsdDom2Lat = 0;
|
||||||
pi_bsd_dom1_pwd = 0;
|
piBsdDom1Pwd = 0;
|
||||||
pi_bsd_dom2_pwd = 0;
|
piBsdDom2Pwd = 0;
|
||||||
pi_bsd_dom1_pgs = 0;
|
piBsdDom1Pgs = 0;
|
||||||
pi_bsd_dom2_pgs = 0;
|
piBsdDom2Pgs = 0;
|
||||||
pi_bsd_dom1_rls = 0;
|
piBsdDom1Rls = 0;
|
||||||
pi_bsd_dom2_rls = 0;
|
piBsdDom2Rls = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PI::WriteLatch(u32 value) {
|
bool PI::WriteLatch(u32 value) {
|
||||||
@@ -34,7 +34,7 @@ bool PI::WriteLatch(u32 value) {
|
|||||||
} else {
|
} else {
|
||||||
ioBusy = true;
|
ioBusy = true;
|
||||||
latch = value;
|
latch = value;
|
||||||
scheduler.enqueueRelative(100, PI_BUS_WRITE_COMPLETE);
|
scheduler.EnqueueRelative(100, PI_BUS_WRITE_COMPLETE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ bool PI::WriteLatch(u32 value) {
|
|||||||
bool PI::ReadLatch() {
|
bool PI::ReadLatch() {
|
||||||
if (ioBusy) [[unlikely]] {
|
if (ioBusy) [[unlikely]] {
|
||||||
ioBusy = false;
|
ioBusy = false;
|
||||||
CpuStall(scheduler.remove(PI_BUS_WRITE_COMPLETE));
|
CpuStall(scheduler.Remove(PI_BUS_WRITE_COMPLETE));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -367,14 +367,14 @@ auto PI::Read(MI& mi, u32 addr) const -> u32 {
|
|||||||
value |= (mi.miIntr.pi << 3); // PI interrupt?
|
value |= (mi.miIntr.pi << 3); // PI interrupt?
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
case 0x04600014: return pi_bsd_dom1_lat;
|
case 0x04600014: return piBsdDom1Lat;
|
||||||
case 0x04600018: return pi_bsd_dom1_pwd;
|
case 0x04600018: return piBsdDom1Pwd;
|
||||||
case 0x0460001C: return pi_bsd_dom1_pgs;
|
case 0x0460001C: return piBsdDom1Pgs;
|
||||||
case 0x04600020: return pi_bsd_dom1_rls;
|
case 0x04600020: return piBsdDom1Rls;
|
||||||
case 0x04600024: return pi_bsd_dom2_lat;
|
case 0x04600024: return piBsdDom2Lat;
|
||||||
case 0x04600028: return pi_bsd_dom2_pwd;
|
case 0x04600028: return piBsdDom2Pwd;
|
||||||
case 0x0460002C: return pi_bsd_dom2_pgs;
|
case 0x0460002C: return piBsdDom2Pgs;
|
||||||
case 0x04600030: return pi_bsd_dom2_rls;
|
case 0x04600030: return piBsdDom2Rls;
|
||||||
default:
|
default:
|
||||||
Util::panic("Unhandled PI[{:08X}] read", addr);
|
Util::panic("Unhandled PI[{:08X}] read", addr);
|
||||||
}
|
}
|
||||||
@@ -404,16 +404,16 @@ u32 PI::AccessTiming(u8 domain, u32 length) const {
|
|||||||
|
|
||||||
switch (domain) {
|
switch (domain) {
|
||||||
case 1:
|
case 1:
|
||||||
latency = pi_bsd_dom1_lat + 1;
|
latency = piBsdDom1Lat + 1;
|
||||||
pulse_width = pi_bsd_dom1_pwd + 1;
|
pulse_width = piBsdDom1Pwd + 1;
|
||||||
release = pi_bsd_dom1_rls + 1;
|
release = piBsdDom1Rls + 1;
|
||||||
page_size = std::pow(2, (pi_bsd_dom1_pgs + 2));
|
page_size = std::pow(2, (piBsdDom1Pgs + 2));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
latency = pi_bsd_dom2_lat + 1;
|
latency = piBsdDom2Lat + 1;
|
||||||
pulse_width = pi_bsd_dom2_pwd + 1;
|
pulse_width = piBsdDom2Pwd + 1;
|
||||||
release = pi_bsd_dom2_rls + 1;
|
release = piBsdDom2Rls + 1;
|
||||||
page_size = std::pow(2, (pi_bsd_dom2_pgs + 2));
|
page_size = std::pow(2, (piBsdDom2Pgs + 2));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Util::panic("Unknown PI domain: {}\n", domain);
|
Util::panic("Unknown PI domain: {}\n", domain);
|
||||||
@@ -449,7 +449,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
|||||||
Util::trace("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);
|
||||||
dmaBusy = true;
|
dmaBusy = true;
|
||||||
toCart = true;
|
toCart = true;
|
||||||
scheduler.enqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE);
|
scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE);
|
||||||
} break;
|
} break;
|
||||||
case 0x0460000C: {
|
case 0x0460000C: {
|
||||||
u32 len = (val & 0x00FFFFFF) + 1;
|
u32 len = (val & 0x00FFFFFF) + 1;
|
||||||
@@ -470,20 +470,20 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
|||||||
dmaBusy = true;
|
dmaBusy = true;
|
||||||
Util::trace("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);
|
||||||
toCart = false;
|
toCart = false;
|
||||||
scheduler.enqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE);
|
scheduler.EnqueueRelative(AccessTiming(GetDomain(cartAddr), len), PI_DMA_COMPLETE);
|
||||||
} break;
|
} break;
|
||||||
case 0x04600010:
|
case 0x04600010:
|
||||||
if(val & 2) {
|
if(val & 2) {
|
||||||
mi.InterruptLower(MI::Interrupt::PI);
|
mi.InterruptLower(MI::Interrupt::PI);
|
||||||
} break;
|
} break;
|
||||||
case 0x04600014: pi_bsd_dom1_lat = val & 0xff; break;
|
case 0x04600014: piBsdDom1Lat = val & 0xff; break;
|
||||||
case 0x04600018: pi_bsd_dom1_pwd = val & 0xff; break;
|
case 0x04600018: piBsdDom1Pwd = val & 0xff; break;
|
||||||
case 0x0460001C: pi_bsd_dom1_pgs = val & 0xff; break;
|
case 0x0460001C: piBsdDom1Pgs = val & 0xff; break;
|
||||||
case 0x04600020: pi_bsd_dom1_rls = val & 0xff; break;
|
case 0x04600020: piBsdDom1Rls = val & 0xff; break;
|
||||||
case 0x04600024: pi_bsd_dom2_lat = val & 0xff; break;
|
case 0x04600024: piBsdDom2Lat = val & 0xff; break;
|
||||||
case 0x04600028: pi_bsd_dom2_pwd = val & 0xff; break;
|
case 0x04600028: piBsdDom2Pwd = val & 0xff; break;
|
||||||
case 0x0460002C: pi_bsd_dom2_pgs = val & 0xff; break;
|
case 0x0460002C: piBsdDom2Pgs = val & 0xff; break;
|
||||||
case 0x04600030: pi_bsd_dom2_rls = val & 0xff; break;
|
case 0x04600030: piBsdDom2Rls = val & 0xff; break;
|
||||||
default:
|
default:
|
||||||
Util::panic("Unhandled PI[{:08X}] write ({:08X})", val, addr);
|
Util::panic("Unhandled PI[{:08X}] write ({:08X})", val, addr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ struct PI {
|
|||||||
u32 latch{};
|
u32 latch{};
|
||||||
u32 dramAddr{}, cartAddr{}, dramAddrInternal{}, cartAddrInternal{};
|
u32 dramAddr{}, cartAddr{}, dramAddrInternal{}, cartAddrInternal{};
|
||||||
u32 rdLen{}, wrLen{};
|
u32 rdLen{}, wrLen{};
|
||||||
u32 pi_bsd_dom1_lat{}, pi_bsd_dom2_lat{};
|
u32 piBsdDom1Lat{}, piBsdDom2Lat{};
|
||||||
u32 pi_bsd_dom1_pwd{}, pi_bsd_dom2_pwd{};
|
u32 piBsdDom1Pwd{}, piBsdDom2Pwd{};
|
||||||
u32 pi_bsd_dom1_pgs{}, pi_bsd_dom2_pgs{};
|
u32 piBsdDom1Pgs{}, piBsdDom2Pgs{};
|
||||||
u32 pi_bsd_dom1_rls{}, pi_bsd_dom2_rls{};
|
u32 piBsdDom1Rls{}, piBsdDom2Rls{};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -60,13 +60,13 @@ void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
|||||||
pifAddr = val & 0x1FFFFFFF;
|
pifAddr = val & 0x1FFFFFFF;
|
||||||
status.dmaBusy = true;
|
status.dmaBusy = true;
|
||||||
toDram = true;
|
toDram = true;
|
||||||
scheduler.enqueueRelative(SI_DMA_DELAY, SI_DMA);
|
scheduler.EnqueueRelative(SI_DMA_DELAY, SI_DMA);
|
||||||
} break;
|
} break;
|
||||||
case 0x04800010: {
|
case 0x04800010: {
|
||||||
pifAddr = val & 0x1FFFFFFF;
|
pifAddr = val & 0x1FFFFFFF;
|
||||||
status.dmaBusy = true;
|
status.dmaBusy = true;
|
||||||
toDram = false;
|
toDram = false;
|
||||||
scheduler.enqueueRelative(SI_DMA_DELAY, SI_DMA);
|
scheduler.EnqueueRelative(SI_DMA_DELAY, SI_DMA);
|
||||||
} break;
|
} break;
|
||||||
case 0x04800018:
|
case 0x04800018:
|
||||||
mem.mmio.mi.InterruptLower(MI::Interrupt::SI);
|
mem.mmio.mi.InterruptLower(MI::Interrupt::SI);
|
||||||
|
|||||||
Reference in New Issue
Block a user