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