diff --git a/build/win32/Cxbx.vcxproj b/build/win32/Cxbx.vcxproj
index c5b271a41..5074bfe6d 100644
--- a/build/win32/Cxbx.vcxproj
+++ b/build/win32/Cxbx.vcxproj
@@ -190,6 +190,7 @@
+
@@ -359,6 +360,7 @@
+
diff --git a/build/win32/Cxbx.vcxproj.filters b/build/win32/Cxbx.vcxproj.filters
index 53da67549..546c0b4c5 100644
--- a/build/win32/Cxbx.vcxproj.filters
+++ b/build/win32/Cxbx.vcxproj.filters
@@ -226,6 +226,9 @@
Hardware
+
+ Hardware
+
@@ -441,6 +444,9 @@
Hardware
+
+ Hardware
+
diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp
index c94c01044..1162d9cd4 100644
--- a/src/CxbxKrnl/CxbxKrnl.cpp
+++ b/src/CxbxKrnl/CxbxKrnl.cpp
@@ -1017,9 +1017,6 @@ __declspec(noreturn) void CxbxKrnlInit
// Now the hardware devices exist, couple the EEPROM buffer to it's device
g_EEPROM->SetEEPROM((uint8_t*)EEPROM);
- // Always initialise NV2A: We may need it for disabled HLE patches too!
- EmuNV2A_Init();
-
if (bLLE_GPU)
{
DbgPrintf("INIT: Initializing OpenGL.\n");
diff --git a/src/CxbxKrnl/EmuX86.cpp b/src/CxbxKrnl/EmuX86.cpp
index 379eba313..15bc5c9ff 100644
--- a/src/CxbxKrnl/EmuX86.cpp
+++ b/src/CxbxKrnl/EmuX86.cpp
@@ -47,10 +47,8 @@
#include "mnemonics.h"
#include "CxbxKrnl.h"
-#include "Emu.h"
+#include "Emu.h" // For EmuWarning
#include "EmuX86.h"
-#include "EmuNV2A.h"
-#include "EmuNVNet.h"
#include "HLEIntercept.h" // for bLLE_GPU
#include
@@ -177,11 +175,7 @@ uint32_t EmuX86_Read(xbaddr addr, int size)
uint32_t value;
- if (addr >= NV2A_ADDR && addr < NV2A_ADDR + NV2A_SIZE) {
- // Access NV2A regardless weither HLE is disabled or not (ignoring bLLE_GPU)
- value = EmuNV2A_Read(addr - NV2A_ADDR, size);
- // Note : EmuNV2A_Read does it's own logging
- } else if (addr >= XBOX_FLASH_ROM_BASE) { // 0xFFF00000 - 0xFFFFFFF
+ if (addr >= XBOX_FLASH_ROM_BASE) { // 0xFFF00000 - 0xFFFFFFF
value = EmuFlash_Read32(addr - XBOX_FLASH_ROM_BASE); // TODO : Make flash access size-aware
} else {
// Pass the Read to the PCI Bus, this will handle devices with BARs set to MMIO addresses
@@ -211,13 +205,6 @@ void EmuX86_Write(xbaddr addr, uint32_t value, int size)
return;
}
- if (addr >= NV2A_ADDR && addr < NV2A_ADDR + NV2A_SIZE) {
- // Access NV2A regardless weither HLE is disabled or not (ignoring bLLE_GPU)
- EmuNV2A_Write(addr - NV2A_ADDR, value, size);
- // Note : EmuNV2A_Write does it's own logging
- return;
- }
-
if (addr >= XBOX_FLASH_ROM_BASE) { // 0xFFF00000 - 0xFFFFFFF
EmuWarning("EmuX86_Write(0x%08X, 0x%08X) [FLASH_ROM]", addr, value);
return;
diff --git a/src/CxbxKrnl/Xbox.cpp b/src/CxbxKrnl/Xbox.cpp
index 2e6c4c10e..e354bbb4b 100644
--- a/src/CxbxKrnl/Xbox.cpp
+++ b/src/CxbxKrnl/Xbox.cpp
@@ -40,12 +40,14 @@
#include "SMCDevice.h" // For SMCDevice
#include "EEPROMDevice.h" // For EEPROMDevice
#include "EmuNVNet.h" // For NVNetDevice
+#include "devices\video\nv2a.h" // For NV2ADevice
PCIBus* g_PCIBus;
SMBus* g_SMBus;
SMCDevice* g_SMC;
EEPROMDevice* g_EEPROM;
NVNetDevice* g_NVNet;
+NV2ADevice* g_NV2A;
#define SMBUS_TV_ENCODER_ID_CONEXANT 0x8A // = Write; Read = 08B
#define SMBUS_TV_ENCODER_ID_FOCUS 0xD4 // = Write; Read = 0D5
@@ -57,12 +59,14 @@ void InitXboxHardware()
g_SMC = new SMCDevice(Revision1_1); // TODO : Make configurable
g_EEPROM = new EEPROMDevice();
g_NVNet = new NVNetDevice();
+ g_NV2A = new NV2ADevice();
g_SMBus->ConnectDevice(SMBUS_SMC_SLAVE_ADDRESS, g_SMC);
g_SMBus->ConnectDevice(SMBUS_EEPROM_ADDRESS, g_EEPROM);
g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(1, 1)), g_SMBus);
g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(4, 0)), g_NVNet);
+ g_PCIBus->ConnectDevice(PCI_DEVID(1, PCI_DEVFN(0, 0)), g_NV2A);
// TODO : Handle other SMBUS Addresses, like PIC_ADDRESS, XCALIBUR_ADDRESS
// Resources : http://pablot.com/misc/fancontroller.cpp
diff --git a/src/CxbxKrnl/devices/video/nv2a.cpp b/src/CxbxKrnl/devices/video/nv2a.cpp
new file mode 100644
index 000000000..3ea6c6972
--- /dev/null
+++ b/src/CxbxKrnl/devices/video/nv2a.cpp
@@ -0,0 +1,122 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check it.
+// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+// ******************************************************************
+// *
+// * .,-::::: .,:: .::::::::. .,:: .:
+// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
+// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
+// * $$$ Y$$$P $$""""Y$$ Y$$$P
+// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
+// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
+// *
+// * src->devices->video->nv2a.cpp
+// *
+// * This file is part of the Cxbx project.
+// *
+// * Cxbx and Cxbe are free software; you can redistribute them
+// * and/or modify them under the terms of the GNU General Public
+// * License as published by the Free Software Foundation; either
+// * version 2 of the license, or (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have recieved a copy of the GNU General Public License
+// * along with this program; see the file COPYING.
+// * If not, write to the Free Software Foundation, Inc.,
+// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
+// *
+// * (c) 2017-2018 Luke Usher
+// * (c) 2018 Patrick van Logchem
+// *
+// * All rights reserved
+// *
+// ******************************************************************
+#define _XBOXKRNL_DEFEXTRN_
+
+#define LOG_PREFIX "NV2A"
+
+#include "../../CxbxKrnl/CxbxKrnl.h" // For XBOX_MEMORY_SIZE, DWORD, etc
+#include "../../CxbxKrnl/EmuNV2A.h" // For now, use EmuNV2A
+
+#include "nv2a.h"
+
+/* NV2ADevice */
+
+// PCI Device functions
+
+void NV2ADevice::Init()
+{
+ PCIBarRegister r;
+
+ // Register Memory bar :
+ r.Raw.type = PCI_BAR_TYPE_MEMORY;
+ r.Memory.address = NV2A_ADDR >> 4;
+ RegisterBAR(0, NV2A_SIZE, r.value);
+
+ // Register physical memory on bar 1
+ r.Memory.address = 0;
+ RegisterBAR(1, XBOX_MEMORY_SIZE, r.value); // TODO : Read g_PhysicalMemory->Size
+
+ m_DeviceId = 0x02A5;
+ m_VendorId = PCI_VENDOR_ID_NVIDIA;
+
+ // For now, forward to EmuNv2A
+ EmuNV2A_Init();
+}
+
+void NV2ADevice::Reset()
+{
+}
+
+uint32_t NV2ADevice::IORead(int barIndex, uint32_t port, unsigned size)
+{
+ return 0;
+}
+
+void NV2ADevice::IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size)
+{
+}
+
+uint32_t NV2ADevice::MMIORead(int barIndex, uint32_t addr, unsigned size)
+{
+ switch (barIndex) {
+ case 0:
+ uint32_t value;
+ // For now, forward to EmuNV2A
+ {
+ // Access NV2A regardless weither HLE is disabled or not (ignoring bLLE_GPU)
+ value = EmuNV2A_Read(addr, size);
+ // Note : EmuNV2A_Read does it's own logging
+ }
+ // TODO : call block handler
+ return value;
+ case 1:
+ return 0; // TODO : access physical memory
+ }
+
+ // TODO : Log unexpected bar access
+ return 0;
+}
+
+void NV2ADevice::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size)
+{
+ switch (barIndex) {
+ case 0:
+ // For now, forward to EmuNV2A
+ {
+ // Access NV2A regardless weither HLE is disabled or not (ignoring bLLE_GPU)
+ EmuNV2A_Write(addr, value, size);
+ // Note : EmuNV2A_Write does it's own logging
+ }
+ // TODO : call block handler
+ return;
+ case 1:
+ // TODO : access physical memory
+ return;
+ }
+
+ // TODO : Log unexpected bar access
+}
diff --git a/src/CxbxKrnl/devices/video/nv2a.h b/src/CxbxKrnl/devices/video/nv2a.h
new file mode 100644
index 000000000..be6c90324
--- /dev/null
+++ b/src/CxbxKrnl/devices/video/nv2a.h
@@ -0,0 +1,54 @@
+// ******************************************************************
+// *
+// * .,-::::: .,:: .::::::::. .,:: .:
+// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
+// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
+// * $$$ Y$$$P $$""""Y$$ Y$$$P
+// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
+// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
+// *
+// * src->devices->video->nv2a.h
+// *
+// * This file is part of the Cxbx project.
+// *
+// * Cxbx and Cxbe are free software; you can redistribute them
+// * and/or modify them under the terms of the GNU General Public
+// * License as published by the Free Software Foundation; either
+// * version 2 of the license, or (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have recieved a copy of the GNU General Public License
+// * along with this program; see the file COPYING.
+// * If not, write to the Free Software Foundation, Inc.,
+// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
+// *
+// * (c) 2017-2018 Luke Usher
+// * (c) 2018 Patrick van Logchem
+// *
+// * All rights reserved
+// *
+// ******************************************************************
+#pragma once
+
+#include "../../CxbxKrnl/PCIDevice.h" // For PCIDevice
+
+#define NV2A_ADDR 0xFD000000
+#define NV2A_SIZE 0x01000000
+
+class NV2ADevice : public PCIDevice {
+public:
+ // PCI Device functions
+ void Init();
+ void Reset();
+
+ uint32_t IORead(int barIndex, uint32_t port, unsigned size);
+ void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size);
+ uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size);
+ void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size);
+};
+
+extern NV2ADevice* g_NV2A;