Began implementing X86 interpreter fallback for instructions Direct Code execution fails on
Began setting up LLE structure for NV2A
This commit is contained in:
parent
0b07ff8600
commit
514cce2f6e
|
@ -179,6 +179,7 @@
|
|||
<ClInclude Include="..\..\src\CxbxKrnl\HLEDataBase.h" />
|
||||
<ClInclude Include="..\..\src\CxbxKrnl\HLEIntercept.h" />
|
||||
<ClInclude Include="..\..\src\Common\Win32\Mutex.h" />
|
||||
<ClInclude Include="..\..\src\CxbxKrnl\nv2a_int.h" />
|
||||
<ClInclude Include="..\..\src\CxbxKrnl\OOVPA.h" />
|
||||
<ClInclude Include="..\..\src\CxbxKrnl\ResourceTracker.h" />
|
||||
<ClInclude Include="..\..\src\Common\Win32\XBController.h" />
|
||||
|
|
|
@ -39,9 +39,41 @@
|
|||
#include "CxbxKrnl.h"
|
||||
#include "Emu.h"
|
||||
#include "EmuNV2A.h"
|
||||
#include "nv2a_int.h"
|
||||
|
||||
uint32_t EmuNV2A_PMC_Read32(uint32_t addr)
|
||||
{
|
||||
switch (addr) {
|
||||
default:
|
||||
EmuWarning("EmuNV2A_PMC_Read32: Unknown Read Address %08X", addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t EmuNV2A_PBUS_Read32(uint32_t addr)
|
||||
{
|
||||
switch (addr) {
|
||||
case NV_PBUS_PCI_NV_0:
|
||||
return 0x10de; // PCI_VENDOR_ID_NVIDIA
|
||||
break;
|
||||
default:
|
||||
EmuWarning("EmuNV2A_PBUS_Read32: Unknown Read Address %08X", addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint32_t EmuNV2A_Read32(uint32_t addr)
|
||||
{
|
||||
if (addr <= 0x1000) {
|
||||
return EmuNV2A_PMC_Read32(addr);
|
||||
}
|
||||
else if (addr <= 0x2000) {
|
||||
return EmuNV2A_PBUS_Read32(addr - 0x1000);
|
||||
}
|
||||
|
||||
EmuWarning("EmuNV2A_Read32: Unknown Read Address %08X", addr);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -61,43 +61,109 @@ void EmuX86_Write32(uint32_t addr, uint32_t value)
|
|||
EmuWarning("EmuX86_Write32: Unknown Write Address %08X", addr);
|
||||
}
|
||||
|
||||
bool EmuX86_DecodeMemoryOperand(uint32_t* output, LPEXCEPTION_POINTERS e, Zydis::OperandInfo& operand)
|
||||
{
|
||||
uint32_t base = 0;
|
||||
uint32_t index = 0;
|
||||
|
||||
switch (operand.base) {
|
||||
case Zydis::Register::EAX:
|
||||
base = e->ContextRecord->Eax;
|
||||
break;
|
||||
case Zydis::Register::EBX:
|
||||
base = e->ContextRecord->Ebx;
|
||||
break;
|
||||
case Zydis::Register::ECX:
|
||||
base = e->ContextRecord->Ecx;
|
||||
break;
|
||||
case Zydis::Register::EDX:
|
||||
base = e->ContextRecord->Edx;
|
||||
break;
|
||||
case Zydis::Register::NONE:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (operand.index) {
|
||||
case Zydis::Register::NONE:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
*output = base + index + operand.lval.udword;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmuX86_MOV(LPEXCEPTION_POINTERS e, Zydis::InstructionInfo& info)
|
||||
{
|
||||
if (info.operand[0].type == Zydis::OperandType::REGISTER && info.operand[1].type == Zydis::OperandType::MEMORY)
|
||||
{
|
||||
DWORD* pDstReg = nullptr;
|
||||
uint32_t srcAddr = 0;
|
||||
|
||||
switch (info.operand[0].base) {
|
||||
case Zydis::Register::EAX:
|
||||
e->ContextRecord->Eax = EmuX86_Read32(info.operand[1].lval.udword);
|
||||
return true;
|
||||
pDstReg = &e->ContextRecord->Eax;
|
||||
break;
|
||||
case Zydis::Register::EBX:
|
||||
e->ContextRecord->Ebx = EmuX86_Read32(info.operand[1].lval.udword);
|
||||
return true;
|
||||
pDstReg = &e->ContextRecord->Ebx;
|
||||
break;
|
||||
case Zydis::Register::ECX:
|
||||
e->ContextRecord->Ebx = EmuX86_Read32(info.operand[1].lval.udword);
|
||||
return true;
|
||||
pDstReg = &e->ContextRecord->Ecx;
|
||||
break;
|
||||
case Zydis::Register::EDX:
|
||||
pDstReg = &e->ContextRecord->Edx;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!EmuX86_DecodeMemoryOperand(&srcAddr, e, info.operand[1])) {
|
||||
return false;
|
||||
}
|
||||
*pDstReg = EmuX86_Read32(srcAddr);
|
||||
return true;
|
||||
}
|
||||
else if (info.operand[0].type == Zydis::OperandType::MEMORY && info.operand[1].type == Zydis::OperandType::REGISTER)
|
||||
{
|
||||
uint32_t addr = 0;
|
||||
uint32_t value = 0;
|
||||
|
||||
if (!EmuX86_DecodeMemoryOperand(&addr, e, info.operand[0])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (info.operand[1].base) {
|
||||
case Zydis::Register::EAX:
|
||||
EmuX86_Write32(info.operand[1].lval.udword, e->ContextRecord->Eax);
|
||||
return true;
|
||||
value = e->ContextRecord->Eax;
|
||||
break;
|
||||
case Zydis::Register::EBX:
|
||||
EmuX86_Write32(info.operand[1].lval.udword, e->ContextRecord->Ebx);
|
||||
return true;
|
||||
value = e->ContextRecord->Ebx;
|
||||
break;
|
||||
case Zydis::Register::ECX:
|
||||
EmuX86_Write32(info.operand[1].lval.udword, e->ContextRecord->Ecx);
|
||||
return true;
|
||||
value = e->ContextRecord->Ecx;
|
||||
break;
|
||||
case Zydis::Register::EDX:
|
||||
value = e->ContextRecord->Edx;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
EmuX86_Write32(addr, value);
|
||||
return true;
|
||||
}
|
||||
else if (info.operand[0].type == Zydis::OperandType::MEMORY && info.operand[1].type == Zydis::OperandType::IMMEDIATE)
|
||||
{
|
||||
EmuX86_Write32(info.operand[0].lval.udword, info.operand[1].lval.udword);
|
||||
uint32_t addr = 0;
|
||||
|
||||
if (!EmuX86_DecodeMemoryOperand(&addr, e, info.operand[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EmuX86_Write32(addr, info.operand[1].lval.udword);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue