mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Invalidate icache before letting the cwcheat engine change memory. Might fix JIT-related cheat crashes.
This commit is contained in:
parent
a370475425
commit
4d11aa3edb
@ -11,6 +11,8 @@
|
||||
#include "Core/ELF/ParamSFO.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/HLE/sceCtrl.h"
|
||||
#include "Core/MIPS/JitCommon/NativeJit.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "util/text/utf8.h"
|
||||
#endif
|
||||
@ -280,6 +282,12 @@ std::vector<std::string> CWCheatEngine::GetCodesList() { //Reads the entire chea
|
||||
return codesList;
|
||||
}
|
||||
|
||||
void CWCheatEngine::InvalidateICache(u32 addr, int size) {
|
||||
if (MIPSComp::jit) {
|
||||
MIPSComp::jit->GetBlockCache()->InvalidateICache(addr & ~3, 4);
|
||||
}
|
||||
}
|
||||
|
||||
void CWCheatEngine::Run() {
|
||||
exit2 = false;
|
||||
while (!exit2) {
|
||||
@ -300,6 +308,7 @@ void CWCheatEngine::Run() {
|
||||
switch (comm >> 28) {
|
||||
case 0: // 8-bit write.But need more check
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
InvalidateICache(addr & ~3, 4);
|
||||
if (arg < 0x00000100) // 8-bit
|
||||
Memory::Write_U8((u8) arg, addr);
|
||||
else if (arg < 0x00010000) // 16-bit
|
||||
@ -310,17 +319,20 @@ void CWCheatEngine::Run() {
|
||||
break;
|
||||
case 0x1: // 16-bit write
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
InvalidateICache(addr & ~3, 4);
|
||||
Memory::Write_U16((u16) arg, addr);
|
||||
}
|
||||
break;
|
||||
case 0x2: // 32-bit write
|
||||
if (Memory::IsValidAddress(addr)){
|
||||
InvalidateICache(addr & ~3, 4);
|
||||
Memory::Write_U32((u32) arg, addr);
|
||||
}
|
||||
break;
|
||||
case 0x3: // Increment/Decrement
|
||||
{
|
||||
addr = GetAddress(arg & 0x0FFFFFFF);
|
||||
InvalidateICache(addr & ~3, 4);
|
||||
value = 0;
|
||||
int increment = 0;
|
||||
// Read value from memory
|
||||
@ -382,6 +394,8 @@ void CWCheatEngine::Run() {
|
||||
|
||||
int maxAddr = (arg >> 16) & 0xFFFF;
|
||||
int stepAddr = (arg & 0xFFFF) * 4;
|
||||
|
||||
InvalidateICache(addr, maxAddr - addr);
|
||||
for (int a = 0; a < maxAddr; a++) {
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
Memory::Write_U32((u32) data, addr);
|
||||
@ -395,8 +409,10 @@ void CWCheatEngine::Run() {
|
||||
code = GetNextCode();
|
||||
if (true) {
|
||||
int destAddr = GetAddress(code[0]);
|
||||
int len = arg;
|
||||
InvalidateICache(destAddr, len);
|
||||
if (Memory::IsValidAddress(addr) && Memory::IsValidAddress(destAddr)) {
|
||||
Memory::Memcpy(destAddr, Memory::GetPointer(addr), arg);
|
||||
Memory::Memcpy(destAddr, Memory::GetPointer(addr), len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -406,6 +422,7 @@ void CWCheatEngine::Run() {
|
||||
int arg2 = code[0];
|
||||
int offset = code[1];
|
||||
int baseOffset = (arg2 >> 20) * 4;
|
||||
InvalidateICache(addr + baseOffset, 4);
|
||||
int base = Memory::Read_U32(addr + baseOffset);
|
||||
int count = arg2 & 0xFFFF;
|
||||
int type = (arg2 >> 16) & 0xF;
|
||||
@ -454,6 +471,7 @@ void CWCheatEngine::Run() {
|
||||
}
|
||||
}
|
||||
|
||||
InvalidateICache((base + offset) & ~3, 4);
|
||||
switch (type) {
|
||||
case 0: // 8 bit write
|
||||
Memory::Write_U8((u8) arg, base + offset);
|
||||
@ -482,6 +500,7 @@ void CWCheatEngine::Run() {
|
||||
switch (arg >> 16) {
|
||||
case 0x0000: // 8-bit OR.
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
InvalidateICache(addr & ~3, 4);
|
||||
int val1 = (int) (arg & 0xFF);
|
||||
int val2 = (int) Memory::Read_U8(addr);
|
||||
Memory::Write_U8((u8) (val1 | val2), addr);
|
||||
@ -489,6 +508,7 @@ void CWCheatEngine::Run() {
|
||||
break;
|
||||
case 0x0002: // 8-bit AND.
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
InvalidateICache(addr & ~3, 4);
|
||||
int val1 = (int) (arg & 0xFF);
|
||||
int val2 = (int) Memory::Read_U8(addr);
|
||||
Memory::Write_U8((u8) (val1 & val2), addr);
|
||||
@ -496,6 +516,7 @@ void CWCheatEngine::Run() {
|
||||
break;
|
||||
case 0x0004: // 8-bit XOR.
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
InvalidateICache(addr & ~3, 4);
|
||||
int val1 = (int) (arg & 0xFF);
|
||||
int val2 = (int) Memory::Read_U8(addr);
|
||||
Memory::Write_U8((u8) (val1 ^ val2), addr);
|
||||
@ -503,6 +524,7 @@ void CWCheatEngine::Run() {
|
||||
break;
|
||||
case 0x0001: // 16-bit OR.
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
InvalidateICache(addr & ~3, 4);
|
||||
short val1 = (short) (arg & 0xFFFF);
|
||||
short val2 = (short) Memory::Read_U16(addr);
|
||||
Memory::Write_U16((u16) (val1 | val2), addr);
|
||||
@ -510,6 +532,7 @@ void CWCheatEngine::Run() {
|
||||
break;
|
||||
case 0x0003: // 16-bit AND.
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
InvalidateICache(addr & ~3, 4);
|
||||
short val1 = (short) (arg & 0xFFFF);
|
||||
short val2 = (short) Memory::Read_U16(addr);
|
||||
Memory::Write_U16((u16) (val1 & val2), addr);
|
||||
@ -517,6 +540,7 @@ void CWCheatEngine::Run() {
|
||||
break;
|
||||
case 0x0005: // 16-bit OR.
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
InvalidateICache(addr & ~3, 4);
|
||||
short val1 = (short) (arg & 0xFFFF);
|
||||
short val2 = (short) Memory::Read_U16(addr);
|
||||
Memory::Write_U16((u16) (val1 ^ val2), addr);
|
||||
@ -533,6 +557,7 @@ void CWCheatEngine::Run() {
|
||||
bool is8Bit = (data >> 16) == 0x0000;
|
||||
int maxAddr = (arg >> 16) & 0xFFFF;
|
||||
int stepAddr = (arg & 0xFFFF) * (is8Bit ? 1 : 2);
|
||||
InvalidateICache(addr, maxAddr - addr);
|
||||
for (int a = 0; a < maxAddr; a++) {
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
if (is8Bit) {
|
||||
@ -551,6 +576,7 @@ void CWCheatEngine::Run() {
|
||||
break;
|
||||
case 0xC: // Code stopper
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
InvalidateICache(addr, 4);
|
||||
value = Memory::Read_U32(addr);
|
||||
if ((u32)value != arg) {
|
||||
SkipAllCodes();
|
||||
|
@ -29,6 +29,7 @@ public:
|
||||
bool HasCheats();
|
||||
|
||||
private:
|
||||
void InvalidateICache(u32 addr, int size);
|
||||
void SkipCodes(int count);
|
||||
void SkipAllCodes();
|
||||
bool cheatsOn, exit2, cheatEnabled;
|
||||
|
Loading…
Reference in New Issue
Block a user