[Core] Clean up load/store usage in MemoryVirtualMem

This commit is contained in:
zilmar 2022-05-09 10:06:10 +09:30
parent 1aee99fde5
commit 718d7e0359
8 changed files with 340 additions and 631 deletions

View File

@ -169,42 +169,34 @@ bool CMipsMemoryVM::FilterX86Exception(uint32_t MemAddress, X86_CONTEXT & contex
switch (*(TypePos + 1)) switch (*(TypePos + 1))
{ {
case 0xB6: case 0xB6:
if (!g_MMU->LB_NonMemory(MemAddress, (uint32_t *)Reg, false))
{ {
if (ShowUnhandledMemory()) uint8_t Value = 0;
{ g_MMU->LB_NonMemory((MemAddress | 0x80000000) ^ 3, Value);
g_Notify->DisplayError(stdstr_f("Failed to load byte\n\nMIPS address: %08X\nX86 address: %08X", MemAddress, (uint8_t *)*context.Eip).c_str()); *(uint32_t *)Reg = Value;
}
} }
*context.Eip = (uint32_t)ReadPos; *context.Eip = (uint32_t)ReadPos;
return true; return true;
case 0xB7: case 0xB7:
if (!g_MMU->LH_NonMemory(MemAddress, (uint32_t *)Reg, false))
{ {
if (ShowUnhandledMemory()) uint16_t Value = 0;
{ g_MMU->LH_NonMemory((MemAddress | 0x80000000) ^ 2, Value);
g_Notify->DisplayError(stdstr_f("Failed to load half word\n\nMIPS address: %08X\nX86 address: %08X", MemAddress, (uint8_t *)*context.Eip).c_str()); *(uint32_t *)Reg = Value;
}
} }
*context.Eip = (uint32_t)ReadPos; *context.Eip = (uint32_t)ReadPos;
return true; return true;
case 0xBE: case 0xBE:
if (!g_MMU->LB_NonMemory(MemAddress, (uint32_t *)Reg, true))
{ {
if (ShowUnhandledMemory()) uint8_t Value = 0;
{ g_MMU->LB_NonMemory((MemAddress | 0x80000000) ^ 3, Value);
g_Notify->DisplayError(stdstr_f("Failed to load byte\n\nMIPS address: %08X\nX86 address: %08X", MemAddress, (uint8_t *)*context.Eip).c_str()); *(int32_t *)Reg = (int8_t)Value;
}
} }
*context.Eip = (uint32_t)ReadPos; *context.Eip = (uint32_t)ReadPos;
return true; return true;
case 0xBF: case 0xBF:
if (!g_MMU->LH_NonMemory(MemAddress, (uint32_t *)Reg, true))
{ {
if (ShowUnhandledMemory()) uint16_t Value = 0;
{ g_MMU->LH_NonMemory((MemAddress | 0x80000000) ^ 2, Value);
g_Notify->DisplayError(stdstr_f("Failed to load half word\n\nMIPS address: %08X\nX86 address: %08X", MemAddress, (uint8_t *)*context.Eip).c_str()); *(int32_t *)Reg = (int16_t)Value;
}
} }
*context.Eip = (uint32_t)ReadPos; *context.Eip = (uint32_t)ReadPos;
return true; return true;
@ -220,24 +212,15 @@ bool CMipsMemoryVM::FilterX86Exception(uint32_t MemAddress, X86_CONTEXT & contex
switch (*(TypePos + 1)) switch (*(TypePos + 1))
{ {
case 0x8B: case 0x8B:
if (!g_MMU->LH_NonMemory(MemAddress, (uint32_t *)Reg, false))
{ {
if (ShowUnhandledMemory()) uint16_t Value = 0;
{ g_MMU->LH_NonMemory((MemAddress | 0x80000000) ^ 2, Value);
g_Notify->DisplayError(stdstr_f("Failed to half word\n\nMIPS address: %08X\nX86 address: %08X", MemAddress, (uint8_t *)*context.Eip).c_str()); *(uint32_t *)Reg = Value;
}
} }
*context.Eip = (uint32_t)ReadPos; *context.Eip = (uint32_t)ReadPos;
return true; return true;
case 0x89: case 0x89:
if (!g_MMU->SH_NonMemory(MemAddress, *(uint16_t *)Reg)) g_MMU->SH_NonMemory((MemAddress | 0x80000000) ^ 2, *(uint16_t *)Reg);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store half word\n\nMIPS address: %08X\nX86 address: %08X", MemAddress,
(uint8_t *)*context.Eip).c_str());
}
}
*context.Eip = (uint32_t)ReadPos; *context.Eip = (uint32_t)ReadPos;
return true; return true;
case 0xC7: case 0xC7:
@ -249,13 +232,7 @@ bool CMipsMemoryVM::FilterX86Exception(uint32_t MemAddress, X86_CONTEXT & contex
} }
return false; return false;
} }
if (!g_MMU->SH_NonMemory(MemAddress, *(uint16_t *)ReadPos)) g_MMU->SH_NonMemory((MemAddress | 0x80000000) ^ 2, *(uint16_t *)ReadPos);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store half word\n\nMIPS address: %08X\nX86 address: %08X", MemAddress, (uint8_t *)*context.Eip).c_str());
}
}
*context.Eip = (uint32_t)(ReadPos + 2); *context.Eip = (uint32_t)(ReadPos + 2);
return true; return true;
default: default:
@ -267,43 +244,23 @@ bool CMipsMemoryVM::FilterX86Exception(uint32_t MemAddress, X86_CONTEXT & contex
} }
break; break;
case 0x88: case 0x88:
if (!g_MMU->SB_NonMemory(MemAddress, *(uint8_t *)Reg)) g_MMU->SB_NonMemory((MemAddress | 0x80000000) ^ 3, *(uint8_t *)Reg);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store byte\n\nMIPS address: %08X\nX86 address: %08X", MemAddress, (uint8_t *)*context.Eip).c_str());
}
}
*context.Eip = (uint32_t)ReadPos; *context.Eip = (uint32_t)ReadPos;
return true; return true;
case 0x8A: case 0x8A:
if (!g_MMU->LB_NonMemory(MemAddress, (uint32_t *)Reg, false))
{ {
if (ShowUnhandledMemory()) uint8_t Value = 0;
{ g_MMU->LB_NonMemory((MemAddress | 0x80000000) ^ 3, Value);
g_Notify->DisplayError(stdstr_f("Failed to load byte\n\nMIPS address: %08X\nX86 address: %08X", MemAddress, (uint8_t *)*context.Eip).c_str()); *(uint32_t *)Reg = Value;
}
} }
*context.Eip = (uint32_t)ReadPos; *context.Eip = (uint32_t)ReadPos;
return true; return true;
case 0x8B: case 0x8B:
if (!g_MMU->LW_NonMemory(MemAddress, (uint32_t *)Reg)) g_MMU->LW_NonMemory(MemAddress | 0x80000000, *((uint32_t *)Reg));
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to load word\n\nMIPS address: %08X\nX86 address: %08X", MemAddress, (uint8_t *)*context.Eip).c_str());
}
}
*context.Eip = (uint32_t)ReadPos; *context.Eip = (uint32_t)ReadPos;
return true; return true;
case 0x89: case 0x89:
if (!g_MMU->SW_NonMemory(MemAddress, *(uint32_t *)Reg)) g_MMU->SW_NonMemory(MemAddress | 0x80000000, *(uint32_t *)Reg);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store word\n\nMIPS address: %08X\nX86 address: %08X", MemAddress, (uint8_t *)*context.Eip).c_str());
}
}
*context.Eip = (uint32_t)ReadPos; *context.Eip = (uint32_t)ReadPos;
return true; return true;
case 0xC6: case 0xC6:
@ -315,13 +272,7 @@ bool CMipsMemoryVM::FilterX86Exception(uint32_t MemAddress, X86_CONTEXT & contex
} }
return false; return false;
} }
if (!g_MMU->SB_NonMemory(MemAddress, *(uint8_t *)ReadPos)) g_MMU->SB_NonMemory((MemAddress | 0x80000000) ^ 3, *(uint8_t *)ReadPos);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store byte\n\nMIPS address: %08X\nX86 address: %08X", MemAddress, (uint8_t *)*context.Eip).c_str());
}
}
*context.Eip = (uint32_t)(ReadPos + 1); *context.Eip = (uint32_t)(ReadPos + 1);
return true; return true;
case 0xC7: case 0xC7:
@ -333,13 +284,7 @@ bool CMipsMemoryVM::FilterX86Exception(uint32_t MemAddress, X86_CONTEXT & contex
} }
return false; return false;
} }
if (!g_MMU->SW_NonMemory(MemAddress, *(uint32_t *)ReadPos)) g_MMU->SW_NonMemory(MemAddress | 0x80000000, *(uint32_t *)ReadPos);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store word\n\nMIPS address: %08X\nX86 address: %08X", MemAddress, (uint8_t *)*context.Eip).c_str());
}
}
*context.Eip = (uint32_t)(ReadPos + 4); *context.Eip = (uint32_t)(ReadPos + 4);
return true; return true;
} }
@ -448,25 +393,13 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
Arm32Opcode * OpCode32 = (Arm32Opcode *)context.arm_pc; Arm32Opcode * OpCode32 = (Arm32Opcode *)context.arm_pc;
if (OpCode->Reg.opcode == ArmLDR_Reg) if (OpCode->Reg.opcode == ArmLDR_Reg)
{ {
if (!g_MMU->LW_NonMemory(MemAddress, ArmRegisters[OpCode->Reg.rt])) g_MMU->LW_NonMemory(MemAddress | 0x80000000, *ArmRegisters[OpCode->Reg.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to load word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 2; context.arm_pc = context.arm_pc + 2;
return true; return true;
} }
if (OpCode->Reg.opcode == ArmSTR_Reg) if (OpCode->Reg.opcode == ArmSTR_Reg)
{ {
if (!g_MMU->SW_NonMemory(MemAddress, *ArmRegisters[OpCode->Reg.rt])) g_MMU->SW_NonMemory(MemAddress | 0x80000000, *ArmRegisters[OpCode->Reg.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 2; context.arm_pc = context.arm_pc + 2;
return true; return true;
} }
@ -474,13 +407,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode32->imm2.opcode == 0xF84 && OpCode32->imm2.Opcode2 == 0) if (OpCode32->imm2.opcode == 0xF84 && OpCode32->imm2.Opcode2 == 0)
{ {
// 42 f8 03 c0 str.w ip, [r2, r3] // 42 f8 03 c0 str.w ip, [r2, r3]
if (!g_MMU->SW_NonMemory(MemAddress, *ArmRegisters[OpCode32->imm2.rt])) g_MMU->SW_NonMemory(MemAddress | 0x80000000, *ArmRegisters[OpCode32->imm2.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 4; context.arm_pc = context.arm_pc + 4;
return true; return true;
} }
@ -488,13 +415,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode32->imm12.opcode == 0xF8C) if (OpCode32->imm12.opcode == 0xF8C)
{ {
// c9 f8 00 b0 str.w r11, [r9] // c9 f8 00 b0 str.w r11, [r9]
if (!g_MMU->SW_NonMemory(MemAddress, *ArmRegisters[OpCode32->imm2.rt])) g_MMU->SW_NonMemory(MemAddress | 0x80000000, *ArmRegisters[OpCode32->imm2.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 4; context.arm_pc = context.arm_pc + 4;
return true; return true;
} }
@ -502,13 +423,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode32->imm12.opcode == 0xF8D) if (OpCode32->imm12.opcode == 0xF8D)
{ {
// dc f8 70 70 ldr.w r7, [ip, #112] // dc f8 70 70 ldr.w r7, [ip, #112]
if (!g_MMU->LW_NonMemory(MemAddress, ArmRegisters[OpCode32->imm12.rt])) g_MMU->LW_NonMemory(MemAddress | 0x80000000, *ArmRegisters[OpCode32->imm12.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to load word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 4; context.arm_pc = context.arm_pc + 4;
return true; return true;
} }
@ -517,26 +432,14 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
{ {
// 17847001 strne r7, [r4, r1] // 17847001 strne r7, [r4, r1]
// e789300c str r3, [r9, ip] // e789300c str r3, [r9, ip]
if (!g_MMU->SW_NonMemory(MemAddress, *ArmRegisters[OpCode32->reg_cond_imm5.rt])) g_MMU->SW_NonMemory(MemAddress | 0x80000000, *ArmRegisters[OpCode32->reg_cond_imm5.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 4; context.arm_pc = context.arm_pc + 4;
return true; return true;
} }
if (OpCode->Reg.opcode == 0x2A) // STRB if (OpCode->Reg.opcode == 0x2A) // STRB
{ {
if (!g_MMU->SB_NonMemory(MemAddress, *ArmRegisters[OpCode->Reg.rt])) g_MMU->SB_NonMemory((MemAddress | 0x80000000) ^ 3, *ArmRegisters[OpCode->Reg.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store byte\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 2; context.arm_pc = context.arm_pc + 2;
return true; return true;
} }
@ -544,13 +447,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode32->reg_cond_imm5.opcode == 3 && OpCode32->reg_cond_imm5.opcode1 == 1 && OpCode32->reg_cond_imm5.opcode2 == 0 && OpCode32->reg_cond_imm5.opcode3 == 0) if (OpCode32->reg_cond_imm5.opcode == 3 && OpCode32->reg_cond_imm5.opcode1 == 1 && OpCode32->reg_cond_imm5.opcode2 == 0 && OpCode32->reg_cond_imm5.opcode3 == 0)
{ {
// 17c32001 strbne r2, [r3, r1] // 17c32001 strbne r2, [r3, r1]
if (!g_MMU->SB_NonMemory(MemAddress, *ArmRegisters[OpCode32->reg_cond_imm5.rt])) g_MMU->SB_NonMemory((MemAddress | 0x80000000) ^ 3, *ArmRegisters[OpCode32->reg_cond_imm5.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store byte\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 4; context.arm_pc = context.arm_pc + 4;
return true; return true;
} }
@ -558,13 +455,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode32->reg_cond_imm8.opcode == 0 && OpCode32->reg_cond_imm8.opcode1 == 1 && OpCode32->reg_cond_imm8.opcode2 == 0 && OpCode32->reg_cond_imm8.opcode3 == 0xB) if (OpCode32->reg_cond_imm8.opcode == 0 && OpCode32->reg_cond_imm8.opcode1 == 1 && OpCode32->reg_cond_imm8.opcode2 == 0 && OpCode32->reg_cond_imm8.opcode3 == 0xB)
{ {
// 11c020b0 strhne r2, [r0] // 11c020b0 strhne r2, [r0]
if (!g_MMU->SH_NonMemory(MemAddress, *ArmRegisters[OpCode32->reg_cond_imm8.rt])) g_MMU->SH_NonMemory((MemAddress | 0x80000000) ^ 2, *ArmRegisters[OpCode32->reg_cond_imm8.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store half word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 4; context.arm_pc = context.arm_pc + 4;
return true; return true;
} }
@ -572,13 +463,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode->Imm5.opcode == 0x10) if (OpCode->Imm5.opcode == 0x10)
{ {
// 00 80 strh r0, [r0, #0] // 00 80 strh r0, [r0, #0]
if (!g_MMU->SH_NonMemory(MemAddress, *ArmRegisters[OpCode->Imm5.rt])) g_MMU->SH_NonMemory((MemAddress | 0x80000000) ^ 2, *ArmRegisters[OpCode->Imm5.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store half word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 2; context.arm_pc = context.arm_pc + 2;
return true; return true;
} }
@ -586,13 +471,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode->Reg.opcode == 0x29) if (OpCode->Reg.opcode == 0x29)
{ {
// 14 52 strh r4, [r2, r0] // 14 52 strh r4, [r2, r0]
if (!g_MMU->SH_NonMemory(MemAddress, *ArmRegisters[OpCode->Reg.rt])) g_MMU->SH_NonMemory((MemAddress | 0x80000000) ^ 2, *ArmRegisters[OpCode->Reg.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store half word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 2; context.arm_pc = context.arm_pc + 2;
return true; return true;
} }
@ -600,13 +479,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode->Imm5.opcode == 0xC) if (OpCode->Imm5.opcode == 0xC)
{ {
// 2e 60 str r6, [r5, #0] // 2e 60 str r6, [r5, #0]
if (!g_MMU->SW_NonMemory(MemAddress, *ArmRegisters[OpCode->Imm5.rt])) g_MMU->SW_NonMemory(MemAddress | 0x80000000, *ArmRegisters[OpCode->Imm5.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 2; context.arm_pc = context.arm_pc + 2;
return true; return true;
} }
@ -614,13 +487,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode->Imm5.opcode == 0xD) if (OpCode->Imm5.opcode == 0xD)
{ {
// 3F 68 ldr r7, [r7, #0] // 3F 68 ldr r7, [r7, #0]
if (!g_MMU->LW_NonMemory(MemAddress, ArmRegisters[OpCode->Imm5.rt])) g_MMU->LW_NonMemory(MemAddress | 0x80000000, *ArmRegisters[OpCode->Imm5.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to load word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 2; context.arm_pc = context.arm_pc + 2;
return true; return true;
} }
@ -628,13 +495,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode->Imm5.opcode == 0xE) if (OpCode->Imm5.opcode == 0xE)
{ {
// b8 70 strb r0, [r7, #2] // b8 70 strb r0, [r7, #2]
if (!g_MMU->SB_NonMemory(MemAddress, *ArmRegisters[OpCode->Imm5.rt])) g_MMU->SB_NonMemory((MemAddress | 0x80000000) ^ 3, *ArmRegisters[OpCode->Imm5.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store byte\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 2; context.arm_pc = context.arm_pc + 2;
return true; return true;
} }
@ -642,13 +503,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode32->reg_cond.opcode == 0 && OpCode32->reg_cond.opcode1 == 0 && OpCode32->reg_cond.opcode2 == 0 && OpCode32->reg_cond.opcode3 == 0xB) if (OpCode32->reg_cond.opcode == 0 && OpCode32->reg_cond.opcode1 == 0 && OpCode32->reg_cond.opcode2 == 0 && OpCode32->reg_cond.opcode3 == 0xB)
{ {
// 118320b1 strhne r2, [r3, r1] // 118320b1 strhne r2, [r3, r1]
if (!g_MMU->SH_NonMemory(MemAddress, *ArmRegisters[OpCode32->reg_cond.rt])) g_MMU->SH_NonMemory((MemAddress | 0x80000000) ^ 2, *ArmRegisters[OpCode32->reg_cond.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store half word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 4; context.arm_pc = context.arm_pc + 4;
return true; return true;
} }
@ -656,13 +511,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode32->reg_cond_imm12.opcode == 2 && OpCode32->reg_cond_imm12.opcode1 == 0 && OpCode32->reg_cond_imm12.opcode2 == 0) if (OpCode32->reg_cond_imm12.opcode == 2 && OpCode32->reg_cond_imm12.opcode1 == 0 && OpCode32->reg_cond_imm12.opcode2 == 0)
{ {
// e48a1004 str r1, [sl], #4 // e48a1004 str r1, [sl], #4
if (!g_MMU->SW_NonMemory(MemAddress, *ArmRegisters[OpCode32->reg_cond_imm12.rt])) g_MMU->SW_NonMemory(MemAddress | 0x80000000, *ArmRegisters[OpCode32->reg_cond_imm12.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to store word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 4; context.arm_pc = context.arm_pc + 4;
return true; return true;
} }
@ -670,13 +519,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode32->uint16.opcode == ArmLDRH_W) if (OpCode32->uint16.opcode == ArmLDRH_W)
{ {
// f833 c001 ldrh.w ip, [r3, r1] // f833 c001 ldrh.w ip, [r3, r1]
if (!g_MMU->LH_NonMemory(MemAddress, ArmRegisters[OpCode32->uint16.rt], false)) g_MMU->LH_NonMemory((MemAddress | 0x80000000) ^ 2, ArmRegisters[OpCode32->uint16.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to load half word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 4; context.arm_pc = context.arm_pc + 4;
return true; return true;
} }
@ -684,13 +527,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode32->uint32.opcode == ArmLDRH_Reg && OpCode32->uint32.opcode2 == 0xB) if (OpCode32->uint32.opcode == ArmLDRH_Reg && OpCode32->uint32.opcode2 == 0xB)
{ {
// e19a20b2 ldrh r2, [sl, r2] // e19a20b2 ldrh r2, [sl, r2]
if (!g_MMU->LH_NonMemory(MemAddress, ArmRegisters[OpCode32->uint32.rt], false)) g_MMU->LH_NonMemory((MemAddress | 0x80000000) ^ 2, ArmRegisters[OpCode32->uint32.rt], false);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to load half word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 4; context.arm_pc = context.arm_pc + 4;
return true; return true;
} }
@ -699,13 +536,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
{ {
// 119330b1 ldrhne r3, [r3, r1] // 119330b1 ldrhne r3, [r3, r1]
// 11d000b0 ldrhne r0, [r0] // 11d000b0 ldrhne r0, [r0]
if (!g_MMU->LH_NonMemory(MemAddress, ArmRegisters[OpCode32->reg_cond.rt], false)) !g_MMU->LH_NonMemory((MemAddress | 0x80000000) ^ 2, ArmRegisters[OpCode32->reg_cond.rt], false);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to load half word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 4; context.arm_pc = context.arm_pc + 4;
return true; return true;
} }
@ -713,13 +544,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode32->reg_cond_imm5.opcode == 3 && OpCode32->reg_cond_imm5.opcode1 == 0 && OpCode32->reg_cond_imm5.opcode2 == 1 && OpCode32->reg_cond_imm5.opcode3 == 0) if (OpCode32->reg_cond_imm5.opcode == 3 && OpCode32->reg_cond_imm5.opcode1 == 0 && OpCode32->reg_cond_imm5.opcode2 == 1 && OpCode32->reg_cond_imm5.opcode3 == 0)
{ {
// 1790a001 ldrne sl, [r0, r1] // 1790a001 ldrne sl, [r0, r1]
if (!g_MMU->LW_NonMemory(MemAddress, ArmRegisters[OpCode32->reg_cond_imm5.rt])) g_MMU->LW_NonMemory(MemAddress | 0x80000000, *ArmRegisters[OpCode32->reg_cond_imm5.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to load word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 4; context.arm_pc = context.arm_pc + 4;
return true; return true;
} }
@ -727,13 +552,7 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
if (OpCode32->imm2.opcode == 0xF85 && OpCode32->imm2.Opcode2 == 0) if (OpCode32->imm2.opcode == 0xF85 && OpCode32->imm2.Opcode2 == 0)
{ {
// 52 f8 21 30 ldr.w r3, [r2, r1, lsl #2] // 52 f8 21 30 ldr.w r3, [r2, r1, lsl #2]
if (!g_MMU->LW_NonMemory(MemAddress, ArmRegisters[OpCode32->imm2.rt])) g_MMU->LW_NonMemory(MemAddress | 0x80000000, *ArmRegisters[OpCode32->imm2.rt]);
{
if (ShowUnhandledMemory())
{
g_Notify->DisplayError(stdstr_f("Failed to load word\n\nMIPS address: %08X\nPC address: %08X", MemAddress, context.arm_pc).c_str());
}
}
context.arm_pc = context.arm_pc + 4; context.arm_pc = context.arm_pc + 4;
return true; return true;
} }

View File

@ -62,18 +62,6 @@ const int32_t R4300iOp::LWR_SHIFT[4] = { 24, 16, 8, 0 };
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\ g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\
return;}\ return;}\
#define TLB_READ_EXCEPTION(Address) \
g_Reg->DoTLBReadMiss(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,Address);\
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;\
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\
return;
#define TLB_WRITE_EXCEPTION(Address) \
g_Reg->DoTLBWriteMiss(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,Address);\
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;\
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\
return;
void R4300iOp::SPECIAL() void R4300iOp::SPECIAL()
{ {
Jump_Special[m_Opcode.funct](); Jump_Special[m_Opcode.funct]();
@ -999,26 +987,23 @@ int32_t LDL_SHIFT[8] = { 0, 8, 16, 24, 32, 40, 48, 56 };
void R4300iOp::LDL() void R4300iOp::LDL()
{ {
uint32_t Offset, Address; uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
uint64_t Value;
Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
if (HaveReadBP() && g_Debugger->ReadBP64(Address) && MemoryBreakpoint()) if (HaveReadBP() && g_Debugger->ReadBP64(Address) && MemoryBreakpoint())
{ {
return; return;
} }
Offset = Address & 7;
if (!g_MMU->LD_VAddr((Address & ~7), Value)) uint64_t Value;
if (!g_MMU->LD_Memory((Address & ~7), Value))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
}
else
{ {
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str()); uint32_t Offset = Address & 7;
}
TLB_READ_EXCEPTION(Address);
}
_GPR[m_Opcode.rt].DW = _GPR[m_Opcode.rt].DW & LDL_MASK[Offset]; _GPR[m_Opcode.rt].DW = _GPR[m_Opcode.rt].DW & LDL_MASK[Offset];
_GPR[m_Opcode.rt].DW += Value << LDL_SHIFT[Offset]; _GPR[m_Opcode.rt].DW += Value << LDL_SHIFT[Offset];
}
} }
uint64_t LDR_MASK[8] = { 0xFFFFFFFFFFFFFF00, 0xFFFFFFFFFFFF0000, uint64_t LDR_MASK[8] = { 0xFFFFFFFFFFFFFF00, 0xFFFFFFFFFFFF0000,
@ -1029,27 +1014,24 @@ int32_t LDR_SHIFT[8] = { 56, 48, 40, 32, 24, 16, 8, 0 };
void R4300iOp::LDR() void R4300iOp::LDR()
{ {
uint32_t Offset, Address; uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
uint64_t Value;
Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
if (HaveReadBP() && g_Debugger->ReadBP64(Address) && MemoryBreakpoint()) if (HaveReadBP() && g_Debugger->ReadBP64(Address) && MemoryBreakpoint())
{ {
return; return;
} }
Offset = Address & 7;
if (!g_MMU->LD_VAddr((Address & ~7), Value)) uint64_t Value;
if (!g_MMU->LD_Memory((Address & ~7), Value))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
}
else
{ {
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str()); uint32_t Offset = Address & 7;
}
TLB_READ_EXCEPTION(Address);
}
_GPR[m_Opcode.rt].DW = _GPR[m_Opcode.rt].DW & LDR_MASK[Offset]; _GPR[m_Opcode.rt].DW = _GPR[m_Opcode.rt].DW & LDR_MASK[Offset];
_GPR[m_Opcode.rt].DW += Value >> LDR_SHIFT[Offset]; _GPR[m_Opcode.rt].DW += Value >> LDR_SHIFT[Offset];
}
} }
void R4300iOp::LB() void R4300iOp::LB()
@ -1059,13 +1041,9 @@ void R4300iOp::LB()
{ {
return; return;
} }
if (!g_MMU->LB_VAddr(Address, _GPR[m_Opcode.rt].UB[0])) if (!g_MMU->LB_Memory(Address, _GPR[m_Opcode.rt].UB[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {
@ -1084,13 +1062,9 @@ void R4300iOp::LH()
{ {
return; return;
} }
if (!g_MMU->LH_VAddr(Address, _GPR[m_Opcode.rt].UHW[0])) if (!g_MMU->LH_Memory(Address, _GPR[m_Opcode.rt].UHW[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {
@ -1100,26 +1074,22 @@ void R4300iOp::LH()
void R4300iOp::LWL() void R4300iOp::LWL()
{ {
uint32_t Offset, Address, Value; uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
{ {
return; return;
} }
Offset = Address & 3; uint32_t Value;
if (!g_MMU->LW_Memory((Address & ~3), Value))
if (!g_MMU->LW_VAddr((Address & ~3), Value))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
}
else
{ {
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str()); uint32_t Offset = Address & 3;
}
TLB_READ_EXCEPTION(Address);
}
_GPR[m_Opcode.rt].DW = (int32_t)(_GPR[m_Opcode.rt].W[0] & LWL_MASK[Offset]); _GPR[m_Opcode.rt].DW = (int32_t)(_GPR[m_Opcode.rt].W[0] & LWL_MASK[Offset]);
_GPR[m_Opcode.rt].DW += (int32_t)(Value << LWL_SHIFT[Offset]); _GPR[m_Opcode.rt].DW += (int32_t)(Value << LWL_SHIFT[Offset]);
}
} }
void R4300iOp::LW() void R4300iOp::LW()
@ -1134,13 +1104,9 @@ void R4300iOp::LW()
return; return;
} }
if (!g_MMU->LW_VAddr(Address, _GPR[m_Opcode.rt].UW[0])) if (!g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {
@ -1155,13 +1121,9 @@ void R4300iOp::LBU()
{ {
return; return;
} }
if (!g_MMU->LB_VAddr(Address, _GPR[m_Opcode.rt].UB[0])) if (!g_MMU->LB_Memory(Address, _GPR[m_Opcode.rt].UB[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {
@ -1180,13 +1142,9 @@ void R4300iOp::LHU()
{ {
return; return;
} }
if (!g_MMU->LH_VAddr(Address, _GPR[m_Opcode.rt].UHW[0])) if (!g_MMU->LH_Memory(Address, _GPR[m_Opcode.rt].UHW[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {
@ -1196,26 +1154,23 @@ void R4300iOp::LHU()
void R4300iOp::LWR() void R4300iOp::LWR()
{ {
uint32_t Offset, Address, Value; uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
Offset = Address & 3;
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
{ {
return; return;
} }
if (!g_MMU->LW_VAddr((Address & ~3), Value)) uint32_t Value;
if (!g_MMU->LW_Memory((Address & ~3), Value))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
}
else
{ {
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str()); uint32_t Offset = Address & 3;
}
TLB_READ_EXCEPTION(Address);
}
_GPR[m_Opcode.rt].DW = (int32_t)(_GPR[m_Opcode.rt].W[0] & LWR_MASK[Offset]); _GPR[m_Opcode.rt].DW = (int32_t)(_GPR[m_Opcode.rt].W[0] & LWR_MASK[Offset]);
_GPR[m_Opcode.rt].DW += (int32_t)(Value >> LWR_SHIFT[Offset]); _GPR[m_Opcode.rt].DW += (int32_t)(Value >> LWR_SHIFT[Offset]);
}
} }
void R4300iOp::LWU() void R4300iOp::LWU()
@ -1230,13 +1185,9 @@ void R4300iOp::LWU()
return; return;
} }
if (!g_MMU->LW_VAddr(Address, _GPR[m_Opcode.rt].UW[0])) if (!g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {
@ -1253,11 +1204,7 @@ void R4300iOp::SB()
} }
if (!g_MMU->SB_VAddr(Address, _GPR[m_Opcode.rt].UB[0])) if (!g_MMU->SB_VAddr(Address, _GPR[m_Opcode.rt].UB[0]))
{ {
if (bShowTLBMisses()) GenerateTLBWriteException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
} }
} }
@ -1274,11 +1221,7 @@ void R4300iOp::SH()
} }
if (!g_MMU->SH_VAddr(Address, _GPR[m_Opcode.rt].UHW[0])) if (!g_MMU->SH_VAddr(Address, _GPR[m_Opcode.rt].UHW[0]))
{ {
if (bShowTLBMisses()) GenerateTLBWriteException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
} }
} }
@ -1293,26 +1236,15 @@ void R4300iOp::SWL()
} }
Offset = Address & 3; Offset = Address & 3;
if (!g_MMU->LW_VAddr((Address & ~3), Value)) if (!g_MMU->LW_Memory((Address & ~3), Value))
{ {
if (bShowTLBMisses()) GenerateTLBWriteException(Address, __FUNCTION__);
{ return;
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
} }
Value &= SWL_MASK[Offset]; Value &= SWL_MASK[Offset];
Value += _GPR[m_Opcode.rt].UW[0] >> SWL_SHIFT[Offset]; Value += _GPR[m_Opcode.rt].UW[0] >> SWL_SHIFT[Offset];
g_MMU->SW_VAddr((Address & ~0x03), Value);
if (!g_MMU->SW_VAddr((Address & ~0x03), Value))
{
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
} }
void R4300iOp::SW() void R4300iOp::SW()
@ -1328,11 +1260,7 @@ void R4300iOp::SW()
} }
if (!g_MMU->SW_VAddr(Address, _GPR[m_Opcode.rt].UW[0])) if (!g_MMU->SW_VAddr(Address, _GPR[m_Opcode.rt].UW[0]))
{ {
if (bShowTLBMisses()) GenerateTLBWriteException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
} }
} }
@ -1358,26 +1286,14 @@ void R4300iOp::SDL()
} }
Offset = Address & 7; Offset = Address & 7;
if (!g_MMU->LD_VAddr((Address & ~7), Value)) if (!g_MMU->LD_Memory((Address & ~7), Value))
{ {
if (bShowTLBMisses()) GenerateTLBWriteException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
} }
Value &= SDL_MASK[Offset]; Value &= SDL_MASK[Offset];
Value += _GPR[m_Opcode.rt].UDW >> SDL_SHIFT[Offset]; Value += _GPR[m_Opcode.rt].UDW >> SDL_SHIFT[Offset];
g_MMU->SD_VAddr((Address & ~7), Value);
if (!g_MMU->SD_VAddr((Address & ~7), Value))
{
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
} }
uint64_t SDR_MASK[8] = { 0x00FFFFFFFFFFFFFF, uint64_t SDR_MASK[8] = { 0x00FFFFFFFFFFFFFF,
@ -1403,26 +1319,15 @@ void R4300iOp::SDR()
} }
Offset = Address & 7; Offset = Address & 7;
if (!g_MMU->LD_VAddr((Address & ~7), Value)) if (!g_MMU->LD_Memory((Address & ~7), Value))
{ {
if (bShowTLBMisses()) GenerateTLBWriteException(Address, __FUNCTION__);
{ return;
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
} }
Value &= SDR_MASK[Offset]; Value &= SDR_MASK[Offset];
Value += _GPR[m_Opcode.rt].UDW << SDR_SHIFT[Offset]; Value += _GPR[m_Opcode.rt].UDW << SDR_SHIFT[Offset];
g_MMU->SD_VAddr((Address & ~7), Value);
if (!g_MMU->SD_VAddr((Address & ~7), Value))
{
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
} }
void R4300iOp::SWR() void R4300iOp::SWR()
@ -1436,26 +1341,17 @@ void R4300iOp::SWR()
} }
Offset = Address & 3; Offset = Address & 3;
if (!g_MMU->LW_VAddr((Address & ~3), Value)) if (g_MMU->LW_Memory((Address & ~3), Value))
{ {
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
Value &= SWR_MASK[Offset]; Value &= SWR_MASK[Offset];
Value += _GPR[m_Opcode.rt].UW[0] << SWR_SHIFT[Offset]; Value += _GPR[m_Opcode.rt].UW[0] << SWR_SHIFT[Offset];
g_MMU->SW_VAddr((Address & ~0x03), Value);
}
else
{
GenerateTLBWriteException(Address, __FUNCTION__);
}
if (!g_MMU->SW_VAddr((Address & ~0x03), Value))
{
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
} }
void R4300iOp::CACHE() void R4300iOp::CACHE()
@ -1480,13 +1376,9 @@ void R4300iOp::LL()
return; return;
} }
if (!g_MMU->LW_VAddr(Address, _GPR[m_Opcode.rt].UW[0])) if (!g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {
@ -1507,13 +1399,9 @@ void R4300iOp::LWC1()
{ {
return; return;
} }
if (!g_MMU->LW_VAddr(Address, *(uint32_t *)_FPR_S[m_Opcode.ft])) if (!g_MMU->LW_Memory(Address, *(uint32_t *)_FPR_S[m_Opcode.ft]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
} }
@ -1532,11 +1420,8 @@ void R4300iOp::SC()
{ {
if (!g_MMU->SW_VAddr(Address, _GPR[m_Opcode.rt].UW[0])) if (!g_MMU->SW_VAddr(Address, _GPR[m_Opcode.rt].UW[0]))
{ {
if (bShowTLBMisses()) GenerateTLBWriteException(Address, __FUNCTION__);
{ return;
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
} }
} }
_GPR[m_Opcode.rt].UW[0] = (*_LLBit); _GPR[m_Opcode.rt].UW[0] = (*_LLBit);
@ -1553,13 +1438,10 @@ void R4300iOp::LD()
{ {
return; return;
} }
if (!g_MMU->LD_VAddr(Address, _GPR[m_Opcode.rt].UDW)) if (!g_MMU->LD_Memory(Address, _GPR[m_Opcode.rt].UDW))
{ {
if (bShowTLBMisses()) GenerateTLBWriteException(Address, __FUNCTION__);
{ return;
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
} }
#ifdef Interpreter_StackTest #ifdef Interpreter_StackTest
if (m_Opcode.rt == 29) if (m_Opcode.rt == 29)
@ -1582,13 +1464,9 @@ void R4300iOp::LDC1()
{ {
return; return;
} }
if (!g_MMU->LD_VAddr(Address, *(uint64_t *)_FPR_D[m_Opcode.ft])) if (!g_MMU->LD_Memory(Address, *(uint64_t *)_FPR_D[m_Opcode.ft]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
} }
@ -1607,11 +1485,7 @@ void R4300iOp::SWC1()
if (!g_MMU->SW_VAddr(Address, *(uint32_t *)_FPR_S[m_Opcode.ft])) if (!g_MMU->SW_VAddr(Address, *(uint32_t *)_FPR_S[m_Opcode.ft]))
{ {
if (bShowTLBMisses()) GenerateTLBWriteException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
} }
} }
@ -1631,11 +1505,7 @@ void R4300iOp::SDC1()
} }
if (!g_MMU->SD_VAddr(Address, *(int64_t *)_FPR_D[m_Opcode.ft])) if (!g_MMU->SD_VAddr(Address, *(int64_t *)_FPR_D[m_Opcode.ft]))
{ {
if (bShowTLBMisses()) GenerateTLBWriteException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
} }
} }
@ -1652,11 +1522,7 @@ void R4300iOp::SD()
} }
if (!g_MMU->SD_VAddr(Address, _GPR[m_Opcode.rt].UDW)) if (!g_MMU->SD_VAddr(Address, _GPR[m_Opcode.rt].UDW))
{ {
if (bShowTLBMisses()) GenerateTLBWriteException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
} }
} }
@ -3023,3 +2889,25 @@ bool R4300iOp::MemoryBreakpoint()
} }
return false; return false;
} }
void R4300iOp::GenerateTLBReadException(uint32_t VAddr, const char * function)
{
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", function, VAddr).c_str());
}
g_Reg->DoTLBReadMiss(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP, VAddr);
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
}
void R4300iOp::GenerateTLBWriteException(uint32_t VAddr, const char * function)
{
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", function, VAddr).c_str());
}
g_Reg->DoTLBWriteMiss(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP, VAddr);
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
}

