diff options
author | Arisotura <thetotalworm@gmail.com> | 2023-11-02 21:04:09 +0100 |
---|---|---|
committer | Arisotura <thetotalworm@gmail.com> | 2023-11-02 21:04:09 +0100 |
commit | 70c6750561b0c130b430e2ec3d076708b3767674 (patch) | |
tree | f2cc1b0aad735f9be60e5f837ceca120980ca682 | |
parent | 5ccd3916ff719ea4ed49030077794fadda048cb9 (diff) |
better, less hacky, more OOP-friendly scheduler design
-rw-r--r-- | src/DSi_Camera.cpp | 16 | ||||
-rw-r--r-- | src/DSi_DSP.cpp | 6 | ||||
-rw-r--r-- | src/DSi_NWifi.cpp | 58 | ||||
-rw-r--r-- | src/DSi_NWifi.h | 4 | ||||
-rw-r--r-- | src/DSi_SD.cpp | 42 | ||||
-rw-r--r-- | src/DSi_SD.h | 4 | ||||
-rw-r--r-- | src/GPU.cpp | 27 | ||||
-rw-r--r-- | src/NDS.cpp | 202 | ||||
-rw-r--r-- | src/NDS.h | 14 | ||||
-rw-r--r-- | src/NDSCart.cpp | 22 | ||||
-rw-r--r-- | src/RTC.cpp | 5 | ||||
-rw-r--r-- | src/SPI.cpp | 6 | ||||
-rw-r--r-- | src/SPU.cpp | 8 | ||||
-rw-r--r-- | src/Wifi.cpp | 6 |
14 files changed, 202 insertions, 218 deletions
diff --git a/src/DSi_Camera.cpp b/src/DSi_Camera.cpp index 80e578f..2471f8c 100644 --- a/src/DSi_Camera.cpp +++ b/src/DSi_Camera.cpp @@ -53,6 +53,9 @@ const u32 kTransferStart = 60000; bool Init() { + NDS::RegisterEventFunc(NDS::Event_DSi_CamIRQ, 0, IRQ); + NDS::RegisterEventFunc(NDS::Event_DSi_CamTransfer, 0, TransferScanline); + Camera0 = new Camera(0); Camera1 = new Camera(1); @@ -66,6 +69,9 @@ void DeInit() Camera0 = nullptr; Camera1 = nullptr; + + NDS::UnregisterEventFunc(NDS::Event_DSi_CamIRQ, 0); + NDS::UnregisterEventFunc(NDS::Event_DSi_CamTransfer, 0); } void Reset() @@ -85,7 +91,7 @@ void Reset() BufferNumLines = 0; CurCamera = nullptr; - NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, false, kIRQInterval, IRQ, 0); + NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, false, kIRQInterval, 0, 0); } void Stop() @@ -132,11 +138,11 @@ void IRQ(u32 param) BufferWritePos = 0; BufferNumLines = 0; CurCamera = activecam; - NDS::ScheduleEvent(NDS::Event_DSi_CamTransfer, false, kTransferStart, TransferScanline, 0); + NDS::ScheduleEvent(NDS::Event_DSi_CamTransfer, false, kTransferStart, 0, 0); } } - NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, true, kIRQInterval, IRQ, 0); + NDS::ScheduleEvent(NDS::Event_DSi_CamIRQ, true, kIRQInterval, 0, 0); } void TransferScanline(u32 line) @@ -162,7 +168,7 @@ void TransferScanline(u32 line) if (line < ystart || line > yend) { if (!CurCamera->TransferDone()) - NDS::ScheduleEvent(NDS::Event_DSi_CamTransfer, false, delay, TransferScanline, line+1); + NDS::ScheduleEvent(NDS::Event_DSi_CamTransfer, false, delay, 0, line+1); return; } @@ -242,7 +248,7 @@ void TransferScanline(u32 line) if (CurCamera->TransferDone()) return; - NDS::ScheduleEvent(NDS::Event_DSi_CamTransfer, false, delay, TransferScanline, line+1); + NDS::ScheduleEvent(NDS::Event_DSi_CamTransfer, false, delay, 0, line+1); } diff --git a/src/DSi_DSP.cpp b/src/DSi_DSP.cpp index eaa80f9..d474763 100644 --- a/src/DSi_DSP.cpp +++ b/src/DSi_DSP.cpp @@ -129,6 +129,8 @@ void AudioCb(std::array<s16, 2> frame) bool Init() { + NDS::RegisterEventFunc(NDS::Event_DSi_DSP, 0, DSPCatchUpU32); + TeakraCore = new Teakra::Teakra(); SCFG_RST = false; @@ -171,6 +173,8 @@ void DeInit() //PDATAReadFifo = NULL; //PDATAWriteFifo = NULL; TeakraCore = NULL; + + NDS::UnregisterEventFunc(NDS::Event_DSi_DSP, 0); } void Reset() @@ -579,7 +583,7 @@ void Run(u32 cycles) NDS::CancelEvent(NDS::Event_DSi_DSP); NDS::ScheduleEvent(NDS::Event_DSi_DSP, false, - 16384/*from citra (TeakraSlice)*/, DSPCatchUpU32, 0); + 16384/*from citra (TeakraSlice)*/, 0, 0); } void DoSavestate(Savestate* file) diff --git a/src/DSi_NWifi.cpp b/src/DSi_NWifi.cpp index 132936a..558cd6f 100644 --- a/src/DSi_NWifi.cpp +++ b/src/DSi_NWifi.cpp @@ -116,9 +116,6 @@ const u8 CIS1[256] = }; -DSi_NWifi* Ctx = nullptr; - - DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host), Mailbox @@ -133,16 +130,17 @@ DSi_NWifi::DSi_NWifi(DSi_SDHost* host) DynamicFIFO<u8>(0x8000) } { + NDS::RegisterEventFunc(NDS::Event_DSi_NWifi, 0, MemberEventFunc(DSi_NWifi, MSTimer)); + // this seems to control whether the firmware upload is done EEPROMReady = 0; - - Ctx = this; } DSi_NWifi::~DSi_NWifi() { NDS::CancelEvent(NDS::Event_DSi_NWifi); - Ctx = nullptr; + + NDS::UnregisterEventFunc(NDS::Event_DSi_NWifi, 0); } void DSi_NWifi::Reset() @@ -908,7 +906,7 @@ void DSi_NWifi::HTC_Command() SendWMIEvent(1, 0x1006, regdomain_evt, 4); BootPhase = 2; - NDS::ScheduleEvent(NDS::Event_DSi_NWifi, false, 33611, MSTimer, 0); + NDS::ScheduleEvent(NDS::Event_DSi_NWifi, false, 33611, 0, 0); } break; @@ -1549,7 +1547,26 @@ void DSi_NWifi::WindowWrite(u32 addr, u32 val) } -void DSi_NWifi::_MSTimer() +void DSi_NWifi::DrainRXBuffer() +{ + while (Mailbox[8].Level() >= 6) + { + u16 len = Mailbox[8].Peek(2) | (Mailbox[8].Peek(3) << 8); + u32 totallen = len + 6; + u32 required = (totallen + 0x7F) & ~0x7F; + + if (!Mailbox[4].CanFit(required)) + break; + + u32 i = 0; + for (; i < totallen; i++) Mailbox[4].Write(Mailbox[8].Read()); + for (; i < required; i++) Mailbox[4].Write(0); + } + + UpdateIRQ_F1(); +} + +void DSi_NWifi::MSTimer(u32 param) { BeaconTimer++; @@ -1587,29 +1604,6 @@ void DSi_NWifi::_MSTimer() //if (Mailbox[4].IsEmpty()) CheckRX(); } -} - -void DSi_NWifi::DrainRXBuffer() -{ - while (Mailbox[8].Level() >= 6) - { - u16 len = Mailbox[8].Peek(2) | (Mailbox[8].Peek(3) << 8); - u32 totallen = len + 6; - u32 required = (totallen + 0x7F) & ~0x7F; - if (!Mailbox[4].CanFit(required)) - break; - - u32 i = 0; - for (; i < totallen; i++) Mailbox[4].Write(Mailbox[8].Read()); - for (; i < required; i++) Mailbox[4].Write(0); - } - - UpdateIRQ_F1(); -} - -void DSi_NWifi::MSTimer(u32 param) -{ - Ctx->_MSTimer(); - NDS::ScheduleEvent(NDS::Event_DSi_NWifi, true, 33611, MSTimer, 0); + NDS::ScheduleEvent(NDS::Event_DSi_NWifi, true, 33611, 0, 0); } diff --git a/src/DSi_NWifi.h b/src/DSi_NWifi.h index ffd5647..a758e96 100644 --- a/src/DSi_NWifi.h +++ b/src/DSi_NWifi.h @@ -40,9 +40,7 @@ public: void SetIRQ_F1_Counter(u32 n); - void _MSTimer(); - - static void MSTimer(u32 param); + void MSTimer(u32 param); private: u32 TransferCmd; diff --git a/src/DSi_SD.cpp b/src/DSi_SD.cpp index 158ae1e..5587034 100644 --- a/src/DSi_SD.cpp +++ b/src/DSi_SD.cpp @@ -48,11 +48,22 @@ using namespace Platform; #define SD_DESC Num?"SDIO":"SD/MMC" +enum +{ + Transfer_TX = 0, + Transfer_RX, +}; + DSi_SDHost::DSi_SDHost(u32 num) { Num = num; + NDS::RegisterEventFunc(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, + Transfer_TX, MemberEventFunc(DSi_SDHost, FinishTX)); + NDS::RegisterEventFunc(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, + Transfer_RX, MemberEventFunc(DSi_SDHost, FinishRX)); + Ports[0] = nullptr; Ports[1] = nullptr; } @@ -61,6 +72,11 @@ DSi_SDHost::~DSi_SDHost() { if (Ports[0]) delete Ports[0]; if (Ports[1]) delete Ports[1]; + + NDS::UnregisterEventFunc(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, + Transfer_TX); + NDS::UnregisterEventFunc(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, + Transfer_RX); } void DSi_SDHost::CloseHandles() @@ -281,14 +297,12 @@ void DSi_SDHost::SendResponse(u32 val, bool last) void DSi_SDHost::FinishRX(u32 param) { - DSi_SDHost* host = (param & 0x1) ? DSi::SDIO : DSi::SDMMC; - - host->CheckSwapFIFO(); + CheckSwapFIFO(); - if (host->DataMode == 1) - host->UpdateFIFO32(); + if (DataMode == 1) + UpdateFIFO32(); else - host->SetIRQ(24); + SetIRQ(24); } u32 DSi_SDHost::DataRX(u8* data, u32 len) @@ -308,21 +322,19 @@ u32 DSi_SDHost::DataRX(u8* data, u32 len) // we need a delay because DSi boot2 will send a command and then wait for IRQ0 // but if IRQ24 is thrown instantly, the handler clears IRQ0 before the // send-command function starts polling IRQ status - u32 param = Num | (last << 1); NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, - false, 512, FinishRX, param); + false, 512, Transfer_RX, 0); return len; } void DSi_SDHost::FinishTX(u32 param) { - DSi_SDHost* host = (param & 0x1) ? DSi::SDIO : DSi::SDMMC; - DSi_SDDevice* dev = host->Ports[host->PortSelect & 0x1]; + DSi_SDDevice* dev = Ports[PortSelect & 0x1]; - if (host->BlockCountInternal == 0) + if (BlockCountInternal == 0) { - if (host->StopAction & (1<<8)) + if (StopAction & (1<<8)) { if (dev) dev->SendCMD(12, 0); } @@ -330,8 +342,8 @@ void DSi_SDHost::FinishTX(u32 param) // CHECKME: presumably IRQ2 should not trigger here, but rather // when the data transfer is done //SetIRQ(0); - host->SetIRQ(2); - host->TXReq = false; + SetIRQ(2); + TXReq = false; } else { @@ -392,7 +404,7 @@ u32 DSi_SDHost::DataTX(u8* data, u32 len) BlockCountInternal--; NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, - false, 512, FinishTX, Num); + false, 512, Transfer_TX, 0); return len; } diff --git a/src/DSi_SD.h b/src/DSi_SD.h index 8e53a77..577572c 100644 --- a/src/DSi_SD.h +++ b/src/DSi_SD.h @@ -43,8 +43,8 @@ public: void DoSavestate(Savestate* file); - static void FinishRX(u32 param); - static void FinishTX(u32 param); + void FinishRX(u32 param); + void FinishTX(u32 param); void SendResponse(u32 val, bool last); u32 DataRX(u8* data, u32 len); u32 DataTX(u8* data, u32 len); diff --git a/src/GPU.cpp b/src/GPU.cpp index 630e88d..0cbc599 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -36,6 +36,13 @@ namespace GPU #define HBLANK_CYCLES (48+(256*6)) #define FRAME_CYCLES (LINE_CYCLES * 263) +enum +{ + LCD_StartHBlank = 0, + LCD_StartScanline, + LCD_FinishFrame, +}; + u16 VCount; u32 NextVCount; u16 TotalScanlines; @@ -151,6 +158,11 @@ std::unique_ptr<GLCompositor> CurGLCompositor = {}; bool Init() { + NDS::RegisterEventFunc(NDS::Event_LCD, LCD_StartHBlank, StartHBlank); + NDS::RegisterEventFunc(NDS::Event_LCD, LCD_StartScanline, StartScanline); + NDS::RegisterEventFunc(NDS::Event_LCD, LCD_FinishFrame, FinishFrame); + NDS::RegisterEventFunc(NDS::Event_DisplayFIFO, 0, DisplayFIFO); + GPU2D_Renderer = std::make_unique<GPU2D::SoftRenderer>(); if (!GPU3D::Init()) return false; @@ -180,6 +192,11 @@ void DeInit() #ifdef OGLRENDERER_ENABLED CurGLCompositor = nullptr; #endif + + NDS::UnregisterEventFunc(NDS::Event_LCD, LCD_StartHBlank); + NDS::UnregisterEventFunc(NDS::Event_LCD, LCD_StartScanline); + NDS::UnregisterEventFunc(NDS::Event_LCD, LCD_FinishFrame); + NDS::UnregisterEventFunc(NDS::Event_DisplayFIFO, 0); } void ResetVRAMCache() @@ -1022,7 +1039,7 @@ void DisplayFIFO(u32 x) { // transfer the next 8 pixels NDS::CheckDMAs(0, 0x04); - NDS::ScheduleEvent(NDS::Event_DisplayFIFO, true, 6*8, DisplayFIFO, x+8); + NDS::ScheduleEvent(NDS::Event_DisplayFIFO, true, 6*8, 0, x+8); } else GPU2D_A.SampleFIFO(253, 3); // sample the remaining pixels @@ -1077,9 +1094,9 @@ void StartHBlank(u32 line) if (DispStat[1] & (1<<4)) NDS::SetIRQ(1, NDS::IRQ_HBlank); if (VCount < 262) - NDS::ScheduleEvent(NDS::Event_LCD, true, (LINE_CYCLES - HBLANK_CYCLES), StartScanline, line+1); + NDS::ScheduleEvent(NDS::Event_LCD, true, (LINE_CYCLES - HBLANK_CYCLES), LCD_StartScanline, line+1); else - NDS::ScheduleEvent(NDS::Event_LCD, true, (LINE_CYCLES - HBLANK_CYCLES), FinishFrame, line+1); + NDS::ScheduleEvent(NDS::Event_LCD, true, (LINE_CYCLES - HBLANK_CYCLES), LCD_FinishFrame, line+1); } void FinishFrame(u32 lines) @@ -1164,7 +1181,7 @@ void StartScanline(u32 line) } if (RunFIFO) - NDS::ScheduleEvent(NDS::Event_DisplayFIFO, false, 32, DisplayFIFO, 0); + NDS::ScheduleEvent(NDS::Event_DisplayFIFO, false, 32, 0, 0); } if (VCount == 262) @@ -1210,7 +1227,7 @@ void StartScanline(u32 line) } } - NDS::ScheduleEvent(NDS::Event_LCD, true, HBLANK_CYCLES, StartHBlank, line); + NDS::ScheduleEvent(NDS::Event_LCD, true, HBLANK_CYCLES, LCD_StartHBlank, line); } diff --git a/src/NDS.cpp b/src/NDS.cpp index 832661a..0efd0e9 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -104,6 +104,14 @@ u64 ARM9Timestamp, ARM9Target; u64 ARM7Timestamp, ARM7Target; u64 SysTimestamp; +struct SchedEvent +{ + std::map<u32, EventFunc> Funcs; + u64 Timestamp; + u32 FuncID; + u32 Param; +}; + SchedEvent SchedList[Event_MAX]; u32 SchedListMask; @@ -184,6 +192,9 @@ void SetGBASlotTimings(); bool Init() { + RegisterEventFunc(Event_Div, 0, DivDone); + RegisterEventFunc(Event_Sqrt, 0, SqrtDone); + ARM9 = new ARMv5(); ARM7 = new ARMv4(); @@ -248,6 +259,9 @@ void DeInit() DSi::DeInit(); AREngine::DeInit(); + + UnregisterEventFunc(Event_Div, 0); + UnregisterEventFunc(Event_Sqrt, 0); } @@ -608,7 +622,14 @@ void Reset() for (i = 0; i < 8; i++) DMAs[i]->Reset(); memset(DMA9Fill, 0, 4*4); - memset(SchedList, 0, sizeof(SchedList)); + for (i = 0; i < Event_MAX; i++) + { + SchedEvent& evt = SchedList[i]; + + evt.Timestamp = 0; + evt.FuncID = 0; + evt.Param = 0; + } SchedListMask = 0; KeyInput = 0x007F03FF; @@ -699,106 +720,6 @@ void Stop(Platform::StopReason reason) DSi::Stop(); } -bool DoSavestate_Scheduler(Savestate* file) -{ - // this is a bit of a hack - // but uh, your local coder realized that the scheduler list contains function pointers - // and that storing those as-is is not a very good idea - // unless you want it to crash and burn - - // this is the solution your local coder came up with. - // it's gross but I think it's the best solution for this problem. - // just remember to add here if you add more event callbacks, kay? - // atleast until we come up with something more elegant. - - void (*eventfuncs[])(u32) = - { - GPU::StartScanline, GPU::StartHBlank, GPU::FinishFrame, - SPU::Mix, - Wifi::USTimer, - RTC::ClockTimer, - - GPU::DisplayFIFO, - NDSCart::ROMPrepareData, NDSCart::ROMEndTransfer, - NDSCart::SPITransferDone, - SPI::TransferDone, - DivDone, - SqrtDone, - - DSi_SDHost::FinishRX, - DSi_SDHost::FinishTX, - DSi_NWifi::MSTimer, - DSi_CamModule::IRQ, - DSi_CamModule::TransferScanline, - DSi_DSP::DSPCatchUpU32, - - nullptr - }; - - int len = Event_MAX; - if (file->Saving) - { - for (int i = 0; i < len; i++) - { - SchedEvent* evt = &SchedList[i]; - - u32 funcid = 0xFFFFFFFF; - if (evt->Func) - { - for (int j = 0; eventfuncs[j]; j++) - { - if (evt->Func == eventfuncs[j]) - { - funcid = j; - break; - } - } - if (funcid == 0xFFFFFFFF) - { - Log(LogLevel::Error, "savestate: VERY BAD!!!!! FUNCTION POINTER FOR EVENT %d NOT IN HACKY LIST. CANNOT SAVE. SMACK ARISOTURA.\n", i); - return false; - } - } - - file->Var32(&funcid); - file->Var64(&evt->Timestamp); - file->Var32(&evt->Param); - } - } - else - { - for (int i = 0; i < len; i++) - { - SchedEvent* evt = &SchedList[i]; - - u32 funcid; - file->Var32(&funcid); - - if (funcid != 0xFFFFFFFF) - { - for (int j = 0; ; j++) - { - if (!eventfuncs[j]) - { - Log(LogLevel::Error, "savestate: VERY BAD!!!!!! EVENT FUNCTION POINTER ID %d IS OUT OF RANGE. HAX?????\n", j); - return false; - } - if (j == funcid) break; - } - - evt->Func = eventfuncs[funcid]; - } - else - evt->Func = nullptr; - - file->Var64(&evt->Timestamp); - file->Var32(&evt->Param); - } - } - - return true; -} - bool DoSavestate(Savestate* file) { file->Section("NDSG"); @@ -871,10 +792,13 @@ bool DoSavestate(Savestate* file) file->VarArray(DMA9Fill, 4*sizeof(u32)); - if (!DoSavestate_Scheduler(file)) + for (int i = 0; i < Event_MAX; i++) { - Platform::Log(Platform::LogLevel::Error, "savestate: failed to %s scheduler state\n", file->Saving ? "save" : "load"); - return false; + SchedEvent& evt = SchedList[i]; + + file->Var64(&evt.Timestamp); + file->Var32(&evt.FuncID); + file->Var32(&evt.Param); } file->Var32(&SchedListMask); file->Var64(&ARM9Timestamp); @@ -1050,10 +974,14 @@ void RunSystem(u64 timestamp) if (!mask) break; if (mask & 0x1) { - if (SchedList[i].Timestamp <= SysTimestamp) + SchedEvent& evt = SchedList[i]; + + if (evt.Timestamp <= SysTimestamp) { SchedListMask &= ~(1<<i); - SchedList[i].Func(SchedList[i].Param); + + EventFunc func = evt.Funcs[evt.FuncID]; + func(evt.Param); } } @@ -1097,7 +1025,9 @@ void RunSystemSleep(u64 timestamp) { if (mask & 0x1) { - if (SchedList[i].Timestamp <= SysTimestamp) + SchedEvent& evt = SchedList[i]; + + if (evt.Timestamp <= SysTimestamp) { SchedListMask &= ~(1<<i); @@ -1105,9 +1035,10 @@ void RunSystemSleep(u64 timestamp) if (i == Event_SPU) param = 1; else - param = SchedList[i].Param; + param = evt.Param; - SchedList[i].Func(param); + EventFunc func = evt.Funcs[evt.FuncID]; + func(param); } } } @@ -1298,7 +1229,21 @@ void Reschedule(u64 target) } } -void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 param) +void RegisterEventFunc(u32 id, u32 funcid, EventFunc func) +{ + SchedEvent& evt = SchedList[id]; + + evt.Funcs[funcid] = func; +} + +void UnregisterEventFunc(u32 id, u32 funcid) +{ + SchedEvent& evt = SchedList[id]; + + evt.Funcs.erase(funcid); +} + +void ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param) { if (SchedListMask & (1<<id)) { @@ -1306,43 +1251,24 @@ void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 para return; } - SchedEvent* evt = &SchedList[id]; + SchedEvent& evt = SchedList[id]; if (periodic) - evt->Timestamp += delay; + evt.Timestamp += delay; else { if (CurCPU == 0) - evt->Timestamp = (ARM9Timestamp >> ARM9ClockShift) + delay; + evt.Timestamp = (ARM9Timestamp >> ARM9ClockShift) + delay; else - evt->Timestamp = ARM7Timestamp + delay; - } - - evt->Func = func; - evt->Param = param; - - SchedListMask |= (1<<id); - - Reschedule(evt->Timestamp); -} - -void ScheduleEvent(u32 id, u64 timestamp, void (*func)(u32), u32 param) -{ - if (SchedListMask & (1<<id)) - { - Log(LogLevel::Debug, "!! EVENT %d ALREADY SCHEDULED\n", id); - return; + evt.Timestamp = ARM7Timestamp + delay; } - SchedEvent* evt = &SchedList[id]; - - evt->Timestamp = timestamp; - evt->Func = func; - evt->Param = param; + evt.FuncID = funcid; + evt.Param = param; SchedListMask |= (1<<id); - Reschedule(evt->Timestamp); + Reschedule(evt.Timestamp); } void CancelEvent(u32 id) @@ -2096,7 +2022,7 @@ void StartDiv() { NDS::CancelEvent(NDS::Event_Div); DivCnt |= 0x8000; - NDS::ScheduleEvent(NDS::Event_Div, false, ((DivCnt&0x3)==0) ? 18:34, DivDone, 0); + NDS::ScheduleEvent(NDS::Event_Div, false, ((DivCnt&0x3)==0) ? 18:34, 0, 0); } // http://stackoverflow.com/questions/1100090/looking-for-an-efficient-integer-square-root-algorithm-for-arm-thumb2 @@ -2144,7 +2070,7 @@ void StartSqrt() { NDS::CancelEvent(NDS::Event_Sqrt); SqrtCnt |= 0x8000; - NDS::ScheduleEvent(NDS::Event_Sqrt, false, 13, SqrtDone, 0); + NDS::ScheduleEvent(NDS::Event_Sqrt, false, 13, 0, 0); } @@ -20,6 +20,7 @@ #define NDS_H #include <string> +#include <functional> #include "Platform.h" #include "Savestate.h" @@ -57,12 +58,8 @@ enum Event_MAX }; -struct SchedEvent -{ - void (*Func)(u32 param); - u64 Timestamp; - u32 Param; -}; +typedef std::function<void(u32)> EventFunc; +#define MemberEventFunc(cls,func) std::bind(&cls::func,this,std::placeholders::_1) enum { @@ -297,8 +294,9 @@ void SetLidClosed(bool closed); void CamInputFrame(int cam, u32* data, int width, int height, bool rgb); void MicInputFrame(s16* data, int samples); -void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 param); -void ScheduleEvent(u32 id, u64 timestamp, void (*func)(u32), u32 param); +void RegisterEventFunc(u32 id, u32 funcid, EventFunc func); +void UnregisterEventFunc(u32 id, u32 funcid); +void ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param); void CancelEvent(u32 id); void debug(u32 p); diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 400f7d6..33d7795 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -34,6 +34,12 @@ using Platform::LogLevel; namespace NDSCart { +enum +{ + ROMTransfer_PrepareData = 0, + ROMTransfer_End +}; + // SRAM TODO: emulate write delays??? u16 SPICnt; @@ -1468,6 +1474,10 @@ void CartHomebrew::ReadROM_B7(u32 addr, u32 len, u8* data, u32 offset) bool Init() { + NDS::RegisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_PrepareData, ROMPrepareData); + NDS::RegisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_End, ROMEndTransfer); + NDS::RegisterEventFunc(NDS::Event_ROMSPITransfer, 0, SPITransferDone); + Cart = nullptr; return true; @@ -1476,6 +1486,10 @@ bool Init() void DeInit() { Cart = nullptr; + + NDS::UnregisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_PrepareData); + NDS::UnregisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_End); + NDS::UnregisterEventFunc(NDS::Event_ROMSPITransfer, 0); } void Reset() @@ -1967,9 +1981,9 @@ void WriteROMCnt(u32 val) } if (datasize == 0) - NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*cmddelay, ROMEndTransfer, 0); + NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*cmddelay, ROMTransfer_End, 0); else - NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*(cmddelay+4), ROMPrepareData, 0); + NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*(cmddelay+4), ROMTransfer_PrepareData, 0); } void AdvanceROMTransfer() @@ -1986,7 +2000,7 @@ void AdvanceROMTransfer() delay += ((ROMCnt >> 16) & 0x3F); } - NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*delay, ROMPrepareData, 0); + NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*delay, ROMTransfer_PrepareData, 0); } else ROMEndTransfer(0); @@ -2088,7 +2102,7 @@ void WriteSPIData(u8 val) // SPI transfers one bit per cycle -> 8 cycles per byte u32 delay = 8 * (8 << (SPICnt & 0x3)); - NDS::ScheduleEvent(NDS::Event_ROMSPITransfer, false, delay, SPITransferDone, 0); + NDS::ScheduleEvent(NDS::Event_ROMSPITransfer, false, delay, 0, 0); } } diff --git a/src/RTC.cpp b/src/RTC.cpp index 3d25226..527b7f4 100644 --- a/src/RTC.cpp +++ b/src/RTC.cpp @@ -53,6 +53,8 @@ void WriteDateTime(int num, u8 val); bool Init() { + NDS::RegisterEventFunc(NDS::Event_RTC, 0, ClockTimer); + ResetState(); // indicate the power was off @@ -64,6 +66,7 @@ bool Init() void DeInit() { + NDS::UnregisterEventFunc(NDS::Event_RTC, 0); } void Reset() @@ -538,7 +541,7 @@ void ScheduleTimer(bool first) s32 delay = sysclock >> 15; TimerError = sysclock & 0x7FFF; - NDS::ScheduleEvent(NDS::Event_RTC, !first, delay, ClockTimer, 0); + NDS::ScheduleEvent(NDS::Event_RTC, !first, delay, 0, 0); } void ClockTimer(u32 param) diff --git a/src/SPI.cpp b/src/SPI.cpp index a755c44..1a4c12e 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -612,6 +612,8 @@ u32 CurDevice; // remove me bool Init() { + NDS::RegisterEventFunc(NDS::Event_SPITransfer, 0, TransferDone); + if (!SPI_Firmware::Init()) return false; if (!SPI_Powerman::Init()) return false; if (!SPI_TSC::Init()) return false; @@ -626,6 +628,8 @@ void DeInit() SPI_Powerman::DeInit(); SPI_TSC::DeInit(); DSi_SPI_TSC::DeInit(); + + NDS::UnregisterEventFunc(NDS::Event_SPITransfer, 0); } void Reset() @@ -725,7 +729,7 @@ void WriteData(u8 val) // SPI transfers one bit per cycle -> 8 cycles per byte u32 delay = 8 * (8 << (Cnt & 0x3)); - NDS::ScheduleEvent(NDS::Event_SPITransfer, false, delay, TransferDone, 0); + NDS::ScheduleEvent(NDS::Event_SPITransfer, false, delay, 0, 0); } } diff --git a/src/SPU.cpp b/src/SPU.cpp index 76fdd2d..cdfc244 100644 --- a/src/SPU.cpp +++ b/src/SPU.cpp @@ -93,6 +93,8 @@ CaptureUnit* Capture[2]; bool Init() { + NDS::RegisterEventFunc(NDS::Event_SPU, 0, Mix); + for (int i = 0; i < 16; i++) Channels[i] = new Channel(i); @@ -147,6 +149,8 @@ void DeInit() Platform::Mutex_Free(AudioLock); AudioLock = nullptr; + + NDS::UnregisterEventFunc(NDS::Event_SPU, 0); } void Reset() @@ -163,7 +167,7 @@ void Reset() Capture[0]->Reset(); Capture[1]->Reset(); - NDS::ScheduleEvent(NDS::Event_SPU, false, 1024, Mix, 0); + NDS::ScheduleEvent(NDS::Event_SPU, false, 1024, 0, 0); } void Stop() @@ -864,7 +868,7 @@ void Mix(u32 dummy) OutputBackbufferWritePosition += 2; } - NDS::ScheduleEvent(NDS::Event_SPU, true, 1024, Mix, 0); + NDS::ScheduleEvent(NDS::Event_SPU, true, 1024, 0, 0); } void TransferOutput() diff --git a/src/Wifi.cpp b/src/Wifi.cpp index d786cd0..c5a67ab 100644 --- a/src/Wifi.cpp +++ b/src/Wifi.cpp @@ -150,6 +150,8 @@ u64 RXTimestamp; bool Init() { + NDS::RegisterEventFunc(NDS::Event_Wifi, 0, USTimer); + //MPInited = false; //LANInited = false; @@ -172,6 +174,8 @@ void DeInit() Platform::LAN_DeInit(); WifiAP::DeInit(); + + NDS::UnregisterEventFunc(NDS::Event_Wifi, 0); } void Reset() @@ -359,7 +363,7 @@ void ScheduleTimer(bool first) s32 delay = (cycles + 999999) / 1000000; TimerError = (delay * 1000000) - cycles; - NDS::ScheduleEvent(NDS::Event_Wifi, !first, delay, USTimer, 0); + NDS::ScheduleEvent(NDS::Event_Wifi, !first, delay, 0, 0); } void UpdatePowerOn() |