Scheduler (SI DMA delay)
This commit is contained in:
@@ -15,7 +15,7 @@ struct Window {
|
|||||||
[[nodiscard]] bool gotClosed(SDL_Event event);
|
[[nodiscard]] bool gotClosed(SDL_Event event);
|
||||||
ImFont *uiFont{}, *codeFont{};
|
ImFont *uiFont{}, *codeFont{};
|
||||||
u32 windowID{};
|
u32 windowID{};
|
||||||
float volumeL = 0.5, volumeR = 0.5;
|
float volumeL = 0.1, volumeR = 0.1;
|
||||||
void LoadROM(n64::Core& core, const std::string& path);
|
void LoadROM(n64::Core& core, const std::string& path);
|
||||||
private:
|
private:
|
||||||
bool lockVolume = true;
|
bool lockVolume = true;
|
||||||
|
|||||||
@@ -10,13 +10,17 @@ Scheduler::Scheduler() {
|
|||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::enqueue(const Event& event) {
|
void Scheduler::enqueueRelative(const Event& event) {
|
||||||
events.push({event.time + ticks, event.event_cb});
|
events.push({event.time + ticks, event.event_cb});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scheduler::enqueueAbsolute(const Event& event) {
|
||||||
|
events.push({event.time, event.event_cb});
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
while(ticks >= events.top().time) {
|
if(ticks >= events.top().time) {
|
||||||
events.top().event_cb(mem, regs);
|
events.top().event_cb(mem, regs);
|
||||||
events.pop();
|
events.pop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ struct Registers;
|
|||||||
|
|
||||||
struct Event {
|
struct Event {
|
||||||
u64 time = UINT64_MAX;
|
u64 time = UINT64_MAX;
|
||||||
void(*event_cb)(n64::Mem&, n64::Registers&);
|
void(*event_cb)(n64::Mem&, n64::Registers&) = nullptr;
|
||||||
|
|
||||||
friend bool operator<(const Event& rhs, const Event& lhs) {
|
friend bool operator<(const Event& rhs, const Event& lhs) {
|
||||||
return lhs.time < rhs.time;
|
return lhs.time < rhs.time;
|
||||||
@@ -18,7 +18,8 @@ struct Event {
|
|||||||
|
|
||||||
struct Scheduler {
|
struct Scheduler {
|
||||||
Scheduler();
|
Scheduler();
|
||||||
void enqueue(const Event&);
|
void enqueueRelative(const Event&);
|
||||||
|
void enqueueAbsolute(const Event&);
|
||||||
void tick(u64, n64::Mem&, n64::Registers&);
|
void tick(u64, n64::Mem&, n64::Registers&);
|
||||||
std::priority_queue<Event> events;
|
std::priority_queue<Event> events;
|
||||||
u64 ticks = 0;
|
u64 ticks = 0;
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ SI::SI() {
|
|||||||
void SI::Reset() {
|
void SI::Reset() {
|
||||||
status.raw = 0;
|
status.raw = 0;
|
||||||
dramAddr = 0;
|
dramAddr = 0;
|
||||||
|
pifAddr = 0;
|
||||||
memset(&controller, 0, sizeof(Controller));
|
memset(&controller, 0, sizeof(Controller));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SI::Read(MI& mi, u32 addr) const -> u32 {
|
auto SI::Read(MI& mi, u32 addr) const -> u32 {
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
case 0x04800000: return dramAddr;
|
case 0x04800000: return dramAddr;
|
||||||
|
case 0x04800004: case 0x04800010: return pifAddr;
|
||||||
case 0x0480000C: return 0;
|
case 0x0480000C: return 0;
|
||||||
case 0x04800018: {
|
case 0x04800018: {
|
||||||
u32 val = 0;
|
u32 val = 0;
|
||||||
@@ -46,6 +48,7 @@ void DMA(Mem& mem, Registers& regs) {
|
|||||||
for(int i = 0; i < 64; i++) {
|
for(int i = 0; i < 64; i++) {
|
||||||
mem.pifRam[i] = mem.mmio.rdp.dram[BYTE_ADDRESS(si.dramAddr + i)];
|
mem.pifRam[i] = mem.mmio.rdp.dram[BYTE_ADDRESS(si.dramAddr + i)];
|
||||||
}
|
}
|
||||||
|
util::logdebug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr);
|
||||||
ProcessPIFCommands(mem.pifRam, si.controller, mem);
|
ProcessPIFCommands(mem.pifRam, si.controller, mem);
|
||||||
}
|
}
|
||||||
InterruptRaise(mem.mmio.mi, regs, Interrupt::SI);
|
InterruptRaise(mem.mmio.mi, regs, Interrupt::SI);
|
||||||
@@ -57,15 +60,16 @@ void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
|||||||
dramAddr = val & RDRAM_DSIZE;
|
dramAddr = val & RDRAM_DSIZE;
|
||||||
break;
|
break;
|
||||||
case 0x04800004: {
|
case 0x04800004: {
|
||||||
|
pifAddr = val & 0x1FFFFFFF;
|
||||||
status.dmaBusy = true;
|
status.dmaBusy = true;
|
||||||
toDram = true;
|
toDram = true;
|
||||||
scheduler.enqueue({SI_DMA_DELAY, DMA});
|
scheduler.enqueueRelative({SI_DMA_DELAY, DMA});
|
||||||
util::logdebug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", val & 0x1FFFFFFF, dramAddr);
|
|
||||||
} break;
|
} break;
|
||||||
case 0x04800010: {
|
case 0x04800010: {
|
||||||
|
pifAddr = val & 0x1FFFFFFF;
|
||||||
status.dmaBusy = true;
|
status.dmaBusy = true;
|
||||||
toDram = false;
|
toDram = false;
|
||||||
scheduler.enqueue({SI_DMA_DELAY, DMA});
|
scheduler.enqueueRelative({SI_DMA_DELAY, DMA});
|
||||||
util::logdebug("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})\n", dramAddr, val & 0x1FFFFFFF);
|
util::logdebug("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})\n", dramAddr, val & 0x1FFFFFFF);
|
||||||
} break;
|
} break;
|
||||||
case 0x04800018:
|
case 0x04800018:
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ struct SI {
|
|||||||
void Reset();
|
void Reset();
|
||||||
SIStatus status{};
|
SIStatus status{};
|
||||||
u32 dramAddr{};
|
u32 dramAddr{};
|
||||||
|
u32 pifAddr{};
|
||||||
Controller controller{};
|
Controller controller{};
|
||||||
|
|
||||||
bool toDram = false;
|
bool toDram = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user