Merge pull request #492 from LukeUsher/xonline-tweaks

Xonline tweaks
This commit is contained in:
PatrickvL 2017-06-27 08:25:41 +02:00 committed by GitHub
commit 3e8e4acd75
14 changed files with 614 additions and 62 deletions

View File

@ -214,6 +214,7 @@ $(SOLUTIONDIR)Export.bat</Command>
<ClInclude Include="..\..\src\CxbxKrnl\EmuKrnlLogging.h" /> <ClInclude Include="..\..\src\CxbxKrnl\EmuKrnlLogging.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuNtDll.h" /> <ClInclude Include="..\..\src\CxbxKrnl\EmuNtDll.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuNV2A.h" /> <ClInclude Include="..\..\src\CxbxKrnl\EmuNV2A.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuNVNet.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuSha.h" /> <ClInclude Include="..\..\src\CxbxKrnl\EmuSha.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuX86.h" /> <ClInclude Include="..\..\src\CxbxKrnl\EmuX86.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuXactEng.h" /> <ClInclude Include="..\..\src\CxbxKrnl\EmuXactEng.h" />
@ -502,6 +503,7 @@ $(SOLUTIONDIR)Export.bat</Command>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\EmuNV2A.cpp" /> <ClCompile Include="..\..\src\CxbxKrnl\EmuNV2A.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\EmuNVNet.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\EmuSha.cpp" /> <ClCompile Include="..\..\src\CxbxKrnl\EmuSha.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\EmuX86.cpp" /> <ClCompile Include="..\..\src\CxbxKrnl\EmuX86.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\EmuXactEng.cpp" /> <ClCompile Include="..\..\src\CxbxKrnl\EmuXactEng.cpp" />

View File

@ -202,6 +202,9 @@
<ClCompile Include="..\..\src\CxbxKrnl\EmuD3D8Logging.cpp"> <ClCompile Include="..\..\src\CxbxKrnl\EmuD3D8Logging.cpp">
<Filter>Emulator</Filter> <Filter>Emulator</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\EmuNVNet.cpp">
<Filter>Emulator</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\src\Cxbx\DlgControllerConfig.h"> <ClInclude Include="..\..\src\Cxbx\DlgControllerConfig.h">
@ -552,6 +555,9 @@
<ClInclude Include="..\..\src\CxbxKrnl\EmuD3D8Logging.h"> <ClInclude Include="..\..\src\CxbxKrnl\EmuD3D8Logging.h">
<Filter>Emulator</Filter> <Filter>Emulator</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\EmuNVNet.h">
<Filter>Emulator</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\resource\About.jpg"> <None Include="..\..\resource\About.jpg">

View File

