RSP: Can exit after jump from MT/MF Cop 0
This commit is contained in:
parent
38ec949a6e
commit
36def4094a
|
@ -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");
|
||||||
|
Ret();
|
||||||
|
NextInstruction = FINISH_SUB_BLOCK;
|
||||||
|
} else {
|
||||||
|
CompilerWarning("WTF\n\nBREAK\nNextInstruction = %X", NextInstruction);
|
||||||
|
BreakPoint();
|
||||||
}
|
}
|
||||||
MoveConstToVariable(CompilePC + 4,PrgCount,"RSP PC");
|
|
||||||
Ret();
|
|
||||||
NextInstruction = FINISH_BLOCK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
||||||
MoveConstToVariable(CompilePC + 4,PrgCount,"RSP PC");
|
if (NextInstruction == NORMAL)
|
||||||
Ret();
|
{
|
||||||
NextInstruction = FINISH_BLOCK;
|
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();
|
||||||
|
}
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue