mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
* Rename cpuBranch[...] functions and vars to cpuEvent[...], which should be more clear and consistent as to their true purpose. (to clarify: events typically run during cpu branch instructions, but most branches don't actually have anything to do with whether or not there are events pending or events being run).
* Add some missing & ~0x0f address alignment stuff to odd-size FIFO reads/writes (thanks gregory) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3730 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
1698382065
commit
3cfd0c68af
@ -38,7 +38,7 @@ __ri void cpuUpdateOperationMode() {
|
|||||||
void __fastcall WriteCP0Status(u32 value) {
|
void __fastcall WriteCP0Status(u32 value) {
|
||||||
cpuRegs.CP0.n.Status.val = value;
|
cpuRegs.CP0.n.Status.val = value;
|
||||||
cpuUpdateOperationMode();
|
cpuUpdateOperationMode();
|
||||||
cpuSetNextBranchDelta(4);
|
cpuSetNextEventDelta(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapTLB(int i)
|
void MapTLB(int i)
|
||||||
@ -534,7 +534,7 @@ void ERET() {
|
|||||||
cpuRegs.CP0.n.Status.b.EXL = 0;
|
cpuRegs.CP0.n.Status.b.EXL = 0;
|
||||||
}
|
}
|
||||||
cpuUpdateOperationMode();
|
cpuUpdateOperationMode();
|
||||||
cpuSetNextBranchDelta(4);
|
cpuSetNextEventDelta(4);
|
||||||
intSetBranch();
|
intSetBranch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,7 +543,7 @@ void DI() {
|
|||||||
cpuRegs.CP0.n.Status.b.ERL || (cpuRegs.CP0.n.Status.b.KSU == 0)) {
|
cpuRegs.CP0.n.Status.b.ERL || (cpuRegs.CP0.n.Status.b.KSU == 0)) {
|
||||||
cpuRegs.CP0.n.Status.b.EIE = 0;
|
cpuRegs.CP0.n.Status.b.EIE = 0;
|
||||||
// IRQs are disabled so no need to do a cpu exception/event test...
|
// IRQs are disabled so no need to do a cpu exception/event test...
|
||||||
//cpuSetNextBranchDelta();
|
//cpuSetNextEventDelta();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -552,7 +552,7 @@ void EI() {
|
|||||||
cpuRegs.CP0.n.Status.b.ERL || (cpuRegs.CP0.n.Status.b.KSU == 0)) {
|
cpuRegs.CP0.n.Status.b.ERL || (cpuRegs.CP0.n.Status.b.KSU == 0)) {
|
||||||
cpuRegs.CP0.n.Status.b.EIE = 1;
|
cpuRegs.CP0.n.Status.b.EIE = 1;
|
||||||
// schedule an event test, which will check for and raise pending IRQs.
|
// schedule an event test, which will check for and raise pending IRQs.
|
||||||
cpuSetNextBranchDelta(4);
|
cpuSetNextEventDelta(4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
#define __COP0_H__
|
#define __COP0_H__
|
||||||
|
|
||||||
extern void __fastcall WriteCP0Status(u32 value);
|
extern void __fastcall WriteCP0Status(u32 value);
|
||||||
extern void UpdateCP0Status();
|
extern void cpuUpdateOperationMode();
|
||||||
extern void WriteTLB(int i);
|
extern void WriteTLB(int i);
|
||||||
extern void UnmapTLB(int i);
|
extern void UnmapTLB(int i);
|
||||||
extern void MapTLB(int i);
|
extern void MapTLB(int i);
|
||||||
|
|||||||
@ -93,7 +93,7 @@ static __fi void _rcntSet( int cntidx )
|
|||||||
if (c < nextCounter)
|
if (c < nextCounter)
|
||||||
{
|
{
|
||||||
nextCounter = c;
|
nextCounter = c;
|
||||||
cpuSetNextBranch( nextsCounter, nextCounter ); //Need to update on counter resets/target changes
|
cpuSetNextEvent( nextsCounter, nextCounter ); //Need to update on counter resets/target changes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore target diff if target is currently disabled.
|
// Ignore target diff if target is currently disabled.
|
||||||
@ -111,7 +111,7 @@ static __fi void _rcntSet( int cntidx )
|
|||||||
if (c < nextCounter)
|
if (c < nextCounter)
|
||||||
{
|
{
|
||||||
nextCounter = c;
|
nextCounter = c;
|
||||||
cpuSetNextBranch( nextsCounter, nextCounter ); //Need to update on counter resets/target changes
|
cpuSetNextEvent( nextsCounter, nextCounter ); //Need to update on counter resets/target changes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -419,7 +419,7 @@ __fi void rcntUpdate_hScanline()
|
|||||||
{
|
{
|
||||||
if( !cpuTestCycle( hsyncCounter.sCycle, hsyncCounter.CycleT ) ) return;
|
if( !cpuTestCycle( hsyncCounter.sCycle, hsyncCounter.CycleT ) ) return;
|
||||||
|
|
||||||
//iopBranchAction = 1;
|
//iopEventAction = 1;
|
||||||
if (hsyncCounter.Mode & MODE_HBLANK) { //HBLANK Start
|
if (hsyncCounter.Mode & MODE_HBLANK) { //HBLANK Start
|
||||||
rcntStartGate(false, hsyncCounter.sCycle);
|
rcntStartGate(false, hsyncCounter.sCycle);
|
||||||
psxCheckStartGate16(0);
|
psxCheckStartGate16(0);
|
||||||
@ -890,6 +890,6 @@ void SaveStateBase::rcntFreeze()
|
|||||||
for( int i=0; i<4; i++ )
|
for( int i=0; i<4; i++ )
|
||||||
_rcntSetGate( i );
|
_rcntSetGate( i );
|
||||||
|
|
||||||
iopBranchAction = 1; // probably not needed but won't hurt anything either.
|
iopEventAction = 1; // probably not needed but won't hurt anything either.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,7 +55,7 @@ void iDumpPsxRegisters(u32 startpc, u32 temp)
|
|||||||
|
|
||||||
for(i = 0; i < 34; i+=2) __Log("%spsx%s: %x %x", pstr, disRNameGPR[i], psxRegs.GPR.r[i], psxRegs.GPR.r[i+1]);
|
for(i = 0; i < 34; i+=2) __Log("%spsx%s: %x %x", pstr, disRNameGPR[i], psxRegs.GPR.r[i], psxRegs.GPR.r[i+1]);
|
||||||
|
|
||||||
DbgCon.WriteLn("%scycle: %x %x %x; counters %x %x", pstr, psxRegs.cycle, g_psxNextBranchCycle, EEsCycle,
|
DbgCon.WriteLn("%scycle: %x %x %x; counters %x %x", pstr, psxRegs.cycle, g_iopNextEventCycle, EEsCycle,
|
||||||
psxNextsCounter, psxNextCounter);
|
psxNextsCounter, psxNextCounter);
|
||||||
|
|
||||||
DbgCon.WriteLn(wxsFormat(L"psxdma%d ", 2) + hw_dma(2).desc());
|
DbgCon.WriteLn(wxsFormat(L"psxdma%d ", 2) + hw_dma(2).desc());
|
||||||
@ -109,7 +109,7 @@ void iDumpRegisters(u32 startpc, u32 temp)
|
|||||||
__Log("%svfACC: %x %x %x %x", pstr, VU0.ACC.UL[3], VU0.ACC.UL[2], VU0.ACC.UL[1], VU0.ACC.UL[0]);
|
__Log("%svfACC: %x %x %x %x", pstr, VU0.ACC.UL[3], VU0.ACC.UL[2], VU0.ACC.UL[1], VU0.ACC.UL[0]);
|
||||||
__Log("%sLO: %x_%x_%x_%x, HI: %x_%x_%x_%x", pstr, cpuRegs.LO.UL[3], cpuRegs.LO.UL[2], cpuRegs.LO.UL[1], cpuRegs.LO.UL[0],
|
__Log("%sLO: %x_%x_%x_%x, HI: %x_%x_%x_%x", pstr, cpuRegs.LO.UL[3], cpuRegs.LO.UL[2], cpuRegs.LO.UL[1], cpuRegs.LO.UL[0],
|
||||||
cpuRegs.HI.UL[3], cpuRegs.HI.UL[2], cpuRegs.HI.UL[1], cpuRegs.HI.UL[0]);
|
cpuRegs.HI.UL[3], cpuRegs.HI.UL[2], cpuRegs.HI.UL[1], cpuRegs.HI.UL[0]);
|
||||||
__Log("%sCycle: %x %x, Count: %x", pstr, cpuRegs.cycle, g_nextBranchCycle, cpuRegs.CP0.n.Count);
|
__Log("%sCycle: %x %x, Count: %x", pstr, cpuRegs.cycle, g_nextEventCycle, cpuRegs.CP0.n.Count);
|
||||||
|
|
||||||
iDumpPsxRegisters(psxRegs.pc, temp);
|
iDumpPsxRegisters(psxRegs.pc, temp);
|
||||||
|
|
||||||
|
|||||||
@ -27,8 +27,8 @@ static __fi void IntCHackCheck()
|
|||||||
{
|
{
|
||||||
// Sanity check: To protect from accidentally "rewinding" the cyclecount
|
// Sanity check: To protect from accidentally "rewinding" the cyclecount
|
||||||
// on the few times nextBranchCycle can be behind our current cycle.
|
// on the few times nextBranchCycle can be behind our current cycle.
|
||||||
s32 diff = g_nextBranchCycle - cpuRegs.cycle;
|
s32 diff = g_nextEventCycle - cpuRegs.cycle;
|
||||||
if( diff > 0 ) cpuRegs.cycle = g_nextBranchCycle;
|
if( diff > 0 ) cpuRegs.cycle = g_nextEventCycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint HwF_VerboseConLog = 1<<0;
|
static const uint HwF_VerboseConLog = 1<<0;
|
||||||
@ -65,7 +65,7 @@ mem32_t __fastcall _hwRead32(u32 mem)
|
|||||||
DevCon.WriteLn( Color_Cyan, "Reading 32-bit FIFO data" );
|
DevCon.WriteLn( Color_Cyan, "Reading 32-bit FIFO data" );
|
||||||
|
|
||||||
u128 out128;
|
u128 out128;
|
||||||
_hwRead128<page>(mem, &out128);
|
_hwRead128<page>(mem & ~0x0f, &out128);
|
||||||
return out128._u32[(mem >> 2) & 0x3];
|
return out128._u32[(mem >> 2) & 0x3];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -221,7 +221,7 @@ static void _hwRead64(u32 mem, mem64_t* result )
|
|||||||
DevCon.WriteLn( Color_Cyan, "Reading 64-bit FIFO data (%s 64 bits discarded)", wordpart ? "upper" : "lower" );
|
DevCon.WriteLn( Color_Cyan, "Reading 64-bit FIFO data (%s 64 bits discarded)", wordpart ? "upper" : "lower" );
|
||||||
|
|
||||||
u128 out128;
|
u128 out128;
|
||||||
_hwRead128<page>(mem, &out128);
|
_hwRead128<page>(mem & ~0x0f, &out128);
|
||||||
*result = out128._u64[wordpart];
|
*result = out128._u64[wordpart];
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -68,7 +68,7 @@ void __fastcall _hwWrite32( u32 mem, u32 value )
|
|||||||
zerofill._u32[(mem >> 2) & 0x03] = value;
|
zerofill._u32[(mem >> 2) & 0x03] = value;
|
||||||
|
|
||||||
DevCon.WriteLn( Color_Cyan, "Writing 32-bit FIFO data (zero-extended to 128 bits)" );
|
DevCon.WriteLn( Color_Cyan, "Writing 32-bit FIFO data (zero-extended to 128 bits)" );
|
||||||
_hwWrite128<page>(mem, &zerofill);
|
_hwWrite128<page>(mem & ~0x0f, &zerofill);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -301,7 +301,7 @@ void __fastcall _hwWrite64( u32 mem, const mem64_t* srcval )
|
|||||||
|
|
||||||
u128 zerofill = u128::From32(0);
|
u128 zerofill = u128::From32(0);
|
||||||
zerofill._u64[(mem >> 3) & 0x01] = *srcval;
|
zerofill._u64[(mem >> 3) & 0x01] = *srcval;
|
||||||
hwWrite128<page>(mem, &zerofill);
|
hwWrite128<page>(mem & ~0x0f, &zerofill);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@ -375,7 +375,7 @@ static void intReset()
|
|||||||
static void intEventTest()
|
static void intEventTest()
|
||||||
{
|
{
|
||||||
// Perform counters, ints, and IOP updates:
|
// Perform counters, ints, and IOP updates:
|
||||||
_cpuBranchTest_Shared();
|
_cpuEventTest_Shared();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intExecute()
|
static void intExecute()
|
||||||
|
|||||||
@ -391,7 +391,7 @@ void psxRcntUpdate()
|
|||||||
int i;
|
int i;
|
||||||
//u32 change = 0;
|
//u32 change = 0;
|
||||||
|
|
||||||
g_psxNextBranchCycle = psxRegs.cycle + 32;
|
g_iopNextEventCycle = psxRegs.cycle + 32;
|
||||||
|
|
||||||
psxNextCounter = 0x7fffffff;
|
psxNextCounter = 0x7fffffff;
|
||||||
psxNextsCounter = psxRegs.cycle;
|
psxNextsCounter = psxRegs.cycle;
|
||||||
|
|||||||
@ -51,10 +51,10 @@ static void __fastcall psxDmaGeneric(u32 madr, u32 bcr, u32 chcr, u32 spuCore, _
|
|||||||
if (psxCounters[6].CycleT < psxNextCounter)
|
if (psxCounters[6].CycleT < psxNextCounter)
|
||||||
psxNextCounter = psxCounters[6].CycleT;
|
psxNextCounter = psxCounters[6].CycleT;
|
||||||
|
|
||||||
if((g_psxNextBranchCycle - psxNextsCounter) > (u32)psxNextCounter)
|
if((g_iopNextEventCycle - psxNextsCounter) > (u32)psxNextCounter)
|
||||||
{
|
{
|
||||||
//DevCon.Warning("SPU2async Setting new counter branch, old %x new %x ((%x - %x = %x) > %x delta)", g_psxNextBranchCycle, psxNextsCounter + psxNextCounter, g_psxNextBranchCycle, psxNextsCounter, (g_psxNextBranchCycle - psxNextsCounter), psxNextCounter);
|
//DevCon.Warning("SPU2async Setting new counter branch, old %x new %x ((%x - %x = %x) > %x delta)", g_iopNextEventCycle, psxNextsCounter + psxNextCounter, g_iopNextEventCycle, psxNextsCounter, (g_iopNextEventCycle - psxNextsCounter), psxNextCounter);
|
||||||
g_psxNextBranchCycle = psxNextsCounter + psxNextCounter;
|
g_iopNextEventCycle = psxNextsCounter + psxNextCounter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,22 +29,22 @@ u32 g_psxConstRegs[32];
|
|||||||
u32 g_psxHasConstReg, g_psxFlushedConstReg;
|
u32 g_psxHasConstReg, g_psxFlushedConstReg;
|
||||||
|
|
||||||
// Controls when branch tests are performed.
|
// Controls when branch tests are performed.
|
||||||
u32 g_psxNextBranchCycle = 0;
|
u32 g_iopNextEventCycle = 0;
|
||||||
|
|
||||||
// This value is used when the IOP execution is broken to return control to the EE.
|
// This value is used when the IOP execution is broken to return control to the EE.
|
||||||
// (which happens when the IOP throws EE-bound interrupts). It holds the value of
|
// (which happens when the IOP throws EE-bound interrupts). It holds the value of
|
||||||
// psxCycleEE (which is set to zero to facilitate the code break), so that the unrun
|
// iopCycleEE (which is set to zero to facilitate the code break), so that the unrun
|
||||||
// cycles can be accounted for later.
|
// cycles can be accounted for later.
|
||||||
s32 psxBreak = 0;
|
s32 iopBreak = 0;
|
||||||
|
|
||||||
// tracks the IOP's current sync status with the EE. When it dips below zero,
|
// tracks the IOP's current sync status with the EE. When it dips below zero,
|
||||||
// control is returned to the EE.
|
// control is returned to the EE.
|
||||||
s32 psxCycleEE = -1;
|
s32 iopCycleEE = -1;
|
||||||
|
|
||||||
// Used to signal to the EE when important actions that need IOP-attention have
|
// Used to signal to the EE when important actions that need IOP-attention have
|
||||||
// happened (hsyncs, vsyncs, IOP exceptions, etc). IOP runs code whenever this
|
// happened (hsyncs, vsyncs, IOP exceptions, etc). IOP runs code whenever this
|
||||||
// is true, even if it's already running ahead a bit.
|
// is true, even if it's already running ahead a bit.
|
||||||
bool iopBranchAction = false;
|
bool iopEventAction = false;
|
||||||
|
|
||||||
bool iopEventTestIsActive = false;
|
bool iopEventTestIsActive = false;
|
||||||
|
|
||||||
@ -58,9 +58,9 @@ void psxReset()
|
|||||||
psxRegs.CP0.n.Status = 0x10900000; // COP0 enabled | BEV = 1 | TS = 1
|
psxRegs.CP0.n.Status = 0x10900000; // COP0 enabled | BEV = 1 | TS = 1
|
||||||
psxRegs.CP0.n.PRid = 0x0000001f; // PRevID = Revision ID, same as the IOP R3000A
|
psxRegs.CP0.n.PRid = 0x0000001f; // PRevID = Revision ID, same as the IOP R3000A
|
||||||
|
|
||||||
psxBreak = 0;
|
iopBreak = 0;
|
||||||
psxCycleEE = -1;
|
iopCycleEE = -1;
|
||||||
g_psxNextBranchCycle = psxRegs.cycle + 4;
|
g_iopNextEventCycle = psxRegs.cycle + 4;
|
||||||
|
|
||||||
psxHwReset();
|
psxHwReset();
|
||||||
|
|
||||||
@ -113,8 +113,8 @@ __fi void psxSetNextBranch( u32 startCycle, s32 delta )
|
|||||||
// typecast the conditional to signed so that things don't blow up
|
// typecast the conditional to signed so that things don't blow up
|
||||||
// if startCycle is greater than our next branch cycle.
|
// if startCycle is greater than our next branch cycle.
|
||||||
|
|
||||||
if( (int)(g_psxNextBranchCycle - startCycle) > delta )
|
if( (int)(g_iopNextEventCycle - startCycle) > delta )
|
||||||
g_psxNextBranchCycle = startCycle + delta;
|
g_iopNextEventCycle = startCycle + delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void psxSetNextBranchDelta( s32 delta )
|
__fi void psxSetNextBranchDelta( s32 delta )
|
||||||
@ -151,13 +151,13 @@ __fi void PSX_INT( IopEventId n, s32 ecycle )
|
|||||||
|
|
||||||
psxSetNextBranchDelta( ecycle );
|
psxSetNextBranchDelta( ecycle );
|
||||||
|
|
||||||
if( psxCycleEE < 0 )
|
if( iopCycleEE < 0 )
|
||||||
{
|
{
|
||||||
// The EE called this int, so inform it to branch as needed:
|
// The EE called this int, so inform it to branch as needed:
|
||||||
// fixme - this doesn't take into account EE/IOP sync (the IOP may be running
|
// fixme - this doesn't take into account EE/IOP sync (the IOP may be running
|
||||||
// ahead or behind the EE as per the EEsCycles value)
|
// ahead or behind the EE as per the EEsCycles value)
|
||||||
s32 iopDelta = (g_psxNextBranchCycle-psxRegs.cycle)*8;
|
s32 iopDelta = (g_iopNextEventCycle-psxRegs.cycle)*8;
|
||||||
cpuSetNextBranchDelta( iopDelta );
|
cpuSetNextEventDelta( iopDelta );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,18 +211,18 @@ static __fi void _psxTestInterrupts()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__ri void psxBranchTest()
|
__ri void iopEventTest()
|
||||||
{
|
{
|
||||||
if( psxTestCycle( psxNextsCounter, psxNextCounter ) )
|
if( psxTestCycle( psxNextsCounter, psxNextCounter ) )
|
||||||
{
|
{
|
||||||
psxRcntUpdate();
|
psxRcntUpdate();
|
||||||
iopBranchAction = true;
|
iopEventAction = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// start the next branch at the next counter event by default
|
// start the next branch at the next counter event by default
|
||||||
// the interrupt code below will assign nearer branches if needed.
|
// the interrupt code below will assign nearer branches if needed.
|
||||||
g_psxNextBranchCycle = psxNextsCounter+psxNextCounter;
|
g_iopNextEventCycle = psxNextsCounter+psxNextCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ __ri void psxBranchTest()
|
|||||||
{
|
{
|
||||||
PSXCPU_LOG("Interrupt: %x %x", psxHu32(0x1070), psxHu32(0x1074));
|
PSXCPU_LOG("Interrupt: %x %x", psxHu32(0x1070), psxHu32(0x1074));
|
||||||
psxException(0, 0);
|
psxException(0, 0);
|
||||||
iopBranchAction = true;
|
iopEventAction = true;
|
||||||
|
|
||||||
// No need to execute the SIFhack after cpuExceptions, since these by nature break SIF's
|
// No need to execute the SIFhack after cpuExceptions, since these by nature break SIF's
|
||||||
// thread sleep hangs and allow the IOP to "come back to life."
|
// thread sleep hangs and allow the IOP to "come back to life."
|
||||||
@ -258,9 +258,9 @@ void iopTestIntc()
|
|||||||
// An iop exception has occurred while the EE is running code.
|
// An iop exception has occurred while the EE is running code.
|
||||||
// Inform the EE to branch so the IOP can handle it promptly:
|
// Inform the EE to branch so the IOP can handle it promptly:
|
||||||
|
|
||||||
cpuSetNextBranchDelta( 16 );
|
cpuSetNextEventDelta( 16 );
|
||||||
iopBranchAction = true;
|
iopEventAction = true;
|
||||||
//Console.Error( "** IOP Needs an EE EventText, kthx ** %d", psxCycleEE );
|
//Console.Error( "** IOP Needs an EE EventText, kthx ** %d", iopCycleEE );
|
||||||
|
|
||||||
// Note: No need to set the iop's branch delta here, since the EE
|
// Note: No need to set the iop's branch delta here, since the EE
|
||||||
// will run an IOP branch test regardless.
|
// will run an IOP branch test regardless.
|
||||||
|
|||||||
@ -117,9 +117,9 @@ struct psxRegisters {
|
|||||||
|
|
||||||
extern __aligned16 psxRegisters psxRegs;
|
extern __aligned16 psxRegisters psxRegs;
|
||||||
|
|
||||||
extern u32 g_psxNextBranchCycle;
|
extern u32 g_iopNextEventCycle;
|
||||||
extern s32 psxBreak; // used when the IOP execution is broken and control returned to the EE
|
extern s32 iopBreak; // used when the IOP execution is broken and control returned to the EE
|
||||||
extern s32 psxCycleEE; // tracks IOP's current sych status with the EE
|
extern s32 iopCycleEE; // tracks IOP's current sych status with the EE
|
||||||
|
|
||||||
#ifndef _PC_
|
#ifndef _PC_
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ extern u32 EEoCycle;
|
|||||||
|
|
||||||
extern s32 psxNextCounter;
|
extern s32 psxNextCounter;
|
||||||
extern u32 psxNextsCounter;
|
extern u32 psxNextsCounter;
|
||||||
extern bool iopBranchAction;
|
extern bool iopEventAction;
|
||||||
extern bool iopEventTestIsActive;
|
extern bool iopEventTestIsActive;
|
||||||
|
|
||||||
// Branching status used when throwing exceptions.
|
// Branching status used when throwing exceptions.
|
||||||
@ -196,7 +196,7 @@ extern R3000Acpu psxRec;
|
|||||||
|
|
||||||
extern void psxReset();
|
extern void psxReset();
|
||||||
extern void __fastcall psxException(u32 code, u32 step);
|
extern void __fastcall psxException(u32 code, u32 step);
|
||||||
extern void psxBranchTest();
|
extern void iopEventTest();
|
||||||
extern void psxMemReset();
|
extern void psxMemReset();
|
||||||
|
|
||||||
// Subsets
|
// Subsets
|
||||||
|
|||||||
@ -133,7 +133,7 @@ static __fi void execI()
|
|||||||
|
|
||||||
psxRegs.pc+= 4;
|
psxRegs.pc+= 4;
|
||||||
psxRegs.cycle++;
|
psxRegs.cycle++;
|
||||||
psxCycleEE-=8;
|
iopCycleEE-=8;
|
||||||
|
|
||||||
psxBSC[psxRegs.code >> 26]();
|
psxBSC[psxRegs.code >> 26]();
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ static void doBranch(s32 tar) {
|
|||||||
iopIsDelaySlot = false;
|
iopIsDelaySlot = false;
|
||||||
psxRegs.pc = branchPC;
|
psxRegs.pc = branchPC;
|
||||||
|
|
||||||
psxBranchTest();
|
iopEventTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intAlloc() {
|
static void intAlloc() {
|
||||||
@ -162,16 +162,16 @@ static void intExecute() {
|
|||||||
|
|
||||||
static s32 intExecuteBlock( s32 eeCycles )
|
static s32 intExecuteBlock( s32 eeCycles )
|
||||||
{
|
{
|
||||||
psxBreak = 0;
|
iopBreak = 0;
|
||||||
psxCycleEE = eeCycles;
|
iopCycleEE = eeCycles;
|
||||||
|
|
||||||
while (psxCycleEE > 0){
|
while (iopCycleEE > 0){
|
||||||
branch2 = 0;
|
branch2 = 0;
|
||||||
while (!branch2) {
|
while (!branch2) {
|
||||||
execI();
|
execI();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return psxBreak + psxCycleEE;
|
return iopBreak + iopCycleEE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intClear(u32 Addr, u32 Size) {
|
static void intClear(u32 Addr, u32 Size) {
|
||||||
|
|||||||
@ -71,7 +71,7 @@ void cpuReset()
|
|||||||
fpuRegs.fprc[0] = 0x00002e00; // fpu Revision..
|
fpuRegs.fprc[0] = 0x00002e00; // fpu Revision..
|
||||||
fpuRegs.fprc[31] = 0x01000001; // fpu Status/Control
|
fpuRegs.fprc[31] = 0x01000001; // fpu Status/Control
|
||||||
|
|
||||||
g_nextBranchCycle = cpuRegs.cycle + 4;
|
g_nextEventCycle = cpuRegs.cycle + 4;
|
||||||
EEsCycle = 0;
|
EEsCycle = 0;
|
||||||
EEoCycle = cpuRegs.cycle;
|
EEoCycle = cpuRegs.cycle;
|
||||||
|
|
||||||
@ -209,21 +209,21 @@ void cpuTlbMissW(u32 addr, u32 bd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sets a branch test to occur some time from an arbitrary starting point.
|
// sets a branch test to occur some time from an arbitrary starting point.
|
||||||
__fi void cpuSetNextBranch( u32 startCycle, s32 delta )
|
__fi void cpuSetNextEvent( u32 startCycle, s32 delta )
|
||||||
{
|
{
|
||||||
// typecast the conditional to signed so that things don't blow up
|
// typecast the conditional to signed so that things don't blow up
|
||||||
// if startCycle is greater than our next branch cycle.
|
// if startCycle is greater than our next branch cycle.
|
||||||
|
|
||||||
if( (int)(g_nextBranchCycle - startCycle) > delta )
|
if( (int)(g_nextEventCycle - startCycle) > delta )
|
||||||
{
|
{
|
||||||
g_nextBranchCycle = startCycle + delta;
|
g_nextEventCycle = startCycle + delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sets a branch to occur some time from the current cycle
|
// sets a branch to occur some time from the current cycle
|
||||||
__fi void cpuSetNextBranchDelta( s32 delta )
|
__fi void cpuSetNextEventDelta( s32 delta )
|
||||||
{
|
{
|
||||||
cpuSetNextBranch( cpuRegs.cycle, delta );
|
cpuSetNextEvent( cpuRegs.cycle, delta );
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests the cpu cycle against the given start and delta values.
|
// tests the cpu cycle against the given start and delta values.
|
||||||
@ -237,9 +237,9 @@ __fi int cpuTestCycle( u32 startCycle, s32 delta )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// tells the EE to run the branch test the next time it gets a chance.
|
// tells the EE to run the branch test the next time it gets a chance.
|
||||||
__fi void cpuSetBranch()
|
__fi void cpuSetEvent()
|
||||||
{
|
{
|
||||||
g_nextBranchCycle = cpuRegs.cycle;
|
g_nextEventCycle = cpuRegs.cycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void cpuClearInt( uint i )
|
__fi void cpuClearInt( uint i )
|
||||||
@ -258,7 +258,7 @@ static __fi void TESTINT( u8 n, void (*callback)() )
|
|||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cpuSetNextBranch( cpuRegs.sCycle[n], cpuRegs.eCycle[n] );
|
cpuSetNextEvent( cpuRegs.sCycle[n], cpuRegs.eCycle[n] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// [TODO] move this function to LegacyDmac.cpp, and remove most of the DMAC-related headers from
|
// [TODO] move this function to LegacyDmac.cpp, and remove most of the DMAC-related headers from
|
||||||
@ -303,7 +303,7 @@ static __fi void _cpuTestTIMR()
|
|||||||
s_iLastCOP0Cycle = cpuRegs.cycle;
|
s_iLastCOP0Cycle = cpuRegs.cycle;
|
||||||
|
|
||||||
// fixme: this looks like a hack to make up for the fact that the TIMR
|
// fixme: this looks like a hack to make up for the fact that the TIMR
|
||||||
// doesn't yet have a proper mechanism for setting itself up on a nextBranchCycle.
|
// doesn't yet have a proper mechanism for setting itself up on a nextEventCycle.
|
||||||
// A proper fix would schedule the TIMR to trigger at a specific cycle anytime
|
// A proper fix would schedule the TIMR to trigger at a specific cycle anytime
|
||||||
// the Count or Compare registers are modified.
|
// the Count or Compare registers are modified.
|
||||||
|
|
||||||
@ -338,15 +338,15 @@ static bool cpuIntsEnabled(int Interrupt)
|
|||||||
!cpuRegs.CP0.n.Status.b.EXL && (cpuRegs.CP0.n.Status.b.ERL == 0);
|
!cpuRegs.CP0.n.Status.b.EXL && (cpuRegs.CP0.n.Status.b.ERL == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if cpuRegs.cycle is greater than this cycle, should check cpuBranchTest for updates
|
// if cpuRegs.cycle is greater than this cycle, should check cpuEventTest for updates
|
||||||
u32 g_nextBranchCycle = 0;
|
u32 g_nextEventCycle = 0;
|
||||||
|
|
||||||
// Shared portion of the branch test, called from both the Interpreter
|
// Shared portion of the branch test, called from both the Interpreter
|
||||||
// and the recompiler. (moved here to help alleviate redundant code)
|
// and the recompiler. (moved here to help alleviate redundant code)
|
||||||
__fi void _cpuBranchTest_Shared()
|
__fi void _cpuEventTest_Shared()
|
||||||
{
|
{
|
||||||
ScopedBool etest(eeEventTestIsActive);
|
ScopedBool etest(eeEventTestIsActive);
|
||||||
g_nextBranchCycle = cpuRegs.cycle + eeWaitCycles;
|
g_nextEventCycle = cpuRegs.cycle + eeWaitCycles;
|
||||||
|
|
||||||
// ---- INTC / DMAC (CPU-level Exceptions) -----------------
|
// ---- INTC / DMAC (CPU-level Exceptions) -----------------
|
||||||
// Done first because exceptions raised during event tests need to be postponed a few
|
// Done first because exceptions raised during event tests need to be postponed a few
|
||||||
@ -379,34 +379,34 @@ __fi void _cpuBranchTest_Shared()
|
|||||||
_cpuTestInterrupts();
|
_cpuTestInterrupts();
|
||||||
|
|
||||||
// ---- IOP -------------
|
// ---- IOP -------------
|
||||||
// * It's important to run a psxBranchTest before calling ExecuteBlock. This
|
// * It's important to run a iopEventTest before calling ExecuteBlock. This
|
||||||
// is because the IOP does not always perform branch tests before returning
|
// is because the IOP does not always perform branch tests before returning
|
||||||
// (during the prev branch) and also so it can act on the state the EE has
|
// (during the prev branch) and also so it can act on the state the EE has
|
||||||
// given it before executing any code.
|
// given it before executing any code.
|
||||||
//
|
//
|
||||||
// * The IOP cannot always be run. If we run IOP code every time through the
|
// * The IOP cannot always be run. If we run IOP code every time through the
|
||||||
// cpuBranchTest, the IOP generally starts to run way ahead of the EE.
|
// cpuEventTest, the IOP generally starts to run way ahead of the EE.
|
||||||
|
|
||||||
EEsCycle += cpuRegs.cycle - EEoCycle;
|
EEsCycle += cpuRegs.cycle - EEoCycle;
|
||||||
EEoCycle = cpuRegs.cycle;
|
EEoCycle = cpuRegs.cycle;
|
||||||
|
|
||||||
if( EEsCycle > 0 )
|
if( EEsCycle > 0 )
|
||||||
iopBranchAction = true;
|
iopEventAction = true;
|
||||||
|
|
||||||
psxBranchTest();
|
iopEventTest();
|
||||||
|
|
||||||
if( iopBranchAction )
|
if( iopEventAction )
|
||||||
{
|
{
|
||||||
//if( EEsCycle < -450 )
|
//if( EEsCycle < -450 )
|
||||||
// Console.WriteLn( " IOP ahead by: %d cycles", -EEsCycle );
|
// Console.WriteLn( " IOP ahead by: %d cycles", -EEsCycle );
|
||||||
|
|
||||||
EEsCycle = psxCpu->ExecuteBlock( EEsCycle );
|
EEsCycle = psxCpu->ExecuteBlock( EEsCycle );
|
||||||
|
|
||||||
iopBranchAction = false;
|
iopEventAction = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- VU0 -------------
|
// ---- VU0 -------------
|
||||||
// We're in a BranchTest. All dynarec registers are flushed
|
// We're in a EventTest. All dynarec registers are flushed
|
||||||
// so there is no need to freeze registers here.
|
// so there is no need to freeze registers here.
|
||||||
CpuVU0->ExecuteBlock();
|
CpuVU0->ExecuteBlock();
|
||||||
|
|
||||||
@ -421,19 +421,19 @@ __fi void _cpuBranchTest_Shared()
|
|||||||
// EE's running way ahead of the IOP still, so we should branch quickly to give the
|
// EE's running way ahead of the IOP still, so we should branch quickly to give the
|
||||||
// IOP extra timeslices in short order.
|
// IOP extra timeslices in short order.
|
||||||
|
|
||||||
cpuSetNextBranchDelta( 48 );
|
cpuSetNextEventDelta( 48 );
|
||||||
//Console.Warning( "EE ahead of the IOP -- Rapid Branch! %d", EEsCycle );
|
//Console.Warning( "EE ahead of the IOP -- Rapid Event! %d", EEsCycle );
|
||||||
}
|
}
|
||||||
|
|
||||||
// The IOP could be running ahead/behind of us, so adjust the iop's next branch by its
|
// The IOP could be running ahead/behind of us, so adjust the iop's next branch by its
|
||||||
// relative position to the EE (via EEsCycle)
|
// relative position to the EE (via EEsCycle)
|
||||||
cpuSetNextBranchDelta( ((g_psxNextBranchCycle-psxRegs.cycle)*8) - EEsCycle );
|
cpuSetNextEventDelta( ((g_iopNextEventCycle-psxRegs.cycle)*8) - EEsCycle );
|
||||||
|
|
||||||
// Apply the hsync counter's nextCycle
|
// Apply the hsync counter's nextCycle
|
||||||
cpuSetNextBranch( hsyncCounter.sCycle, hsyncCounter.CycleT );
|
cpuSetNextEvent( hsyncCounter.sCycle, hsyncCounter.CycleT );
|
||||||
|
|
||||||
// Apply vsync and other counter nextCycles
|
// Apply vsync and other counter nextCycles
|
||||||
cpuSetNextBranch( nextsCounter, nextCounter );
|
cpuSetNextEvent( nextsCounter, nextCounter );
|
||||||
}
|
}
|
||||||
|
|
||||||
__ri void cpuTestINTCInts()
|
__ri void cpuTestINTCInts()
|
||||||
@ -444,11 +444,11 @@ __ri void cpuTestINTCInts()
|
|||||||
|
|
||||||
if( (psHu32(INTC_STAT) & psHu32(INTC_MASK)) == 0 ) return;
|
if( (psHu32(INTC_STAT) & psHu32(INTC_MASK)) == 0 ) return;
|
||||||
|
|
||||||
cpuSetNextBranchDelta( 4 );
|
cpuSetNextEventDelta( 4 );
|
||||||
if(eeEventTestIsActive && (psxCycleEE > 0))
|
if(eeEventTestIsActive && (iopCycleEE > 0))
|
||||||
{
|
{
|
||||||
psxBreak += psxCycleEE; // record the number of cycles the IOP didn't run.
|
iopBreak += iopCycleEE; // record the number of cycles the IOP didn't run.
|
||||||
psxCycleEE = 0;
|
iopCycleEE = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,11 +461,11 @@ __fi void cpuTestDMACInts()
|
|||||||
if ( ( (psHu16(0xe012) & psHu16(0xe010)) == 0) &&
|
if ( ( (psHu16(0xe012) & psHu16(0xe010)) == 0) &&
|
||||||
( (psHu16(0xe010) & 0x8000) == 0) ) return;
|
( (psHu16(0xe010) & 0x8000) == 0) ) return;
|
||||||
|
|
||||||
cpuSetNextBranchDelta( 4 );
|
cpuSetNextEventDelta( 4 );
|
||||||
if(eeEventTestIsActive && (psxCycleEE > 0))
|
if(eeEventTestIsActive && (iopCycleEE > 0))
|
||||||
{
|
{
|
||||||
psxBreak += psxCycleEE; // record the number of cycles the IOP didn't run.
|
iopBreak += iopCycleEE; // record the number of cycles the IOP didn't run.
|
||||||
psxCycleEE = 0;
|
iopCycleEE = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,16 +499,16 @@ __fi void CPU_INT( EE_EventType n, s32 ecycle)
|
|||||||
|
|
||||||
// Interrupt is happening soon: make sure both EE and IOP are aware.
|
// Interrupt is happening soon: make sure both EE and IOP are aware.
|
||||||
|
|
||||||
if( ecycle <= 28 && psxCycleEE > 0 )
|
if( ecycle <= 28 && iopCycleEE > 0 )
|
||||||
{
|
{
|
||||||
// If running in the IOP, force it to break immediately into the EE.
|
// If running in the IOP, force it to break immediately into the EE.
|
||||||
// the EE's branch test is due to run.
|
// the EE's branch test is due to run.
|
||||||
|
|
||||||
psxBreak += psxCycleEE; // record the number of cycles the IOP didn't run.
|
iopBreak += iopCycleEE; // record the number of cycles the IOP didn't run.
|
||||||
psxCycleEE = 0;
|
iopCycleEE = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuSetNextBranchDelta( cpuRegs.eCycle[n] );
|
cpuSetNextEventDelta( cpuRegs.eCycle[n] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from recompilers; __fastcall define is mandatory.
|
// Called from recompilers; __fastcall define is mandatory.
|
||||||
|
|||||||
@ -244,7 +244,7 @@ extern __aligned16 cpuRegisters cpuRegs;
|
|||||||
extern __aligned16 fpuRegisters fpuRegs;
|
extern __aligned16 fpuRegisters fpuRegs;
|
||||||
extern __aligned16 tlbs tlb[48];
|
extern __aligned16 tlbs tlb[48];
|
||||||
|
|
||||||
extern u32 g_nextBranchCycle;
|
extern u32 g_nextEventCycle;
|
||||||
extern bool eeEventTestIsActive;
|
extern bool eeEventTestIsActive;
|
||||||
extern u32 s_iLastCOP0Cycle;
|
extern u32 s_iLastCOP0Cycle;
|
||||||
extern u32 s_iLastPERFCycle[2];
|
extern u32 s_iLastPERFCycle[2];
|
||||||
@ -415,12 +415,12 @@ extern void cpuTlbMissW(u32 addr, u32 bd);
|
|||||||
extern void cpuTestHwInts();
|
extern void cpuTestHwInts();
|
||||||
extern void cpuClearInt(uint n);
|
extern void cpuClearInt(uint n);
|
||||||
|
|
||||||
extern void cpuSetNextBranch( u32 startCycle, s32 delta );
|
extern void cpuSetNextEvent( u32 startCycle, s32 delta );
|
||||||
extern void cpuSetNextBranchDelta( s32 delta );
|
extern void cpuSetNextEventDelta( s32 delta );
|
||||||
extern int cpuTestCycle( u32 startCycle, s32 delta );
|
extern int cpuTestCycle( u32 startCycle, s32 delta );
|
||||||
extern void cpuSetBranch();
|
extern void cpuSetEvent();
|
||||||
|
|
||||||
extern void _cpuBranchTest_Shared(); // for internal use by the Dynarecs and Ints inside R5900:
|
extern void _cpuEventTest_Shared(); // for internal use by the Dynarecs and Ints inside R5900:
|
||||||
|
|
||||||
extern void cpuTestINTCInts();
|
extern void cpuTestINTCInts();
|
||||||
extern void cpuTestDMACInts();
|
extern void cpuTestDMACInts();
|
||||||
|
|||||||
@ -179,8 +179,8 @@ void SaveStateBase::FreezeRegisters()
|
|||||||
FreezeTag( "Cycles" );
|
FreezeTag( "Cycles" );
|
||||||
Freeze(EEsCycle);
|
Freeze(EEsCycle);
|
||||||
Freeze(EEoCycle);
|
Freeze(EEoCycle);
|
||||||
Freeze(g_nextBranchCycle);
|
Freeze(g_nextEventCycle);
|
||||||
Freeze(g_psxNextBranchCycle);
|
Freeze(g_iopNextEventCycle);
|
||||||
Freeze(s_iLastCOP0Cycle);
|
Freeze(s_iLastCOP0Cycle);
|
||||||
Freeze(s_iLastPERFCycle);
|
Freeze(s_iLastPERFCycle);
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,7 @@ void BaseVUmicroCPU::ExecuteBlock(bool startUp) {
|
|||||||
|
|
||||||
// Let VUs run behind EE instead of ahead
|
// Let VUs run behind EE instead of ahead
|
||||||
if (stat & test) {
|
if (stat & test) {
|
||||||
cpuSetNextBranchDelta((s+c)*2);
|
cpuSetNextEventDelta((s+c)*2);
|
||||||
m_lastEEcycles = cpuRegs.cycle + (s*2);
|
m_lastEEcycles = cpuRegs.cycle + (s*2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,11 +43,11 @@ void BaseVUmicroCPU::ExecuteBlock(bool startUp) {
|
|||||||
delta >>= 1; // Divide by 2 (unsigned)
|
delta >>= 1; // Divide by 2 (unsigned)
|
||||||
Execute(delta); // Execute the time since the last call
|
Execute(delta); // Execute the time since the last call
|
||||||
if (stat & test) {
|
if (stat & test) {
|
||||||
cpuSetNextBranchDelta(c*2);
|
cpuSetNextEventDelta(c*2);
|
||||||
m_lastEEcycles = cpuRegs.cycle;
|
m_lastEEcycles = cpuRegs.cycle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else cpuSetNextBranchDelta(-delta); // Haven't caught-up from kick start
|
else cpuSetNextEventDelta(-delta); // Haven't caught-up from kick start
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ void __fastcall BaseVUmicroCPU::ExecuteBlockJIT(BaseVUmicroCPU* cpu) {
|
|||||||
cpu->Execute(c); // Execute VU
|
cpu->Execute(c); // Execute VU
|
||||||
if (stat & test) {
|
if (stat & test) {
|
||||||
cpu->m_lastEEcycles+=(c*2);
|
cpu->m_lastEEcycles+=(c*2);
|
||||||
cpuSetNextBranchDelta(c*2);
|
cpuSetNextEventDelta(c*2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ void BaseVUmicroCPU::ExecuteBlock(bool startUp) {
|
|||||||
// If the VU0 program didn't finish then we'll want to finish it up
|
// If the VU0 program didn't finish then we'll want to finish it up
|
||||||
// pretty soon. This fixes vmhacks in some games (Naruto Ultimate Ninja 2)
|
// pretty soon. This fixes vmhacks in some games (Naruto Ultimate Ninja 2)
|
||||||
if(VU0.VI[REG_VPU_STAT].UL & vuRunning)
|
if(VU0.VI[REG_VPU_STAT].UL & vuRunning)
|
||||||
cpuSetNextBranchDelta( 192 ); // fixme : ideally this should be higher, like 512 or so.
|
cpuSetNextEventDelta( 192 ); // fixme : ideally this should be higher, like 512 or so.
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Execute(vu0RunCycles);
|
Execute(vu0RunCycles);
|
||||||
@ -89,7 +89,7 @@ void BaseVUmicroCPU::ExecuteBlock(bool startUp) {
|
|||||||
// This helps keep the EE and VU0 in sync.
|
// This helps keep the EE and VU0 in sync.
|
||||||
// Check Silver Surfer. Currently has SPS varying with different branch deltas set below.
|
// Check Silver Surfer. Currently has SPS varying with different branch deltas set below.
|
||||||
if(VU0.VI[REG_VPU_STAT].UL & vuRunning)
|
if(VU0.VI[REG_VPU_STAT].UL & vuRunning)
|
||||||
cpuSetNextBranchDelta( 768 );
|
cpuSetNextEventDelta( 768 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
using namespace x86Emitter;
|
using namespace x86Emitter;
|
||||||
|
|
||||||
extern u32 g_psxNextBranchCycle;
|
extern u32 g_iopNextEventCycle;
|
||||||
extern void psxBREAK();
|
extern void psxBREAK();
|
||||||
|
|
||||||
u32 g_psxMaxRecMem = 0;
|
u32 g_psxMaxRecMem = 0;
|
||||||
@ -121,7 +121,7 @@ static DynGenFunc* iopExitRecompiledCode = NULL;
|
|||||||
|
|
||||||
static void recEventTest()
|
static void recEventTest()
|
||||||
{
|
{
|
||||||
_cpuBranchTest_Shared();
|
_cpuEventTest_Shared();
|
||||||
}
|
}
|
||||||
|
|
||||||
// parameters:
|
// parameters:
|
||||||
@ -876,28 +876,28 @@ static void recExecute()
|
|||||||
|
|
||||||
static __noinline s32 recExecuteBlock( s32 eeCycles )
|
static __noinline s32 recExecuteBlock( s32 eeCycles )
|
||||||
{
|
{
|
||||||
psxBreak = 0;
|
iopBreak = 0;
|
||||||
psxCycleEE = eeCycles;
|
iopCycleEE = eeCycles;
|
||||||
|
|
||||||
// [TODO] recExecuteBlock could be replaced by a direct call to the iopEnterRecompiledCode()
|
// [TODO] recExecuteBlock could be replaced by a direct call to the iopEnterRecompiledCode()
|
||||||
// (by assigning its address to the psxRec structure). But for that to happen, we need
|
// (by assigning its address to the psxRec structure). But for that to happen, we need
|
||||||
// to move psxBreak/psxCycleEE update code to emitted assembly code. >_< --air
|
// to move iopBreak/iopCycleEE update code to emitted assembly code. >_< --air
|
||||||
|
|
||||||
// Likely Disasm, as borrowed from MSVC:
|
// Likely Disasm, as borrowed from MSVC:
|
||||||
|
|
||||||
// Entry:
|
// Entry:
|
||||||
// mov eax,dword ptr [esp+4]
|
// mov eax,dword ptr [esp+4]
|
||||||
// mov dword ptr [psxBreak (0E88DCCh)],0
|
// mov dword ptr [iopBreak (0E88DCCh)],0
|
||||||
// mov dword ptr [psxCycleEE (832A84h)],eax
|
// mov dword ptr [iopCycleEE (832A84h)],eax
|
||||||
|
|
||||||
// Exit:
|
// Exit:
|
||||||
// mov ecx,dword ptr [psxBreak (0E88DCCh)]
|
// mov ecx,dword ptr [iopBreak (0E88DCCh)]
|
||||||
// mov edx,dword ptr [psxCycleEE (832A84h)]
|
// mov edx,dword ptr [iopCycleEE (832A84h)]
|
||||||
// lea eax,[edx+ecx]
|
// lea eax,[edx+ecx]
|
||||||
|
|
||||||
iopEnterRecompiledCode();
|
iopEnterRecompiledCode();
|
||||||
|
|
||||||
return psxBreak + psxCycleEE;
|
return iopBreak + iopCycleEE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the offset to the next instruction after any cleared memory
|
// Returns the offset to the next instruction after any cleared memory
|
||||||
@ -1021,19 +1021,19 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
|
|||||||
{
|
{
|
||||||
xMOV(eax, ptr32[&psxRegs.cycle]);
|
xMOV(eax, ptr32[&psxRegs.cycle]);
|
||||||
xMOV(ecx, eax);
|
xMOV(ecx, eax);
|
||||||
xMOV(edx, ptr32[&psxCycleEE]);
|
xMOV(edx, ptr32[&iopCycleEE]);
|
||||||
xADD(edx, 7);
|
xADD(edx, 7);
|
||||||
xSHR(edx, 3);
|
xSHR(edx, 3);
|
||||||
xADD(eax, edx);
|
xADD(eax, edx);
|
||||||
xCMP(eax, ptr32[&g_psxNextBranchCycle]);
|
xCMP(eax, ptr32[&g_iopNextEventCycle]);
|
||||||
xCMOVNS(eax, ptr32[&g_psxNextBranchCycle]);
|
xCMOVNS(eax, ptr32[&g_iopNextEventCycle]);
|
||||||
xMOV(ptr32[&psxRegs.cycle], eax);
|
xMOV(ptr32[&psxRegs.cycle], eax);
|
||||||
xSUB(eax, ecx);
|
xSUB(eax, ecx);
|
||||||
xSHL(eax, 3);
|
xSHL(eax, 3);
|
||||||
xSUB(ptr32[&psxCycleEE], eax);
|
xSUB(ptr32[&iopCycleEE], eax);
|
||||||
xJLE(iopExitRecompiledCode);
|
xJLE(iopExitRecompiledCode);
|
||||||
|
|
||||||
xCALL(psxBranchTest);
|
xCALL(iopEventTest);
|
||||||
|
|
||||||
if( newpc != 0xffffffff )
|
if( newpc != 0xffffffff )
|
||||||
{
|
{
|
||||||
@ -1047,15 +1047,15 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
|
|||||||
xADD(eax, blockCycles);
|
xADD(eax, blockCycles);
|
||||||
xMOV(ptr32[&psxRegs.cycle], eax); // update cycles
|
xMOV(ptr32[&psxRegs.cycle], eax); // update cycles
|
||||||
|
|
||||||
// jump if psxCycleEE <= 0 (iop's timeslice timed out, so time to return control to the EE)
|
// jump if iopCycleEE <= 0 (iop's timeslice timed out, so time to return control to the EE)
|
||||||
xSUB(ptr32[&psxCycleEE], blockCycles*8);
|
xSUB(ptr32[&iopCycleEE], blockCycles*8);
|
||||||
xJLE(iopExitRecompiledCode);
|
xJLE(iopExitRecompiledCode);
|
||||||
|
|
||||||
// check if an event is pending
|
// check if an event is pending
|
||||||
xSUB(eax, ptr32[&g_psxNextBranchCycle]);
|
xSUB(eax, ptr32[&g_iopNextEventCycle]);
|
||||||
xForwardJS<u8> nointerruptpending;
|
xForwardJS<u8> nointerruptpending;
|
||||||
|
|
||||||
xCALL(psxBranchTest);
|
xCALL(iopEventTest);
|
||||||
|
|
||||||
if( newpc != 0xffffffff ) {
|
if( newpc != 0xffffffff ) {
|
||||||
xCMP(ptr32[&psxRegs.pc], newpc);
|
xCMP(ptr32[&psxRegs.pc], newpc);
|
||||||
@ -1098,7 +1098,7 @@ void rpsxSYSCALL()
|
|||||||
j8Ptr[0] = JE8(0);
|
j8Ptr[0] = JE8(0);
|
||||||
|
|
||||||
ADD32ItoM((uptr)&psxRegs.cycle, psxScaleBlockCycles() );
|
ADD32ItoM((uptr)&psxRegs.cycle, psxScaleBlockCycles() );
|
||||||
SUB32ItoM((uptr)&psxCycleEE, psxScaleBlockCycles()*8 );
|
SUB32ItoM((uptr)&iopCycleEE, psxScaleBlockCycles()*8 );
|
||||||
JMP32((uptr)iopDispatcherReg - ( (uptr)x86Ptr + 5 ));
|
JMP32((uptr)iopDispatcherReg - ( (uptr)x86Ptr + 5 ));
|
||||||
|
|
||||||
// jump target for skipping blockCycle updates
|
// jump target for skipping blockCycle updates
|
||||||
@ -1120,7 +1120,7 @@ void rpsxBREAK()
|
|||||||
CMP32ItoM((uptr)&psxRegs.pc, psxpc-4);
|
CMP32ItoM((uptr)&psxRegs.pc, psxpc-4);
|
||||||
j8Ptr[0] = JE8(0);
|
j8Ptr[0] = JE8(0);
|
||||||
ADD32ItoM((uptr)&psxRegs.cycle, psxScaleBlockCycles() );
|
ADD32ItoM((uptr)&psxRegs.cycle, psxScaleBlockCycles() );
|
||||||
SUB32ItoM((uptr)&psxCycleEE, psxScaleBlockCycles()*8 );
|
SUB32ItoM((uptr)&iopCycleEE, psxScaleBlockCycles()*8 );
|
||||||
JMP32((uptr)iopDispatcherReg - ( (uptr)x86Ptr + 5 ));
|
JMP32((uptr)iopDispatcherReg - ( (uptr)x86Ptr + 5 ));
|
||||||
x86SetJ8(j8Ptr[0]);
|
x86SetJ8(j8Ptr[0]);
|
||||||
|
|
||||||
@ -1373,7 +1373,7 @@ StartRecomp:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ADD32ItoM((uptr)&psxRegs.cycle, psxScaleBlockCycles() );
|
ADD32ItoM((uptr)&psxRegs.cycle, psxScaleBlockCycles() );
|
||||||
SUB32ItoM((uptr)&psxCycleEE, psxScaleBlockCycles()*8 );
|
SUB32ItoM((uptr)&iopCycleEE, psxScaleBlockCycles()*8 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (willbranch3 || !psxbranch) {
|
if (willbranch3 || !psxbranch) {
|
||||||
|
|||||||
@ -316,7 +316,7 @@ void recBranchCall( void (*func)() )
|
|||||||
// to the current cpu cycle.
|
// to the current cpu cycle.
|
||||||
|
|
||||||
MOV32MtoR( EAX, (uptr)&cpuRegs.cycle );
|
MOV32MtoR( EAX, (uptr)&cpuRegs.cycle );
|
||||||
MOV32RtoM( (uptr)&g_nextBranchCycle, EAX );
|
MOV32RtoM( (uptr)&g_nextEventCycle, EAX );
|
||||||
|
|
||||||
recCall(func);
|
recCall(func);
|
||||||
branch = 2;
|
branch = 2;
|
||||||
@ -350,7 +350,7 @@ static DynGenFunc* ExitRecompiledCode = NULL;
|
|||||||
|
|
||||||
static void recEventTest()
|
static void recEventTest()
|
||||||
{
|
{
|
||||||
_cpuBranchTest_Shared();
|
_cpuEventTest_Shared();
|
||||||
}
|
}
|
||||||
|
|
||||||
// parameters:
|
// parameters:
|
||||||
@ -1111,11 +1111,11 @@ static void iBranchTest(u32 newpc)
|
|||||||
// Check the Event scheduler if our "cycle target" has been reached.
|
// Check the Event scheduler if our "cycle target" has been reached.
|
||||||
// Equiv code to:
|
// Equiv code to:
|
||||||
// cpuRegs.cycle += blockcycles;
|
// cpuRegs.cycle += blockcycles;
|
||||||
// if( cpuRegs.cycle > g_nextBranchCycle ) { DoEvents(); }
|
// if( cpuRegs.cycle > g_nextEventCycle ) { DoEvents(); }
|
||||||
|
|
||||||
if (EmuConfig.Speedhacks.WaitLoop && s_nBlockFF && newpc == s_branchTo)
|
if (EmuConfig.Speedhacks.WaitLoop && s_nBlockFF && newpc == s_branchTo)
|
||||||
{
|
{
|
||||||
xMOV(eax, ptr32[&g_nextBranchCycle]);
|
xMOV(eax, ptr32[&g_nextEventCycle]);
|
||||||
xADD(ptr32[&cpuRegs.cycle], eeScaleBlockCycles());
|
xADD(ptr32[&cpuRegs.cycle], eeScaleBlockCycles());
|
||||||
xCMP(eax, ptr32[&cpuRegs.cycle]);
|
xCMP(eax, ptr32[&cpuRegs.cycle]);
|
||||||
xCMOVS(eax, ptr32[&cpuRegs.cycle]);
|
xCMOVS(eax, ptr32[&cpuRegs.cycle]);
|
||||||
@ -1128,7 +1128,7 @@ static void iBranchTest(u32 newpc)
|
|||||||
xMOV(eax, ptr[&cpuRegs.cycle]);
|
xMOV(eax, ptr[&cpuRegs.cycle]);
|
||||||
xADD(eax, eeScaleBlockCycles());
|
xADD(eax, eeScaleBlockCycles());
|
||||||
xMOV(ptr[&cpuRegs.cycle], eax); // update cycles
|
xMOV(ptr[&cpuRegs.cycle], eax); // update cycles
|
||||||
xSUB(eax, ptr[&g_nextBranchCycle]);
|
xSUB(eax, ptr[&g_nextEventCycle]);
|
||||||
|
|
||||||
if (newpc == 0xffffffff)
|
if (newpc == 0xffffffff)
|
||||||
xJS( DispatcherReg );
|
xJS( DispatcherReg );
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user