mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-16 10:49:47 -06:00
redesign main emu loop to use timestamps instead of being a trainwreck
* cleaner code * faster in some cases * more accurate (on-demand compensation for timers and GPU) * less prone to desyncs * overall betterer
This commit is contained in:
@ -91,6 +91,7 @@
|
||||
// and imposes rules on when further vertex commands can run
|
||||
// (one every 9-cycle time slot during polygon setup)
|
||||
// polygon setup time is 27 cycles for a triangle and 36 for a quad
|
||||
// except: only one time slot is taken if the polygon is rejected by culling/clipping
|
||||
// * additionally, some commands (BEGIN, LIGHT_VECTOR, BOXTEST) stall the polygon pipeline
|
||||
|
||||
|
||||
@ -182,6 +183,7 @@ u32 GXStat;
|
||||
u32 ExecParams[32];
|
||||
u32 ExecParamCount;
|
||||
|
||||
u64 Timestamp;
|
||||
s32 CycleCount;
|
||||
s32 VertexPipeline;
|
||||
s32 NormalPipeline;
|
||||
@ -330,6 +332,7 @@ void Reset()
|
||||
memset(ExecParams, 0, 32*4);
|
||||
ExecParamCount = 0;
|
||||
|
||||
Timestamp = 0;
|
||||
CycleCount = 0;
|
||||
VertexPipeline = 0;
|
||||
NormalPipeline = 0;
|
||||
@ -405,6 +408,7 @@ void DoSavestate(Savestate* file)
|
||||
file->VarArray(ExecParams, 32*4);
|
||||
file->Var32(&ExecParamCount);
|
||||
file->Var32((u32*)&CycleCount);
|
||||
file->Var64(&Timestamp);
|
||||
|
||||
file->Var32(&MatrixMode);
|
||||
|
||||
@ -2271,16 +2275,18 @@ void FinishWork(s32 cycles)
|
||||
GXStat &= ~(1<<27);
|
||||
}
|
||||
|
||||
void Run(s32 cycles)
|
||||
void Run()
|
||||
{
|
||||
if (!GeometryEnabled)
|
||||
return;
|
||||
if (FlushRequest)
|
||||
return;
|
||||
if (CmdPIPE->IsEmpty() && !(GXStat & (1<<27)))
|
||||
if (!GeometryEnabled || FlushRequest ||
|
||||
(CmdPIPE->IsEmpty() && !(GXStat & (1<<27))))
|
||||
{
|
||||
Timestamp = NDS::ARM9Timestamp >> NDS::ARM9ClockShift;
|
||||
return;
|
||||
}
|
||||
|
||||
s32 cycles = (NDS::ARM9Timestamp >> NDS::ARM9ClockShift) - Timestamp;
|
||||
CycleCount -= cycles;
|
||||
Timestamp = NDS::ARM9Timestamp >> NDS::ARM9ClockShift;
|
||||
|
||||
if (CycleCount <= 0)
|
||||
{
|
||||
@ -2465,21 +2471,27 @@ u8 Read8(u32 addr)
|
||||
switch (addr)
|
||||
{
|
||||
case 0x04000600:
|
||||
Run();
|
||||
return GXStat & 0xFF;
|
||||
case 0x04000601:
|
||||
{
|
||||
Run();
|
||||
return ((GXStat >> 8) & 0xFF) |
|
||||
(PosMatrixStackPointer & 0x1F) |
|
||||
((ProjMatrixStackPointer & 0x1) << 5);
|
||||
}
|
||||
case 0x04000602:
|
||||
{
|
||||
Run();
|
||||
|
||||
u32 fifolevel = CmdFIFO->Level();
|
||||
|
||||
return fifolevel & 0xFF;
|
||||
}
|
||||
case 0x04000603:
|
||||
{
|
||||
Run();
|
||||
|
||||
u32 fifolevel = CmdFIFO->Level();
|
||||
|
||||
return ((GXStat >> 24) & 0xFF) |
|
||||
@ -2505,12 +2517,16 @@ u16 Read16(u32 addr)
|
||||
|
||||
case 0x04000600:
|
||||
{
|
||||
Run();
|
||||
|
||||
return (GXStat & 0xFFFF) |
|
||||
((PosMatrixStackPointer & 0x1F) << 8) |
|
||||
((ProjMatrixStackPointer & 0x1) << 13);
|
||||
}
|
||||
case 0x04000602:
|
||||
{
|
||||
Run();
|
||||
|
||||
u32 fifolevel = CmdFIFO->Level();
|
||||
|
||||
return (GXStat >> 16) |
|
||||
@ -2545,6 +2561,8 @@ u32 Read32(u32 addr)
|
||||
|
||||
case 0x04000600:
|
||||
{
|
||||
Run();
|
||||
|
||||
u32 fifolevel = CmdFIFO->Level();
|
||||
|
||||
return GXStat |
|
||||
|
Reference in New Issue
Block a user