@ -41,7 +41,7 @@ XBSYSAPI EXPORTNUM(42) PANSI_STRING HalDiskSerialNumber;
// ****************************************************************** // ******************************************************************
// * 0x002B - HalEnableSystemInterrupt() // * 0x002B - HalEnableSystemInterrupt()
// ****************************************************************** // ******************************************************************
XBSYSAPI EXPORTNUM(43) BOOLEAN NTAPI HalEnableSystemInterrupt XBSYSAPI EXPORTNUM(43) VOID NTAPI HalEnableSystemInterrupt
( (
IN ULONG BusInterruptLevel, IN ULONG BusInterruptLevel,
IN KINTERRUPT_MODE InterruptMode IN KINTERRUPT_MODE InterruptMode

View File

@ -174,7 +174,7 @@ XBSYSAPI EXPORTNUM(164) PLAUNCH_DATA_PAGE LaunchDataPage;
// ****************************************************************** // ******************************************************************
// * 0x00FC - PhyGetLinkState() // * 0x00FC - PhyGetLinkState()
// ****************************************************************** // ******************************************************************
XBSYSAPI EXPORTNUM(252) NTSTATUS NTAPI PhyGetLinkState XBSYSAPI EXPORTNUM(252) DWORD NTAPI PhyGetLinkState
( (
IN ULONG Mode IN ULONG Mode
); );

View File

@ -440,6 +440,14 @@ NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::strin
// Look up the partition in the list of pre-registered devices : // Look up the partition in the list of pre-registered devices :
result = STATUS_DEVICE_DOES_NOT_EXIST; // TODO : Is this the correct error? result = STATUS_DEVICE_DOES_NOT_EXIST; // TODO : Is this the correct error?
// If aFullPath starts with a Drive letter, find the originating path and substitute that
if (aFullPath[1] == ':' && aFullPath[0] >= 'A' && aFullPath[0] <= 'Z') {
EmuNtSymbolicLinkObject* DriveLetterLink = FindNtSymbolicLinkObjectByDriveLetter(aFullPath[0]);
if (DriveLetterLink != NULL) {
aFullPath = DriveLetterLink->XboxSymbolicLinkPath;
}
}
// Make a distinction between Xbox paths (starting with '\Device'...) and host paths : // Make a distinction between Xbox paths (starting with '\Device'...) and host paths :
IsHostBasedPath = _strnicmp(aFullPath.c_str(), DevicePrefix.c_str(), DevicePrefix.length()) != 0; IsHostBasedPath = _strnicmp(aFullPath.c_str(), DevicePrefix.c_str(), DevicePrefix.length()) != 0;
if (IsHostBasedPath) if (IsHostBasedPath)

View File

@ -50,6 +50,7 @@ namespace xboxkrnl
#include "Logging.h" #include "Logging.h"
#include "EmuKrnlLogging.h" #include "EmuKrnlLogging.h"
#include "CxbxKrnl.h" #include "CxbxKrnl.h"
#include "EmuXTL.h"
// prevent name collisions // prevent name collisions
namespace NtDll namespace NtDll
@ -344,16 +345,14 @@ XBSYSAPI EXPORTNUM(163) xboxkrnl::VOID FASTCALL xboxkrnl::KiUnlockDispatcherData
// ****************************************************************** // ******************************************************************
// * 0x00FC - PhyGetLinkState() // * 0x00FC - PhyGetLinkState()
// ****************************************************************** // ******************************************************************
XBSYSAPI EXPORTNUM(252) xboxkrnl::NTSTATUS NTAPI xboxkrnl::PhyGetLinkState XBSYSAPI EXPORTNUM(252) xboxkrnl::DWORD NTAPI xboxkrnl::PhyGetLinkState
( (
IN ULONG Mode IN ULONG Mode
) )
{ {
LOG_FUNC_ONE_ARG(Mode); LOG_FUNC_ONE_ARG(Mode);
LOG_UNIMPLEMENTED(); return XNET_ETHERNET_LINK_ACTIVE | XNET_ETHERNET_LINK_100MBPS | XNET_ETHERNET_LINK_FULL_DUPLEX;
RETURN(S_OK);
} }
// ****************************************************************** // ******************************************************************

View File

@ -139,7 +139,7 @@ XBSYSAPI EXPORTNUM(42) xboxkrnl::PANSI_STRING xboxkrnl::HalDiskSerialNumber = 0;
// ****************************************************************** // ******************************************************************
// * 0x002B - HalEnableSystemInterrupt() // * 0x002B - HalEnableSystemInterrupt()
// ****************************************************************** // ******************************************************************
XBSYSAPI EXPORTNUM(43) xboxkrnl::BOOLEAN NTAPI xboxkrnl::HalEnableSystemInterrupt XBSYSAPI EXPORTNUM(43) xboxkrnl::VOID NTAPI xboxkrnl::HalEnableSystemInterrupt
( (
IN ULONG BusInterruptLevel, IN ULONG BusInterruptLevel,
IN KINTERRUPT_MODE InterruptMode IN KINTERRUPT_MODE InterruptMode
@ -151,8 +151,6 @@ XBSYSAPI EXPORTNUM(43) xboxkrnl::BOOLEAN NTAPI xboxkrnl::HalEnableSystemInterrup
LOG_FUNC_END; LOG_FUNC_END;
LOG_UNIMPLEMENTED(); // TODO : Once thread-switching works, make system interrupts work too LOG_UNIMPLEMENTED(); // TODO : Once thread-switching works, make system interrupts work too
RETURN(FALSE);
} }
#ifdef _DEBUG_TRACE #ifdef _DEBUG_TRACE

View File

@ -59,6 +59,7 @@
#include <gl\glew.h> #include <gl\glew.h>
#include <gl\GL.h> #include <gl\GL.h>
#include <gl\GLU.h> #include <gl\GLU.h>
#include <cassert>
//#include <gl\glut.h> //#include <gl\glut.h>
#define NV_PMC_ADDR 0x00000000 #define NV_PMC_ADDR 0x00000000
@ -1235,28 +1236,68 @@ const NV2ABlockInfo* EmuNV2A_Block(xbaddr addr)
return nullptr; return nullptr;
} }
uint32_t EmuNV2A_Read32(xbaddr addr) uint32_t EmuNV2A_Read(xbaddr addr, int size)
{ {
const NV2ABlockInfo* block = EmuNV2A_Block(addr); const NV2ABlockInfo* block = EmuNV2A_Block(addr);
if (block != nullptr) { if (block != nullptr) {
return block->read(addr - block->offset); switch (size) {
case 8:
return block->read(addr - block->offset) & 0xFF;
case 16:
return block->read(addr - block->offset) & 0xFFFF;
case 32:
return block->read(addr - block->offset);
default:
EmuWarning("EmuNV2A_Read: Invalid read size: %d", size);
return 0;
}
} }
EmuWarning("EmuNV2A_Read32: Unhandled Read Address %08X", addr); EmuWarning("EmuNV2A_Read%d: Unhandled Read Address %08X", size, addr);
return 0; return 0;
} }
void EmuNV2A_Write32(xbaddr addr, uint32_t value) void EmuNV2A_Write(xbaddr addr, uint32_t value, int size)
{ {
const NV2ABlockInfo* block = EmuNV2A_Block(addr); const NV2ABlockInfo* block = EmuNV2A_Block(addr);
if (block != nullptr) { if (block != nullptr) {
block->write(addr - block->offset, value); int shift = 0;
return; xbaddr aligned_addr = 0;
uint32_t aligned_value = 0;
uint32_t mask = 0;
switch (size) {
case 8:
shift = (addr & 3) * 8;
aligned_addr = addr & ~3;
aligned_value = block->read(aligned_addr - block->offset);
mask = 0xFF << shift;
// TODO : Must the second byte be written to the next DWORD?
block->write(aligned_addr - block->offset, (aligned_value & ~mask) | (value << shift));
return;
case 16:
assert((addr & 1) == 0);
shift = (addr & 2) * 16;
aligned_addr = addr & ~3;
aligned_value = block->read(addr - block->offset);
mask = 0xFFFF << shift;
// TODO : Must the second byte be written to the next DWORD?
block->write(aligned_addr - block->offset, (aligned_value & ~mask) | (value << shift));
return;
case 32:
block->write(addr - block->offset, value);
return;
default:
EmuWarning("EmuNV2A_Read: Invalid read size: %d", size);
return;
}
} }
EmuWarning("EmuNV2A_Write32: Unhandled Write Address %08X (value %08X)", addr, value); EmuWarning("EmuNV2A_Write%d: Unhandled Write Address %08X (value %08X)", size, addr, value);
return; return;
} }