View File

@ -238,6 +238,9 @@ protected:
static Func Jump_CoP1_W[64]; static Func Jump_CoP1_W[64];
static Func Jump_CoP1_L[64]; static Func Jump_CoP1_L[64];
static void GenerateTLBReadException(uint32_t VAddr, const char * function);
static void GenerateTLBWriteException(uint32_t VAddr, const char * function);
static const uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4]; static const uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4];
static const int32_t SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4]; static const int32_t SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4];
}; };

View File

@ -24,12 +24,6 @@ bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
return;\ return;\
} }
#define TLB_READ_EXCEPTION(Address) \
g_Reg->DoTLBReadMiss(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,Address);\
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;\
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\
return;
R4300iOp32::Func * R4300iOp32::BuildInterpreter() R4300iOp32::Func * R4300iOp32::BuildInterpreter()
{ {
Jump_Opcode[0] = SPECIAL; Jump_Opcode[0] = SPECIAL;
@ -888,13 +882,9 @@ void R4300iOp32::LB()
{ {
return; return;
} }
if (!g_MMU->LB_VAddr(Address, _GPR[m_Opcode.rt].UB[0])) if (!g_MMU->LB_Memory(Address, _GPR[m_Opcode.rt].UB[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {
@ -913,13 +903,9 @@ void R4300iOp32::LH()
{ {
return; return;
} }
if (!g_MMU->LH_VAddr(Address, _GPR[m_Opcode.rt].UHW[0])) if (!g_MMU->LH_Memory(Address, _GPR[m_Opcode.rt].UHW[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {
@ -929,27 +915,22 @@ void R4300iOp32::LH()
void R4300iOp32::LWL() void R4300iOp32::LWL()
{ {
uint32_t Offset, Address, Value; uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
Offset = Address & 3;
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint()) if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
{ {
return; return;
} }
if (!g_MMU->LW_VAddr((Address & ~3), Value)) uint32_t Value;
if (!g_MMU->LW_Memory((Address & ~3), Value))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
}
else
{ {
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str()); uint32_t Offset = Address & 3;
}
TLB_READ_EXCEPTION(Address);
return;
}
_GPR[m_Opcode.rt].W[0] = (int32_t)(_GPR[m_Opcode.rt].W[0] & LWL_MASK[Offset]); _GPR[m_Opcode.rt].W[0] = (int32_t)(_GPR[m_Opcode.rt].W[0] & LWL_MASK[Offset]);
_GPR[m_Opcode.rt].W[0] += (int32_t)(Value << LWL_SHIFT[Offset]); _GPR[m_Opcode.rt].W[0] += (int32_t)(Value << LWL_SHIFT[Offset]);
}
} }
void R4300iOp32::LW() void R4300iOp32::LW()
@ -963,14 +944,9 @@ void R4300iOp32::LW()
{ {
return; return;
} }
if (!g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
if (!g_MMU->LW_VAddr(Address, _GPR[m_Opcode.rt].UW[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {
@ -985,13 +961,9 @@ void R4300iOp32::LBU()
{ {
return; return;
} }
if (!g_MMU->LB_VAddr(Address, _GPR[m_Opcode.rt].UB[0])) if (!g_MMU->LB_Memory(Address, _GPR[m_Opcode.rt].UB[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {
@ -1010,13 +982,9 @@ void R4300iOp32::LHU()
{ {
return; return;
} }
if (!g_MMU->LH_VAddr(Address, _GPR[m_Opcode.rt].UHW[0])) if (!g_MMU->LH_Memory(Address, _GPR[m_Opcode.rt].UHW[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {
@ -1034,7 +1002,7 @@ void R4300iOp32::LWR()
{ {
return; return;
} }
if (!g_MMU->LW_VAddr((Address & ~3), Value)) if (!g_MMU->LW_Memory((Address & ~3), Value))
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
if (bShowTLBMisses()) if (bShowTLBMisses())
@ -1060,13 +1028,9 @@ void R4300iOp32::LWU()
{ {
return; return;
} }
if (!g_MMU->LW_VAddr(Address, _GPR[m_Opcode.rt].UW[0])) if (!g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {
@ -1085,13 +1049,9 @@ void R4300iOp32::LL()
{ {
return; return;
} }
if (!g_MMU->LW_VAddr(Address, _GPR[m_Opcode.rt].UW[0])) if (!g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
{ {
if (bShowTLBMisses()) GenerateTLBReadException(Address, __FUNCTION__);
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
} }
else else
{ {

View File

@ -428,7 +428,7 @@ bool CMipsMemoryVM::UpdateMemoryValue32(uint32_t VAddr, uint32_t Value)
return false; return false;
} }
bool CMipsMemoryVM::LB_VAddr(uint32_t VAddr, uint8_t& Value) bool CMipsMemoryVM::LB_Memory(uint32_t VAddr, uint8_t& Value)
{ {
uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12]; uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12];
if (MemoryPtr != (uint8_t*)-1) if (MemoryPtr != (uint8_t*)-1)
@ -436,16 +436,15 @@ bool CMipsMemoryVM::LB_VAddr(uint32_t VAddr, uint8_t& Value)
Value = *(uint8_t*)(MemoryPtr + (VAddr ^ 3)); Value = *(uint8_t*)(MemoryPtr + (VAddr ^ 3));
return true; return true;
} }
if (m_TLB_ReadMap[VAddr >> 12] == -1) uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{ {
return false; return false;
} }
return LB_NonMemory(VAddr, Value);
Value = *(uint8_t*)((m_TLB_ReadMap[VAddr >> 12] + (VAddr ^ 3)) + m_RDRAM);
return true;
} }
bool CMipsMemoryVM::LH_VAddr(uint32_t VAddr, uint16_t& Value) bool CMipsMemoryVM::LH_Memory(uint32_t VAddr, uint16_t & Value)
{ {
uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12]; uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12];
if (MemoryPtr != (uint8_t*)-1) if (MemoryPtr != (uint8_t*)-1)
@ -453,16 +452,15 @@ bool CMipsMemoryVM::LH_VAddr(uint32_t VAddr, uint16_t& Value)
Value = *(uint16_t*)(MemoryPtr + (VAddr ^ 2)); Value = *(uint16_t*)(MemoryPtr + (VAddr ^ 2));
return true; return true;
} }
if (m_TLB_ReadMap[VAddr >> 12] == -1) uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{ {
return false; return false;
} }
return LH_NonMemory(VAddr, Value);
Value = *(uint16_t*)((m_TLB_ReadMap[VAddr >> 12] + (VAddr ^ 2)) + m_RDRAM);
return true;
} }
bool CMipsMemoryVM::LW_VAddr(uint32_t VAddr, uint32_t & Value) bool CMipsMemoryVM::LW_Memory(uint32_t VAddr, uint32_t & Value)
{ {
uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12]; uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12];
if (MemoryPtr != (uint8_t *)-1) if (MemoryPtr != (uint8_t *)-1)
@ -470,27 +468,15 @@ bool CMipsMemoryVM::LW_VAddr(uint32_t VAddr, uint32_t & Value)
Value = *(uint32_t*)(MemoryPtr + VAddr); Value = *(uint32_t*)(MemoryPtr + VAddr);
return true; return true;
} }
if (VAddr >= 0xA3F00000 && VAddr < 0xC0000000)
{
if ((VAddr & 0xFFFFE000ul) != 0xA4000000ul) // !(A4000000 <= addr < A4002000)
{
VAddr &= 0x1FFFFFFF;
LW_NonMemory(VAddr, &Value);
return true;
}
}
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12]; uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1) if (BaseAddress == -1)
{ {
return false; return false;
} }
return LW_NonMemory(VAddr, Value);
Value = *(uint32_t*)(BaseAddress + VAddr + m_RDRAM);
return true;
} }
bool CMipsMemoryVM::LD_VAddr(uint32_t VAddr, uint64_t& Value) bool CMipsMemoryVM::LD_Memory(uint32_t VAddr, uint64_t& Value)
{ {
uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12]; uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12];
if (MemoryPtr != (uint8_t *)-1) if (MemoryPtr != (uint8_t *)-1)
@ -499,14 +485,12 @@ bool CMipsMemoryVM::LD_VAddr(uint32_t VAddr, uint64_t& Value)
*((uint32_t*)(&Value) + 0) = *(uint32_t*)(MemoryPtr + VAddr + 4); *((uint32_t*)(&Value) + 0) = *(uint32_t*)(MemoryPtr + VAddr + 4);
return true; return true;
} }
if (m_TLB_ReadMap[VAddr >> 12] == -1) uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{ {
return false; return false;
} }
return LD_NonMemory(VAddr, Value);
*((uint32_t*)(&Value) + 1) = *(uint32_t*)(m_TLB_ReadMap[VAddr >> 12] + VAddr + m_RDRAM);
*((uint32_t*)(&Value) + 0) = *(uint32_t*)(m_TLB_ReadMap[VAddr >> 12] + VAddr + 4 + m_RDRAM);
return true;
} }
bool CMipsMemoryVM::SB_VAddr(uint32_t VAddr, uint8_t Value) bool CMipsMemoryVM::SB_VAddr(uint32_t VAddr, uint8_t Value)
@ -521,9 +505,7 @@ bool CMipsMemoryVM::SB_VAddr(uint32_t VAddr, uint8_t Value)
{ {
return false; return false;
} }
return SB_NonMemory(VAddr, Value);
*(uint8_t*)(m_TLB_WriteMap[VAddr >> 12] + (VAddr ^ 3) + m_RDRAM) = Value;
return true;
} }
bool CMipsMemoryVM::SH_VAddr(uint32_t VAddr, uint16_t Value) bool CMipsMemoryVM::SH_VAddr(uint32_t VAddr, uint16_t Value)
@ -534,13 +516,12 @@ bool CMipsMemoryVM::SH_VAddr(uint32_t VAddr, uint16_t Value)
*(uint16_t*)(MemoryPtr + (VAddr ^ 2)) = Value; *(uint16_t*)(MemoryPtr + (VAddr ^ 2)) = Value;
return true; return true;
} }
if (m_TLB_WriteMap[VAddr >> 12] == -1) uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{ {
return false; return false;
} }
return SH_NonMemory(VAddr, Value);
*(uint16_t*)(m_TLB_WriteMap[VAddr >> 12] + (VAddr ^ 2) + m_RDRAM) = Value;
return true;
} }
bool CMipsMemoryVM::SW_VAddr(uint32_t VAddr, uint32_t Value) bool CMipsMemoryVM::SW_VAddr(uint32_t VAddr, uint32_t Value)
@ -551,23 +532,12 @@ bool CMipsMemoryVM::SW_VAddr(uint32_t VAddr, uint32_t Value)
*(uint32_t*)(MemoryPtr + VAddr) = Value; *(uint32_t*)(MemoryPtr + VAddr) = Value;
return true; return true;
} }
if (VAddr >= 0xA3F00000 && VAddr < 0xC0000000) uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
{ if (BaseAddress == -1)
if ((VAddr & 0xFFFFE000ul) != 0xA4000000ul) // !(A4000000 <= addr < A4002000)
{
VAddr &= 0x1FFFFFFF;
SW_NonMemory(VAddr, Value);
return true;
}
}
if (m_TLB_WriteMap[VAddr >> 12] == -1)
{ {
return false; return false;
} }
return SW_NonMemory(VAddr, Value);
*(uint32_t*)(m_TLB_WriteMap[VAddr >> 12] + VAddr + m_RDRAM) = Value;
return true;
} }
bool CMipsMemoryVM::SD_VAddr(uint32_t VAddr, uint64_t Value) bool CMipsMemoryVM::SD_VAddr(uint32_t VAddr, uint64_t Value)
@ -583,10 +553,7 @@ bool CMipsMemoryVM::SD_VAddr(uint32_t VAddr, uint64_t Value)
{ {
return false; return false;
} }
return SD_NonMemory(VAddr, Value);
*(uint32_t*)(m_TLB_WriteMap[VAddr >> 12] + VAddr + m_RDRAM + 0) = *((uint32_t*)(&Value) + 1);
*(uint32_t*)(m_TLB_WriteMap[VAddr >> 12] + VAddr + m_RDRAM + 4) = *((uint32_t*)(&Value));
return true;
} }
bool CMipsMemoryVM::ValidVaddr(uint32_t VAddr) const bool CMipsMemoryVM::ValidVaddr(uint32_t VAddr) const
@ -604,11 +571,18 @@ bool CMipsMemoryVM::VAddrToPAddr(uint32_t VAddr, uint32_t &PAddr) const
return true; return true;
} }
bool CMipsMemoryVM::LB_NonMemory(uint32_t PAddr, uint32_t* Value, bool /*SignExtend*/) bool CMipsMemoryVM::LB_NonMemory(uint32_t VAddr, uint8_t & Value)
{ {
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBReadException(VAddr, __FUNCTION__);
return false;
}
uint32_t PAddr = BaseAddress + VAddr;
if (PAddr < 0x800000) if (PAddr < 0x800000)
{ {
*Value = 0; Value = 0;
return true; return true;
} }
@ -619,65 +593,103 @@ bool CMipsMemoryVM::LB_NonMemory(uint32_t PAddr, uint32_t* Value, bool /*SignExt
{ {
return false; return false;
} }
*Value = ((Value32 >> (((PAddr & 3) ^ 3) << 3)) & 0xff); Value = ((Value32 >> (((PAddr & 3) ^ 3) << 3)) & 0xff);
} }
else else
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
*Value = 0; Value = 0;
} }
return true; return true;
} }
bool CMipsMemoryVM::LH_NonMemory(uint32_t PAddr, uint32_t* Value, bool/* SignExtend*/) bool CMipsMemoryVM::LH_NonMemory(uint32_t VAddr, uint16_t & Value)
{ {
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBReadException(VAddr, __FUNCTION__);
return false;
}
uint32_t PAddr = BaseAddress + VAddr;
if (PAddr < 0x800000) if (PAddr < 0x800000)
{ {
*Value = 0; Value = 0;
return true; return true;
} }
if (PAddr >= 0x10000000 && PAddr < 0x16000000)
{
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} Value = 0;
*Value = 0;
return false; return false;
} }
bool CMipsMemoryVM::LW_NonMemory(uint32_t PAddr, uint32_t* Value) bool CMipsMemoryVM::LW_NonMemory(uint32_t VAddr, uint32_t & Value)
{ {
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBReadException(VAddr, __FUNCTION__);
return false;
}
uint32_t PAddr = BaseAddress + VAddr;
switch (PAddr & 0xFFF00000) switch (PAddr & 0xFFF00000)
{ {
case 0x03F00000: m_RDRAMRegistersHandler.Read32(PAddr, *Value); break; case 0x03F00000: m_RDRAMRegistersHandler.Read32(PAddr, Value); break;
case 0x04000000: m_SPRegistersHandler.Read32(PAddr, *Value); break; case 0x04000000: m_SPRegistersHandler.Read32(PAddr, Value); break;
case 0x04100000: m_DPCommandRegistersHandler.Read32(PAddr, *Value); break; case 0x04100000: m_DPCommandRegistersHandler.Read32(PAddr, Value); break;
case 0x04300000: m_MIPSInterfaceHandler.Read32(PAddr, *Value); break; case 0x04300000: m_MIPSInterfaceHandler.Read32(PAddr, Value); break;
case 0x04400000: m_VideoInterfaceHandler.Read32(PAddr, *Value); break; case 0x04400000: m_VideoInterfaceHandler.Read32(PAddr, Value); break;
case 0x04500000: m_AudioInterfaceHandler.Read32(PAddr, *Value); break; case 0x04500000: m_AudioInterfaceHandler.Read32(PAddr, Value); break;
case 0x04600000: m_PeripheralInterfaceHandler.Read32(PAddr, *Value); break; case 0x04600000: m_PeripheralInterfaceHandler.Read32(PAddr, Value); break;
case 0x04700000: m_RDRAMInterfaceHandler.Read32(PAddr, *Value); break; case 0x04700000: m_RDRAMInterfaceHandler.Read32(PAddr, Value); break;
case 0x04800000: m_SerialInterfaceHandler.Read32(PAddr, *Value); break; case 0x04800000: m_SerialInterfaceHandler.Read32(PAddr, Value); break;
case 0x05000000: m_CartridgeDomain2Address1Handler.Read32(PAddr, *Value); break; case 0x05000000: m_CartridgeDomain2Address1Handler.Read32(PAddr, Value); break;
case 0x06000000: m_CartridgeDomain1Address1Handler.Read32(PAddr, *Value); break; case 0x06000000: m_CartridgeDomain1Address1Handler.Read32(PAddr, Value); break;
case 0x08000000: m_CartridgeDomain2Address2Handler.Read32(PAddr, *Value); break; case 0x08000000: m_CartridgeDomain2Address2Handler.Read32(PAddr, Value); break;
case 0x1FC00000: m_PifRamHandler.Read32(PAddr, *Value); break; case 0x1FC00000: m_PifRamHandler.Read32(PAddr, Value); break;
case 0x1FF00000: m_CartridgeDomain1Address3Handler.Read32(PAddr, *Value); break; case 0x1FF00000: m_CartridgeDomain1Address3Handler.Read32(PAddr, Value); break;
default: default:
if (PAddr >= 0x10000000 && PAddr < 0x16000000) if (PAddr >= 0x10000000 && PAddr < 0x16000000)
{ {
m_RomMemoryHandler.Read32(PAddr, *Value); m_RomMemoryHandler.Read32(PAddr, Value);
} }
else else
{ {
*Value = ((PAddr & 0xFFFF) << 16) | (PAddr & 0xFFFF); Value = ((PAddr & 0xFFFF) << 16) | (PAddr & 0xFFFF);
} }
} }
return true; return true;
} }
bool CMipsMemoryVM::SB_NonMemory(uint32_t PAddr, uint8_t Value) bool CMipsMemoryVM::LD_NonMemory(uint32_t VAddr, uint64_t & Value)
{ {
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBReadException(VAddr, __FUNCTION__);
return false;
}
uint32_t PAddr = BaseAddress + VAddr;
if (PAddr < 0x800000)
{
Value = 0;
return true;
}
g_Notify->BreakPoint(__FILE__, __LINE__);
Value = 0;
return false;
}
bool CMipsMemoryVM::SB_NonMemory(uint32_t VAddr, uint8_t Value)
{
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBWriteException(VAddr, __FUNCTION__);
return false;
}
uint32_t PAddr = BaseAddress + VAddr;
switch (PAddr & 0xFFF00000) switch (PAddr & 0xFFF00000)
{ {
case 0x00000000: case 0x00000000:
@ -692,18 +704,26 @@ bool CMipsMemoryVM::SB_NonMemory(uint32_t PAddr, uint8_t Value)
{ {
g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0xFFC, CRecompiler::Remove_ProtectedMem); g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0xFFC, CRecompiler::Remove_ProtectedMem);
::ProtectMemory(m_RDRAM + (PAddr & ~0xFFF), 0xFFC, MEM_READWRITE); ::ProtectMemory(m_RDRAM + (PAddr & ~0xFFF), 0xFFC, MEM_READWRITE);
*(uint8_t *)(m_RDRAM + PAddr) = Value; *(uint8_t *)(m_RDRAM + (PAddr ^ 3)) = Value;
} }
break; break;
default: default:
g_Notify->BreakPoint(__FILE__, __LINE__);
return false; return false;
} }
return true; return true;
} }
bool CMipsMemoryVM::SH_NonMemory(uint32_t PAddr, uint16_t Value) bool CMipsMemoryVM::SH_NonMemory(uint32_t VAddr, uint16_t Value)
{ {
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBWriteException(VAddr, __FUNCTION__);
return false;
}
uint32_t PAddr = BaseAddress + VAddr;
switch (PAddr & 0xFFF00000) switch (PAddr & 0xFFF00000)
{ {
case 0x00000000: case 0x00000000:
@ -718,18 +738,26 @@ bool CMipsMemoryVM::SH_NonMemory(uint32_t PAddr, uint16_t Value)
{ {
g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0x1000, CRecompiler::Remove_ProtectedMem); g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0x1000, CRecompiler::Remove_ProtectedMem);
::ProtectMemory(m_RDRAM + (PAddr & ~0xFFF), 0xFFC, MEM_READWRITE); ::ProtectMemory(m_RDRAM + (PAddr & ~0xFFF), 0xFFC, MEM_READWRITE);
*(uint16_t *)(m_RDRAM + PAddr) = Value; *(uint16_t *)(m_RDRAM + (PAddr ^ 2)) = Value;
} }
break; break;
default: default:
g_Notify->BreakPoint(__FILE__, __LINE__);
return false; return false;
} }
return true; return true;
} }
bool CMipsMemoryVM::SW_NonMemory(uint32_t PAddr, uint32_t Value) bool CMipsMemoryVM::SW_NonMemory(uint32_t VAddr, uint32_t Value)
{ {
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBWriteException(VAddr, __FUNCTION__);
return false;
}
uint32_t PAddr = BaseAddress + VAddr;
switch (PAddr & 0xFFF00000) switch (PAddr & 0xFFF00000)
{ {
case 0x00000000: case 0x00000000:
@ -775,15 +803,25 @@ bool CMipsMemoryVM::SW_NonMemory(uint32_t PAddr, uint32_t Value)
if (PAddr >= 0x10000000 && PAddr < 0x16000000) if (PAddr >= 0x10000000 && PAddr < 0x16000000)
{ {
m_RomMemoryHandler.Write32(PAddr, Value, 0xFFFFFFFF); m_RomMemoryHandler.Write32(PAddr, Value, 0xFFFFFFFF);
return true;
} }
return false;
break; break;
} }
return true; return true;
} }
bool CMipsMemoryVM::SD_NonMemory(uint32_t VAddr, uint64_t Value)
{
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBWriteException(VAddr, __FUNCTION__);
return false;
}
g_Notify->BreakPoint(__FILE__, __LINE__);
return true;
}
void CMipsMemoryVM::ProtectMemory(uint32_t StartVaddr, uint32_t EndVaddr) void CMipsMemoryVM::ProtectMemory(uint32_t StartVaddr, uint32_t EndVaddr)
{ {
WriteTrace(TraceProtectedMem, TraceDebug, "StartVaddr: %08X EndVaddr: %08X", StartVaddr, EndVaddr); WriteTrace(TraceProtectedMem, TraceDebug, "StartVaddr: %08X EndVaddr: %08X", StartVaddr, EndVaddr);

View File

@ -81,10 +81,10 @@ public:
bool UpdateMemoryValue16(uint32_t VAddr, uint16_t Value); bool UpdateMemoryValue16(uint32_t VAddr, uint16_t Value);
bool UpdateMemoryValue32(uint32_t VAddr, uint32_t Value); bool UpdateMemoryValue32(uint32_t VAddr, uint32_t Value);
bool LB_VAddr(uint32_t VAddr, uint8_t & Value); bool LB_Memory(uint32_t VAddr, uint8_t & Value);
bool LH_VAddr(uint32_t VAddr, uint16_t & Value); bool LH_Memory(uint32_t VAddr, uint16_t & Value);
bool LW_VAddr(uint32_t VAddr, uint32_t & Value); bool LW_Memory(uint32_t VAddr, uint32_t & Value);
bool LD_VAddr(uint32_t VAddr, uint64_t & Value); bool LD_Memory(uint32_t VAddr, uint64_t & Value);
bool SB_VAddr(uint32_t VAddr, uint8_t Value); bool SB_VAddr(uint32_t VAddr, uint8_t Value);
bool SH_VAddr(uint32_t VAddr, uint16_t Value); bool SH_VAddr(uint32_t VAddr, uint16_t Value);
@ -131,13 +131,15 @@ private:
static void ChangeSpStatus(); static void ChangeSpStatus();
static void ChangeMiIntrMask(); static void ChangeMiIntrMask();
bool LB_NonMemory(uint32_t PAddr, uint32_t * Value, bool SignExtend); bool LB_NonMemory(uint32_t VAddr, uint8_t & Value);
bool LH_NonMemory(uint32_t PAddr, uint32_t * Value, bool SignExtend); bool LH_NonMemory(uint32_t VAddr, uint16_t & Value);
bool LW_NonMemory(uint32_t PAddr, uint32_t * Value); bool LW_NonMemory(uint32_t VAddr, uint32_t & Value);
bool LD_NonMemory(uint32_t VAddr, uint64_t & Value);
bool SB_NonMemory(uint32_t PAddr, uint8_t Value); bool SB_NonMemory(uint32_t VAddr, uint8_t Value);
bool SH_NonMemory(uint32_t PAddr, uint16_t Value); bool SH_NonMemory(uint32_t VAddr, uint16_t Value);
bool SW_NonMemory(uint32_t PAddr, uint32_t Value); bool SW_NonMemory(uint32_t VAddr, uint32_t Value);
bool SD_NonMemory(uint32_t VAddr, uint64_t Value);
#if defined(__i386__) || defined(_M_IX86) #if defined(__i386__) || defined(_M_IX86)

View File

@ -6087,7 +6087,7 @@ void CArmRecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr)
m_RegWorkingSet.BeforeCallDirect(); m_RegWorkingSet.BeforeCallDirect();
MoveConstToArmReg(Arm_R2, Value); MoveConstToArmReg(Arm_R2, Value);
MoveConstToArmReg(Arm_R1, PAddr); MoveConstToArmReg(Arm_R1, PAddr | 0xA0000000);
MoveConstToArmReg(Arm_R0, (uint32_t)(g_MMU), "g_MMU"); MoveConstToArmReg(Arm_R0, (uint32_t)(g_MMU), "g_MMU");
CallFunction(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); CallFunction(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory");
m_RegWorkingSet.AfterCallDirect(); m_RegWorkingSet.AfterCallDirect();
@ -6109,7 +6109,7 @@ void CArmRecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr)
case 0x0410000C: case 0x0410000C:
m_RegWorkingSet.BeforeCallDirect(); m_RegWorkingSet.BeforeCallDirect();
MoveConstToArmReg(Arm_R2, Value); MoveConstToArmReg(Arm_R2, Value);
MoveConstToArmReg(Arm_R1, PAddr); MoveConstToArmReg(Arm_R1, PAddr | 0xA0000000);
MoveConstToArmReg(Arm_R0, (uint32_t)(g_MMU), "g_MMU"); MoveConstToArmReg(Arm_R0, (uint32_t)(g_MMU), "g_MMU");
CallFunction(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); CallFunction(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory");
m_RegWorkingSet.AfterCallDirect(); m_RegWorkingSet.AfterCallDirect();
@ -6345,7 +6345,7 @@ void CArmRecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr)
case 0x04500010: case 0x04500010:
m_RegWorkingSet.BeforeCallDirect(); m_RegWorkingSet.BeforeCallDirect();
MoveConstToArmReg(Arm_R2, Value); MoveConstToArmReg(Arm_R2, Value);
MoveConstToArmReg(Arm_R1, PAddr); MoveConstToArmReg(Arm_R1, PAddr | 0xA0000000);
MoveConstToArmReg(Arm_R0, (uint32_t)(g_MMU), "g_MMU"); MoveConstToArmReg(Arm_R0, (uint32_t)(g_MMU), "g_MMU");
CallFunction(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); CallFunction(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory");
m_RegWorkingSet.AfterCallDirect(); m_RegWorkingSet.AfterCallDirect();
@ -6494,7 +6494,7 @@ void CArmRecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr)
m_RegWorkingSet.BeforeCallDirect(); m_RegWorkingSet.BeforeCallDirect();
MoveConstToArmReg(Arm_R2, Value); MoveConstToArmReg(Arm_R2, Value);
MoveConstToArmReg(Arm_R1, PAddr); MoveConstToArmReg(Arm_R1, PAddr | 0xA0000000);
MoveConstToArmReg(Arm_R0, (uint32_t)(g_MMU), "g_MMU"); MoveConstToArmReg(Arm_R0, (uint32_t)(g_MMU), "g_MMU");
CallFunction(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); CallFunction(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory");
m_RegWorkingSet.AfterCallDirect(); m_RegWorkingSet.AfterCallDirect();
@ -6632,7 +6632,7 @@ void CArmRecompilerOps::SW_Register(ArmReg Reg, uint32_t VAddr)
{ {
AddConstToArmReg(Arm_R2, Reg, 0); AddConstToArmReg(Arm_R2, Reg, 0);
} }
MoveConstToArmReg(Arm_R1, PAddr); MoveConstToArmReg(Arm_R1, PAddr | 0xA0000000);
MoveConstToArmReg(Arm_R0, (uint32_t)(g_MMU), "g_MMU"); MoveConstToArmReg(Arm_R0, (uint32_t)(g_MMU), "g_MMU");
CallFunction(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); CallFunction(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory");
m_RegWorkingSet.AfterCallDirect(); m_RegWorkingSet.AfterCallDirect();
@ -6771,7 +6771,7 @@ void CArmRecompilerOps::SW_Register(ArmReg Reg, uint32_t VAddr)
{ {
AddConstToArmReg(Arm_R2, Reg, 0); AddConstToArmReg(Arm_R2, Reg, 0);
} }
MoveConstToArmReg(Arm_R1, PAddr); MoveConstToArmReg(Arm_R1, PAddr | 0xA0000000);
MoveConstToArmReg(Arm_R0, (uint32_t)(g_MMU), "g_MMU"); MoveConstToArmReg(Arm_R0, (uint32_t)(g_MMU), "g_MMU");
CallFunction(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); CallFunction(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory");
m_RegWorkingSet.AfterCallDirect(); m_RegWorkingSet.AfterCallDirect();

View File

@ -3270,10 +3270,9 @@ void CX86RecompilerOps::LW_KnownAddress(x86Reg Reg, uint32_t VAddr)
break; break;
case 0x04100000: case 0x04100000:
{ {
static uint32_t TempValue = 0;
m_RegWorkingSet.BeforeCallDirect(); m_RegWorkingSet.BeforeCallDirect();
PushImm32("TempValue", (uint32_t)&TempValue); PushImm32("TempValue", (uint32_t)&m_TempValue);
PushImm32(PAddr); PushImm32(PAddr | 0xA0000000);
#ifdef _MSC_VER #ifdef _MSC_VER
MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX); MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX);
Call_Direct(AddressOf(&CMipsMemoryVM::LW_NonMemory), "CMipsMemoryVM::LW_NonMemory"); Call_Direct(AddressOf(&CMipsMemoryVM::LW_NonMemory), "CMipsMemoryVM::LW_NonMemory");
@ -3283,7 +3282,7 @@ void CX86RecompilerOps::LW_KnownAddress(x86Reg Reg, uint32_t VAddr)
AddConstToX86Reg(x86_ESP, 12); AddConstToX86Reg(x86_ESP, 12);
#endif #endif
m_RegWorkingSet.AfterCallDirect(); m_RegWorkingSet.AfterCallDirect();
MoveVariableToX86reg(&TempValue, "TempValue", Reg); MoveVariableToX86reg(&m_TempValue, "TempValue", Reg);
} }
break; break;
case 0x04300000: case 0x04300000:
@ -10744,7 +10743,7 @@ void CX86RecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr)
m_RegWorkingSet.BeforeCallDirect(); m_RegWorkingSet.BeforeCallDirect();
PushImm32(Value); PushImm32(Value);
PushImm32(PAddr); PushImm32(PAddr | 0xA0000000);
#ifdef _MSC_VER #ifdef _MSC_VER
MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX); MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX);
Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory");
@ -10771,7 +10770,7 @@ void CX86RecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr)
case 0x0410000C: case 0x0410000C:
m_RegWorkingSet.BeforeCallDirect(); m_RegWorkingSet.BeforeCallDirect();
PushImm32(Value); PushImm32(Value);
PushImm32(PAddr); PushImm32(PAddr | 0xA0000000);
#ifdef _MSC_VER #ifdef _MSC_VER
MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX); MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX);
Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory");
@ -11176,7 +11175,7 @@ void CX86RecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr)
m_RegWorkingSet.BeforeCallDirect(); m_RegWorkingSet.BeforeCallDirect();
PushImm32(Value); PushImm32(Value);
PushImm32(PAddr); PushImm32(PAddr | 0xA0000000);
#ifdef _MSC_VER #ifdef _MSC_VER
MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX); MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX);
Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory");
@ -11199,7 +11198,7 @@ void CX86RecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr)
m_RegWorkingSet.BeforeCallDirect(); m_RegWorkingSet.BeforeCallDirect();
PushImm32(Value); PushImm32(Value);
PushImm32(PAddr); PushImm32(PAddr | 0xA0000000);
#ifdef _MSC_VER #ifdef _MSC_VER
MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX); MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX);
Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory");
@ -11325,7 +11324,7 @@ void CX86RecompilerOps::SW_Register(x86Reg Reg, uint32_t VAddr)
} }
m_RegWorkingSet.BeforeCallDirect(); m_RegWorkingSet.BeforeCallDirect();
Push(Reg); Push(Reg);
PushImm32(PAddr); PushImm32(PAddr | 0xA0000000);
#ifdef _MSC_VER #ifdef _MSC_VER
MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX); MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX);
Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory");