Fix merge-conflicts while merging branch upstream 'master' into SmallStuff

This commit is contained in:
PatrickvL 2018-01-15 11:44:49 +01:00 committed by patrickvl
commit c70f678470
67 changed files with 4057 additions and 1321 deletions

View File

@ -17,7 +17,7 @@ Cxbx-Reloaded is early in development and still pretty unstable, so don't expect
* Visual C++ 2015 and 2017 redistributables may be required. Download them [here](https://support.microsoft.com/en-gb/help/2977003/the-latest-supported-visual-c-downloads). * Visual C++ 2015 and 2017 redistributables may be required. Download them [here](https://support.microsoft.com/en-gb/help/2977003/the-latest-supported-visual-c-downloads).
## Automated Builds ## Automated Builds
Cxbx-Reloaded is not yet ready for general release, but the latest development build can always be downloaded from our [AppVeyor](https://ci.appveyor.com/project/SoullessSentinel/cxbx-reloaded/branch/master) (navigate to Configuration: Release => Artifacts => export\Release.zip). Cxbx-Reloaded is not yet ready for general release, but the latest development build can always be downloaded from our [AppVeyor](https://ci.appveyor.com/project/SoullessSentinel/cxbx-reloaded/branch/master) (navigate to Configuration: Release => Artifacts => export\Release.zip). Also, a history of AppVeyor builds is [available here](https://ci.appveyor.com/project/SoullessSentinel/cxbx-reloaded/history).
## Compatibility ## Compatibility
Cxbx-Reloaded has a separate [compatibility list](https://github.com/Cxbx-Reloaded/game-compatibility/issues). If you have something to report on a title, please create or update the issue for it over there. (Please, read the [Read-me file](https://github.com/Cxbx-Reloaded/game-compatibility/blob/master/README.md) first!) Cxbx-Reloaded has a separate [compatibility list](https://github.com/Cxbx-Reloaded/game-compatibility/issues). If you have something to report on a title, please create or update the issue for it over there. (Please, read the [Read-me file](https://github.com/Cxbx-Reloaded/game-compatibility/blob/master/README.md) first!)

View File

@ -171,6 +171,8 @@
<BaseAddress>0x10000</BaseAddress> <BaseAddress>0x10000</BaseAddress>
<FixedBaseAddress>true</FixedBaseAddress> <FixedBaseAddress>true</FixedBaseAddress>
<LargeAddressAware>true</LargeAddressAware> <LargeAddressAware>true</LargeAddressAware>
<StackReserveSize>65536</StackReserveSize>
<StackCommitSize>65536</StackCommitSize>
</Link> </Link>
<Bscmake> <Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
@ -188,9 +190,10 @@
</PreBuildEvent> </PreBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\src\Common\Win32\Threads.h" />
<ClInclude Include="..\..\src\Common\Win32\XBAudio.h" /> <ClInclude Include="..\..\src\Common\Win32\XBAudio.h" />
<ClInclude Include="..\..\src\Common\XADPCM.h" /> <ClInclude Include="..\..\src\Common\XADPCM.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EEPROMDevice.h" /> <ClInclude Include="..\..\src\Common\XbePrinter.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuD3D8Logging.h" /> <ClInclude Include="..\..\src\CxbxKrnl\EmuD3D8Logging.h" />
<ClInclude Include="..\..\import\stb\stb_image.h" /> <ClInclude Include="..\..\import\stb\stb_image.h" />
<ClInclude Include="..\..\src\Common\EmuEEPROM.h" /> <ClInclude Include="..\..\src\Common\EmuEEPROM.h" />
@ -217,8 +220,6 @@
<ClInclude Include="..\..\src\CxbxKrnl\EmuFS.h" /> <ClInclude Include="..\..\src\CxbxKrnl\EmuFS.h" />
<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\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" />
@ -230,20 +231,13 @@
<ClInclude Include="..\..\src\CxbxKrnl\HLEDataBase.h" /> <ClInclude Include="..\..\src\CxbxKrnl\HLEDataBase.h" />
<ClInclude Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.OOVPA.h" /> <ClInclude Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.OOVPA.h" />
<ClInclude Include="..\..\src\CxbxKrnl\HLEIntercept.h" /> <ClInclude Include="..\..\src\CxbxKrnl\HLEIntercept.h" />
<ClInclude Include="..\..\src\CxbxKrnl\LED.h" />
<ClInclude Include="..\..\src\CxbxKrnl\LibRc4.h" /> <ClInclude Include="..\..\src\CxbxKrnl\LibRc4.h" />
<ClInclude Include="..\..\src\CxbxKrnl\nv2a_int.h" />
<ClInclude Include="..\..\src\CxbxKrnl\OOVPA.h" /> <ClInclude Include="..\..\src\CxbxKrnl\OOVPA.h" />
<ClInclude Include="..\..\src\CxbxKrnl\PhysicalMemory.h" /> <ClInclude Include="..\..\src\CxbxKrnl\PhysicalMemory.h" />
<ClInclude Include="..\..\src\CxbxKrnl\PCIBus.h" />
<ClInclude Include="..\..\src\CxbxKrnl\PCIDevice.h" /> <ClInclude Include="..\..\src\CxbxKrnl\PCIDevice.h" />
<ClInclude Include="..\..\src\CxbxKrnl\SMCDevice.h" />
<ClInclude Include="..\..\src\CxbxKrnl\ReservedMemory.h" /> <ClInclude Include="..\..\src\CxbxKrnl\ReservedMemory.h" />
<ClInclude Include="..\..\src\CxbxKrnl\ResourceTracker.h" /> <ClInclude Include="..\..\src\CxbxKrnl\ResourceTracker.h" />
<ClInclude Include="..\..\src\CxbxKrnl\VMManager.h" /> <ClInclude Include="..\..\src\CxbxKrnl\VMManager.h" />
<ClInclude Include="..\..\src\CxbxKrnl\SMBus.h" />
<ClInclude Include="..\..\src\CxbxKrnl\SMDevice.h" />
<ClInclude Include="..\..\src\CxbxKrnl\Xbox.h" />
<ClInclude Include="..\..\src\CxbxVersion.h" /> <ClInclude Include="..\..\src\CxbxVersion.h" />
<ClInclude Include="..\..\src\Cxbx\DlgAbout.h" /> <ClInclude Include="..\..\src\Cxbx\DlgAbout.h" />
<ClInclude Include="..\..\src\Cxbx\DlgAudioConfig.h" /> <ClInclude Include="..\..\src\Cxbx\DlgAudioConfig.h" />
@ -259,6 +253,20 @@
<ClInclude Include="..\..\src\Common\Win32\XBController.h" /> <ClInclude Include="..\..\src\Common\Win32\XBController.h" />
<ClInclude Include="..\..\src\Common\Xbe.h" /> <ClInclude Include="..\..\src\Common\Xbe.h" />
<ClInclude Include="..\..\src\Common\Win32\XBVideo.h" /> <ClInclude Include="..\..\src\Common\Win32\XBVideo.h" />
<ClInclude Include="..\..\src\devices\EEPROMDevice.h" />
<ClInclude Include="..\..\src\devices\EmuNVNet.h" />
<ClInclude Include="..\..\src\devices\LED.h" />
<ClInclude Include="..\..\src\devices\MCPXDevice.h" />
<ClInclude Include="..\..\src\devices\PCIBus.h" />
<ClInclude Include="..\..\src\devices\PCIDevice.h" />
<ClInclude Include="..\..\src\devices\SMBus.h" />
<ClInclude Include="..\..\src\devices\SMCDevice.h" />
<ClInclude Include="..\..\src\devices\SMDevice.h" />
<ClInclude Include="..\..\src\devices\video\EmuNV2A.h" />
<ClInclude Include="..\..\src\devices\video\nv2a.h" />
<ClInclude Include="..\..\src\devices\video\nv2a_int.h" />
<ClInclude Include="..\..\src\devices\video\vga.h" />
<ClInclude Include="..\..\src\devices\Xbox.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\CONTRIBUTORS" /> <None Include="..\..\CONTRIBUTORS" />
@ -285,7 +293,6 @@
<None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5344.inl" /> <None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5344.inl" />
<None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5455.inl" /> <None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5455.inl" />
<None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5558.inl" /> <None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5558.inl" />
<None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5659.inl" />
<None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5788.inl" /> <None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5788.inl" />
<None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5849.inl" /> <None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5849.inl" />
<None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.OOVPA.inl" /> <None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.OOVPA.inl" />
@ -358,8 +365,9 @@
</ResourceCompile> </ResourceCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\Common\Win32\Threads.cpp" />
<ClCompile Include="..\..\src\Common\Win32\XBAudio.cpp" /> <ClCompile Include="..\..\src\Common\Win32\XBAudio.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\EEPROMDevice.cpp" /> <ClCompile Include="..\..\src\Common\XbePrinter.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\EmuD3D8Logging.cpp" /> <ClCompile Include="..\..\src\CxbxKrnl\EmuD3D8Logging.cpp" />
<ClCompile Include="..\..\src\Common\EmuEEPROM.cpp" /> <ClCompile Include="..\..\src\Common\EmuEEPROM.cpp" />
<ClCompile Include="..\..\src\Common\Logging.cpp" /> <ClCompile Include="..\..\src\Common\Logging.cpp" />
@ -479,8 +487,6 @@
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<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\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" />
@ -523,18 +529,12 @@
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\LibRc4.cpp" /> <ClCompile Include="..\..\src\CxbxKrnl\LibRc4.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\PhysicalMemory.cpp" /> <ClCompile Include="..\..\src\CxbxKrnl\PhysicalMemory.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\PCIBus.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\PCIDevice.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\SMCDevice.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\ResourceTracker.cpp"> <ClCompile Include="..\..\src\CxbxKrnl\ResourceTracker.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\SMBus.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\SMDevice.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\Xbox.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\VMManager.cpp" /> <ClCompile Include="..\..\src\CxbxKrnl\VMManager.cpp" />
<ClCompile Include="..\..\src\Cxbx\DlgAbout.cpp" /> <ClCompile Include="..\..\src\Cxbx\DlgAbout.cpp" />
<ClCompile Include="..\..\src\Cxbx\DlgAudioConfig.cpp" /> <ClCompile Include="..\..\src\Cxbx\DlgAudioConfig.cpp" />
@ -598,6 +598,17 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\devices\EEPROMDevice.cpp" />
<ClCompile Include="..\..\src\devices\EmuNVNet.cpp" />
<ClCompile Include="..\..\src\devices\MCPXDevice.cpp" />
<ClCompile Include="..\..\src\devices\PCIBus.cpp" />
<ClCompile Include="..\..\src\devices\PCIDevice.cpp" />
<ClCompile Include="..\..\src\devices\SMBus.cpp" />
<ClCompile Include="..\..\src\devices\SMCDevice.cpp" />
<ClCompile Include="..\..\src\devices\SMDevice.cpp" />
<ClCompile Include="..\..\src\devices\video\EmuNV2A.cpp" />
<ClCompile Include="..\..\src\devices\video\nv2a.cpp" />
<ClCompile Include="..\..\src\devices\Xbox.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="subhook.vcxproj"> <ProjectReference Include="subhook.vcxproj">

View File

@ -196,34 +196,46 @@
<ClCompile Include="..\..\src\CxbxKrnl\VMManager.cpp"> <ClCompile Include="..\..\src\CxbxKrnl\VMManager.cpp">
<Filter>Emulator</Filter> <Filter>Emulator</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\EmuNV2A.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\EmuNVNet.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\PCIBus.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\PCIDevice.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\SMBus.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\SMDevice.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\EEPROMDevice.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\SMCDevice.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\EmuX86.cpp"> <ClCompile Include="..\..\src\CxbxKrnl\EmuX86.cpp">
<Filter>Hardware</Filter> <Filter>Hardware</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\Xbox.cpp"> <ClCompile Include="..\..\src\devices\EEPROMDevice.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\devices\PCIBus.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\devices\PCIDevice.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\devices\SMBus.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\devices\SMCDevice.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\devices\SMDevice.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\devices\video\nv2a.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\devices\Xbox.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\devices\EmuNVNet.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\devices\video\EmuNV2A.cpp">
<Filter>Hardware</Filter>
</ClCompile>
<ClCompile Include="..\..\src\Common\XbePrinter.cpp">
<Filter>Shared</Filter>
</ClCompile>
<ClCompile Include="..\..\src\Common\Win32\Threads.cpp">
<Filter>Shared</Filter>
</ClCompile>
<ClCompile Include="..\..\src\devices\MCPXDevice.cpp">
<Filter>Hardware</Filter> <Filter>Hardware</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
@ -351,9 +363,6 @@
<ClInclude Include="..\..\src\Common\Logging.h"> <ClInclude Include="..\..\src\Common\Logging.h">
<Filter>Emulator</Filter> <Filter>Emulator</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\nv2a_int.h">
<Filter>Emulator</Filter>
</ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\OOVPA.h"> <ClInclude Include="..\..\src\CxbxKrnl\OOVPA.h">
<Filter>Emulator</Filter> <Filter>Emulator</Filter>
</ClInclude> </ClInclude>
@ -402,43 +411,64 @@
<ClInclude Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.OOVPA.h"> <ClInclude Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.OOVPA.h">
<Filter>HLEDatabase\D3D8</Filter> <Filter>HLEDatabase\D3D8</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\EmuNV2A.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\EmuNVNet.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\PCIBus.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\PCIDevice.h"> <ClInclude Include="..\..\src\CxbxKrnl\PCIDevice.h">
<Filter>Hardware</Filter> <Filter>Hardware</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\SMBus.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\SMDevice.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\EEPROMDevice.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\SMCDevice.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\PhysicalMemory.h"> <ClInclude Include="..\..\src\CxbxKrnl\PhysicalMemory.h">
<Filter>Emulator</Filter> <Filter>Emulator</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\VMManager.h"> <ClInclude Include="..\..\src\CxbxKrnl\VMManager.h">
<Filter>Emulator</Filter> <Filter>Emulator</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\LED.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\EmuX86.h"> <ClInclude Include="..\..\src\CxbxKrnl\EmuX86.h">
<Filter>Hardware</Filter> <Filter>Hardware</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\Xbox.h"> <ClInclude Include="..\..\src\devices\EEPROMDevice.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\devices\PCIBus.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\devices\PCIDevice.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\devices\SMBus.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\devices\SMCDevice.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\devices\SMDevice.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\devices\video\nv2a.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\devices\LED.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\devices\Xbox.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\devices\EmuNVNet.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\devices\video\EmuNV2A.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\devices\video\nv2a_int.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\devices\video\vga.h">
<Filter>Hardware</Filter>
</ClInclude>
<ClInclude Include="..\..\src\Common\XbePrinter.h">
<Filter>Shared</Filter>
</ClInclude>
<ClInclude Include="..\..\src\Common\Win32\Threads.h">
<Filter>Shared</Filter>
</ClInclude>
<ClInclude Include="..\..\src\devices\MCPXDevice.h">
<Filter>Hardware</Filter> <Filter>Hardware</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
@ -530,9 +560,6 @@
<None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5558.inl"> <None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5558.inl">
<Filter>HLEDatabase\D3D8</Filter> <Filter>HLEDatabase\D3D8</Filter>
</None> </None>
<None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5659.inl">
<Filter>HLEDatabase\D3D8</Filter>
</None>
<None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5788.inl"> <None Include="..\..\src\CxbxKrnl\HLEDataBase\D3D8.1.0.5788.inl">
<Filter>HLEDatabase\D3D8</Filter> <Filter>HLEDatabase\D3D8</Filter>
</None> </None>

View File

@ -84,7 +84,7 @@ typedef VOID (*PHAL_SHUTDOWN_NOTIFICATION)(
IN struct _HAL_SHUTDOWN_REGISTRATION *ShutdownRegistration IN struct _HAL_SHUTDOWN_REGISTRATION *ShutdownRegistration
); );
typedef struct { typedef struct _HAL_SHUTDOWN_REGISTRATION {
PHAL_SHUTDOWN_NOTIFICATION NotificationRoutine; PHAL_SHUTDOWN_NOTIFICATION NotificationRoutine;
LONG Priority; LONG Priority;
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;

View File

@ -400,6 +400,46 @@ typedef struct _LIST_ENTRY
} }
LIST_ENTRY, *PLIST_ENTRY; LIST_ENTRY, *PLIST_ENTRY;
// See the links below for the details about the kernel structure LIST_ENTRY and the related functions
// https://www.codeproject.com/Articles/800404/Understanding-LIST-ENTRY-Lists-and-Its-Importance
// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/singly-and-doubly-linked-lists
#define LIST_ENTRY_INITIALIZE_HEAD(ListHead) xboxkrnl::LIST_ENTRY ListHead = { &ListHead, &ListHead }
#define LIST_ENTRY_ACCESS_RECORD(address, type, field) \
((type*)((UCHAR*)(address) - (ULONG)(&((type*)0)->field)))
#define LIST_ENTRY_INSERT_HEAD(ListHead, Entry) {\
xboxkrnl::PLIST_ENTRY Flink;\
Flink = ListHead->Flink;\
(Entry)->Flink = Flink;\
(Entry)->Blink = ListHead;\
Flink->Blink = Entry;\
ListHead->Flink = Entry;\
}
#define LIST_ENTRY_INSERT_TAIL(ListHead, Entry) {\
xboxkrnl::PLIST_ENTRY Blink;\
Blink = ListHead->Blink;\
(Entry)->Flink = ListHead;\
(Entry)->Blink = Blink;\
Blink->Flink = Entry;\
ListHead->Blink = Entry;\
}
#define LIST_ENTRY_REMOVE(Entry) {\
xboxkrnl::PLIST_ENTRY ExFlink;\
xboxkrnl::PLIST_ENTRY ExBlink;\
ExFlink = (Entry)->Flink;\
ExBlink = (Entry)->Blink;\
ExFlink->Blink = ExBlink;\
ExBlink->Flink = ExFlink;\
}
#define LIST_ENTRY_REMOVE_AT_HEAD(ListHead) \
(ListHead)->Flink;\
LIST_ENTRY_REMOVE((ListHead)->Flink)
typedef struct _SINGLE_LIST_ENTRY { typedef struct _SINGLE_LIST_ENTRY {
struct _SINGLE_LIST_ENTRY *Next; struct _SINGLE_LIST_ENTRY *Next;
} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY, SLIST_ENTRY, *PSLIST_ENTRY; } SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY, SLIST_ENTRY, *PSLIST_ENTRY;
@ -1271,6 +1311,19 @@ typedef struct _LAUNCH_DATA_PAGE
} }
LAUNCH_DATA_PAGE, *PLAUNCH_DATA_PAGE; LAUNCH_DATA_PAGE, *PLAUNCH_DATA_PAGE;
// ******************************************************************
// * DASH_LAUNCH_DATA
// ******************************************************************
typedef struct _DASH_LAUNCH_DATA
{
DWORD dwReason;
DWORD dwContext;
DWORD dwParameter1;
DWORD dwParameter2;
BYTE Reserved[3072 - 16];
}
DASH_LAUNCH_DATA, *PDASH_LAUNCH_DATA;
// ****************************************************************** // ******************************************************************
// * DISPATCHER_HEADER // * DISPATCHER_HEADER
// ****************************************************************** // ******************************************************************
@ -2183,6 +2236,44 @@ typedef struct _XBOX_EEPROM
} }
XBOX_EEPROM; XBOX_EEPROM;
// ******************************************************************
// * XBOX_UEM_INFO
// ******************************************************************
typedef struct _XBOX_UEM_INFO
{
UCHAR ErrorCode;
UCHAR Reserved;
USHORT History;
}
XBOX_UEM_INFO;
// ******************************************************************
// * Xbox UEM (fatal error) codes
// ******************************************************************
#define FATAL_ERROR_NONE 0x00
#define FATAL_ERROR_CORE_DIGITAL 0x01
#define FATAL_ERROR_BAD_EEPROM 0x02
#define FATAL_ERROR_UNUSED1 0x03
#define FATAL_ERROR_BAD_RAM 0x04
#define FATAL_ERROR_HDD_NOT_LOCKED 0x05
#define FATAL_ERROR_HDD_CANNOT_UNLOCK 0x06
#define FATAL_ERROR_HDD_TIMEOUT 0x07
#define FATAL_ERROR_HDD_NOT_FOUND 0x08
#define FATAL_ERROR_HDD_BAD_CONFIG 0x09
#define FATAL_ERROR_DVD_TIMEOUT 0x0A
#define FATAL_ERROR_DVD_NOT_FOUND 0x0B
#define FATAL_ERROR_DVD_BAD_CONFIG 0x0C
#define FATAL_ERROR_XBE_DASH_GENERIC 0x0D
#define FATAL_ERROR_XBE_DASH_ERROR 0x0E
#define FATAL_ERROR_UNUSED2 0x0F
#define FATAL_ERROR_XBE_DASH_SETTINGS 0x10
#define FATAL_ERROR_UNUSED3 0x11
#define FATAL_ERROR_UNUSED4 0x12
#define FATAL_ERROR_UNUSED5 0x13
#define FATAL_ERROR_XBE_DASH_X2_PASS 0x14
#define FATAL_ERROR_REBOOT_ROUTINE 0x15
#define FATAL_ERROR_RESERVED 0xFF
// ****************************************************************** // ******************************************************************
// * TIME_FIELDS // * TIME_FIELDS
// ****************************************************************** // ******************************************************************

Binary file not shown.

Binary file not shown.

View File

@ -136,7 +136,7 @@ void EmuShared::Cleanup()
EmuShared::EmuShared() EmuShared::EmuShared()
{ {
Load(); Load();
m_bMultiXbe = false; m_bKeQuickReboot = false;
m_LaunchDataPAddress = NULL; m_LaunchDataPAddress = NULL;
} }

View File

@ -0,0 +1,76 @@
// ******************************************************************
// *
// * .,-::::: .,:: .::::::::. .,:: .:
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
// * $$$ Y$$$P $$""""Y$$ Y$$$P
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
// *
// * Cxbx->Win32->Threads.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>
// *
// * All rights reserved
// *
// ******************************************************************
#include <windows.h>
#include "Threads.h"
// Exception structure and method from:
// https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
void SetThreadName(DWORD dwThreadID, const char* szThreadName)
{
if (!IsDebuggerPresent())
return;
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = szThreadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
#pragma warning(push)
#pragma warning(disable: 6320 6322)
__try {
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
}
#pragma warning(pop)
}
void SetCurrentThreadName(const char* szThreadName)
{
SetThreadName(GetCurrentThreadId(), szThreadName);
}

View File

@ -1,5 +1,3 @@
// 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
// ****************************************************************** // ******************************************************************
// * // *
// * .,-::::: .,:: .::::::::. .,:: .: // * .,-::::: .,:: .::::::::. .,:: .:
@ -9,7 +7,7 @@
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, // * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, // * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
// * // *
// * src->CxbxKrnl->Xbox.h // * Cxbx->Win32->Threads.h
// * // *
// * This file is part of the Cxbx project. // * This file is part of the Cxbx project.
// * // *
@ -28,10 +26,12 @@
// * If not, write to the Free Software Foundation, Inc., // * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA. // * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// * // *
// * (c) 2017 Patrick van Logchem <pvanlogchem@gmail.com> // * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// * // *
// * All rights reserved // * All rights reserved
// * // *
// ******************************************************************#pragma once // ******************************************************************
extern void InitXboxHardware(); #pragma once
void SetCurrentThreadName(const char* szThreadName);

View File

@ -33,20 +33,28 @@
// * All rights reserved // * All rights reserved
// * // *
// ****************************************************************** // ******************************************************************
#define _XBOXKRNL_DEFEXTRN_
// prevent name collisions
namespace xboxkrnl
{
#include <xboxkrnl/xboxkrnl.h>
};
#include "Xbe.h" #include "Xbe.h"
#include "CxbxVersion.h" #include "CxbxUtil.h" // For RoundUp
#include "CxbxUtil.h" #include <experimental/filesystem> // filesystem related functions available on C++ 17
#include <locale> // For ctime
#include "devices\LED.h" // For LED::Sequence
#include "CxbxKrnl/CxbxKrnl.h" // For CxbxKrnlPrintUEM
#include "CxbxKrnl/EmuShared.h" // Include this to avoid including EmuXapi.h and EmuD3D8.h
namespace fs = std::experimental::filesystem;
#include <memory.h>
#include <clocale>
#include <cstdlib>
#include <cstring>
#include <ctime>
#define PAGE_SIZE 0x1000
// construct via Xbe file // construct via Xbe file
Xbe::Xbe(const char *x_szFilename) Xbe::Xbe(const char *x_szFilename, bool bFromGUI)
{ {
char szBuffer[MAX_PATH]; char szBuffer[MAX_PATH];
@ -59,8 +67,38 @@ Xbe::Xbe(const char *x_szFilename)
// verify Xbe file was opened successfully // verify Xbe file was opened successfully
if(XbeFile == 0) if(XbeFile == 0)
{ {
SetFatalError("Could not open Xbe file."); using namespace fs; // limit its scope inside here
return;
std::string XbeName = path(x_szFilename).filename().string(); // recover the xbe name
// NOTE: the check for the existence of the child window is necessary because the user could have previously loaded the dashboard,
// removed/changed the path and attempt to load it again from the recent list, which will crash CxbxInitWindow below
// Note that GetHwnd(), CxbxKrnl_hEmuParent and HalReturnToFirmware are all not suitable here for various reasons
if (XbeName.compare(std::string("xboxdash.xbe")) == 0 && !bFromGUI)
{
// The dashboard could not be found on partition2. This is a fatal error on the Xbox so we display the UEM. The
// error code is different if we have a launch data page
XTL::CxbxInitWindow(false);
ULONG FatalErrorCode = FATAL_ERROR_XBE_DASH_GENERIC;
if (xboxkrnl::LaunchDataPage && xboxkrnl::LaunchDataPage->Header.dwLaunchDataType == LDT_FROM_DASHBOARD)
{
xboxkrnl::PDASH_LAUNCH_DATA pLaunchDashboard = (xboxkrnl::PDASH_LAUNCH_DATA)&(xboxkrnl::LaunchDataPage->LaunchData[0]);
FatalErrorCode += pLaunchDashboard->dwReason;
}
SetLEDSequence(0xE1); // green, red, red, red
CxbxKrnlPrintUEM(FatalErrorCode); // won't return
// TODO: FATAL_ERROR_XBE_DASH_X2_PASS (requires DVD drive authentication emulation...)
}
else
{
// Report which xbe could not be found
SetFatalError(std::string("Could not open the Xbe file ") + XbeName);
return;
}
} }
printf("OK\n"); printf("OK\n");
@ -548,281 +586,6 @@ static char *BetterTime(uint32 x_timeDate)
return x_ctime; return x_ctime;
} }
// dump Xbe information to text file
void Xbe::DumpInformation(FILE *x_file)
{
if(HasError())
return;
fprintf(x_file, "XBE information generated by Cxbx-Reloaded (Version " _CXBX_VERSION ")\n");
fprintf(x_file, "\n");
fprintf(x_file, "Title identified as \"%s\"\n", m_szAsciiTitle);
fprintf(x_file, "\n");
fprintf(x_file, "Dumping XBE file header...\n");
fprintf(x_file, "\n");
fprintf(x_file, "Magic Number : XBEH\n");
// print digital signature
{
fprintf(x_file, "Digitial Signature : <Hex Dump>");
for(int y=0;y<16;y++)
{
fprintf(x_file, "\n ");
for(int x=0;x<16;x++)
fprintf(x_file, "%.02X", m_Header.pbDigitalSignature[y*16+x]);
}
fprintf(x_file, "\n </Hex Dump>\n");
}
fprintf(x_file, "Base Address : 0x%.08X\n", m_Header.dwBaseAddr);
fprintf(x_file, "Size of Headers : 0x%.08X\n", m_Header.dwSizeofHeaders);
fprintf(x_file, "Size of Image : 0x%.08X\n", m_Header.dwSizeofImage);
fprintf(x_file, "Size of Image Header : 0x%.08X\n", m_Header.dwSizeofImageHeader);
fprintf(x_file, "TimeDate Stamp : 0x%.08X (%s)\n", m_Header.dwTimeDate, BetterTime(m_Header.dwTimeDate));
fprintf(x_file, "Certificate Address : 0x%.08X\n", m_Header.dwCertificateAddr);
fprintf(x_file, "Number of Sections : 0x%.08X\n", m_Header.dwSections);
fprintf(x_file, "Section Headers Address : 0x%.08X\n", m_Header.dwSectionHeadersAddr);
// print init flags
{
fprintf(x_file, "Init Flags : 0x%.08X ", m_Header.dwInitFlags.bMountUtilityDrive);
if(m_Header.dwInitFlags.bMountUtilityDrive)
fprintf(x_file, "[Mount Utility Drive] ");
if(m_Header.dwInitFlags.bFormatUtilityDrive)
fprintf(x_file, "[Format Utility Drive] ");
if(m_Header.dwInitFlags.bLimit64MB)
fprintf(x_file, "[Limit Devkit Run Time Memory to 64MB] ");
if(!m_Header.dwInitFlags.bDontSetupHarddisk)
fprintf(x_file, "[Setup Harddisk] ");
fprintf(x_file, "\n");
}
char AsciiFilename[40];
setlocale( LC_ALL, "English" );
const wchar_t *wszFilename = (const wchar_t *)GetAddr(m_Header.dwDebugUnicodeFilenameAddr);
if(wszFilename != NULL)
wcstombs(AsciiFilename, wszFilename, 40);
else
AsciiFilename[0] = '\0';
fprintf(x_file, "Entry Point : 0x%.08X (Retail: 0x%.08X, Debug: 0x%.08X)\n", m_Header.dwEntryAddr, m_Header.dwEntryAddr ^ XOR_EP_RETAIL, m_Header.dwEntryAddr ^ XOR_EP_DEBUG);
fprintf(x_file, "TLS Address : 0x%.08X\n", m_Header.dwTLSAddr);
fprintf(x_file, "(PE) Stack Commit : 0x%.08X\n", m_Header.dwPeStackCommit);
fprintf(x_file, "(PE) Heap Reserve : 0x%.08X\n", m_Header.dwPeHeapReserve);
fprintf(x_file, "(PE) Heap Commit : 0x%.08X\n", m_Header.dwPeHeapCommit);
fprintf(x_file, "(PE) Base Address : 0x%.08X\n", m_Header.dwPeBaseAddr);
fprintf(x_file, "(PE) Size of Image : 0x%.08X\n", m_Header.dwPeSizeofImage);
fprintf(x_file, "(PE) Checksum : 0x%.08X\n", m_Header.dwPeChecksum);
fprintf(x_file, "(PE) TimeDate Stamp : 0x%.08X (%s)\n", m_Header.dwPeTimeDate, BetterTime(m_Header.dwPeTimeDate));
fprintf(x_file, "Debug Pathname Address : 0x%.08X (\"%s\")\n", m_Header.dwDebugPathnameAddr, GetAddr(m_Header.dwDebugPathnameAddr));
fprintf(x_file, "Debug Filename Address : 0x%.08X (\"%s\")\n", m_Header.dwDebugFilenameAddr, GetAddr(m_Header.dwDebugFilenameAddr));
fprintf(x_file, "Debug Unicode filename Address : 0x%.08X (L\"%s\")\n", m_Header.dwDebugUnicodeFilenameAddr, AsciiFilename);
fprintf(x_file, "Kernel Image Thunk Address : 0x%.08X (Retail: 0x%.08X, Debug: 0x%.08X)\n", m_Header.dwKernelImageThunkAddr, m_Header.dwKernelImageThunkAddr ^ XOR_KT_RETAIL, m_Header.dwKernelImageThunkAddr ^ XOR_KT_DEBUG);
fprintf(x_file, "NonKernel Import Dir Address : 0x%.08X\n", m_Header.dwNonKernelImportDirAddr);
fprintf(x_file, "Library Versions : 0x%.08X\n", m_Header.dwLibraryVersions);
fprintf(x_file, "Library Versions Address : 0x%.08X\n", m_Header.dwLibraryVersionsAddr);
fprintf(x_file, "Kernel Library Version Address : 0x%.08X\n", m_Header.dwKernelLibraryVersionAddr);
fprintf(x_file, "XAPI Library Version Address : 0x%.08X\n", m_Header.dwXAPILibraryVersionAddr);
fprintf(x_file, "Logo Bitmap Address : 0x%.08X\n", m_Header.dwLogoBitmapAddr);
fprintf(x_file, "Logo Bitmap Size : 0x%.08X\n", m_Header.dwSizeofLogoBitmap);
fprintf(x_file, "\n");
fprintf(x_file, "Dumping XBE Certificate...\n");
fprintf(x_file, "\n");
fprintf(x_file, "Size of Certificate : 0x%.08X\n", m_Certificate.dwSize);
fprintf(x_file, "TimeDate Stamp : 0x%.08X (%s)\n", m_Certificate.dwTimeDate, BetterTime(m_Certificate.dwTimeDate));
fprintf(x_file, "Title ID : 0x%.08X\n", m_Certificate.dwTitleId);
fprintf(x_file, "Title : L\"%s\"\n", m_szAsciiTitle);
// print alternate title IDs
{
fprintf(x_file, "Alternate Titles IDs : ");
for(int v=0;v<0x10;v++)
{
if(v != 0)
fprintf(x_file, " ");
fprintf(x_file, "0x%.08X", m_Certificate.dwAlternateTitleId[v]);
if(v != 0x0F)
fprintf(x_file, "\n");
}
fprintf(x_file, "\n");
}
fprintf(x_file, "Allowed Media : 0x%.08X (%s)\n", m_Certificate.dwAllowedMedia, AllowedMediaToString().c_str());
fprintf(x_file, "Game Region : 0x%.08X (%s)\n", m_Certificate.dwGameRegion, GameRegionToString());
fprintf(x_file, "Game Ratings : 0x%.08X\n", m_Certificate.dwGameRatings);
fprintf(x_file, "Disk Number : 0x%.08X\n", m_Certificate.dwDiskNumber);
fprintf(x_file, "Version : 0x%.08X\n", m_Certificate.dwVersion);
// print LAN key
{
fprintf(x_file, "LAN Key : ");
for(int x=0;x<16;x++)
fprintf(x_file, "%.02X", m_Certificate.bzLanKey[x]);
fprintf(x_file, "\n");
}
// print signature key
{
fprintf(x_file, "Signature Key : ");
for(int x=0;x<16;x++)
fprintf(x_file, "%.02X", m_Certificate.bzSignatureKey[x]);
fprintf(x_file, "\n");
}
// print alternate signature keys
{
fprintf(x_file, "Title Alternate Signature Keys : <Hex Dump>");
for(int y=0;y<16;y++)
{
fprintf(x_file, "\n ");
for(int x=0;x<16;x++)
fprintf(x_file, "%.02X", m_Certificate.bzTitleAlternateSignatureKey[y][x]);
}
fprintf(x_file, "\n </Hex Dump>\n");
}
fprintf(x_file, "\n");
fprintf(x_file, "Dumping XBE Section Headers...\n");
fprintf(x_file, "\n");
// print section headers
{
for(uint32 v=0;v<m_Header.dwSections;v++)
{
fprintf(x_file, "Section Name : 0x%.08X (\"%s\")\n", m_SectionHeader[v].dwSectionNameAddr, m_szSectionName[v]);
// print flags
{
fprintf(x_file, "Flags : 0x%.08X ", m_SectionHeader[v].dwFlags.bWritable);
if(m_SectionHeader[v].dwFlags.bWritable)
fprintf(x_file, "(Writable) ");
if(m_SectionHeader[v].dwFlags.bPreload)
fprintf(x_file, "(Preload) ");
if(m_SectionHeader[v].dwFlags.bExecutable)
fprintf(x_file, "(Executable) ");
if(m_SectionHeader[v].dwFlags.bInsertedFile)
fprintf(x_file, "(Inserted File) ");
if(m_SectionHeader[v].dwFlags.bHeadPageRO)
fprintf(x_file, "(Head Page RO) ");
if(m_SectionHeader[v].dwFlags.bTailPageRO)
fprintf(x_file, "(Tail Page RO) ");
fprintf(x_file, "\n");
}
fprintf(x_file, "Virtual Address : 0x%.08X\n", m_SectionHeader[v].dwVirtualAddr);
fprintf(x_file, "Virtual Size : 0x%.08X\n", m_SectionHeader[v].dwVirtualSize);
fprintf(x_file, "Raw Address : 0x%.08X\n", m_SectionHeader[v].dwRawAddr);
fprintf(x_file, "Size of Raw : 0x%.08X\n", m_SectionHeader[v].dwSizeofRaw);
fprintf(x_file, "Section Name Address : 0x%.08X\n", m_SectionHeader[v].dwSectionNameAddr);
fprintf(x_file, "Section Reference Count : 0x%.08X\n", m_SectionHeader[v].dwSectionRefCount);
fprintf(x_file, "Head Shared Reference Count Addr : 0x%.08X\n", m_SectionHeader[v].dwHeadSharedRefCountAddr);
fprintf(x_file, "Tail Shared Reference Count Addr : 0x%.08X\n", m_SectionHeader[v].dwTailSharedRefCountAddr);
// print section digest
{
fprintf(x_file, "Section Digest : ");
for(int s=0;s<20;s++)
fprintf(x_file, "%.02X", m_SectionHeader[v].bzSectionDigest[s]);
fprintf(x_file, "\n");
}
fprintf(x_file, "\n");
}
}
fprintf(x_file, "Dumping XBE Library Versions...\n");
fprintf(x_file, "\n");
// print library versions
{
if(m_LibraryVersion == 0 || m_Header.dwLibraryVersions == 0)
{
fprintf(x_file, "(This XBE contains no Library Versions)\n");
fprintf(x_file, "\n");
}
else
{
for(uint32 v=0;v<m_Header.dwLibraryVersions;v++)
{
char tmp[9];
for(uint32 c=0;c<8;c++)
tmp[c] = m_LibraryVersion[v].szName[c];
tmp[8] = '\0';
fprintf(x_file, "Library Name : %s\n", tmp);
fprintf(x_file, "Version : %d.%d.%d\n", m_LibraryVersion[v].wMajorVersion, m_LibraryVersion[v].wMinorVersion, m_LibraryVersion[v].wBuildVersion);
// print flags
{
fprintf(x_file, "Flags : ");
fprintf(x_file, "QFEVersion : 0x%.04X, ", m_LibraryVersion[v].dwFlags.QFEVersion);
if(m_LibraryVersion[v].dwFlags.bDebugBuild)
fprintf(x_file, "Debug, ");
else
fprintf(x_file, "Retail, ");
switch(m_LibraryVersion[v].dwFlags.Approved)
{
case 0:
fprintf(x_file, "Unapproved");
break;
case 1:
fprintf(x_file, "Possibly Approved");
break;
case 2:
fprintf(x_file, "Approved");
break;
}
fprintf(x_file, "\n");
}
fprintf(x_file, "\n");
}
}
}
fprintf(x_file, "Dumping XBE TLS...\n");
fprintf(x_file, "\n");
// print thread local storage
if(m_TLS != 0)
{
fprintf(x_file, "Data Start Address : 0x%.08X\n", m_TLS->dwDataStartAddr);
fprintf(x_file, "Data End Address : 0x%.08X\n", m_TLS->dwDataEndAddr);
fprintf(x_file, "TLS Index Address : 0x%.08X\n", m_TLS->dwTLSIndexAddr);
fprintf(x_file, "TLS Callback Address : 0x%.08X\n", m_TLS->dwTLSCallbackAddr);
fprintf(x_file, "Size of Zero Fill : 0x%.08X\n", m_TLS->dwSizeofZeroFill);
fprintf(x_file, "Characteristics : 0x%.08X\n", m_TLS->dwCharacteristics);
}
else
{
fprintf(x_file, "(This XBE contains no TLS)\n");
}
}
// import logo bitmap from raw monochrome data // import logo bitmap from raw monochrome data
void Xbe::ImportLogoBitmap(const uint08 x_Gray[100*17]) void Xbe::ImportLogoBitmap(const uint08 x_Gray[100*17])
{ {
@ -1037,42 +800,7 @@ const char *Xbe::GameRegionToString()
return Region_text[index]; return Region_text[index];
} }
std::string Xbe::AllowedMediaToString() const wchar_t *Xbe::GetUnicodeFilenameAddr()
{ {
const uint32 dwAllowedMedia = m_Certificate.dwAllowedMedia; return (const wchar_t *)GetAddr(m_Header.dwDebugUnicodeFilenameAddr);
std::string text = "Media Types:";
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_MEDIA_MASK) {
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_HARD_DISK)
text.append(" HARD_DISK");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_X2)
text.append(" DVD_X2");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_CD)
text.append(" DVD_CD");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_CD)
text.append(" CD");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_5_RO)
text.append(" DVD_5_RO");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_9_RO)
text.append(" DVD_9_RO");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_5_RW)
text.append(" DVD_5_RW");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_9_RW)
text.append(" DVD_9_RW");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DONGLE)
text.append(" DONGLE");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_MEDIA_BOARD)
text.append(" BOARD");
if((dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_MEDIA_MASK) >= (XBEIMAGE_MEDIA_TYPE_MEDIA_BOARD * 2))
text.append(" UNKNOWN");
}
if(dwAllowedMedia & ~XBEIMAGE_MEDIA_TYPE_MEDIA_MASK) {
text.append(" NONSECURE");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_NONSECURE_HARD_DISK)
text.append(" HARD_DISK");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_NONSECURE_MODE)
text.append(" MODE");
}
return text;
} }

View File

@ -51,7 +51,7 @@ class Xbe : public Error
{ {
public: public:
// construct via Xbe file // construct via Xbe file
Xbe(const char *x_szFilename); Xbe(const char *x_szFilename, bool bFromGUI);
// deconstructor // deconstructor
~Xbe(); ~Xbe();
@ -62,8 +62,7 @@ class Xbe : public Error
// export to Xbe file // export to Xbe file
void Export(const char *x_szXbeFilename); void Export(const char *x_szXbeFilename);
// dump Xbe information to text file std::string DumpInformation();
void DumpInformation(FILE *x_file);
// import logo bitmap from raw monochrome data // import logo bitmap from raw monochrome data
void ImportLogoBitmap(const uint08 x_Gray[100*17]); void ImportLogoBitmap(const uint08 x_Gray[100*17]);
@ -92,7 +91,7 @@ class Xbe : public Error
uint32 dwSections; // 0x011C - number of sections uint32 dwSections; // 0x011C - number of sections
uint32 dwSectionHeadersAddr; // 0x0120 - section headers address uint32 dwSectionHeadersAddr; // 0x0120 - section headers address
struct InitFlags // 0x0124 - initialization flags typedef struct
{ {
uint32 bMountUtilityDrive : 1; // mount utility drive flag uint32 bMountUtilityDrive : 1; // mount utility drive flag
uint32 bFormatUtilityDrive : 1; // format utility drive flag uint32 bFormatUtilityDrive : 1; // format utility drive flag
@ -102,8 +101,12 @@ class Xbe : public Error
uint32 Unused_b1 : 8; // unused (or unknown) uint32 Unused_b1 : 8; // unused (or unknown)
uint32 Unused_b2 : 8; // unused (or unknown) uint32 Unused_b2 : 8; // unused (or unknown)
uint32 Unused_b3 : 8; // unused (or unknown) uint32 Unused_b3 : 8; // unused (or unknown)
} } InitFlags;
dwInitFlags;
union { // 0x0124 - initialization flags
InitFlags dwInitFlags;
uint32 dwInitFlags_value;
};
uint32 dwEntryAddr; // 0x0128 - entry point address uint32 dwEntryAddr; // 0x0128 - entry point address
uint32 dwTLSAddr; // 0x012C - thread local storage directory address uint32 dwTLSAddr; // 0x012C - thread local storage directory address
@ -154,6 +157,7 @@ class Xbe : public Error
uint32 dwOriginalCertificateSize; // 0x01D0 - Original Certificate Size? uint32 dwOriginalCertificateSize; // 0x01D0 - Original Certificate Size?
uint32 dwOnlineService; // 0x01D4 - Online Service ID uint32 dwOnlineService; // 0x01D4 - Online Service ID
uint32 dwSecurityFlags; // 0x01D8 - Extra Security Flags uint32 dwSecurityFlags; // 0x01D8 - Extra Security Flags
uint08 bzCodeEncKey[16]; // 0x01DC - Code Encryption Key?
} }
#include "AlignPosfix1.h" #include "AlignPosfix1.h"
m_Certificate; m_Certificate;
@ -162,7 +166,7 @@ class Xbe : public Error
#include "AlignPrefix1.h" #include "AlignPrefix1.h"
struct SectionHeader struct SectionHeader
{ {
struct _Flags typedef struct
{ {
uint32 bWritable : 1; // writable flag uint32 bWritable : 1; // writable flag
uint32 bPreload : 1; // preload flag uint32 bPreload : 1; // preload flag
@ -175,8 +179,12 @@ class Xbe : public Error
uint32 Unused_b1 : 8; // unused (or unknown) uint32 Unused_b1 : 8; // unused (or unknown)
uint32 Unused_b2 : 8; // unused (or unknown) uint32 Unused_b2 : 8; // unused (or unknown)
uint32 Unused_b3 : 8; // unused (or unknown) uint32 Unused_b3 : 8; // unused (or unknown)
} } _Flags;
dwFlags;
union {
_Flags dwFlags;
uint32 dwFlags_value;
};
uint32 dwVirtualAddr; // virtual address uint32 dwVirtualAddr; // virtual address
uint32 dwVirtualSize; // virtual size uint32 dwVirtualSize; // virtual size
@ -200,13 +208,17 @@ class Xbe : public Error
uint16 wMinorVersion; // minor version uint16 wMinorVersion; // minor version
uint16 wBuildVersion; // build version uint16 wBuildVersion; // build version
struct Flags typedef struct
{ {
uint16 QFEVersion : 13; // QFE Version uint16 QFEVersion : 13; // QFE Version
uint16 Approved : 2; // Approved? (0:no, 1:possibly, 2:yes) uint16 Approved : 2; // Approved? (0:no, 1:possibly, 2:yes)
uint16 bDebugBuild : 1; // Is this a debug build? uint16 bDebugBuild : 1; // Is this a debug build?
} } Flags;
dwFlags;
union {
Flags wFlags;
uint16 wFlags_value;
};
} }
#include "AlignPosfix1.h" #include "AlignPosfix1.h"
*m_LibraryVersion, *m_KernelLibraryVersion, *m_XAPILibraryVersion; *m_LibraryVersion, *m_KernelLibraryVersion, *m_XAPILibraryVersion;
@ -243,17 +255,17 @@ class Xbe : public Error
// retrieve thread local storage index address // retrieve thread local storage index address
uint32 *GetTLSIndex() { if(m_TLS == 0) return 0; else return (uint32*)GetAddr(m_TLS->dwTLSIndexAddr); } uint32 *GetTLSIndex() { if(m_TLS == 0) return 0; else return (uint32*)GetAddr(m_TLS->dwTLSIndexAddr); }
// return a modifiable pointer inside this structure that corresponds to a virtual address
uint08 *GetAddr(uint32 x_dwVirtualAddress);
const wchar_t *GetUnicodeFilenameAddr();
private: private:
// constructor initialization // constructor initialization
void ConstructorInit(); void ConstructorInit();
// return a modifiable pointer inside this structure that corresponds to a virtual address
uint08 *GetAddr(uint32 x_dwVirtualAddress);
// return a modifiable pointer to logo bitmap data // return a modifiable pointer to logo bitmap data
uint08 *GetLogoBitmap(uint32 x_dwSize); uint08 *GetLogoBitmap(uint32 x_dwSize);
std::string AllowedMediaToString();
// used to encode/decode logo bitmap data // used to encode/decode logo bitmap data
union LogoRLE union LogoRLE

540
src/Common/XbePrinter.cpp Normal file
View File

@ -0,0 +1,540 @@
// 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->Common->Xbe.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>
// *
// * All rights reserved
// *
// ******************************************************************
#include "XbePrinter.h"
#include "CxbxVersion.h" // For _CXBX_VERSION
#include <locale> // For ctime
#include <codecvt> // For std::codecvt_utf8<>
#include <sstream> // For std::stringstream
#include <iomanip> // For std::setfill, std::uppercase, std::hex
// better time
static char *BetterTime(uint32 x_timeDate)
{
time_t x_time = x_timeDate;
char *x_ctime = ctime(&x_time);
int v=0;
for(v=0;x_ctime[v] != '\n';v++);
x_ctime[v] = '\0';
return x_ctime;
}
std::string DumpInformation(Xbe* Xbe_object)
{
if(Xbe_object->HasError()) {
return "ERROR";
}
XbePrinter printer(Xbe_object);
return printer.GenXbeInfo();
}
#define SSTREAM_SET_HEX(stream_name) stream_name << std::setfill('0') << std::uppercase << std::hex;
XbePrinter::XbePrinter(Xbe* Xbe_object)
{
Xbe_to_print = Xbe_object;
Xbe_header = &(Xbe_object->m_Header);
Xbe_certificate = &(Xbe_object->m_Certificate);
}
std::string XbePrinter::GenXbeInfo()
{
std::string info;
info.append(GenDumpHeader());
info.append(GenXbeHeaderInfo());
info.append(GenXbeCertificateInfo());
info.append(GenSectionInfo());
info.append(GenLibraryVersions());
info.append(GenTLS());
return info;
}
std::string XbePrinter::GenHexRow(
uint08 *signature, const uint08 row, const uint08 row_size
)
{
const uint16 offset = row * row_size;
std::stringstream text;
SSTREAM_SET_HEX(text);
for(uint08 x = 0; x < row_size; x++) {
text << std::setw(2) << static_cast<unsigned>(signature[offset + x]);
}
return text.str();
}
// https://stackoverflow.com/questions/4786292/converting-unicode-strings-and-vice-versa
std::string XbePrinter::utf8_to_ascii(const wchar_t* utf8_string)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_to_ascii;
const std::wstring utf8_filename(utf8_string);
return utf8_to_ascii.to_bytes(utf8_filename);
}
std::string XbePrinter::AllowedMediaToString()
{
const uint32 dwAllowedMedia = Xbe_certificate->dwAllowedMedia;
std::string text = "Media Types:";
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_MEDIA_MASK) {
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_HARD_DISK)
text.append(" HARD_DISK");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_X2)
text.append(" DVD_X2");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_CD)
text.append(" DVD_CD");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_CD)
text.append(" CD");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_5_RO)
text.append(" DVD_5_RO");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_9_RO)
text.append(" DVD_9_RO");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_5_RW)
text.append(" DVD_5_RW");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_9_RW)
text.append(" DVD_9_RW");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DONGLE)
text.append(" DONGLE");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_MEDIA_BOARD)
text.append(" BOARD");
if((dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_MEDIA_MASK) >= (XBEIMAGE_MEDIA_TYPE_MEDIA_BOARD * 2))
text.append(" UNKNOWN");
}
if(dwAllowedMedia & ~XBEIMAGE_MEDIA_TYPE_MEDIA_MASK) {
text.append(" NONSECURE");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_NONSECURE_HARD_DISK)
text.append(" HARD_DISK");
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_NONSECURE_MODE)
text.append(" MODE");
}
return text;
}
std::string XbePrinter::GameRatingToString()
{
std::string text;
// Info from: http://xboxdevwiki.net/EEPROM
switch(Xbe_certificate->dwGameRatings) {
case 0x0:
text.append("(RP) Rating Pending");
break;
case 0x1:
text.append("(AO) Adults Only");
break;
case 0x2:
text.append("(M) Mature");
break;
case 0x3:
text.append("(T) Teen");
break;
case 0x4:
text.append("(E) Everyone");
break;
case 0x5:
text.append("(K-A) Kids to Adults");
break;
case 0x6:
text.append("(EC) Early Childhood");
break;
default:
text.append("ERROR: no rating");
break;
}
return text;
}
std::string XbePrinter::GenDumpHeader()
{
std::string text;
text.append("XBE information generated by Cxbx-Reloaded (Version " _CXBX_VERSION ")\n\n");
text.append("Title identified as \"");
text.append(Xbe_to_print->m_szAsciiTitle);
text.append("\"\n\n");
text.append("Dumping XBE file header...\n\n");
text.append("Magic Number : XBEH\n");
return text;
}
std::string XbePrinter::GenXbeHeaderInfo()
{
std::string text;
text.append(GenDigitalSignature());
text.append(GenGeneralHeaderInfo1());
text.append(GenInitFlags());
text.append(GenGeneralHeaderInfo2());
return text;
}
std::string XbePrinter::GenDigitalSignature()
{
const uint08 row_size = 16;
std::string text;
text.append("Digital Signature : <Hex Dump>");
for(int row = 0; row < 16; row++) {
text.append("\n ");
text.append(GenHexRow(&(Xbe_header->pbDigitalSignature[0]), row, row_size));
}
text.append("\n </Hex Dump>\n");
return text;
}
std::string XbePrinter::GenGeneralHeaderInfo1()
{
std::stringstream text;
SSTREAM_SET_HEX(text);
text << "Base Address : 0x" << std::setw(8) << Xbe_header->dwBaseAddr << "\n";
text << "Size of Headers : 0x" << std::setw(8) << Xbe_header->dwSizeofHeaders << "\n";
text << "Size of Image : 0x" << std::setw(8) << Xbe_header->dwSizeofImage << "\n";
text << "Size of Image Header : 0x" << std::setw(8) << Xbe_header->dwSizeofImageHeader << "\n";
text << "TimeDate Stamp : 0x" << std::setw(8) << Xbe_header->dwTimeDate << " (" << BetterTime(Xbe_header->dwTimeDate) << ")\n";
text << "Certificate Address : 0x" << std::setw(8) << Xbe_header->dwCertificateAddr << "\n";
text << "Number of Sections : 0x" << std::setw(8) << Xbe_header->dwSections << "\n";
text << "Section Headers Address : 0x" << std::setw(8) << Xbe_header->dwSectionHeadersAddr << "\n";
return text.str();
}
std::string XbePrinter::GenInitFlags()
{
std::stringstream text;
SSTREAM_SET_HEX(text);
text << "Init Flags : 0x" << std::setw(8) << Xbe_header->dwInitFlags_value << " ";
if(Xbe_header->dwInitFlags.bMountUtilityDrive) {
text << "[Mount Utility Drive] ";
}
if(Xbe_header->dwInitFlags.bFormatUtilityDrive) {
text << "[Format Utility Drive] ";
}
if(Xbe_header->dwInitFlags.bLimit64MB) {
text << "[Limit Devkit Run Time Memory to 64MB] ";
}
if(!Xbe_header->dwInitFlags.bDontSetupHarddisk) {
text << "[Setup Harddisk] ";
}
text << "\n";
return text.str();
}
std::string XbePrinter::GenGeneralHeaderInfo2()
{
const uint32 retail_entry_point = Xbe_header->dwEntryAddr ^ XOR_EP_RETAIL;
const uint32 debug_entry_point = Xbe_header->dwEntryAddr ^ XOR_EP_DEBUG;
const uint32 retail_thunk_addr = Xbe_header->dwKernelImageThunkAddr ^ XOR_KT_RETAIL;
const uint32 debug_thunk_addr = Xbe_header->dwKernelImageThunkAddr ^ XOR_KT_DEBUG;
const std::string AsciiFilename = utf8_to_ascii(Xbe_to_print->GetUnicodeFilenameAddr());
std::stringstream text;
SSTREAM_SET_HEX(text);
text << "Entry Point : 0x" << std::setw(8) << Xbe_header->dwEntryAddr << " (Retail: 0x" << std::setw(8) << retail_entry_point << ", Debug: 0x" << std::setw(8) << debug_entry_point << ")\n";
text << "TLS Address : 0x" << std::setw(8) << Xbe_header->dwTLSAddr << "\n";
text << "(PE) Stack Commit : 0x" << std::setw(8) << Xbe_header->dwPeStackCommit << "\n";
text << "(PE) Heap Reserve : 0x" << std::setw(8) << Xbe_header->dwPeHeapReserve << "\n";
text << "(PE) Heap Commit : 0x" << std::setw(8) << Xbe_header->dwPeHeapCommit << "\n";
text << "(PE) Base Address : 0x" << std::setw(8) << Xbe_header->dwPeBaseAddr << "\n";
text << "(PE) Size of Image : 0x" << std::setw(8) << Xbe_header->dwPeSizeofImage << "\n";
text << "(PE) Checksum : 0x" << std::setw(8) << Xbe_header->dwPeChecksum << "\n";
text << "(PE) TimeDate Stamp : 0x" << std::setw(8) << Xbe_header->dwPeTimeDate << " (" << BetterTime(Xbe_header->dwPeTimeDate) << ")\n";
text << "Debug Pathname Address : 0x" << std::setw(8) << Xbe_header->dwDebugPathnameAddr << " (\"" << Xbe_to_print->GetAddr(Xbe_header->dwDebugPathnameAddr) << "\")\n";
text << "Debug Filename Address : 0x" << std::setw(8) << Xbe_header->dwDebugFilenameAddr << " (\"" << Xbe_to_print->GetAddr(Xbe_header->dwDebugFilenameAddr) << "\")\n";
text << "Debug Unicode filename Address : 0x" << std::setw(8) << Xbe_header->dwDebugUnicodeFilenameAddr << " (L\"" << AsciiFilename << "\")\n";
text << "Kernel Image Thunk Address : 0x" << std::setw(8) << Xbe_header->dwKernelImageThunkAddr << " (Retail: 0x" << std::setw(8) << retail_thunk_addr << ", Debug: 0x" << std::setw(8) << debug_thunk_addr << ")\n";
text << "NonKernel Import Dir Address : 0x" << std::setw(8) << Xbe_header->dwNonKernelImportDirAddr << "\n";
text << "Library Versions : 0x" << std::setw(8) << Xbe_header->dwLibraryVersions << "\n";
text << "Library Versions Address : 0x" << std::setw(8) << Xbe_header->dwLibraryVersionsAddr << "\n";
text << "Kernel Library Version Address : 0x" << std::setw(8) << Xbe_header->dwKernelLibraryVersionAddr << "\n";
text << "XAPI Library Version Address : 0x" << std::setw(8) << Xbe_header->dwXAPILibraryVersionAddr << "\n";
text << "Logo Bitmap Address : 0x" << std::setw(8) << Xbe_header->dwLogoBitmapAddr << "\n";
text << "Logo Bitmap Size : 0x" << std::setw(8) << Xbe_header->dwSizeofLogoBitmap << "\n\n";
return text.str();
}
std::string XbePrinter::GenXbeCertificateInfo()
{
std::string text;
text.append(GenCertificateHeader());
text.append(GenAlternateTitleIDs());
text.append(GenMediaInfo());
text.append(GenLANKey());
text.append(GenSignatureKey());
text.append(GenAlternateSignatureKeys());
text.append(GenExtraInfo());
return text;
}
std::string XbePrinter::GenCertificateHeader()
{
std::stringstream text;
SSTREAM_SET_HEX(text);
text << "Dumping XBE Certificate...\n\n";
text << "Size of Certificate : 0x" << std::setw(8) << Xbe_certificate->dwSize << "\n";
text << "TimeDate Stamp : 0x" << std::setw(8) << Xbe_certificate->dwTimeDate << " (" << BetterTime(Xbe_certificate->dwTimeDate) << ")\n";
text << "Title ID : 0x" << std::setw(8) << Xbe_certificate->dwTitleId << "\n";
text << "Title : L\"" << Xbe_to_print->m_szAsciiTitle << "\"\n";
return text.str();
}
std::string XbePrinter::GenAlternateTitleIDs()
{
std::stringstream text;
SSTREAM_SET_HEX(text);
text << "Alternate Titles IDs : ";
for(int v = 0; v < 0x10; v++) {
if(v != 0) {
text << " ";
}
text << "0x" << std::setw(8) << Xbe_certificate->dwAlternateTitleId[v];
if(v != 0x0F) {
text << "\n";
}
}
text << "\n";
return text.str();
}
std::string XbePrinter::GenMediaInfo()
{
std::stringstream text;
SSTREAM_SET_HEX(text);
text << "Allowed Media : 0x" << std::setw(8) << Xbe_certificate->dwAllowedMedia << " (" << AllowedMediaToString() << ")\n";
text << "Game Region : 0x" << std::setw(8) << Xbe_certificate->dwGameRegion << " (" << Xbe_to_print->GameRegionToString() << ")\n";
text << "Game Ratings : 0x" << std::setw(8) << Xbe_certificate->dwGameRatings << " (" << GameRatingToString() << ")\n";
text << "Disk Number : 0x" << std::setw(8) << Xbe_certificate->dwDiskNumber << "\n";
text << "Version : 0x" << std::setw(8) << Xbe_certificate->dwVersion << "\n";
return text.str();
}
std::string XbePrinter::GenLANKey()
{
const uint08 row = 0;
const uint08 row_size = 16;
std::string text;
text.append("LAN Key : ");
text.append(GenHexRow(&(Xbe_certificate->bzLanKey[0]), row, row_size));
text.append("\n");
return text;
}
std::string XbePrinter::GenSignatureKey()
{
const uint08 row = 0;
const uint08 row_size = 16;
std::string text;
text.append("Signature Key : ");
text.append(GenHexRow(&(Xbe_certificate->bzSignatureKey[0]), row, row_size));
text.append("\n");
return text;
}
std::string XbePrinter::GenAlternateSignatureKeys()
{
const uint08 row = 0;
const uint08 row_size = 16;
std::string text;
text.append("Title Alternate Signature Keys : <Hex Dump>");
for(int row = 0; row < 16; row++)
{
text.append("\n ");
text.append(GenHexRow(&(Xbe_certificate->bzTitleAlternateSignatureKey[0][0]), row, row_size));
}
text.append("\n </Hex Dump>\n");
return text;
}
std::string XbePrinter::GenExtraInfo()
{
std::stringstream text;
if (Xbe_certificate->dwSize >= 0x1EC)
{
SSTREAM_SET_HEX(text);
text << "Original Certificate Size : 0x" << std::setw(8) << Xbe_certificate->dwOriginalCertificateSize << "\n";
text << "Online Service ID : 0x" << std::setw(8) << Xbe_certificate->dwOnlineService << "\n";
text << "Extra Security Flags : 0x" << std::setw(8) << Xbe_certificate->dwSecurityFlags << "\n";
text << "Code Encryption Key : ";
text << GenHexRow(&(Xbe_certificate->bzCodeEncKey[0]), 0, 16) << "\n";
}
return text.str();
}
std::string XbePrinter::GenSectionInfo()
{
std::string text;
text.append("\nDumping XBE Section Headers...\n\n");
text.append(GenSectionHeaders());
return text;
}
std::string XbePrinter::GenSectionHeaders()
{
std::stringstream text;
SSTREAM_SET_HEX(text);
for(uint32 v=0; v < Xbe_header->dwSections; v++) {
text << "Section Name : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwSectionNameAddr << " (\"" << Xbe_to_print->m_szSectionName[v] << "\")\n";
text << GenSectionFlags(Xbe_to_print->m_SectionHeader[v]);
text << "Virtual Address : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwVirtualAddr << "\n";
text << "Virtual Size : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwVirtualSize << "\n";
text << "Raw Address : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwRawAddr << "\n";
text << "Size of Raw : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwSizeofRaw << "\n";
text << "Section Name Address : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwSectionNameAddr << "\n";
text << "Section Reference Count : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwSectionRefCount << "\n";
text << "Head Shared Reference Count Addr : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwHeadSharedRefCountAddr << "\n";
text << "Tail Shared Reference Count Addr : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwTailSharedRefCountAddr << "\n";
text << GenSectionDigest(Xbe_to_print->m_SectionHeader[v]) << "\n";
}
return text.str();
}
std::string XbePrinter::GenSectionFlags(Xbe::SectionHeader section_header)
{
std::stringstream text;
SSTREAM_SET_HEX(text);
text << "Flags : 0x" << std::setw(8) << section_header.dwFlags_value << " ";
if(section_header.dwFlags.bWritable) {
text << "(Writable) ";
}
if(section_header.dwFlags.bPreload) {
text << "(Preload) ";
}
if(section_header.dwFlags.bExecutable) {
text << "(Executable) ";
}
if(section_header.dwFlags.bInsertedFile) {
text << "(Inserted File) ";
}
if(section_header.dwFlags.bHeadPageRO) {
text << "(Head Page RO) ";
}
if(section_header.dwFlags.bTailPageRO) {
text << "(Tail Page RO) ";
}
text << "\n";
return text.str();
}
std::string XbePrinter::GenSectionDigest(Xbe::SectionHeader section_header)
{
std::string text;
text.append("Section Digest : ");
text.append(GenHexRow(&section_header.bzSectionDigest[0], 0, 20));
text.append("\n");
return text;
}
std::string XbePrinter::GenLibraryVersions()
{
std::stringstream text;
text << "Dumping XBE Library Versions...\n\n";
if(Xbe_to_print->m_LibraryVersion == 0 || Xbe_header->dwLibraryVersions == 0) {
text << "(This XBE contains no Library Versions)\n\n";
}
else {
for(uint32 v = 0; v < Xbe_header->dwLibraryVersions; v++) {
char libname[9];
for(uint32 c=0;c<8;c++) {
libname[c] = Xbe_to_print->m_LibraryVersion[v].szName[c];
}
libname[8] = '\0';
text << "Library Name : " << libname << "\n";
text << "Version : "
<< Xbe_to_print->m_LibraryVersion[v].wMajorVersion << "."
<< Xbe_to_print->m_LibraryVersion[v].wMinorVersion << "."
<< Xbe_to_print->m_LibraryVersion[v].wBuildVersion << "\n";
text << GenLibraryFlags(Xbe_to_print->m_LibraryVersion[v]);
text << "\n";
}
}
return text.str();
}
std::string XbePrinter::GenLibraryFlags(Xbe::LibraryVersion libver)
{
std::stringstream text;
SSTREAM_SET_HEX(text);
text << "Flags : 0x" << std::setw(4) << libver.wFlags_value << " ";
text << "QFEVersion : 0x" << std::setw(4) << libver.wFlags.QFEVersion << ", ";
if(libver.wFlags.bDebugBuild) {
text << "Debug, ";
}
else {
text << "Retail, ";
}
switch(libver.wFlags.Approved) {
case 0:
text << "Unapproved";
break;
case 1:
text << "Possibly Approved";
break;
case 2:
text << "Approved";
break;
}
text << "\n";
return text.str();
}
std::string XbePrinter::GenTLS()
{
std::stringstream text;
SSTREAM_SET_HEX(text);
Xbe::TLS *local_TLS = Xbe_to_print->m_TLS;
text << "Dumping XBE TLS...\n\n";
// print thread local storage
if(local_TLS != 0) {
text << "Data Start Address : 0x" << std::setw(8) << local_TLS->dwDataStartAddr << "\n";
text << "Data End Address : 0x" << std::setw(8) << local_TLS->dwDataEndAddr << "\n";
text << "TLS Index Address : 0x" << std::setw(8) << local_TLS->dwTLSIndexAddr << "\n";
text << "TLS Callback Address : 0x" << std::setw(8) << local_TLS->dwTLSCallbackAddr << "\n";
text << "Size of Zero Fill : 0x" << std::setw(8) << local_TLS->dwSizeofZeroFill << "\n";
text << "Characteristics : 0x" << std::setw(8) << local_TLS->dwCharacteristics << "\n";
}
else {
text << "(This XBE contains no TLS)\n";
}
return text.str();
}

88
src/Common/XbePrinter.h Normal file
View File

@ -0,0 +1,88 @@
// ******************************************************************
// *
// * .,-::::: .,:: .::::::::. .,:: .:
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
// * $$$ Y$$$P $$""""Y$$ Y$$$P
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
// *
// * Cxbx->Common->XbePrinter.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>
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef XBE_PRINTER_H
#define XBE_PRINTER_H
#include "Common/Error.h"
#include "Common/Xbe.h"
#include <cstdio>
extern std::string DumpInformation(Xbe* Xbe_object);
class XbePrinter
{
public:
XbePrinter(Xbe*);
std::string GenXbeInfo();
private:
Xbe *Xbe_to_print;
Xbe::Header *Xbe_header;
Xbe::Certificate *Xbe_certificate;
std::string GenHexRow(uint08*, const uint08, const uint08);
std::string utf8_to_ascii(const wchar_t*);
std::string AllowedMediaToString();
std::string GameRatingToString();
std::string GenDumpHeader();
std::string GenXbeHeaderInfo();
std::string GenDigitalSignature();
std::string GenGeneralHeaderInfo1();
std::string GenInitFlags();
std::string GenGeneralHeaderInfo2();
std::string GenXbeCertificateInfo();
std::string GenCertificateHeader();
std::string GenAlternateTitleIDs();
std::string GenMediaInfo();
std::string GenLANKey();
std::string GenSignatureKey();
std::string GenAlternateSignatureKeys();
std::string GenExtraInfo();
std::string GenSectionInfo();
std::string GenSectionHeaders();
std::string GenSectionFlags(Xbe::SectionHeader);
std::string GenSectionDigest(Xbe::SectionHeader);
std::string GenLibraryVersions();
std::string GenLibraryFlags(Xbe::LibraryVersion);
std::string GenTLS();
};
#endif // XBE_PRINTER_H

View File

@ -143,4 +143,11 @@ extern volatile bool g_bPrintfOn;
#define DbgPrintf null_func #define DbgPrintf null_func
#endif #endif
#if WIN32
#include "Win32\Threads.h"
#define CxbxSetThreadName(Name) SetCurrentThreadName(Name)
#else
#define CxbxSetThreadName(Name)
#endif
#endif #endif

View File

@ -1,6 +1,5 @@
//{{NO_DEPENDENCIES}} //{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file. // Microsoft Visual C++ generated include file.
// Used by C:\Users\lukeu\Desktop\Projects\Xbox\Cxbx-Reloaded\resource\Cxbx.rc
// //
#define IDI_CXBX 101 #define IDI_CXBX 101
#define IDB_SPLASH 102 #define IDB_SPLASH 102
@ -15,6 +14,7 @@
#define IDD_ABOUT 119 #define IDD_ABOUT 119
#define IDR_CONTRIBUTORS 121 #define IDR_CONTRIBUTORS 121
#define IDR_COPYING 122 #define IDR_COPYING 122
#define IDS_UEM 123
#define IDC_SET_X 1000 #define IDC_SET_X 1000
#define IDC_SET_Y 1001 #define IDC_SET_Y 1001
#define IDC_SET_A 1002 #define IDC_SET_A 1002
@ -102,6 +102,9 @@
#define ID_CACHE_CLEARHLECACHE_ALL 40084 #define ID_CACHE_CLEARHLECACHE_ALL 40084
#define ID_CACHE_CLEARHLECACHE_CURRENT 40085 #define ID_CACHE_CLEARHLECACHE_CURRENT 40085
#define ID_SETTINGS_XINPUT 40086 #define ID_SETTINGS_XINPUT 40086
#define ID_SETTINGS_HACKS 40087
#define ID_HACKS_DISABLEPIXELSHADERS 40088
#define ID_LED 40089
#define IDC_STATIC -1 #define IDC_STATIC -1
// Next default values for new objects // Next default values for new objects
@ -109,7 +112,7 @@
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 130 #define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 40087 #define _APS_NEXT_COMMAND_VALUE 40089
#define _APS_NEXT_CONTROL_VALUE 1058 #define _APS_NEXT_CONTROL_VALUE 1058
#define _APS_NEXT_SYMED_VALUE 104 #define _APS_NEXT_SYMED_VALUE 104
#endif #endif

View File

@ -38,16 +38,21 @@
#include "DlgControllerConfig.h" #include "DlgControllerConfig.h"
#include "DlgVideoConfig.h" #include "DlgVideoConfig.h"
#include "DlgAudioConfig.h" #include "DlgAudioConfig.h"
#include "Common/XbePrinter.h" // For DumpInformation
#include "CxbxKrnl/EmuShared.h" #include "CxbxKrnl/EmuShared.h"
#include "ResCxbx.h" #include "ResCxbx.h"
#include "CxbxVersion.h" #include "CxbxVersion.h"
#include "Shlwapi.h" #include "Shlwapi.h"
#include <multimon.h>
#include <io.h> #include <io.h>
#include <sstream> // for std::stringstream #include <sstream> // for std::stringstream
#include <fstream>
#include <iostream>
#include "CxbxKrnl/xxhash32.h" // for XXHash32::hash #include "CxbxKrnl/xxhash32.h" // for XXHash32::hash
#define XBOX_LED_FLASH_PERIOD 176 // if you know a more accurate value, put it here
#define STBI_ONLY_JPEG #define STBI_ONLY_JPEG
#define STBI_NO_LINEAR #define STBI_NO_LINEAR
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
@ -84,6 +89,7 @@ void ClearHLECache()
} }
#define TIMERID_FPS 0 #define TIMERID_FPS 0
#define TIMERID_LED 1
WndMain::WndMain(HINSTANCE x_hInstance) : WndMain::WndMain(HINSTANCE x_hInstance) :
Wnd(x_hInstance), Wnd(x_hInstance),
@ -131,26 +137,55 @@ WndMain::WndMain(HINSTANCE x_hInstance) :
if(RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Cxbx-Reloaded", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS) if(RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Cxbx-Reloaded", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS)
{ {
dwType = REG_DWORD; dwSize = sizeof(DWORD); LONG result = ERROR_SUCCESS;
RegQueryValueEx(hKey, "LLEFLAGS", NULL, &dwType, (PBYTE)&m_FlagsLLE, &dwSize);
dwType = REG_DWORD; dwSize = sizeof(DWORD); dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegQueryValueEx(hKey, "XInputEnabled", NULL, &dwType, (PBYTE)&m_XInputEnabled, &dwSize); result = RegQueryValueEx(hKey, "LLEFLAGS", NULL, &dwType, (PBYTE)&m_FlagsLLE, &dwSize);
if (result != ERROR_SUCCESS) {
m_FlagsLLE = 0;
}
dwType = REG_DWORD; dwSize = sizeof(DWORD); dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegQueryValueEx(hKey, "CxbxDebug", NULL, &dwType, (PBYTE)&m_CxbxDebug, &dwSize); result = RegQueryValueEx(hKey, "XInputEnabled", NULL, &dwType, (PBYTE)&m_XInputEnabled, &dwSize);
if (result != ERROR_SUCCESS) {
m_XInputEnabled = 0;
}
dwType = REG_DWORD; dwSize = sizeof(DWORD); dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegQueryValueEx(hKey, "KrnlDebug", NULL, &dwType, (PBYTE)&m_KrnlDebug, &dwSize); result = RegQueryValueEx(hKey, "HackDisablePixelShaders", NULL, &dwType, (PBYTE)&m_DisablePixelShaders, &dwSize);
if (result != ERROR_SUCCESS) {
m_DisablePixelShaders = 0;
}
dwType = REG_DWORD; dwSize = sizeof(DWORD);
result = RegQueryValueEx(hKey, "CxbxDebug", NULL, &dwType, (PBYTE)&m_CxbxDebug, &dwSize);
if (result != ERROR_SUCCESS) {
m_CxbxDebug = DebugMode::DM_NONE;
}
dwType = REG_DWORD; dwSize = sizeof(DWORD);
result = RegQueryValueEx(hKey, "KrnlDebug", NULL, &dwType, (PBYTE)&m_KrnlDebug, &dwSize);
if (result != ERROR_SUCCESS) {
m_KrnlDebug = DebugMode::DM_NONE;
}
dwType = REG_DWORD; dwSize = sizeof(DWORD); dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegQueryValueEx(hKey, "RecentXbe", NULL, &dwType, (PBYTE)&m_dwRecentXbe, &dwSize); result = RegQueryValueEx(hKey, "RecentXbe", NULL, &dwType, (PBYTE)&m_dwRecentXbe, &dwSize);
if (result != ERROR_SUCCESS) {
m_dwRecentXbe = 0;
}
dwType = REG_SZ; dwSize = MAX_PATH; LONG lErrCodeCxbxDebugFilename; dwType = REG_SZ; dwSize = MAX_PATH; ULONG lErrCodeCxbxDebugFilename;
lErrCodeCxbxDebugFilename = RegQueryValueEx(hKey, "CxbxDebugFilename", NULL, &dwType, (PBYTE)m_CxbxDebugFilename, &dwSize); lErrCodeCxbxDebugFilename = RegQueryValueEx(hKey, "CxbxDebugFilename", NULL, &dwType, (PBYTE)m_CxbxDebugFilename, &dwSize);
if (lErrCodeCxbxDebugFilename != ERROR_SUCCESS) {
m_CxbxDebugFilename[0] = '\0';
}
dwType = REG_SZ; dwSize = MAX_PATH; LONG lErrCodeKrnlDebugFilename; dwType = REG_SZ; dwSize = MAX_PATH; LONG lErrCodeKrnlDebugFilename;
lErrCodeKrnlDebugFilename = RegQueryValueEx(hKey, "KrnlDebugFilename", NULL, &dwType, (PBYTE)m_KrnlDebugFilename, &dwSize); lErrCodeKrnlDebugFilename = RegQueryValueEx(hKey, "KrnlDebugFilename", NULL, &dwType, (PBYTE)m_KrnlDebugFilename, &dwSize);
if (lErrCodeKrnlDebugFilename != ERROR_SUCCESS) {
m_KrnlDebugFilename[0] = '\0';
}
// Prevent using an incorrect path from the registry if the debug folders have been moved // Prevent using an incorrect path from the registry if the debug folders have been moved
if (m_CxbxDebug == DM_FILE) if (m_CxbxDebug == DM_FILE)
@ -228,7 +263,11 @@ WndMain::WndMain(HINSTANCE x_hInstance) :
m_szRecentXbe[v] = (char*)calloc(1, MAX_PATH); m_szRecentXbe[v] = (char*)calloc(1, MAX_PATH);
dwType = REG_SZ; dwSize = MAX_PATH; dwType = REG_SZ; dwSize = MAX_PATH;
RegQueryValueEx(hKey, buffer, NULL, &dwType, (PBYTE)m_szRecentXbe[v], &dwSize); result = RegQueryValueEx(hKey, buffer, NULL, &dwType, (PBYTE)m_szRecentXbe[v], &dwSize);
if (result != ERROR_SUCCESS) {
m_szRecentXbe[v] = "";
}
} }
RegCloseKey(hKey); RegCloseKey(hKey);
@ -268,6 +307,9 @@ WndMain::~WndMain()
dwType = REG_DWORD; dwSize = sizeof(DWORD); dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegSetValueEx(hKey, "XInputEnabled", 0, dwType, (PBYTE)&m_XInputEnabled, dwSize); RegSetValueEx(hKey, "XInputEnabled", 0, dwType, (PBYTE)&m_XInputEnabled, dwSize);
dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegSetValueEx(hKey, "HackDisablePixelShaders", 0, dwType, (PBYTE)&m_DisablePixelShaders, dwSize);
dwType = REG_DWORD; dwSize = sizeof(DWORD); dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegSetValueEx(hKey, "CxbxDebug", 0, dwType, (PBYTE)&m_CxbxDebug, dwSize); RegSetValueEx(hKey, "CxbxDebug", 0, dwType, (PBYTE)&m_CxbxDebug, dwSize);
@ -330,6 +372,23 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
m_BackBmp = CreateCompatibleBitmap(hDC, m_w, m_h); m_BackBmp = CreateCompatibleBitmap(hDC, m_w, m_h);
// create Xbox LED bitmap
{
m_xBmp = GetSystemMetrics(SM_CXMENUCHECK);
m_yBmp = GetSystemMetrics(SM_CYMENUCHECK);
m_LedDC = CreateCompatibleDC(hDC);
m_LedBmp = CreateCompatibleBitmap(hDC, m_xBmp, m_yBmp);
m_Brushes[XBOX_LED_COLOUR_OFF] = CreateSolidBrush(RGB(0, 0, 0));
m_Brushes[XBOX_LED_COLOUR_GREEN] = CreateSolidBrush(RGB(0, 255, 0));
m_Brushes[XBOX_LED_COLOUR_RED] = CreateSolidBrush(RGB(255, 0, 0));
m_Brushes[XBOX_LED_COLOUR_ORANGE] = CreateSolidBrush(RGB(255, 165, 0));
m_Pens[XBOX_LED_COLOUR_OFF] = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
m_Pens[XBOX_LED_COLOUR_GREEN] = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
m_Pens[XBOX_LED_COLOUR_RED] = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
m_Pens[XBOX_LED_COLOUR_ORANGE] = CreatePen(PS_SOLID, 1, RGB(255, 165, 0));
DrawLedBitmap(hwnd, true);
}
// decompress jpeg, convert to bitmap resource // decompress jpeg, convert to bitmap resource
{ {
HRSRC hSrc = FindResource(NULL, MAKEINTRESOURCE(IDR_JPEG_SPLASH), "JPEG"); HRSRC hSrc = FindResource(NULL, MAKEINTRESOURCE(IDR_JPEG_SPLASH), "JPEG");
@ -414,9 +473,12 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
if (m_hwndChild == NULL) { if (m_hwndChild == NULL) {
float fps = 0; float fps = 0;
float mspf = 0; float mspf = 0;
int LedSequence[4] = { XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN };
g_EmuShared->SetCurrentMSpF(&mspf); g_EmuShared->SetCurrentMSpF(&mspf);
g_EmuShared->SetCurrentFPS(&fps); g_EmuShared->SetCurrentFPS(&fps);
g_EmuShared->SetLedSequence(LedSequence);
SetTimer(hwnd, TIMERID_FPS, 1000, (TIMERPROC)NULL); SetTimer(hwnd, TIMERID_FPS, 1000, (TIMERPROC)NULL);
SetTimer(hwnd, TIMERID_LED, XBOX_LED_FLASH_PERIOD, (TIMERPROC)NULL);
m_hwndChild = GetWindow(hwnd, GW_CHILD); // (HWND)HIWORD(wParam) seems to be NULL m_hwndChild = GetWindow(hwnd, GW_CHILD); // (HWND)HIWORD(wParam) seems to be NULL
UpdateCaption(); UpdateCaption();
RefreshMenus(); RefreshMenus();
@ -433,8 +495,10 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
// (HWND)HIWORD(wParam) seems to be NULL, so we can't compare to m_hwndChild // (HWND)HIWORD(wParam) seems to be NULL, so we can't compare to m_hwndChild
if (m_hwndChild != NULL) { // Let's hope this signal originated from the only child window if (m_hwndChild != NULL) { // Let's hope this signal originated from the only child window
KillTimer(hwnd, TIMERID_FPS); KillTimer(hwnd, TIMERID_FPS);
KillTimer(hwnd, TIMERID_LED);
m_hwndChild = NULL; m_hwndChild = NULL;
StopEmulation(); StopEmulation();
DrawLedBitmap(hwnd, true);
} }
} }
break; break;
@ -451,6 +515,12 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
UpdateCaption(); UpdateCaption();
} }
break; break;
case TIMERID_LED:
{
DrawLedBitmap(hwnd, false);
}
break;
} }
} }
break; break;
@ -937,56 +1007,43 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
// dump xbe information to file // dump xbe information to file
{ {
FILE *TxtFile = fopen(ofn.lpstrFile, "wt"); std::string Xbe_info = DumpInformation(m_Xbe);
if (m_Xbe->HasError()) {
// verify file was opened MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK);
if (TxtFile == 0) }
MessageBox(m_hwnd, "Could not open text file.", "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); else {
else std::ofstream Xbe_dump_file(ofn.lpstrFile);
{ if(Xbe_dump_file.is_open()) {
m_Xbe->DumpInformation(TxtFile); Xbe_dump_file << Xbe_info;
Xbe_dump_file.close();
fclose(TxtFile); char buffer[255];
sprintf(buffer, "%s's .xbe info was successfully dumped.", m_Xbe->m_szAsciiTitle);
if (m_Xbe->HasError()) printf("WndMain: %s\n", buffer);
{ MessageBox(m_hwnd, buffer, "Cxbx-Reloaded", MB_ICONINFORMATION | MB_OK);
MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); }
} else {
else MessageBox(m_hwnd, "Could not open Xbe text file.", "Cxbx-Reloaded", MB_ICONSTOP | MB_OK);
{ }
char buffer[255]; }
sprintf(buffer, "%s's .xbe info was successfully dumped.", m_Xbe->m_szAsciiTitle);
printf("WndMain: %s\n", buffer);
MessageBox(m_hwnd, buffer, "Cxbx-Reloaded", MB_ICONINFORMATION | MB_OK);
}
}
} }
} }
} }
break; break;
case ID_EDIT_DUMPXBEINFOTO_DEBUGCONSOLE: case ID_EDIT_DUMPXBEINFOTO_DEBUGCONSOLE:
{ {
// dump xbe information to debug console std::string Xbe_info = DumpInformation(m_Xbe);
m_Xbe->DumpInformation(stdout); if (m_Xbe->HasError()) {
MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK);
if (m_Xbe->HasError()) }
{ else {
MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); std::cout << Xbe_info;
} char buffer[255];
else sprintf(buffer, "%s's .xbe info was successfully dumped to console.", m_Xbe->m_szAsciiTitle);
{ printf("WndMain: %s\n", buffer);
char buffer[255]; }
}
sprintf(buffer, "%s's .xbe info was successfully dumped.", m_Xbe->m_szAsciiTitle); break;
printf("WndMain: %s\n", buffer);
}
}
break;
case ID_SETTINGS_CONFIG_CONTROLLER: case ID_SETTINGS_CONFIG_CONTROLLER:
ShowControllerConfig(hwnd); ShowControllerConfig(hwnd);
@ -1177,6 +1234,11 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
StopEmulation(); StopEmulation();
break; break;
case ID_HACKS_DISABLEPIXELSHADERS:
m_DisablePixelShaders = !m_DisablePixelShaders;
RefreshMenus();
break;
case ID_HELP_ABOUT: case ID_HELP_ABOUT:
{ {
ShowAboutDialog(hwnd); ShowAboutDialog(hwnd);
@ -1205,27 +1267,49 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
{ {
FreeConsole(); FreeConsole();
HDC hDC = GetDC(hwnd); HDC hDC = GetDC(hwnd);
SelectObject(m_LogoDC, m_OrigLogo); SelectObject(m_LogoDC, m_OrigLogo);
SelectObject(m_BackDC, m_OrigBmp); SelectObject(m_BackDC, m_OrigBmp);
SelectObject(m_GameLogoDC, m_OrigGameLogo); SelectObject(m_GameLogoDC, m_OrigGameLogo);
DeleteObject(m_LogoDC); SelectObject(m_LedDC, m_OriLed);
DeleteObject(m_BackDC); DeleteObject(m_LogoDC);
DeleteObject(m_BackDC);
DeleteObject(m_GameLogoDC); DeleteObject(m_GameLogoDC);
DeleteObject(m_LogoBmp); DeleteObject(m_LedDC);
DeleteObject(m_BackBmp); DeleteObject(m_LogoBmp);
DeleteObject(m_BackBmp);
DeleteObject(m_GameLogoBMP); DeleteObject(m_GameLogoBMP);
ReleaseDC(hwnd, hDC); DeleteObject(m_LedBmp);
DeleteObject(m_Brushes[XBOX_LED_COLOUR_OFF]);
DeleteObject(m_Brushes[XBOX_LED_COLOUR_GREEN]);
DeleteObject(m_Brushes[XBOX_LED_COLOUR_RED]);
DeleteObject(m_Brushes[XBOX_LED_COLOUR_ORANGE]);
DeleteObject(m_Pens[XBOX_LED_COLOUR_OFF]);
DeleteObject(m_Pens[XBOX_LED_COLOUR_GREEN]);
DeleteObject(m_Pens[XBOX_LED_COLOUR_RED]);
DeleteObject(m_Pens[XBOX_LED_COLOUR_ORANGE]);
ReleaseDC(hwnd, hDC);
delete m_Xbe; delete m_Xbe;
@ -1571,6 +1655,9 @@ void WndMain::RefreshMenus()
chk_flag = (m_XInputEnabled) ? MF_CHECKED : MF_UNCHECKED; chk_flag = (m_XInputEnabled) ? MF_CHECKED : MF_UNCHECKED;
CheckMenuItem(settings_menu, ID_SETTINGS_XINPUT, chk_flag); CheckMenuItem(settings_menu, ID_SETTINGS_XINPUT, chk_flag);
chk_flag = (m_DisablePixelShaders) ? MF_CHECKED : MF_UNCHECKED;
CheckMenuItem(settings_menu, ID_HACKS_DISABLEPIXELSHADERS, chk_flag);
} }
// emulation menu // emulation menu
@ -1699,7 +1786,7 @@ void WndMain::OpenXbe(const char *x_filename)
strcpy(m_XbeFilename, x_filename); strcpy(m_XbeFilename, x_filename);
m_Xbe = new Xbe(m_XbeFilename); m_Xbe = new Xbe(m_XbeFilename, true);
if(m_Xbe->HasError()) if(m_Xbe->HasError())
{ {
@ -1906,6 +1993,9 @@ void WndMain::StartEmulation(HWND hwndParent)
// register XInput flags with emulator process // register XInput flags with emulator process
g_EmuShared->SetXInputEnabled(&m_XInputEnabled); g_EmuShared->SetXInputEnabled(&m_XInputEnabled);
// register Hacks with emulator process
g_EmuShared->SetDisablePixelShaders(&m_DisablePixelShaders);
// shell exe // shell exe
{ {
GetModuleFileName(NULL, szBuffer, MAX_PATH); GetModuleFileName(NULL, szBuffer, MAX_PATH);
@ -1954,6 +2044,8 @@ void WndMain::StopEmulation()
// wrapper function to call CrashMonitor // wrapper function to call CrashMonitor
DWORD WINAPI WndMain::CrashMonitorWrapper(LPVOID lpVoid) DWORD WINAPI WndMain::CrashMonitorWrapper(LPVOID lpVoid)
{ {
CxbxSetThreadName("Cxbx Crash Monitor");
static_cast<WndMain*>(lpVoid)->CrashMonitor(); static_cast<WndMain*>(lpVoid)->CrashMonitor();
return 0; return 0;
} }
@ -1961,12 +2053,12 @@ DWORD WINAPI WndMain::CrashMonitorWrapper(LPVOID lpVoid)
// monitor for crashes // monitor for crashes
void WndMain::CrashMonitor() void WndMain::CrashMonitor()
{ {
bool bMultiXbe; bool bQuickReboot;
HANDLE hCrashMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "CrashMutex"); HANDLE hCrashMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "CrashMutex");
DWORD state = WaitForSingleObject(hCrashMutex, INFINITE); DWORD state = WaitForSingleObject(hCrashMutex, INFINITE);
g_EmuShared->GetMultiXbeFlag(&bMultiXbe); g_EmuShared->GetQuickRebootFlag(&bQuickReboot);
if (state == WAIT_OBJECT_0) // StopEmulation if (state == WAIT_OBJECT_0) // StopEmulation
{ {
@ -1974,14 +2066,14 @@ void WndMain::CrashMonitor()
return; return;
} }
if (state == WAIT_ABANDONED && !bMultiXbe) // that's a crash if (state == WAIT_ABANDONED && !bQuickReboot) // that's a crash
{ {
CloseHandle(hCrashMutex); CloseHandle(hCrashMutex);
if (m_bIsStarted) // that's a hard crash, Dr Watson is invoked if (m_bIsStarted) // that's a hard crash, Dr Watson is invoked
{ {
KillTimer(m_hwnd, TIMERID_FPS); KillTimer(m_hwnd, TIMERID_FPS);
//KillTimer(m_hwnd, 2); for the LED KillTimer(m_hwnd, TIMERID_LED);
//DrawDefaultLedBitmap(hwnd); for the LED DrawLedBitmap(m_hwnd, true);
m_hwndChild = NULL; m_hwndChild = NULL;
m_bIsStarted = false; m_bIsStarted = false;
UpdateCaption(); UpdateCaption();
@ -1993,8 +2085,48 @@ void WndMain::CrashMonitor()
// multi-xbe // multi-xbe
// destroy this thread and start a new one // destroy this thread and start a new one
CloseHandle(hCrashMutex); CloseHandle(hCrashMutex);
bMultiXbe = false; bQuickReboot = false;
g_EmuShared->SetMultiXbeFlag(&bMultiXbe); g_EmuShared->SetQuickRebootFlag(&bQuickReboot);
return;
}
// draw Xbox LED bitmap
void WndMain::DrawLedBitmap(HWND hwnd, bool bdefault)
{
HMENU hMenu = GetMenu(hwnd);
int ActiveLEDColor;
// When so requested, or when not emulating, draw a black bitmap
if (bdefault || !m_bIsStarted) {
ActiveLEDColor = XBOX_LED_COLOUR_OFF;
}
else { // draw colored bitmap
int LedSequence[4] = { XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF };
static int LedSequenceOffset = 0;
g_EmuShared->GetLedSequence(LedSequence);
// Select active color and cycle through all 4 phases in the sequence
ActiveLEDColor = LedSequence[LedSequenceOffset & 3];
++LedSequenceOffset;
}
SelectObject(m_LedDC, m_Brushes[ActiveLEDColor]);
SelectObject(m_LedDC, m_Pens[ActiveLEDColor]);
m_OriLed = (HBITMAP)SelectObject(m_LedDC, m_LedBmp);
Rectangle(m_LedDC, 0, 0, m_xBmp, m_yBmp);
m_LedBmp = (HBITMAP)SelectObject(m_LedDC, m_OriLed);
MENUITEMINFO mii = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_FTYPE | MIIM_BITMAP;
mii.fType = MFT_RIGHTJUSTIFY;
mii.hbmpItem = m_LedBmp;
SetMenuItemInfo(hMenu, ID_LED, FALSE, &mii);
DrawMenuBar(hwnd);
return; return;
} }

View File

@ -131,18 +131,29 @@ class WndMain : public Wnd
// ****************************************************************** // ******************************************************************
void CrashMonitor(); void CrashMonitor();
// ****************************************************************** // ******************************************************************
// * drawing information // * draw Xbox LED bitmap
// ****************************************************************** // ******************************************************************
HDC m_BackDC; void DrawLedBitmap(HWND hwnd, bool boolbDefault);
HDC m_LogoDC;
// ******************************************************************
// * drawing information
// ******************************************************************
HDC m_BackDC;
HDC m_LogoDC;
HDC m_GameLogoDC; HDC m_GameLogoDC;
HBITMAP m_OrigBmp; HDC m_LedDC;
HBITMAP m_OrigLogo; HBITMAP m_OrigBmp;
HBITMAP m_OrigLogo;
HBITMAP m_OrigGameLogo; HBITMAP m_OrigGameLogo;
HBITMAP m_BackBmp; HBITMAP m_OriLed;
HBITMAP m_LogoBmp; HBITMAP m_BackBmp;
HBITMAP m_LogoBmp;
HBITMAP m_GameLogoBMP; HBITMAP m_GameLogoBMP;
HBITMAP m_LedBmp;
HBRUSH m_Brushes[4];
HPEN m_Pens[4];
int m_xBmp, m_yBmp;
// ****************************************************************** // ******************************************************************
// * Xbe objects // * Xbe objects
@ -188,10 +199,15 @@ class WndMain : public Wnd
int m_FlagsLLE; int m_FlagsLLE;
// ****************************************************************** // ******************************************************************
// * XInout Enabled Flag // * XInput Enabled Flag
// ****************************************************************** // ******************************************************************
int m_XInputEnabled; int m_XInputEnabled;
// ******************************************************************
// * Hack Flags
// ******************************************************************
int m_DisablePixelShaders;
// ****************************************************************** // ******************************************************************
// * debug output filenames // * debug output filenames
// ****************************************************************** // ******************************************************************

View File

@ -51,7 +51,6 @@ namespace xboxkrnl
#include "EmuEEPROM.h" // For CxbxRestoreEEPROM, EEPROM, XboxFactoryGameRegion #include "EmuEEPROM.h" // For CxbxRestoreEEPROM, EEPROM, XboxFactoryGameRegion
#include "EmuKrnl.h" #include "EmuKrnl.h"
#include "EmuShared.h" #include "EmuShared.h"
#include "EmuNV2A.h" // For InitOpenGLContext
#include "HLEIntercept.h" #include "HLEIntercept.h"
#include "ReservedMemory.h" // For virtual_memory_placeholder #include "ReservedMemory.h" // For virtual_memory_placeholder
#include "VMManager.h" #include "VMManager.h"
@ -63,9 +62,10 @@ namespace xboxkrnl
#include <time.h> // For time() #include <time.h> // For time()
#include <sstream> // For std::ostringstream #include <sstream> // For std::ostringstream
#include "Xbox.h" // For InitXboxHardware() #include "devices\EEPROMDevice.h" // For g_EEPROM
#include "EEPROMDevice.h" // For g_EEPROM #include "devices\video\EmuNV2A.h" // For InitOpenGLContext
#include "LED.h" // For LED::Sequence #include "devices\Xbox.h" // For InitXboxHardware()
#include "devices\LED.h" // For LED::Sequence
/* prevent name collisions */ /* prevent name collisions */
namespace NtDll namespace NtDll
@ -83,7 +83,7 @@ Xbe::Header *CxbxKrnl_XbeHeader = NULL;
HWND CxbxKrnl_hEmuParent = NULL; HWND CxbxKrnl_hEmuParent = NULL;
DebugMode CxbxKrnl_DebugMode = DebugMode::DM_NONE; DebugMode CxbxKrnl_DebugMode = DebugMode::DM_NONE;
char* CxbxKrnl_DebugFileName = NULL; std::string CxbxKrnl_DebugFileName = "";
Xbe::Certificate *g_pCertificate = NULL; Xbe::Certificate *g_pCertificate = NULL;
/*! thread handles */ /*! thread handles */
@ -106,6 +106,9 @@ DWORD_PTR g_CPUOthers = 0;
HANDLE g_CurrentProcessHandle = 0; // Set in CxbxKrnlMain HANDLE g_CurrentProcessHandle = 0; // Set in CxbxKrnlMain
bool g_IsWine = false; bool g_IsWine = false;
bool g_CxbxPrintUEM = false;
ULONG g_CxbxFatalErrorCode = FATAL_ERROR_NONE;
// Define function located in EmuXApi so we can call it from here // Define function located in EmuXApi so we can call it from here
void SetupXboxDeviceTypes(); void SetupXboxDeviceTypes();
@ -486,11 +489,19 @@ void PrintCurrentConfigurationLog()
printf("Unknown Codec is %s\n", XBAudioConf.GetUnknownCodec() ? "enabled" : "disabled"); printf("Unknown Codec is %s\n", XBAudioConf.GetUnknownCodec() ? "enabled" : "disabled");
} }
// Print Enabled Hacks
{
printf("--------------------------- HACKS CONFIG ---------------------------\n");
printf("Disable Pixel Shaders: %s\n", g_DisablePixelShaders == 1 ? "On" : "Off");
}
printf("------------------------- END OF CONFIG LOG ------------------------\n"); printf("------------------------- END OF CONFIG LOG ------------------------\n");
} }
static unsigned int WINAPI CxbxKrnlInterruptThread(PVOID param) static unsigned int WINAPI CxbxKrnlInterruptThread(PVOID param)
{ {
CxbxSetThreadName("CxbxKrnl Interrupts");
// Make sure Xbox1 code runs on one core : // Make sure Xbox1 code runs on one core :
InitXboxThread(g_CPUXbox); InitXboxThread(g_CPUXbox);
@ -510,6 +521,11 @@ static unsigned int WINAPI CxbxKrnlInterruptThread(PVOID param)
void CxbxKrnlMain(int argc, char* argv[]) void CxbxKrnlMain(int argc, char* argv[])
{ {
// Treat this instance as the Xbox runtime entry point XBOXStartup()
// This is defined in OpenXDK:
// import/OpenXDK/include/xhal/xhal.h
CxbxSetThreadName("Cxbx XBOXStartup");
// Skip '/load' switch // Skip '/load' switch
// Get XBE Name : // Get XBE Name :
std::string xbePath = argv[2]; std::string xbePath = argv[2];
@ -527,7 +543,7 @@ void CxbxKrnlMain(int argc, char* argv[])
} }
// Get KernelDebugFileName : // Get KernelDebugFileName :
std::string DebugFileName; std::string DebugFileName = "";
if (argc > 4) { if (argc > 4) {
DebugFileName = argv[5]; DebugFileName = argv[5];
} }
@ -562,6 +578,9 @@ void CxbxKrnlMain(int argc, char* argv[])
} }
} }
// We must save this handle now to keep the child window working in the case we need to display the UEM
CxbxKrnl_hEmuParent = IsWindow(hWnd) ? hWnd : NULL;
g_CurrentProcessHandle = GetCurrentProcess(); // OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); g_CurrentProcessHandle = GetCurrentProcess(); // OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
// Write a header to the log // Write a header to the log
@ -591,6 +610,7 @@ void CxbxKrnlMain(int argc, char* argv[])
g_IsWine = true; g_IsWine = true;
} }
} }
// Now we got the arguments, start by initializing the Xbox memory map : // Now we got the arguments, start by initializing the Xbox memory map :
// PrepareXBoxMemoryMap() // PrepareXBoxMemoryMap()
{ {
@ -644,6 +664,7 @@ void CxbxKrnlMain(int argc, char* argv[])
} }
CxbxRestoreContiguousMemory(szFilePath_memory_bin); CxbxRestoreContiguousMemory(szFilePath_memory_bin);
CxbxRestorePersistentMemoryRegions();
EEPROM = CxbxRestoreEEPROM(szFilePath_EEPROM_bin); EEPROM = CxbxRestoreEEPROM(szFilePath_EEPROM_bin);
if (EEPROM == nullptr) if (EEPROM == nullptr)
@ -660,7 +681,7 @@ void CxbxKrnlMain(int argc, char* argv[])
{ {
// Load Xbe (this one will reside above WinMain's virtual_memory_placeholder) // Load Xbe (this one will reside above WinMain's virtual_memory_placeholder)
g_EmuShared->SetXbePath(xbePath.c_str()); g_EmuShared->SetXbePath(xbePath.c_str());
CxbxKrnl_Xbe = new Xbe(xbePath.c_str()); // TODO : Instead of using the Xbe class, port Dxbx _ReadXbeBlock() CxbxKrnl_Xbe = new Xbe(xbePath.c_str(), false); // TODO : Instead of using the Xbe class, port Dxbx _ReadXbeBlock()
if (CxbxKrnl_Xbe->HasFatalError()) { if (CxbxKrnl_Xbe->HasFatalError()) {
CxbxKrnlCleanup(CxbxKrnl_Xbe->GetError().c_str()); CxbxKrnlCleanup(CxbxKrnl_Xbe->GetError().c_str());
@ -680,8 +701,6 @@ void CxbxKrnlMain(int argc, char* argv[])
g_VMManager.InitializeChihiroDebug(); g_VMManager.InitializeChihiroDebug();
} }
CxbxRestorePersistentMemoryRegions();
// Copy over loaded Xbe Headers to specified base address // Copy over loaded Xbe Headers to specified base address
memcpy((void*)CxbxKrnl_Xbe->m_Header.dwBaseAddr, &CxbxKrnl_Xbe->m_Header, sizeof(Xbe::Header)); memcpy((void*)CxbxKrnl_Xbe->m_Header.dwBaseAddr, &CxbxKrnl_Xbe->m_Header, sizeof(Xbe::Header));
memcpy((void*)(CxbxKrnl_Xbe->m_Header.dwBaseAddr + sizeof(Xbe::Header)), CxbxKrnl_Xbe->m_HeaderEx, CxbxKrnl_Xbe->m_ExSize); memcpy((void*)(CxbxKrnl_Xbe->m_Header.dwBaseAddr + sizeof(Xbe::Header)), CxbxKrnl_Xbe->m_HeaderEx, CxbxKrnl_Xbe->m_ExSize);
@ -732,7 +751,6 @@ void CxbxKrnlMain(int argc, char* argv[])
EntryPoint ^= XOR_EP_KEY[g_XbeType]; EntryPoint ^= XOR_EP_KEY[g_XbeType];
// Launch XBE // Launch XBE
CxbxKrnlInit( CxbxKrnlInit(
hWnd,
XbeTlsData, XbeTlsData,
XbeTls, XbeTls,
CxbxKrnl_Xbe->m_LibraryVersion, CxbxKrnl_Xbe->m_LibraryVersion,
@ -780,15 +798,8 @@ void LoadXboxKeys(std::string path)
EmuWarning("Failed to load Keys.bin. Cxbx-Reloaded will be unable to read Save Data from a real Xbox"); EmuWarning("Failed to load Keys.bin. Cxbx-Reloaded will be unable to read Save Data from a real Xbox");
} }
void SetLEDSequence(LED::Sequence aLEDSequence)
{
// TODO : Move to best suited location & implement
// See http://xboxdevwiki.net/PIC#The_LED
}
__declspec(noreturn) void CxbxKrnlInit __declspec(noreturn) void CxbxKrnlInit
( (
HWND hwndParent,
void *pTLSData, void *pTLSData,
Xbe::TLS *pTLS, Xbe::TLS *pTLS,
Xbe::LibraryVersion *pLibraryVersion, Xbe::LibraryVersion *pLibraryVersion,
@ -802,7 +813,6 @@ __declspec(noreturn) void CxbxKrnlInit
CxbxKrnl_TLS = pTLS; CxbxKrnl_TLS = pTLS;
CxbxKrnl_TLSData = pTLSData; CxbxKrnl_TLSData = pTLSData;
CxbxKrnl_XbeHeader = pXbeHeader; CxbxKrnl_XbeHeader = pXbeHeader;
CxbxKrnl_hEmuParent = IsWindow(hwndParent) ? hwndParent : NULL;
CxbxKrnl_DebugMode = DbgMode; CxbxKrnl_DebugMode = DbgMode;
CxbxKrnl_DebugFileName = (char*)szDebugFilename; CxbxKrnl_DebugFileName = (char*)szDebugFilename;
@ -835,7 +845,7 @@ __declspec(noreturn) void CxbxKrnlInit
" pXBEHeaderSize : 0x%.08X\n" " pXBEHeaderSize : 0x%.08X\n"
" Entry : 0x%.08X\n" " Entry : 0x%.08X\n"
");\n", ");\n",
GetCurrentThreadId(), hwndParent, pTLSData, pTLS, pLibraryVersion, DbgMode, szDebugFilename, pXbeHeader, dwXbeHeaderSize, Entry); GetCurrentThreadId(), CxbxKrnl_hEmuParent, pTLSData, pTLS, pLibraryVersion, DbgMode, szDebugFilename, pXbeHeader, dwXbeHeaderSize, Entry);
#else #else
printf("[0x%X] INIT: Debug Trace Disabled.\n", GetCurrentThreadId()); printf("[0x%X] INIT: Debug Trace Disabled.\n", GetCurrentThreadId());
#endif #endif
@ -877,6 +887,13 @@ __declspec(noreturn) void CxbxKrnlInit
g_XInputEnabled = !!XInputEnabled; g_XInputEnabled = !!XInputEnabled;
} }
// Process Hacks
{
int HackEnabled = 0;
g_EmuShared->GetDisablePixelShaders(&HackEnabled);
g_DisablePixelShaders = !!HackEnabled;
}
#ifdef _DEBUG_PRINT_CURRENT_CONF #ifdef _DEBUG_PRINT_CURRENT_CONF
PrintCurrentConfigurationLog(); PrintCurrentConfigurationLog();
#endif #endif
@ -971,13 +988,7 @@ __declspec(noreturn) void CxbxKrnlInit
} }
} }
// duplicate handle in order to retain Suspend/Resume thread rights from a remote thread CxbxKrnlRegisterThread(GetCurrentThread());
{
HANDLE hDupHandle = NULL;
DuplicateHandle(g_CurrentProcessHandle, GetCurrentThread(), g_CurrentProcessHandle, &hDupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
CxbxKrnlRegisterThread(hDupHandle);
}
// Clear critical section list // Clear critical section list
//extern void InitializeSectionStructures(void); //extern void InitializeSectionStructures(void);
@ -1005,7 +1016,23 @@ __declspec(noreturn) void CxbxKrnlInit
// initialize grapchics // initialize grapchics
DbgPrintf("INIT: Initializing render window.\n"); DbgPrintf("INIT: Initializing render window.\n");
XTL::CxbxInitWindow(pXbeHeader, dwXbeHeaderSize); XTL::CxbxInitWindow(true);
// Now process the boot flags to see if there are any special conditions to handle
int BootFlags = 0;
g_EmuShared->GetBootFlags(&BootFlags);
if (BootFlags & BOOT_EJECT_PENDING) {} // TODO
if (BootFlags & BOOT_FATAL_ERROR)
{
// If we are here it means we have been rebooted to display the fatal error screen. The error code is set
// to 0x15 and the led flashes with the sequence green, red, red, red
SetLEDSequence(0xE1);
CxbxKrnlPrintUEM(FATAL_ERROR_REBOOT_ROUTINE); // won't return
}
if (BootFlags & BOOT_SKIP_ANIMATION) {} // TODO
if (BootFlags & BOOT_RUN_DASHBOARD) {} // TODO
XTL::CxbxInitAudio(); XTL::CxbxInitAudio();
@ -1013,14 +1040,11 @@ __declspec(noreturn) void CxbxKrnlInit
SetupXboxDeviceTypes(); SetupXboxDeviceTypes();
InitXboxHardware(); InitXboxHardware(HardwareModel::Revision1_5); // TODO : Make configurable
// Now the hardware devices exist, couple the EEPROM buffer to it's device // Now the hardware devices exist, couple the EEPROM buffer to it's device
g_EEPROM->SetEEPROM((uint8_t*)EEPROM); g_EEPROM->SetEEPROM((uint8_t*)EEPROM);
// Always initialise NV2A: We may need it for disabled HLE patches too!
EmuNV2A_Init();
if (bLLE_GPU) if (bLLE_GPU)
{ {
DbgPrintf("INIT: Initializing OpenGL.\n"); DbgPrintf("INIT: Initializing OpenGL.\n");
@ -1099,7 +1123,7 @@ void CxbxRestoreLaunchDataPage()
if (LaunchDataPAddr) if (LaunchDataPAddr)
{ {
xboxkrnl::LaunchDataPage = (xboxkrnl::LAUNCH_DATA_PAGE*)CONTIGUOUS_MEMORY_BASE + LaunchDataPAddr; xboxkrnl::LaunchDataPage = (xboxkrnl::LAUNCH_DATA_PAGE*)(CONTIGUOUS_MEMORY_BASE + LaunchDataPAddr);
// Mark the launch page as allocated to prevent other allocations from overwriting it // Mark the launch page as allocated to prevent other allocations from overwriting it
xboxkrnl::MmAllocateContiguousMemoryEx(PAGE_SIZE, LaunchDataPAddr, LaunchDataPAddr + PAGE_SIZE - 1, PAGE_SIZE, PAGE_READWRITE); xboxkrnl::MmAllocateContiguousMemoryEx(PAGE_SIZE, LaunchDataPAddr, LaunchDataPAddr + PAGE_SIZE - 1, PAGE_SIZE, PAGE_READWRITE);
LaunchDataPAddr = NULL; LaunchDataPAddr = NULL;
@ -1156,6 +1180,19 @@ __declspec(noreturn) void CxbxKrnlCleanup(const char *szErrorMessage, ...)
void CxbxKrnlRegisterThread(HANDLE hThread) void CxbxKrnlRegisterThread(HANDLE hThread)
{ {
// we must duplicate this handle in order to retain Suspend/Resume thread rights from a remote thread
{
HANDLE hDupHandle = NULL;
if (DuplicateHandle(g_CurrentProcessHandle, hThread, g_CurrentProcessHandle, &hDupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
hThread = hDupHandle; // Thread handle was duplicated, continue registration with the duplicate
}
else {
auto message = CxbxGetLastErrorString("DuplicateHandle");
EmuWarning(message.c_str());
}
}
int v=0; int v=0;
for(v=0;v<MAXIMUM_XBOX_THREADS;v++) for(v=0;v<MAXIMUM_XBOX_THREADS;v++)
@ -1252,6 +1289,63 @@ void CxbxKrnlResume()
g_bEmuSuspended = false; g_bEmuSuspended = false;
} }
void CxbxKrnlShutDown()
{
if (CxbxKrnl_hEmuParent != NULL)
SendMessage(CxbxKrnl_hEmuParent, WM_PARENTNOTIFY, WM_DESTROY, 0);
EmuShared::Cleanup();
TerminateProcess(g_CurrentProcessHandle, 0);
}
void CxbxKrnlPrintUEM(ULONG ErrorCode)
{
ULONG Type;
xboxkrnl::XBOX_EEPROM Eeprom;
ULONG ResultSize;
int BootFlags;
g_EmuShared->GetBootFlags(&BootFlags);
BootFlags &= ~BOOT_FATAL_ERROR; // clear the fatal error flag to avoid looping here endlessly
g_EmuShared->SetBootFlags(&BootFlags);
NTSTATUS status = xboxkrnl::ExQueryNonVolatileSetting(xboxkrnl::XC_MAX_ALL, &Type, &Eeprom, sizeof(Eeprom), &ResultSize);
if (status == STATUS_SUCCESS)
{
xboxkrnl::XBOX_UEM_INFO* UEMInfo = (xboxkrnl::XBOX_UEM_INFO*)&(Eeprom.UEMInfo[0]);
if (UEMInfo->ErrorCode == FATAL_ERROR_NONE)
{
// ergo720: the Xbox sets the error code and displays the UEM only for non-manufacturing xbe's (it power cycles
// otherwise). Considering that this flag can be easily tampered with in the xbe and the typical end user of cxbx
// can't fix the cause of the fatal error, I decided to always display it anyway.
UEMInfo->ErrorCode = (UCHAR)ErrorCode;
UEMInfo->History |= (1 << (ErrorCode - 5));
}
else {
UEMInfo->ErrorCode = FATAL_ERROR_NONE;
}
xboxkrnl::ExSaveNonVolatileSetting(xboxkrnl::XC_MAX_ALL, Type, &Eeprom, sizeof(Eeprom));
}
else {
CxbxKrnlCleanup("Could not display the fatal error screen");
}
if (g_bIsChihiro)
{
// The Chihiro doesn't display the UEM
CxbxKrnlCleanup("The running Chihiro xbe has encountered a fatal error and needs to close");
}
g_CxbxFatalErrorCode = ErrorCode;
g_CxbxPrintUEM = true; // print the UEM
// Sleep forever to prevent continuing the initialization
Sleep(INFINITE);
}
__declspec(noreturn) void CxbxKrnlTerminateThread() __declspec(noreturn) void CxbxKrnlTerminateThread()
{ {
TerminateThread(GetCurrentThread(), 0); TerminateThread(GetCurrentThread(), 0);

View File

@ -152,6 +152,14 @@ extern "C" {
#define VECTOR2IRQ(vector) ((vector)-IRQ_BASE) #define VECTOR2IRQ(vector) ((vector)-IRQ_BASE)
#define VECTOR2IRQL(vector) (PROFILE_LEVEL - VECTOR2IRQ(vector)) #define VECTOR2IRQL(vector) (PROFILE_LEVEL - VECTOR2IRQ(vector))
// Kernel boot flags
enum {
BOOT_EJECT_PENDING = 1 << 0,
BOOT_FATAL_ERROR = 1 << 1,
BOOT_SKIP_ANIMATION = 1 << 2,
BOOT_RUN_DASHBOARD = 1 << 3,
};
void CxbxPopupMessage(const char *message, ...); void CxbxPopupMessage(const char *message, ...);
#define LOG_TEST_CASE(message) do { static bool bPopupShown = false; \ #define LOG_TEST_CASE(message) do { static bool bPopupShown = false; \
@ -169,7 +177,7 @@ bool CxbxKrnlVerifyVersion(const char *szVersion);
void CxbxKrnlMain(int argc, char* argv[]); void CxbxKrnlMain(int argc, char* argv[]);
/*! initialize emulation */ /*! initialize emulation */
__declspec(noreturn) void CxbxKrnlInit(HWND hwndParent, void *pTLSData, Xbe::TLS *pTLS, Xbe::LibraryVersion *LibraryVersion, DebugMode DbgMode, const char *szDebugFilename, Xbe::Header *XbeHeader, uint32 XbeHeaderSize, void (*Entry)()); __declspec(noreturn) void CxbxKrnlInit(void *pTLSData, Xbe::TLS *pTLS, Xbe::LibraryVersion *LibraryVersion, DebugMode DbgMode, const char *szDebugFilename, Xbe::Header *XbeHeader, uint32 XbeHeaderSize, void (*Entry)());
/*! cleanup emulation */ /*! cleanup emulation */
__declspec(noreturn) void CxbxKrnlCleanup(const char *szErrorMessage, ...); __declspec(noreturn) void CxbxKrnlCleanup(const char *szErrorMessage, ...);
@ -183,6 +191,12 @@ void CxbxKrnlSuspend();
/*! resume emulation */ /*! resume emulation */
void CxbxKrnlResume(); void CxbxKrnlResume();
/*! terminate gracefully the emulation */
void CxbxKrnlShutDown();
/*! display the fatal error message*/
void CxbxKrnlPrintUEM(ULONG ErrorCode);
/*! terminate the calling thread */ /*! terminate the calling thread */
__declspec(noreturn) void CxbxKrnlTerminateThread(); __declspec(noreturn) void CxbxKrnlTerminateThread();
@ -205,6 +219,9 @@ extern uint32 CxbxKrnl_KernelThunkTable[379];
extern bool g_IsWine; extern bool g_IsWine;
extern bool g_CxbxPrintUEM;
extern ULONG g_CxbxFatalErrorCode;
void InitXboxThread(DWORD_PTR cores); void InitXboxThread(DWORD_PTR cores);
/*! thread local storage structure */ /*! thread local storage structure */
@ -221,7 +238,7 @@ extern Xbe *CxbxKrnl_Xbe;
/*! parent window handle */ /*! parent window handle */
extern HWND CxbxKrnl_hEmuParent; extern HWND CxbxKrnl_hEmuParent;
extern DebugMode CxbxKrnl_DebugMode; extern DebugMode CxbxKrnl_DebugMode;
extern char* CxbxKrnl_DebugFileName; extern std::string CxbxKrnl_DebugFileName;
/*! file paths */ /*! file paths */
extern char szFilePath_CxbxReloaded_Exe[MAX_PATH]; extern char szFilePath_CxbxReloaded_Exe[MAX_PATH];
@ -232,4 +249,7 @@ extern char szFilePath_EEPROM_bin[MAX_PATH];
} }
#endif #endif
// Returns the last Win32 error, in string format. Returns an empty string if there is no error.
extern std::string CxbxGetLastErrorString(char * lpszFunction);
#endif #endif

View File

@ -70,6 +70,7 @@ volatile thread_local bool g_bEmuException = false;
volatile bool g_bEmuSuspended = false; volatile bool g_bEmuSuspended = false;
volatile bool g_bPrintfOn = true; volatile bool g_bPrintfOn = true;
bool g_XInputEnabled = false; bool g_XInputEnabled = false;
bool g_DisablePixelShaders = false;
// Delta added to host SystemTime, used in xboxkrnl::KeQuerySystemTime and xboxkrnl::NtSetSystemTime // Delta added to host SystemTime, used in xboxkrnl::KeQuerySystemTime and xboxkrnl::NtSetSystemTime
LARGE_INTEGER HostSystemTimeDelta = {}; LARGE_INTEGER HostSystemTimeDelta = {};

View File

@ -108,4 +108,7 @@ typedef struct DUMMY_KERNEL
IMAGE_SECTION_HEADER SectionHeader; IMAGE_SECTION_HEADER SectionHeader;
} *PDUMMY_KERNEL; } *PDUMMY_KERNEL;
extern bool g_DisablePixelShaders;
#endif #endif

View File

@ -57,6 +57,7 @@ namespace xboxkrnl
#include "Logging.h" #include "Logging.h"
#include "EmuD3D8Logging.h" #include "EmuD3D8Logging.h"
#include "HLEIntercept.h" // for bLLE_GPU #include "HLEIntercept.h" // for bLLE_GPU
#include "Cxbx\\ResCxbx.h"
#include <assert.h> #include <assert.h>
#include <process.h> #include <process.h>
@ -97,8 +98,6 @@ static XTL::DDCAPS g_DriverCaps = { 0 };
static DWORD g_dwOverlayW = 640; // Cached Overlay Width static DWORD g_dwOverlayW = 640; // Cached Overlay Width
static DWORD g_dwOverlayH = 480; // Cached Overlay Height static DWORD g_dwOverlayH = 480; // Cached Overlay Height
static DWORD g_dwOverlayP = 640; // Cached Overlay Pitch static DWORD g_dwOverlayP = 640; // Cached Overlay Pitch
static Xbe::Header *g_XbeHeader = NULL; // XbeHeader
static uint32 g_XbeHeaderSize = 0; // XbeHeaderSize
static HBRUSH g_hBgBrush = NULL; // Background Brush static HBRUSH g_hBgBrush = NULL; // Background Brush
static volatile bool g_bRenderWindowActive = false; static volatile bool g_bRenderWindowActive = false;
static XBVideo g_XBVideo; static XBVideo g_XBVideo;
@ -162,7 +161,7 @@ static XTL::X_VERTEXSHADERCONSTANTMODE g_VertexShaderConstantMode = X_D3DSCM_192
XTL::X_D3DTILE XTL::EmuD3DTileCache[0x08] = {0}; XTL::X_D3DTILE XTL::EmuD3DTileCache[0x08] = {0};
// cached active texture // cached active texture
XTL::X_D3DPixelContainer *XTL::EmuD3DActiveTexture[TEXTURE_STAGES] = {0,0,0,0}; XTL::X_D3DBaseTexture *XTL::EmuD3DActiveTexture[TEXTURE_STAGES] = {0,0,0,0};
// information passed to the create device proxy thread // information passed to the create device proxy thread
@ -394,7 +393,7 @@ const char *CxbxGetErrorDescription(HRESULT hResult)
case DDERR_NOTLOCKED: return "An attempt was made to unlock a surface that was not locked."; case DDERR_NOTLOCKED: return "An attempt was made to unlock a surface that was not locked.";
case DDERR_NOTPAGELOCKED: return "An attempt was made to page-unlock a surface with no outstanding page locks."; case DDERR_NOTPAGELOCKED: return "An attempt was made to page-unlock a surface with no outstanding page locks.";
case DDERR_NOTPALETTIZED: return "The surface being used is not a palette-based surface."; case DDERR_NOTPALETTIZED: return "The surface being used is not a palette-based surface.";
case DDERR_NOVSYNCHW: return "There is no hardware support for vertical blank–synchronized operations."; case DDERR_NOVSYNCHW: return "There is no hardware support for vertical blanksynchronized operations.";
case DDERR_NOZBUFFERHW: return "The operation to create a z-buffer in display memory or to perform a blit, using a z-buffer cannot be carried out because there is no hardware support for z-buffers."; case DDERR_NOZBUFFERHW: return "The operation to create a z-buffer in display memory or to perform a blit, using a z-buffer cannot be carried out because there is no hardware support for z-buffers.";
case DDERR_NOZOVERLAYHW: return "The overlay surfaces cannot be z-layered, based on the z-order because the hardware does not support z-ordering of overlays."; case DDERR_NOZOVERLAYHW: return "The overlay surfaces cannot be z-layered, based on the z-order because the hardware does not support z-ordering of overlays.";
case DDERR_OUTOFCAPS: return "The hardware needed for the requested operation has already been allocated."; case DDERR_OUTOFCAPS: return "The hardware needed for the requested operation has already been allocated.";
@ -452,18 +451,15 @@ const char *D3DErrorString(HRESULT hResult)
return buffer; return buffer;
} }
VOID XTL::CxbxInitWindow(Xbe::Header *XbeHeader, uint32 XbeHeaderSize) VOID XTL::CxbxInitWindow(bool bFullInit)
{ {
g_EmuShared->GetXBVideo(&g_XBVideo); g_EmuShared->GetXBVideo(&g_XBVideo);
if(g_XBVideo.GetFullscreen()) if(g_XBVideo.GetFullscreen())
CxbxKrnl_hEmuParent = NULL; CxbxKrnl_hEmuParent = NULL;
// cache XbeHeader and size of XbeHeader
g_XbeHeader = XbeHeader;
g_XbeHeaderSize = XbeHeaderSize;
// create timing thread // create timing thread
if (bFullInit)
{ {
DWORD dwThreadId; DWORD dwThreadId;
@ -471,14 +467,7 @@ VOID XTL::CxbxInitWindow(Xbe::Header *XbeHeader, uint32 XbeHeaderSize)
// We set the priority of this thread a bit higher, to assure reliable timing : // We set the priority of this thread a bit higher, to assure reliable timing :
SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL); SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);
// we must duplicate this handle in order to retain Suspend/Resume thread rights from a remote thread CxbxKrnlRegisterThread(hThread);
{
HANDLE hDupHandle = NULL;
DuplicateHandle(g_CurrentProcessHandle, hThread, g_CurrentProcessHandle, &hDupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
CxbxKrnlRegisterThread(hDupHandle);
}
} }
/* TODO : Port this Dxbx code : /* TODO : Port this Dxbx code :
@ -506,7 +495,8 @@ VOID XTL::CxbxInitWindow(Xbe::Header *XbeHeader, uint32 XbeHeaderSize)
// Ported from Dxbx : // Ported from Dxbx :
// If possible, assign this thread to another core than the one that runs Xbox1 code : // If possible, assign this thread to another core than the one that runs Xbox1 code :
SetThreadAffinityMask(hRenderWindowThread, g_CPUOthers); if (bFullInit)
SetThreadAffinityMask(hRenderWindowThread, g_CPUOthers);
while(!g_bRenderWindowActive) while(!g_bRenderWindowActive)
SwitchToThread(); SwitchToThread();
@ -517,6 +507,70 @@ VOID XTL::CxbxInitWindow(Xbe::Header *XbeHeader, uint32 XbeHeaderSize)
SetFocus(g_hEmuWindow); SetFocus(g_hEmuWindow);
} }
void DrawUEM(HWND hWnd)
{
// Draw the universal error message (UEM)
// See http://xboxdevwiki.net/Fatal_Error
// Only call this from WM_PAINT message!
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
HDC hDC = GetDC(hWnd);
HDC hMemDC = CreateCompatibleDC(hDC);
HBITMAP hUEMBmp = CreateCompatibleBitmap(hDC, 640, 480);
HBITMAP hOriUEMBmp = (HBITMAP)SelectObject(hMemDC, hUEMBmp);
int nHeight = -MulDiv(8, GetDeviceCaps(hMemDC, LOGPIXELSY), 72);
HFONT hFont = CreateFont(nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_ROMAN, "Verdana");
HGDIOBJ tmpObj = SelectObject(hMemDC, hFont);
SetBkColor(hMemDC, RGB(0, 0, 0));
SetTextColor(hMemDC, RGB(0, 204, 0));
wchar_t buff[500];
LoadStringW(GetModuleHandle(NULL), IDS_UEM, buff, sizeof(buff) / sizeof(wchar_t));
std::wstring wstr(buff);
// Unfortunately, DrawTextW doesn't support vertical alignemnt, so we have to do the calculation
// ourselves. See here: https://social.msdn.microsoft.com/Forums/vstudio/en-US/abd89aae-16a0-41c6-8db6-b119ea90b42a/win32-drawtext-how-center-in-vertical-with-new-lines-and-tabs?forum=vclanguage
RECT rect = { 0, 0, 640, 480 };
RECT textrect = { 0, 0, 640, 480 };
DrawTextW(hMemDC, wstr.c_str(), wstr.length(), &textrect, DT_CALCRECT);
rect.top = (rect.bottom - textrect.bottom) / 2;
DrawTextW(hMemDC, wstr.c_str(), wstr.length(), &rect, DT_CENTER);
// Draw the Xbox error code
SetTextColor(hMemDC, RGB(255, 255, 255));
std::string err_str(std::to_string(g_CxbxFatalErrorCode));
rect.left = 20;
DrawText(hMemDC, err_str.c_str(), err_str.length(), &rect, DT_LEFT);
GetClientRect(hWnd, &rect);
SetStretchBltMode(hDC, COLORONCOLOR);
StretchBlt(hDC, rect.left, rect.top, rect.right, rect.bottom, hMemDC, 0, 0, 640, 480, SRCCOPY);
SelectObject(hMemDC, hOriUEMBmp);
SelectObject(hDC, tmpObj);
DeleteObject(hUEMBmp);
DeleteObject(hFont);
DeleteObject(hMemDC);
if (hDC != NULL)
ReleaseDC(hWnd, hDC);
EndPaint(hWnd, &ps);
}
inline DWORD GetXboxCommonResourceType(const XTL::X_D3DResource *pXboxResource) inline DWORD GetXboxCommonResourceType(const XTL::X_D3DResource *pXboxResource)
{ {
// Don't pass in unassigned Xbox resources // Don't pass in unassigned Xbox resources
@ -991,12 +1045,66 @@ VOID CxbxGetPixelContainerMeasures
} }
} }
bool ConvertD3DTextureToARGBBuffer(
XTL::X_D3DFORMAT X_Format,
uint8 *pSrc,
int SrcWidth, int SrcHeight,
uint SrcPitch,
uint8 *pDest, int DestPitch,
int TextureStage = 0
)
{
const XTL::FormatToARGBRow ConvertRowToARGB = EmuXBFormatComponentConverter(X_Format);
if (ConvertRowToARGB == nullptr)
return false; // Unhandled conversion
uint8 *unswizleBuffer = nullptr;
if (XTL::EmuXBFormatIsSwizzled(X_Format)) {
unswizleBuffer = (uint8*)malloc(SrcPitch * SrcHeight); // TODO : Reuse buffer when performance is important
// First we need to unswizzle the texture data
XTL::EmuUnswizzleRect(
pSrc, SrcWidth, SrcHeight, 1, unswizleBuffer,
SrcPitch, {}, {}, EmuXBFormatBytesPerPixel(X_Format)
);
// Convert colors from the unswizzled buffer
pSrc = unswizleBuffer;
}
int AdditionalArgument;
if (X_Format == XTL::X_D3DFMT_P8)
AdditionalArgument = (int)g_pCurrentPalette[TextureStage];
else
AdditionalArgument = DestPitch;
DWORD SrcRowOff = 0;
uint8 *pDestRow = pDest;
if (EmuXBFormatIsCompressed(X_Format)) {
// All compressed formats (DXT1, DXT3 and DXT5) encode blocks of 4 pixels on 4 lines
SrcHeight = (SrcHeight + 3) / 4;
DestPitch *= 4;
}
for (int y = 0; y < SrcHeight; y++) {
*(int*)pDestRow = AdditionalArgument; // Dirty hack, to avoid an extra parameter to all conversion callbacks
ConvertRowToARGB(pSrc + SrcRowOff, pDestRow, SrcWidth);
SrcRowOff += SrcPitch;
pDestRow += DestPitch;
}
if (unswizleBuffer)
free(unswizleBuffer);
return true;
}
uint8 *XTL::ConvertD3DTextureToARGB( uint8 *XTL::ConvertD3DTextureToARGB(
XTL::X_D3DPixelContainer *pXboxPixelContainer, XTL::X_D3DPixelContainer *pXboxPixelContainer,
uint8 *pSrc, uint8 *pSrc,
int *pWidth, int *pHeight int *pWidth, int *pHeight,
int TextureStage // default = 0
) )
{ {
// Avoid allocating pDest when ConvertD3DTextureToARGBBuffer will fail anyway
XTL::X_D3DFORMAT X_Format = GetXboxPixelContainerFormat(pXboxPixelContainer); XTL::X_D3DFORMAT X_Format = GetXboxPixelContainerFormat(pXboxPixelContainer);
const XTL::FormatToARGBRow ConvertRowToARGB = EmuXBFormatComponentConverter(X_Format); const XTL::FormatToARGBRow ConvertRowToARGB = EmuXBFormatComponentConverter(X_Format);
if (ConvertRowToARGB == nullptr) if (ConvertRowToARGB == nullptr)
@ -1012,43 +1120,18 @@ uint8 *XTL::ConvertD3DTextureToARGB(
&SrcSize &SrcSize
); );
// Now we know ConvertD3DTextureToARGBBuffer will do it's thing, allocate the resulting buffer
int DestPitch = *pWidth * sizeof(DWORD); int DestPitch = *pWidth * sizeof(DWORD);
uint8 *pDest = (uint8 *)malloc(DestPitch * *pHeight); uint8 *pDest = (uint8 *)malloc(DestPitch * *pHeight);
uint8 *unswizleBuffer = nullptr; // And convert the source towards that buffer
if (XTL::EmuXBFormatIsSwizzled(X_Format)) { /*ignore result*/ConvertD3DTextureToARGBBuffer(
unswizleBuffer = (uint8*)malloc(SrcPitch * *pHeight); // TODO : Reuse buffer when performance is important X_Format,
// First we need to unswizzle the texture data pSrc, *pWidth, *pHeight, SrcPitch,
XTL::EmuUnswizzleRect( pDest, DestPitch,
pSrc, *pWidth, *pHeight, 1, unswizleBuffer, TextureStage);
SrcPitch, {}, {}, EmuXBFormatBytesPerPixel(X_Format)
);
// Convert colors from the unswizzled buffer
pSrc = unswizleBuffer;
}
DWORD SrcRowOff = 0;
uint8 *pDestRow = pDest;
if (EmuXBFormatIsCompressed(X_Format)) {
// All compressed formats (DXT1, DXT3 and DXT5) encode blocks of 4 pixels on 4 lines
for (int y = 0; y < *pHeight; y+=4) {
*(int*)pDestRow = DestPitch; // Dirty hack, to avoid an extra parameter to all conversion callbacks
ConvertRowToARGB(pSrc + SrcRowOff, pDestRow, *pWidth);
SrcRowOff += SrcPitch;
pDestRow += DestPitch * 4;
}
}
else {
while (SrcRowOff < SrcSize) {
ConvertRowToARGB(pSrc + SrcRowOff, pDestRow, *pWidth);
SrcRowOff += SrcPitch;
pDestRow += DestPitch;
}
}
if (unswizleBuffer)
free(unswizleBuffer);
// NOTE : Caller must take ownership!
return pDest; return pDest;
} }
@ -1147,6 +1230,8 @@ static BOOL WINAPI EmuEnumDisplayDevices(GUID FAR *lpGUID, LPSTR lpDriverDescrip
// window message processing thread // window message processing thread
static DWORD WINAPI EmuRenderWindow(LPVOID lpVoid) static DWORD WINAPI EmuRenderWindow(LPVOID lpVoid)
{ {
CxbxSetThreadName("Cxbx Render Window");
// register window class // register window class
{ {
LOGBRUSH logBrush = {BS_SOLID, RGB(0,0,0)}; LOGBRUSH logBrush = {BS_SOLID, RGB(0,0,0)};
@ -1169,13 +1254,13 @@ static DWORD WINAPI EmuRenderWindow(LPVOID lpVoid)
RegisterClassEx(&wc); RegisterClassEx(&wc);
} }
bool bMultiXbe; bool bQuickReboot;
g_EmuShared->GetMultiXbeFlag(&bMultiXbe); g_EmuShared->GetQuickRebootFlag(&bQuickReboot);
// precaution for multi-xbe titles in the case CrashMonitor has still not destoyed the previous mutex // precaution for multi-xbe titles in the case CrashMonitor has still not destoyed the previous mutex
while (bMultiXbe) while (bQuickReboot)
{ {
g_EmuShared->GetMultiXbeFlag(&bMultiXbe); g_EmuShared->GetQuickRebootFlag(&bQuickReboot);
} }
HANDLE hCrashMutex = CreateMutex(NULL, TRUE, "CrashMutex"); HANDLE hCrashMutex = CreateMutex(NULL, TRUE, "CrashMutex");
@ -1343,6 +1428,15 @@ static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
} }
break; break;
case WM_PAINT:
{
if (g_CxbxPrintUEM)
{
DrawUEM(hWnd);
}
}
break;
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN:
{ {
if(wParam == VK_RETURN) if(wParam == VK_RETURN)
@ -1480,6 +1574,8 @@ std::chrono::time_point<std::chrono::steady_clock, std::chrono::duration<double,
// timing thread procedure // timing thread procedure
static DWORD WINAPI EmuUpdateTickCount(LPVOID) static DWORD WINAPI EmuUpdateTickCount(LPVOID)
{ {
CxbxSetThreadName("Cxbx Timing Thread");
// since callbacks come from here // since callbacks come from here
InitXboxThread(g_CPUOthers); // avoid Xbox1 core for lowest possible latency InitXboxThread(g_CPUOthers); // avoid Xbox1 core for lowest possible latency
@ -1580,6 +1676,8 @@ static DWORD WINAPI EmuCreateDeviceProxy(LPVOID)
{ {
LOG_FUNC(); LOG_FUNC();
CxbxSetThreadName("Cxbx CreateDevice Proxy");
DbgPrintf("EmuD3D8: CreateDevice proxy thread is running.\n"); DbgPrintf("EmuD3D8: CreateDevice proxy thread is running.\n");
while(true) while(true)
@ -2058,12 +2156,12 @@ static void EmuUnswizzleTextureStages()
for( int i = 0; i < TEXTURE_STAGES; i++ ) for( int i = 0; i < TEXTURE_STAGES; i++ )
{ {
XTL::X_D3DPixelContainer *pPixelContainer = XTL::EmuD3DActiveTexture[i]; XTL::X_D3DBaseTexture *pBaseTexture = XTL::EmuD3DActiveTexture[i];
if (pPixelContainer == NULL) if (pBaseTexture == NULL)
continue; continue;
HRESULT hRet; HRESULT hRet;
XTL::IDirect3DTexture8 *pHostTexture = GetHostTexture(pPixelContainer); XTL::IDirect3DTexture8 *pHostTexture = GetHostTexture(pBaseTexture);
if (pHostTexture != nullptr) if (pHostTexture != nullptr)
{ {
if (pHostTexture->GetType() == XTL::D3DRTYPE_CUBETEXTURE) continue; // Prevent exceptions - skip cubes for now if (pHostTexture->GetType() == XTL::D3DRTYPE_CUBETEXTURE) continue; // Prevent exceptions - skip cubes for now
@ -2071,15 +2169,15 @@ static void EmuUnswizzleTextureStages()
DEBUG_D3DRESULT(hRet, "pHostTexture->UnlockRect"); DEBUG_D3DRESULT(hRet, "pHostTexture->UnlockRect");
} }
if(!IsXboxResourceLocked(pPixelContainer)) if(!IsXboxResourceLocked(pBaseTexture))
continue; continue;
XTL::X_D3DFORMAT XBFormat = GetXboxPixelContainerFormat(pPixelContainer); XTL::X_D3DFORMAT XBFormat = GetXboxPixelContainerFormat(pBaseTexture);
if(!XTL::EmuXBFormatIsSwizzled(XBFormat)) if(!XTL::EmuXBFormatIsSwizzled(XBFormat))
continue; continue;
DWORD dwBPP = XTL::EmuXBFormatBytesPerPixel(XBFormat); DWORD dwBPP = XTL::EmuXBFormatBytesPerPixel(XBFormat);
pPixelContainer->Common &= ~X_D3DCOMMON_ISLOCKED; pBaseTexture->Common &= ~X_D3DCOMMON_ISLOCKED;
// TODO: potentially XXHash32::hash() to see if this surface was actually modified.. // TODO: potentially XXHash32::hash() to see if this surface was actually modified..
@ -2720,6 +2818,8 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SelectVertexShader)
LOG_FUNC_END; LOG_FUNC_END;
HRESULT hRet; HRESULT hRet;
g_CurrentVertexShader = Handle;
if(VshHandleIsVertexShader(Handle)) if(VshHandleIsVertexShader(Handle))
{ {
@ -3090,6 +3190,9 @@ XTL::X_D3DSurface* WINAPI XTL::EMUPATCH(D3DDevice_GetBackBuffer2)
SetHostSurface(pBackBuffer, pNewHostSurface); SetHostSurface(pBackBuffer, pNewHostSurface);
// update data pointer // update data pointer
pBackBuffer->Data = X_D3DRESOURCE_DATA_BACK_BUFFER; pBackBuffer->Data = X_D3DRESOURCE_DATA_BACK_BUFFER;
// Increment reference count
pBackBuffer->Common++; // EMUPATCH(D3DResource_AddRef)(pBackBuffer);
return pBackBuffer; return pBackBuffer;
} }
@ -3297,7 +3400,8 @@ XTL::X_D3DSurface * WINAPI XTL::EMUPATCH(D3DDevice_GetRenderTarget2)()
X_D3DSurface *result = g_pCachedRenderTarget; X_D3DSurface *result = g_pCachedRenderTarget;
EMUPATCH(D3DResource_AddRef)(result); if (result)
result->Common++; // EMUPATCH(D3DResource_AddRef)(result);
RETURN(result); RETURN(result);
} }
@ -3330,7 +3434,8 @@ XTL::X_D3DSurface * WINAPI XTL::EMUPATCH(D3DDevice_GetDepthStencilSurface2)()
X_D3DSurface *result = g_pCachedDepthStencil; X_D3DSurface *result = g_pCachedDepthStencil;
EMUPATCH(D3DResource_AddRef)(result); if (result)
result->Common++; // EMUPATCH(D3DResource_AddRef)(result);
RETURN(result); RETURN(result);
} }
@ -3791,6 +3896,13 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreatePixelShader)
LOG_FUNC_END; LOG_FUNC_END;
HRESULT hRet = E_FAIL; HRESULT hRet = E_FAIL;
// If PixelShader Disable Hack is enabled, return a dummy handle
if (g_DisablePixelShaders) {
*pHandle = X_PIXELSHADER_FAKE_HANDLE;
RETURN(D3D_OK);
}
#if 0 // PatrickvL Dxbx pixel shader translation #if 0 // PatrickvL Dxbx pixel shader translation
// Attempt to recompile PixelShader // Attempt to recompile PixelShader
@ -4423,7 +4535,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_SetIndices)
VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTexture) VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTexture)
( (
DWORD Stage, DWORD Stage,
X_D3DResource *pTexture X_D3DBaseTexture *pTexture
) )
{ {
FUNC_EXPORTS FUNC_EXPORTS
@ -4435,7 +4547,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTexture)
IDirect3DBaseTexture8 *pHostBaseTexture = nullptr; IDirect3DBaseTexture8 *pHostBaseTexture = nullptr;
EmuD3DActiveTexture[Stage] = (X_D3DPixelContainer*)pTexture; EmuD3DActiveTexture[Stage] = pTexture;
if(pTexture != NULL) if(pTexture != NULL)
{ {
EmuVerifyResourceIsRegistered(pTexture); EmuVerifyResourceIsRegistered(pTexture);
@ -4642,11 +4754,6 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_Begin)
g_IVBPrimitiveType = PrimitiveType; g_IVBPrimitiveType = PrimitiveType;
if(g_IVBTable == nullptr)
{
g_IVBTable = (struct XTL::_D3DIVB*)g_VMManager.Allocate(sizeof(XTL::_D3DIVB)*IVB_TABLE_SIZE);
}
g_IVBTblOffs = 0; g_IVBTblOffs = 0;
g_IVBFVF = 0; g_IVBFVF = 0;
@ -4867,7 +4974,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexData4f)
} }
default: default:
CxbxKrnlCleanup("Unknown IVB Register : %d", Register); EmuWarning("Unknown IVB Register : %d", Register);
} }
} }
@ -5215,7 +5322,7 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
{ {
// TODO: once this is known to be working, remove the warning // TODO: once this is known to be working, remove the warning
EmuWarning("Vertex buffer allocation size unknown"); EmuWarning("Vertex buffer allocation size unknown");
dwSize = 0x2000; // temporarily assign a small buffer, which will be increased later dwSize = PAGE_SIZE; // temporarily assign a small buffer, which will be increased later
/*hRet = E_FAIL; /*hRet = E_FAIL;
goto fail;*/ goto fail;*/
} }
@ -5258,7 +5365,7 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
memcpy(pNativeData, (void*)pBase, dwSize); memcpy(pNativeData, (void*)pBase, dwSize);
pNewHostVertexBuffer->Unlock(); pNewHostVertexBuffer->Unlock();
pResource->Data = (DWORD)pNativeData; // For now, give the native buffer memory to Xbox. TODO : g_VMManager.Allocate(..., AllocationType::Contiguous) pResource->Data = (DWORD)pBase; // Set pResource->Data to point to Xbox Vertex buffer memory
} }
DbgPrintf("EmuIDirect3DResource8_Register : Successfully Created VertexBuffer (0x%.08X)\n", pNewHostVertexBuffer); DbgPrintf("EmuIDirect3DResource8_Register : Successfully Created VertexBuffer (0x%.08X)\n", pNewHostVertexBuffer);
@ -5301,7 +5408,9 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
DbgPrintf("EmuIDirect3DResource8_Register :-> Texture...\n"); DbgPrintf("EmuIDirect3DResource8_Register :-> Texture...\n");
} }
X_D3DPixelContainer *pPixelContainer = (X_D3DPixelContainer*)pResource; pBase = (void*)((xbaddr)pBase | MM_SYSTEM_PHYSICAL_MAP);
X_D3DPixelContainer *pPixelContainer = (X_D3DPixelContainer*)pResource;
X_D3DFORMAT X_Format = GetXboxPixelContainerFormat(pPixelContainer); X_D3DFORMAT X_Format = GetXboxPixelContainerFormat(pPixelContainer);
D3DFORMAT PCFormat = EmuXB2PC_D3DFormat(X_Format); D3DFORMAT PCFormat = EmuXB2PC_D3DFormat(X_Format);
@ -5327,9 +5436,20 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
// Let's try using some 16-bit format instead... // Let's try using some 16-bit format instead...
if(X_Format == X_D3DFMT_X1R5G5B5 ) if(X_Format == X_D3DFMT_X1R5G5B5 )
{ {
#ifdef OLD_COLOR_CONVERSION // Current approach
EmuWarning( "X_D3DFMT_X1R5G5B5 -> D3DFMT_R5GB5" ); EmuWarning( "X_D3DFMT_X1R5G5B5 -> D3DFMT_R5GB5" );
X_Format = X_D3DFMT_R5G6B5; X_Format = X_D3DFMT_R5G6B5;
PCFormat = D3DFMT_R5G6B5; PCFormat = D3DFMT_R5G6B5;
#else // Later, convert to ARGB :
CacheFormat = PCFormat; // Save this for later
PCFormat = D3DFMT_A8R8G8B8; // ARGB
}
// Detect formats that must be converted to ARGB
if (EmuXBFormatRequiresConversionToARGB(X_Format)) {
CacheFormat = PCFormat; // Save this for later
PCFormat = D3DFMT_A8R8G8B8; // ARGB
#endif // !OLD_COLOR_CONVERSION
} }
DWORD dwWidth, dwHeight, dwBPP, dwDepth = 1, dwPitch = 0, dwMipMapLevels = 1; DWORD dwWidth, dwHeight, dwBPP, dwDepth = 1, dwPitch = 0, dwMipMapLevels = 1;
@ -5484,6 +5604,7 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
dwMipMapLevels = 3; dwMipMapLevels = 3;
} }
#ifdef OLD_COLOR_CONVERSION // Current palette approach - Later, use ______P8ToARGBRow_C()
// HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK // HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK
// Since most modern graphics cards does not support // Since most modern graphics cards does not support
// palette based textures we need to expand it to // palette based textures we need to expand it to
@ -5498,6 +5619,7 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
CacheFormat = PCFormat; // Save this for later CacheFormat = PCFormat; // Save this for later
PCFormat = D3DFMT_A8R8G8B8; // ARGB PCFormat = D3DFMT_A8R8G8B8; // ARGB
} }
#endif // OLD_COLOR_CONVERSION
if(bCubemap) if(bCubemap)
{ {
@ -5623,6 +5745,39 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
{ {
// TODO: Fix or handle this situation..? // TODO: Fix or handle this situation..?
} }
#ifndef OLD_COLOR_CONVERSION // Later, use ConvertD3DTextureToARGBBuffer
else if (CacheFormat != 0) // Do we need to convert to ARGB?
{
EmuWarning("Unsupported texture format, expanding to D3DFMT_A8R8G8B8");
BYTE *pPixelData = (BYTE*)LockedRect.pBits;
DWORD dwDataSize = dwMipWidth*dwMipHeight;
DWORD* pExpandedTexture = (DWORD*)malloc(dwDataSize * sizeof(DWORD));
uint8 *pSrc = pPixelData;
uint8 *pDest = (uint8 *)pExpandedTexture;
DWORD dwSrcPitch = dwMipWidth * dwBPP;//sizeof(DWORD);
DWORD dwDestPitch = dwMipWidth * sizeof(DWORD);
DWORD dwMipSizeInBytes = dwDataSize;
// Convert a row at a time, using a libyuv-like callback approach :
if (!ConvertD3DTextureToARGBBuffer(
X_Format,
pSrc, dwMipWidth, dwMipHeight, dwSrcPitch,
pDest, dwDestPitch,
TextureStage)) {
CxbxKrnlCleanup("Unhandled conversion!");
}
//__asm int 3;
// Copy the expanded texture back to the buffer
memcpy(pPixelData, pExpandedTexture, dwDataSize * sizeof(DWORD));
// Flush unused data buffers
free(pExpandedTexture);
}
#endif // !OLD_COLOR_CONVERSION
else else
{ {
if (bSwizzled) if (bSwizzled)
@ -5680,6 +5835,7 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
} }
} }
#ifdef OLD_COLOR_CONVERSION // Currently, convert here. Later, use ConvertD3DTextureToARGBBuffer above
if (CacheFormat != 0) // Do we need to convert to ARGB? if (CacheFormat != 0) // Do we need to convert to ARGB?
{ {
EmuWarning("Unsupported texture format, expanding to D3DFMT_A8R8G8B8"); EmuWarning("Unsupported texture format, expanding to D3DFMT_A8R8G8B8");
@ -5720,7 +5876,6 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
} }
else else
{ {
#ifdef OLD_COLOR_CONVERSION
const ComponentEncodingInfo *encoding = EmuXBFormatComponentEncodingInfo(X_Format); const ComponentEncodingInfo *encoding = EmuXBFormatComponentEncodingInfo(X_Format);
for (unsigned int y = 0; y < dwDataSize; y++) for (unsigned int y = 0; y < dwDataSize; y++)
@ -5747,26 +5902,6 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
w += dwMipWidth * (sizeof(DWORD) - dwBPP); w += dwMipWidth * (sizeof(DWORD) - dwBPP);
} }
} }
#else // !OLD_COLOR_CONVERSION
// Convert a row at a time, using a libyuv-like callback approach :
const FormatToARGBRow ConvertRowToARGB = EmuXBFormatComponentConverter(X_Format);
if (ConvertRowToARGB == nullptr)
CxbxKrnlCleanup("Unhandled conversion!");
uint8 *pSrc = pPixelData;
uint8 *pDest = (uint8 *)pExpandedTexture;
DWORD dwSrcPitch = dwMipWidth * sizeof(DWORD);
DWORD dwDestPitch = dwMipWidth * sizeof(DWORD);
DWORD dwMipSizeInBytes = dwDataSize;
DWORD SrcRowOff = 0;
uint8 *pDestRow = (uint8 *)pDest;
while (SrcRowOff < dwMipSizeInBytes) {
ConvertRowToARGB(((uint8 *)pSrc) + SrcRowOff, pDestRow, dwMipWidth);
SrcRowOff += dwSrcPitch;
pDestRow += dwDestPitch;
}
#endif // !OLD_COLOR_CONVERSION
} }
//__asm int 3; //__asm int 3;
@ -5776,6 +5911,7 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
// Flush unused data buffers // Flush unused data buffers
free(pExpandedTexture); free(pExpandedTexture);
} }
#endif // !OLD_COLOR_CONVERSION
} }
} }
@ -5889,7 +6025,7 @@ ULONG WINAPI XTL::EMUPATCH(D3DResource_AddRef)
X_D3DResource *pThis X_D3DResource *pThis
) )
{ {
FUNC_EXPORTS // FUNC_EXPORTS
LOG_FUNC_ONE_ARG(pThis); LOG_FUNC_ONE_ARG(pThis);
@ -7873,7 +8009,7 @@ XTL::X_D3DVertexBuffer* WINAPI XTL::EMUPATCH(D3DDevice_GetStreamSource2)
pVertexBuffer = g_D3DStreams[StreamNumber]; pVertexBuffer = g_D3DStreams[StreamNumber];
if (pVertexBuffer) if (pVertexBuffer)
{ {
EMUPATCH(D3DResource_AddRef)(pVertexBuffer); pVertexBuffer->Common++; // EMUPATCH(D3DResource_AddRef)(pVertexBuffer);
*pStride = g_D3DStreamStrides[StreamNumber]; *pStride = g_D3DStreamStrides[StreamNumber];
} }
} }
@ -7934,7 +8070,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetStreamSource)
#ifdef _DEBUG_TRACK_VB #ifdef _DEBUG_TRACK_VB
if(pStreamData != NULL) if(pStreamData != NULL)
{ {
g_bVBSkipStream = g_VBTrackDisable.exists(GetHostVertexBuffer(pStreamData)); g_bVBSkipStream = g_VBTrackDisable.exists(pHostVertexBuffer);
} }
#endif #endif
@ -8904,7 +9040,36 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_LoadVertexShaderProgram)
LOG_FUNC_ARG(Address) LOG_FUNC_ARG(Address)
LOG_FUNC_END; LOG_FUNC_END;
LOG_UNIMPLEMENTED(); // NOTE: Azurik needs this to work, but this implementation makes
// Sonic Heroes (E3 Demo) run slower and look a bit worse. An investigation
// may be necessary...
#if 1
DWORD Handle = g_CurrentVertexShader;
// TODO: Cache vertex shaders? Azurik overwrites the same vertex shader
// slot over and over again with many different vertex shaders per frame...
if( VshHandleIsVertexShader(Handle) )
{
X_D3DVertexShader *pD3DVertexShader = (X_D3DVertexShader *)(Handle & 0x7FFFFFFF);
VERTEX_SHADER *pVertexShader = (VERTEX_SHADER *)pD3DVertexShader->Handle;
// Save the contents of the existing vertex shader program
DWORD* pDeclaration = (DWORD*) malloc( pVertexShader->DeclarationSize );
memmove( pDeclaration, pVertexShader->pDeclaration, pVertexShader->DeclarationSize );
// Delete the vertex shader
EMUPATCH(D3DDevice_DeleteVertexShader)(Handle);
// Re-create the vertex shader with the new code
HRESULT hr = EMUPATCH(D3DDevice_CreateVertexShader)( pDeclaration, pFunction, &Handle, 0 );
free(pDeclaration);
if( FAILED( hr ) )
CxbxKrnlCleanup( "Error re-creating vertex shader!" );
EMUPATCH(D3DDevice_LoadVertexShader)(Handle, Address);
EMUPATCH(D3DDevice_SelectVertexShader)(Handle, Address);
}
#endif
} }
// ****************************************************************** // ******************************************************************
@ -9609,18 +9774,38 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_KickPushBuffer)()
// ****************************************************************** // ******************************************************************
// * patch: D3DDevice_GetTexture2 // * patch: D3DDevice_GetTexture2
// ****************************************************************** // ******************************************************************
XTL::X_D3DResource* WINAPI XTL::EMUPATCH(D3DDevice_GetTexture2)(DWORD Stage) XTL::X_D3DBaseTexture* WINAPI XTL::EMUPATCH(D3DDevice_GetTexture2)(DWORD Stage)
{ {
FUNC_EXPORTS FUNC_EXPORTS
LOG_FUNC_ONE_ARG(Stage); LOG_FUNC_ONE_ARG(Stage);
// Get the active texture from this stage // Get the active texture from this stage
X_D3DPixelContainer* pRet = EmuD3DActiveTexture[Stage]; X_D3DBaseTexture* pRet = EmuD3DActiveTexture[Stage];
if (pRet) {
pRet->Common++; // EMUPATCH(D3DResource_AddRef)(pRet);
}
return pRet; return pRet;
} }
// ******************************************************************
// * patch: D3DDevice_GetTexture
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_GetTexture)
(
DWORD Stage,
XTL::X_D3DBaseTexture **pTexture
)
{
FUNC_EXPORTS
LOG_FORWARD("D3DDevice_GetTexture2");
*pTexture = EMUPATCH(D3DDevice_GetTexture2)(Stage);
}
// ****************************************************************** // ******************************************************************
// * patch: D3DDevice_SetStateVB (D3D::CDevice::SetStateVB) // * patch: D3DDevice_SetStateVB (D3D::CDevice::SetStateVB)
// ****************************************************************** // ******************************************************************
@ -9759,7 +9944,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_PersistDisplay)()
// ****************************************************************** // ******************************************************************
DWORD WINAPI XTL::EMUPATCH(D3D_CMiniport_GetDisplayCapabilities)() DWORD WINAPI XTL::EMUPATCH(D3D_CMiniport_GetDisplayCapabilities)()
{ {
FUNC_EXPORTS //FUNC_EXPORTS
LOG_FUNC(); LOG_FUNC();

View File

@ -43,7 +43,7 @@
#include <ddraw.h> #include <ddraw.h>
// initialize render window // initialize render window
extern VOID CxbxInitWindow(Xbe::Header *XbeHeader, uint32 XbeHeaderSize); extern VOID CxbxInitWindow(bool bFullInit);
extern VOID CxbxSetPixelContainerHeader extern VOID CxbxSetPixelContainerHeader
( (
@ -60,7 +60,8 @@ extern VOID CxbxSetPixelContainerHeader
extern uint8 *ConvertD3DTextureToARGB( extern uint8 *ConvertD3DTextureToARGB(
XTL::X_D3DPixelContainer *pXboxPixelContainer, XTL::X_D3DPixelContainer *pXboxPixelContainer,
uint8 *pSrc, uint8 *pSrc,
int *pWidth, int *pHeight int *pWidth, int *pHeight,
int TextureStage = 0
); );
// initialize direct3d // initialize direct3d
@ -73,7 +74,7 @@ extern VOID EmuD3DCleanup();
extern X_D3DTILE EmuD3DTileCache[0x08]; extern X_D3DTILE EmuD3DTileCache[0x08];
// EmuD3DActiveTexture // EmuD3DActiveTexture
extern X_D3DPixelContainer *EmuD3DActiveTexture[TEXTURE_STAGES]; extern X_D3DBaseTexture *EmuD3DActiveTexture[TEXTURE_STAGES];
// ****************************************************************** // ******************************************************************
// * patch: Direct3D_CreateDevice // * patch: Direct3D_CreateDevice
@ -559,7 +560,7 @@ HRESULT WINAPI EMUPATCH(D3DDevice_SetIndices)
VOID WINAPI EMUPATCH(D3DDevice_SetTexture) VOID WINAPI EMUPATCH(D3DDevice_SetTexture)
( (
DWORD Stage, DWORD Stage,
X_D3DResource *pTexture X_D3DBaseTexture *pTexture
); );
// ****************************************************************** // ******************************************************************
@ -1735,7 +1736,16 @@ VOID WINAPI EMUPATCH(D3DDevice_KickPushBuffer)();
// ****************************************************************** // ******************************************************************
// * patch: D3DDevice_GetTexture2 // * patch: D3DDevice_GetTexture2
// ****************************************************************** // ******************************************************************
X_D3DResource* WINAPI EMUPATCH(D3DDevice_GetTexture2)(DWORD Stage); X_D3DBaseTexture* WINAPI EMUPATCH(D3DDevice_GetTexture2)(DWORD Stage);
// ******************************************************************
// * patch: D3DDevice_GetTexture
// ******************************************************************
VOID WINAPI EMUPATCH(D3DDevice_GetTexture)
(
DWORD Stage,
X_D3DBaseTexture **pTexture
);
// ****************************************************************** // ******************************************************************
// * patch: D3DDevice_SetStateVB (D3D::CDevice::SetStateVB) // * patch: D3DDevice_SetStateVB (D3D::CDevice::SetStateVB)

View File

@ -51,15 +51,15 @@
enum _ComponentEncoding { enum _ComponentEncoding {
NoCmpnts = 0, // Format doesn't contain any component (ARGB/QWVU) NoCmpnts = 0, // Format doesn't contain any component (ARGB/QWVU)
A1R5G5B5, A1R5G5B5,
X1R5G5B5, X1R5G5B5, // NOTE : A=255
A4R4G4B4, A4R4G4B4,
__R5G6B5, // NOTE : A=255 __R5G6B5, // NOTE : A=255
A8R8G8B8, A8R8G8B8,
X8R8G8B8, X8R8G8B8, // NOTE : A=255
____R8B8, // NOTE : A takes R, G takes B ____R8B8, // NOTE : A takes R, G takes B
____G8B8, // NOTE : A takes G, R takes B ____G8B8, // NOTE : A takes G, R takes B
______A8, ______A8, // TEST : R=G=B= 255
__R6G5B5, __R6G5B5, // NOTE : A=255
R5G5B5A1, R5G5B5A1,
R4G4B4A4, R4G4B4A4,
A8B8G8R8, A8B8G8R8,
@ -754,8 +754,8 @@ enum _FormatStorage {
Cmprsd // Compressed Cmprsd // Compressed
}; };
enum _FormatSpecial { enum _FormatUsage {
None = 0, Texture = 0,
RenderTarget, RenderTarget,
DepthBuffer DepthBuffer
}; };
@ -765,7 +765,7 @@ typedef struct _FormatInfo {
_FormatStorage stored; _FormatStorage stored;
_ComponentEncoding components; _ComponentEncoding components;
XTL::D3DFORMAT pc; XTL::D3DFORMAT pc;
_FormatSpecial special; _FormatUsage usage;
char *warning; char *warning;
} FormatInfo; } FormatInfo;
@ -781,7 +781,7 @@ static const FormatInfo FormatInfos[] = {
// to ARGB is needed (which is implemented in EMUPATCH(D3DResource_Register). // to ARGB is needed (which is implemented in EMUPATCH(D3DResource_Register).
/* 0x00 X_D3DFMT_L8 */ { 8, Swzzld, ______L8, XTL::D3DFMT_L8 }, /* 0x00 X_D3DFMT_L8 */ { 8, Swzzld, ______L8, XTL::D3DFMT_L8 },
/* 0x01 X_D3DFMT_AL8 */ { 8, Swzzld, _____AL8, XTL::D3DFMT_L8 , None, "X_D3DFMT_AL8 -> D3DFMT_L8" }, /* 0x01 X_D3DFMT_AL8 */ { 8, Swzzld, _____AL8, XTL::D3DFMT_L8 , Texture, "X_D3DFMT_AL8 -> D3DFMT_L8" },
/* 0x02 X_D3DFMT_A1R5G5B5 */ { 16, Swzzld, A1R5G5B5, XTL::D3DFMT_A1R5G5B5 }, /* 0x02 X_D3DFMT_A1R5G5B5 */ { 16, Swzzld, A1R5G5B5, XTL::D3DFMT_A1R5G5B5 },
/* 0x03 X_D3DFMT_X1R5G5B5 */ { 16, Swzzld, X1R5G5B5, XTL::D3DFMT_X1R5G5B5 , RenderTarget }, /* 0x03 X_D3DFMT_X1R5G5B5 */ { 16, Swzzld, X1R5G5B5, XTL::D3DFMT_X1R5G5B5 , RenderTarget },
/* 0x04 X_D3DFMT_A4R4G4B4 */ { 16, Swzzld, A4R4G4B4, XTL::D3DFMT_A4R4G4B4 }, /* 0x04 X_D3DFMT_A4R4G4B4 */ { 16, Swzzld, A4R4G4B4, XTL::D3DFMT_A4R4G4B4 },
@ -802,12 +802,12 @@ static const FormatInfo FormatInfos[] = {
/* 0x13 X_D3DFMT_LIN_L8 */ { 8, Linear, ______L8, XTL::D3DFMT_L8 , RenderTarget }, /* 0x13 X_D3DFMT_LIN_L8 */ { 8, Linear, ______L8, XTL::D3DFMT_L8 , RenderTarget },
/* 0x14 undefined */ {}, /* 0x14 undefined */ {},
/* 0x15 undefined */ {}, /* 0x15 undefined */ {},
/* 0x16 X_D3DFMT_LIN_R8B8 */ { 16, Linear, ____R8B8, XTL::D3DFMT_R5G6B5 , None, "X_D3DFMT_LIN_R8B8 -> D3DFMT_R5G6B5" }, /* 0x16 X_D3DFMT_LIN_R8B8 */ { 16, Linear, ____R8B8, XTL::D3DFMT_R5G6B5 , Texture, "X_D3DFMT_LIN_R8B8 -> D3DFMT_R5G6B5" },
/* 0x17 X_D3DFMT_LIN_G8B8 */ { 16, Linear, ____G8B8, XTL::D3DFMT_R5G6B5 , RenderTarget, "X_D3DFMT_LIN_G8B8 -> D3DFMT_R5G6B5" }, // Alias : X_D3DFMT_LIN_V8U8 /* 0x17 X_D3DFMT_LIN_G8B8 */ { 16, Linear, ____G8B8, XTL::D3DFMT_R5G6B5 , RenderTarget, "X_D3DFMT_LIN_G8B8 -> D3DFMT_R5G6B5" }, // Alias : X_D3DFMT_LIN_V8U8
/* 0x18 undefined */ {}, /* 0x18 undefined */ {},
/* 0x19 X_D3DFMT_A8 */ { 8, Swzzld, ______A8, XTL::D3DFMT_A8 }, /* 0x19 X_D3DFMT_A8 */ { 8, Swzzld, ______A8, XTL::D3DFMT_A8 },
/* 0x1A X_D3DFMT_A8L8 */ { 16, Swzzld, ____A8L8, XTL::D3DFMT_A8L8 }, /* 0x1A X_D3DFMT_A8L8 */ { 16, Swzzld, ____A8L8, XTL::D3DFMT_A8L8 },
/* 0x1B X_D3DFMT_LIN_AL8 */ { 8, Linear, _____AL8, XTL::D3DFMT_L8 , None, "X_D3DFMT_LIN_AL8 -> D3DFMT_L8" }, /* 0x1B X_D3DFMT_LIN_AL8 */ { 8, Linear, _____AL8, XTL::D3DFMT_L8 , Texture, "X_D3DFMT_LIN_AL8 -> D3DFMT_L8" },
/* 0x1C X_D3DFMT_LIN_X1R5G5B5 */ { 16, Linear, X1R5G5B5, XTL::D3DFMT_X1R5G5B5 , RenderTarget }, /* 0x1C X_D3DFMT_LIN_X1R5G5B5 */ { 16, Linear, X1R5G5B5, XTL::D3DFMT_X1R5G5B5 , RenderTarget },
/* 0x1D X_D3DFMT_LIN_A4R4G4B4 */ { 16, Linear, A4R4G4B4, XTL::D3DFMT_A4R4G4B4 }, /* 0x1D X_D3DFMT_LIN_A4R4G4B4 */ { 16, Linear, A4R4G4B4, XTL::D3DFMT_A4R4G4B4 },
/* 0x1E X_D3DFMT_LIN_X8R8G8B8 */ { 32, Linear, X8R8G8B8, XTL::D3DFMT_X8R8G8B8 , RenderTarget }, // Alias : X_D3DFMT_LIN_X8L8V8U8 /* 0x1E X_D3DFMT_LIN_X8R8G8B8 */ { 32, Linear, X8R8G8B8, XTL::D3DFMT_X8R8G8B8 , RenderTarget }, // Alias : X_D3DFMT_LIN_X8L8V8U8
@ -821,31 +821,31 @@ static const FormatInfo FormatInfos[] = {
/* 0x26 undefined */ {}, /* 0x26 undefined */ {},
/* 0x27 X_D3DFMT_L6V5U5 */ { 16, Swzzld, __R6G5B5, XTL::D3DFMT_L6V5U5 }, // Alias : X_D3DFMT_R6G5B5 // XQEMU NOTE : This might be signed /* 0x27 X_D3DFMT_L6V5U5 */ { 16, Swzzld, __R6G5B5, XTL::D3DFMT_L6V5U5 }, // Alias : X_D3DFMT_R6G5B5 // XQEMU NOTE : This might be signed
/* 0x28 X_D3DFMT_V8U8 */ { 16, Swzzld, ____G8B8, XTL::D3DFMT_V8U8 }, // Alias : X_D3DFMT_G8B8 // XQEMU NOTE : This might be signed /* 0x28 X_D3DFMT_V8U8 */ { 16, Swzzld, ____G8B8, XTL::D3DFMT_V8U8 }, // Alias : X_D3DFMT_G8B8 // XQEMU NOTE : This might be signed
/* 0x29 X_D3DFMT_R8B8 */ { 16, Swzzld, ____R8B8, XTL::D3DFMT_R5G6B5 , None, "X_D3DFMT_R8B8 -> D3DFMT_R5G6B5" }, // XQEMU NOTE : This might be signed /* 0x29 X_D3DFMT_R8B8 */ { 16, Swzzld, ____R8B8, XTL::D3DFMT_R5G6B5 , Texture, "X_D3DFMT_R8B8 -> D3DFMT_R5G6B5" }, // XQEMU NOTE : This might be signed
/* 0x2A X_D3DFMT_D24S8 */ { 32, Swzzld, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer }, /* 0x2A X_D3DFMT_D24S8 */ { 32, Swzzld, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer },
/* 0x2B X_D3DFMT_F24S8 */ { 32, Swzzld, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer, "X_D3DFMT_F24S8 -> D3DFMT_D24S8" }, // HACK : PC doesn't have D3DFMT_F24S8 (Float vs Int) /* 0x2B X_D3DFMT_F24S8 */ { 32, Swzzld, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer, "X_D3DFMT_F24S8 -> D3DFMT_D24S8" }, // HACK : PC doesn't have D3DFMT_F24S8 (Float vs Int)
/* 0x2C X_D3DFMT_D16 */ { 16, Swzzld, NoCmpnts, XTL::D3DFMT_D16 , DepthBuffer }, // Alias : X_D3DFMT_D16_LOCKABLE // TODO : D3DFMT_D16 is always lockable on Xbox; Should PC use D3DFMT_D16_LOCKABLE instead? Needs testcase. /* 0x2C X_D3DFMT_D16 */ { 16, Swzzld, NoCmpnts, XTL::D3DFMT_D16_LOCKABLE, DepthBuffer }, // Alias : X_D3DFMT_D16_LOCKABLE // Note : D3DFMT_D16 is always lockable on Xbox, D3DFMT_D16 on host is not.
/* 0x2D X_D3DFMT_F16 */ { 16, Swzzld, NoCmpnts, XTL::D3DFMT_D16 , DepthBuffer, "X_D3DFMT_F16 -> D3DFMT_D16" }, // HACK : PC doesn't have D3DFMT_F16 (Float vs Int) /* 0x2D X_D3DFMT_F16 */ { 16, Swzzld, NoCmpnts, XTL::D3DFMT_D16_LOCKABLE, DepthBuffer, "X_D3DFMT_F16 -> D3DFMT_D16" }, // HACK : PC doesn't have D3DFMT_F16 (Float vs Int)
/* 0x2E X_D3DFMT_LIN_D24S8 */ { 32, Linear, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer }, /* 0x2E X_D3DFMT_LIN_D24S8 */ { 32, Linear, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer },
/* 0x2F X_D3DFMT_LIN_F24S8 */ { 32, Linear, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer, "X_D3DFMT_LIN_F24S8 -> D3DFMT_D24S8" }, // HACK : PC doesn't have D3DFMT_F24S8 (Float vs Int) /* 0x2F X_D3DFMT_LIN_F24S8 */ { 32, Linear, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer, "X_D3DFMT_LIN_F24S8 -> D3DFMT_D24S8" }, // HACK : PC doesn't have D3DFMT_F24S8 (Float vs Int)
/* 0x30 X_D3DFMT_LIN_D16 */ { 16, Linear, NoCmpnts, XTL::D3DFMT_D16 , DepthBuffer }, // TODO : D3DFMT_D16 is always lockable on Xbox; Should PC use D3DFMT_D16_LOCKABLE instead? Needs testcase. /* 0x30 X_D3DFMT_LIN_D16 */ { 16, Linear, NoCmpnts, XTL::D3DFMT_D16_LOCKABLE, DepthBuffer }, // Note : D3DFMT_D16 is always lockable on Xbox, D3DFMT_D16 on host is not.
/* 0x31 X_D3DFMT_LIN_F16 */ { 16, Linear, NoCmpnts, XTL::D3DFMT_D16 , DepthBuffer, "X_D3DFMT_LIN_F16 -> D3DFMT_D16" }, // HACK : PC doesn't have D3DFMT_F16 (Float vs Int) /* 0x31 X_D3DFMT_LIN_F16 */ { 16, Linear, NoCmpnts, XTL::D3DFMT_D16_LOCKABLE, DepthBuffer, "X_D3DFMT_LIN_F16 -> D3DFMT_D16" }, // HACK : PC doesn't have D3DFMT_F16 (Float vs Int)
/* 0x32 X_D3DFMT_L16 */ { 16, Swzzld, _____L16, XTL::D3DFMT_A8L8 , None, "X_D3DFMT_L16 -> D3DFMT_A8L8" }, /* 0x32 X_D3DFMT_L16 */ { 16, Swzzld, _____L16, XTL::D3DFMT_A8L8 , Texture, "X_D3DFMT_L16 -> D3DFMT_A8L8" },
/* 0x33 X_D3DFMT_V16U16 */ { 32, Swzzld, NoCmpnts, XTL::D3DFMT_V16U16 }, /* 0x33 X_D3DFMT_V16U16 */ { 32, Swzzld, NoCmpnts, XTL::D3DFMT_V16U16 },
/* 0x34 undefined */ {}, /* 0x34 undefined */ {},
/* 0x35 X_D3DFMT_LIN_L16 */ { 16, Linear, _____L16, XTL::D3DFMT_A8L8 , None, "X_D3DFMT_LIN_L16 -> D3DFMT_A8L8" }, /* 0x35 X_D3DFMT_LIN_L16 */ { 16, Linear, _____L16, XTL::D3DFMT_A8L8 , Texture, "X_D3DFMT_LIN_L16 -> D3DFMT_A8L8" },
/* 0x36 X_D3DFMT_LIN_V16U16 */ { 32, Linear, NoCmpnts, XTL::D3DFMT_V16U16 }, /* 0x36 X_D3DFMT_LIN_V16U16 */ { 32, Linear, NoCmpnts, XTL::D3DFMT_V16U16 },
/* 0x37 X_D3DFMT_LIN_L6V5U5 */ { 16, Linear, __R6G5B5, XTL::D3DFMT_L6V5U5 }, // Alias : X_D3DFMT_LIN_R6G5B5 /* 0x37 X_D3DFMT_LIN_L6V5U5 */ { 16, Linear, __R6G5B5, XTL::D3DFMT_L6V5U5 }, // Alias : X_D3DFMT_LIN_R6G5B5
/* 0x38 X_D3DFMT_R5G5B5A1 */ { 16, Swzzld, R5G5B5A1, XTL::D3DFMT_A1R5G5B5 , None, "X_D3DFMT_R5G5B5A1 -> D3DFMT_A1R5G5B5" }, /* 0x38 X_D3DFMT_R5G5B5A1 */ { 16, Swzzld, R5G5B5A1, XTL::D3DFMT_A1R5G5B5 , Texture, "X_D3DFMT_R5G5B5A1 -> D3DFMT_A1R5G5B5" },
/* 0x39 X_D3DFMT_R4G4B4A4 */ { 16, Swzzld, R4G4B4A4, XTL::D3DFMT_A4R4G4B4 , None, "X_D3DFMT_R4G4B4A4 -> D3DFMT_A4R4G4B4" }, /* 0x39 X_D3DFMT_R4G4B4A4 */ { 16, Swzzld, R4G4B4A4, XTL::D3DFMT_A4R4G4B4 , Texture, "X_D3DFMT_R4G4B4A4 -> D3DFMT_A4R4G4B4" },
/* 0x3A X_D3DFMT_Q8W8V8U8 */ { 32, Swzzld, A8B8G8R8, XTL::D3DFMT_Q8W8V8U8 }, // Alias : X_D3DFMT_A8B8G8R8 // TODO : Needs testcase. /* 0x3A X_D3DFMT_Q8W8V8U8 */ { 32, Swzzld, A8B8G8R8, XTL::D3DFMT_Q8W8V8U8 }, // Alias : X_D3DFMT_A8B8G8R8 // TODO : Needs testcase.
/* 0x3B X_D3DFMT_B8G8R8A8 */ { 32, Swzzld, B8G8R8A8, XTL::D3DFMT_A8R8G8B8 , None, "X_D3DFMT_B8G8R8A8 -> D3DFMT_A8R8G8B8" }, /* 0x3B X_D3DFMT_B8G8R8A8 */ { 32, Swzzld, B8G8R8A8, XTL::D3DFMT_A8R8G8B8 , Texture, "X_D3DFMT_B8G8R8A8 -> D3DFMT_A8R8G8B8" },
/* 0x3C X_D3DFMT_R8G8B8A8 */ { 32, Swzzld, R8G8B8A8, XTL::D3DFMT_A8R8G8B8 , None, "X_D3DFMT_R8G8B8A8 -> D3DFMT_A8R8G8B8" }, /* 0x3C X_D3DFMT_R8G8B8A8 */ { 32, Swzzld, R8G8B8A8, XTL::D3DFMT_A8R8G8B8 , Texture, "X_D3DFMT_R8G8B8A8 -> D3DFMT_A8R8G8B8" },
/* 0x3D X_D3DFMT_LIN_R5G5B5A1 */ { 16, Linear, R5G5B5A1, XTL::D3DFMT_A1R5G5B5 , None, "X_D3DFMT_LIN_R5G5B5A1 -> D3DFMT_A1R5G5B5" }, /* 0x3D X_D3DFMT_LIN_R5G5B5A1 */ { 16, Linear, R5G5B5A1, XTL::D3DFMT_A1R5G5B5 , Texture, "X_D3DFMT_LIN_R5G5B5A1 -> D3DFMT_A1R5G5B5" },
/* 0x3E X_D3DFMT_LIN_R4G4B4A4 */ { 16, Linear, R4G4B4A4, XTL::D3DFMT_A4R4G4B4 , None, "X_D3DFMT_LIN_R4G4B4A4 -> D3DFMT_A4R4G4B4" }, /* 0x3E X_D3DFMT_LIN_R4G4B4A4 */ { 16, Linear, R4G4B4A4, XTL::D3DFMT_A4R4G4B4 , Texture, "X_D3DFMT_LIN_R4G4B4A4 -> D3DFMT_A4R4G4B4" },
/* 0x3F X_D3DFMT_LIN_A8B8G8R8 */ { 32, Linear, A8B8G8R8, XTL::D3DFMT_A8R8G8B8 , None, "X_D3DFMT_LIN_A8B8G8R8 -> D3DFMT_A8R8G8B8" }, /* 0x3F X_D3DFMT_LIN_A8B8G8R8 */ { 32, Linear, A8B8G8R8, XTL::D3DFMT_A8R8G8B8 , Texture, "X_D3DFMT_LIN_A8B8G8R8 -> D3DFMT_A8R8G8B8" },
/* 0x40 X_D3DFMT_LIN_B8G8R8A8 */ { 32, Linear, B8G8R8A8, XTL::D3DFMT_A8R8G8B8 , None, "X_D3DFMT_LIN_B8G8R8A8 -> D3DFMT_A8R8G8B8" }, /* 0x40 X_D3DFMT_LIN_B8G8R8A8 */ { 32, Linear, B8G8R8A8, XTL::D3DFMT_A8R8G8B8 , Texture, "X_D3DFMT_LIN_B8G8R8A8 -> D3DFMT_A8R8G8B8" },
/* 0x41 X_D3DFMT_LIN_R8G8B8A8 */ { 32, Linear, R8G8B8A8, XTL::D3DFMT_A8R8G8B8 , None, "X_D3DFMT_LIN_R8G8B8A8 -> D3DFMT_A8R8G8B8" }, /* 0x41 X_D3DFMT_LIN_R8G8B8A8 */ { 32, Linear, R8G8B8A8, XTL::D3DFMT_A8R8G8B8 , Texture, "X_D3DFMT_LIN_R8G8B8A8 -> D3DFMT_A8R8G8B8" },
#if 0 #if 0
/* 0x42 to 0x63 undefined */ {},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}, /* 0x42 to 0x63 undefined */ {},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
/* 0x64 X_D3DFMT_VERTEXDATA */ { 8, Linear, NoCmpnts, XTL::D3DFMT_VERTEXDATA }, /* 0x64 X_D3DFMT_VERTEXDATA */ { 8, Linear, NoCmpnts, XTL::D3DFMT_VERTEXDATA },
@ -883,17 +883,28 @@ const XTL::FormatToARGBRow XTL::EmuXBFormatComponentConverter(X_D3DFORMAT Format
return nullptr; return nullptr;
} }
// Is there a converter available from the supplied format to ARGB?
bool XTL::EmuXBFormatCanBeConvertedToARGB(X_D3DFORMAT Format)
{
const FormatToARGBRow info = EmuXBFormatComponentConverter(Format);
return (info != nullptr);
}
// Returns if convertion to ARGB is required. This is the case when
// the format has a warning message and there's a converter present.
bool XTL::EmuXBFormatRequiresConversionToARGB(X_D3DFORMAT Format) bool XTL::EmuXBFormatRequiresConversionToARGB(X_D3DFORMAT Format)
{ {
#ifdef OLD_COLOR_CONVERSION #ifdef OLD_COLOR_CONVERSION
const ComponentEncodingInfo *info = EmuXBFormatComponentEncodingInfo(Format); const ComponentEncodingInfo *info = EmuXBFormatComponentEncodingInfo(Format);
#else // !OLD_COLOR_CONVERSION
const FormatToARGBRow info = EmuXBFormatComponentConverter(Format);
#endif // !OLD_COLOR_CONVERSION
// Conversion is required if there's ARGB conversion info present, and the format has a warning message // Conversion is required if there's ARGB conversion info present, and the format has a warning message
if (info != nullptr) if (info != nullptr)
if (FormatInfos[Format].warning != nullptr) if (FormatInfos[Format].warning != nullptr)
return true; return true;
#else // !OLD_COLOR_CONVERSION
if (FormatInfos[Format].warning != nullptr)
if (EmuXBFormatCanBeConvertedToARGB(Format))
return true;
#endif // !OLD_COLOR_CONVERSION
return false; return false;
} }
@ -939,7 +950,7 @@ BOOL XTL::EmuXBFormatIsSwizzled(X_D3DFORMAT Format)
BOOL XTL::EmuXBFormatIsRenderTarget(X_D3DFORMAT Format) BOOL XTL::EmuXBFormatIsRenderTarget(X_D3DFORMAT Format)
{ {
if (Format <= X_D3DFMT_LIN_R8G8B8A8) if (Format <= X_D3DFMT_LIN_R8G8B8A8)
return (FormatInfos[Format].special == RenderTarget); return (FormatInfos[Format].usage == RenderTarget);
return false; return false;
} }
@ -947,7 +958,7 @@ BOOL XTL::EmuXBFormatIsRenderTarget(X_D3DFORMAT Format)
BOOL XTL::EmuXBFormatIsDepthBuffer(X_D3DFORMAT Format) BOOL XTL::EmuXBFormatIsDepthBuffer(X_D3DFORMAT Format)
{ {
if (Format <= X_D3DFMT_LIN_R8G8B8A8) if (Format <= X_D3DFMT_LIN_R8G8B8A8)
return (FormatInfos[Format].special == DepthBuffer); return (FormatInfos[Format].usage == DepthBuffer);
return false; return false;
} }

7
src/CxbxKrnl/EmuD3D8/Convert.h Normal file → Executable file
View File

@ -36,6 +36,11 @@
#include "CxbxKrnl.h" #include "CxbxKrnl.h"
// It's a real shame but the new conversion code needs to be disable for now
// it causes crashes and other issues in titles using palletted textures
// It seems draw time conversion is really required before this can function
// correctly.
#define OLD_COLOR_CONVERSION #define OLD_COLOR_CONVERSION
// simple render state encoding lookup table // simple render state encoding lookup table
@ -58,6 +63,8 @@ typedef void(*FormatToARGBRow)(const uint8* src, uint8* dst_argb, int width);
extern const FormatToARGBRow EmuXBFormatComponentConverter(X_D3DFORMAT Format); extern const FormatToARGBRow EmuXBFormatComponentConverter(X_D3DFORMAT Format);
bool EmuXBFormatCanBeConvertedToARGB(X_D3DFORMAT Format);
bool EmuXBFormatRequiresConversionToARGB(X_D3DFORMAT Format); bool EmuXBFormatRequiresConversionToARGB(X_D3DFORMAT Format);
// how many bits does this format use per pixel? // how many bits does this format use per pixel?

28
src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp Normal file → Executable file
View File

@ -53,7 +53,7 @@
XTL::DWORD *XTL::g_pIVBVertexBuffer = nullptr; XTL::DWORD *XTL::g_pIVBVertexBuffer = nullptr;
XTL::X_D3DPRIMITIVETYPE XTL::g_IVBPrimitiveType = XTL::X_D3DPT_INVALID; XTL::X_D3DPRIMITIVETYPE XTL::g_IVBPrimitiveType = XTL::X_D3DPT_INVALID;
UINT XTL::g_IVBTblOffs = 0; UINT XTL::g_IVBTblOffs = 0;
struct XTL::_D3DIVB *XTL::g_IVBTable = nullptr; struct XTL::_D3DIVB XTL::g_IVBTable[IVB_TABLE_SIZE];
extern DWORD XTL::g_IVBFVF = 0; extern DWORD XTL::g_IVBFVF = 0;
extern XTL::X_D3DVertexBuffer *g_pVertexBuffer = NULL; extern XTL::X_D3DVertexBuffer *g_pVertexBuffer = NULL;
@ -639,18 +639,18 @@ bool XTL::VertexPatcher::NormalizeTexCoords(VertexPatchDesc *pPatchDesc, UINT ui
{ {
// Check for active linear textures. // Check for active linear textures.
bool bHasLinearTex = false, bTexIsLinear[4] = { false }; bool bHasLinearTex = false, bTexIsLinear[4] = { false };
X_D3DPixelContainer *pLinearPixelContainer[4]; X_D3DBaseTexture *pLinearBaseTexture[4];
for(uint08 i = 0; i < 4; i++) for(uint08 i = 0; i < 4; i++)
{ {
X_D3DPixelContainer *pPixelContainer = EmuD3DActiveTexture[i]; X_D3DBaseTexture *pBaseTexture = EmuD3DActiveTexture[i];
if (pPixelContainer) if (pBaseTexture)
{ {
XTL::X_D3DFORMAT XBFormat = (XTL::X_D3DFORMAT)((pPixelContainer->Format & X_D3DFORMAT_FORMAT_MASK) >> X_D3DFORMAT_FORMAT_SHIFT); XTL::X_D3DFORMAT XBFormat = (XTL::X_D3DFORMAT)((pBaseTexture->Format & X_D3DFORMAT_FORMAT_MASK) >> X_D3DFORMAT_FORMAT_SHIFT);
if (EmuXBFormatIsLinear(XBFormat)) if (EmuXBFormatIsLinear(XBFormat))
{ {
bHasLinearTex = bTexIsLinear[i] = true; bHasLinearTex = bTexIsLinear[i] = true;
pLinearPixelContainer[i] = pPixelContainer; pLinearBaseTexture[i] = pBaseTexture;
} }
} }
} }
@ -741,8 +741,8 @@ bool XTL::VertexPatcher::NormalizeTexCoords(VertexPatchDesc *pPatchDesc, UINT ui
{ {
if(bTexIsLinear[0]) if(bTexIsLinear[0])
{ {
((FLOAT*)pUVData)[0] /= ( pLinearPixelContainer[0]->Size & X_D3DSIZE_WIDTH_MASK) + 1; ((FLOAT*)pUVData)[0] /= ( pLinearBaseTexture[0]->Size & X_D3DSIZE_WIDTH_MASK) + 1;
((FLOAT*)pUVData)[1] /= ((pLinearPixelContainer[0]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1; ((FLOAT*)pUVData)[1] /= ((pLinearBaseTexture[0]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
} }
pUVData += sizeof(FLOAT) * 2; pUVData += sizeof(FLOAT) * 2;
} }
@ -751,8 +751,8 @@ bool XTL::VertexPatcher::NormalizeTexCoords(VertexPatchDesc *pPatchDesc, UINT ui
{ {
if(bTexIsLinear[1]) if(bTexIsLinear[1])
{ {
((FLOAT*)pUVData)[0] /= ( pLinearPixelContainer[1]->Size & X_D3DSIZE_WIDTH_MASK) + 1; ((FLOAT*)pUVData)[0] /= ( pLinearBaseTexture[1]->Size & X_D3DSIZE_WIDTH_MASK) + 1;
((FLOAT*)pUVData)[1] /= ((pLinearPixelContainer[1]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1; ((FLOAT*)pUVData)[1] /= ((pLinearBaseTexture[1]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
} }
pUVData += sizeof(FLOAT) * 2; pUVData += sizeof(FLOAT) * 2;
} }
@ -761,16 +761,16 @@ bool XTL::VertexPatcher::NormalizeTexCoords(VertexPatchDesc *pPatchDesc, UINT ui
{ {
if(bTexIsLinear[2]) if(bTexIsLinear[2])
{ {
((FLOAT*)pUVData)[0] /= ( pLinearPixelContainer[2]->Size & X_D3DSIZE_WIDTH_MASK) + 1; ((FLOAT*)pUVData)[0] /= ( pLinearBaseTexture[2]->Size & X_D3DSIZE_WIDTH_MASK) + 1;
((FLOAT*)pUVData)[1] /= ((pLinearPixelContainer[2]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1; ((FLOAT*)pUVData)[1] /= ((pLinearBaseTexture[2]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
} }
pUVData += sizeof(FLOAT) * 2; pUVData += sizeof(FLOAT) * 2;
} }
if((dwTexN >= 4) && bTexIsLinear[3]) if((dwTexN >= 4) && bTexIsLinear[3])
{ {
((FLOAT*)pUVData)[0] /= ( pLinearPixelContainer[3]->Size & X_D3DSIZE_WIDTH_MASK) + 1; ((FLOAT*)pUVData)[0] /= ( pLinearBaseTexture[3]->Size & X_D3DSIZE_WIDTH_MASK) + 1;
((FLOAT*)pUVData)[1] /= ((pLinearPixelContainer[3]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1; ((FLOAT*)pUVData)[1] /= ((pLinearBaseTexture[3]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
} }
} }

12
src/CxbxKrnl/EmuD3D8/VertexBuffer.h Normal file → Executable file
View File

@ -130,12 +130,13 @@ extern DWORD *g_pIVBVertexBuffer;
extern X_D3DPRIMITIVETYPE g_IVBPrimitiveType; extern X_D3DPRIMITIVETYPE g_IVBPrimitiveType;
extern DWORD g_IVBFVF; extern DWORD g_IVBFVF;
#define IVB_TABLE_SIZE 1024 #define IVB_TABLE_SIZE 4096 // This should be more than enough. Tweak as necessary if it overflows or the resulting VertexBuffer fails to allocate
#define IVB_BUFFER_SIZE sizeof(_D3DIVB)*1024 #define IVB_BUFFER_SIZE sizeof(_D3DIVB) * IVB_TABLE_SIZE
// TODO : Enlarge IVB_TABLE_SIZE and IVB_BUFFER_SIZE // TODO : Enlarge IVB_TABLE_SIZE and IVB_BUFFER_SIZE
// TODO : Calculate IVB_BUFFER_SIZE using sizeof(DWORD) // TODO : Calculate IVB_BUFFER_SIZE using sizeof(DWORD)
extern struct _D3DIVB struct _D3DIVB
{ {
XTL::D3DXVECTOR3 Position; // Position XTL::D3DXVECTOR3 Position; // Position
FLOAT Rhw; // Rhw FLOAT Rhw; // Rhw
@ -147,8 +148,9 @@ extern struct _D3DIVB
XTL::D3DXVECTOR2 TexCoord2; // TexCoord2 XTL::D3DXVECTOR2 TexCoord2; // TexCoord2
XTL::D3DXVECTOR2 TexCoord3; // TexCoord3 XTL::D3DXVECTOR2 TexCoord3; // TexCoord3
XTL::D3DXVECTOR2 TexCoord4; // TexCoord4 XTL::D3DXVECTOR2 TexCoord4; // TexCoord4
} };
*g_IVBTable;
extern _D3DIVB g_IVBTable[IVB_TABLE_SIZE];
extern UINT g_IVBTblOffs; extern UINT g_IVBTblOffs;

View File

@ -2194,6 +2194,12 @@ extern HRESULT XTL::EmuRecompileVshFunction
// The size of the shader is // The size of the shader is
*pOriginalSize = (DWORD)pToken - (DWORD)pFunction; *pOriginalSize = (DWORD)pToken - (DWORD)pFunction;
// Do not attempt to compile empty shaders
if (pShader->IntermediateCount == 0) {
EmuWarning("Skipped empty Pixel Shader");
return STATUS_INVALID_PARAMETER;
}
char* pShaderDisassembly = (char*)malloc(pShader->IntermediateCount * 100); // Should be plenty char* pShaderDisassembly = (char*)malloc(pShader->IntermediateCount * 100); // Should be plenty
DbgVshPrintf("-- Before conversion --\n"); DbgVshPrintf("-- Before conversion --\n");
VshWriteShader(pShader, pShaderDisassembly, FALSE); VshWriteShader(pShader, pShaderDisassembly, FALSE);

View File

@ -135,7 +135,6 @@ XTL::X_XFileMediaObject::_vtbl XTL::X_XFileMediaObject::vtbl =
&XTL::EMUPATCH(XFileMediaObject_DoWork), // 0x24 &XTL::EMUPATCH(XFileMediaObject_DoWork), // 0x24
}; };
/* NOTE: SUCCEEDED define is only checking for is equal or greater than zero value. /* NOTE: SUCCEEDED define is only checking for is equal or greater than zero value.
And FAILED check for less than zero value. Since DS_OK is only 0 base on DirectSound documentation, And FAILED check for less than zero value. Since DS_OK is only 0 base on DirectSound documentation,
there is chance of failure which contain value greater than 0. there is chance of failure which contain value greater than 0.
@ -3345,7 +3344,7 @@ HRESULT WINAPI XTL::EMUPATCH(XFileCreateMediaObjectEx)
HANDLE hFile, HANDLE hFile,
OUT void** ppMediaObject) OUT void** ppMediaObject)
{ {
FUNC_EXPORTS; //FUNC_EXPORTS;
enterCriticalSection; enterCriticalSection;
@ -3370,7 +3369,7 @@ HRESULT WINAPI XTL::EMUPATCH(XWaveFileCreateMediaObject)
LPCWAVEFORMATEX* ppwfxFormat, LPCWAVEFORMATEX* ppwfxFormat,
OUT void** ppMediaObject) //XFileMediaObject, include XMediaObject interface OUT void** ppMediaObject) //XFileMediaObject, include XMediaObject interface
{ {
FUNC_EXPORTS; //FUNC_EXPORTS;
enterCriticalSection; enterCriticalSection;
@ -3590,7 +3589,7 @@ HRESULT WINAPI XTL::EMUPATCH(XFileCreateMediaObjectAsync)
DWORD dwMaxPackets, DWORD dwMaxPackets,
OUT void** ppMediaObject) OUT void** ppMediaObject)
{ {
FUNC_EXPORTS; //FUNC_EXPORTS;
enterCriticalSection; enterCriticalSection;
@ -3619,7 +3618,7 @@ HRESULT WINAPI XTL::EMUPATCH(XFileMediaObject_Seek)
DWORD dwOrigin, DWORD dwOrigin,
LPDWORD pdwAbsolute) LPDWORD pdwAbsolute)
{ {
FUNC_EXPORTS; //FUNC_EXPORTS;
enterCriticalSection; enterCriticalSection;
@ -3642,7 +3641,7 @@ HRESULT WINAPI XTL::EMUPATCH(XFileMediaObject_Seek)
// ****************************************************************** // ******************************************************************
VOID WINAPI XTL::EMUPATCH(XFileMediaObject_DoWork)(X_XFileMediaObject* pThis) VOID WINAPI XTL::EMUPATCH(XFileMediaObject_DoWork)(X_XFileMediaObject* pThis)
{ {
FUNC_EXPORTS; //FUNC_EXPORTS;
enterCriticalSection; enterCriticalSection;
@ -3661,7 +3660,7 @@ HRESULT WINAPI XTL::EMUPATCH(XFileMediaObject_GetStatus)
X_XFileMediaObject* pThis, X_XFileMediaObject* pThis,
OUT LPDWORD pdwStatus) OUT LPDWORD pdwStatus)
{ {
FUNC_EXPORTS; //FUNC_EXPORTS;
enterCriticalSection; enterCriticalSection;
@ -3685,7 +3684,7 @@ HRESULT WINAPI XTL::EMUPATCH(XFileMediaObject_GetInfo)
X_XFileMediaObject* pThis, X_XFileMediaObject* pThis,
OUT XMEDIAINFO* pInfo) OUT XMEDIAINFO* pInfo)
{ {
FUNC_EXPORTS; //FUNC_EXPORTS;
enterCriticalSection; enterCriticalSection;
@ -3710,7 +3709,7 @@ HRESULT WINAPI XTL::EMUPATCH(XFileMediaObject_Process)
LPXMEDIAPACKET pInputBuffer, LPXMEDIAPACKET pInputBuffer,
LPXMEDIAPACKET pOutputBuffer) LPXMEDIAPACKET pOutputBuffer)
{ {
FUNC_EXPORTS; //FUNC_EXPORTS;
enterCriticalSection; enterCriticalSection;
@ -3734,7 +3733,7 @@ ULONG WINAPI XTL::EMUPATCH(XFileMediaObject_AddRef)
( (
X_XFileMediaObject* pThis) X_XFileMediaObject* pThis)
{ {
FUNC_EXPORTS; //FUNC_EXPORTS;
enterCriticalSection; enterCriticalSection;
@ -3758,7 +3757,7 @@ ULONG WINAPI XTL::EMUPATCH(XFileMediaObject_Release)
( (
X_XFileMediaObject* pThis) X_XFileMediaObject* pThis)
{ {
FUNC_EXPORTS; //FUNC_EXPORTS;
enterCriticalSection; enterCriticalSection;
@ -3785,7 +3784,7 @@ HRESULT WINAPI XTL::EMUPATCH(XFileMediaObject_Discontinuity)
( (
X_XFileMediaObject *pThis) X_XFileMediaObject *pThis)
{ {
FUNC_EXPORTS; //FUNC_EXPORTS;
enterCriticalSection; enterCriticalSection;
@ -3908,7 +3907,7 @@ HRESULT WINAPI XTL::EMUPATCH(XFileCreateMediaObject)
DWORD dwFlagsAndAttributes, DWORD dwFlagsAndAttributes,
OUT void** ppMediaObject) OUT void** ppMediaObject)
{ {
FUNC_EXPORTS; //FUNC_EXPORTS;
enterCriticalSection; enterCriticalSection;
@ -3937,7 +3936,7 @@ HRESULT WINAPI XTL::EMUPATCH(XWaveFileCreateMediaObjectEx)
HANDLE hFile, HANDLE hFile,
OUT void** ppMediaObject) //XWaveFileMediaObject, include XFileMediaObject and XMediaObject interfaces OUT void** ppMediaObject) //XWaveFileMediaObject, include XFileMediaObject and XMediaObject interfaces
{ {
FUNC_EXPORTS; //FUNC_EXPORTS;
enterCriticalSection; enterCriticalSection;

View File

@ -188,8 +188,16 @@ void CxbxFormatPartitionByHandle(HANDLE hFile)
// In this case, experimental means that these functions work and are safe // In this case, experimental means that these functions work and are safe
// but not officially in the C++ standard yet // but not officially in the C++ standard yet
// Requires a compiler with C++17 support // Requires a compiler with C++17 support
std::experimental::filesystem::remove_all(partitionPath); try
std::experimental::filesystem::create_directory(partitionPath); {
std::experimental::filesystem::remove_all(partitionPath);
std::experimental::filesystem::create_directory(partitionPath);
}
catch (std::experimental::filesystem::filesystem_error fsException)
{
printf("std::experimental::filesystem failed with message: %s\n", fsException.what());
}
printf("Formatted EmuDisk Partition%d\n", CxbxGetPartitionNumberFromHandle(hFile)); printf("Formatted EmuDisk Partition%d\n", CxbxGetPartitionNumberFromHandle(hFile));
} }
@ -323,6 +331,16 @@ void copy_string_to_PSTRING_to(std::string const & src, const xboxkrnl::PSTRING
memcpy(dest->Buffer, src.c_str(), dest->Length); memcpy(dest->Buffer, src.c_str(), dest->Length);
} }
void replace_all(std::string& str, const std::string& from, const std::string& to) {
if(from.empty())
return;
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
}
NTSTATUS CxbxConvertFilePath( NTSTATUS CxbxConvertFilePath(
std::string RelativeXboxPath, std::string RelativeXboxPath,
OUT std::wstring &RelativeHostPath, OUT std::wstring &RelativeHostPath,
@ -415,6 +433,9 @@ NTSTATUS CxbxConvertFilePath(
HostPath.append(1, '\\'); HostPath.append(1, '\\');
} }
// Lastly, remove any '\\' sequences in the string (this should fix the problem with Azurik game saves)
replace_all( RelativePath, "\\\\", "\\" );
if (g_bPrintfOn) { if (g_bPrintfOn) {
DbgPrintf("FILE: %s Corrected path...\n", aFileAPIName.c_str()); DbgPrintf("FILE: %s Corrected path...\n", aFileAPIName.c_str());
printf(" Org:\"%s\"\n", OriginalPath.c_str()); printf(" Org:\"%s\"\n", OriginalPath.c_str());

View File

@ -51,12 +51,13 @@ namespace xboxkrnl
#include "Emu.h" // For EmuWarning() #include "Emu.h" // For EmuWarning()
#include "EmuKrnl.h" #include "EmuKrnl.h"
#include "EmuX86.h" // HalReadWritePciSpace needs this #include "EmuX86.h" // HalReadWritePciSpace needs this
#include "SMBus.h" // For g_SMBus
#include "EmuEEPROM.h" // For EEPROM
#include "SMCDevice.h" // For SMC_COMMAND_SCRATCH
#include "EmuShared.h" #include "EmuShared.h"
#include "EmuFile.h" // For FindNtSymbolicLinkObjectByDriveLetter #include "EmuFile.h" // For FindNtSymbolicLinkObjectByDriveLetter
#include "Common\EmuEEPROM.h" // For EEPROM
#include "devices\Xbox.h" // For g_SMBus, SMBUS_ADDRESS_SYSTEM_MICRO_CONTROLLER
#include "devices\SMCDevice.h" // For SMC_COMMAND_SCRATCH
#include <algorithm> // for std::replace
#include <locale> #include <locale>
#include <codecvt> #include <codecvt>
@ -69,6 +70,14 @@ namespace NtDll
static DWORD EmuSoftwareInterrupRequestRegister = 0; static DWORD EmuSoftwareInterrupRequestRegister = 0;
HalSystemInterrupt HalSystemInterrupts[MAX_BUS_INTERRUPT_LEVEL + 1]; HalSystemInterrupt HalSystemInterrupts[MAX_BUS_INTERRUPT_LEVEL + 1];
// variables used by the SMC to know a reset / shutdown is pending
uint8_t ResetOrShutdownCommandCode = 0;
uint32_t ResetOrShutdownDataValue = 0;
// global list of routines executed during a reboot
LIST_ENTRY_INITIALIZE_HEAD(ShutdownRoutineList);
// ****************************************************************** // ******************************************************************
// * 0x0009 - HalReadSMCTrayState() // * 0x0009 - HalReadSMCTrayState()
// ****************************************************************** // ******************************************************************
@ -371,9 +380,46 @@ XBSYSAPI EXPORTNUM(47) xboxkrnl::VOID NTAPI xboxkrnl::HalRegisterShutdownNotific
LOG_FUNC_BEGIN LOG_FUNC_BEGIN
LOG_FUNC_ARG(ShutdownRegistration) LOG_FUNC_ARG(ShutdownRegistration)
LOG_FUNC_ARG(Register) LOG_FUNC_ARG(Register)
LOG_FUNC_END; LOG_FUNC_END;
LOG_UNIMPLEMENTED(); PLIST_ENTRY ListEntry;
KIRQL OldIrql;
OldIrql = KeRaiseIrqlToDpcLevel();
if (Register)
{
ListEntry = ShutdownRoutineList.Flink;
while (ListEntry != &ShutdownRoutineList)
{
if (ShutdownRegistration->Priority > LIST_ENTRY_ACCESS_RECORD(ListEntry, HAL_SHUTDOWN_REGISTRATION, ListEntry)->Priority)
{
LIST_ENTRY_INSERT_TAIL(ListEntry, &ShutdownRegistration->ListEntry)
break;
}
ListEntry = ListEntry->Flink;
}
if (ListEntry == &ShutdownRoutineList)
{
LIST_ENTRY_INSERT_TAIL(ListEntry, &ShutdownRegistration->ListEntry)
}
}
else
{
ListEntry = ShutdownRoutineList.Flink;
while (ListEntry != &ShutdownRoutineList)
{
if (ShutdownRegistration == LIST_ENTRY_ACCESS_RECORD(ListEntry, HAL_SHUTDOWN_REGISTRATION, ListEntry))
{
LIST_ENTRY_REMOVE(&ShutdownRegistration->ListEntry)
break;
}
ListEntry = ListEntry->Flink;
}
}
KfLowerIrql(OldIrql);
} }
// ****************************************************************** // ******************************************************************
@ -421,6 +467,35 @@ XBSYSAPI EXPORTNUM(49) xboxkrnl::VOID DECLSPEC_NORETURN NTAPI xboxkrnl::HalRetur
// Commented out because XLaunchNewImage is disabled! // Commented out because XLaunchNewImage is disabled!
// MmPersistContiguousMemory((PVOID)xboxkrnl::LaunchDataPage, sizeof(LAUNCH_DATA_PAGE), TRUE); // MmPersistContiguousMemory((PVOID)xboxkrnl::LaunchDataPage, sizeof(LAUNCH_DATA_PAGE), TRUE);
{
// ergo720: I tested this with Tenchu and Dead or Alive Ultimate, both of which register a single shutdown
// routine with HalRegisterShutdownNotification. The routines are correctly registered but when invoked they
// cause a crash. It's because these routines are registered by and act upon the Xbox hardware, most of it
// is not LLEd enough and so, until then, we don't try to execute the shutdown routines
#if 0
KIRQL OldIrql;
PLIST_ENTRY ListEntry;
PHAL_SHUTDOWN_REGISTRATION ShutdownRegistration;
while (true)
{
OldIrql = KeRaiseIrqlToDpcLevel();
ListEntry = LIST_ENTRY_REMOVE_AT_HEAD(&ShutdownRoutineList)
KfLowerIrql(OldIrql);
if (ListEntry == &ShutdownRoutineList)
break;
ShutdownRegistration = LIST_ENTRY_ACCESS_RECORD(ListEntry, HAL_SHUTDOWN_REGISTRATION, ListEntry);
ShutdownRegistration->NotificationRoutine(ShutdownRegistration);
}
#endif
}
std::string TitlePath = xboxkrnl::LaunchDataPage->Header.szLaunchPath; std::string TitlePath = xboxkrnl::LaunchDataPage->Header.szLaunchPath;
char szWorkingDirectoy[MAX_PATH]; char szWorkingDirectoy[MAX_PATH];
@ -467,12 +542,16 @@ XBSYSAPI EXPORTNUM(49) xboxkrnl::VOID DECLSPEC_NORETURN NTAPI xboxkrnl::HalRetur
// Relaunch Cxbx, to load another Xbe // Relaunch Cxbx, to load another Xbe
{ {
bool bMultiXbe = true; bool bQuickReboot = true;
g_EmuShared->SetMultiXbeFlag(&bMultiXbe); g_EmuShared->SetQuickRebootFlag(&bQuickReboot);
char szArgsBuffer[4096]; char szArgsBuffer[4096];
snprintf(szArgsBuffer, 4096, "/load \"%s\" %u %d \"%s\"", XbePath.c_str(), CxbxKrnl_hEmuParent, CxbxKrnl_DebugMode, CxbxKrnl_DebugFileName); // Some titles (Xbox Dashboard) use ";" as a final path seperator
// This allows the Xbox Live option on the dashboard to properly launch XOnlinedash.xbe
std::replace(XbePath.begin(), XbePath.end(), ';', '\\');
snprintf(szArgsBuffer, 4096, "/load \"%s\" %u %d \"%s\"", XbePath.c_str(), CxbxKrnl_hEmuParent, CxbxKrnl_DebugMode, CxbxKrnl_DebugFileName.c_str());
if ((int)ShellExecute(NULL, "open", szFilePath_CxbxReloaded_Exe, szArgsBuffer, szWorkingDirectoy, SW_SHOWDEFAULT) <= 32) if ((int)ShellExecute(NULL, "open", szFilePath_CxbxReloaded_Exe, szArgsBuffer, szWorkingDirectoy, SW_SHOWDEFAULT) <= 32)
CxbxKrnlCleanup("Could not launch %s", XbePath.c_str()); CxbxKrnlCleanup("Could not launch %s", XbePath.c_str());
} }
@ -485,8 +564,25 @@ XBSYSAPI EXPORTNUM(49) xboxkrnl::VOID DECLSPEC_NORETURN NTAPI xboxkrnl::HalRetur
break; break;
case ReturnFirmwareFatal: case ReturnFirmwareFatal:
CxbxPopupMessage("Emulated Xbox hit a fatal error (might be called by XapiBootToDash from within dashboard)"); {
// NOTE: the error code is displayed by ExDisplayFatalError by other code paths so we need to change our corresponding
// paths if we want to emulate all the possible fatal errors
xboxkrnl::HalWriteSMBusValue(SMBUS_ADDRESS_SYSTEM_MICRO_CONTROLLER, SMC_COMMAND_SCRATCH, 0, SMC_SCRATCH_DISPLAY_FATAL_ERROR);
char szArgsBuffer[4096];
char szWorkingDirectoy[MAX_PATH];
bool bQuickReboot = true;
g_EmuShared->SetQuickRebootFlag(&bQuickReboot);
g_EmuShared->GetXbePath(szWorkingDirectoy);
snprintf(szArgsBuffer, 4096, "/load \"%s\" %u %d \"%s\"", szWorkingDirectoy, CxbxKrnl_hEmuParent, CxbxKrnl_DebugMode, CxbxKrnl_DebugFileName.c_str());
if ((int)ShellExecute(NULL, "open", szFilePath_CxbxReloaded_Exe, szArgsBuffer, szWorkingDirectoy, SW_SHOWDEFAULT) <= 32)
{
int BootFlags = 0;
g_EmuShared->SetBootFlags(&BootFlags); // clear all boot flags in the case of failure
CxbxKrnlCleanup("Could not reboot");
}
break; break;
}
case ReturnFirmwareAll: case ReturnFirmwareAll:
LOG_UNIMPLEMENTED(); LOG_UNIMPLEMENTED();
@ -534,7 +630,7 @@ XBSYSAPI EXPORTNUM(50) xboxkrnl::NTSTATUS NTAPI xboxkrnl::HalWriteSMBusValue
// Note : GE_HOST_STC triggers ExecuteTransaction, which writes the command to the specified address // Note : GE_HOST_STC triggers ExecuteTransaction, which writes the command to the specified address
// Check if the command was executed successfully // Check if the command was executed successfully
if (g_SMBus->IORead(1, SMB_GLOBAL_STATUS) | GS_PRERR_STS) { if (g_SMBus->IORead(1, SMB_GLOBAL_STATUS) & GS_PRERR_STS) {
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
} }
@ -679,9 +775,11 @@ XBSYSAPI EXPORTNUM(358) xboxkrnl::BOOLEAN NTAPI xboxkrnl::HalIsResetOrShutdownPe
{ {
LOG_FUNC(); LOG_FUNC();
LOG_UNIMPLEMENTED(); BOOLEAN ret = FALSE;
RETURN(FALSE); if (ResetOrShutdownCommandCode != 0) { ret = TRUE; }
RETURN(ret);
} }
// ****************************************************************** // ******************************************************************
@ -693,8 +791,10 @@ XBSYSAPI EXPORTNUM(360) xboxkrnl::NTSTATUS NTAPI xboxkrnl::HalInitiateShutdown
) )
{ {
LOG_FUNC(); LOG_FUNC();
LOG_UNIMPLEMENTED(); ResetOrShutdownCommandCode = SMC_COMMAND_RESET;
ResetOrShutdownDataValue = SMC_RESET_ASSERT_SHUTDOWN;
xboxkrnl::HalWriteSMBusValue(SMBUS_ADDRESS_SYSTEM_MICRO_CONTROLLER, ResetOrShutdownCommandCode, 0, ResetOrShutdownDataValue);
RETURN(S_OK); RETURN(S_OK);
} }
@ -729,7 +829,7 @@ XBSYSAPI EXPORTNUM(366) xboxkrnl::NTSTATUS NTAPI xboxkrnl::HalWriteSMCScratchReg
// HalpSMCScratchRegister = ScratchRegister; // HalpSMCScratchRegister = ScratchRegister;
NTSTATUS Res = HalWriteSMBusValue(SMBUS_SMC_SLAVE_ADDRESS, SMC_COMMAND_SCRATCH, /*WordFlag:*/false, ScratchRegister); NTSTATUS Res = HalWriteSMBusValue(SMBUS_ADDRESS_SYSTEM_MICRO_CONTROLLER, SMC_COMMAND_SCRATCH, /*WordFlag:*/false, ScratchRegister);
RETURN(Res); RETURN(Res);
} }

View File

@ -271,6 +271,8 @@ DWORD ExecuteDpcQueue()
DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid) DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid)
{ {
CxbxSetThreadName("DPC Handler");
DbgPrintf("KRNL: DPC thread is running\n"); DbgPrintf("KRNL: DPC thread is running\n");
// Make sure DPC callbacks run on the same core as the one that runs Xbox1 code : // Make sure DPC callbacks run on the same core as the one that runs Xbox1 code :

View File

@ -1262,8 +1262,6 @@ XBSYSAPI EXPORTNUM(211) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQueryInformationFil
// Bail out if the buffer gets too big // Bail out if the buffer gets too big
if (bufferSize > 65536) if (bufferSize > 65536)
return STATUS_INVALID_PARAMETER; // TODO: what's the appropriate error code to return here? return STATUS_INVALID_PARAMETER; // TODO: what's the appropriate error code to return here?
ntFileInfo = malloc(bufferSize);
} }
} while (ret == STATUS_BUFFER_OVERFLOW); } while (ret == STATUS_BUFFER_OVERFLOW);

View File

@ -114,6 +114,8 @@ static unsigned int WINAPI PCSTProxy
IN PVOID Parameter IN PVOID Parameter
) )
{ {
CxbxSetThreadName("PsCreateSystemThread Proxy");
PCSTProxyParam *iPCSTProxyParam = (PCSTProxyParam*)Parameter; PCSTProxyParam *iPCSTProxyParam = (PCSTProxyParam*)Parameter;
PVOID StartRoutine = iPCSTProxyParam->StartRoutine; PVOID StartRoutine = iPCSTProxyParam->StartRoutine;
@ -132,9 +134,12 @@ static unsigned int WINAPI PCSTProxy
StartSuspended, StartSuspended,
hStartedEvent); hStartedEvent);
// Do minimal thread initialization // Do minimal thread initialization
InitXboxThread(g_CPUXbox); InitXboxThread(g_CPUXbox);
SetEvent(hStartedEvent);
if (StartSuspended == TRUE) if (StartSuspended == TRUE)
// Suspend right before calling the thread notification routines // Suspend right before calling the thread notification routines
SuspendThread(GetCurrentThread()); SuspendThread(GetCurrentThread());
@ -159,8 +164,6 @@ static unsigned int WINAPI PCSTProxy
// use the special calling convention // use the special calling convention
__try __try
{ {
SetEvent(hStartedEvent);
// Given the non-standard calling convention (requiring // Given the non-standard calling convention (requiring
// the first argument in ebp+4) we need the below __asm. // the first argument in ebp+4) we need the below __asm.
// //
@ -186,9 +189,6 @@ static unsigned int WINAPI PCSTProxy
callComplete: callComplete:
if (hStartedEvent != NULL) {
CloseHandle(hStartedEvent);
}
// This will also handle thread notification : // This will also handle thread notification :
xboxkrnl::PsTerminateSystemThread(STATUS_SUCCESS); xboxkrnl::PsTerminateSystemThread(STATUS_SUCCESS);
@ -301,6 +301,11 @@ XBSYSAPI EXPORTNUM(255) xboxkrnl::NTSTATUS NTAPI xboxkrnl::PsCreateSystemThreadE
{ {
DWORD dwThreadId = 0, dwThreadWait; DWORD dwThreadId = 0, dwThreadWait;
bool bWait = true; bool bWait = true;
HANDLE hStartedEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("PCSTProxyEvent"));
if (hStartedEvent == NULL) {
std::string errorMessage = CxbxGetLastErrorString("PsCreateSystemThreadEx could not create PCSTProxyEvent");
CxbxKrnlCleanup(errorMessage.c_str());
}
// PCSTProxy is responsible for cleaning up this pointer // PCSTProxy is responsible for cleaning up this pointer
::PCSTProxyParam *iPCSTProxyParam = new ::PCSTProxyParam(); ::PCSTProxyParam *iPCSTProxyParam = new ::PCSTProxyParam();
@ -309,45 +314,48 @@ XBSYSAPI EXPORTNUM(255) xboxkrnl::NTSTATUS NTAPI xboxkrnl::PsCreateSystemThreadE
iPCSTProxyParam->StartContext = StartContext; iPCSTProxyParam->StartContext = StartContext;
iPCSTProxyParam->SystemRoutine = SystemRoutine; // NULL, XapiThreadStartup or unknown? iPCSTProxyParam->SystemRoutine = SystemRoutine; // NULL, XapiThreadStartup or unknown?
iPCSTProxyParam->StartSuspended = CreateSuspended; iPCSTProxyParam->StartSuspended = CreateSuspended;
iPCSTProxyParam->hStartedEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("PCSTProxyEvent")); iPCSTProxyParam->hStartedEvent = hStartedEvent;
*ThreadHandle = (HANDLE)_beginthreadex(NULL, NULL, PCSTProxy, iPCSTProxyParam, NULL, (uint*)&dwThreadId); *ThreadHandle = (HANDLE)_beginthreadex(NULL, NULL, PCSTProxy, iPCSTProxyParam, NULL, (uint*)&dwThreadId);
// Note : DO NOT use iPCSTProxyParam anymore, since ownership is transferred to the proxy (which frees it too)
DbgPrintf("KRNL: Waiting for Xbox proxy thread to start...\n"); // Give the thread chance to start
Sleep(100);
EmuWarning("KRNL: Waiting for Xbox proxy thread to start...\n");
while (bWait) { while (bWait) {
dwThreadWait = WaitForSingleObject(*ThreadHandle, 300); dwThreadWait = WaitForSingleObject(hStartedEvent, 300);
switch (dwThreadWait) { switch (dwThreadWait) {
// Thread is running case WAIT_TIMEOUT: { // The time-out interval elapsed, and the object's state is nonsignaled.
case WAIT_TIMEOUT: EmuWarning("KRNL: Timeout while waiting for Xbox proxy thread to start...\n");
// Thread is complete
case WAIT_OBJECT_0: {
// if either of two above is true, don't need to wait.
bWait = false; bWait = false;
break; break;
} }
// A problem has occurred, what should we do? case WAIT_OBJECT_0: { // The state of the specified object is signaled.
case WAIT_FAILED: { DbgPrintf("KRNL: Xbox proxy thread is started.\n");
break;
}
// Unknown wait
default:
bWait = false; bWait = false;
break; break;
}
default: {
if (dwThreadWait == WAIT_FAILED) // The function has failed
bWait = false;
std::string ErrorStr = CxbxGetLastErrorString("KRNL: While waiting for Xbox proxy thread to start");
EmuWarning("%s\n", ErrorStr.c_str());
break;
}
} }
} }
// Release the event
CloseHandle(hStartedEvent);
hStartedEvent = NULL;
// Log ThreadID identical to how GetCurrentThreadID() is rendered : // Log ThreadID identical to how GetCurrentThreadID() is rendered :
DbgPrintf("KRNL: Created Xbox proxy thread. Handle : 0x%X, ThreadId : [0x%.4X]\n", *ThreadHandle, dwThreadId); EmuWarning("KRNL: Created Xbox proxy thread. Handle : 0x%X, ThreadId : [0x%.4X]\n", *ThreadHandle, dwThreadId);
// we must duplicate this handle in order to retain Suspend/Resume thread rights from a remote thread CxbxKrnlRegisterThread(*ThreadHandle);
{
HANDLE hDupHandle = NULL;
DuplicateHandle(g_CurrentProcessHandle, *ThreadHandle, g_CurrentProcessHandle, &hDupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
CxbxKrnlRegisterThread(hDupHandle);
}
if (ThreadId != NULL) if (ThreadId != NULL)
*ThreadId = (xboxkrnl::HANDLE)dwThreadId; *ThreadId = (xboxkrnl::HANDLE)dwThreadId;

View File

@ -41,6 +41,13 @@
#include <memory.h> #include <memory.h>
enum {
XBOX_LED_COLOUR_OFF,
XBOX_LED_COLOUR_GREEN,
XBOX_LED_COLOUR_RED,
XBOX_LED_COLOUR_ORANGE,
};
enum { enum {
LLE_APU = 1 << 0, LLE_APU = 1 << 0,
LLE_GPU = 1 << 1, LLE_GPU = 1 << 1,
@ -100,12 +107,24 @@ class EmuShared : public Mutex
void GetFlagsLLE( int *flags) { Lock(); *flags = m_FlagsLLE; Unlock(); } void GetFlagsLLE( int *flags) { Lock(); *flags = m_FlagsLLE; Unlock(); }
void SetFlagsLLE(const int *flags) { Lock(); m_FlagsLLE = *flags; Unlock(); } void SetFlagsLLE(const int *flags) { Lock(); m_FlagsLLE = *flags; Unlock(); }
// ******************************************************************
// * Boot flag Accessors
// ******************************************************************
void GetBootFlags(int *value) { Lock(); *value = m_BootFlags; Unlock(); }
void SetBootFlags(int *value) { Lock(); m_BootFlags = *value; Unlock(); }
// ****************************************************************** // ******************************************************************
// * XInput Flag Accessors // * XInput Flag Accessors
// ****************************************************************** // ******************************************************************
void GetXInputEnabled(int* value) { Lock(); *value = m_XInputEnabled; Unlock(); } void GetXInputEnabled(int* value) { Lock(); *value = m_XInputEnabled; Unlock(); }
void SetXInputEnabled(int* value) { Lock(); m_XInputEnabled = *value; Unlock(); } void SetXInputEnabled(int* value) { Lock(); m_XInputEnabled = *value; Unlock(); }
// ******************************************************************
// * Hack Flag Accessors
// ******************************************************************
void GetDisablePixelShaders(int* value) { Lock(); *value = m_DisablePixelShaders; Unlock(); }
void SetDisablePixelShaders(int* value) { Lock(); m_DisablePixelShaders = *value; Unlock(); }
// ****************************************************************** // ******************************************************************
// * MSpF/Benchmark values Accessors // * MSpF/Benchmark values Accessors
// ****************************************************************** // ******************************************************************
@ -119,10 +138,10 @@ class EmuShared : public Mutex
void SetCurrentFPS(float *value) { Lock(); m_FPS = *value; Unlock(); } void SetCurrentFPS(float *value) { Lock(); m_FPS = *value; Unlock(); }
// ****************************************************************** // ******************************************************************
// * MultiXbe flag Accessors // * Kernel quick reboot flag Accessors
// ****************************************************************** // ******************************************************************
void GetMultiXbeFlag(bool *value) { Lock(); *value = m_bMultiXbe; Unlock(); } void GetQuickRebootFlag(bool *value) { Lock(); *value = m_bKeQuickReboot; Unlock(); }
void SetMultiXbeFlag(bool *value) { Lock(); m_bMultiXbe = *value; Unlock(); } void SetQuickRebootFlag(bool *value) { Lock(); m_bKeQuickReboot = *value; Unlock(); }
// ****************************************************************** // ******************************************************************
// * Launch data physical address Accessors // * Launch data physical address Accessors
@ -130,6 +149,28 @@ class EmuShared : public Mutex
void GetLaunchDataPAddress(PAddr *value) { Lock(); *value = m_LaunchDataPAddress; Unlock(); } void GetLaunchDataPAddress(PAddr *value) { Lock(); *value = m_LaunchDataPAddress; Unlock(); }
void SetLaunchDataPAddress(PAddr *value) { Lock(); m_LaunchDataPAddress = *value; Unlock(); } void SetLaunchDataPAddress(PAddr *value) { Lock(); m_LaunchDataPAddress = *value; Unlock(); }
// ******************************************************************
// * Xbox LED values Accessors
// ******************************************************************
void GetLedSequence(int *value)
{
Lock();
for (int i = 0; i < 4; ++i)
{
value[i] = m_LedSequence[i];
}
Unlock();
}
void SetLedSequence(int *value)
{
Lock();
for (int i = 0; i < 4; ++i)
{
m_LedSequence[i] = value[i];
}
Unlock();
}
private: private:
// ****************************************************************** // ******************************************************************
@ -145,12 +186,15 @@ class EmuShared : public Mutex
XBVideo m_XBVideo; XBVideo m_XBVideo;
XBAudio m_XBAudio; XBAudio m_XBAudio;
char m_XbePath[MAX_PATH]; char m_XbePath[MAX_PATH];
int m_BootFlags;
int m_FlagsLLE; int m_FlagsLLE;
int m_XInputEnabled; int m_XInputEnabled;
int m_DisablePixelShaders;
float m_MSpF; float m_MSpF;
float m_FPS; float m_FPS;
bool m_bMultiXbe; bool m_bKeQuickReboot;
PAddr m_LaunchDataPAddress; PAddr m_LaunchDataPAddress;
int m_LedSequence[4];
}; };
// ****************************************************************** // ******************************************************************

View File

@ -47,14 +47,12 @@
#include "mnemonics.h" #include "mnemonics.h"
#include "CxbxKrnl.h" #include "CxbxKrnl.h"
#include "Emu.h" #include "Emu.h" // For EmuWarning
#include "EmuX86.h" #include "EmuX86.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>
#include "PCIBus.h" #include "devices\Xbox.h" // For g_PCIBus
// //
// Read & write handlers handlers for I/O // Read & write handlers handlers for I/O
@ -177,11 +175,7 @@ uint32_t EmuX86_Read(xbaddr addr, int size)
uint32_t value; uint32_t value;
if (addr >= NV2A_ADDR && addr < NV2A_ADDR + NV2A_SIZE) { if (addr >= XBOX_FLASH_ROM_BASE) { // 0xFFF00000 - 0xFFFFFFF
// 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
value = EmuFlash_Read32(addr - XBOX_FLASH_ROM_BASE); // TODO : Make flash access size-aware value = EmuFlash_Read32(addr - XBOX_FLASH_ROM_BASE); // TODO : Make flash access size-aware
} else { } else {
// Pass the Read to the PCI Bus, this will handle devices with BARs set to MMIO addresses // 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; 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 if (addr >= XBOX_FLASH_ROM_BASE) { // 0xFFF00000 - 0xFFFFFFF
EmuWarning("EmuX86_Write(0x%08X, 0x%08X) [FLASH_ROM]", addr, value); EmuWarning("EmuX86_Write(0x%08X, 0x%08X) [FLASH_ROM]", addr, value);
return; return;

View File

@ -176,7 +176,10 @@ OOVPA_END;
// * D3D_CommonSetRenderTarget // * D3D_CommonSetRenderTarget
// ****************************************************************** // ******************************************************************
#ifndef WIP_LessVertexPatching #ifndef WIP_LessVertexPatching
OOVPA_NO_XREF(D3D_CommonSetRenderTarget, 4627, 12) OOVPA_XREF(D3D_CommonSetRenderTarget, 4627, 12,
XREF_D3D_CommonSetRenderTarget,
XRefZero)
#else #else
OOVPA_XREF(D3D_CommonSetRenderTarget, 4627, 1+12, OOVPA_XREF(D3D_CommonSetRenderTarget, 4627, 1+12,
@ -498,7 +501,10 @@ OOVPA_END;
// * D3DDevice_GetDepthStencilSurface2 // * D3DDevice_GetDepthStencilSurface2
// ****************************************************************** // ******************************************************************
#ifndef WIP_LessVertexPatching #ifndef WIP_LessVertexPatching
OOVPA_NO_XREF(D3DDevice_GetDepthStencilSurface2, 4627, 20) OOVPA_XREF(D3DDevice_GetDepthStencilSurface2, 4627, 20,
XREF_D3DDevice_GetDepthStencilSurface2,
XRefZero)
#else #else
OOVPA_XREF(D3DDevice_GetDepthStencilSurface2, 4627, 1+20, OOVPA_XREF(D3DDevice_GetDepthStencilSurface2, 4627, 1+20,

View File

@ -1,328 +0,0 @@
// ******************************************************************
// *
// * .,-::::: .,:: .::::::::. .,:: .:
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
// * $$$ Y$$$P $$""""Y$$ Y$$$P
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
// *
// * Cxbx->Win32->CxbxKrnl->HLEDataBase->D3D8.1.0.5659.inl
// *
// * 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 jarupxx
// *
// * All rights reserved
// *
// ******************************************************************
// ******************************************************************
// * D3DDevice_SetMaterial
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_SetMaterial, 5659, 11)
{ 0x04, 0x08 },
{ 0x0C, 0x81 },
{ 0x0D, 0xC7 },
{ 0x0E, 0x00 },
{ 0x0F, 0x0F },
{ 0x10, 0x00 },
{ 0x16, 0x00 },
{ 0x1F, 0x81 },
{ 0x22, 0x90 },
{ 0x2C, 0x5E },
{ 0x2E, 0x04 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_GetMaterial
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_GetMaterial, 5659, 8)
{ 0x05, 0x56 },
{ 0x06, 0x57 },
{ 0x0A, 0x0C },
{ 0x0D, 0x00 },
{ 0x0E, 0x0F },
{ 0x12, 0x11 },
{ 0x16, 0xF3 },
{ 0x1A, 0xC2 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_AddRef
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_AddRef, 5659, 10)
// D3DDevice_AddRef+0x00 : mov eax, [addr]
{ 0x00, 0xA1 },
// D3DDevice_AddRef+0x05 : mov ecx, [eax+0x0938]
{ 0x05, 0x8B },
{ 0x06, 0x88 },
{ 0x07, 0x38 },
{ 0x08, 0x09 },
// D3DDevice_AddRef+0x0B : inc ecx
{ 0x0B, 0x41 },
// D3DDevice_AddRef+0x0C : mov [eax+0x0938], ecx
{ 0x0C, 0x89 },
{ 0x0D, 0x88 },
{ 0x0E, 0x38 },
{ 0x0F, 0x09 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_SetBackMaterial
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_SetBackMaterial, 5659, 11)
{ 0x04, 0x08 },
{ 0x0C, 0x81 },
{ 0x0D, 0xC7 },
{ 0x0E, 0x44 },
{ 0x0F, 0x0F },
{ 0x10, 0x00 },
{ 0x16, 0x00 },
{ 0x1F, 0x81 },
{ 0x22, 0x90 },
{ 0x2C, 0x5E },
{ 0x2E, 0x04 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_GetBackMaterial
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_GetBackMaterial, 5659, 8)
{ 0x05, 0x56 },
{ 0x06, 0x57 },
{ 0x0A, 0x0C },
{ 0x0D, 0x44 },
{ 0x0E, 0x0F },
{ 0x12, 0x11 },
{ 0x16, 0xF3 },
{ 0x1A, 0xC2 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_SetVerticalBlankCallback
// ******************************************************************
OOVPA_XREF(D3DDevice_SetVerticalBlankCallback, 5659, 1+12,
XRefNoSaveIndex,
XRefOne)
XREF_ENTRY( 0x06, XREF_D3DDEVICE ), // Derived
// D3DDevice_SetVerticalBlankCallback+0x00 : mov eax, [esp+0x04]
{ 0x00, 0x8B },
{ 0x01, 0x44 },
{ 0x02, 0x24 },
{ 0x03, 0x04 },
// D3DDevice_SetVerticalBlankCallback+0x04 : mov ecx, [addr]
{ 0x04, 0x8B },
{ 0x05, 0x0D },
// D3DDevice_SetVerticalBlankCallback+0x0A : mov [ecx+0x1DB4], eax
{ 0x0A, 0x89 },
{ 0x0B, 0x81 },
{ 0x0C, 0xB8 }, // B4 vs B8
{ 0x0D, 0x1D },
// D3DDevice_SetVerticalBlankCallback+0x10 : retn 0x04
{ 0x10, 0xC2 },
{ 0x11, 0x04 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_SetSwapCallback
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_SetSwapCallback, 5659, 12)
// D3DDevice_SetSwapCallback+0x00 : mov eax, [esp+0x04]
{ 0x00, 0x8B },
{ 0x01, 0x44 },
{ 0x02, 0x24 },
{ 0x03, 0x04 },
// D3DDevice_SetSwapCallback+0x04 : mov ecx, [addr]
{ 0x04, 0x8B },
{ 0x05, 0x0D },
// D3DDevice_SetSwapCallback+0x0A : mov [ecx+0x1DB4], eax
{ 0x0A, 0x89 },
{ 0x0B, 0x81 },
{ 0x0C, 0xB4 }, // B4 vs B8
{ 0x0D, 0x1D },
// D3DDevice_SetSwapCallback+0x10 : retn 0x04
{ 0x10, 0xC2 },
{ 0x11, 0x04 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_GetVertexShader
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_GetVertexShader, 5659, 16)
{ 0x00, 0xA1 },
{ 0x05, 0x8B },
{ 0x06, 0x88 },
{ 0x07, 0x98 },
{ 0x08, 0x07 },
{ 0x09, 0x00 },
{ 0x0A, 0x00 },
{ 0x0B, 0x8B },
{ 0x0C, 0x54 },
{ 0x0D, 0x24 },
{ 0x0E, 0x04 },
{ 0x0F, 0x89 },
{ 0x10, 0x0A },
{ 0x11, 0xC2 },
{ 0x12, 0x04 },
{ 0x13, 0x00 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_GetPixelShader
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_GetPixelShader, 5659, 16)
{ 0x00, 0xA1 },
{ 0x05, 0x8B },
{ 0x06, 0x88 },
{ 0x07, 0x84 },
{ 0x08, 0x07 },
{ 0x09, 0x00 },
{ 0x0A, 0x00 },
{ 0x0B, 0x8B },
{ 0x0C, 0x54 },
{ 0x0D, 0x24 },
{ 0x0E, 0x04 },
{ 0x0F, 0x89 },
{ 0x10, 0x0A },
{ 0x11, 0xC2 },
{ 0x12, 0x04 },
{ 0x13, 0x00 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_BlockUntilVerticalBlank
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_BlockUntilVerticalBlank, 5659, 11)
// D3DDevice_BlockUntilVerticalBlank+0x05 : push 0; push 0; push 1
{ 0x05, 0x6A },
{ 0x06, 0x00 },
{ 0x07, 0x6A },
{ 0x08, 0x00 },
{ 0x09, 0x6A },
{ 0x0A, 0x01 },
// D3DDevice_BlockUntilVerticalBlank+0x17 : add eax, 0x1DBC
{ 0x17, 0x05 },
{ 0x18, 0xBC },
{ 0x19, 0x1D },
// D3DDevice_BlockUntilVerticalBlank+0x1D : call [KrnlImport]
{ 0x1D, 0xFF },
// D3DDevice_BlockUntilVerticalBlank+0x23 : retn
{ 0x23, 0xC3 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_GetShaderConstantMode
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_GetShaderConstantMode, 5659, 16)
{ 0x00, 0xA1 },
{ 0x05, 0x8B },
{ 0x06, 0x88 },
{ 0x07, 0x28 },
{ 0x08, 0x19 },
{ 0x09, 0x00 },
{ 0x0A, 0x00 },
{ 0x0B, 0x8B },
{ 0x0C, 0x54 },
{ 0x0D, 0x24 },
{ 0x0E, 0x04 },
{ 0x0F, 0x89 },
{ 0x10, 0x0A },
{ 0x11, 0xC2 },
{ 0x12, 0x04 },
{ 0x13, 0x00 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_GetTexture, named with 2 suffix to match EMUPATCH(D3DDevice_GetTexture2)
// ******************************************************************
#ifndef WIP_LessVertexPatching
OOVPA_NO_XREF(D3DDevice_GetTexture2, 5659, 23) // Up to 5849
#else
OOVPA_XREF(D3DDevice_GetTexture2, 5659, 1+23, // Up to 5849
XRefNoSaveIndex,
XRefOne)
XREF_ENTRY( 0x0E, XREF_OFFSET_D3DDEVICE_M_TEXTURES ), // Derived
#endif
{ 0x00, 0x8B },
{ 0x01, 0x44 },
{ 0x02, 0x24 },
{ 0x03, 0x04 },
{ 0x04, 0x8B },
{ 0x05, 0x0D },
{ 0x0A, 0x56 },
{ 0x0B, 0x8D },
{ 0x0C, 0xB4 },
{ 0x0D, 0x81 },
{ 0x0E, 0x88 }, // GetTexture2 880F vs GetPalette2 980F
{ 0x0F, 0x0F },
{ 0x10, 0x00 },
{ 0x11, 0x00 },
{ 0x12, 0x8B },
{ 0x13, 0x06 },
{ 0x14, 0x85 },
{ 0x15, 0xC0 },
{ 0x16, 0x74 },
{ 0x18, 0x50 },
{ 0x19, 0xE8 },
{ 0x1E, 0x8B },
{ 0x1F, 0x06 },
// { 0x21, 0xC2 },
OOVPA_END;

View File

@ -56,3 +56,298 @@ OOVPA_XREF(D3D_RecordStateBlock, 5788, 10,
{ 0xD7, 0x0C }, { 0xD7, 0x0C },
{ 0xD8, 0x01 }, { 0xD8, 0x01 },
OOVPA_END; OOVPA_END;
// ******************************************************************
// * D3DDevice_SetMaterial
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_SetMaterial, 5788, 11)
{ 0x04, 0x08 },
{ 0x0C, 0x81 },
{ 0x0D, 0xC7 },
{ 0x0E, 0x00 },
{ 0x0F, 0x0F },
{ 0x10, 0x00 },
{ 0x16, 0x00 },
{ 0x1F, 0x81 },
{ 0x22, 0x90 },
{ 0x2C, 0x5E },
{ 0x2E, 0x04 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_GetMaterial
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_GetMaterial, 5788, 8)
{ 0x05, 0x56 },
{ 0x06, 0x57 },
{ 0x0A, 0x0C },
{ 0x0D, 0x00 },
{ 0x0E, 0x0F },
{ 0x12, 0x11 },
{ 0x16, 0xF3 },
{ 0x1A, 0xC2 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_AddRef
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_AddRef, 5788, 10)
// D3DDevice_AddRef+0x00 : mov eax, [addr]
{ 0x00, 0xA1 },
// D3DDevice_AddRef+0x05 : mov ecx, [eax+0x0938]
{ 0x05, 0x8B },
{ 0x06, 0x88 },
{ 0x07, 0x38 },
{ 0x08, 0x09 },
// D3DDevice_AddRef+0x0B : inc ecx
{ 0x0B, 0x41 },
// D3DDevice_AddRef+0x0C : mov [eax+0x0938], ecx
{ 0x0C, 0x89 },
{ 0x0D, 0x88 },
{ 0x0E, 0x38 },
{ 0x0F, 0x09 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_SetBackMaterial
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_SetBackMaterial, 5788, 11)
{ 0x04, 0x08 },
{ 0x0C, 0x81 },
{ 0x0D, 0xC7 },
{ 0x0E, 0x44 },
{ 0x0F, 0x0F },
{ 0x10, 0x00 },
{ 0x16, 0x00 },
{ 0x1F, 0x81 },
{ 0x22, 0x90 },
{ 0x2C, 0x5E },
{ 0x2E, 0x04 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_GetBackMaterial
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_GetBackMaterial, 5788, 8)
{ 0x05, 0x56 },
{ 0x06, 0x57 },
{ 0x0A, 0x0C },
{ 0x0D, 0x44 },
{ 0x0E, 0x0F },
{ 0x12, 0x11 },
{ 0x16, 0xF3 },
{ 0x1A, 0xC2 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_SetVerticalBlankCallback
// ******************************************************************
OOVPA_XREF(D3DDevice_SetVerticalBlankCallback, 5788, 1+12,
XRefNoSaveIndex,
XRefOne)
XREF_ENTRY( 0x06, XREF_D3DDEVICE ), // Derived
// D3DDevice_SetVerticalBlankCallback+0x00 : mov eax, [esp+0x04]
{ 0x00, 0x8B },
{ 0x01, 0x44 },
{ 0x02, 0x24 },
{ 0x03, 0x04 },
// D3DDevice_SetVerticalBlankCallback+0x04 : mov ecx, [addr]
{ 0x04, 0x8B },
{ 0x05, 0x0D },
// D3DDevice_SetVerticalBlankCallback+0x0A : mov [ecx+0x1DB4], eax
{ 0x0A, 0x89 },
{ 0x0B, 0x81 },
{ 0x0C, 0xB8 }, // B4 vs B8
{ 0x0D, 0x1D },
// D3DDevice_SetVerticalBlankCallback+0x10 : retn 0x04
{ 0x10, 0xC2 },
{ 0x11, 0x04 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_SetSwapCallback
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_SetSwapCallback, 5788, 12)
// D3DDevice_SetSwapCallback+0x00 : mov eax, [esp+0x04]
{ 0x00, 0x8B },
{ 0x01, 0x44 },
{ 0x02, 0x24 },
{ 0x03, 0x04 },
// D3DDevice_SetSwapCallback+0x04 : mov ecx, [addr]
{ 0x04, 0x8B },
{ 0x05, 0x0D },
// D3DDevice_SetSwapCallback+0x0A : mov [ecx+0x1DB4], eax
{ 0x0A, 0x89 },
{ 0x0B, 0x81 },
{ 0x0C, 0xB4 }, // B4 vs B8
{ 0x0D, 0x1D },
// D3DDevice_SetSwapCallback+0x10 : retn 0x04
{ 0x10, 0xC2 },
{ 0x11, 0x04 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_GetVertexShader
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_GetVertexShader, 5788, 16)
{ 0x00, 0xA1 },
{ 0x05, 0x8B },
{ 0x06, 0x88 },
{ 0x07, 0x98 },
{ 0x08, 0x07 },
{ 0x09, 0x00 },
{ 0x0A, 0x00 },
{ 0x0B, 0x8B },
{ 0x0C, 0x54 },
{ 0x0D, 0x24 },
{ 0x0E, 0x04 },
{ 0x0F, 0x89 },
{ 0x10, 0x0A },
{ 0x11, 0xC2 },
{ 0x12, 0x04 },
{ 0x13, 0x00 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_GetPixelShader
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_GetPixelShader, 5788, 16)
{ 0x00, 0xA1 },
{ 0x05, 0x8B },
{ 0x06, 0x88 },
{ 0x07, 0x84 },
{ 0x08, 0x07 },
{ 0x09, 0x00 },
{ 0x0A, 0x00 },
{ 0x0B, 0x8B },
{ 0x0C, 0x54 },
{ 0x0D, 0x24 },
{ 0x0E, 0x04 },
{ 0x0F, 0x89 },
{ 0x10, 0x0A },
{ 0x11, 0xC2 },
{ 0x12, 0x04 },
{ 0x13, 0x00 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_BlockUntilVerticalBlank
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_BlockUntilVerticalBlank, 5788, 11)
// D3DDevice_BlockUntilVerticalBlank+0x05 : push 0; push 0; push 1
{ 0x05, 0x6A },
{ 0x06, 0x00 },
{ 0x07, 0x6A },
{ 0x08, 0x00 },
{ 0x09, 0x6A },
{ 0x0A, 0x01 },
// D3DDevice_BlockUntilVerticalBlank+0x17 : add eax, 0x1DBC
{ 0x17, 0x05 },
{ 0x18, 0xBC },
{ 0x19, 0x1D },
// D3DDevice_BlockUntilVerticalBlank+0x1D : call [KrnlImport]
{ 0x1D, 0xFF },
// D3DDevice_BlockUntilVerticalBlank+0x23 : retn
{ 0x23, 0xC3 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_GetShaderConstantMode
// ******************************************************************
OOVPA_NO_XREF(D3DDevice_GetShaderConstantMode, 5788, 16)
{ 0x00, 0xA1 },
{ 0x05, 0x8B },
{ 0x06, 0x88 },
{ 0x07, 0x28 },
{ 0x08, 0x19 },
{ 0x09, 0x00 },
{ 0x0A, 0x00 },
{ 0x0B, 0x8B },
{ 0x0C, 0x54 },
{ 0x0D, 0x24 },
{ 0x0E, 0x04 },
{ 0x0F, 0x89 },
{ 0x10, 0x0A },
{ 0x11, 0xC2 },
{ 0x12, 0x04 },
{ 0x13, 0x00 },
OOVPA_END;
// ******************************************************************
// * D3DDevice_GetTexture, named with 2 suffix to match EMUPATCH(D3DDevice_GetTexture2)
// ******************************************************************
#ifndef WIP_LessVertexPatching
OOVPA_NO_XREF(D3DDevice_GetTexture2, 5788, 23) // Up to 5849
#else
OOVPA_XREF(D3DDevice_GetTexture2, 5788, 1+23, // Up to 5849
XRefNoSaveIndex,
XRefOne)
XREF_ENTRY( 0x0E, XREF_OFFSET_D3DDEVICE_M_TEXTURES ), // Derived
#endif
{ 0x00, 0x8B },
{ 0x01, 0x44 },
{ 0x02, 0x24 },
{ 0x03, 0x04 },
{ 0x04, 0x8B },
{ 0x05, 0x0D },
{ 0x0A, 0x56 },
{ 0x0B, 0x8D },
{ 0x0C, 0xB4 },
{ 0x0D, 0x81 },
{ 0x0E, 0x88 }, // GetTexture2 880F vs GetPalette2 980F
{ 0x0F, 0x0F },
{ 0x10, 0x00 },
{ 0x11, 0x00 },
{ 0x12, 0x8B },
{ 0x13, 0x06 },
{ 0x14, 0x85 },
{ 0x15, 0xC0 },
{ 0x16, 0x74 },
{ 0x18, 0x50 },
{ 0x19, 0xE8 },
{ 0x1E, 0x8B },
{ 0x1F, 0x06 },
// { 0x21, 0xC2 },
OOVPA_END;

View File

@ -53,9 +53,11 @@
// * [5233] Evil Dead | 100% | have 208/230 library. // * [5233] Evil Dead | 100% | have 208/230 library.
// * [5344] Gladius DEMO | 100% | have 202/229 library. // * [5344] Gladius DEMO | 100% | have 202/229 library.
// * [5455] Dinosaur Hunting | 100% | have 207/229 library. // * [5455] Dinosaur Hunting | 100% | have 207/229 library.
// * [5558] NHL HITZ Pro 2004 | 100% | have 218/229 library. // * [5558] NHL HITZ Pro 2004 | 100% | have 218/230 library.
// * [5659] Midway Arcade Treasures Paperboy | 100% | have 212/229 library. // * [5558] XIII | 100% | With Intergrated Hotfixes. have 209/230 library.
// * [5788] Digimon Battle Chronicle | 100% | have 210/229 library. // * [5659] NFL Blitz Pro | 100% | have 208/230 library.
// * [5659] Midway Arcade Treasures Paperboy | 100% | With Intergrated Hotfixes. have 212/230 library.
// * [5788] Digimon Battle Chronicle | 100% | have 210/230 library.
// * [5849] Nickelodeon Tak 2 | 100% | have 210/229 library. // * [5849] Nickelodeon Tak 2 | 100% | have 210/229 library.
// TODO: Known D3D8 OOVPA issue list // TODO: Known D3D8 OOVPA issue list
@ -181,7 +183,6 @@
#include "D3D8.1.0.5344.inl" #include "D3D8.1.0.5344.inl"
#include "D3D8.1.0.5455.inl" #include "D3D8.1.0.5455.inl"
#include "D3D8.1.0.5558.inl" #include "D3D8.1.0.5558.inl"
#include "D3D8.1.0.5659.inl"
#include "D3D8.1.0.5788.inl" #include "D3D8.1.0.5788.inl"
#include "D3D8.1.0.5849.inl" #include "D3D8.1.0.5849.inl"
@ -198,7 +199,7 @@ OOVPATable D3D8_OOVPAV2[] = {
REGISTER_OOVPAS(D3DCubeTexture_GetCubeMapSurface, PATCH, 3911, 4627), // Called D3DCubeTexture_GetCubeMapSurface2 (from 4627's comment) NOTE: Use D3DCubeTexture_GetCubeMapSurface2 for 4627 and above REGISTER_OOVPAS(D3DCubeTexture_GetCubeMapSurface, PATCH, 3911, 4627), // Called D3DCubeTexture_GetCubeMapSurface2 (from 4627's comment) NOTE: Use D3DCubeTexture_GetCubeMapSurface2 for 4627 and above
REGISTER_OOVPAS(D3DCubeTexture_GetCubeMapSurface2, PATCH, 4627), REGISTER_OOVPAS(D3DCubeTexture_GetCubeMapSurface2, PATCH, 4627),
REGISTER_OOVPAS(D3DCubeTexture_LockRect, PATCH, 3911), // Just calls Lock2DSurface (from 4134, 4432's comment) REGISTER_OOVPAS(D3DCubeTexture_LockRect, PATCH, 3911), // Just calls Lock2DSurface (from 4134, 4432's comment)
REGISTER_OOVPAS(D3DDevice_AddRef, PATCH, 3911, 4039, 4134, 4242, 4627, 5028, 5344, 5558, 5659), REGISTER_OOVPAS(D3DDevice_AddRef, PATCH, 3911, 4039, 4134, 4242, 4627, 5028, 5344, 5558, 5788),
REGISTER_OOVPAS(D3DDevice_ApplyStateBlock, PATCH, 3911, 4627), REGISTER_OOVPAS(D3DDevice_ApplyStateBlock, PATCH, 3911, 4627),
REGISTER_OOVPAS(D3DDevice_Begin, PATCH, 3911, 4039), REGISTER_OOVPAS(D3DDevice_Begin, PATCH, 3911, 4039),
REGISTER_OOVPAS(D3DDevice_BeginPush, PATCH, 4134, 4627, 5028), REGISTER_OOVPAS(D3DDevice_BeginPush, PATCH, 4134, 4627, 5028),
@ -207,7 +208,7 @@ OOVPATable D3D8_OOVPAV2[] = {
REGISTER_OOVPAS(D3DDevice_BeginStateBlock, PATCH, 3911, 4134), REGISTER_OOVPAS(D3DDevice_BeginStateBlock, PATCH, 3911, 4134),
REGISTER_OOVPAS(D3DDevice_BeginVisibilityTest, PATCH, 3911, 4034), REGISTER_OOVPAS(D3DDevice_BeginVisibilityTest, PATCH, 3911, 4034),
REGISTER_OOVPAS(D3DDevice_BlockOnFence, PATCH, 3911), REGISTER_OOVPAS(D3DDevice_BlockOnFence, PATCH, 3911),
REGISTER_OOVPAS(D3DDevice_BlockUntilVerticalBlank, PATCH, 3911, 4034, 4134, 4242, 4432, 4627, 5028, 5233, 5344, 5455, 5558, 5659), REGISTER_OOVPAS(D3DDevice_BlockUntilVerticalBlank, PATCH, 3911, 4034, 4134, 4242, 4432, 4627, 5028, 5233, 5344, 5455, 5558, 5788),
REGISTER_OOVPAS(D3DDevice_CaptureStateBlock, PATCH, 3911, 4134), REGISTER_OOVPAS(D3DDevice_CaptureStateBlock, PATCH, 3911, 4134),
REGISTER_OOVPAS(D3DDevice_Clear, PATCH, 3911, 4034), REGISTER_OOVPAS(D3DDevice_Clear, PATCH, 3911, 4034),
REGISTER_OOVPAS(D3DDevice_CopyRects, PATCH, 3911, 4034, 4627, 5120), REGISTER_OOVPAS(D3DDevice_CopyRects, PATCH, 3911, 4034, 4627, 5120),
@ -244,7 +245,7 @@ OOVPATable D3D8_OOVPAV2[] = {
REGISTER_OOVPAS(D3DDevice_FlushVertexCache, PATCH, 3911, 4134), REGISTER_OOVPAS(D3DDevice_FlushVertexCache, PATCH, 3911, 4134),
REGISTER_OOVPAS(D3DDevice_GetBackBuffer, PATCH, 3911, 4034, 4134, 4627), // Called D3DDevice_GetBackBuffer2 (from 4627's comment) NOTE: Use D3DDevice_GetBackBuffer2 for 4627 and above REGISTER_OOVPAS(D3DDevice_GetBackBuffer, PATCH, 3911, 4034, 4134, 4627), // Called D3DDevice_GetBackBuffer2 (from 4627's comment) NOTE: Use D3DDevice_GetBackBuffer2 for 4627 and above
REGISTER_OOVPAS(D3DDevice_GetBackBuffer2, PATCH, 4627), // 5233 (from 5344's comment) REGISTER_OOVPAS(D3DDevice_GetBackBuffer2, PATCH, 4627), // 5233 (from 5344's comment)
REGISTER_OOVPAS(D3DDevice_GetBackMaterial, PATCH, 3911, 4134, 4627, 5344, 5558, 5659), REGISTER_OOVPAS(D3DDevice_GetBackMaterial, PATCH, 3911, 4134, 4627, 5344, 5558, 5788),
REGISTER_OOVPAS(D3DDevice_GetCreationParameters, PATCH, 3911), REGISTER_OOVPAS(D3DDevice_GetCreationParameters, PATCH, 3911),
REGISTER_OOVPAS(D3DDevice_GetDepthStencilSurface, PATCH, 3911, 4627), // Called D3DDevice_GetDepthStencilSurface2 (from 4627's comment) NOTE: Use D3DDevice_GetDepthStencilSurface2 for 4627 and above REGISTER_OOVPAS(D3DDevice_GetDepthStencilSurface, PATCH, 3911, 4627), // Called D3DDevice_GetDepthStencilSurface2 (from 4627's comment) NOTE: Use D3DDevice_GetDepthStencilSurface2 for 4627 and above
REGISTER_OOVPAS(D3DDevice_GetDepthStencilSurface2, PATCH, 4627), REGISTER_OOVPAS(D3DDevice_GetDepthStencilSurface2, PATCH, 4627),
@ -254,22 +255,22 @@ OOVPATable D3D8_OOVPAV2[] = {
REGISTER_OOVPAS(D3DDevice_GetGammaRamp, PATCH, 3911), REGISTER_OOVPAS(D3DDevice_GetGammaRamp, PATCH, 3911),
REGISTER_OOVPAS(D3DDevice_GetLight, PATCH, 3911), REGISTER_OOVPAS(D3DDevice_GetLight, PATCH, 3911),
REGISTER_OOVPAS(D3DDevice_GetLightEnable, PATCH, 3911, 5344), REGISTER_OOVPAS(D3DDevice_GetLightEnable, PATCH, 3911, 5344),
REGISTER_OOVPAS(D3DDevice_GetMaterial, PATCH, 3911, 4134, 4627, 5344, 5558, 5659), REGISTER_OOVPAS(D3DDevice_GetMaterial, PATCH, 3911, 4134, 4627, 5344, 5558, 5788),
REGISTER_OOVPAS(D3DDevice_GetModelView, PATCH, 3911, 4134), REGISTER_OOVPAS(D3DDevice_GetModelView, PATCH, 3911, 4134),
REGISTER_OOVPAS(D3DDevice_GetOverlayUpdateStatus, PATCH, 3911), REGISTER_OOVPAS(D3DDevice_GetOverlayUpdateStatus, PATCH, 3911),
REGISTER_OOVPAS(D3DDevice_GetPersistedSurface2, PATCH, 4928), // For only on Unreal Championship (from 4627's comment) REGISTER_OOVPAS(D3DDevice_GetPersistedSurface2, PATCH, 4928), // For only on Unreal Championship (from 4627's comment)
REGISTER_OOVPAS(D3DDevice_GetPixelShader, PATCH, 3911, 4039, 4134, 5028, 5558, 5659), REGISTER_OOVPAS(D3DDevice_GetPixelShader, PATCH, 3911, 4039, 4134, 5028, 5558, 5788),
REGISTER_OOVPAS(D3DDevice_GetProjectionViewportMatrix, PATCH, 3911, 4134, 4627, 5344, 5558), // For 5455 (from 5558's comment) REGISTER_OOVPAS(D3DDevice_GetProjectionViewportMatrix, PATCH, 3911, 4134, 4627, 5344, 5558), // For 5455 (from 5558's comment)
REGISTER_OOVPAS(D3DDevice_GetPushBufferOffset, PATCH, 3911, 4627),//TODO 4831 (from 4627's comment) REGISTER_OOVPAS(D3DDevice_GetPushBufferOffset, PATCH, 3911, 4627),//TODO 4831 (from 4627's comment)
REGISTER_OOVPAS(D3DDevice_GetRenderTarget, PATCH, 3911, 4627), // Called D3DDevice_GetRenderTarget2 (from 4627's comment) NOTE: Use D3DDevice_GetRenderTarget2 for 4627 and above REGISTER_OOVPAS(D3DDevice_GetRenderTarget, PATCH, 3911, 4627), // Called D3DDevice_GetRenderTarget2 (from 4627's comment) NOTE: Use D3DDevice_GetRenderTarget2 for 4627 and above
REGISTER_OOVPAS(D3DDevice_GetRenderTarget2, PATCH, 4627), REGISTER_OOVPAS(D3DDevice_GetRenderTarget2, PATCH, 4627),
REGISTER_OOVPAS(D3DDevice_GetScissors, PATCH, 3911), REGISTER_OOVPAS(D3DDevice_GetScissors, PATCH, 3911),
REGISTER_OOVPAS(D3DDevice_GetShaderConstantMode, PATCH, 3911, 4134, 4627, 5028, 5344, 5558, 5659), REGISTER_OOVPAS(D3DDevice_GetShaderConstantMode, PATCH, 3911, 4134, 4627, 5028, 5344, 5558, 5788),
REGISTER_OOVPAS(D3DDevice_GetStreamSource2, PATCH, 4627), REGISTER_OOVPAS(D3DDevice_GetStreamSource2, PATCH, 4627),
REGISTER_OOVPAS(D3DDevice_GetTexture2, PATCH, 3911, 4134, 4627, 5344, 5558, 5659), REGISTER_OOVPAS(D3DDevice_GetTexture2, PATCH, 3911, 4134, 4627, 5344, 5558, 5788),
REGISTER_OOVPAS(D3DDevice_GetTile, PATCH, 3911, 5455), REGISTER_OOVPAS(D3DDevice_GetTile, PATCH, 3911, 5455),
REGISTER_OOVPAS(D3DDevice_GetTransform, PATCH, 3911, 4034), REGISTER_OOVPAS(D3DDevice_GetTransform, PATCH, 3911, 4034),
REGISTER_OOVPAS(D3DDevice_GetVertexShader, PATCH, 3911, 4039, 4134, 5028, 5558, 5659), REGISTER_OOVPAS(D3DDevice_GetVertexShader, PATCH, 3911, 4039, 4134, 5028, 5558, 5788),
REGISTER_OOVPAS(D3DDevice_GetVertexShaderConstant, PATCH, 3911, 4039, 5028), REGISTER_OOVPAS(D3DDevice_GetVertexShaderConstant, PATCH, 3911, 4039, 5028),
REGISTER_OOVPAS(D3DDevice_GetVertexShaderDeclaration, PATCH, 3911), REGISTER_OOVPAS(D3DDevice_GetVertexShaderDeclaration, PATCH, 3911),
REGISTER_OOVPAS(D3DDevice_GetVertexShaderFunction, PATCH, 3911), REGISTER_OOVPAS(D3DDevice_GetVertexShaderFunction, PATCH, 3911),
@ -301,13 +302,13 @@ OOVPATable D3D8_OOVPAV2[] = {
REGISTER_OOVPAS(D3DDevice_SelectVertexShader, PATCH, 3911, 4034, 5455), REGISTER_OOVPAS(D3DDevice_SelectVertexShader, PATCH, 3911, 4034, 5455),
REGISTER_OOVPAS(D3DDevice_SelectVertexShaderDirect, PATCH, 4361), REGISTER_OOVPAS(D3DDevice_SelectVertexShaderDirect, PATCH, 4361),
REGISTER_OOVPAS(D3DDevice_SetBackBufferScale, PATCH, 4134), REGISTER_OOVPAS(D3DDevice_SetBackBufferScale, PATCH, 4134),
REGISTER_OOVPAS(D3DDevice_SetBackMaterial, PATCH, 3911, 4134, 4627, 5344, 5558, 5659), REGISTER_OOVPAS(D3DDevice_SetBackMaterial, PATCH, 3911, 4134, 4627, 5344, 5558, 5788),
REGISTER_OOVPAS(D3DDevice_SetDepthClipPlanes, PATCH, 4432), REGISTER_OOVPAS(D3DDevice_SetDepthClipPlanes, PATCH, 4432),
REGISTER_OOVPAS(D3DDevice_SetFlickerFilter, PATCH, 3911, 4034, 4134), REGISTER_OOVPAS(D3DDevice_SetFlickerFilter, PATCH, 3911, 4034, 4134),
REGISTER_OOVPAS(D3DDevice_SetGammaRamp, PATCH, 3911, 4627), REGISTER_OOVPAS(D3DDevice_SetGammaRamp, PATCH, 3911, 4627),
REGISTER_OOVPAS(D3DDevice_SetIndices, UNPATCHED, 3911, 4034), REGISTER_OOVPAS(D3DDevice_SetIndices, UNPATCHED, 3911, 4034),
REGISTER_OOVPAS(D3DDevice_SetLight, PATCH, 3911, 5344), REGISTER_OOVPAS(D3DDevice_SetLight, PATCH, 3911, 5344),
REGISTER_OOVPAS(D3DDevice_SetMaterial, PATCH, 3911, 4034, 4134, 4627, 5344, 5558, 5659), // Was 4627 (from 5344's comment) REGISTER_OOVPAS(D3DDevice_SetMaterial, PATCH, 3911, 4034, 4134, 4627, 5344, 5558, 5788), // Was 4627 (from 5344's comment)
REGISTER_OOVPAS(D3DDevice_SetModelView, PATCH, 3911, 4134, 4627), REGISTER_OOVPAS(D3DDevice_SetModelView, PATCH, 3911, 4134, 4627),
REGISTER_OOVPAS(D3DDevice_SetPalette, PATCH, 3911, 4034), REGISTER_OOVPAS(D3DDevice_SetPalette, PATCH, 3911, 4034),
REGISTER_OOVPAS(D3DDevice_SetPixelShader, PATCH, 3911, 4034, 4627), REGISTER_OOVPAS(D3DDevice_SetPixelShader, PATCH, 3911, 4034, 4627),
@ -355,7 +356,7 @@ OOVPATable D3D8_OOVPAV2[] = {
REGISTER_OOVPAS(D3DDevice_SetStateVB, UNPATCHED, 3911, 4034, 4134), REGISTER_OOVPAS(D3DDevice_SetStateVB, UNPATCHED, 3911, 4034, 4134),
REGISTER_OOVPAS(D3DDevice_SetStipple, PATCH, 4627), REGISTER_OOVPAS(D3DDevice_SetStipple, PATCH, 4627),
REGISTER_OOVPAS(D3DDevice_SetStreamSource, PATCH, 3911, 4034), REGISTER_OOVPAS(D3DDevice_SetStreamSource, PATCH, 3911, 4034),
REGISTER_OOVPAS(D3DDevice_SetSwapCallback, PATCH, 4134, 4242, 4432, 4627, 5028, 5233, 5344, 5455, 5558, 5659), REGISTER_OOVPAS(D3DDevice_SetSwapCallback, PATCH, 4134, 4242, 4432, 4627, 5028, 5233, 5344, 5455, 5558, 5788),
REGISTER_OOVPAS(D3DDevice_SetTexture, PATCH, 3911, 4034, 4361, 4831), REGISTER_OOVPAS(D3DDevice_SetTexture, PATCH, 3911, 4034, 4361, 4831),
REGISTER_OOVPAS(D3DDevice_SetTextureState_BorderColor, PATCH, 3911, 4034), REGISTER_OOVPAS(D3DDevice_SetTextureState_BorderColor, PATCH, 3911, 4034),
REGISTER_OOVPAS(D3DDevice_SetTextureState_BumpEnv, PATCH, 3911, 4034), REGISTER_OOVPAS(D3DDevice_SetTextureState_BumpEnv, PATCH, 3911, 4034),
@ -378,7 +379,7 @@ OOVPATable D3D8_OOVPAV2[] = {
REGISTER_OOVPAS(D3DDevice_SetVertexShaderConstantNotInlineFast, PATCH, 4627), REGISTER_OOVPAS(D3DDevice_SetVertexShaderConstantNotInlineFast, PATCH, 4627),
REGISTER_OOVPAS(D3DDevice_SetVertexShaderInput, PATCH, 3911, 4134), REGISTER_OOVPAS(D3DDevice_SetVertexShaderInput, PATCH, 3911, 4134),
REGISTER_OOVPAS(D3DDevice_SetVertexShaderInputDirect, PATCH, 4361), REGISTER_OOVPAS(D3DDevice_SetVertexShaderInputDirect, PATCH, 4361),
REGISTER_OOVPAS(D3DDevice_SetVerticalBlankCallback, PATCH, 3911, 4039, 4134, 4242, 4432, 4627, 5028, 5233, 5344, 5455, 5558, 5659), // Was 5233 (from 5344's comment) REGISTER_OOVPAS(D3DDevice_SetVerticalBlankCallback, PATCH, 3911, 4039, 4134, 4242, 4432, 4627, 5028, 5233, 5344, 5455, 5558, 5788), // Was 5233 (from 5344's comment)
REGISTER_OOVPAS(D3DDevice_SetViewport, PATCH, 3911, 4034, 5344, 5455), // Was 5233 (from 5344's comment) REGISTER_OOVPAS(D3DDevice_SetViewport, PATCH, 3911, 4034, 5344, 5455), // Was 5233 (from 5344's comment)
REGISTER_OOVPAS(D3DDevice_Swap, PATCH, 4034, 4531, 4627), REGISTER_OOVPAS(D3DDevice_Swap, PATCH, 4034, 4531, 4627),
REGISTER_OOVPAS(D3DDevice_SwitchTexture, PATCH, 3911), REGISTER_OOVPAS(D3DDevice_SwitchTexture, PATCH, 3911),

View File

@ -348,6 +348,7 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
for(uint32 v=0;v<dwLibraryVersions;v++) for(uint32 v=0;v<dwLibraryVersions;v++)
{ {
uint16 BuildVersion = pLibraryVersion[v].wBuildVersion; uint16 BuildVersion = pLibraryVersion[v].wBuildVersion;
uint16 QFEVersion = pLibraryVersion[v].wFlags.QFEVersion;
if (preserveVersion < BuildVersion) { if (preserveVersion < BuildVersion) {
preserveVersion = BuildVersion; preserveVersion = BuildVersion;
@ -377,6 +378,14 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
// Skip scanning for D3D8 symbols when LLE GPU is selected // Skip scanning for D3D8 symbols when LLE GPU is selected
if (bLLE_GPU) if (bLLE_GPU)
continue; continue;
// Functions in this library were updated by June 2003 XDK (5558) with Integrated Hotfixes,
// However August 2003 XDK (5659) still uses the old function.
// Please use updated 5788 instead.
if (BuildVersion >= 5558 && BuildVersion <=5659 && QFEVersion > 1) {
EmuWarning("D3D8 version 1.0.%d.%d Title Detected: This game uses an alias version 1.0.5788", BuildVersion, QFEVersion);
BuildVersion = 5788;
}
} }
if (strcmp(LibraryName.c_str(), Lib_DSOUND) == 0) if (strcmp(LibraryName.c_str(), Lib_DSOUND) == 0)
{ {

View File

@ -0,0 +1,94 @@
// 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->CxbxKrnl->EEPROMDevice.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 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#include <cstring> // For memcpy
#include "EEPROMDevice.h" // For EEPROMDevice
void EEPROMDevice::Init()
{
// TODO
}
void EEPROMDevice::Reset()
{
// TODO
}
void EEPROMDevice::QuickCommand(bool read)
{
// TODO
}
uint8_t EEPROMDevice::ReceiveByte()
{
return 0; // TODO
}
uint8_t EEPROMDevice::ReadByte(uint8_t command)
{
return *(m_pEEPROM + command);
}
uint16_t EEPROMDevice::ReadWord(uint8_t command)
{
return *((uint16_t*)(m_pEEPROM + command));
}
int EEPROMDevice::ReadBlock(uint8_t command, uint8_t *data)
{
return 0; // TODO
}
void EEPROMDevice::SendByte(uint8_t data)
{
// TODO
}
void EEPROMDevice::WriteByte(uint8_t command, uint8_t value)
{
*((uint16_t*)(m_pEEPROM + command)) = value;
}
void EEPROMDevice::WriteWord(uint8_t command, uint16_t value)
{
*((uint16_t*)(m_pEEPROM + command)) = value;
}
void EEPROMDevice::WriteBlock(uint8_t command, uint8_t* data, int length)
{
std::memcpy(m_pEEPROM + command, data, length);
}

View File

@ -37,8 +37,6 @@
#include "SMDevice.h" #include "SMDevice.h"
#define SMBUS_EEPROM_ADDRESS 0xA8 // = Write; Read = 0xA9
class EEPROMDevice : public SMDevice { class EEPROMDevice : public SMDevice {
public: public:
// SMDevice functions // SMDevice functions
@ -61,5 +59,3 @@ public:
private: private:
uint8_t* m_pEEPROM; uint8_t* m_pEEPROM;
}; };
extern EEPROMDevice* g_EEPROM;

View File

@ -48,9 +48,10 @@ namespace xboxkrnl
#include <xboxkrnl/xboxkrnl.h> // For PKINTERRUPT, etc. #include <xboxkrnl/xboxkrnl.h> // For PKINTERRUPT, etc.
}; };
#include "CxbxKrnl.h" #include "CxbxKrnl\CxbxKrnl.h"
#include "Emu.h" #include "CxbxKrnl\Emu.h"
#include "EmuKrnl.h" #include "CxbxKrnl\EmuKrnl.h"
#include "EmuNVNet.h" #include "EmuNVNet.h"
// NVNET Register Definitions // NVNET Register Definitions

View File

@ -48,5 +48,3 @@ public:
uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size); uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size);
void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size); void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size);
}; };
extern NVNetDevice* g_NVNet;

94
src/devices/LED.h Normal file
View File

@ -0,0 +1,94 @@
// 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->CxbxKrnl->LED.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 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#pragma once
namespace LED {
// See http://xboxdevwiki.net/PIC#The_LED
namespace Phase0 { enum { Off = 0, Red = 1 << 7, Green = 1 << 3, Orange = Red | Green }; };
namespace Phase1 { enum { Off = 0, Red = 1 << 6, Green = 1 << 2, Orange = Red | Green }; };
namespace Phase2 { enum { Off = 0, Red = 1 << 5, Green = 1 << 1, Orange = Red | Green }; };
namespace Phase3 { enum { Off = 0, Red = 1 << 4, Green = 1 << 0, Orange = Red | Green }; };
typedef uint8_t Sequence;
// Pre-defined LED Phase sequences
constexpr Sequence OFF = Phase0::Off | Phase1::Off | Phase2::Off | Phase3::Off;
// Solid single color: constant on
constexpr Sequence RED = Phase0::Red | Phase1::Red | Phase2::Red | Phase3::Red;
constexpr Sequence GREEN = Phase0::Green | Phase1::Green | Phase2::Green | Phase3::Green;
constexpr Sequence ORANGE = Phase0::Orange | Phase1::Orange | Phase2::Orange | Phase3::Orange;
// Signal single color: thrice on, once off
constexpr Sequence SIGNAL_RED = Phase0::Red | Phase1::Red | Phase2::Red | Phase3::Off;
constexpr Sequence SIGNAL_GREEN = Phase0::Green | Phase1::Green | Phase2::Green | Phase3::Off;
constexpr Sequence SIGNAL_ORANGE = Phase0::Orange | Phase1::Orange | Phase2::Orange | Phase3::Off;
// Blink single color: twice on, twice off
constexpr Sequence BLINK_RED = Phase0::Red | Phase1::Red | Phase2::Off | Phase3::Off;
constexpr Sequence BLINK_GREEN = Phase0::Green | Phase1::Green | Phase2::Off | Phase3::Off;
constexpr Sequence BLINK_ORANGE = Phase0::Orange | Phase1::Orange | Phase2::Off | Phase3::Off;
// Blip single color: once on, thrice off
constexpr Sequence BLIP_RED = Phase0::Red | Phase1::Off | Phase2::Off | Phase3::Off;
constexpr Sequence BLIP_GREEN = Phase0::Green | Phase1::Off | Phase2::Off | Phase3::Off;
constexpr Sequence BLIP_ORANGE = Phase0::Orange | Phase1::Off | Phase2::Off | Phase3::Off;
// Blip twice, single color: on, off, on, off
constexpr Sequence BLIP_RED_RED = Phase0::Red | Phase1::Off | Phase2::Red | Phase3::Off;
constexpr Sequence BLIP_GREEN_GREEN = Phase0::Green | Phase1::Off | Phase2::Green | Phase3::Off;
constexpr Sequence BLIP_ORANGE_ORANGE = Phase0::Orange | Phase1::Off | Phase2::Orange | Phase3::Off;
// Blip, two colors: first, off, second, off
constexpr Sequence BLIP_RED_GREEN = Phase0::Red | Phase1::Off | Phase2::Green | Phase3::Off;
constexpr Sequence BLIP_RED_ORANGE = Phase0::Red | Phase1::Off | Phase2::Orange | Phase3::Off;
constexpr Sequence BLIP_GREEN_ORANGE = Phase0::Green | Phase1::Off | Phase2::Orange | Phase3::Off;
// Solid, two colors: alternating
constexpr Sequence RED_GREEN = Phase0::Red | Phase1::Red | Phase2::Green | Phase3::Green;
constexpr Sequence RED_ORANGE = Phase0::Red | Phase1::Red | Phase2::Orange | Phase3::Orange;
constexpr Sequence GREEN_ORANGE = Phase0::Green | Phase1::Green | Phase2::Orange | Phase3::Orange;
// Solid, two colors: alternating quickly
constexpr Sequence FAST_RED_GREEN = Phase0::Red | Phase1::Green | Phase2::Red | Phase3::Green;
constexpr Sequence FAST_RED_ORANGE = Phase0::Red | Phase1::Orange | Phase2::Red | Phase3::Orange;
constexpr Sequence FAST_GREEN_ORANGE = Phase0::Green | Phase1::Orange | Phase2::Green | Phase3::Orange;
}
extern void SetLEDSequence(LED::Sequence aLEDSequence);

View File

@ -0,0 +1,79 @@
// 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->MCPXDevice.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) 2018 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#define _XBOXKRNL_DEFEXTRN_
#define LOG_PREFIX "MCPX"
#include "MCPXDevice.h"
/* MCPXDevice */
MCPXDevice::MCPXDevice(MCPXRevision revision)
{
m_revision = revision;
}
// PCI Device functions
void MCPXDevice::Init()
{
// m_DeviceId = ?;
// m_VendorId = PCI_VENDOR_ID_NVIDIA;
}
void MCPXDevice::Reset()
{
}
uint32_t MCPXDevice::IORead(int barIndex, uint32_t port, unsigned size)
{
return 0;
}
void MCPXDevice::IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size)
{
}
uint32_t MCPXDevice::MMIORead(int barIndex, uint32_t addr, unsigned size)
{
return 0;
}
void MCPXDevice::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size)
{
// TODO : Log unexpected bar access
}

63
src/devices/MCPXDevice.h Normal file
View File

@ -0,0 +1,63 @@
// ******************************************************************
// *
// * .,-::::: .,:: .::::::::. .,:: .:
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
// * $$$ Y$$$P $$""""Y$$ Y$$$P
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
// *
// * src->devices->video->MCPXDevice.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) 2018 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#pragma once
#include "devices\PCIDevice.h" // For PCIDevice
typedef enum {
MCPX_1_0,
MCPX_1_1,
} MCPXROMVersion;
typedef enum {
MCPX_X2,
MCPX_X3,
} MCPXRevision;
class MCPXDevice : public PCIDevice {
public:
// constructor
MCPXDevice(MCPXRevision revision);
// 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);
private:
MCPXRevision m_revision;
};

View File

@ -47,7 +47,7 @@ void PCIBus::IOWriteConfigData(uint32_t pData) {
bool PCIBus::IORead(uint32_t addr, uint32_t* data, unsigned size) bool PCIBus::IORead(uint32_t addr, uint32_t* data, unsigned size)
{ {
switch (addr) { switch (addr) {
case PORT_PCI_CONFIG_DATA: case PORT_PCI_CONFIG_DATA: // 0xCFC
if (size == sizeof(uint32_t)) { if (size == sizeof(uint32_t)) {
*data = IOReadConfigData(); *data = IOReadConfigData();
return true; return true;
@ -69,13 +69,13 @@ bool PCIBus::IORead(uint32_t addr, uint32_t* data, unsigned size)
bool PCIBus::IOWrite(uint32_t addr, uint32_t value, unsigned size) bool PCIBus::IOWrite(uint32_t addr, uint32_t value, unsigned size)
{ {
switch (addr) { switch (addr) {
case PORT_PCI_CONFIG_ADDRESS: case PORT_PCI_CONFIG_ADDRESS: // 0xCF8
if (size == sizeof(uint32_t)) { if (size == sizeof(uint32_t)) {
IOWriteConfigAddress(value); IOWriteConfigAddress(value);
return true; return true;
} // TODO : else log wrong size-access? } // TODO : else log wrong size-access?
break; break;
case PORT_PCI_CONFIG_DATA: case PORT_PCI_CONFIG_DATA: // 0xCFC
if (size == sizeof(uint32_t)) { if (size == sizeof(uint32_t)) {
IOWriteConfigData(value); IOWriteConfigData(value);
return true; // TODO : Should IOWriteConfigData() success/failure be returned? return true; // TODO : Should IOWriteConfigData() success/failure be returned?

View File

@ -11,16 +11,19 @@
#define PCI_CONFIG_REGISTER_MASK 0xFC #define PCI_CONFIG_REGISTER_MASK 0xFC
#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) #define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
#define PCI_FUNC(devfn) ((devfn) & 0x07) #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) // 5 bits (PCIConfigAddressRegister.deviceNumber)
#define PCI_FUNC(devfn) ((devfn) & 0x07) // 3 bits (PCIConfigAddressRegister.functionNumber)
#define PCI_DEVID(bus, devfn) ((((uint16_t)(bus)) << 8) | (devfn)) #define PCI_DEVID(bus, devfn) ((((uint16_t)(bus)) << 8) | (devfn))
#define PCI_BUS_NUM(x) (((x) >> 8) & 0xff) #define PCI_BUS_NUM(x) (((x) >> 8) & 0xff)
typedef struct { typedef struct {
uint8_t registerNumber : 8; uint8_t registerNumber : 8;
uint8_t functionNumber : 3; uint8_t functionNumber : 3; // PCI_FUNC
uint8_t deviceNumber : 5; uint8_t deviceNumber : 5; // PCI_SLOT
uint8_t busNumber : 8; uint8_t busNumber : 8; // PCI_BUS_NUM
uint8_t reserved : 7; uint8_t reserved : 7;
uint8_t enable : 1; uint8_t enable : 1;
} PCIConfigAddressRegister; } PCIConfigAddressRegister;
@ -45,6 +48,4 @@ private:
PCIConfigAddressRegister m_configAddressRegister; PCIConfigAddressRegister m_configAddressRegister;
}; };
extern PCIBus* g_PCIBus;
#endif #endif

104
src/devices/PCIDevice.cpp Normal file
View File

@ -0,0 +1,104 @@
#include "PCIDevice.h"
bool PCIDevice::GetIOBar(uint32_t port, PCIBar* bar)
{
for (auto it = m_BAR.begin(); it != m_BAR.end(); ++it) {
if (it->second.reg.Raw.type == PCI_BAR_TYPE_IO && (port >= it->second.reg.IO.address) && (port < it->second.reg.IO.address + it->second.size)) {
*bar = it->second;
return true;
}
}
return false;
}
bool PCIDevice::GetMMIOBar(uint32_t addr, PCIBar* bar)
{
for (auto it = m_BAR.begin(); it != m_BAR.end(); ++it) {
if (it->second.reg.Raw.type == PCI_BAR_TYPE_MEMORY && (addr >= (it->second.reg.Memory.address << 4)) && (addr < (it->second.reg.Memory.address << 4) + it->second.size)) {
*bar = it->second;
return true;
}
}
return false;
}
bool PCIDevice::RegisterBAR(int index, uint32_t size, uint32_t defaultValue)
{
if (m_BAR.find(index) != m_BAR.end()) {
printf("PCIDevice::RegisterBar: Trying to register a BAR that is already allocated (index: %d)\n", index);
return false;
}
PCIBar bar;
bar.size = size;
bar.pDevice = this;
bar.reg.value = defaultValue;
bar.index = index;
m_BAR[index] = bar;
return true;
}
bool PCIDevice::UpdateBAR(int index, uint32_t newValue)
{
auto it = m_BAR.find(index);
if (it == m_BAR.end()) {
printf("PCIDevice::UpdateBAR: Trying to update a BAR that does not exist (index: %d, value 0x%08X)\n", index, newValue);
return false;
}
it->second.reg.value = newValue;
return true;
}
uint32_t PCIDevice::ReadConfigRegister(uint32_t reg)
{
switch (reg) {
case PCI_CONFIG_DEVICE:
return (m_DeviceId << 16) | m_VendorId;
case PCI_CONFIG_BAR_0:
case PCI_CONFIG_BAR_1:
case PCI_CONFIG_BAR_2:
case PCI_CONFIG_BAR_3:
case PCI_CONFIG_BAR_4:
case PCI_CONFIG_BAR_5:
{
int barIndex = (reg - PCI_CONFIG_BAR_0) / 4;
auto it = m_BAR.find(barIndex);
if (it == m_BAR.end()) {
printf("PCIDevice::ReadConfigRegister: Trying to Read a BAR that does not exist (index: %d)\n", barIndex);
return 0xFFFFFFFF;
}
return it->second.reg.value;
}
default:
printf("PCIDevice::ReadConfigRegister: Unhandled Register %X\n", reg);
break;
}
return 0;
}
void PCIDevice::WriteConfigRegister(uint32_t reg, uint32_t value)
{
switch (reg) {
case PCI_CONFIG_BAR_0:
case PCI_CONFIG_BAR_1:
case PCI_CONFIG_BAR_2:
case PCI_CONFIG_BAR_3:
case PCI_CONFIG_BAR_4:
case PCI_CONFIG_BAR_5:
{
int barIndex = (reg - PCI_CONFIG_BAR_0) / 4;
UpdateBAR(barIndex, value);
break;
}
default:
printf("PCIDevice::WriteConfigRegister: Unhandled Register %X\n", reg);
break;
}
}

95
src/devices/PCIDevice.h Normal file
View File

@ -0,0 +1,95 @@
#ifndef _PCIDEVICE_H_
#define _PCIDEVICE_H_
#include <cstdint>
#include <map>
#define PCI_BAR_TYPE_IO 1
#define PCI_BAR_TYPE_MEMORY 0
#define PCI_CONFIG_DEVICE 0x00
#define PCI_CONFIG_BAR_0 0x10
#define PCI_CONFIG_BAR_1 0x14
#define PCI_CONFIG_BAR_2 0x18
#define PCI_CONFIG_BAR_3 0x1C
#define PCI_CONFIG_BAR_4 0x20
#define PCI_CONFIG_BAR_5 0x24
#define PCI_VENDOR_ID_NVIDIA 0x10DE
class PCIDevice;
typedef struct
{
} PCIBarMemory;
typedef struct
{
} PCIBarIO;
typedef struct {
union {
struct {
uint32_t type : 1;
uint32_t locatable : 2;
uint32_t prefetchable : 1;
uint32_t address : 28;
}Memory;
struct {
uint32_t type : 1;
uint32_t reserved : 1;
uint32_t address : 30;
}IO;
struct {
uint32_t type : 1;
uint32_t other : 31;
}Raw ;
uint32_t value;
};
} PCIBarRegister;
typedef struct {
uint32_t size;
PCIBarRegister reg;
int index;
PCIDevice* pDevice;
} PCIBar;
class PCIDevice {
// PCI Device Interface
public:
virtual void Init() = 0;
virtual void Reset() = 0;
virtual uint32_t IORead(int barIndex, uint32_t port, unsigned size) = 0;
virtual void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size) = 0;
virtual uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size) = 0;
virtual void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) = 0;
// PCI Device Implementation
public:
bool GetIOBar(uint32_t port, PCIBar* bar);
bool GetMMIOBar(uint32_t addr, PCIBar * bar);
bool RegisterBAR(int index, uint32_t size, uint32_t defaultValue);
bool UpdateBAR(int index, uint32_t newValue);
uint32_t ReadConfigRegister(uint32_t reg);
void WriteConfigRegister(uint32_t reg, uint32_t value);
protected:
std::map<int, PCIBar> m_BAR;
uint16_t m_DeviceId;
uint16_t m_VendorId;
/* Unused?
private:
static uint64_t MMIOBarRead(struct uc_struct* uc, void* pBar, uint64_t addr, unsigned size);
static void MMIOBarWrite(struct uc_struct* uc, void* pBar, uint64_t addr, uint64_t value, unsigned size);
*/
};
#endif

View File

@ -24,13 +24,14 @@ void SMBus::Reset()
void SMBus::ConnectDevice(uint8_t addr, SMDevice *pDevice) void SMBus::ConnectDevice(uint8_t addr, SMDevice *pDevice)
{ {
uint8_t dev_addr = (addr >> 1) & 0x7f;
if (m_Devices.find(addr) != m_Devices.end()) { if (m_Devices.find(dev_addr) != m_Devices.end()) {
printf("PCIBus: Attempting to connect two devices to the same device address\n"); printf("PCIBus: Attempting to connect two devices to the same device address\n");
return; return;
} }
m_Devices[addr] = pDevice; m_Devices[dev_addr] = pDevice;
pDevice->Init(); pDevice->Init();
} }

View File

@ -78,6 +78,4 @@ class SMBus : public PCIDevice {
std::map<uint8_t, SMDevice*> m_Devices; std::map<uint8_t, SMDevice*> m_Devices;
}; };
extern SMBus* g_SMBus;
#endif #endif

View File

@ -35,20 +35,38 @@
// ****************************************************************** // ******************************************************************
#define _XBOXKRNL_DEFEXTRN_ #define _XBOXKRNL_DEFEXTRN_
#include "SMCDevice.h" // For SMCDevice
#include "LED.h"
/* prevent name collisions */ /* prevent name collisions */
namespace xboxkrnl namespace xboxkrnl
{ {
#include <xboxkrnl/xboxkrnl.h> // For xbox.h:AV_PACK_HDTV #include <xboxkrnl/xboxkrnl.h> // For xbox.h:AV_PACK_HDTV
}; };
#include "CxbxKrnl\CxbxKrnl.h"
#include "CxbxKrnl\EmuShared.h"
#include "SMCDevice.h" // For SMCDevice
#include "LED.h"
void SetLEDSequence(LED::Sequence aLEDSequence)
{
// See http://xboxdevwiki.net/PIC#The_LED
DbgPrintf("SMC : SetLEDSequence : %u\n", (byte)aLEDSequence);
int LedSequence[4] = { XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF };
LedSequence[0] = ((aLEDSequence >> 6) & 2) | ((aLEDSequence >> 3) & 1);
LedSequence[1] = ((aLEDSequence >> 5) & 2) | ((aLEDSequence >> 2) & 1);
LedSequence[2] = ((aLEDSequence >> 4) & 2) | ((aLEDSequence >> 1) & 1);
LedSequence[3] = ((aLEDSequence >> 3) & 2) | ((aLEDSequence >> 0) & 1);
g_EmuShared->SetLedSequence(LedSequence);
}
/* SMCDevice */ /* SMCDevice */
SMCDevice::SMCDevice(HardwareModel hardwareModel) SMCDevice::SMCDevice(SCMRevision revision)
{ {
m_HardwareModel = hardwareModel; m_revision = revision;
} }
void SMCDevice::Init() void SMCDevice::Init()
@ -79,30 +97,31 @@ uint8_t SMCDevice::ReadByte(uint8_t command)
switch (command) { switch (command) {
case SMC_COMMAND_VERSION: // 0x01 PIC version string case SMC_COMMAND_VERSION: // 0x01 PIC version string
// See http://xboxdevwiki.net/PIC#PIC_version_string // See http://xboxdevwiki.net/PIC#PIC_version_string
switch (m_HardwareModel) { switch (m_revision) {
case Revision1_0: buffer[0] = "P01"[m_PICVersionStringIndex]; break; case SCMRevision::P01: buffer[0] = "P01"[m_PICVersionStringIndex]; break;
case Revision1_1: buffer[0] = "P05"[m_PICVersionStringIndex]; break; case SCMRevision::P2L: buffer[0] = "P05"[m_PICVersionStringIndex]; break; // ??
case DebugKit: buffer[0] = "DXB"[m_PICVersionStringIndex]; break; case SCMRevision::D01: buffer[0] = "DXB"[m_PICVersionStringIndex]; break;
// default: UNREACHABLE(hardwareModel); case SCMRevision::D05: buffer[0] = "D05"[m_PICVersionStringIndex]; break; // ??
// default: UNREACHABLE(m_revision);
} }
m_PICVersionStringIndex = (m_PICVersionStringIndex + 1) % 3; m_PICVersionStringIndex = (m_PICVersionStringIndex + 1) % 3;
break; break;
//0x03 tray state //case 0x03: // tray state
//#define SMC_COMMAND_AV_PACK 0x04 // A / V Pack state //case SMC_COMMAND_AV_PACK: // 0x04 // A / V Pack state
//0x09 CPU temperature(°C) //case SMC_COMMAND_CPU_TEMP: // 0x09 // CPU temperature (°C)
//0x0A board temperature(°C) //case SMC_COMMAND_GPU_TEMP: // 0x0A // GPU (board?) temperature (°C)
case 0x0F: // reads scratch register written with 0x0E case 0x0F: // reads scratch register written with 0x0E
return buffer[0x0E]; return buffer[0x0E];
//0x10 current fan speed(0~50) //case SMC_COMMAND_POWER_FAN_READBACK: // 0x10 // Current power fan speed (0-50)
//0x11 interrupt reason //case 0x11: // interrupt reason
//0x18 reading this reg locks up xbox in "overheated" state //case 0x18: // reading this reg locks up xbox in "overheated" state
//#define SMC_COMMAND_SCRATCH 0x1B // scratch register for the original kernel //case SMC_COMMAND_SCRATCH: // 0x1B // scratch register for the original kernel
case SMC_COMMAND_CHALLENGE_1C: // random number for boot challenge case SMC_COMMAND_CHALLENGE_1C: // random number for boot challenge
case SMC_COMMAND_CHALLENGE_1D: // random number for boot challenge case SMC_COMMAND_CHALLENGE_1D: // random number for boot challenge
case SMC_COMMAND_CHALLENGE_1E: // random number for boot challenge case SMC_COMMAND_CHALLENGE_1E: // random number for boot challenge
case SMC_COMMAND_CHALLENGE_1F: // random number for boot challenge case SMC_COMMAND_CHALLENGE_1F: // random number for boot challenge
if (m_HardwareModel == DebugKit) if (m_revision == SCMRevision::D01)
// See http://xboxdevwiki.net/PIC#PIC_Challenge_.28regs_0x1C.7E0x21.29 // See http://xboxdevwiki.net/PIC#PIC_Challenge_.28regs_0x1C.7E0x21.29
return 0; return 0;
@ -135,9 +154,15 @@ void SMCDevice::WriteByte(uint8_t command, uint8_t value)
if (value == 0) // Note : MAME Xbox/Chihiro driver doesn't check for zero if (value == 0) // Note : MAME Xbox/Chihiro driver doesn't check for zero
m_PICVersionStringIndex = 0; m_PICVersionStringIndex = 0;
return; return;
//0x02 reset and power off control case SMC_COMMAND_RESET: //0x02 reset and power off control
//0x05 power fan mode(0 = automatic; 1 = custom speed from reg 0x06) // See http://xboxdevwiki.net/PIC#Reset_and_Power_Off
//0x06 power fan speed(0..~50) switch (value) {
case SMC_RESET_ASSERT_RESET: return; // TODO
case SMC_RESET_ASSERT_POWERCYCLE: return; // TODO
case SMC_RESET_ASSERT_SHUTDOWN: CxbxKrnlShutDown(); return; // Power off, terminating the emulation
}
//case SMC_COMMAND_POWER_FAN_MODE: // 0x05 // power fan mode(0 = automatic; 1 = custom speed from reg 0x06)
//case SMC_COMMAND_POWER_FAN_REGISTER: // 0x06 // Set custom power fan speed (0-50)
case SMC_COMMAND_LED_MODE: // 0x07 LED mode(0 = automatic; 1 = custom sequence from reg 0x08) case SMC_COMMAND_LED_MODE: // 0x07 LED mode(0 = automatic; 1 = custom sequence from reg 0x08)
switch (value) { switch (value) {
case 0: SetLEDSequence(LED::GREEN); return; // Automatic LED management: we set it to solid green case 0: SetLEDSequence(LED::GREEN); return; // Automatic LED management: we set it to solid green
@ -146,21 +171,40 @@ void SMCDevice::WriteByte(uint8_t command, uint8_t value)
// Notes from https://github.com/ergo720/Cxbx-Reloaded/blob/LED/src/CxbxKrnl/EmuKrnlHal.cpp#L572 // Notes from https://github.com/ergo720/Cxbx-Reloaded/blob/LED/src/CxbxKrnl/EmuKrnlHal.cpp#L572
// //
// HalWriteSMBusValue(0x20, 0x08, false, x) and then HalWriteSMBusValue(0x20, 0x07, false, y > 1) // HalWriteSMBusValue(0x20, 0x08, false, x) and then HalWriteSMBusValue(0x20, 0x07, false, y > 1)
// will cause the led to be solid green, with the next pair of // will cause the led to be solid green, while the next pair of
// HalWriteSMBusValue with arbitrary y will cause the led to assume the color of the sequence x // HalWriteSMBusValue with arbitrary y will cause the led to assume the color of the sequence x
// and afterwards this will repeat with whatever y; ntstatus are always 0 // and afterwards this will repeat with whatever y; ntstatus is always 0
// //
// TODO : Implement the above, SMB_GLOBAL_STATUS should probably get the GS_PRERR_STS flag. But how? // TODO : Implement the above, SMB_GLOBAL_STATUS should probably get the GS_PRERR_STS flag. But how?
return; return;
} }
// #define SMC_COMMAND_LED_SEQUENCE 0x08 // LED flashing sequence case SMC_COMMAND_LED_SEQUENCE: // 0x08 LED flashing sequence
//0x0C tray eject(0 = eject; 1 = load) // ergo720: if WriteWord is true the Xbox still sets the LED correctly but it errors with ntstatus
//0x0E another scratch register ? seems like an error code. // STATUS_IO_DEVICE_ERROR, however WriteWord is not accessible from here
//0x19 reset on eject(0 = enable; 1 = disable) // The LED flashing sequence is stored in the buffer of the SMCDevice class, so there's nothing to do here
//0x1A interrupt enable(write 0x01 to enable; can't disable once enabled) break;
//0x1B scratch register for the original kernel //case 0x0C: // tray eject(0 = eject; 1 = load)
//0x20 response to PIC challenge(written first) //case 0x0E: // another scratch register ? seems like an error code.
//0x21 response to PIC challenge(written second) //case 0x19: // reset on eject(0 = enable; 1 = disable)
//case 0x1A: // interrupt enable(write 0x01 to enable; can't disable once enabled)
case SMC_COMMAND_SCRATCH: //0x1B scratch register for the original kernel
// See http://xboxdevwiki.net/PIC#Scratch_register_values
switch (value) {
case SMC_SCRATCH_TRAY_EJECT_PENDING: return; // TODO
case SMC_SCRATCH_DISPLAY_FATAL_ERROR:
{
int FatalFlag;
g_EmuShared->GetBootFlags(&FatalFlag);
FatalFlag |= BOOT_FATAL_ERROR;
g_EmuShared->SetBootFlags(&FatalFlag);
break;
}
case SMC_SCRATCH_SHORT_ANIMATION: return; // TODO
case SMC_SCRATCH_DASHBOARD_BOOT: return; // TODO
}
break;
//case 0x20: // response to PIC challenge(written first)
//case 0x21: // response to PIC challenge(written second)
} }
buffer[command] = value; buffer[command] = value;
@ -181,3 +225,4 @@ void SMCDevice::WriteBlock(uint8_t command, uint8_t* data, int length)
{ {
// TODO // TODO
} }

View File

@ -49,8 +49,6 @@
// the low-level functionality of this PIC, but only the minimum set of // the low-level functionality of this PIC, but only the minimum set of
// high-level commands that are sufficient for the Xbox. // high-level commands that are sufficient for the Xbox.
#define SMBUS_SMC_SLAVE_ADDRESS 0x20 // = Write; Read = 0x21
// Reading: // Reading:
// From https://web.archive.org/web/20100617022549/http://www.xbox-linux.org/wiki/PIC : // From https://web.archive.org/web/20100617022549/http://www.xbox-linux.org/wiki/PIC :
@ -58,10 +56,10 @@
#define SMC_COMMAND_VERSION 0x01 // PIC version string #define SMC_COMMAND_VERSION 0x01 // PIC version string
//0x03 tray state //0x03 tray state
#define SMC_COMMAND_AV_PACK 0x04 // A / V Pack state #define SMC_COMMAND_AV_PACK 0x04 // A / V Pack state
//0x09 CPU temperature(°C) #define SMC_COMMAND_CPU_TEMP 0x09 // CPU temperature (°C)
//0x0A board temperature(°C) #define SMC_COMMAND_GPU_TEMP 0x0A // GPU (board?) temperature (°C)
//0x0F reads scratch register written with 0x0E //0x0F reads scratch register written with 0x0E
//0x10 current fan speed(0~50) #define SMC_COMMAND_POWER_FAN_READBACK 0x10 // Current power fan speed (0-50)
//0x11 interrupt reason //0x11 interrupt reason
//0x18 reading this reg locks up xbox in "overheated" state //0x18 reading this reg locks up xbox in "overheated" state
#define SMC_COMMAND_SCRATCH 0x1B // scratch register for the original kernel #define SMC_COMMAND_SCRATCH 0x1B // scratch register for the original kernel
@ -74,29 +72,46 @@
// //
//Command Description //Command Description
//0x01 PIC version string counter reset //0x01 PIC version string counter reset
//0x02 reset and power off control #define SMC_COMMAND_RESET 0x02 //0x02 reset and power off control
//0x05 power fan mode(0 = automatic; 1 = custom speed from reg 0x06) #define SMC_COMMAND_POWER_FAN_MODE 0x05 // power fan mode(0 = automatic; 1 = custom speed from reg 0x06)
//0x06 power fan speed(0..~50) #define SMC_COMMAND_POWER_FAN_REGISTER 0x06 // Set custom power fan speed (0-50)
#define SMC_COMMAND_LED_MODE 0x07 // LED mode(0 = automatic; 1 = custom sequence from reg 0x08) #define SMC_COMMAND_LED_MODE 0x07 // LED mode(0 = automatic; 1 = custom sequence from reg 0x08)
#define SMC_COMMAND_LED_SEQUENCE 0x08 // LED flashing sequence #define SMC_COMMAND_LED_SEQUENCE 0x08 // LED flashing sequence
//0x0C tray eject(0 = eject; 1 = load) //0x0C tray eject(0 = eject; 1 = load)
//0x0E another scratch register ? seems like an error code. //0x0E another scratch register ? seems like an error code.
//0x19 reset on eject(0 = enable; 1 = disable) //0x19 reset on eject(0 = enable; 1 = disable)
//0x1A interrupt enable(write 0x01 to enable; can't disable once enabled) //0x1A interrupt enable(write 0x01 to enable; can't disable once enabled)
//0x1B scratch register for the original kernel #define SMC_COMMAND_SCRATCH 0x1B //0x1B scratch register for the original kernel
//0x20 response to PIC challenge(written first) //0x20 response to PIC challenge(written first)
//0x21 response to PIC challenge(written second) //0x21 response to PIC challenge(written second)
typedef enum { // TODO : Move to it's own file //
Revision1_0, // Register values for SMC_COMMAND_RESET
Revision1_1, //
DebugKit #define SMC_RESET_ASSERT_RESET 0x01
} HardwareModel; #define SMC_RESET_ASSERT_POWERCYCLE 0x40
#define SMC_RESET_ASSERT_SHUTDOWN 0x80
//
// Register values for SMC_COMMAND_SCRATCH
//
#define SMC_SCRATCH_TRAY_EJECT_PENDING 0x01
#define SMC_SCRATCH_DISPLAY_FATAL_ERROR 0x02
#define SMC_SCRATCH_SHORT_ANIMATION 0x04
#define SMC_SCRATCH_DASHBOARD_BOOT 0x08
typedef enum {
// http://xboxdevwiki.net/System_Management_Controller
P01,
P2L,
D01, // Seen in a debug kit
D05, // Seen in a earlier model chihiro
} SCMRevision;
class SMCDevice : public SMDevice { class SMCDevice : public SMDevice {
public: public:
// constructor // constructor
SMCDevice(HardwareModel hardwareModel); SMCDevice(SCMRevision revision);
// SMDevice functions // SMDevice functions
void Init(); void Init();
@ -112,10 +127,9 @@ public:
void WriteByte(uint8_t command, uint8_t value); void WriteByte(uint8_t command, uint8_t value);
void WriteWord(uint8_t command, uint16_t value); void WriteWord(uint8_t command, uint16_t value);
void WriteBlock(uint8_t command, uint8_t* data, int length); void WriteBlock(uint8_t command, uint8_t* data, int length);
private: private:
HardwareModel m_HardwareModel; SCMRevision m_revision;
int m_PICVersionStringIndex = 0; int m_PICVersionStringIndex = 0;
uint8_t buffer[256] = {}; uint8_t buffer[256] = {};
}; };
extern SMCDevice* g_SMC;

2
src/devices/SMDevice.cpp Normal file
View File

@ -0,0 +1,2 @@
#include "SMDevice.h"

23
src/devices/SMDevice.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef _SMDEVICE_H_
#define _SMDEVICE_H_
#include <cstdint>
class SMDevice {
public:
virtual void Init() = 0;
virtual void Reset() = 0;
virtual void QuickCommand(bool read) = 0;
virtual uint8_t ReceiveByte() = 0;
virtual uint8_t ReadByte(uint8_t command) = 0;
virtual uint16_t ReadWord(uint8_t command) = 0;
virtual int ReadBlock(uint8_t command, uint8_t *data) = 0;
virtual void SendByte(uint8_t data) = 0;
virtual void WriteByte(uint8_t command, uint8_t value) = 0;
virtual void WriteWord(uint8_t command, uint16_t value) = 0;
virtual void WriteBlock(uint8_t command, uint8_t* data, int length) = 0;
};
#endif

162
src/devices/Xbox.cpp Normal file
View File

@ -0,0 +1,162 @@
// 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->CxbxKrnl->Xbox.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 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#include "Xbox.h" // For HardwareModel
PCIBus* g_PCIBus;
SMBus* g_SMBus;
MCPXDevice* g_MCPX;
SMCDevice* g_SMC;
EEPROMDevice* g_EEPROM;
NVNetDevice* g_NVNet;
NV2ADevice* g_NV2A;
MCPXRevision MCPXRevisionFromHardwareModel(HardwareModel hardwareModel)
{
switch (hardwareModel) {
case Revision1_0:
case Revision1_1:
case Revision1_2:
case Revision1_3:
case Revision1_4:
case Revision1_5:
case Revision1_6:
return MCPXRevision::MCPX_X3;
case DebugKit:
// EmuWarning("Guessing MCPXVersion");
return MCPXRevision::MCPX_X2;
default:
// UNREACHABLE(hardwareModel);
return MCPXRevision::MCPX_X3;
}
}
SCMRevision SCMRevisionFromHardwareModel(HardwareModel hardwareModel)
{
switch (hardwareModel) {
case Revision1_0:
return SCMRevision::P01; // Our SCM returns PIC version string "P01"
case Revision1_1:
case Revision1_2:
case Revision1_3:
case Revision1_4:
case Revision1_5:
case Revision1_6:
// EmuWarning("Guessing SCMRevision");
return SCMRevision::P2L; // Assumption; Our SCM returns PIC version string "P05"
case DebugKit:
return SCMRevision::D01; // Our SCM returns PIC version string "DXB"
default:
// UNREACHABLE(hardwareModel);
return SCMRevision::P2L;
}
}
TVEncoder TVEncoderFromHardwareModel(HardwareModel hardwareModel)
{
switch (hardwareModel) {
case Revision1_0:
case Revision1_1:
case Revision1_2:
case Revision1_3:
return TVEncoder::Conexant;
case Revision1_4:
return TVEncoder::Focus;
case Revision1_5:
return TVEncoder::Focus; // Assumption
case Revision1_6:
return TVEncoder::XCalibur;
case DebugKit:
// LukeUsher : My debug kit and at least most of them (maybe all?)
// are equivalent to v1.0 and have Conexant encoders.
return TVEncoder::Conexant;
default:
// UNREACHABLE(hardwareModel);
return TVEncoder::Focus;
}
}
void InitXboxHardware(HardwareModel hardwareModel)
{
// Determine which (revisions of which) components should be used for this hardware model
MCPXRevision mcpx_revision = MCPXRevisionFromHardwareModel(hardwareModel);
SCMRevision smc_revision = SCMRevisionFromHardwareModel(hardwareModel);
TVEncoder tv_encoder = TVEncoderFromHardwareModel(hardwareModel);
// Create busses
g_PCIBus = new PCIBus();
g_SMBus = new SMBus();
// Create devices
g_MCPX = new MCPXDevice(mcpx_revision);
g_SMC = new SMCDevice(smc_revision);
g_EEPROM = new EEPROMDevice();
g_NVNet = new NVNetDevice();
g_NV2A = new NV2ADevice();
// Connect devices to SM bus
g_SMBus->ConnectDevice(SMBUS_ADDRESS_SYSTEM_MICRO_CONTROLLER, g_SMC); // W 0x20 R 0x21
g_SMBus->ConnectDevice(SMBUS_ADDRESS_EEPROM, g_EEPROM); // W 0xA8 R 0xA9
// TODO : Other SMBus devices to connect
//g_SMBus->ConnectDevice(SMBUS_ADDRESS_MCPX, g_MCPX); // W 0x10 R 0x11 -- TODO : Is MCPX an SMBus and/or PCI device?
//g_SMBus->ConnectDevice(SMBUS_ADDRESS_TEMPERATURE_MEASUREMENT, g_TemperatureMeasurement); // W 0x98 R 0x99
//g_SMBus->ConnectDevice(SMBUS_ADDRESS_TV_ENCODER, g_TVEncoder); // W 0x88 R 0x89
switch (tv_encoder) {
case TVEncoder::Conexant:
// g_SMBus->ConnectDevice(SMBUS_ADDRESS_TV_ENCODER_ID_CONEXANT, g_TVEncoderConexant); // W 0x8A R 0x8B
break;
case TVEncoder::Focus:
// g_SMBus->ConnectDevice(SMBUS_ADDRESS_TV_ENCODER_ID_FOCUS, g_TVEncoderFocus); // W 0xD4 R 0xD5
break;
case TVEncoder::XCalibur:
// g_SMBus->ConnectDevice(SMBUS_ADDRESS_TV_ENCODER_ID_XCALIBUR, g_TVEncoderXCalibur); // W 0xE0 R 0xE1
break;
}
// Connect devices to PCI bus
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(0, PCI_DEVFN(4, 1)), g_MCPX); // MCPX device ID = 0x0808 ?
//g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(5, 0)), g_NVAPU);
//g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(6, 0)), g_AC97);
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
// https://github.com/JayFoxRox/Chihiro-Launcher/blob/master/hook.h
// https://github.com/docbrown/vxb/wiki/Xbox-Hardware-Information
// https://web.archive.org/web/20100617022549/http://www.xbox-linux.org/wiki/PIC
}

View File

@ -9,7 +9,7 @@
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, // * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, // * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
// * // *
// * src->CxbxKrnl->Xbox.cpp // * src->CxbxKrnl->Xbox.h
// * // *
// * This file is part of the Cxbx project. // * This file is part of the Cxbx project.
// * // *
@ -32,41 +32,50 @@
// * // *
// * All rights reserved // * All rights reserved
// * // *
// ****************************************************************** // ******************************************************************#pragma once
#include "Xbox.h" #pragma once
#include "PCIBus.h" // For PCIBus #include "PCIBus.h" // For PCIBus
#include "SMBus.h" // For SMBus #include "SMBus.h" // For SMBus
#include "MCPXDevice.h" // For MCPXDevice
#include "SMCDevice.h" // For SMCDevice #include "SMCDevice.h" // For SMCDevice
#include "EEPROMDevice.h" // For EEPROMDevice #include "EEPROMDevice.h" // For EEPROMDevice
#include "EmuNVNet.h" // For NVNetDevice #include "EmuNVNet.h" // For NVNetDevice
#include "devices\video\nv2a.h" // For NV2ADevice
PCIBus* g_PCIBus; #define SMBUS_ADDRESS_MCPX 0x10 // = Write; Read = 0x11
SMBus* g_SMBus; #define SMBUS_ADDRESS_TV_ENCODER 0x88 // = Write; Read = 0x89
SMCDevice* g_SMC; #define SMBUS_ADDRESS_SYSTEM_MICRO_CONTROLLER 0x20 // = Write; Read = 0x21
EEPROMDevice* g_EEPROM; #define SMBUS_ADDRESS_TV_ENCODER_ID_CONEXANT 0x8A // = Write; Read = 0x8B
NVNetDevice* g_NVNet; #define SMBUS_ADDRESS_TEMPERATURE_MEASUREMENT 0x98 // = Write; Read = 0x99
#define SMBUS_ADDRESS_EEPROM 0xA8 // = Write; Read = 0xA9
#define SMBUS_ADDRESS_TV_ENCODER_ID_FOCUS 0xD4 // = Write; Read = 0xD5
#define SMBUS_ADDRESS_TV_ENCODER_ID_XCALIBUR 0xE0 // = Write; Read = 0xE1
#define SMBUS_TV_ENCODER_ID_CONEXANT 0x8A // = Write; Read = 08B typedef enum {
#define SMBUS_TV_ENCODER_ID_FOCUS 0xD4 // = Write; Read = 0D5 Revision1_0,
Revision1_1,
Revision1_2,
Revision1_3,
Revision1_4,
Revision1_5,
Revision1_6,
DebugKit
} HardwareModel;
void InitXboxHardware() typedef enum { // TODO : Move to it's own file
{ // http://xboxdevwiki.net/Hardware_Revisions#Video_encoder
g_PCIBus = new PCIBus(); Conexant,
g_SMBus = new SMBus(); Focus,
g_SMC = new SMCDevice(Revision1_1); // TODO : Make configurable XCalibur
g_EEPROM = new EEPROMDevice(); } TVEncoder;
g_NVNet = new NVNetDevice();
g_SMBus->ConnectDevice(SMBUS_SMC_SLAVE_ADDRESS, g_SMC); extern PCIBus* g_PCIBus;
g_SMBus->ConnectDevice(SMBUS_EEPROM_ADDRESS, g_EEPROM); extern SMBus* g_SMBus;
extern MCPXDevice* g_MCPX;
extern SMCDevice* g_SMC;
extern EEPROMDevice* g_EEPROM;
extern NVNetDevice* g_NVNet;
extern NV2ADevice* g_NV2A;
g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(1, 1)), g_SMBus); extern void InitXboxHardware(HardwareModel hardwareModel);
g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(4, 0)), g_NVNet);
// TODO : Handle other SMBUS Addresses, like PIC_ADDRESS, XCALIBUR_ADDRESS
// Resources : http://pablot.com/misc/fancontroller.cpp
// https://github.com/JayFoxRox/Chihiro-Launcher/blob/master/hook.h
// https://github.com/docbrown/vxb/wiki/Xbox-Hardware-Information
// https://web.archive.org/web/20100617022549/http://www.xbox-linux.org/wiki/PIC
}

View File

@ -66,12 +66,13 @@ namespace xboxkrnl
#include <queue> #include <queue>
#include <thread> #include <thread>
#include "CxbxKrnl.h" #include "CxbxKrnl\CxbxKrnl.h"
#include "Emu.h" #include "CxbxKrnl\Emu.h"
#include "EmuFS.h" #include "CxbxKrnl\EmuFS.h"
#include "EmuKrnl.h" #include "CxbxKrnl\EmuKrnl.h"
#include "CxbxKrnl\HLEIntercept.h"
#include "EmuNV2A.h" #include "EmuNV2A.h"
#include "HLEIntercept.h"
#include "nv2a_int.h" // from https://github.com/espes/xqemu/tree/xbox/hw/xbox #include "nv2a_int.h" // from https://github.com/espes/xqemu/tree/xbox/hw/xbox
#include <gl\glew.h> #include <gl\glew.h>
@ -350,7 +351,7 @@ struct {
uint32_t enabled_interrupts; uint32_t enabled_interrupts;
std::thread puller_thread; std::thread puller_thread;
Cache1State cache1; Cache1State cache1;
uint32_t regs[NV_PFIFO_SIZE]; // TODO : union uint32_t regs[_NV_PFIFO_SIZE]; // TODO : union
} pfifo; } pfifo;
struct { struct {
@ -571,12 +572,14 @@ const char *DebugNV_##DEV##(xbaddr addr) \
DEBUG_START(PMC) DEBUG_START(PMC)
DEBUG_CASE(NV_PMC_BOOT_0); DEBUG_CASE(NV_PMC_BOOT_0);
DEBUG_CASE(NV_PMC_BOOT_1);
DEBUG_CASE(NV_PMC_INTR_0); DEBUG_CASE(NV_PMC_INTR_0);
DEBUG_CASE(NV_PMC_INTR_EN_0); DEBUG_CASE(NV_PMC_INTR_EN_0);
DEBUG_CASE(NV_PMC_ENABLE); DEBUG_CASE(NV_PMC_ENABLE);
DEBUG_END(PMC) DEBUG_END(PMC)
DEBUG_START(PBUS) DEBUG_START(PBUS)
DEBUG_CASE(NV_PBUS_FBIO_RAM)
DEBUG_CASE_EX(NV_PBUS_PCI_NV_0, ":VENDOR_ID"); DEBUG_CASE_EX(NV_PBUS_PCI_NV_0, ":VENDOR_ID");
DEBUG_CASE(NV_PBUS_PCI_NV_1); DEBUG_CASE(NV_PBUS_PCI_NV_1);
DEBUG_CASE_EX(NV_PBUS_PCI_NV_2, ":REVISION_ID"); DEBUG_CASE_EX(NV_PBUS_PCI_NV_2, ":REVISION_ID");
@ -604,25 +607,45 @@ DEBUG_START(PBUS)
DEBUG_END(PBUS) DEBUG_END(PBUS)
DEBUG_START(PFIFO) DEBUG_START(PFIFO)
DEBUG_CASE(NV_PFIFO_DELAY_0);
DEBUG_CASE(NV_PFIFO_DMA_TIMESLICE);
DEBUG_CASE(NV_PFIFO_TIMESLICE);
DEBUG_CASE(NV_PFIFO_INTR_0); DEBUG_CASE(NV_PFIFO_INTR_0);
DEBUG_CASE(NV_PFIFO_INTR_EN_0); DEBUG_CASE(NV_PFIFO_INTR_EN_0);
DEBUG_CASE(NV_PFIFO_RAMHT); DEBUG_CASE(NV_PFIFO_RAMHT);
DEBUG_CASE(NV_PFIFO_RAMFC); DEBUG_CASE(NV_PFIFO_RAMFC);
DEBUG_CASE(NV_PFIFO_RAMRO); DEBUG_CASE(NV_PFIFO_RAMRO);
DEBUG_CASE(NV_PFIFO_RUNOUT_STATUS); DEBUG_CASE(NV_PFIFO_RUNOUT_STATUS);
DEBUG_CASE(NV_PFIFO_RUNOUT_PUT_ADDRESS);
DEBUG_CASE(NV_PFIFO_RUNOUT_GET_ADDRESS);
DEBUG_CASE(NV_PFIFO_CACHES);
DEBUG_CASE(NV_PFIFO_MODE); DEBUG_CASE(NV_PFIFO_MODE);
DEBUG_CASE(NV_PFIFO_DMA); DEBUG_CASE(NV_PFIFO_DMA);
DEBUG_CASE(NV_PFIFO_SIZE)
DEBUG_CASE(NV_PFIFO_CACHE0_PUSH0);
DEBUG_CASE(NV_PFIFO_CACHE0_PULL0);
DEBUG_CASE(NV_PFIFO_CACHE0_HASH);
DEBUG_CASE(NV_PFIFO_CACHE1_PUSH0); DEBUG_CASE(NV_PFIFO_CACHE1_PUSH0);
DEBUG_CASE(NV_PFIFO_CACHE1_PUSH1); DEBUG_CASE(NV_PFIFO_CACHE1_PUSH1);
DEBUG_CASE(NV_PFIFO_CACHE1_PUT);
DEBUG_CASE(NV_PFIFO_CACHE1_STATUS); DEBUG_CASE(NV_PFIFO_CACHE1_STATUS);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_PUSH); DEBUG_CASE(NV_PFIFO_CACHE1_DMA_PUSH);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_FETCH); DEBUG_CASE(NV_PFIFO_CACHE1_DMA_FETCH);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_STATE); DEBUG_CASE(NV_PFIFO_CACHE1_DMA_STATE);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_INSTANCE); DEBUG_CASE(NV_PFIFO_CACHE1_DMA_INSTANCE);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_CTL);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_PUT); DEBUG_CASE(NV_PFIFO_CACHE1_DMA_PUT);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_GET); DEBUG_CASE(NV_PFIFO_CACHE1_DMA_GET);
DEBUG_CASE(NV_PFIFO_CACHE1_REF);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_SUBROUTINE); DEBUG_CASE(NV_PFIFO_CACHE1_DMA_SUBROUTINE);
DEBUG_CASE(NV_PFIFO_CACHE1_PULL0); DEBUG_CASE(NV_PFIFO_CACHE1_PULL0);
DEBUG_CASE(NV_PFIFO_CACHE1_PULL1);
DEBUG_CASE(NV_PFIFO_CACHE1_HASH);
DEBUG_CASE(NV_PFIFO_CACHE1_ACQUIRE_0);
DEBUG_CASE(NV_PFIFO_CACHE1_ACQUIRE_1);
DEBUG_CASE(NV_PFIFO_CACHE1_ACQUIRE_2);
DEBUG_CASE(NV_PFIFO_CACHE1_SEMAPHORE);
DEBUG_CASE(NV_PFIFO_CACHE1_GET);
DEBUG_CASE(NV_PFIFO_CACHE1_ENGINE); DEBUG_CASE(NV_PFIFO_CACHE1_ENGINE);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_DCOUNT); DEBUG_CASE(NV_PFIFO_CACHE1_DMA_DCOUNT);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_GET_JMP_SHADOW); DEBUG_CASE(NV_PFIFO_CACHE1_DMA_GET_JMP_SHADOW);
@ -634,22 +657,36 @@ DEBUG_START(PRMA)
DEBUG_END(PRMA) DEBUG_END(PRMA)
DEBUG_START(PVIDEO) DEBUG_START(PVIDEO)
DEBUG_CASE(NV_PVIDEO_DEBUG_2);
DEBUG_CASE(NV_PVIDEO_DEBUG_3);
DEBUG_CASE(NV_PVIDEO_INTR); DEBUG_CASE(NV_PVIDEO_INTR);
DEBUG_CASE(NV_PVIDEO_INTR_EN); DEBUG_CASE(NV_PVIDEO_INTR_EN);
DEBUG_CASE(NV_PVIDEO_BUFFER); DEBUG_CASE(NV_PVIDEO_BUFFER);
DEBUG_CASE(NV_PVIDEO_STOP); DEBUG_CASE(NV_PVIDEO_STOP);
DEBUG_CASE(NV_PVIDEO_BASE); DEBUG_CASE(NV_PVIDEO_BASE(0));
DEBUG_CASE(NV_PVIDEO_LIMIT); DEBUG_CASE(NV_PVIDEO_BASE(1));
DEBUG_CASE(NV_PVIDEO_LUMINANCE); DEBUG_CASE(NV_PVIDEO_LIMIT(0));
DEBUG_CASE(NV_PVIDEO_CHROMINANCE); DEBUG_CASE(NV_PVIDEO_LIMIT(1));
DEBUG_CASE(NV_PVIDEO_OFFSET); DEBUG_CASE(NV_PVIDEO_LUMINANCE(0));
DEBUG_CASE(NV_PVIDEO_SIZE_IN); DEBUG_CASE(NV_PVIDEO_LUMINANCE(1));
DEBUG_CASE(NV_PVIDEO_POINT_IN); DEBUG_CASE(NV_PVIDEO_CHROMINANCE(0));
DEBUG_CASE(NV_PVIDEO_DS_DX); DEBUG_CASE(NV_PVIDEO_CHROMINANCE(1));
DEBUG_CASE(NV_PVIDEO_DT_DY); DEBUG_CASE(NV_PVIDEO_OFFSET(0));
DEBUG_CASE(NV_PVIDEO_POINT_OUT); DEBUG_CASE(NV_PVIDEO_OFFSET(1));
DEBUG_CASE(NV_PVIDEO_SIZE_OUT); DEBUG_CASE(NV_PVIDEO_SIZE_IN(0));
DEBUG_CASE(NV_PVIDEO_FORMAT); DEBUG_CASE(NV_PVIDEO_SIZE_IN(1));
DEBUG_CASE(NV_PVIDEO_POINT_IN(0));
DEBUG_CASE(NV_PVIDEO_POINT_IN(1));
DEBUG_CASE(NV_PVIDEO_DS_DX(0));
DEBUG_CASE(NV_PVIDEO_DS_DX(1));
DEBUG_CASE(NV_PVIDEO_DT_DY(0));
DEBUG_CASE(NV_PVIDEO_DT_DY(1));
DEBUG_CASE(NV_PVIDEO_POINT_OUT(0));
DEBUG_CASE(NV_PVIDEO_POINT_OUT(1));
DEBUG_CASE(NV_PVIDEO_SIZE_OUT(0));
DEBUG_CASE(NV_PVIDEO_SIZE_OUT(1));
DEBUG_CASE(NV_PVIDEO_FORMAT(0));
DEBUG_CASE(NV_PVIDEO_FORMAT(1));
DEBUG_END(PVIDEO) DEBUG_END(PVIDEO)
DEBUG_START(PTIMER) DEBUG_START(PTIMER)
@ -660,7 +697,6 @@ DEBUG_START(PTIMER)
DEBUG_CASE(NV_PTIMER_TIME_0); DEBUG_CASE(NV_PTIMER_TIME_0);
DEBUG_CASE(NV_PTIMER_TIME_1); DEBUG_CASE(NV_PTIMER_TIME_1);
DEBUG_CASE(NV_PTIMER_ALARM_0); DEBUG_CASE(NV_PTIMER_ALARM_0);
DEBUG_END(PTIMER) DEBUG_END(PTIMER)
DEBUG_START(PCOUNTER) DEBUG_START(PCOUNTER)
@ -680,6 +716,7 @@ DEBUG_END(PRMVIO)
DEBUG_START(PFB) DEBUG_START(PFB)
DEBUG_CASE(NV_PFB_CFG0) DEBUG_CASE(NV_PFB_CFG0)
DEBUG_CASE(NV_PFB_CFG1)
DEBUG_CASE(NV_PFB_CSTATUS) DEBUG_CASE(NV_PFB_CSTATUS)
DEBUG_CASE(NV_PFB_REFCTRL) DEBUG_CASE(NV_PFB_REFCTRL)
DEBUG_CASE(NV_PFB_NVM) // NV_PFB_NVM_MODE_DISABLE DEBUG_CASE(NV_PFB_NVM) // NV_PFB_NVM_MODE_DISABLE
@ -688,17 +725,53 @@ DEBUG_START(PFB)
DEBUG_CASE(NV_PFB_TIMING0) DEBUG_CASE(NV_PFB_TIMING0)
DEBUG_CASE(NV_PFB_TIMING1) DEBUG_CASE(NV_PFB_TIMING1)
DEBUG_CASE(NV_PFB_TIMING2) DEBUG_CASE(NV_PFB_TIMING2)
DEBUG_CASE(NV_PFB_TILE) DEBUG_CASE(NV_PFB_TILE(0))
DEBUG_CASE(NV_PFB_TLIMIT) DEBUG_CASE(NV_PFB_TLIMIT(0))
DEBUG_CASE(NV_PFB_TSIZE) DEBUG_CASE(NV_PFB_TSIZE(0))
DEBUG_CASE(NV_PFB_TSTATUS) DEBUG_CASE(NV_PFB_TSTATUS(0))
DEBUG_CASE(NV_PFB_TILE(1))
DEBUG_CASE(NV_PFB_TLIMIT(1))
DEBUG_CASE(NV_PFB_TSIZE(1))
DEBUG_CASE(NV_PFB_TSTATUS(1))
DEBUG_CASE(NV_PFB_TILE(2))
DEBUG_CASE(NV_PFB_TLIMIT(2))
DEBUG_CASE(NV_PFB_TSIZE(2))
DEBUG_CASE(NV_PFB_TSTATUS(2))
DEBUG_CASE(NV_PFB_TILE(3))
DEBUG_CASE(NV_PFB_TLIMIT(3))
DEBUG_CASE(NV_PFB_TSIZE(3))
DEBUG_CASE(NV_PFB_TSTATUS(3))
DEBUG_CASE(NV_PFB_TILE(4))
DEBUG_CASE(NV_PFB_TLIMIT(4))
DEBUG_CASE(NV_PFB_TSIZE(4))
DEBUG_CASE(NV_PFB_TSTATUS(4))
DEBUG_CASE(NV_PFB_TILE(5))
DEBUG_CASE(NV_PFB_TLIMIT(5))
DEBUG_CASE(NV_PFB_TSIZE(5))
DEBUG_CASE(NV_PFB_TSTATUS(5))
DEBUG_CASE(NV_PFB_TILE(6))
DEBUG_CASE(NV_PFB_TLIMIT(6))
DEBUG_CASE(NV_PFB_TSIZE(6))
DEBUG_CASE(NV_PFB_TSTATUS(6))
DEBUG_CASE(NV_PFB_TILE(7))
DEBUG_CASE(NV_PFB_TLIMIT(7))
DEBUG_CASE(NV_PFB_TSIZE(7))
DEBUG_CASE(NV_PFB_TSTATUS(7))
DEBUG_CASE(NV_PFB_MRS) DEBUG_CASE(NV_PFB_MRS)
DEBUG_CASE(NV_PFB_EMRS) DEBUG_CASE(NV_PFB_EMRS)
DEBUG_CASE(NV_PFB_MRS_EXT) DEBUG_CASE(NV_PFB_MRS_EXT)
DEBUG_CASE(NV_PFB_EMRS_EXT) DEBUG_CASE(NV_PFB_EMRS_EXT)
DEBUG_CASE(NV_PFB_REF) DEBUG_CASE(NV_PFB_REF)
DEBUG_CASE(NV_PFB_PRE) DEBUG_CASE(NV_PFB_PRE)
DEBUG_CASE(NV_PFB_ZCOMP) DEBUG_CASE(NV_PFB_ZCOMP(0))
DEBUG_CASE(NV_PFB_ZCOMP(1))
DEBUG_CASE(NV_PFB_ZCOMP(2))
DEBUG_CASE(NV_PFB_ZCOMP(3))
DEBUG_CASE(NV_PFB_ZCOMP(4))
DEBUG_CASE(NV_PFB_ZCOMP(5))
DEBUG_CASE(NV_PFB_ZCOMP(6))
DEBUG_CASE(NV_PFB_ZCOMP(7))
DEBUG_CASE(NV_PFB_ZCOMP_OFFSET)
DEBUG_CASE(NV_PFB_ARB_PREDIVIDER) DEBUG_CASE(NV_PFB_ARB_PREDIVIDER)
DEBUG_CASE(NV_PFB_ARB_TIMEOUT) DEBUG_CASE(NV_PFB_ARB_TIMEOUT)
DEBUG_CASE(NV_PFB_ARB_XFER_REM) DEBUG_CASE(NV_PFB_ARB_XFER_REM)
@ -722,20 +795,81 @@ DEBUG_START(PSTRAPS)
DEBUG_END(PSTRAPS) DEBUG_END(PSTRAPS)
DEBUG_START(PGRAPH) DEBUG_START(PGRAPH)
DEBUG_CASE(NV_PGRAPH_DEBUG_0);
DEBUG_CASE(NV_PGRAPH_DEBUG_1);
DEBUG_CASE(NV_PGRAPH_DEBUG_3);
DEBUG_CASE(NV_PGRAPH_DEBUG_4);
DEBUG_CASE(NV_PGRAPH_DEBUG_5);
DEBUG_CASE(NV_PGRAPH_DEBUG_8);
DEBUG_CASE(NV_PGRAPH_DEBUG_9);
DEBUG_CASE(NV_PGRAPH_INTR); DEBUG_CASE(NV_PGRAPH_INTR);
DEBUG_CASE(NV_PGRAPH_NSOURCE); DEBUG_CASE(NV_PGRAPH_NSOURCE);
DEBUG_CASE(NV_PGRAPH_INTR_EN); DEBUG_CASE(NV_PGRAPH_INTR_EN);
DEBUG_CASE(NV_PGRAPH_CTX_CONTROL); DEBUG_CASE(NV_PGRAPH_CTX_CONTROL);
DEBUG_CASE(NV_PGRAPH_CTX_USER); DEBUG_CASE(NV_PGRAPH_CTX_USER);
DEBUG_CASE(NV_PGRAPH_CTX_SWITCH1); DEBUG_CASE(NV_PGRAPH_CTX_SWITCH1);
DEBUG_CASE(NV_PGRAPH_CTX_SWITCH2);
DEBUG_CASE(NV_PGRAPH_CTX_SWITCH3);
DEBUG_CASE(NV_PGRAPH_CTX_SWITCH4);
DEBUG_CASE(NV_PGRAPH_STATUS);
DEBUG_CASE(NV_PGRAPH_TRAPPED_ADDR); DEBUG_CASE(NV_PGRAPH_TRAPPED_ADDR);
DEBUG_CASE(NV_PGRAPH_TRAPPED_DATA_LOW); DEBUG_CASE(NV_PGRAPH_TRAPPED_DATA_LOW);
DEBUG_CASE(NV_PGRAPH_SURFACE); DEBUG_CASE(NV_PGRAPH_SURFACE);
DEBUG_CASE(NV_PGRAPH_INCREMENT); DEBUG_CASE(NV_PGRAPH_INCREMENT);
DEBUG_CASE(NV_PGRAPH_FIFO); DEBUG_CASE(NV_PGRAPH_FIFO);
DEBUG_CASE(NV_PGRAPH_RDI_INDEX);
DEBUG_CASE(NV_PGRAPH_RDI_DATA);
DEBUG_CASE(NV_PGRAPH_FFINTFC_ST2);
DEBUG_CASE(NV_PGRAPH_CHANNEL_CTX_TABLE); DEBUG_CASE(NV_PGRAPH_CHANNEL_CTX_TABLE);
DEBUG_CASE(NV_PGRAPH_CHANNEL_CTX_POINTER); DEBUG_CASE(NV_PGRAPH_CHANNEL_CTX_POINTER);
DEBUG_CASE(NV_PGRAPH_CHANNEL_CTX_TRIGGER); DEBUG_CASE(NV_PGRAPH_CHANNEL_CTX_TRIGGER);
DEBUG_CASE(NV_PGRAPH_DEBUG_2);
DEBUG_CASE(NV_PGRAPH_TTILE(0));
DEBUG_CASE(NV_PGRAPH_TLIMIT(0));
DEBUG_CASE(NV_PGRAPH_TSIZE(0));
DEBUG_CASE(NV_PGRAPH_TSTATUS(0));
DEBUG_CASE(NV_PGRAPH_TTILE(1));
DEBUG_CASE(NV_PGRAPH_TLIMIT(1));
DEBUG_CASE(NV_PGRAPH_TSIZE(1));
DEBUG_CASE(NV_PGRAPH_TSTATUS(1));
DEBUG_CASE(NV_PGRAPH_TTILE(2));
DEBUG_CASE(NV_PGRAPH_TLIMIT(2));
DEBUG_CASE(NV_PGRAPH_TSIZE(2));
DEBUG_CASE(NV_PGRAPH_TSTATUS(2));
DEBUG_CASE(NV_PGRAPH_TTILE(3));
DEBUG_CASE(NV_PGRAPH_TLIMIT(3));
DEBUG_CASE(NV_PGRAPH_TSIZE(3));
DEBUG_CASE(NV_PGRAPH_TSTATUS(3));
DEBUG_CASE(NV_PGRAPH_TTILE(4));
DEBUG_CASE(NV_PGRAPH_TLIMIT(4));
DEBUG_CASE(NV_PGRAPH_TSIZE(4));
DEBUG_CASE(NV_PGRAPH_TSTATUS(4));
DEBUG_CASE(NV_PGRAPH_TTILE(5));
DEBUG_CASE(NV_PGRAPH_TLIMIT(5));
DEBUG_CASE(NV_PGRAPH_TSIZE(5));
DEBUG_CASE(NV_PGRAPH_TSTATUS(5));
DEBUG_CASE(NV_PGRAPH_TTILE(6));
DEBUG_CASE(NV_PGRAPH_TLIMIT(6));
DEBUG_CASE(NV_PGRAPH_TSIZE(6));
DEBUG_CASE(NV_PGRAPH_TSTATUS(6));
DEBUG_CASE(NV_PGRAPH_TTILE(7));
DEBUG_CASE(NV_PGRAPH_TLIMIT(7));
DEBUG_CASE(NV_PGRAPH_TSIZE(7));
DEBUG_CASE(NV_PGRAPH_TSTATUS(7));
DEBUG_CASE(NV_PGRAPH_ZCOMP(0));
DEBUG_CASE(NV_PGRAPH_ZCOMP(1));
DEBUG_CASE(NV_PGRAPH_ZCOMP(2));
DEBUG_CASE(NV_PGRAPH_ZCOMP(3));
DEBUG_CASE(NV_PGRAPH_ZCOMP(4));
DEBUG_CASE(NV_PGRAPH_ZCOMP(5));
DEBUG_CASE(NV_PGRAPH_ZCOMP(6));
DEBUG_CASE(NV_PGRAPH_ZCOMP(7));
DEBUG_CASE(NV_PGRAPH_ZCOMP_OFFSET);
DEBUG_CASE(NV_PGRAPH_FBCFG0);
DEBUG_CASE(NV_PGRAPH_FBCFG1);
DEBUG_CASE(NV_PGRAPH_DEBUG_6);
DEBUG_CASE(NV_PGRAPH_DEBUG_7);
DEBUG_CASE(NV_PGRAPH_DEBUG_10);
DEBUG_CASE(NV_PGRAPH_CSV0_D); DEBUG_CASE(NV_PGRAPH_CSV0_D);
DEBUG_CASE(NV_PGRAPH_CSV0_C); DEBUG_CASE(NV_PGRAPH_CSV0_C);
DEBUG_CASE(NV_PGRAPH_CSV1_B); DEBUG_CASE(NV_PGRAPH_CSV1_B);
@ -774,8 +908,7 @@ DEBUG_START(PGRAPH)
DEBUG_CASE(NV_PGRAPH_SHADOWZSLOPETHRESHOLD); DEBUG_CASE(NV_PGRAPH_SHADOWZSLOPETHRESHOLD);
DEBUG_CASE(NV_PGRAPH_SPECFOGFACTOR0); DEBUG_CASE(NV_PGRAPH_SPECFOGFACTOR0);
DEBUG_CASE(NV_PGRAPH_SPECFOGFACTOR1); DEBUG_CASE(NV_PGRAPH_SPECFOGFACTOR1);
DEBUG_CASE(NV_PGRAPH_TEXADDRESS0); DEBUG_CASE_EX(NV_PGRAPH_TEXADDRESS0, ":_ADDRV");
DEBUG_CASE(NV_PGRAPH_TEXADDRESS0_ADDRV);
DEBUG_CASE(NV_PGRAPH_TEXADDRESS1); DEBUG_CASE(NV_PGRAPH_TEXADDRESS1);
DEBUG_CASE(NV_PGRAPH_TEXADDRESS2); DEBUG_CASE(NV_PGRAPH_TEXADDRESS2);
DEBUG_CASE(NV_PGRAPH_TEXADDRESS3); DEBUG_CASE(NV_PGRAPH_TEXADDRESS3);
@ -824,7 +957,6 @@ DEBUG_START(PCRTC)
DEBUG_CASE(NV_PCRTC_INTR_EN_0); DEBUG_CASE(NV_PCRTC_INTR_EN_0);
DEBUG_CASE(NV_PCRTC_START); DEBUG_CASE(NV_PCRTC_START);
DEBUG_CASE(NV_PCRTC_CONFIG); DEBUG_CASE(NV_PCRTC_CONFIG);
DEBUG_END(PCRTC) DEBUG_END(PCRTC)
DEBUG_START(PRMCIO) DEBUG_START(PRMCIO)
@ -864,12 +996,10 @@ DEBUG_START(PRAMIN)
DEBUG_END(PRAMIN) DEBUG_END(PRAMIN)
DEBUG_START(USER) DEBUG_START(USER)
DEBUG_CASE(NV_USER_DMA_PUT); DEBUG_CASE(NV_USER_DMA_PUT);
DEBUG_CASE(NV_USER_DMA_GET); DEBUG_CASE(NV_USER_DMA_GET);
DEBUG_CASE(NV_USER_REF); DEBUG_CASE(NV_USER_REF);
DEBUG_END(USER)
DEBUG_END(USER)
@ -894,6 +1024,11 @@ static inline uint32_t ldl_le_p(const void *p)
return *(uint32_t*)p; return *(uint32_t*)p;
} }
static inline void stl_le_p(uint32_t *p, uint32 v)
{
*p = v;
}
static DMAObject nv_dma_load(xbaddr dma_obj_address) static DMAObject nv_dma_load(xbaddr dma_obj_address)
{ {
assert(dma_obj_address < NV_PRAMIN_SIZE); assert(dma_obj_address < NV_PRAMIN_SIZE);
@ -919,7 +1054,7 @@ static void *nv_dma_map(xbaddr dma_obj_address, xbaddr *len)
DMAObject dma = nv_dma_load(dma_obj_address); DMAObject dma = nv_dma_load(dma_obj_address);
/* TODO: Handle targets and classes properly */ /* TODO: Handle targets and classes properly */
printf("dma_map %x, %x, %x %x" "\n", printf("dma_map %x, %x, %x %x\n",
dma.dma_class, dma.dma_target, dma.address, dma.limit); dma.dma_class, dma.dma_target, dma.address, dma.limit);
dma.address &= 0x07FFFFFF; dma.address &= 0x07FFFFFF;
@ -1073,7 +1208,7 @@ static void pfifo_run_pusher() {
static uint32_t ramht_hash(uint32_t handle) static uint32_t ramht_hash(uint32_t handle)
{ {
unsigned int ramht_size = 1 << (GET_MASK(pfifo.regs[NV_PFIFO_RAMHT], NV_PFIFO_RAMHT_SIZE) + 12); unsigned int ramht_size = 1 << (GET_MASK(pfifo.regs[NV_PFIFO_RAMHT], NV_PFIFO_RAMHT_SIZE_MASK) + 12);
/* XXX: Think this is different to what nouveau calculates... */ /* XXX: Think this is different to what nouveau calculates... */
unsigned int bits = ffs(ramht_size) - 2; unsigned int bits = ffs(ramht_size) - 2;
@ -1091,14 +1226,14 @@ static uint32_t ramht_hash(uint32_t handle)
static RAMHTEntry ramht_lookup(uint32_t handle) static RAMHTEntry ramht_lookup(uint32_t handle)
{ {
unsigned int ramht_size = 1 << (GET_MASK(pfifo.regs[NV_PFIFO_RAMHT], NV_PFIFO_RAMHT_SIZE) + 12); unsigned int ramht_size = 1 << (GET_MASK(pfifo.regs[NV_PFIFO_RAMHT], NV_PFIFO_RAMHT_SIZE_MASK) + 12);
uint32_t hash = ramht_hash(handle); uint32_t hash = ramht_hash(handle);
assert(hash * 8 < ramht_size); assert(hash * 8 < ramht_size);
uint32_t ramht_address = uint32_t ramht_address =
GET_MASK(pfifo.regs[NV_PFIFO_RAMHT], GET_MASK(pfifo.regs[NV_PFIFO_RAMHT],
NV_PFIFO_RAMHT_BASE_ADDRESS) << 12; NV_PFIFO_RAMHT_BASE_ADDRESS_MASK) << 12;
uint8_t *entry_ptr = (uint8_t*)(NV2A_ADDR + NV_PRAMIN_ADDR + ramht_address + hash * 8); uint8_t *entry_ptr = (uint8_t*)(NV2A_ADDR + NV_PRAMIN_ADDR + ramht_address + hash * 8);
@ -1244,6 +1379,12 @@ static bool pgraph_zeta_write_enabled()
| NV_PGRAPH_CONTROL_0_STENCIL_WRITE_ENABLE); | NV_PGRAPH_CONTROL_0_STENCIL_WRITE_ENABLE);
} }
static void pgraph_update_surface(bool upload,
bool color_write, bool zeta_write)
{
printf("TODO: pgraph_update_surface\n");
}
static unsigned int kelvin_map_stencil_op(uint32_t parameter) static unsigned int kelvin_map_stencil_op(uint32_t parameter)
{ {
unsigned int op; unsigned int op;
@ -1319,7 +1460,7 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t
{ {
std::lock_guard<std::mutex> lk(pgraph.mutex); std::lock_guard<std::mutex> lk(pgraph.mutex);
int i; // int i;
GraphicsSubchannel *subchannel_data; GraphicsSubchannel *subchannel_data;
GraphicsObject *object; GraphicsObject *object;
@ -1396,7 +1537,7 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t
/* I guess this kicks it off? */ /* I guess this kicks it off? */
if (image_blit->operation == NV09F_SET_OPERATION_SRCCOPY) { if (image_blit->operation == NV09F_SET_OPERATION_SRCCOPY) {
printf("NV09F_SET_OPERATION_SRCCOPY"); printf("NV09F_SET_OPERATION_SRCCOPY\n");
GraphicsObject *context_surfaces_obj = lookup_graphics_object(image_blit->context_surfaces); GraphicsObject *context_surfaces_obj = lookup_graphics_object(image_blit->context_surfaces);
assert(context_surfaces_obj); assert(context_surfaces_obj);
@ -1434,7 +1575,7 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t
printf(" - 0x%tx -> 0x%tx\n", source - MM_SYSTEM_PHYSICAL_MAP,dest - MM_SYSTEM_PHYSICAL_MAP); printf(" - 0x%tx -> 0x%tx\n", source - MM_SYSTEM_PHYSICAL_MAP,dest - MM_SYSTEM_PHYSICAL_MAP);
int y; unsigned int y;
for (y = 0; y<image_blit->height; y++) { for (y = 0; y<image_blit->height; y++) {
uint8_t *source_row = source uint8_t *source_row = source
+ (image_blit->in_y + y) * context_surfaces->source_pitch + (image_blit->in_y + y) * context_surfaces->source_pitch
@ -1474,9 +1615,8 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t
kelvin->dma_state = parameter; kelvin->dma_state = parameter;
break; break;
case NV097_SET_CONTEXT_DMA_COLOR: case NV097_SET_CONTEXT_DMA_COLOR:
printf("TODO: pgraph_update_surface\n");
/* try to get any straggling draws in before the surface's changed :/ */ /* try to get any straggling draws in before the surface's changed :/ */
//pgraph_update_surface(d, false, true, true); pgraph_update_surface(false, true, true);
pgraph.dma_color = parameter; pgraph.dma_color = parameter;
break; break;
@ -1496,8 +1636,7 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t
pgraph.dma_report = parameter; pgraph.dma_report = parameter;
break; break;
case NV097_SET_SURFACE_CLIP_HORIZONTAL: case NV097_SET_SURFACE_CLIP_HORIZONTAL:
printf("TODO: pgraph_update_surface\n"); pgraph_update_surface(false, true, true);
//pgraph_update_surface(d, false, true, true);
pgraph.surface_shape.clip_x = pgraph.surface_shape.clip_x =
GET_MASK(parameter, NV097_SET_SURFACE_CLIP_HORIZONTAL_X); GET_MASK(parameter, NV097_SET_SURFACE_CLIP_HORIZONTAL_X);
@ -1505,8 +1644,7 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t
GET_MASK(parameter, NV097_SET_SURFACE_CLIP_HORIZONTAL_WIDTH); GET_MASK(parameter, NV097_SET_SURFACE_CLIP_HORIZONTAL_WIDTH);
break; break;
case NV097_SET_SURFACE_CLIP_VERTICAL: case NV097_SET_SURFACE_CLIP_VERTICAL:
printf("TODO: pgraph_update_surface\n"); pgraph_update_surface(false, true, true);
//pgraph_update_surface(d, false, true, true);
pgraph.surface_shape.clip_y = pgraph.surface_shape.clip_y =
GET_MASK(parameter, NV097_SET_SURFACE_CLIP_VERTICAL_Y); GET_MASK(parameter, NV097_SET_SURFACE_CLIP_VERTICAL_Y);
@ -1514,8 +1652,7 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t
GET_MASK(parameter, NV097_SET_SURFACE_CLIP_VERTICAL_HEIGHT); GET_MASK(parameter, NV097_SET_SURFACE_CLIP_VERTICAL_HEIGHT);
break; break;
case NV097_SET_SURFACE_FORMAT: case NV097_SET_SURFACE_FORMAT:
printf("TODO: pgraph_update_surface\n"); pgraph_update_surface(false, true, true);
//pgraph_update_surface(d, false, true, true);
pgraph.surface_shape.color_format = pgraph.surface_shape.color_format =
GET_MASK(parameter, NV097_SET_SURFACE_FORMAT_COLOR); GET_MASK(parameter, NV097_SET_SURFACE_FORMAT_COLOR);
@ -1531,8 +1668,7 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t
GET_MASK(parameter, NV097_SET_SURFACE_FORMAT_HEIGHT); GET_MASK(parameter, NV097_SET_SURFACE_FORMAT_HEIGHT);
break; break;
case NV097_SET_SURFACE_PITCH: case NV097_SET_SURFACE_PITCH:
printf("TODO: pgraph_update_surface\n"); pgraph_update_surface(false, true, true);
//pgraph_update_surface(d, false, true, true);
pgraph.surface_color.pitch = pgraph.surface_color.pitch =
GET_MASK(parameter, NV097_SET_SURFACE_PITCH_COLOR); GET_MASK(parameter, NV097_SET_SURFACE_PITCH_COLOR);
@ -1540,14 +1676,12 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t
GET_MASK(parameter, NV097_SET_SURFACE_PITCH_ZETA); GET_MASK(parameter, NV097_SET_SURFACE_PITCH_ZETA);
break; break;
case NV097_SET_SURFACE_COLOR_OFFSET: case NV097_SET_SURFACE_COLOR_OFFSET:
printf("TODO: pgraph_update_surface\n"); pgraph_update_surface(false, true, true);
//pgraph_update_surface(d, false, true, true);
pgraph.surface_color.offset = parameter; pgraph.surface_color.offset = parameter;
break; break;
case NV097_SET_SURFACE_ZETA_OFFSET: case NV097_SET_SURFACE_ZETA_OFFSET:
printf("TODO: pgraph_update_surface\n"); pgraph_update_surface(false, true, true);
//pgraph_update_surface(d, false, true, true);
pgraph.surface_zeta.offset = parameter; pgraph.surface_zeta.offset = parameter;
break; break;
@ -1562,8 +1696,7 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t
pgraph.regs[NV_PGRAPH_TEXADDRESS0 + slot * 4] = parameter; pgraph.regs[NV_PGRAPH_TEXADDRESS0 + slot * 4] = parameter;
break; break;
case NV097_SET_CONTROL0: { case NV097_SET_CONTROL0: {
printf("TODO: pgraph_update_surface\n"); pgraph_update_surface(false, true, true);
//pgraph_update_surface(d, false, true, true);
bool stencil_write_enable = bool stencil_write_enable =
parameter & NV097_SET_CONTROL0_STENCIL_WRITE_ENABLE; parameter & NV097_SET_CONTROL0_STENCIL_WRITE_ENABLE;
@ -1989,6 +2122,29 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t
case NV097_SET_TEXGEN_VIEW_MODEL: case NV097_SET_TEXGEN_VIEW_MODEL:
SET_MASK(pgraph.regs[NV_PGRAPH_CSV0_D], NV_PGRAPH_CSV0_D_TEXGEN_REF, parameter); SET_MASK(pgraph.regs[NV_PGRAPH_CSV0_D], NV_PGRAPH_CSV0_D_TEXGEN_REF, parameter);
break; break;
case NV097_SET_SEMAPHORE_OFFSET:
kelvin->semaphore_offset = parameter;
break;
case NV097_BACK_END_WRITE_SEMAPHORE_RELEASE: {
pgraph_update_surface(false, true, true);
//qemu_mutex_unlock(&d->pgraph.lock);
//qemu_mutex_lock_iothread();
xbaddr semaphore_dma_len;
uint8_t *semaphore_data = (uint8_t*)nv_dma_map(kelvin->dma_semaphore,
&semaphore_dma_len);
assert(kelvin->semaphore_offset < semaphore_dma_len);
semaphore_data += kelvin->semaphore_offset;
stl_le_p((uint32_t*)semaphore_data, parameter);
//qemu_mutex_lock(&d->pgraph.lock);
//qemu_mutex_unlock_iothread();
break;
}
default: default:
if (method >= NV097_SET_COMBINER_ALPHA_ICW && method <= NV097_SET_COMBINER_ALPHA_ICW + 28) { if (method >= NV097_SET_COMBINER_ALPHA_ICW && method <= NV097_SET_COMBINER_ALPHA_ICW + 28) {
slot = (method - NV097_SET_COMBINER_ALPHA_ICW) / 4; slot = (method - NV097_SET_COMBINER_ALPHA_ICW) / 4;
@ -2141,6 +2297,8 @@ static void pgraph_method(unsigned int subchannel, unsigned int method, uint32_t
static void* pfifo_puller_thread() static void* pfifo_puller_thread()
{ {
CxbxSetThreadName("Cxbx NV2A FIFO");
Cache1State *state = &pfifo.cache1; Cache1State *state = &pfifo.cache1;
while (true) { while (true) {
@ -2234,10 +2392,13 @@ DEVICE_READ32(PMC)
case NV_PMC_BOOT_0: // chipset and stepping: NV2A, A02, Rev 0 case NV_PMC_BOOT_0: // chipset and stepping: NV2A, A02, Rev 0
result = 0x02A000A2; result = 0x02A000A2;
break; break;
case NV_PMC_INTR_0: case NV_PMC_BOOT_1: // Selects big/little endian mode for the card
result = 0; // When read, returns 0 if in little-endian mode, 0x01000001 if in big-endian mode.
break;
case NV_PMC_INTR_0: // Shows which functional units have pending IRQ
result = pmc.pending_interrupts; result = pmc.pending_interrupts;
break; break;
case NV_PMC_INTR_EN_0: case NV_PMC_INTR_EN_0: // Selects which functional units can cause IRQs
result = pmc.enabled_interrupts; result = pmc.enabled_interrupts;
break; break;
default: default:
@ -2360,7 +2521,7 @@ DEVICE_READ32(PFIFO)
pfifo.cache1.error); pfifo.cache1.error);
break; break;
case NV_PFIFO_CACHE1_DMA_INSTANCE: case NV_PFIFO_CACHE1_DMA_INSTANCE:
SET_MASK(result, NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS, SET_MASK(result, NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS_MASK,
pfifo.cache1.dma_instance >> 4); pfifo.cache1.dma_instance >> 4);
break; break;
case NV_PFIFO_CACHE1_DMA_PUT: case NV_PFIFO_CACHE1_DMA_PUT:
@ -2439,7 +2600,7 @@ DEVICE_WRITE32(PFIFO)
pfifo.cache1.error = GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_ERROR); pfifo.cache1.error = GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_ERROR);
break; break;
case NV_PFIFO_CACHE1_DMA_INSTANCE: case NV_PFIFO_CACHE1_DMA_INSTANCE:
pfifo.cache1.dma_instance = GET_MASK(value, NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS) << 4; pfifo.cache1.dma_instance = GET_MASK(value, NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS_MASK) << 4;
break; break;
case NV_PFIFO_CACHE1_DMA_PUT: case NV_PFIFO_CACHE1_DMA_PUT:
user.channel_control[pfifo.cache1.channel_id].dma_put = value; user.channel_control[pfifo.cache1.channel_id].dma_put = value;
@ -3258,7 +3419,7 @@ static const NV2ABlockInfo regions[] = {{
}, { }, {
/* MMIO and DMA FIFO submission to PGRAPH and VPE */ /* MMIO and DMA FIFO submission to PGRAPH and VPE */
NV_PFIFO_ADDR, // = 0x002000 NV_PFIFO_ADDR, // = 0x002000
NV_PFIFO_SIZE, // = 0x002000 _NV_PFIFO_SIZE, // = 0x002000
EmuNV2A_PFIFO_Read32, EmuNV2A_PFIFO_Read32,
EmuNV2A_PFIFO_Write32, EmuNV2A_PFIFO_Write32,
}, { }, {
@ -3306,7 +3467,7 @@ static const NV2ABlockInfo regions[] = {{
}, { }, {
/* aliases VGA sequencer and graphics controller registers */ /* aliases VGA sequencer and graphics controller registers */
NV_PRMVIO_ADDR, // = 0x0c0000 NV_PRMVIO_ADDR, // = 0x0c0000
NV_PRMVIO_SIZE, // = 0x001000 NV_PRMVIO_SIZE, // = 0x008000 // Was 0x001000
EmuNV2A_PRMVIO_Read32, EmuNV2A_PRMVIO_Read32,
EmuNV2A_PRMVIO_Write32, EmuNV2A_PRMVIO_Write32,
},{ },{
@ -3359,10 +3520,16 @@ static const NV2ABlockInfo regions[] = {{
EmuNV2A_PRAMIN_Write32, EmuNV2A_PRAMIN_Write32,
},{ },{
/* PFIFO MMIO and DMA submission area */ /* PFIFO MMIO and DMA submission area */
NV_USER_ADDR, // = 0x800000, NV_USER_ADDR, // = 0x800000
NV_USER_SIZE, // = 0x800000, NV_USER_SIZE, // = 0x400000 // Was 0x800000
EmuNV2A_USER_Read32, EmuNV2A_USER_Read32,
EmuNV2A_USER_Write32, EmuNV2A_USER_Write32,
}, {
/* User area remapped? */
NV_UREMAP_ADDR, // = 0xC00000
NV_UREMAP_SIZE, // = 0x400000
EmuNV2A_USER_Read32, // NOTE : Re-used (*not* EmuNV2A_UREMAP_Read32)
EmuNV2A_USER_Write32, // NOTE : Re-used (*not* EmuNV2A_UREMAP_Write32)
}, { }, {
0xFFFFFFFF, 0xFFFFFFFF,
0, 0,
@ -3435,7 +3602,7 @@ void EmuNV2A_Write(xbaddr addr, uint32_t value, int size)
shift = (addr & 2) * 16; shift = (addr & 2) * 16;
aligned_addr = addr & ~3; aligned_addr = addr & ~3;
aligned_value = block->read(addr - block->offset); aligned_value = block->read(addr - block->offset);
mask = 0xFFFF << shift; mask = 0xFFFF << shift;
// TODO : Must the second byte be written to the next DWORD? // TODO : Must the second byte be written to the next DWORD?
block->write(aligned_addr - block->offset, (aligned_value & ~mask) | (value << shift)); block->write(aligned_addr - block->offset, (aligned_value & ~mask) | (value << shift));
@ -3728,6 +3895,8 @@ std::thread vblank_thread;
extern std::chrono::time_point<std::chrono::steady_clock, std::chrono::duration<double, std::nano>> GetNextVBlankTime(); extern std::chrono::time_point<std::chrono::steady_clock, std::chrono::duration<double, std::nano>> GetNextVBlankTime();
static void nv2a_vblank_thread() static void nv2a_vblank_thread()
{ {
CxbxSetThreadName("Cxbx NV2A VBlank");
auto nextVBlankTime = GetNextVBlankTime(); auto nextVBlankTime = GetNextVBlankTime();
while (true) { while (true) {
@ -3740,10 +3909,42 @@ static void nv2a_vblank_thread()
} }
} }
void CxbxReserveNV2AMemory()
{
// Reserve NV2A memory :
void *memory = (void *)VirtualAllocEx(
GetCurrentProcess(),
(void *)NV2A_ADDR,
NV2A_SIZE,
MEM_RESERVE, // Don't allocate actual physical storage in memory
PAGE_NOACCESS); // Any access must result in an access violation exception (handled in EmuException/EmuX86_DecodeException)
if (memory == NULL) {
EmuWarning("Couldn't reserve NV2A memory, continuing assuming we'll receive (and handle) access violation exceptions anyway...");
return;
}
printf("[0x%.4X] INIT: Reserved %d MiB of Xbox NV2A memory at 0x%.8X to 0x%.8X\n",
GetCurrentThreadId(), NV2A_SIZE / ONE_MB, NV2A_ADDR, NV2A_ADDR + NV2A_SIZE - 1);
// Allocate PRAMIN Region
memory = VirtualAllocEx(
GetCurrentProcess(),
(void*)(NV2A_ADDR + NV_PRAMIN_ADDR),
NV_PRAMIN_SIZE,
MEM_COMMIT, // No MEM_RESERVE |
PAGE_READWRITE);
if (memory == NULL) {
EmuWarning("Couldn't allocate NV2A PRAMIN memory");
return;
}
printf("[0x%.4X] INIT: Allocated %d MiB of Xbox NV2A PRAMIN memory at 0x%.8X to 0x%.8X\n",
GetCurrentThreadId(), NV_PRAMIN_SIZE / ONE_MB, NV2A_ADDR + NV_PRAMIN_ADDR, NV2A_ADDR + NV_PRAMIN_ADDR + NV_PRAMIN_SIZE - 1);
}
void EmuNV2A_Init() void EmuNV2A_Init()
{ {
// Allocate PRAMIN Region CxbxReserveNV2AMemory();
VirtualAlloc((void*)(NV2A_ADDR + NV_PRAMIN_ADDR), NV_PRAMIN_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
pcrtc.start = 0; pcrtc.start = 0;
@ -3756,6 +3957,6 @@ void EmuNV2A_Init()
// Only spawn VBlank thread when LLE is enabled // Only spawn VBlank thread when LLE is enabled
if (bLLE_GPU) { if (bLLE_GPU) {
vblank_thread = std::thread(nv2a_vblank_thread);; vblank_thread = std::thread(nv2a_vblank_thread);
} }
} }

View File

@ -45,7 +45,7 @@
#define NV_PBUS_ADDR 0x00001000 #define NV_PBUS_ADDR 0x00001000
#define NV_PBUS_SIZE 0x001000 #define NV_PBUS_SIZE 0x001000
#define NV_PFIFO_ADDR 0x00002000 #define NV_PFIFO_ADDR 0x00002000
#define NV_PFIFO_SIZE 0x002000 #define _NV_PFIFO_SIZE 0x002000 // Underscore prefix to prevent clash with NV_PFIFO_SIZE
#define NV_PRMA_ADDR 0x00007000 #define NV_PRMA_ADDR 0x00007000
#define NV_PRMA_SIZE 0x001000 #define NV_PRMA_SIZE 0x001000
#define NV_PVIDEO_ADDR 0x00008000 #define NV_PVIDEO_ADDR 0x00008000
@ -61,7 +61,7 @@
#define NV_PRMFB_ADDR 0x000A0000 #define NV_PRMFB_ADDR 0x000A0000
#define NV_PRMFB_SIZE 0x020000 #define NV_PRMFB_SIZE 0x020000
#define NV_PRMVIO_ADDR 0x000C0000 #define NV_PRMVIO_ADDR 0x000C0000
#define NV_PRMVIO_SIZE 0x001000 #define NV_PRMVIO_SIZE 0x008000 // Was 0x001000
#define NV_PFB_ADDR 0x00100000 #define NV_PFB_ADDR 0x00100000
#define NV_PFB_SIZE 0x001000 #define NV_PFB_SIZE 0x001000
#define NV_PSTRAPS_ADDR 0x00101000 #define NV_PSTRAPS_ADDR 0x00101000
@ -79,18 +79,65 @@
#define NV_PRAMIN_ADDR 0x00700000 #define NV_PRAMIN_ADDR 0x00700000
#define NV_PRAMIN_SIZE 0x100000 #define NV_PRAMIN_SIZE 0x100000
#define NV_USER_ADDR 0x00800000 #define NV_USER_ADDR 0x00800000
#define NV_USER_SIZE 0x800000 #define NV_USER_SIZE 0x400000
#define NV_UREMAP_ADDR 0x00C00000 // Looks like a mapping of NV_USER_ADDR
#define NV_UREMAP_SIZE 0x400000
typedef volatile DWORD *PPUSH;
typedef struct { typedef struct {
DWORD Ignored[0x10]; DWORD Ignored[0x10];
DWORD* Put; // On Xbox1, this field is only written to by the CPU (the GPU uses this as a trigger to start executing from the given address) PPUSH Put; // On Xbox1, this field is only written to by the CPU (the GPU uses this as a trigger to start executing from the given address)
DWORD* Get; // On Xbox1, this field is only read from by the CPU (the GPU reflects in here where it is/stopped executing) PPUSH Get; // On Xbox1, this field is only read from by the CPU (the GPU reflects in here where it is/stopped executing)
DWORD Reference; // TODO : xbaddr / void* / DWORD ? PPUSH Reference; // TODO : xbaddr / void* / DWORD ?
DWORD Ignored2[0x7ED]; DWORD Ignored2[0x7ED];
} Nv2AControlDma; } Nv2AControlDma;
uint32_t EmuNV2A_Read(xbaddr addr, int size); uint32_t EmuNV2A_Read(xbaddr addr, int size);
void EmuNV2A_Write(xbaddr addr, uint32_t value, int size); void EmuNV2A_Write(xbaddr addr, uint32_t value, int size);
#define PUSH_TYPE_MASK 0x00000002 // 2 bits
#define PUSH_TYPE_SHIFT 0
#define PUSH_TYPE_METHOD 0 // method
#define PUSH_TYPE_JMP_FAR 1 // jump far
#define PUSH_TYPE_CALL_FAR 2 // call far
#define PUSH_TYPE_METHOD_UNUSED 3 // method (unused)
#define PUSH_METHOD_MASK 0x00001FFC // 12 bits
#define PUSH_METHOD_SHIFT 0 // Dxbx note : Not 2, because methods are actually DWORD offsets (and thus defined with increments of 4)
#define PUSH_SUBCH_MASK 0x0000E000 // 3 bits
#define PUSH_SUBCH_SHIFT 13
#define PUSH_COUNT_MASK 0x1FFC0000 // 11 bits
#define PUSH_COUNT_SHIFT 18
#define PUSH_INSTR_MASK 0xE0000000 // 3 bits
#define PUSH_INSTR_SHIFT 29
#define PUSH_INSTR_IMM_INCR 0 // immediate, increment
#define PUSH_INSTR_JMP_NEAR 1 // near jump
#define PUSH_INSTR_IMM_NOINC 2 // immediate, no-increment
#define PUSH_ADDR_FAR_MASK 0xFFFFFFFC // 30 bits
#define PUSH_ADDR_FAR_SHIFT 0
#define PUSH_ADDR_NEAR_MASK 0x1FFFFFFC // 27 bits
#define PUSH_ADDR_NEAR_SHIFT 0 // Cxbx note : Not 2, because methods are actually DWORD offsets (and thus defined with increments of 4)
#define PUSH_TYPE(dwPushCommand) ((dwPushCommand & PUSH_TYPE_MASK) >> PUSH_TYPE_SHIFT)
#define PUSH_METHOD(dwPushCommand) ((dwPushCommand & PUSH_METHOD_MASK) >> PUSH_METHOD_SHIFT)
#define PUSH_SUBCH(dwPushCommand) ((dwPushCommand & PUSH_SUBCH_MASK) >> PUSH_SUBCH_SHIFT)
#define PUSH_COUNT(dwPushCommand) ((dwPushCommand & PUSH_COUNT_MASK) >> PUSH_COUNT_SHIFT)
#define PUSH_INSTR(dwPushCommand) ((dwPushCommand & PUSH_INSTR_MASK) >> PUSH_INSTR_SHIFT)
#define PUSH_ADDR_FAR(dwPushCommand) ((dwPushCommand & PUSH_ADDR_FAR_MASK) >> PUSH_ADDR_FAR_SHIFT)
#define PUSH_ADDR_NEAR(dwPushCommand) ((dwPushCommand & PUSH_ADDR_NEAR_MASK) >> PUSH_ADDR_NEAR_SHIFT)
#define PUSH_METHOD_MAX ((PUSH_METHOD_MASK | 3) >> PUSH_METHOD_SHIFT) // = 8191
#define PUSH_SUBCH_MAX (PUSH_SUBCH_MASK >> PUSH_SUBCH_SHIFT) // = 7
#define PUSH_COUNT_MAX (PUSH_COUNT_MASK >> PUSH_COUNT_SHIFT) // = 2047
// Decode push buffer conmmand (inverse of D3DPUSH_ENCODE)
inline void D3DPUSH_DECODE(const DWORD dwPushCommand, DWORD &dwMethod, DWORD &dwSubCh, DWORD &dwCount)
{
dwMethod = PUSH_METHOD(dwPushCommand);
dwSubCh = PUSH_SUBCH(dwPushCommand);
dwCount = PUSH_COUNT(dwPushCommand);
}
void EmuNV2A_Init(); void EmuNV2A_Init();
void InitOpenGLContext(); void InitOpenGLContext();

130
src/devices/video/nv2a.cpp Normal file
View File

@ -0,0 +1,130 @@
// 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 <luke.usher@outlook.com>
// * (c) 2018 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#define _XBOXKRNL_DEFEXTRN_
#define LOG_PREFIX "NV2A"
#include "CxbxKrnl\CxbxKrnl.h" // For XBOX_MEMORY_SIZE, DWORD, etc
#include "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
/* LukeUsher commented at https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/pull/882#discussion_r162871029
This is not right: I should have done a better review ;)
The starting address here is the physical address in the Xbox memory the VRAM should be placed at,
and should point to the TILED memory region ((0xF0000000 >> 4))
This maps VRAM address 0 to 0xF0000000. (this is what our TILED memory is: VRAM accessed via the GPU device)
*/
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
}

52
src/devices/video/nv2a.h Normal file
View File

@ -0,0 +1,52 @@
// ******************************************************************
// *
// * .,-::::: .,:: .::::::::. .,:: .:
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
// * $$$ 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 <luke.usher@outlook.com>
// * (c) 2018 Patrick van Logchem <pvanlogchem@gmail.com>
// *
// * All rights reserved
// *
// ******************************************************************
#pragma once
#include "devices\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);
};

View File

@ -1,3 +1,4 @@
// Source : https://github.com/espes/xqemu/blob/xbox/hw/xbox/nv2a_int.h
/* /*
* QEMU Geforce NV2A internal definitions * QEMU Geforce NV2A internal definitions
* *
@ -18,12 +19,38 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>. * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/ */
#define NV_NUM_BLOCKS 21
#define NV_PMC 0 /* card master control */
#define NV_PBUS 1 /* bus control */
#define NV_PFIFO 2 /* MMIO and DMA FIFO submission to PGRAPH and VPE */
#define NV_PFIFO_CACHE 3
#define NV_PRMA 4 /* access to BAR0/BAR1 from real mode */
#define NV_PVIDEO 5 /* video overlay */
#define NV_PTIMER 6 /* time measurement and time-based alarms */
#define NV_PCOUNTER 7 /* performance monitoring counters */
#define NV_PVPE 8 /* MPEG2 decoding engine */
#define NV_PTV 9 /* TV encoder */
#define NV_PRMFB 10 /* aliases VGA memory window */
#define NV_PRMVIO 11 /* aliases VGA sequencer and graphics controller registers */
#define NV_PFB 12 /* memory interface */
#define NV_PSTRAPS 13 /* straps readout / override */
#define NV_PGRAPH 14 /* accelerated 2d/3d drawing engine */
#define NV_PCRTC 15 /* more CRTC controls */
#define NV_PRMCIO 16 /* aliases VGA CRTC and attribute controller registers */
#define NV_PRAMDAC 17 /* RAMDAC, cursor, and PLL control */
#define NV_PRMDIO 18 /* aliases VGA palette registers */
#define NV_PRAMIN 19 /* RAMIN access */
#define NV_USER 20 /* PFIFO MMIO and DMA submission area */
#define NV_PMC_BOOT_0 0x00000000 #define NV_PMC_BOOT_0 0x00000000
#define NV_PMC_BOOT_1 0x00000004
#define NV_PMC_INTR_0 0x00000100 #define NV_PMC_INTR_0 0x00000100
# define NV_PMC_INTR_0_PFIFO (1 << 8) # define NV_PMC_INTR_0_PFIFO (1 << 8)
# define NV_PMC_INTR_0_PGRAPH (1 << 12) # define NV_PMC_INTR_0_PGRAPH (1 << 12)
# define NV_PMC_INTR_0_PVIDEO (1 << 16)
# define NV_PMC_INTR_0_PTIMER (1 << 20)
# define NV_PMC_INTR_0_PCRTC (1 << 24) # define NV_PMC_INTR_0_PCRTC (1 << 24)
# define NV_PMC_INTR_0_PCRTC2 (1 << 25)
# define NV_PMC_INTR_0_PBUS (1 << 28) # define NV_PMC_INTR_0_PBUS (1 << 28)
# define NV_PMC_INTR_0_SOFTWARE (1 << 31) # define NV_PMC_INTR_0_SOFTWARE (1 << 31)
#define NV_PMC_INTR_EN_0 0x00000140 #define NV_PMC_INTR_EN_0 0x00000140
@ -32,8 +59,16 @@
#define NV_PMC_ENABLE 0x00000200 #define NV_PMC_ENABLE 0x00000200
# define NV_PMC_ENABLE_PFIFO (1 << 8) # define NV_PMC_ENABLE_PFIFO (1 << 8)
# define NV_PMC_ENABLE_PGRAPH (1 << 12) # define NV_PMC_ENABLE_PGRAPH (1 << 12)
# define NV_PMC_ENABLE_PFB (1 << 20)
# define NV_PMC_ENABLE_PCRTC (1 << 24)
# define NV_PMC_ENABLE_PCRTC2 (1 << 25)
# define NV_PMC_ENABLE_PVIDEO (1 << 28)
#define NV_PBUS_FBIO_RAM 0x00000218
# define NV_PBUS_FBIO_RAM_TYPE 0x00000100
# define NV_PBUS_FBIO_RAM_TYPE_DDR (0 << 8)
# define NV_PBUS_FBIO_RAM_TYPE_SDR (1 << 8)
/* These map approximately to the pci registers */ /* These map approximately to the pci registers */
#define NV_PBUS_PCI_NV_0 0x00000800 #define NV_PBUS_PCI_NV_0 0x00000800
# define NV_PBUS_PCI_NV_0_VENDOR_ID 0x0000FFFF # define NV_PBUS_PCI_NV_0_VENDOR_ID 0x0000FFFF
@ -65,6 +100,9 @@
#define NV_PBUS_PCI_NV_26 0x00000868 #define NV_PBUS_PCI_NV_26 0x00000868
#define NV_PFIFO_DELAY_0 0x00000040
#define NV_PFIFO_DMA_TIMESLICE 0x00000044
#define NV_PFIFO_TIMESLICE 0x0000004C
#define NV_PFIFO_INTR_0 0x00000100 #define NV_PFIFO_INTR_0 0x00000100
# define NV_PFIFO_INTR_0_CACHE_ERROR (1 << 0) # define NV_PFIFO_INTR_0_CACHE_ERROR (1 << 0)
# define NV_PFIFO_INTR_0_RUNOUT (1 << 4) # define NV_PFIFO_INTR_0_RUNOUT (1 << 4)
@ -82,21 +120,37 @@
# define NV_PFIFO_INTR_EN_0_SEMAPHORE (1 << 20) # define NV_PFIFO_INTR_EN_0_SEMAPHORE (1 << 20)
# define NV_PFIFO_INTR_EN_0_ACQUIRE_TIMEOUT (1 << 24) # define NV_PFIFO_INTR_EN_0_ACQUIRE_TIMEOUT (1 << 24)
#define NV_PFIFO_RAMHT 0x00000210 #define NV_PFIFO_RAMHT 0x00000210
# define NV_PFIFO_RAMHT_BASE_ADDRESS 0x000001F0 //# define NV_PFIFO_RAMHT_BASE_ADDRESS 0x000001F0
# define NV_PFIFO_RAMHT_SIZE 0x00030000 # define NV_PFIFO_RAMHT_BASE_ADDRESS_MASK 0x000001F0
# define NV_PFIFO_RAMHT_BASE_ADDRESS_SHIFT 4
# define NV_PFIFO_RAMHT_BASE_ADDRESS_MOVE 12
//# define NV_PFIFO_RAMHT_SIZE 0x00030000
# define NV_PFIFO_RAMHT_SIZE_MASK 0x00030000
# define NV_PFIFO_RAMHT_SIZE_SHIFT 16
# define NV_PFIFO_RAMHT_SIZE_4K 0 # define NV_PFIFO_RAMHT_SIZE_4K 0
# define NV_PFIFO_RAMHT_SIZE_8K 1 # define NV_PFIFO_RAMHT_SIZE_8K 1
# define NV_PFIFO_RAMHT_SIZE_16K 2 # define NV_PFIFO_RAMHT_SIZE_16K 2
# define NV_PFIFO_RAMHT_SIZE_32K 3 # define NV_PFIFO_RAMHT_SIZE_32K 3
# define NV_PFIFO_RAMHT_SEARCH 0x03000000 //# define NV_PFIFO_RAMHT_SEARCH 0x03000000
# define NV_PFIFO_RAMHT_SEARCH_MASK 0x03000000
# define NV_PFIFO_RAMHT_SEARCH_SHIFT 24
# define NV_PFIFO_RAMHT_SEARCH_16 0 # define NV_PFIFO_RAMHT_SEARCH_16 0
# define NV_PFIFO_RAMHT_SEARCH_32 1 # define NV_PFIFO_RAMHT_SEARCH_32 1
# define NV_PFIFO_RAMHT_SEARCH_64 2 # define NV_PFIFO_RAMHT_SEARCH_64 2
# define NV_PFIFO_RAMHT_SEARCH_128 3 # define NV_PFIFO_RAMHT_SEARCH_128 3
#define NV_PFIFO_RAMFC 0x00000214 #define NV_PFIFO_RAMFC 0x00000214
# define NV_PFIFO_RAMFC_BASE_ADDRESS1 0x000001FC //# define NV_PFIFO_RAMFC_BASE_ADDRESS1 0x000001FC
# define NV_PFIFO_RAMFC_SIZE 0x00010000 # define NV_PFIFO_RAMFC_BASE_ADDRESS1_MASK 0x000001FC
# define NV_PFIFO_RAMFC_BASE_ADDRESS2 0x00FE0000 # define NV_PFIFO_RAMFC_BASE_ADDRESS1_SHIFT 2
# define NV_PFIFO_RAMFC_BASE_ADDRESS1_MOVE 10
//# define NV_PFIFO_RAMFC_SIZE 0x00010000
# define NV_PFIFO_RAMFC_SIZE_MASK 0x00010000
# define NV_PFIFO_RAMFC_SIZE_1K 0x00000000
# define NV_PFIFO_RAMFC_SIZE_2K 0x00010000
//# define NV_PFIFO_RAMFC_BASE_ADDRESS2 0x00FE0000
# define NV_PFIFO_RAMFC_BASE_ADDRESS2_MASK 0x00FE0000
# define NV_PFIFO_RAMFC_BASE_ADDRESS2_SHIFT 17
# define NV_PFIFO_RAMFC_BASE_ADDRESS2_MOVE 10
#define NV_PFIFO_RAMRO 0x00000218 #define NV_PFIFO_RAMRO 0x00000218
# define NV_PFIFO_RAMRO_BASE_ADDRESS 0x000001FE # define NV_PFIFO_RAMRO_BASE_ADDRESS 0x000001FE
# define NV_PFIFO_RAMRO_SIZE 0x00010000 # define NV_PFIFO_RAMRO_SIZE 0x00010000
@ -104,13 +158,21 @@
# define NV_PFIFO_RUNOUT_STATUS_RANOUT (1 << 0) # define NV_PFIFO_RUNOUT_STATUS_RANOUT (1 << 0)
# define NV_PFIFO_RUNOUT_STATUS_LOW_MARK (1 << 4) # define NV_PFIFO_RUNOUT_STATUS_LOW_MARK (1 << 4)
# define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK (1 << 8) # define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK (1 << 8)
#define NV_PFIFO_RUNOUT_PUT_ADDRESS 0x00000410
#define NV_PFIFO_RUNOUT_GET_ADDRESS 0x00000420
#define NV_PFIFO_CACHES 0x00000500
#define NV_PFIFO_MODE 0x00000504 #define NV_PFIFO_MODE 0x00000504
#define NV_PFIFO_DMA 0x00000508 #define NV_PFIFO_DMA 0x00000508
#define NV_PFIFO_SIZE 0x0000050C
#define NV_PFIFO_CACHE0_PUSH0 0x00001000
#define NV_PFIFO_CACHE0_PULL0 0x00001050
#define NV_PFIFO_CACHE0_HASH 0x00001058
#define NV_PFIFO_CACHE1_PUSH0 0x00001200 #define NV_PFIFO_CACHE1_PUSH0 0x00001200
# define NV_PFIFO_CACHE1_PUSH0_ACCESS (1 << 0) # define NV_PFIFO_CACHE1_PUSH0_ACCESS (1 << 0)
#define NV_PFIFO_CACHE1_PUSH1 0x00001204 #define NV_PFIFO_CACHE1_PUSH1 0x00001204
# define NV_PFIFO_CACHE1_PUSH1_CHID 0x0000001F # define NV_PFIFO_CACHE1_PUSH1_CHID 0x0000001F
# define NV_PFIFO_CACHE1_PUSH1_MODE 0x00000100 # define NV_PFIFO_CACHE1_PUSH1_MODE 0x00000100
#define NV_PFIFO_CACHE1_PUT 0x00001210
#define NV_PFIFO_CACHE1_STATUS 0x00001214 #define NV_PFIFO_CACHE1_STATUS 0x00001214
# define NV_PFIFO_CACHE1_STATUS_LOW_MARK (1 << 4) # define NV_PFIFO_CACHE1_STATUS_LOW_MARK (1 << 4)
# define NV_PFIFO_CACHE1_STATUS_HIGH_MARK (1 << 8) # define NV_PFIFO_CACHE1_STATUS_HIGH_MARK (1 << 8)
@ -137,14 +199,26 @@
# define NV_PFIFO_CACHE1_DMA_STATE_ERROR_RESERVED_CMD 4 # define NV_PFIFO_CACHE1_DMA_STATE_ERROR_RESERVED_CMD 4
# define NV_PFIFO_CACHE1_DMA_STATE_ERROR_PROTECTION 6 # define NV_PFIFO_CACHE1_DMA_STATE_ERROR_PROTECTION 6
#define NV_PFIFO_CACHE1_DMA_INSTANCE 0x0000122C #define NV_PFIFO_CACHE1_DMA_INSTANCE 0x0000122C
# define NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS 0x0000FFFF //# define NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS 0x0000FFFF
# define NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS_MASK 0x0000FFFF
# define NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS_SHIFT 0
# define NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS_MOVE 4
#define NV_PFIFO_CACHE1_DMA_CTL 0x00001230
#define NV_PFIFO_CACHE1_DMA_PUT 0x00001240 #define NV_PFIFO_CACHE1_DMA_PUT 0x00001240
#define NV_PFIFO_CACHE1_DMA_GET 0x00001244 #define NV_PFIFO_CACHE1_DMA_GET 0x00001244
#define NV_PFIFO_CACHE1_REF 0x00001248
#define NV_PFIFO_CACHE1_DMA_SUBROUTINE 0x0000124C #define NV_PFIFO_CACHE1_DMA_SUBROUTINE 0x0000124C
# define NV_PFIFO_CACHE1_DMA_SUBROUTINE_RETURN_OFFSET 0x1FFFFFFC # define NV_PFIFO_CACHE1_DMA_SUBROUTINE_RETURN_OFFSET 0x1FFFFFFC
# define NV_PFIFO_CACHE1_DMA_SUBROUTINE_STATE (1 << 0) # define NV_PFIFO_CACHE1_DMA_SUBROUTINE_STATE (1 << 0)
#define NV_PFIFO_CACHE1_PULL0 0x00001250 #define NV_PFIFO_CACHE1_PULL0 0x00001250
# define NV_PFIFO_CACHE1_PULL0_ACCESS (1 << 0) # define NV_PFIFO_CACHE1_PULL0_ACCESS (1 << 0)
#define NV_PFIFO_CACHE1_PULL1 0x00001254
#define NV_PFIFO_CACHE1_HASH 0x00001258
#define NV_PFIFO_CACHE1_ACQUIRE_0 0x00001260
#define NV_PFIFO_CACHE1_ACQUIRE_1 0x00001264
#define NV_PFIFO_CACHE1_ACQUIRE_2 0x00001268
#define NV_PFIFO_CACHE1_SEMAPHORE 0x0000126C
#define NV_PFIFO_CACHE1_GET 0x00001270
#define NV_PFIFO_CACHE1_ENGINE 0x00001280 #define NV_PFIFO_CACHE1_ENGINE 0x00001280
#define NV_PFIFO_CACHE1_DMA_DCOUNT 0x000012A0 #define NV_PFIFO_CACHE1_DMA_DCOUNT 0x000012A0
# define NV_PFIFO_CACHE1_DMA_DCOUNT_VALUE 0x00001FFC # define NV_PFIFO_CACHE1_DMA_DCOUNT_VALUE 0x00001FFC
@ -154,6 +228,13 @@
#define NV_PFIFO_CACHE1_DMA_DATA_SHADOW 0x000012AC #define NV_PFIFO_CACHE1_DMA_DATA_SHADOW 0x000012AC
#define NV_PGRAPH_DEBUG_0 0x00000080
#define NV_PGRAPH_DEBUG_1 0x00000084
#define NV_PGRAPH_DEBUG_3 0x0000008C
#define NV_PGRAPH_DEBUG_4 0x00000090
#define NV_PGRAPH_DEBUG_5 0x00000094
#define NV_PGRAPH_DEBUG_8 0x00000098
#define NV_PGRAPH_DEBUG_9 0x0000009C
#define NV_PGRAPH_INTR 0x00000100 #define NV_PGRAPH_INTR 0x00000100
# define NV_PGRAPH_INTR_NOTIFY (1 << 0) # define NV_PGRAPH_INTR_NOTIFY (1 << 0)
# define NV_PGRAPH_INTR_MISSING_HW (1 << 4) # define NV_PGRAPH_INTR_MISSING_HW (1 << 4)
@ -212,6 +293,10 @@
# define NV_PGRAPH_CTX_SWITCH1_CONTEXT_BETA1 (1 << 29) # define NV_PGRAPH_CTX_SWITCH1_CONTEXT_BETA1 (1 << 29)
# define NV_PGRAPH_CTX_SWITCH1_CONTEXT_BETA4 (1 << 30) # define NV_PGRAPH_CTX_SWITCH1_CONTEXT_BETA4 (1 << 30)
# define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET (1 << 31) # define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET (1 << 31)
#define NV_PGRAPH_CTX_SWITCH2 0x00000150
#define NV_PGRAPH_CTX_SWITCH3 0x00000154
#define NV_PGRAPH_CTX_SWITCH4 0x00000158
#define NV_PGRAPH_STATUS 0x00000700
#define NV_PGRAPH_TRAPPED_ADDR 0x00000704 #define NV_PGRAPH_TRAPPED_ADDR 0x00000704
# define NV_PGRAPH_TRAPPED_ADDR_MTHD 0x00001FFF # define NV_PGRAPH_TRAPPED_ADDR_MTHD 0x00001FFF
# define NV_PGRAPH_TRAPPED_ADDR_SUBCH 0x00070000 # define NV_PGRAPH_TRAPPED_ADDR_SUBCH 0x00070000
@ -227,6 +312,9 @@
# define NV_PGRAPH_INCREMENT_READ_3D (1 << 1) # define NV_PGRAPH_INCREMENT_READ_3D (1 << 1)
#define NV_PGRAPH_FIFO 0x00000720 #define NV_PGRAPH_FIFO 0x00000720
# define NV_PGRAPH_FIFO_ACCESS (1 << 0) # define NV_PGRAPH_FIFO_ACCESS (1 << 0)
#define NV_PGRAPH_RDI_INDEX 0x00000750
#define NV_PGRAPH_RDI_DATA 0x00000754
#define NV_PGRAPH_FFINTFC_ST2 0x00000764
#define NV_PGRAPH_CHANNEL_CTX_TABLE 0x00000780 #define NV_PGRAPH_CHANNEL_CTX_TABLE 0x00000780
# define NV_PGRAPH_CHANNEL_CTX_TABLE_INST 0x0000FFFF # define NV_PGRAPH_CHANNEL_CTX_TABLE_INST 0x0000FFFF
#define NV_PGRAPH_CHANNEL_CTX_POINTER 0x00000784 #define NV_PGRAPH_CHANNEL_CTX_POINTER 0x00000784
@ -234,6 +322,18 @@
#define NV_PGRAPH_CHANNEL_CTX_TRIGGER 0x00000788 #define NV_PGRAPH_CHANNEL_CTX_TRIGGER 0x00000788
# define NV_PGRAPH_CHANNEL_CTX_TRIGGER_READ_IN (1 << 0) # define NV_PGRAPH_CHANNEL_CTX_TRIGGER_READ_IN (1 << 0)
# define NV_PGRAPH_CHANNEL_CTX_TRIGGER_WRITE_OUT (1 << 1) # define NV_PGRAPH_CHANNEL_CTX_TRIGGER_WRITE_OUT (1 << 1)
#define NV_PGRAPH_DEBUG_2 0x00000880
#define NV_PGRAPH_TTILE(i) 0x00000900 + (i * 0x10)
#define NV_PGRAPH_TLIMIT(i) 0x00000904 + (i * 0x10)
#define NV_PGRAPH_TSIZE(i) 0x00000908 + (i * 0x10)
#define NV_PGRAPH_TSTATUS(i) 0x0000090C + (i * 0x10)
#define NV_PGRAPH_ZCOMP(i) 0x00000980 + (i * 4)
#define NV_PGRAPH_ZCOMP_OFFSET 0x000009A0
#define NV_PGRAPH_FBCFG0 0x000009A4
#define NV_PGRAPH_FBCFG1 0x000009A8
#define NV_PGRAPH_DEBUG_6 0x00000B80
#define NV_PGRAPH_DEBUG_7 0x00000B84
#define NV_PGRAPH_DEBUG_10 0x00000B88
#define NV_PGRAPH_CSV0_D 0x00000FB4 #define NV_PGRAPH_CSV0_D 0x00000FB4
# define NV_PGRAPH_CSV0_D_LIGHTS 0x0000FFFF # define NV_PGRAPH_CSV0_D_LIGHTS 0x0000FFFF
# define NV_PGRAPH_CSV0_D_LIGHT0 0x00000003 # define NV_PGRAPH_CSV0_D_LIGHT0 0x00000003
@ -544,6 +644,8 @@
#define NV_PCRTC_CONFIG 0x00000804 #define NV_PCRTC_CONFIG 0x00000804
#define NV_PVIDEO_DEBUG_2 0x00000088
#define NV_PVIDEO_DEBUG_3 0x0000008C
#define NV_PVIDEO_INTR 0x00000100 #define NV_PVIDEO_INTR 0x00000100
# define NV_PVIDEO_INTR_BUFFER_0 (1 << 0) # define NV_PVIDEO_INTR_BUFFER_0 (1 << 0)
# define NV_PVIDEO_INTR_BUFFER_1 (1 << 4) # define NV_PVIDEO_INTR_BUFFER_1 (1 << 4)
@ -554,26 +656,26 @@
# define NV_PVIDEO_BUFFER_0_USE (1 << 0) # define NV_PVIDEO_BUFFER_0_USE (1 << 0)
# define NV_PVIDEO_BUFFER_1_USE (1 << 4) # define NV_PVIDEO_BUFFER_1_USE (1 << 4)
#define NV_PVIDEO_STOP 0x00000704 #define NV_PVIDEO_STOP 0x00000704
#define NV_PVIDEO_BASE 0x00000900 #define NV_PVIDEO_BASE(i) 0x00000900 + (i * 4)
#define NV_PVIDEO_LIMIT 0x00000908 #define NV_PVIDEO_LIMIT(i) 0x00000908 + (i * 4)
#define NV_PVIDEO_LUMINANCE 0x00000910 #define NV_PVIDEO_LUMINANCE(i) 0x00000910 + (i * 4)
#define NV_PVIDEO_CHROMINANCE 0x00000918 #define NV_PVIDEO_CHROMINANCE(i) 0x00000918 + (i * 4)
#define NV_PVIDEO_OFFSET 0x00000920 #define NV_PVIDEO_OFFSET(i) 0x00000920 + (i * 4)
#define NV_PVIDEO_SIZE_IN 0x00000928 #define NV_PVIDEO_SIZE_IN(i) 0x00000928 + (i * 4)
# define NV_PVIDEO_SIZE_IN_WIDTH 0x000007FF # define NV_PVIDEO_SIZE_IN_WIDTH 0x000007FF
# define NV_PVIDEO_SIZE_IN_HEIGHT 0x07FF0000 # define NV_PVIDEO_SIZE_IN_HEIGHT 0x07FF0000
#define NV_PVIDEO_POINT_IN 0x00000930 #define NV_PVIDEO_POINT_IN(i) 0x00000930 + (i * 4)
# define NV_PVIDEO_POINT_IN_S 0x00007FFF # define NV_PVIDEO_POINT_IN_S 0x00007FFF
# define NV_PVIDEO_POINT_IN_T 0xFFFE0000 # define NV_PVIDEO_POINT_IN_T 0xFFFE0000
#define NV_PVIDEO_DS_DX 0x00000938 #define NV_PVIDEO_DS_DX(i) 0x00000938 + (i * 4)
#define NV_PVIDEO_DT_DY 0x00000940 #define NV_PVIDEO_DT_DY(i) 0x00000940 + (i * 4)
#define NV_PVIDEO_POINT_OUT 0x00000948 #define NV_PVIDEO_POINT_OUT(i) 0x00000948 + (i * 4)
# define NV_PVIDEO_POINT_OUT_X 0x00000FFF # define NV_PVIDEO_POINT_OUT_X 0x00000FFF
# define NV_PVIDEO_POINT_OUT_Y 0x0FFF0000 # define NV_PVIDEO_POINT_OUT_Y 0x0FFF0000
#define NV_PVIDEO_SIZE_OUT 0x00000950 #define NV_PVIDEO_SIZE_OUT(i) 0x00000950 + (i * 4)
# define NV_PVIDEO_SIZE_OUT_WIDTH 0x00000FFF # define NV_PVIDEO_SIZE_OUT_WIDTH 0x00000FFF
# define NV_PVIDEO_SIZE_OUT_HEIGHT 0x0FFF0000 # define NV_PVIDEO_SIZE_OUT_HEIGHT 0x0FFF0000
#define NV_PVIDEO_FORMAT 0x00000958 #define NV_PVIDEO_FORMAT(i) 0x00000958 + (i * 4)
# define NV_PVIDEO_FORMAT_PITCH 0x00001FFF # define NV_PVIDEO_FORMAT_PITCH 0x00001FFF
# define NV_PVIDEO_FORMAT_COLOR 0x00030000 # define NV_PVIDEO_FORMAT_COLOR 0x00030000
# define NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8 1 # define NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8 1
@ -594,6 +696,7 @@
#define NV_PFB_DEBUG_0 0x00000080 #define NV_PFB_DEBUG_0 0x00000080
#define NV_PFB_CFG0 0x00000200 #define NV_PFB_CFG0 0x00000200
# define NV_PFB_CFG0_PART 0x00000003 # define NV_PFB_CFG0_PART 0x00000003
#define NV_PFB_CFG1 0x00000204
#define NV_PFB_CSTATUS 0x0000020C #define NV_PFB_CSTATUS 0x0000020C
#define NV_PFB_REFCTRL 0x00000210 #define NV_PFB_REFCTRL 0x00000210
#define NV_PFB_NVM 0x00000214 // NV_PFB_NVM_MODE_DISABLE #define NV_PFB_NVM 0x00000214 // NV_PFB_NVM_MODE_DISABLE
@ -602,17 +705,18 @@
#define NV_PFB_TIMING0 0x00000220 #define NV_PFB_TIMING0 0x00000220
#define NV_PFB_TIMING1 0x00000224 #define NV_PFB_TIMING1 0x00000224
#define NV_PFB_TIMING2 0x00000228 #define NV_PFB_TIMING2 0x00000228
#define NV_PFB_TILE 0x00000240 #define NV_PFB_TILE(i) 0x00000240 + (i * 0x10)
#define NV_PFB_TLIMIT 0x00000244 #define NV_PFB_TLIMIT(i) 0x00000244 + (i * 0x10)
#define NV_PFB_TSIZE 0x00000248 #define NV_PFB_TSIZE(i) 0x00000248 + (i * 0x10)
#define NV_PFB_TSTATUS 0x0000024C #define NV_PFB_TSTATUS(i) 0x0000024C + (i * 0x10)
#define NV_PFB_MRS 0x000002C0 #define NV_PFB_MRS 0x000002C0
#define NV_PFB_EMRS 0x000002C4 #define NV_PFB_EMRS 0x000002C4
#define NV_PFB_MRS_EXT 0x000002C8 #define NV_PFB_MRS_EXT 0x000002C8
#define NV_PFB_EMRS_EXT 0x000002CC #define NV_PFB_EMRS_EXT 0x000002CC
#define NV_PFB_REF 0x000002D0 #define NV_PFB_REF 0x000002D0
#define NV_PFB_PRE 0x000002D4 #define NV_PFB_PRE 0x000002D4
#define NV_PFB_ZCOMP 0x00000300 #define NV_PFB_ZCOMP(i) 0x00000300 + (i * 4)
#define NV_PFB_ZCOMP_OFFSET 0x00000324
#define NV_PFB_ARB_PREDIVIDER 0x00000328 #define NV_PFB_ARB_PREDIVIDER 0x00000328
#define NV_PFB_ARB_TIMEOUT 0x0000032C #define NV_PFB_ARB_TIMEOUT 0x0000032C
#define NV_PFB_ARB_XFER_REM 0x00000334 #define NV_PFB_ARB_XFER_REM 0x00000334
@ -632,6 +736,10 @@
#define NV_PFB_CPU_RRQ 0x00000420 #define NV_PFB_CPU_RRQ 0x00000420
#define NV_PFB_BYPASS 0x00000424 #define NV_PFB_BYPASS 0x00000424
#define NV_PRAMIN_DMA_CLASS(i) 0x00000000 + (i * 0x10)
#define NV_PRAMIN_DMA_LIMIT(i) 0x00000004 + (i * 0x10)
#define NV_PRAMIN_DMA_START(i) 0x00000008 + (i * 0x10)
#define NV_PRAMIN_DMA_ADDRESS(i) 0x0000000C + (i * 0x10)
#define NV_PRAMDAC_NVPLL_COEFF 0x00000500 #define NV_PRAMDAC_NVPLL_COEFF 0x00000500
# define NV_PRAMDAC_NVPLL_COEFF_MDIV 0x000000FF # define NV_PRAMDAC_NVPLL_COEFF_MDIV 0x000000FF
@ -704,7 +812,7 @@
# define NV062_SET_CONTEXT_DMA_IMAGE_DESTIN 0x00000188 # define NV062_SET_CONTEXT_DMA_IMAGE_DESTIN 0x00000188
# define NV062_SET_COLOR_FORMAT 0x00000300 # define NV062_SET_COLOR_FORMAT 0x00000300
# define NV062_SET_COLOR_FORMAT_LE_Y8 0x01 # define NV062_SET_COLOR_FORMAT_LE_Y8 0x01
# define NV062_SET_COLOR_FORMAT_LE_R5G6B5 0x04 # define NV062_SET_COLOR_FORMAT_LE_R5G6B5 0x04
# define NV062_SET_COLOR_FORMAT_LE_A8R8G8B8 0x0A # define NV062_SET_COLOR_FORMAT_LE_A8R8G8B8 0x0A
# define NV062_SET_PITCH 0x00000304 # define NV062_SET_PITCH 0x00000304
# define NV062_SET_OFFSET_SOURCE 0x00000308 # define NV062_SET_OFFSET_SOURCE 0x00000308
@ -773,8 +881,84 @@
# define NV097_SET_SURFACE_COLOR_OFFSET 0x00000210 # define NV097_SET_SURFACE_COLOR_OFFSET 0x00000210
# define NV097_SET_SURFACE_ZETA_OFFSET 0x00000214 # define NV097_SET_SURFACE_ZETA_OFFSET 0x00000214
# define NV097_SET_COMBINER_ALPHA_ICW 0x00000260 # define NV097_SET_COMBINER_ALPHA_ICW 0x00000260
# define NV097_SET_COMBINER_ALPHA_ICW_A_MAP 0xE0000000
# define NV097_SET_COMBINER_ALPHA_ICW_A_MAP_UNSIGNED_IDENTITY 0
# define NV097_SET_COMBINER_ALPHA_ICW_A_MAP_UNSIGNED_INVERT 1
# define NV097_SET_COMBINER_ALPHA_ICW_A_MAP_EXPAND_NORMAL 2
# define NV097_SET_COMBINER_ALPHA_ICW_A_MAP_EXPAND_NEGATE 3
# define NV097_SET_COMBINER_ALPHA_ICW_A_MAP_HALFBIAS_NORMAL 4
# define NV097_SET_COMBINER_ALPHA_ICW_A_MAP_HALFBIAS_NEGATE 5
# define NV097_SET_COMBINER_ALPHA_ICW_A_MAP_SIGNED_IDENTITY 6
# define NV097_SET_COMBINER_ALPHA_ICW_A_MAP_SIGNED_NEGATE 7
# define NV097_SET_COMBINER_ALPHA_ICW_A_ALPHA (1<<28)
# define NV097_SET_COMBINER_ALPHA_ICW_A_SOURCE 0x0F000000
# define NV097_SET_COMBINER_ALPHA_ICW_B_MAP 0x00E00000
# define NV097_SET_COMBINER_ALPHA_ICW_B_MAP_UNSIGNED_IDENTITY 0
# define NV097_SET_COMBINER_ALPHA_ICW_B_MAP_UNSIGNED_INVERT 1
# define NV097_SET_COMBINER_ALPHA_ICW_B_MAP_EXPAND_NORMAL 2
# define NV097_SET_COMBINER_ALPHA_ICW_B_MAP_EXPAND_NEGATE 3
# define NV097_SET_COMBINER_ALPHA_ICW_B_MAP_HALFBIAS_NORMAL 4
# define NV097_SET_COMBINER_ALPHA_ICW_B_MAP_HALFBIAS_NEGATE 5
# define NV097_SET_COMBINER_ALPHA_ICW_B_MAP_SIGNED_IDENTITY 6
# define NV097_SET_COMBINER_ALPHA_ICW_B_MAP_SIGNED_NEGATE 7
# define NV097_SET_COMBINER_ALPHA_ICW_B_ALPHA (1<<20)
# define NV097_SET_COMBINER_ALPHA_ICW_B_SOURCE 0x000F0000
# define NV097_SET_COMBINER_ALPHA_ICW_C_MAP 0x0000E000
# define NV097_SET_COMBINER_ALPHA_ICW_C_MAP_UNSIGNED_IDENTITY 0
# define NV097_SET_COMBINER_ALPHA_ICW_C_MAP_UNSIGNED_INVERT 1
# define NV097_SET_COMBINER_ALPHA_ICW_C_MAP_EXPAND_NORMAL 2
# define NV097_SET_COMBINER_ALPHA_ICW_C_MAP_EXPAND_NEGATE 3
# define NV097_SET_COMBINER_ALPHA_ICW_C_MAP_HALFBIAS_NORMAL 4
# define NV097_SET_COMBINER_ALPHA_ICW_C_MAP_HALFBIAS_NEGATE 5
# define NV097_SET_COMBINER_ALPHA_ICW_C_MAP_SIGNED_IDENTITY 6
# define NV097_SET_COMBINER_ALPHA_ICW_C_MAP_SIGNED_NEGATE 7
# define NV097_SET_COMBINER_ALPHA_ICW_C_ALPHA (1<<12)
# define NV097_SET_COMBINER_ALPHA_ICW_C_SOURCE 0x00000F00
# define NV097_SET_COMBINER_ALPHA_ICW_D_MAP 0x000000E0
# define NV097_SET_COMBINER_ALPHA_ICW_D_MAP_UNSIGNED_IDENTITY 0
# define NV097_SET_COMBINER_ALPHA_ICW_D_MAP_UNSIGNED_INVERT 1
# define NV097_SET_COMBINER_ALPHA_ICW_D_MAP_EXPAND_NORMAL 2
# define NV097_SET_COMBINER_ALPHA_ICW_D_MAP_EXPAND_NEGATE 3
# define NV097_SET_COMBINER_ALPHA_ICW_D_MAP_HALFBIAS_NORMAL 4
# define NV097_SET_COMBINER_ALPHA_ICW_D_MAP_HALFBIAS_NEGATE 5
# define NV097_SET_COMBINER_ALPHA_ICW_D_MAP_SIGNED_IDENTITY 6
# define NV097_SET_COMBINER_ALPHA_ICW_D_MAP_SIGNED_NEGATE 7
# define NV097_SET_COMBINER_ALPHA_ICW_D_ALPHA (1<<4)
# define NV097_SET_COMBINER_ALPHA_ICW_D_SOURCE 0x0000000F
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0 0x00000288 # define NV097_SET_COMBINER_SPECULAR_FOG_CW0 0x00000288
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_A_INVERSE 0xE0000000
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_A_ALPHA (1<<28)
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_A_SOURCE 0x0F000000
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_A_SOURCE_REG_SPECLIT 0xE
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_A_SOURCE_REG_EF_PROD 0xF
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_B_INVERSE 0x00E00000
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_B_ALPHA (1<<20)
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_B_SOURCE 0x000F0000
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_B_SOURCE_REG_SPECLIT 0xE
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_B_SOURCE_REG_EF_PROD 0xF
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_C_INVERSE 0x0000E000
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_C_ALPHA (1<<12)
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_C_SOURCE 0x00000F00
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_C_SOURCE_REG_SPECLIT 0xE
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_C_SOURCE_REG_EF_PROD 0xF
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_D_INVERSE 0x000000E0
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_D_ALPHA (1<<4)
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_D_SOURCE 0x0000000F
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_D_SOURCE_REG_SPECLIT 0xE
# define NV097_SET_COMBINER_SPECULAR_FOG_CW0_D_SOURCE_REG_EF_PROD 0xF
# define NV097_SET_COMBINER_SPECULAR_FOG_CW1 0x0000028C # define NV097_SET_COMBINER_SPECULAR_FOG_CW1 0x0000028C
# define NV097_SET_COMBINER_SPECULAR_FOG_CW1_E_INVERSE 0xE0000000
# define NV097_SET_COMBINER_SPECULAR_FOG_CW1_E_ALPHA (1<<28)
# define NV097_SET_COMBINER_SPECULAR_FOG_CW1_E_SOURCE 0x0F000000
# define NV097_SET_COMBINER_SPECULAR_FOG_CW1_F_INVERSE 0x00E00000
# define NV097_SET_COMBINER_SPECULAR_FOG_CW1_F_ALPHA (1<<20)
# define NV097_SET_COMBINER_SPECULAR_FOG_CW1_F_SOURCE 0x000F0000
# define NV097_SET_COMBINER_SPECULAR_FOG_CW1_G_INVERSE 0x0000E000
# define NV097_SET_COMBINER_SPECULAR_FOG_CW1_G_ALPHA (1<<12)
# define NV097_SET_COMBINER_SPECULAR_FOG_CW1_G_SOURCE 0x00000F00
# define NV097_SET_COMBINER_SPECULAR_FOG_CW1_SPECULAR_CLAMP (1<<7)
# define NV097_SET_COMBINER_SPECULAR_FOG_CW1_SPECULAR_ADD_INVERT_R5 (1<<6)
# define NV097_SET_COMBINER_SPECULAR_FOG_CW1_SPECULAR_ADD_INVERT_R12 0x0000003F
# define NV097_SET_CONTROL0 0x00000290 # define NV097_SET_CONTROL0 0x00000290
# define NV097_SET_CONTROL0_STENCIL_WRITE_ENABLE (1 << 0) # define NV097_SET_CONTROL0_STENCIL_WRITE_ENABLE (1 << 0)
# define NV097_SET_CONTROL0_Z_FORMAT (1 << 12) # define NV097_SET_CONTROL0_Z_FORMAT (1 << 12)
@ -928,13 +1112,37 @@
# define NV097_SET_TEXGEN_VIEW_MODEL_LOCAL_VIEWER 0 # define NV097_SET_TEXGEN_VIEW_MODEL_LOCAL_VIEWER 0
# define NV097_SET_TEXGEN_VIEW_MODEL_INFINITE_VIEWER 1 # define NV097_SET_TEXGEN_VIEW_MODEL_INFINITE_VIEWER 1
# define NV097_SET_FOG_PLANE 0x000009D0 # define NV097_SET_FOG_PLANE 0x000009D0
# define NV097_SET_FLAT_SHADE_OP 0x000009FC
# define NV097_SET_SCENE_AMBIENT_COLOR 0x00000A10 # define NV097_SET_SCENE_AMBIENT_COLOR 0x00000A10
# define NV097_SET_VIEWPORT_OFFSET 0x00000A20 # define NV097_SET_VIEWPORT_OFFSET 0x00000A20
# define NV097_SET_EYE_POSITION 0x00000A50 # define NV097_SET_EYE_POSITION 0x00000A50
# define NV097_SET_COMBINER_FACTOR0 0x00000A60 # define NV097_SET_COMBINER_FACTOR0 0x00000A60
# define NV097_SET_COMBINER_FACTOR1 0x00000A80 # define NV097_SET_COMBINER_FACTOR1 0x00000A80
# define NV097_SET_COMBINER_ALPHA_OCW 0x00000AA0 # define NV097_SET_COMBINER_ALPHA_OCW 0x00000AA0
# define NV097_SET_COMBINER_ALPHA_OCW_OP 0xFFFF8000
# define NV097_SET_COMBINER_ALPHA_OCW_OP_NOSHIFT 0
# define NV097_SET_COMBINER_ALPHA_OCW_OP_NOSHIFT_BIAS 1
# define NV097_SET_COMBINER_ALPHA_OCW_OP_SHIFTLEFTBY1 2
# define NV097_SET_COMBINER_ALPHA_OCW_OP_SHIFTLEFTBY1_BIAS 3
# define NV097_SET_COMBINER_ALPHA_OCW_OP_SHIFTLEFTBY2 4
# define NV097_SET_COMBINER_ALPHA_OCW_OP_SHIFTRIGHTBY1 6
# define NV097_SET_COMBINER_ALPHA_OCW_MUX_ENABLE (1<<14)
# define NV097_SET_COMBINER_ALPHA_OCW_SUM_DST 0x00000F00
# define NV097_SET_COMBINER_ALPHA_OCW_AB_DST 0x000000F0
# define NV097_SET_COMBINER_ALPHA_OCW_CD_DST 0x0000000F
# define NV097_SET_COMBINER_COLOR_ICW 0x00000AC0 # define NV097_SET_COMBINER_COLOR_ICW 0x00000AC0
# define NV097_SET_COMBINER_COLOR_ICW_A_MAP 0xE0000000
# define NV097_SET_COMBINER_COLOR_ICW_A_ALPHA (1<<28)
# define NV097_SET_COMBINER_COLOR_ICW_A_SOURCE 0x0F000000
# define NV097_SET_COMBINER_COLOR_ICW_B_MAP 0x00E00000
# define NV097_SET_COMBINER_COLOR_ICW_B_ALPHA (1<<20)
# define NV097_SET_COMBINER_COLOR_ICW_B_SOURCE 0x000F0000
# define NV097_SET_COMBINER_COLOR_ICW_C_MAP 0x0000E000
# define NV097_SET_COMBINER_COLOR_ICW_C_ALPHA (1<<12)
# define NV097_SET_COMBINER_COLOR_ICW_C_SOURCE 0x00000F00
# define NV097_SET_COMBINER_COLOR_ICW_D_MAP 0x000000E0
# define NV097_SET_COMBINER_COLOR_ICW_D_ALPHA (1<<4)
# define NV097_SET_COMBINER_COLOR_ICW_D_SOURCE 0x0000000F
# define NV097_SET_VIEWPORT_SCALE 0x00000AF0 # define NV097_SET_VIEWPORT_SCALE 0x00000AF0
# define NV097_SET_TRANSFORM_PROGRAM 0x00000B00 # define NV097_SET_TRANSFORM_PROGRAM 0x00000B00
# define NV097_SET_TRANSFORM_CONSTANT 0x00000B80 # define NV097_SET_TRANSFORM_CONSTANT 0x00000B80
@ -1081,6 +1289,8 @@
# define NV097_SET_TEXTURE_SET_BUMP_ENV_OFFSET 0x00001B3C # define NV097_SET_TEXTURE_SET_BUMP_ENV_OFFSET 0x00001B3C
# define NV097_SET_SEMAPHORE_OFFSET 0x00001D6C # define NV097_SET_SEMAPHORE_OFFSET 0x00001D6C
# define NV097_BACK_END_WRITE_SEMAPHORE_RELEASE 0x00001D70 # define NV097_BACK_END_WRITE_SEMAPHORE_RELEASE 0x00001D70
# define NV097_SET_ZMIN_MAX_CONTROL 0x00001D78
# define NV097_SET_COMPRESS_ZBUFFER_EN 0x00001D80
# define NV097_SET_ZSTENCIL_CLEAR_VALUE 0x00001D8C # define NV097_SET_ZSTENCIL_CLEAR_VALUE 0x00001D8C
# define NV097_SET_COLOR_CLEAR_VALUE 0x00001D90 # define NV097_SET_COLOR_CLEAR_VALUE 0x00001D90
# define NV097_CLEAR_SURFACE 0x00001D94 # define NV097_CLEAR_SURFACE 0x00001D94
@ -1095,13 +1305,118 @@
# define NV097_SET_CLEAR_RECT_VERTICAL 0x00001D9C # define NV097_SET_CLEAR_RECT_VERTICAL 0x00001D9C
# define NV097_SET_SPECULAR_FOG_FACTOR 0x00001E20 # define NV097_SET_SPECULAR_FOG_FACTOR 0x00001E20
# define NV097_SET_COMBINER_COLOR_OCW 0x00001E40 # define NV097_SET_COMBINER_COLOR_OCW 0x00001E40
# define NV097_SET_COMBINER_COLOR_OCW_BLUETOALPHA_AB 0xFFF80000
# define NV097_SET_COMBINER_COLOR_OCW_BLUETOALPHA_AB_DISABLE 0
# define NV097_SET_COMBINER_COLOR_OCW_BLUETOALPHA_AB_AB_DST_ENABLE 1
# define NV097_SET_COMBINER_COLOR_OCW_BLUETOALPHA_CD (1<<18)
# define NV097_SET_COMBINER_COLOR_OCW_BLUETOALPHA_CD_DISABLE 0
# define NV097_SET_COMBINER_COLOR_OCW_BLUETOALPHA_CD_CD_DST_ENABLE 1
# define NV097_SET_COMBINER_COLOR_OCW_OP 0x00038000
# define NV097_SET_COMBINER_COLOR_OCW_OP_NOSHIFT 0
# define NV097_SET_COMBINER_COLOR_OCW_OP_NOSHIFT_BIAS 1
# define NV097_SET_COMBINER_COLOR_OCW_OP_SHIFTLEFTBY1 2
# define NV097_SET_COMBINER_COLOR_OCW_OP_SHIFTLEFTBY1_BIAS 3
# define NV097_SET_COMBINER_COLOR_OCW_OP_SHIFTLEFTBY2 4
# define NV097_SET_COMBINER_COLOR_OCW_OP_SHIFTRIGHTBY1 6
# define NV097_SET_COMBINER_COLOR_OCW_MUX_ENABLE (1 << 14)
# define NV097_SET_COMBINER_COLOR_OCW_AB_DOT_ENABLE (1 << 13)
# define NV097_SET_COMBINER_COLOR_OCW_CD_DOT_ENABLE (1<<12)
# define NV097_SET_COMBINER_COLOR_OCW_SUM_DST 0x00000F00
# define NV097_SET_COMBINER_COLOR_OCW_AB_DST 0x000000F0
# define NV097_SET_COMBINER_COLOR_OCW_CD_DST 0x0000000F
# define NV097_SET_COMBINER_CONTROL 0x00001E60 # define NV097_SET_COMBINER_CONTROL 0x00001E60
# define NV097_SET_COMBINER_CONTROL_ITERATION_COUNT 0x000000FF
# define NV097_SET_COMBINER_CONTROL_ITERATION_COUNT_ONE 1
# define NV097_SET_COMBINER_CONTROL_ITERATION_COUNT_TWO 2
# define NV097_SET_COMBINER_CONTROL_ITERATION_COUNT_THREE 3
# define NV097_SET_COMBINER_CONTROL_ITERATION_COUNT_FOUR 4
# define NV097_SET_COMBINER_CONTROL_ITERATION_COUNT_FIVE 5
# define NV097_SET_COMBINER_CONTROL_ITERATION_COUNT_SIX 6
# define NV097_SET_COMBINER_CONTROL_ITERATION_COUNT_SEVEN 7
# define NV097_SET_COMBINER_CONTROL_ITERATION_COUNT_EIGHT 8
# define NV097_SET_COMBINER_CONTROL_MUX_SELECT 0x00000F00
# define NV097_SET_COMBINER_CONTROL_MUX_SELECT_LSB 0
# define NV097_SET_COMBINER_CONTROL_MUX_SELECT_MSB 1
# define NV097_SET_COMBINER_CONTROL_FACTOR0 0x0000F000
# define NV097_SET_COMBINER_CONTROL_FACTOR0_SAME_FACTOR_ALL 0
# define NV097_SET_COMBINER_CONTROL_FACTOR0_EACH_STAGE 1
# define NV097_SET_COMBINER_CONTROL_FACTOR1 0xFFFF0000
# define NV097_SET_COMBINER_CONTROL_FACTOR1_SAME_FACTOR_ALL 0
# define NV097_SET_COMBINER_CONTROL_FACTOR1_EACH_STAGE 1
# define NV097_SET_SHADOW_ZSLOPE_THRESHOLD 0x00001E68 # define NV097_SET_SHADOW_ZSLOPE_THRESHOLD 0x00001E68
# define NV097_SET_SHADER_STAGE_PROGRAM 0x00001E70 # define NV097_SET_SHADER_STAGE_PROGRAM 0x00001E70
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE0 0x0000001F
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE0_PROGRAM_NONE 0
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE0_2D_PROJECTIVE 1
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE0_3D_PROJECTIVE 2
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE0_CUBE_MAP 3
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE0_PASS_THROUGH 4
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE0_CLIP_PLANE 5
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE1 0x000003E0
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE1_PROGRAM_NONE 0x00
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE1_2D_PROJECTIVE 0x01
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE1_3D_PROJECTIVE 0x02
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE1_CUBE_MAP 0x03
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE1_PASS_THROUGH 0x04
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE1_CLIP_PLANE 0x05
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE1_BUMPENVMAP 0x06
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE1_BUMPENVMAP_LUMINANCE 0x07
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE1_DEPENDENT_AR 0x0F
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE1_DEPENDENT_GB 0x10
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE1_DOT_PRODUCT 0x11
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2 0x00007C00
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_PROGRAM_NONE 0x00
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_2D_PROJECTIVE 0x01
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_3D_PROJECTIVE 0x02
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_CUBE_MAP 0x03
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_PASS_THROUGH 0x04
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_CLIP_PLANE 0x05
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_BUMPENVMAP 0x06
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_BUMPENVMAP_LUMINANCE 0x07
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_BRDF 0x08
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_DOT_ST 0x09
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_DOT_ZW 0x0A
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_DOT_REFLECT_DIFFUSE 0x0B
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_DEPENDENT_AR 0x0F
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_DEPENDENT_GB 0x10
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE2_DOT_PRODUCT 0x11
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3 0x000F8000
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_PROGRAM_NONE 0x00
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_2D_PROJECTIVE 0x01
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_3D_PROJECTIVE 0x02
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_CUBE_MAP 0x03
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_PASS_THROUGH 0x04
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_CLIP_PLANE 0x05
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_BUMPENVMAP 0x06
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_BUMPENVMAP_LUMINANCE 0x07
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_BRDF 0x08
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_DOT_ST 0x09
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_DOT_ZW 0x0A
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_DOT_REFLECT_SPECULAR 0x0C
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_DOT_STR_3D 0x0D
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_DOT_STR_CUBE 0x0E
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_DEPENDENT_AR 0x0F
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_DEPENDENT_GB 0x10
# define NV097_SET_SHADER_STAGE_PROGRAM_STAGE3_DOT_REFLECT_SPECULAR_CONST 0x12
# define NV097_SET_SHADER_OTHER_STAGE_INPUT 0x00001E78 # define NV097_SET_SHADER_OTHER_STAGE_INPUT 0x00001E78
# define NV097_SET_SHADER_OTHER_STAGE_INPUT_STAGE1 0x0000FFFF
# define NV097_SET_SHADER_OTHER_STAGE_INPUT_STAGE1_INSTAGE_0 0
# define NV097_SET_SHADER_OTHER_STAGE_INPUT_STAGE2 0x000F0000
# define NV097_SET_SHADER_OTHER_STAGE_INPUT_STAGE2_INSTAGE_0 0
# define NV097_SET_SHADER_OTHER_STAGE_INPUT_STAGE2_INSTAGE_1 1
# define NV097_SET_SHADER_OTHER_STAGE_INPUT_STAGE3 0x00F00000
# define NV097_SET_SHADER_OTHER_STAGE_INPUT_STAGE3_INSTAGE_0 0
# define NV097_SET_SHADER_OTHER_STAGE_INPUT_STAGE3_INSTAGE_1 1
# define NV097_SET_SHADER_OTHER_STAGE_INPUT_STAGE3_INSTAGE_2 2
# define NV097_SET_TRANSFORM_DATA 0x00001E80
# define NV097_LAUNCH_TRANSFORM_PROGRAM 0x00001E90
# define NV097_SET_TRANSFORM_EXECUTION_MODE 0x00001E94 # define NV097_SET_TRANSFORM_EXECUTION_MODE 0x00001E94
# define NV097_SET_TRANSFORM_EXECUTION_MODE_MODE 0x00000003 # define NV097_SET_TRANSFORM_EXECUTION_MODE_MODE 0x00000003
# define NV097_SET_TRANSFORM_EXECUTION_MODE_MODE_FIXED 0
# define NV097_SET_TRANSFORM_EXECUTION_MODE_MODE_PROGRAM 2
# define NV097_SET_TRANSFORM_EXECUTION_MODE_RANGE_MODE 0xFFFFFFFC # define NV097_SET_TRANSFORM_EXECUTION_MODE_RANGE_MODE 0xFFFFFFFC
# define NV097_SET_TRANSFORM_EXECUTION_MODE_RANGE_MODE_USER 0
# define NV097_SET_TRANSFORM_EXECUTION_MODE_RANGE_MODE_PRIV 1
# define NV097_SET_TRANSFORM_PROGRAM_CXT_WRITE_EN 0x00001E98 # define NV097_SET_TRANSFORM_PROGRAM_CXT_WRITE_EN 0x00001E98
# define NV097_SET_TRANSFORM_PROGRAM_LOAD 0x00001E9C # define NV097_SET_TRANSFORM_PROGRAM_LOAD 0x00001E9C
# define NV097_SET_TRANSFORM_PROGRAM_START 0x00001EA0 # define NV097_SET_TRANSFORM_PROGRAM_START 0x00001EA0