View File

@ -40,8 +40,8 @@
#define NV2A_ADDR 0xFD000000 #define NV2A_ADDR 0xFD000000
#define NV2A_SIZE 0x01000000 #define NV2A_SIZE 0x01000000
uint32_t EmuNV2A_Read32(xbaddr addr); uint32_t EmuNV2A_Read(xbaddr addr, int size);
void EmuNV2A_Write32(xbaddr addr, uint32_t value); void EmuNV2A_Write(xbaddr addr, uint32_t value, int size);
void InitOpenGLContext(); void InitOpenGLContext();

269
src/CxbxKrnl/EmuNVNet.cpp Normal file
View File

@ -0,0 +1,269 @@
// 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,
// *
// * Cxbx->Win32->CxbxKrnl->EmuNVNet.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) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * (c) 2017 Luke Usher <luke.usher@outlook.com>
// *
// * This file is based on code from the XQEMU Project
// * https://github.com/espes/xqemu/blob/xbox/hw/xbox/nvnet.c
// *
// * All rights reserved
// *
// ******************************************************************
#define _CXBXKRNL_INTERNAL
#define _XBOXKRNL_DEFEXTRN_
#include "CxbxKrnl.h"
#include "Emu.h"
#include "EmuNVNet.h"
// NVNET Register Definitions
// Taken from XQEMU
enum {
NvRegIrqStatus = 0x000,
# define NVREG_IRQSTAT_BIT1 0x002
# define NVREG_IRQSTAT_BIT4 0x010
# define NVREG_IRQSTAT_MIIEVENT 0x040
# define NVREG_IRQSTAT_MASK 0x1ff
NvRegIrqMask = 0x004,
# define NVREG_IRQ_RX 0x0002
# define NVREG_IRQ_RX_NOBUF 0x0004
# define NVREG_IRQ_TX_ERR 0x0008
# define NVREG_IRQ_TX2 0x0010
# define NVREG_IRQ_TIMER 0x0020
# define NVREG_IRQ_LINK 0x0040
# define NVREG_IRQ_TX1 0x0100
# define NVREG_IRQMASK_WANTED_1 0x005f
# define NVREG_IRQMASK_WANTED_2 0x0147
# define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|\
NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|\
NVREG_IRQ_TX1))
NvRegUnknownSetupReg6 = 0x008,
# define NVREG_UNKSETUP6_VAL 3
/*
* NVREG_POLL_DEFAULT is the interval length of the timer source on the nic
* NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
*/
NvRegPollingInterval = 0x00c,
# define NVREG_POLL_DEFAULT 970
NvRegMisc1 = 0x080,
# define NVREG_MISC1_HD 0x02
# define NVREG_MISC1_FORCE 0x3b0f3c
NvRegTransmitterControl = 0x084,
# define NVREG_XMITCTL_START 0x01
NvRegTransmitterStatus = 0x088,
# define NVREG_XMITSTAT_BUSY 0x01
NvRegPacketFilterFlags = 0x8c,
# define NVREG_PFF_ALWAYS 0x7F0008
# define NVREG_PFF_PROMISC 0x80
# define NVREG_PFF_MYADDR 0x20
NvRegOffloadConfig = 0x90,
# define NVREG_OFFLOAD_HOMEPHY 0x601
# define NVREG_OFFLOAD_NORMAL 0x5ee
NvRegReceiverControl = 0x094,
# define NVREG_RCVCTL_START 0x01
NvRegReceiverStatus = 0x98,
# define NVREG_RCVSTAT_BUSY 0x01
NvRegRandomSeed = 0x9c,
# define NVREG_RNDSEED_MASK 0x00ff
# define NVREG_RNDSEED_FORCE 0x7f00
NvRegUnknownSetupReg1 = 0xA0,
# define NVREG_UNKSETUP1_VAL 0x16070f
NvRegUnknownSetupReg2 = 0xA4,
# define NVREG_UNKSETUP2_VAL 0x16
NvRegMacAddrA = 0xA8,
NvRegMacAddrB = 0xAC,
NvRegMulticastAddrA = 0xB0,
# define NVREG_MCASTADDRA_FORCE 0x01
NvRegMulticastAddrB = 0xB4,
NvRegMulticastMaskA = 0xB8,
NvRegMulticastMaskB = 0xBC,
NvRegTxRingPhysAddr = 0x100,
NvRegRxRingPhysAddr = 0x104,
NvRegRingSizes = 0x108,
# define NVREG_RINGSZ_TXSHIFT 0
# define NVREG_RINGSZ_RXSHIFT 16
NvRegUnknownTransmitterReg = 0x10c,
NvRegLinkSpeed = 0x110,
# define NVREG_LINKSPEED_FORCE 0x10000
# define NVREG_LINKSPEED_10 10
# define NVREG_LINKSPEED_100 100
# define NVREG_LINKSPEED_1000 1000
NvRegUnknownSetupReg5 = 0x130,
# define NVREG_UNKSETUP5_BIT31 (1<<31)
NvRegUnknownSetupReg3 = 0x134,
# define NVREG_UNKSETUP3_VAL1 0x200010
NvRegUnknownSetupReg8 = 0x13C,
# define NVREG_UNKSETUP8_VAL1 0x300010
NvRegUnknownSetupReg7 = 0x140,
# define NVREG_UNKSETUP7_VAL 0x300010
NvRegTxRxControl = 0x144,
# define NVREG_TXRXCTL_KICK 0x0001
# define NVREG_TXRXCTL_BIT1 0x0002
# define NVREG_TXRXCTL_BIT2 0x0004
# define NVREG_TXRXCTL_IDLE 0x0008
# define NVREG_TXRXCTL_RESET 0x0010
NvRegMIIStatus = 0x180,
# define NVREG_MIISTAT_ERROR 0x0001
# define NVREG_MIISTAT_LINKCHANGE 0x0008
# define NVREG_MIISTAT_MASK 0x000f
# define NVREG_MIISTAT_MASK2 0x000f
NvRegUnknownSetupReg4 = 0x184,
# define NVREG_UNKSETUP4_VAL 8
NvRegAdapterControl = 0x188,
# define NVREG_ADAPTCTL_START 0x02
# define NVREG_ADAPTCTL_LINKUP 0x04
# define NVREG_ADAPTCTL_PHYVALID 0x4000
# define NVREG_ADAPTCTL_RUNNING 0x100000
# define NVREG_ADAPTCTL_PHYSHIFT 24
NvRegMIISpeed = 0x18c,
# define NVREG_MIISPEED_BIT8 (1<<8)
# define NVREG_MIIDELAY 5
NvRegMIIControl = 0x190,
# define NVREG_MIICTL_INUSE 0x10000
# define NVREG_MIICTL_WRITE 0x08000
# define NVREG_MIICTL_ADDRSHIFT 5
NvRegMIIData = 0x194,
NvRegWakeUpFlags = 0x200,
# define NVREG_WAKEUPFLAGS_VAL 0x7770
# define NVREG_WAKEUPFLAGS_BUSYSHIFT 24
# define NVREG_WAKEUPFLAGS_ENABLESHIFT 16
# define NVREG_WAKEUPFLAGS_D3SHIFT 12
# define NVREG_WAKEUPFLAGS_D2SHIFT 8
# define NVREG_WAKEUPFLAGS_D1SHIFT 4
# define NVREG_WAKEUPFLAGS_D0SHIFT 0
# define NVREG_WAKEUPFLAGS_ACCEPT_MAGPAT 0x01
# define NVREG_WAKEUPFLAGS_ACCEPT_WAKEUPPAT 0x02
# define NVREG_WAKEUPFLAGS_ACCEPT_LINKCHANGE 0x04
NvRegPatternCRC = 0x204,
NvRegPatternMask = 0x208,
NvRegPowerCap = 0x268,
# define NVREG_POWERCAP_D3SUPP (1<<30)
# define NVREG_POWERCAP_D2SUPP (1<<26)
# define NVREG_POWERCAP_D1SUPP (1<<25)
NvRegPowerState = 0x26c,
# define NVREG_POWERSTATE_POWEREDUP 0x8000
# define NVREG_POWERSTATE_VALID 0x0100
# define NVREG_POWERSTATE_MASK 0x0003
# define NVREG_POWERSTATE_D0 0x0000
# define NVREG_POWERSTATE_D1 0x0001
# define NVREG_POWERSTATE_D2 0x0002
# define NVREG_POWERSTATE_D3 0x0003
};
char* EmuNVNet_GetRegisterName(xbaddr addr)
{
switch (addr) {
case NvRegIrqStatus: return "NvRegIrqStatus";
case NvRegIrqMask: return "NvRegIrqMask";
case NvRegUnknownSetupReg6: return "NvRegUnknownSetupReg6";
case NvRegPollingInterval: return "NvRegPollingInterval";
case NvRegMisc1: return "NvRegMisc1";
case NvRegTransmitterControl: return "NvRegTransmitterControl";
case NvRegTransmitterStatus: return "NvRegTransmitterStatus";
case NvRegPacketFilterFlags: return "NvRegPacketFilterFlags";
case NvRegOffloadConfig: return "NvRegOffloadConfig";
case NvRegReceiverControl: return "NvRegReceiverControl";
case NvRegReceiverStatus: return "NvRegReceiverStatus";
case NvRegRandomSeed: return "NvRegRandomSeed";
case NvRegUnknownSetupReg1: return "NvRegUnknownSetupReg1";
case NvRegUnknownSetupReg2: return "NvRegUnknownSetupReg2";
case NvRegMacAddrA: return "NvRegMacAddrA";
case NvRegMacAddrB: return "NvRegMacAddrB";
case NvRegMulticastAddrA: return "NvRegMulticastAddrA";
case NvRegMulticastAddrB: return "NvRegMulticastAddrB";
case NvRegMulticastMaskA: return "NvRegMulticastMaskA";
case NvRegMulticastMaskB: return "NvRegMulticastMaskB";
case NvRegTxRingPhysAddr: return "NvRegTxRingPhysAddr";
case NvRegRxRingPhysAddr: return "NvRegRxRingPhysAddr";
case NvRegRingSizes: return "NvRegRingSizes";
case NvRegUnknownTransmitterReg: return "NvRegUnknownTransmitterReg";
case NvRegLinkSpeed: return "NvRegLinkSpeed";
case NvRegUnknownSetupReg5: return "NvRegUnknownSetupReg5";
case NvRegUnknownSetupReg3: return "NvRegUnknownSetupReg3";
case NvRegUnknownSetupReg8: return "NvRegUnknownSetupReg8";
case NvRegUnknownSetupReg7: return "NvRegUnknownSetupReg7";
case NvRegTxRxControl: return "NvRegTxRxControl";
case NvRegMIIStatus: return "NvRegMIIStatus";
case NvRegUnknownSetupReg4: return "NvRegUnknownSetupReg4";
case NvRegAdapterControl: return "NvRegAdapterControl";
case NvRegMIISpeed: return "NvRegMIISpeed";
case NvRegMIIControl: return "NvRegMIIControl";
case NvRegMIIData: return "NvRegMIIData";
case NvRegWakeUpFlags: return "NvRegWakeUpFlags";
case NvRegPatternCRC: return "NvRegPatternCRC";
case NvRegPatternMask: return "NvRegPatternMask";
case NvRegPowerCap: return "NvRegPowerCap";
case NvRegPowerState: return "NvRegPowerState";
default: return "Unknown";
}
}
uint8_t NVNetRegs[NVNET_SIZE];
uint32_t EmuNVNet_GetRegister(xbaddr addr, unsigned int size)
{
switch (size) {
case sizeof(uint32_t) :
return ((uint32_t *)NVNetRegs)[addr >> 2];
case sizeof(uint16_t) :
return ((uint16_t *)NVNetRegs)[addr >> 1];
case sizeof(uint8_t) :
return NVNetRegs[addr];
}
return 0;
}
void EmuNVNet_SetRegister(xbaddr addr, uint32_t value, unsigned int size)
{
switch (size) {
case sizeof(uint32_t) :
((uint32_t *)NVNetRegs)[addr >> 2] = value;
break;
case sizeof(uint16_t) :
((uint16_t *)NVNetRegs)[addr >> 1] = (uint16_t)value;
break;
case sizeof(uint8_t) :
NVNetRegs[addr] = (uint8_t)value;
break;
}
}
uint32_t EmuNVNet_Read(xbaddr addr, int size)
{
DbgPrintf("EmuNVNet_Read%d: %s (0x%08X)\n", size, EmuNVNet_GetRegisterName(addr), addr);
return EmuNVNet_GetRegister(addr,size);
}
void EmuNVNet_Write(xbaddr addr, uint32_t value, int size)
{
DbgPrintf("EmuNVNet_Write%d: %s (0x%08X) = 0x%08X\n", size, EmuNVNet_GetRegisterName(addr), addr, value);
return EmuNVNet_SetRegister(addr, value, size);
}

