From eaf487f7a622b4744683d9af6ae5717db6f4180d Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Fri, 21 Oct 2016 17:57:57 +0200 Subject: [PATCH] Added read32 handlers for all nv2a subcomponents --- src/CxbxKrnl/EmuNV2A.cpp | 283 +++++++++++++++++++++++++++++++++++++-- src/CxbxKrnl/EmuX86.cpp | 55 +++----- 2 files changed, 293 insertions(+), 45 deletions(-) diff --git a/src/CxbxKrnl/EmuNV2A.cpp b/src/CxbxKrnl/EmuNV2A.cpp index 342f1a434..0fad844f7 100644 --- a/src/CxbxKrnl/EmuNV2A.cpp +++ b/src/CxbxKrnl/EmuNV2A.cpp @@ -56,7 +56,8 @@ uint32_t EmuNV2A_PBUS_Read32(uint32_t addr) switch (addr) { case NV_PBUS_PCI_NV_0: return 0x10de; // PCI_VENDOR_ID_NVIDIA - break; + case NV_PBUS_PCI_NV_2: + return 0x0; // NV_PBUS_PCI_NV_2_REVISION_ID ?? default: EmuWarning("EmuNV2A_PBUS_Read32: Unknown Read Address %08X", addr); } @@ -64,21 +65,285 @@ uint32_t EmuNV2A_PBUS_Read32(uint32_t addr) return 0; } +uint32_t EmuNV2A_PFIFO_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PFIFO_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PFIFO_CACHE_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PFIFO_CACHE_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PRMA_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PRMA_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PVIDEO_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PVIDEO_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PTIMER_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PTIMER_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PCOUNTER_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PCOUNTER_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PTIMER_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PTIMER_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PVPE_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PVPE_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PTV_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PTV_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PRMFB_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PRMFB_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PRMVIO_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PRMVIO_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PFB_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PFB_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PSTRAPS_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PSTRAPS_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PGRAPH_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PGRAPH_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PCRTC_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PCRTC_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PRMCIO_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PRMCIO_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PRAMDAC_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PRAMDAC_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PRMDIO_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PRMDIO_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_PRAMIN_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_PRAMIN_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} + +uint32_t EmuNV2A_USER_Read32(uint32_t addr) +{ + switch (addr) { + default: + EmuWarning("EmuNV2A_USER_Read32: Unknown Read Address %08X", addr); + } + + return 0; +} uint32_t EmuNV2A_Read32(uint32_t addr) { - if (addr <= 0x1000) { - return EmuNV2A_PMC_Read32(addr); + switch ((addr >> 12) & 31) { + case NV_PMC : /* card master control */ + return EmuNV2A_PMC_Read32(addr & 0x0FFF); + case NV_PBUS : /* bus control */ + return EmuNV2A_PBUS_Read32(addr & 0x0FFF); + case NV_PFIFO : /* MMIO and DMA FIFO submission to PGRAPH and VPE */ + return EmuNV2A_PFIFO_Read32(addr & 0x0FFF); + case NV_PFIFO_CACHE : + return EmuNV2A_PFIFO_CACHE_Read32(addr & 0x0FFF); + case NV_PRMA : /* access to BAR0/BAR1 from real mode */ + return EmuNV2A_PRMA_Read32(addr & 0x0FFF); + case NV_PVIDEO : /* video overlay */ + return EmuNV2A_PVIDEO_Read32(addr & 0x0FFF); + case NV_PTIMER : /* time measurement and time-based alarms */ + return EmuNV2A_PTIMER_Read32(addr & 0x0FFF); + case NV_PCOUNTER : /* performance monitoring counters */ + return EmuNV2A_PCOUNTER_Read32(addr & 0x0FFF); + case NV_PVPE : /* MPEG2 decoding engine */ + return EmuNV2A_PVPE_Read32(addr & 0x0FFF); + case NV_PTV : /* TV encoder */ + return EmuNV2A_PTV_Read32(addr & 0x0FFF); + case NV_PRMFB : /* aliases VGA memory window */ + return EmuNV2A_PRMFB_Read32(addr & 0x0FFF); + case NV_PRMVIO : /* aliases VGA sequencer and graphics controller registers */ + return EmuNV2A_PRMVIO_Read32(addr & 0x0FFF); + case NV_PFB : /* memory interface */ + return EmuNV2A_PFB_Read32(addr & 0x0FFF); + case NV_PSTRAPS : /* straps readout / override */ + return EmuNV2A_PSTRAPS_Read32(addr & 0x0FFF); + case NV_PGRAPH : /* accelerated 2d/3d drawing engine */ + return EmuNV2A_PGRAPH_Read32(addr & 0x0FFF); + case NV_PCRTC : /* more CRTC controls */ + return EmuNV2A_PCRTC_Read32(addr & 0x0FFF); + case NV_PRMCIO : /* aliases VGA CRTC and attribute controller registers */ + return EmuNV2A_PRMCIO_Read32(addr & 0x0FFF); + case NV_PRAMDAC : /* RAMDAC, cursor, and PLL control */ + return EmuNV2A_PRAMDAC_Read32(addr & 0x0FFF); + case NV_PRMDIO : /* aliases VGA palette registers */ + return EmuNV2A_PRMDIO_Read32(addr & 0x0FFF); + case NV_PRAMIN : /* RAMIN access */ + return EmuNV2A_PRAMIN_Read32(addr & 0x0FFF); + case NV_USER : /* PFIFO MMIO and DMA submission area */ + return EmuNV2A_USER_Read32(addr & 0x0FFF); + default: + EmuWarning("EmuNV2A_Read32: Unknown Read Address %08X", addr); } - else if (addr <= 0x2000) { - return EmuNV2A_PBUS_Read32(addr - 0x1000); - } - - EmuWarning("EmuNV2A_Read32: Unknown Read Address %08X", addr); return 0; } void EmuNV2A_Write32(uint32_t addr, uint32_t value) { - EmuWarning("EmuNV2A_Write32: Unknown Write Address %08X (value %08X)", addr, value); + switch ((addr >> 12) & 31) { +// case NV_PMC : /* card master control */ +// return EmuNV2A_PMC_Read32(addr & 0x0FFF); +// case NV_PBUS : /* bus control */ +// return EmuNV2A_PBUS_Read32(addr & 0x0FFF); + +// case NV_PFIFO : /* MMIO and DMA FIFO submission to PGRAPH and VPE */ +// case NV_PFIFO_CACHE : +// case NV_PRMA : /* access to BAR0/BAR1 from real mode */ +// case NV_PVIDEO : /* video overlay */ +// case NV_PTIMER : /* time measurement and time-based alarms */ +// case NV_PCOUNTER : /* performance monitoring counters */ +// case NV_PVPE : /* MPEG2 decoding engine */ +// case NV_PTV : /* TV encoder */ +// case NV_PRMFB : /* aliases VGA memory window */ +// case NV_PRMVIO : /* aliases VGA sequencer and graphics controller registers */ +// case NV_PFB : /* memory interface */ +// case NV_PSTRAPS : /* straps readout / override */ +// case NV_PGRAPH : /* accelerated 2d/3d drawing engine */ +// case NV_PCRTC : /* more CRTC controls */ +// case NV_PRMCIO : /* aliases VGA CRTC and attribute controller registers */ +// case NV_PRAMDAC : /* RAMDAC, cursor, and PLL control */ +// case NV_PRMDIO : /* aliases VGA palette registers */ +// case NV_PRAMIN : /* RAMIN access */ +// case NV_USER : /* PFIFO MMIO and DMA submission area */ + default: + EmuWarning("EmuNV2A_Write32: Unknown Write Address %08X (value %08X)", addr, value); + } } diff --git a/src/CxbxKrnl/EmuX86.cpp b/src/CxbxKrnl/EmuX86.cpp index 02437729b..99a167ebc 100644 --- a/src/CxbxKrnl/EmuX86.cpp +++ b/src/CxbxKrnl/EmuX86.cpp @@ -44,7 +44,7 @@ uint32_t EmuX86_Read32(uint32_t addr) { if (addr >= 0xFD000000 && addr <= 0xFE000000) { - return EmuNV2A_Read32(addr - 0xFD000000); + return EmuNV2A_Read32(addr & 0x00FFFFFF); } EmuWarning("EmuX86_Read32: Unknown Read Address %08X", addr); @@ -54,47 +54,13 @@ uint32_t EmuX86_Read32(uint32_t addr) void EmuX86_Write32(uint32_t addr, uint32_t value) { if (addr >= 0xFD000000 && addr <= 0xFE000000) { - EmuNV2A_Write32(addr - 0xFD000000, value); + EmuNV2A_Write32(addr & 0x00FFFFFF, value); return; } EmuWarning("EmuX86_Write32: Unknown Write Address %08X (value %08X)", addr, value); } -bool EmuX86_GetRegisterValue(uint32_t* output, LPEXCEPTION_POINTERS e, Zydis::Register reg) -{ - uint32_t value = 0; - - switch (reg) { - case Zydis::Register::EAX: - value = e->ContextRecord->Eax; - break; - case Zydis::Register::EBX: - value = e->ContextRecord->Ebx; - break; - case Zydis::Register::ECX: - value = e->ContextRecord->Ecx; - break; - case Zydis::Register::EDX: - value = e->ContextRecord->Edx; - break; - case Zydis::Register::EDI: - value = e->ContextRecord->Edi; - break; - case Zydis::Register::ESI: - value = e->ContextRecord->Esi; - break; - case Zydis::Register::NONE: - value = 0; - break; - default: - return false; - } - - *output = value; - return true; -} - DWORD* EmuX86_GetRegisterPointer(LPEXCEPTION_POINTERS e, Zydis::Register reg) { switch (reg) { @@ -115,6 +81,23 @@ DWORD* EmuX86_GetRegisterPointer(LPEXCEPTION_POINTERS e, Zydis::Register reg) return nullptr; } +bool EmuX86_GetRegisterValue(uint32_t* output, LPEXCEPTION_POINTERS e, Zydis::Register reg) +{ + uint32_t value = 0; + + if (reg != Zydis::Register::NONE) + { + DWORD* regptr = EmuX86_GetRegisterPointer(e, reg); + if (regptr == nullptr) + return false; + + value = *regptr; + } + + *output = value; + return true; +} + bool EmuX86_DecodeMemoryOperand(uint32_t* output, LPEXCEPTION_POINTERS e, Zydis::OperandInfo& operand) { uint32_t base = 0;