Ive fixed definitely Pokemon XD in dual core mode. This game is doing something not allowed. It attach to CPU the same fifo attached to the GPU in multibuffer mode. I added a check to prevent overwrite the GPU FIFO with the CPU FIFO. If the game do that on breakpoint the solution can fail.

Fixed ReadWriteDistance calc when CPRead > CPWrite.
Added Token and Finish cause to GP Jit checking.
This commit is contained in:
marcosvitali 2012-03-18 22:54:58 -03:00
parent cfbcaa2cc6
commit 20eca1bf7e
5 changed files with 22 additions and 6 deletions

View File

@ -584,7 +584,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
FixupBranch noExtException = J_CC(CC_Z);
TEST(32, M((void *)&PowerPC::ppcState.msr), Imm32(0x0008000));
FixupBranch noExtIntEnable = J_CC(CC_Z);
TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP));
TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP | ProcessorInterface::INT_CAUSE_PE_TOKEN | ProcessorInterface::INT_CAUSE_PE_FINISH));
FixupBranch noCPInt = J_CC(CC_Z);
MOV(32, M(&PC), Imm32(ops[i].address));

View File

@ -1932,7 +1932,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
FixupBranch noExtException = Jit->J_CC(CC_Z);
Jit->TEST(32, M((void *)&PowerPC::ppcState.msr), Imm32(0x0008000));
FixupBranch noExtIntEnable = Jit->J_CC(CC_Z);
Jit->TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP));
Jit->TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP || ProcessorInterface::INT_CAUSE_PE_TOKEN || ProcessorInterface::INT_CAUSE_PE_FINISH));
FixupBranch noCPInt = Jit->J_CC(CC_Z);
Jit->MOV(32, M(&PC), Imm32(InstLoc));

View File

@ -61,6 +61,7 @@ volatile bool interruptSet= false;
volatile bool interruptWaiting= false;
volatile bool interruptTokenWaiting = false;
volatile bool interruptFinishWaiting = false;
volatile bool waitingForPEInterruptDisable = false;
bool IsOnThread()
{
@ -174,7 +175,7 @@ void Read16(u16& _rReturnValue, const u32 _Address)
if(fifo.CPWritePointer >= fifo.SafeCPReadPointer)
_rReturnValue = ReadLow (fifo.CPWritePointer - fifo.SafeCPReadPointer);
else
_rReturnValue = ReadLow (fifo.CPEnd - fifo.CPWritePointer + fifo.SafeCPReadPointer);
_rReturnValue = ReadLow (fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32);
else
_rReturnValue = ReadLow (fifo.CPReadWriteDistance);
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_RW_DISTANCE_LO : %04x", _rReturnValue);
@ -184,7 +185,7 @@ void Read16(u16& _rReturnValue, const u32 _Address)
if(fifo.CPWritePointer >= fifo.SafeCPReadPointer)
_rReturnValue = ReadHigh (fifo.CPWritePointer - fifo.SafeCPReadPointer);
else
_rReturnValue = ReadHigh (fifo.CPEnd - fifo.CPWritePointer + fifo.SafeCPReadPointer);
_rReturnValue = ReadHigh (fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32);
else
_rReturnValue = ReadHigh(fifo.CPReadWriteDistance);
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_RW_DISTANCE_HI : %04x", _rReturnValue);
@ -437,11 +438,25 @@ void Write32(const u32 _Data, const u32 _Address)
void STACKALIGN GatherPipeBursted()
{
ProcessFifoEvents();
// if we aren't linked, we don't care about gather pipe data
if (!m_CPCtrlReg.GPLinkEnable)
{
if (!IsOnThread())
RunGpu();
else
{
// In multibuffer mode is not allowed write in the same fifo attached to the GPU.
// Fix Pokemon XD in DC mode.
if((ProcessorInterface::Fifo_CPUEnd == fifo.CPEnd) && (ProcessorInterface::Fifo_CPUBase == fifo.CPBase)
&& fifo.CPReadWriteDistance > 0)
{
waitingForPEInterruptDisable = true;
ProcessFifoAllDistance();
waitingForPEInterruptDisable = false;
}
}
return;
}

View File

@ -35,7 +35,8 @@ extern volatile bool interruptSet;
extern volatile bool interruptWaiting;
extern volatile bool interruptTokenWaiting;
extern volatile bool interruptFinishWaiting;
extern volatile bool waitingForPEInterruptDisable;
// internal hardware addresses
enum
{

View File

@ -462,7 +462,7 @@ void ResetSetToken()
bool WaitingForPEInterrupt()
{
return CommandProcessor::interruptFinishWaiting || CommandProcessor::interruptTokenWaiting || interruptSetFinish || interruptSetToken;
return !CommandProcessor::waitingForPEInterruptDisable && (CommandProcessor::interruptFinishWaiting || CommandProcessor::interruptTokenWaiting || interruptSetFinish || interruptSetToken);
}
void ResumeWaitingForPEInterrupt()