add proper support for GXFIFO stalls.

bad games that blast the GXFIFO and overflow it:
* Super Mario 64 DS
* Rayman RR2

latter seems to get its music streaming crapoed.
This commit is contained in:
StapleButter
2018-11-23 22:21:41 +01:00
parent 27e1ca4103
commit a9e7f8bc5b
8 changed files with 140 additions and 34 deletions

View File

@ -108,6 +108,7 @@ bool Running;
void DivDone(u32 param);
void SqrtDone(u32 param);
void RunTimer(u32 tid, s32 cycles);
bool Init()
@ -608,12 +609,27 @@ u32 RunFrame()
s32 ndscyclestorun;
// TODO: give it some margin, so it can directly do 17 cycles instead of 16 then 1
// TODO: we need to directly change CurIterationCycles when rescheduling shit
CalcIterationCycles();
if (CPUStop & 0x80000000)
{
// GXFIFO stall
// we just run the GPU and the timers.
// the rest of the hardware is driven by the event scheduler.
s32 cycles = GPU3D::CyclesToRunFor();
GPU3D::Run(cycles);
u32 timermask = TimerCheckMask[0];
if (timermask & 0x1) RunTimer(0, cycles);
if (timermask & 0x2) RunTimer(1, cycles);
if (timermask & 0x4) RunTimer(2, cycles);
if (timermask & 0x8) RunTimer(3, cycles);
timermask = TimerCheckMask[1];
if (timermask & 0x1) RunTimer(4, cycles);
if (timermask & 0x2) RunTimer(5, cycles);
if (timermask & 0x4) RunTimer(6, cycles);
if (timermask & 0x8) RunTimer(7, cycles);
}
else
{
@ -818,6 +834,27 @@ void ResumeCPU(u32 cpu, u32 mask)
CPUStop &= ~mask;
}
void GXFIFOStall()
{
if (CPUStop & 0x80000000) return;
CPUStop |= 0x80000000;
if (CurCPU == 1) ARM9->Halt(2);
else
{
DMAs[0]->StallIfRunning();
DMAs[1]->StallIfRunning();
DMAs[2]->StallIfRunning();
DMAs[3]->StallIfRunning();
}
}
void GXFIFOUnstall()
{
CPUStop &= ~0x80000000;
}
u32 GetPC(u32 cpu)
{
return cpu ? ARM7->R[15] : ARM9->R[15];