diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index 67171894d..2108cde51 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -87,6 +87,7 @@ void MIPSState::Reset() exceptions = 0; currentMIPS = this; inDelaySlot = false; + llBit = 0; nextPC = 0; // Initialize the VFPU random number generator with .. something? rng.Init(0x1337); diff --git a/Core/MIPS/MIPS.h b/Core/MIPS/MIPS.h index d08410e51..48d86499c 100644 --- a/Core/MIPS/MIPS.h +++ b/Core/MIPS/MIPS.h @@ -124,6 +124,7 @@ public: GMRng rng; // VFPU hardware random number generator. Probably not the right type. bool inDelaySlot; + int llBit; // ll/sc CPUType cpuType; diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index 06da1ef60..0427be8e5 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -109,7 +109,7 @@ namespace MIPSInt { void Int_Cache(u32 op) { - DEBUG_LOG(CPU,"cache instruction %08x",op); + // DEBUG_LOG(CPU,"cache instruction %08x",op); PC += 4; } @@ -301,6 +301,33 @@ namespace MIPSInt PC += 4; } + void Int_StoreSync(u32 op) + { + s32 imm = (signed short)(op&0xFFFF); + int base = ((op >> 21) & 0x1f); + int rt = (op >> 16) & 0x1f; + u32 addr = R(base) + imm; + + switch (op >> 26) + { + case 48: // ll + R(rt) = Memory::Read_U32(addr); + currentMIPS->llBit = 1; + break; + case 56: // sc + if (currentMIPS->llBit) { + Memory::Write_U32(R(rt), addr); + R(rt) = 1; + } else { + R(rt) = 0; + } + break; + default: + _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + break; + } + PC += 4; + } void Int_RType3(u32 op) diff --git a/Core/MIPS/MIPSInt.h b/Core/MIPS/MIPSInt.h index cf2a882d5..7f7ad7d1c 100644 --- a/Core/MIPS/MIPSInt.h +++ b/Core/MIPS/MIPSInt.h @@ -53,4 +53,5 @@ namespace MIPSInt void Int_Cache(u32 op); void Int_Sync(u32 op); void Int_Break(u32 op); + void Int_StoreSync(u32 op); } diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index 5ee934c27..43efe1888 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -148,7 +148,7 @@ const MIPSInstruction tableImmediate[64] = //xxxxxx ..... INSTR("swr", &Jit::Comp_ITypeMem, Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM), INSTR("cache", &Jit::Comp_Generic, Dis_Generic, Int_Cache, 0), //48 - INSTR("ll", &Jit::Comp_Generic, Dis_Generic, 0, 0), + INSTR("ll", &Jit::Comp_Generic, Dis_Generic, Int_StoreSync, 0), INSTR("lwc1", &Jit::Comp_FPULS, Dis_FPULS, Int_FPULS, IN_RT|IN_RS_ADDR), INSTR("lv.s", &Jit::Comp_Generic, Dis_SV, Int_SV, IS_VFPU), {-2}, // HIT THIS IN WIPEOUT @@ -157,7 +157,7 @@ const MIPSInstruction tableImmediate[64] = //xxxxxx ..... INSTR("lv.q", &Jit::Comp_Generic, Dis_SVQ, Int_SVQ, IS_VFPU), //copU {VFPU5}, //56 - INSTR("sc", &Jit::Comp_Generic, Dis_Generic, 0, 0), + INSTR("sc", &Jit::Comp_Generic, Dis_Generic, Int_StoreSync, 0), INSTR("swc1", &Jit::Comp_FPULS, Dis_FPULS, Int_FPULS, 0), //copU INSTR("sv.s", &Jit::Comp_Generic, Dis_SV, Int_SV,IS_VFPU), {-2},