43
src/CxbxKrnl/EmuNVNet.h Normal file
View File

@ -0,0 +1,43 @@
// ******************************************************************
// *
// * .,-::::: .,:: .::::::::. .,:: .:
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
// * $$$ Y$$$P $$""""Y$$ Y$$$P
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
// *
// * Cxbx->Win32->CxbxKrnl->EmuNVNet.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) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * (c) 2017 Luke Usher <luke.usher@outlook.com>
// * All rights reserved
// *
// ******************************************************************
#ifndef EMUNVNET_H
#define EMUNVNET_H
#define NVNET_ADDR 0xFEF00000
#define NVNET_SIZE 0x00000400
uint32_t EmuNVNet_Read(xbaddr addr, int size);
void EmuNVNet_Write(xbaddr addr, uint32_t value, int size);
#endif

View File

@ -49,6 +49,7 @@
#include "Emu.h" #include "Emu.h"
#include "EmuX86.h" #include "EmuX86.h"
#include "EmuNV2A.h" #include "EmuNV2A.h"
#include "EmuNVNet.h"
#include "HLEIntercept.h" // for bLLE_GPU #include "HLEIntercept.h" // for bLLE_GPU
#include <assert.h> #include <assert.h>
@ -145,8 +146,10 @@ uint32_t EmuX86_Read32Aligned(xbaddr addr)
} }
// Access NV2A regardless weither HLE is disabled or not // Access NV2A regardless weither HLE is disabled or not
value = EmuNV2A_Read32(addr - NV2A_ADDR); value = EmuNV2A_Read(addr - NV2A_ADDR, 32);
// Note : EmuNV2A_Read32 does it's own logging // Note : EmuNV2A_Read32 does it's own logging
} if (addr >= NVNET_ADDR && addr < NVNET_ADDR + NVNET_SIZE) {
value = EmuNVNet_Read(addr - NVNET_ADDR, 32);
} else { } else {
if (g_bEmuException) { if (g_bEmuException) {
EmuWarning("EmuX86_Read32Aligned(0x%08X) [Unknown address]", addr); EmuWarning("EmuX86_Read32Aligned(0x%08X) [Unknown address]", addr);
@ -177,29 +180,60 @@ uint32_t EmuX86_Read32(xbaddr addr)
uint16_t EmuX86_Read16(xbaddr addr) uint16_t EmuX86_Read16(xbaddr addr)
{ {
DbgPrintf("EmuX86_Read16(0x%08X) Forwarding to EmuX86_Read32Aligned...\n", addr); uint16_t value;
int shift = (addr & 3) * 8; if (addr >= NV2A_ADDR && addr < NV2A_ADDR + NV2A_SIZE) {
xbaddr aligned_addr = addr & ~3; if (!bLLE_GPU) {
uint16_t value = (uint16_t)(EmuX86_Read32Aligned(aligned_addr) >> shift); EmuWarning("EmuX86_Read32Aligned(0x%08X) Unexpected NV2A access, missing a HLE patch. " \
"Please notify https://github.com/Cxbx-Reloaded/Cxbx-Reloaded which title raised this!", addr);
}
// Must the second byte be retrieved from the next DWORD? // Access NV2A regardless weither HLE is disabled or not
if ((addr & 3) == 3) value = EmuNV2A_Read(addr - NV2A_ADDR, 16);
value |= (uint16_t)((EmuX86_Read32Aligned(aligned_addr + 4) & 0xff) << 8); // Note : EmuNV2A_Read32 does it's own logging
} else if (addr >= NVNET_ADDR && addr < NVNET_ADDR + NVNET_SIZE) {
value = EmuNVNet_Read(addr - NVNET_ADDR, 16);
} else {
if (g_bEmuException) {
EmuWarning("EmuX86_Read16(0x%08X) [Unknown address]", addr);
value = 0;
} else {
// Outside EmuException, pass the memory-access through to normal memory :
value = EmuX86_Mem_Read16(addr);
}
DbgPrintf("EmuX86_Read16(0x%08X) = 0x%04X\n", addr, value);
}
DbgPrintf("EmuX86_Read16(0x%08X) = 0x%04X\n", addr, value);
return value; return value;
} }
uint8_t EmuX86_Read8(xbaddr addr) uint8_t EmuX86_Read8(xbaddr addr)
{ {
DbgPrintf("EmuX86_Read8(0x%08X) Forwarding to EmuX86_Read32Aligned...\n", addr); uint8_t value;
int shift = (addr & 3) * 8; if (addr >= NV2A_ADDR && addr < NV2A_ADDR + NV2A_SIZE) {
xbaddr aligned_addr = addr & ~3; if (!bLLE_GPU) {
uint8_t value = (uint8_t)(EmuX86_Read32Aligned(aligned_addr) >> shift); EmuWarning("EmuX86_Read32Aligned(0x%08X) Unexpected NV2A access, missing a HLE patch. " \
"Please notify https://github.com/Cxbx-Reloaded/Cxbx-Reloaded which title raised this!", addr);
}
// Access NV2A regardless weither HLE is disabled or not
value = EmuNV2A_Read(addr - NV2A_ADDR, 8);
// Note : EmuNV2A_Read32 does it's own logging
} else if (addr >= NVNET_ADDR && addr < NVNET_ADDR + NVNET_SIZE) {
value = EmuNVNet_Read(addr - NVNET_ADDR, 8);
} else {
if (g_bEmuException) {
EmuWarning("EmuX86_Read8(0x%08X) [Unknown address]", addr);
value = 0;
}
else {
// Outside EmuException, pass the memory-access through to normal memory :
value = EmuX86_Mem_Read8(addr);
}
DbgPrintf("EmuX86_Read8(0x%08X) = 0x%02X\n", addr, value);
}
DbgPrintf("EmuX86_Read8(0x%08X) = 0x%02X\n", addr, value);
return value; return value;
} }
@ -214,11 +248,16 @@ void EmuX86_Write32Aligned(xbaddr addr, uint32_t value)
} }
// Access NV2A regardless weither HLE is disabled or not // Access NV2A regardless weither HLE is disabled or not
EmuNV2A_Write32(addr - NV2A_ADDR, value); EmuNV2A_Write(addr - NV2A_ADDR, value, 32);
// Note : EmuNV2A_Write32 does it's own logging // Note : EmuNV2A_Write32 does it's own logging
return; return;
} }
if (addr >= NVNET_ADDR && addr < NVNET_ADDR + NVNET_SIZE) {
EmuNVNet_Write(addr - NVNET_ADDR, value, 32);
return;
}
if (g_bEmuException) { if (g_bEmuException) {
EmuWarning("EmuX86_Write32Aligned(0x%08X, 0x%08X) [Unknown address]", addr, value); EmuWarning("EmuX86_Write32Aligned(0x%08X, 0x%08X) [Unknown address]", addr, value);
return; return;
@ -240,30 +279,61 @@ void EmuX86_Write32(xbaddr addr, uint32_t value)
void EmuX86_Write16(xbaddr addr, uint16_t value) void EmuX86_Write16(xbaddr addr, uint16_t value)
{ {
DbgPrintf("EmuX86_Write16(0x%08X, 0x%04X) Forwarding to EmuX86_Read32Aligned+EmuX86_Write32Aligned\n", addr, value); if (addr >= NV2A_ADDR && addr < NV2A_ADDR + NV2A_SIZE) {
if (!bLLE_GPU) {
EmuWarning("EmuX86_Write32Aligned(0x%08X, 0x%08X) Unexpected NV2A access, missing a HLE patch. " \
"Please notify https://github.com/Cxbx-Reloaded/Cxbx-Reloaded which title raised this!", addr);
}
assert((addr & 1) == 0); // Access NV2A regardless weither HLE is disabled or not
EmuNV2A_Write(addr - NV2A_ADDR, value, 16);
// Note : EmuNV2A_Write32 does it's own logging
return;
}
int shift = (addr & 2) * 16; if (addr >= NVNET_ADDR && addr < NVNET_ADDR + NVNET_SIZE) {
xbaddr aligned_addr = addr & ~3; EmuNVNet_Write(addr - NVNET_ADDR, value, 16);
uint32_t aligned_value = EmuX86_Read32Aligned(aligned_addr); return;
uint32_t mask = 0xFFFF << shift; }
// TODO : Must the second byte be written to the next DWORD? if (g_bEmuException) {
EmuWarning("EmuX86_Write16(0x%08X, 0x%04X) [Unknown address]", addr, value);
return;
}
EmuX86_Write32Aligned(aligned_addr, (aligned_value & ~mask) | (value << shift)); // Outside EmuException, pass the memory-access through to normal memory :
DbgPrintf("EmuX86_Write16(0x%08X, 0x%04X)\n", addr, value);
EmuX86_Mem_Write16(addr, value);
} }
void EmuX86_Write8(xbaddr addr, uint8_t value) void EmuX86_Write8(xbaddr addr, uint8_t value)
{ {
DbgPrintf("EmuX86_Write8(0x%08X, 0x%02X) Forwarding to EmuX86_Read32Aligned+EmuX86_Write32Aligned\n", addr, value);
int shift = (addr & 3) * 8; if (addr >= NV2A_ADDR && addr < NV2A_ADDR + NV2A_SIZE) {
xbaddr aligned_addr = addr & ~3; if (!bLLE_GPU) {
uint32_t aligned_value = EmuX86_Read32Aligned(aligned_addr); EmuWarning("EmuX86_Write32Aligned(0x%08X, 0x%08X) Unexpected NV2A access, missing a HLE patch. " \
uint32_t mask = 0xFF << shift; "Please notify https://github.com/Cxbx-Reloaded/Cxbx-Reloaded which title raised this!", addr);
}
EmuX86_Write32Aligned(aligned_addr, (aligned_value & ~mask) | (value << shift)); // Access NV2A regardless weither HLE is disabled or not
EmuNV2A_Write(addr - NV2A_ADDR, value, 8);
// Note : EmuNV2A_Write32 does it's own logging
return;
}
if (addr >= NVNET_ADDR && addr < NVNET_ADDR + NVNET_SIZE) {
EmuNVNet_Write(addr - NVNET_ADDR, value, 8);
return;
}
if (g_bEmuException) {
EmuWarning("EmuX86_Write8(0x%08X, 0x%02X) [Unknown address]", addr, value);
return;
}
// Outside EmuException, pass the memory-access through to normal memory :
DbgPrintf("EmuX86_Write8(0x%08X, 0x%02X)\n", addr, value);
EmuX86_Mem_Write8(addr, value);
} }
int ContextRecordOffsetByRegisterType[/*_RegisterType*/R_DR7 + 1] = { 0 }; int ContextRecordOffsetByRegisterType[/*_RegisterType*/R_DR7 + 1] = { 0 };
@ -667,6 +737,121 @@ inline void EmuX86_SetFlag(LPEXCEPTION_POINTERS e, int flag, int value)
e->ContextRecord->EFlags ^= (-value ^ e->ContextRecord->EFlags) & (1 << flag); e->ContextRecord->EFlags ^= (-value ^ e->ContextRecord->EFlags) & (1 << flag);
} }
bool EmuX86_Opcode_AND(LPEXCEPTION_POINTERS e, _DInst& info)
{
// Read value from Source and Destination
uint32_t src = 0;
if (!EmuX86_Operand_Read(e, info, 1, &src))
return false;
uint32_t dest = 0;
if (!EmuX86_Operand_Read(e, info, 0, &dest))
return false;
// AND Destination with src
dest &= src;
// Write back the result
if (!EmuX86_Operand_Write(e, info, 0, dest))
return false;
// OF/CF are cleared
// SF, ZF, and PF are set according to the result
// AF is undefined, so has been left out
EmuX86_SetFlag(e, EMUX86_EFLAG_CF, 0);
EmuX86_SetFlag(e, EMUX86_EFLAG_OF, 0);
EmuX86_SetFlag(e, EMUX86_EFLAG_SF, dest >> 31);
EmuX86_SetFlag(e, EMUX86_EFLAG_ZF, dest == 0 ? 1 : 0);
// Set Parity flag, based on "Compute parity in parallel" method from
// http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel
uint32_t v = 255 & dest;
v ^= v >> 4;
v &= 0xf;
EmuX86_SetFlag(e, EMUX86_EFLAG_PF, (0x6996 >> v) & 1);
return true;
}
bool EmuX86_Opcode_CMPXCHG(LPEXCEPTION_POINTERS e, _DInst& info)
{
// Read value from Source and Destination
uint32_t src = 0;
if (!EmuX86_Operand_Read(e, info, 1, &src))
return false;
uint32_t dest = 0;
if (!EmuX86_Operand_Read(e, info, 0, &dest))
return false;
if (src == dest) {
EmuX86_SetFlag(e, EMUX86_EFLAG_ZF, 1);
// Write the source value to the destination operand
if (!EmuX86_Operand_Write(e, info, 0, src)) {
return false;
}
} else {
EmuX86_SetFlag(e, EMUX86_EFLAG_ZF, 0);
// Write the dest value to the source operand
if (!EmuX86_Operand_Write(e, info, 1, dest)) {
return false;
}
}
// Perform arithmatic operation for flag calculation
uint64_t result = (uint64_t)dest - (uint64_t)src;
// CF, PF, AF, SF, and OF are set according to the result
EmuX86_SetFlag(e, EMUX86_EFLAG_CF, (result >> 32) > 0);
EmuX86_SetFlag(e, EMUX86_EFLAG_OF, (result >> 31) != (dest >> 31));
// TODO: Figure out how to calculate this EmuX86_SetFlag(e, EMUX86_EFLAG_AF, 0);
EmuX86_SetFlag(e, EMUX86_EFLAG_SF, (uint32_t)(result >> 31));
// Set Parity flag, based on "Compute parity in parallel" method from
// http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel
uint32_t v = 255 & result;
v ^= v >> 4;
v &= 0xf;
EmuX86_SetFlag(e, EMUX86_EFLAG_PF, (0x6996 >> v) & 1);
return true;
}
bool EmuX86_Opcode_OR(LPEXCEPTION_POINTERS e, _DInst& info)
{
// Read value from Source and Destination
uint32_t src = 0;
if (!EmuX86_Operand_Read(e, info, 1, &src))
return false;
uint32_t dest = 0;
if (!EmuX86_Operand_Read(e, info, 0, &dest))
return false;
// OR Destination with src
dest |= src;
// Write back the result
if (!EmuX86_Operand_Write(e, info, 0, dest))
return false;
// OF/CF are cleared
// SF, ZF, and PF are set according to the result
// AF is undefined, so has been left out
EmuX86_SetFlag(e, EMUX86_EFLAG_CF, 0);
EmuX86_SetFlag(e, EMUX86_EFLAG_OF, 0);
EmuX86_SetFlag(e, EMUX86_EFLAG_SF, dest >> 31);
EmuX86_SetFlag(e, EMUX86_EFLAG_ZF, dest == 0 ? 1 : 0);
// Set Parity flag, based on "Compute parity in parallel" method from
// http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel
uint32_t v = 255 & dest;
v ^= v >> 4;
v &= 0xf;
EmuX86_SetFlag(e, EMUX86_EFLAG_PF, (0x6996 >> v) & 1);
return true;
}
bool EmuX86_Opcode_TEST(LPEXCEPTION_POINTERS e, _DInst& info) bool EmuX86_Opcode_TEST(LPEXCEPTION_POINTERS e, _DInst& info)
{ {
// TEST reads first value : // TEST reads first value :
@ -819,6 +1004,14 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e)
break; break;
goto unimplemented_opcode; goto unimplemented_opcode;
case I_AND:
if (EmuX86_Opcode_AND(e, info))
break;
goto unimplemented_opcode;
case I_CMPXCHG:
if (EmuX86_Opcode_CMPXCHG(e, info))
break;
goto unimplemented_opcode;
case I_CPUID: case I_CPUID:
EmuX86_Opcode_CPUID(e, info); EmuX86_Opcode_CPUID(e, info);
break; break;
@ -835,6 +1028,10 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e)
break; break;
goto unimplemented_opcode; goto unimplemented_opcode;
case I_OR:
if (EmuX86_Opcode_OR(e, info))
break;
goto unimplemented_opcode;
case I_OUT: case I_OUT:
if (EmuX86_Opcode_OUT(e, info)) if (EmuX86_Opcode_OUT(e, info))
break; break;

