better, less hacky, more OOP-friendly scheduler design

This commit is contained in:
Arisotura 2023-11-02 21:04:09 +01:00
parent 5ccd3916ff
commit 70c6750561
14 changed files with 203 additions and 219 deletions

View File

@ -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);
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
CheckSwapFIFO();
host->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;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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.Timestamp = ARM7Timestamp + delay;
}
evt->Func = func;
evt->Param = param;
evt.FuncID = funcid;
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;
}
SchedEvent* evt = &SchedList[id];
evt->Timestamp = timestamp;
evt->Func = func;
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);
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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()

View File

@ -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()