mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Interpreter: Return 0 on all types of bad memory reads - probably best for IgnoreBadMemoryAccess
But ideally I want to get rid of this at some point.
This commit is contained in:
1 parent
991d43a713
commit
3a1162475b
2 files changed
+25
-16
No files matched your search
@@ -116,7 +116,7 @@ static u8 ReadMMIO_U8(MIPSState *mips, u32 addr) {
|
||||
static u16 ReadMMIO_U16(MIPSState *mips, u32 addr) {
|
||||
if (!Memory::IsKernelCodeAddress(mips->pc)) {
|
||||
Core_MemoryException(addr, 2, mips->pc, MemoryExceptionType::READ_WORD, "Kernel mode only");
|
||||
return (u8)UNKNOWN_MMIO_POISON;
|
||||
return (u16)UNKNOWN_MMIO_POISON;
|
||||
}
|
||||
WARN_LOG(Log::CPU, "Unhandled MMIO Read16 at %08x", addr);
|
||||
return (u16)UNKNOWN_MMIO_POISON;
|
||||
@@ -125,7 +125,7 @@ static u16 ReadMMIO_U16(MIPSState *mips, u32 addr) {
|
||||
static u32 ReadMMIO_U32(MIPSState *mips, u32 addr) {
|
||||
if (!Memory::IsKernelCodeAddress(mips->pc)) {
|
||||
Core_MemoryException(addr, 4, mips->pc, MemoryExceptionType::READ_WORD, "Kernel mode only");
|
||||
return (u8)UNKNOWN_MMIO_POISON;
|
||||
return UNKNOWN_MMIO_POISON;
|
||||
}
|
||||
if (GpioMMIO::IsGpioAddress(addr)) {
|
||||
return GpioMMIO::Read32(addr);
|
||||
@@ -434,6 +434,8 @@ namespace MIPSInt {
|
||||
} else {
|
||||
Memory::WriteUnchecked_U32(R(rt), addr);
|
||||
}
|
||||
// Report success even if the store got dropped - reporting failure just makes
|
||||
// the usual retry loop spin on the same bad address forever.
|
||||
if (rt != 0) {
|
||||
R(rt) = 1;
|
||||
}
|
||||
@@ -481,6 +483,11 @@ namespace MIPSInt {
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
// On a bad access that's set to be ignored (the default), we mirror what
|
||||
// Memory::ReadOrException_*/WriteOrException_* do, which is also what the JIT's slow
|
||||
// path calls: loads produce zero, stores are dropped, and PC advances either way.
|
||||
// Returning without advancing PC instead would just re-execute the same instruction forever.
|
||||
// When the access is set to break, Core_MemoryException has already stopped the core.
|
||||
void Int_ITypeMem(MIPSState *mips, MIPSOpcode op) {
|
||||
int imm = (signed short)(op&0xFFFF);
|
||||
int rt = _RT;
|
||||
@@ -601,12 +608,13 @@ namespace MIPSInt {
|
||||
case 34: //lwl
|
||||
{
|
||||
// Not checking for alignment here - the actual read will be aligned.
|
||||
if (!Memory::IsValidAddress(addr)) {
|
||||
u32 mem = 0;
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
mem = Memory::ReadUnchecked_U32(addr & 0xfffffffc);
|
||||
} else {
|
||||
Core_MemoryException(addr, 4, PC, MemoryExceptionType::READ_WORD, "lwl");
|
||||
break;
|
||||
}
|
||||
u32 shift = (addr & 3) * 8;
|
||||
u32 mem = Memory::ReadUnchecked_U32(addr & 0xfffffffc);
|
||||
u32 result = ( u32(R(rt)) & (0x00ffffff >> shift) ) | ( mem << (24 - shift) );
|
||||
R(rt) = result;
|
||||
}
|
||||
@@ -615,12 +623,13 @@ namespace MIPSInt {
|
||||
case 38: //lwr
|
||||
{
|
||||
// Not checking for alignment here - the actual read will be aligned.
|
||||
if (!Memory::IsValidAddress(addr)) {
|
||||
u32 mem = 0;
|
||||
if (Memory::IsValidAddress(addr)) {
|
||||
mem = Memory::ReadUnchecked_U32(addr & 0xfffffffc);
|
||||
} else {
|
||||
Core_MemoryException(addr, 4, PC, MemoryExceptionType::READ_WORD, "lwr");
|
||||
break;
|
||||
}
|
||||
u32 shift = (addr & 3) * 8;
|
||||
u32 mem = Memory::ReadUnchecked_U32(addr & 0xfffffffc);
|
||||
u32 regval = R(rt);
|
||||
u32 result = ( regval & (0xffffff00 << (24 - shift)) ) | ( mem >> shift );
|
||||
R(rt) = result;
|
||||
|
||||
@@ -216,23 +216,22 @@ namespace MIPSInt
|
||||
float d[4];
|
||||
ReadVector(mips, d, V_Quad, vt);
|
||||
int offset = (addr >> 2) & 3;
|
||||
const bool valid = Memory::IsValid4AlignedAddress(addr);
|
||||
if ((op & 2) == 0) {
|
||||
if (!Memory::IsValid4AlignedAddress(addr)) {
|
||||
if (!valid) {
|
||||
Core_MemoryException(addr, 16, PC, MemoryExceptionType::READ_WORD, "lvl.q");
|
||||
break;
|
||||
}
|
||||
// It's an LVL
|
||||
for (int i = 0; i < offset + 1; i++) {
|
||||
d[3 - i] = Memory::ReadUnchecked_Float(addr - 4 * i);
|
||||
d[3 - i] = valid ? Memory::ReadUnchecked_Float(addr - 4 * i) : 0.0f;
|
||||
}
|
||||
} else {
|
||||
if (!Memory::IsValid4AlignedAddress(addr)) {
|
||||
if (!valid) {
|
||||
Core_MemoryException(addr, 16, PC, MemoryExceptionType::READ_WORD, "lvr.q");
|
||||
break;
|
||||
}
|
||||
// It's an LVR
|
||||
for (int i = 0; i < (3 - offset) + 1; i++) {
|
||||
d[i] = Memory::ReadUnchecked_Float(addr + 4 * i);
|
||||
d[i] = valid ? Memory::ReadUnchecked_Float(addr + 4 * i) : 0.0f;
|
||||
}
|
||||
}
|
||||
WriteVector(mips, d, V_Quad, vt);
|
||||
@@ -244,13 +243,14 @@ namespace MIPSInt
|
||||
// rejected - we don't try to carry it out anyway, same as every other path here.
|
||||
if ((addr & 0xF) || !Memory::IsValid4AlignedAddress(addr)) {
|
||||
Core_MemoryException(addr, 16, PC, MemoryExceptionType::READ_WORD, "lv.q");
|
||||
const float zero[4]{};
|
||||
WriteVector(mips, zero, V_Quad, vt);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef COMMON_BIG_ENDIAN
|
||||
cf = reinterpret_cast<const float *>(Memory::GetPointerUnchecked(addr));
|
||||
if (cf)
|
||||
WriteVector(mips, cf, V_Quad, vt);
|
||||
WriteVector(mips, cf, V_Quad, vt);
|
||||
#else
|
||||
float lvqd[4];
|
||||
|
||||
|
||||
Reference in new issue
Block a user