RSP: Can exit after jump from MT/MF Cop 0

This commit is contained in:
zilmar 2013-01-29 22:29:50 +11:00
parent 38ec949a6e
commit 36def4094a
1 changed files with 97 additions and 20 deletions

View File

@ -28,8 +28,9 @@
#include <stdio.h> #include <stdio.h>
#include "RSP.h" #include "RSP.h"
#include "CPU.h" #include "CPU.h"
#include "Recompiler CPU.h" #include "Interpreter CPU.h"
#include "Interpreter Ops.h" #include "Interpreter Ops.h"
#include "Recompiler CPU.h"
#include "RSP Command.h" #include "RSP Command.h"
#include "RSP Registers.h" #include "RSP Registers.h"
#include "memory.h" #include "memory.h"
@ -145,6 +146,23 @@ void BreakPoint() {
*(RecompPos++) = 0xCC; *(RecompPos++) = 0xCC;
} }
void CompileBranchExit(DWORD TargetPC, DWORD ContinuePC)
{
DWORD * X86Loc = NULL;
NextInstruction = FINISH_SUB_BLOCK;
CompConstToVariable(TRUE, &BranchCompare, "BranchCompare");
JeLabel32("BranchEqual", 0);
X86Loc = (DWORD*)(RecompPos - 4);
MoveConstToVariable(ContinuePC,PrgCount,"RSP PC");
Ret();
CPU_Message("BranchEqual:");
x86_SetBranch32b(X86Loc, RecompPos);
MoveConstToVariable(TargetPC,PrgCount,"RSP PC");
Ret();
}
/************************* OpCode functions *************************/ /************************* OpCode functions *************************/
void Compile_SPECIAL ( void ) { void Compile_SPECIAL ( void ) {
((void (*)()) RSP_Special[ RSPOpC.funct ])(); ((void (*)()) RSP_Special[ RSPOpC.funct ])();
@ -244,6 +262,9 @@ void Compile_BEQ ( void ) {
} }
Branch_AddRef(Target, (DWORD*)(RecompPos - 4)); Branch_AddRef(Target, (DWORD*)(RecompPos - 4));
NextInstruction = FINISH_SUB_BLOCK; NextInstruction = FINISH_SUB_BLOCK;
} else if ( NextInstruction == DELAY_SLOT_EXIT_DONE ) {
DWORD Target = (CompilePC + ((short)RSPOpC.offset << 2) + 4) & 0xFFC;
CompileBranchExit(Target, CompilePC + 8);
} else { } else {
CompilerWarning("BEQ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction); CompilerWarning("BEQ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction);
BreakPoint(); BreakPoint();
@ -300,6 +321,9 @@ void Compile_BNE ( void ) {
} }
Branch_AddRef(Target, (DWORD*)(RecompPos - 4)); Branch_AddRef(Target, (DWORD*)(RecompPos - 4));
NextInstruction = FINISH_SUB_BLOCK; NextInstruction = FINISH_SUB_BLOCK;
} else if ( NextInstruction == DELAY_SLOT_EXIT_DONE ) {
DWORD Target = (CompilePC + ((short)RSPOpC.offset << 2) + 4) & 0xFFC;
CompileBranchExit(Target, CompilePC + 8);
} else { } else {
CompilerWarning("BNE error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction); CompilerWarning("BNE error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction);
BreakPoint(); BreakPoint();
@ -343,6 +367,9 @@ void Compile_BLEZ ( void ) {
Branch_AddRef(Target, (DWORD*)(RecompPos - 4)); Branch_AddRef(Target, (DWORD*)(RecompPos - 4));
NextInstruction = FINISH_SUB_BLOCK; NextInstruction = FINISH_SUB_BLOCK;
} else if ( NextInstruction == DELAY_SLOT_EXIT_DONE ) {
DWORD Target = (CompilePC + ((short)RSPOpC.offset << 2) + 4) & 0xFFC;
CompileBranchExit(Target, CompilePC + 8);
} else { } else {
CompilerWarning("BLEZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction); CompilerWarning("BLEZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction);
BreakPoint(); BreakPoint();
@ -383,6 +410,9 @@ void Compile_BGTZ ( void ) {
} }
Branch_AddRef(Target, (DWORD*)(RecompPos - 4)); Branch_AddRef(Target, (DWORD*)(RecompPos - 4));
NextInstruction = FINISH_SUB_BLOCK; NextInstruction = FINISH_SUB_BLOCK;
} else if ( NextInstruction == DELAY_SLOT_EXIT_DONE ) {
DWORD Target = (CompilePC + ((short)RSPOpC.offset << 2) + 4) & 0xFFC;
CompileBranchExit(Target, CompilePC + 8);
} else { } else {
CompilerWarning("BGTZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction); CompilerWarning("BGTZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction);
BreakPoint(); BreakPoint();
@ -1035,6 +1065,9 @@ void Compile_Special_JR (void) {
Ret(); Ret();
ChangedPC = FALSE; ChangedPC = FALSE;
NextInstruction = FINISH_SUB_BLOCK; NextInstruction = FINISH_SUB_BLOCK;
} else if ( NextInstruction == DELAY_SLOT_EXIT_DONE ) {
NextInstruction = FINISH_SUB_BLOCK;
Ret();
} else { } else {
CompilerWarning("WTF\n\nJR\nNextInstruction = %X", NextInstruction); CompilerWarning("WTF\n\nJR\nNextInstruction = %X", NextInstruction);
BreakPoint(); BreakPoint();
@ -1074,12 +1107,14 @@ void Compile_Special_JALR ( void ) {
void Compile_Special_BREAK ( void ) { void Compile_Special_BREAK ( void ) {
Cheat_r4300iOpcode(RSP_Special_BREAK,"RSP_Special_BREAK"); Cheat_r4300iOpcode(RSP_Special_BREAK,"RSP_Special_BREAK");
if (NextInstruction != NORMAL) { if (NextInstruction == NORMAL) {
DisplayError("Compile_Special_BREAK: problem");
}
MoveConstToVariable(CompilePC + 4,PrgCount,"RSP PC"); MoveConstToVariable(CompilePC + 4,PrgCount,"RSP PC");
Ret(); Ret();
NextInstruction = FINISH_BLOCK; NextInstruction = FINISH_SUB_BLOCK;
} else {
CompilerWarning("WTF\n\nBREAK\nNextInstruction = %X", NextInstruction);
BreakPoint();
}
} }
void Compile_Special_ADD ( void ) { void Compile_Special_ADD ( void ) {
@ -1337,6 +1372,9 @@ void Compile_RegImm_BLTZ ( void ) {
} }
Branch_AddRef(Target, (DWORD*)(RecompPos - 4)); Branch_AddRef(Target, (DWORD*)(RecompPos - 4));
NextInstruction = FINISH_SUB_BLOCK; NextInstruction = FINISH_SUB_BLOCK;
} else if ( NextInstruction == DELAY_SLOT_EXIT_DONE ) {
DWORD Target = (CompilePC + ((short)RSPOpC.offset << 2) + 4) & 0xFFC;
CompileBranchExit(Target, CompilePC + 8);
} else { } else {
CompilerWarning("BLTZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nPC = %X\nEmulation will now stop", NextInstruction, CompilePC); CompilerWarning("BLTZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nPC = %X\nEmulation will now stop", NextInstruction, CompilePC);
BreakPoint(); BreakPoint();
@ -1379,6 +1417,9 @@ void Compile_RegImm_BGEZ ( void ) {
} }
Branch_AddRef(Target, (DWORD*)(RecompPos - 4)); Branch_AddRef(Target, (DWORD*)(RecompPos - 4));
NextInstruction = FINISH_SUB_BLOCK; NextInstruction = FINISH_SUB_BLOCK;
} else if ( NextInstruction == DELAY_SLOT_EXIT_DONE ) {
DWORD Target = (CompilePC + ((short)RSPOpC.offset << 2) + 4) & 0xFFC;
CompileBranchExit(Target, CompilePC + 8);
} else { } else {
CompilerWarning("BGEZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction); CompilerWarning("BGEZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction);
BreakPoint(); BreakPoint();
@ -1461,10 +1502,6 @@ void Compile_RegImm_BGEZAL ( void ) {
/************************** Cop0 functions *************************/ /************************** Cop0 functions *************************/
void Compile_Cop0_MF ( void ) { void Compile_Cop0_MF ( void ) {
#ifndef Compile_Cop0
Cheat_r4300iOpcode(RSP_Cop0_MF,"RSP_Cop0_MF"); return;
#endif
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC)); CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
if (LogRDP) if (LogRDP)
{ {
@ -1478,6 +1515,21 @@ void Compile_Cop0_MF ( void ) {
AddConstToX86Reg(x86_ESP, 8); AddConstToX86Reg(x86_ESP, 8);
} }
#ifndef Compile_Cop0
Cheat_r4300iOpcode(RSP_Cop0_MF,"RSP_Cop0_MF");
if (NextInstruction == NORMAL)
{
MoveConstToVariable(CompilePC + 4,PrgCount,"RSP PC");
Ret();
NextInstruction = FINISH_SUB_BLOCK;
} else if (NextInstruction == DELAY_SLOT) {
NextInstruction = DELAY_SLOT_EXIT;
} else {
CompilerWarning("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction);
BreakPoint();
}
return;
#else
switch (RSPOpC.rd) { switch (RSPOpC.rd) {
case 4: case 4:
MoveVariableToX86reg(RSPInfo.SP_STATUS_REG, "SP_STATUS_REG", x86_EAX); MoveVariableToX86reg(RSPInfo.SP_STATUS_REG, "SP_STATUS_REG", x86_EAX);
@ -1493,9 +1545,17 @@ void Compile_Cop0_MF ( void ) {
break; break;
case 7: case 7:
Cheat_r4300iOpcode(RSP_Cop0_MF,"RSP_Cop0_MF"); Cheat_r4300iOpcode(RSP_Cop0_MF,"RSP_Cop0_MF");
if (NextInstruction == NORMAL)
{
MoveConstToVariable(CompilePC + 4,PrgCount,"RSP PC"); MoveConstToVariable(CompilePC + 4,PrgCount,"RSP PC");
Ret(); Ret();
NextInstruction = FINISH_BLOCK; NextInstruction = FINISH_SUB_BLOCK;
} else if (NextInstruction == DELAY_SLOT) {
NextInstruction = DELAY_SLOT_EXIT;
} else {
CompilerWarning("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction);
BreakPoint();
}
break; break;
case 8: case 8:
MoveVariableToX86reg(RSPInfo.DPC_START_REG, "DPC_START_REG", x86_EAX); MoveVariableToX86reg(RSPInfo.DPC_START_REG, "DPC_START_REG", x86_EAX);
@ -1521,13 +1581,13 @@ void Compile_Cop0_MF ( void ) {
default: default:
CompilerWarning("have not implemented RSP MF CP0 reg %s (%d)",COP0_Name(RSPOpC.rd),RSPOpC.rd); CompilerWarning("have not implemented RSP MF CP0 reg %s (%d)",COP0_Name(RSPOpC.rd),RSPOpC.rd);
} }
#endif
} }
void Compile_Cop0_MT ( void ) { void Compile_Cop0_MT ( void )
#ifndef Compile_Cop0 {
Cheat_r4300iOpcode(RSP_Cop0_MT,"RSP_Cop0_MT");
#else
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC)); CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
if (LogRDP) if (LogRDP)
{ {
char str[40]; char str[40];
@ -1542,6 +1602,23 @@ void Compile_Cop0_MT ( void ) {
AddConstToX86Reg(x86_ESP, 12); AddConstToX86Reg(x86_ESP, 12);
} }
#ifndef Compile_Cop0
Cheat_r4300iOpcode(RSP_Cop0_MT,"RSP_Cop0_MT");
if (RSPOpC.rd == 4)
{
if (NextInstruction == NORMAL)
{
MoveConstToVariable(CompilePC + 4,PrgCount,"RSP PC");
Ret();
NextInstruction = FINISH_BLOCK;
} else if (NextInstruction == DELAY_SLOT) {
NextInstruction = DELAY_SLOT_EXIT;
} else {
CompilerWarning("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction);
BreakPoint();
}
}
#else
switch (RSPOpC.rd) { switch (RSPOpC.rd) {
case 0: case 0:
MoveVariableToX86reg(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX); MoveVariableToX86reg(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX);
@ -4010,7 +4087,7 @@ void Compile_Opcode_LLV ( void ) {
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC)); CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
if ((RSPOpC.del & 0x3) != 0) { if ((RSPOpC.del & 0x3) != 0) {
rsp_UnknownOpcode(); Cheat_r4300iOpcode(RSP_Opcode_LLV,"RSP_Opcode_LLV"); return;
return; return;
} }
@ -4167,7 +4244,7 @@ void Compile_Opcode_LQV ( void ) {
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC)); CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
if (RSPOpC.del != 0) { if (RSPOpC.del != 0) {
rsp_UnknownOpcode(); Cheat_r4300iOpcode(RSP_Opcode_LQV,"RSP_Opcode_LQV"); return;
return; return;
} }