View File

@ -92,21 +92,6 @@ INT WINAPI XTL::EMUPATCH(XNetStartup)
RETURN(ret); RETURN(ret);
} }
// ******************************************************************
// * patch: XNetGetEthernetLinkStatus
// ******************************************************************
DWORD WINAPI XTL::EMUPATCH(XNetGetEthernetLinkStatus)()
{
FUNC_EXPORTS
LOG_FUNC();
// for now, no ethernet connection is available
DWORD ret = XNET_ETHERNET_LINK_ACTIVE | XNET_ETHERNET_LINK_100MBPS;
RETURN(ret);
}
// ****************************************************************** // ******************************************************************
// * patch: This::Emusocket // * patch: This::Emusocket
// ****************************************************************** // ******************************************************************

View File

@ -371,6 +371,8 @@ OOVPATable DSound_5233[] = {
REGISTER_OOVPA(CDirectSoundBuffer_SetMixBins, 4134, XREF), REGISTER_OOVPA(CDirectSoundBuffer_SetMixBins, 4134, XREF),
REGISTER_OOVPA(IDirectSoundBuffer_SetMixBins, 4134, PATCH), REGISTER_OOVPA(IDirectSoundBuffer_SetMixBins, 4134, PATCH),
REGISTER_OOVPA(CDirectSoundStream_SetMixBins, 5233, PATCH), REGISTER_OOVPA(CDirectSoundStream_SetMixBins, 5233, PATCH),
REGISTER_OOVPA(CDirectSound_SetMixBinHeadroom, 4627, XREF),
REGISTER_OOVPA(IDirectSound_SetMixBinHeadroom, 4627, PATCH),
REGISTER_OOVPA(CDirectSound_SetPositionA, 4627, XREF), REGISTER_OOVPA(CDirectSound_SetPositionA, 4627, XREF),
REGISTER_OOVPA(IDirectSound_SetPosition, 3936, PATCH), REGISTER_OOVPA(IDirectSound_SetPosition, 3936, PATCH),
REGISTER_OOVPA(DirectSoundCreateBuffer, 4627, PATCH), REGISTER_OOVPA(DirectSoundCreateBuffer, 4627, PATCH),
@ -449,6 +451,8 @@ OOVPATable DSound_5233[] = {
REGISTER_OOVPA(CDirectSoundVoice_SetDistanceFactor, 4134, XREF), REGISTER_OOVPA(CDirectSoundVoice_SetDistanceFactor, 4134, XREF),
REGISTER_OOVPA(CDirectSoundBuffer_SetDistanceFactor, 4134, XREF), REGISTER_OOVPA(CDirectSoundBuffer_SetDistanceFactor, 4134, XREF),
REGISTER_OOVPA(IDirectSoundBuffer_SetDistanceFactor, 4134, PATCH), REGISTER_OOVPA(IDirectSoundBuffer_SetDistanceFactor, 4134, PATCH),
REGISTER_OOVPA(CDirectSoundBuffer_SetNotificationPositions, 4627, XREF),
REGISTER_OOVPA(IDirectSoundBuffer_SetNotificationPositions, 4627, PATCH)
}; };
// ****************************************************************** // ******************************************************************