wxGui branch: Merged with trunk (2 weeks of changes!)

git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@876 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-03-31 15:54:14 +00:00
commit cf0c53f152
167 changed files with 7006 additions and 5657 deletions

View File

@ -18,7 +18,7 @@
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
ConfigurationType="4" ConfigurationType="4"
InheritedPropertySheets="..\3rdparty.vsprops" InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
CharacterSet="2" CharacterSet="2"
> >
<Tool <Tool
@ -39,7 +39,6 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="1"
WarningLevel="3" WarningLevel="3"
@ -134,7 +133,7 @@
<Configuration <Configuration
Name="Devel|Win32" Name="Devel|Win32"
ConfigurationType="4" ConfigurationType="4"
InheritedPropertySheets="..\3rdparty.vsprops" InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
CharacterSet="2" CharacterSet="2"
WholeProgramOptimization="1" WholeProgramOptimization="1"
> >
@ -158,7 +157,7 @@
Optimization="2" Optimization="2"
EnableIntrinsicFunctions="true" EnableIntrinsicFunctions="true"
RuntimeLibrary="0" RuntimeLibrary="0"
EnableFunctionLevelLinking="true" BufferSecurityCheck="false"
WarningLevel="3" WarningLevel="3"
DebugInformationFormat="3" DebugInformationFormat="3"
/> />

View File

@ -18,7 +18,7 @@
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
ConfigurationType="4" ConfigurationType="4"
InheritedPropertySheets="..\3rdparty.vsprops" InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
CharacterSet="2" CharacterSet="2"
> >
<Tool <Tool
@ -39,7 +39,6 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="1"
WarningLevel="3" WarningLevel="3"
@ -140,7 +139,7 @@
<Configuration <Configuration
Name="Devel|Win32" Name="Devel|Win32"
ConfigurationType="4" ConfigurationType="4"
InheritedPropertySheets="..\3rdparty.vsprops" InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
CharacterSet="2" CharacterSet="2"
WholeProgramOptimization="0" WholeProgramOptimization="0"
> >
@ -170,7 +169,6 @@
StringPooling="true" StringPooling="true"
RuntimeLibrary="0" RuntimeLibrary="0"
BufferSecurityCheck="false" BufferSecurityCheck="false"
EnableFunctionLevelLinking="true"
WarningLevel="3" WarningLevel="3"
DebugInformationFormat="3" DebugInformationFormat="3"
/> />

View File

@ -19,7 +19,7 @@
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
ConfigurationType="4" ConfigurationType="4"
InheritedPropertySheets="..\3rdparty.vsprops" InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
CharacterSet="2" CharacterSet="2"
> >
<Tool <Tool
@ -42,13 +42,10 @@
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(ProjectDir)\include&quot;" AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;;&quot;$(ProjectDir)\include&quot;"
PreprocessorDefinitions="PTW32_STATIC_LIB;__CLEANUP_SEH;WIN32;_DEBUG;_LIB" PreprocessorDefinitions="PTW32_STATIC_LIB;__CLEANUP_SEH;WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
ExceptionHandling="2" ExceptionHandling="2"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="1"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
BrowseInformation="1"
WarningLevel="3" WarningLevel="3"
DebugInformationFormat="4" DebugInformationFormat="4"
CompileAs="1" CompileAs="1"
@ -155,7 +152,7 @@
<Configuration <Configuration
Name="Devel|Win32" Name="Devel|Win32"
ConfigurationType="4" ConfigurationType="4"
InheritedPropertySheets="..\3rdparty.vsprops" InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
CharacterSet="2" CharacterSet="2"
WholeProgramOptimization="0" WholeProgramOptimization="0"
> >
@ -189,9 +186,7 @@
RuntimeLibrary="0" RuntimeLibrary="0"
StructMemberAlignment="5" StructMemberAlignment="5"
BufferSecurityCheck="false" BufferSecurityCheck="false"
EnableFunctionLevelLinking="false"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
BrowseInformation="1"
WarningLevel="3" WarningLevel="3"
DebugInformationFormat="3" DebugInformationFormat="3"
CompileAs="1" CompileAs="1"

View File

@ -18,7 +18,7 @@
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
ConfigurationType="4" ConfigurationType="4"
InheritedPropertySheets="..\3rdparty.vsprops" InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
CharacterSet="2" CharacterSet="2"
> >
<Tool <Tool
@ -39,7 +39,6 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="1"
WarningLevel="3" WarningLevel="3"
@ -138,7 +137,7 @@
<Configuration <Configuration
Name="Devel|Win32" Name="Devel|Win32"
ConfigurationType="4" ConfigurationType="4"
InheritedPropertySheets="..\3rdparty.vsprops" InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
CharacterSet="2" CharacterSet="2"
WholeProgramOptimization="0" WholeProgramOptimization="0"
> >
@ -167,6 +166,7 @@
WholeProgramOptimization="false" WholeProgramOptimization="false"
StringPooling="true" StringPooling="true"
RuntimeLibrary="0" RuntimeLibrary="0"
BufferSecurityCheck="false"
WarningLevel="3" WarningLevel="3"
DebugInformationFormat="3" DebugInformationFormat="3"
/> />

Binary file not shown.

View File

@ -0,0 +1,4 @@
gametitle= Flinstones Bedrock Racing (SLES)
comment=Path 3 Hack
// Moved from Elfheader.cpp
patch=path3hack

View File

@ -0,0 +1,4 @@
gametitle= Sprint Cars (SLUS)
comment=Path 3 Hack
// Moved from Elfheader.cpp
patch=path3hack

View File

@ -548,7 +548,9 @@ typedef void (CALLBACK* _PADgsDriverInfo)(GSdriverInfo *info);
typedef void (CALLBACK* _PADconfigure)(); typedef void (CALLBACK* _PADconfigure)();
typedef s32 (CALLBACK* _PADtest)(); typedef s32 (CALLBACK* _PADtest)();
typedef void (CALLBACK* _PADabout)(); typedef void (CALLBACK* _PADabout)();
typedef int (CALLBACK* _PADfreeze)(int mode, freezeData *data); typedef int (CALLBACK* _PADfreeze)(int mode, freezeData *data);
typedef s32 (CALLBACK* _PADsetSlot)(u8 port, u8 slot);
typedef s32 (CALLBACK* _PADqueryMtap)(u8 port);
// SIO // SIO
typedef s32 (CALLBACK* _SIOinit)(u32 port, u32 slot, SIOchangeSlotCB f); typedef s32 (CALLBACK* _SIOinit)(u32 port, u32 slot, SIOchangeSlotCB f);
@ -734,6 +736,8 @@ extern _PADconfigure PAD1configure;
extern _PADtest PAD1test; extern _PADtest PAD1test;
extern _PADabout PAD1about; extern _PADabout PAD1about;
extern _PADfreeze PAD1freeze; extern _PADfreeze PAD1freeze;
extern _PADsetSlot PAD1setSlot;
extern _PADqueryMtap PAD1queryMtap;
// PAD2 // PAD2
extern _PADinit PAD2init; extern _PADinit PAD2init;
@ -751,6 +755,8 @@ extern _PADconfigure PAD2configure;
extern _PADtest PAD2test; extern _PADtest PAD2test;
extern _PADabout PAD2about; extern _PADabout PAD2about;
extern _PADfreeze PAD2freeze; extern _PADfreeze PAD2freeze;
extern _PADsetSlot PAD2setSlot;
extern _PADqueryMtap PAD2queryMtap;
// SIO[2] // SIO[2]
extern _SIOinit SIOinit[2][9]; extern _SIOinit SIOinit[2][9];

View File

@ -52,6 +52,10 @@ EXPORT_C(char*) PS2EgetLibName(void);
// Intended for them to get the ini and plugin paths, but could allow for other things as well. // Intended for them to get the ini and plugin paths, but could allow for other things as well.
EXPORT_C_(void) PS2EpassConfig(PcsxConfig Config); EXPORT_C_(void) PS2EpassConfig(PcsxConfig Config);
// Alternately, this function serves the same purpose, but would work for emulators outside
// of pcsx2.
EXPORT_C_(void) PS2EpassIniPath(const char *path);
// PS2EgetLibType returns (may be OR'd) // PS2EgetLibType returns (may be OR'd)
enum { enum {
PS2E_LT_GS = 0x01, PS2E_LT_GS = 0x01,

View File

@ -66,6 +66,7 @@ extern SessionOverrideFlags g_Session;
//------------ SPECIAL GAME FIXES!!! --------------- //------------ SPECIAL GAME FIXES!!! ---------------
#define CHECK_VUADDSUBHACK (Config.GameFixes & 0x1) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate. #define CHECK_VUADDSUBHACK (Config.GameFixes & 0x1) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate.
#define CHECK_FPUCOMPAREHACK (Config.GameFixes & 0x4) // Special Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu. #define CHECK_FPUCOMPAREHACK (Config.GameFixes & 0x4) // Special Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
#define CHECK_VUCLIPFLAGHACK (Config.GameFixes & 0x2) // Special Fix for Persona games, maybe others. It's to do with the VU clip flag (again).
#define CHECK_FPUMULHACK (Config.GameFixes & 0x8) // Special Fix for Tales of Destiny hangs. #define CHECK_FPUMULHACK (Config.GameFixes & 0x8) // Special Fix for Tales of Destiny hangs.
//------------ Advanced Options!!! --------------- //------------ Advanced Options!!! ---------------
#define CHECK_VU_OVERFLOW (Config.vuOptions & 0x1) #define CHECK_VU_OVERFLOW (Config.vuOptions & 0x1)
@ -80,8 +81,8 @@ extern SessionOverrideFlags g_Session;
#define DEFAULT_eeOptions 0x01 #define DEFAULT_eeOptions 0x01
#define DEFAULT_vuOptions 0x01 #define DEFAULT_vuOptions 0x01
//------------ DEFAULT sseMXCSR VALUES!!! --------------- //------------ DEFAULT sseMXCSR VALUES!!! ---------------
#define DEFAULT_sseMXCSR 0x7fc0 //FPU rounding, DaZ, "chop" - Note: Dont enable FtZ by default, it breaks games! E.g. Enthusia (Refraction) #define DEFAULT_sseMXCSR 0xffc0 //FPU rounding > DaZ, FtZ, "chop"
#define DEFAULT_sseVUMXCSR 0x7fc0 //VU rounding, DaZ, "chop" #define DEFAULT_sseVUMXCSR 0xffc0 //VU rounding > DaZ, FtZ, "chop"
#define CHECK_FRAMELIMIT (Config.Options&PCSX2_FRAMELIMIT_MASK) #define CHECK_FRAMELIMIT (Config.Options&PCSX2_FRAMELIMIT_MASK)

View File

@ -27,6 +27,7 @@ typedef u32 (CALLBACK* _PS2EgetLibType)(void);
typedef u32 (CALLBACK* _PS2EgetLibVersion2)(u32 type); typedef u32 (CALLBACK* _PS2EgetLibVersion2)(u32 type);
typedef char*(CALLBACK* _PS2EgetLibName)(void); typedef char*(CALLBACK* _PS2EgetLibName)(void);
typedef void (CALLBACK* _PS2EpassConfig)(PcsxConfig *Config); typedef void (CALLBACK* _PS2EpassConfig)(PcsxConfig *Config);
typedef void (CALLBACK* _PS2EpassIniPath)(const char *path);
// GS // GS
// NOTE: GSreadFIFOX/GSwriteCSR functions CANNOT use XMM/MMX regs // NOTE: GSreadFIFOX/GSwriteCSR functions CANNOT use XMM/MMX regs
@ -82,6 +83,8 @@ typedef s32 (CALLBACK* _PADfreeze)(u8 mode, freezeData *data);
typedef void (CALLBACK* _PADconfigure)(); typedef void (CALLBACK* _PADconfigure)();
typedef s32 (CALLBACK* _PADtest)(); typedef s32 (CALLBACK* _PADtest)();
typedef void (CALLBACK* _PADabout)(); typedef void (CALLBACK* _PADabout)();
typedef s32 (CALLBACK* _PADsetSlot)(u8 port, u8 slot);
typedef s32 (CALLBACK* _PADqueryMtap)(u8 port);
// SIO // SIO
typedef s32 (CALLBACK* _SIOinit)(int types, SIOchangeSlotCB f); typedef s32 (CALLBACK* _SIOinit)(int types, SIOchangeSlotCB f);

View File

@ -60,7 +60,19 @@ EXPORT_C_(void) PADupdate(u8 pad);
// Extended functions // Extended functions
EXPORT_C_(void) PADgsDriverInfo(GSdriverInfo *info); EXPORT_C_(void) PADgsDriverInfo(GSdriverInfo *info);
EXPORT_C_(s32) PADfreeze(u8 mode, freezeData *data); EXPORT_C_(s32) PADfreeze(u8 mode, freezeData *data);
// Returns 1 if the pad plugin wants a multitap on the specified port.
// 0 otherwise.
EXPORT_C_(s32) PADqueryMtap(u8 port);
// Sets the active pad slot for the specified port.
// Both numbers are 1-based indices. Should return 0 if there's no
// pad on the specified slot. Even if PADqueryMtap(port) returns 0,
// should handle this properly for slot != 1, so emulator can allow
// Multitap to be enabled/disabled elsewhere.
EXPORT_C_(s32) PADsetSlot(u8 port, u8 slot);
EXPORT_C_(void) PADconfigure(); EXPORT_C_(void) PADconfigure();
EXPORT_C_(void) PADabout(); EXPORT_C_(void) PADabout();
EXPORT_C_(s32) PADtest(); EXPORT_C_(s32) PADtest();

View File

@ -6,8 +6,7 @@
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(SvnRootDir)\3rdparty&quot;" AdditionalIncludeDirectories="&quot;$(SvnRootDir)\3rdparty\&quot;"
PreprocessorDefinitions="PTW32_STATIC_LIB;WIN32_PTHREADS;__CLEANUP_SEH"
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"

View File

@ -19,7 +19,6 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true" GenerateDebugInformation="true"
SubSystem="2" SubSystem="2"
/> />

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioPropertySheet
ProjectType="Visual C++"
Version="8.00"
Name="GlobalOptimizations"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
StringPooling="true"
MinimalRebuild="true"
BufferSecurityCheck="false"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
LinkTimeCodeGeneration="1"
/>
</VisualStudioPropertySheet>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioPropertySheet
ProjectType="Visual C++"
Version="8.00"
Name="IncrementalLinking"
>
<Tool
Name="VCCLCompilerTool"
WholeProgramOptimization="false"
StringPooling="true"
MinimalRebuild="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
OptimizeReferences="1"
EnableCOMDATFolding="1"
/>
</VisualStudioPropertySheet>

View File

@ -5,6 +5,11 @@
Name="w32pthreads" Name="w32pthreads"
> >
<Tool <Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(SvnRootDir)\3rdparty&quot;"
PreprocessorDefinitions="PTW32_STATIC_LIB;WIN32_PTHREADS;__CLEANUP_SEH"
/>
<Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(SvnRootDir)\3rdparty\w32pthreads\include&quot;" AdditionalIncludeDirectories="&quot;$(SvnRootDir)\3rdparty\w32pthreads\include&quot;"
/> />

30
common/vsprops/readme.txt Normal file
View File

@ -0,0 +1,30 @@
Decriptions of Provided .vsprops Sheets
---------------------------------------
* plugin_svnroot - Provides a set of semi-standard user macros for plugins that
conform to an expected folder layout. Each user macro can be optionally overridden
by the plugin using its own property sheet, if needed.
See the contents of plugin_svnroot for explanations of the User Macros used by all
other properties sheets lested below.
* 3rdPartyDeps - Adds the /deps folder to the linker search path. Does not add
any actual dependencies. You must add those manually.
* pthreads - Adds the w32pthreads library to your project, along with the expected
compiler defines for correctly compiling and linking pthreads.
* BaseProperties - Sets up standard Output and Intermediate directories, warning levels,
struct alignment, and other settings required for Pcsx2 and its libs to link in
a workable fashion. Adds standard preprocessor defines for:
__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE
* IncrementalLinking - Enables incremental linking, for use in devel/debug modes only.
Incremental linking force-disables Whole Program Optimization, but builds the result
.exe/.dll much quicker usually.
* GlobalLinking - Enables full support for Whole Program Optimization, and force-
disables any conflicting incremental link settings.

View File

@ -254,7 +254,7 @@ FILE *_cdvdOpenMechaVer() {
// if file doesnt exist, create empty one // if file doesnt exist, create empty one
fd = fopen(file, "r+b"); fd = fopen(file, "r+b");
if (fd == NULL) { if (fd == NULL) {
SysPrintf("MEC File Not Found , Creating Blank File\n"); Console::Notice("MEC File Not Found , Creating Blank File");
fd = fopen(file, "wb"); fd = fopen(file, "wb");
if (fd == NULL) { if (fd == NULL) {
Msgbox::Alert("_cdvdOpenMechaVer: Error creating %s", params file); Msgbox::Alert("_cdvdOpenMechaVer: Error creating %s", params file);
@ -299,7 +299,7 @@ FILE *_cdvdOpenNVM() {
// if file doesnt exist, create empty one // if file doesnt exist, create empty one
fd = fopen(file, "r+b"); fd = fopen(file, "r+b");
if (fd == NULL) { if (fd == NULL) {
SysPrintf("NVM File Not Found , Creating Blank File\n"); Console::Notice("NVM File Not Found , Creating Blank File");
fd = fopen(file, "wb"); fd = fopen(file, "wb");
if (fd == NULL) { if (fd == NULL) {
Msgbox::Alert("_cdvdOpenNVM: Error creating %s", params file); Msgbox::Alert("_cdvdOpenNVM: Error creating %s", params file);
@ -565,7 +565,7 @@ s32 cdvdGetToc(void* toc)
//the code below handles only CdGetToc! //the code below handles only CdGetToc!
//if(cdvd.Param[0]==0x01) //if(cdvd.Param[0]==0x01)
//{ //{
SysPrintf("CDGetToc Param[0]=%d, Param[1]=%d\n",cdvd.Param[0],cdvd.Param[1]); Console::WriteLn("CDGetToc Param[0]=%d, Param[1]=%d", params cdvd.Param[0],cdvd.Param[1]);
//} //}
type = CDVDgetDiskType(); type = CDVDgetDiskType();
if (CDVDgetTN(&diskInfo) == -1) { diskInfo.etrack = 0;diskInfo.strack = 1; } if (CDVDgetTN(&diskInfo) == -1) { diskInfo.etrack = 0;diskInfo.strack = 1; }
@ -831,11 +831,11 @@ void mechaDecryptBytes( u32 madr, int size )
int cdvdReadSector() { int cdvdReadSector() {
s32 bcr; s32 bcr;
CDR_LOG("SECTOR %d (BCR %x;%x)\n", cdvd.Sector, HW_DMA3_BCR_H16, HW_DMA3_BCR_L16); CDR_LOG("SECTOR %d (BCR %x;%x)", cdvd.Sector, HW_DMA3_BCR_H16, HW_DMA3_BCR_L16);
bcr = (HW_DMA3_BCR_H16 * HW_DMA3_BCR_L16) *4; bcr = (HW_DMA3_BCR_H16 * HW_DMA3_BCR_L16) *4;
if (bcr < cdvd.BlockSize) { if (bcr < cdvd.BlockSize) {
CDR_LOG( "READBLOCK: bcr < cdvd.BlockSize; %x < %x\n", bcr, cdvd.BlockSize ); CDR_LOG( "READBLOCK: bcr < cdvd.BlockSize; %x < %x", bcr, cdvd.BlockSize );
if (HW_DMA3_CHCR & 0x01000000) { if (HW_DMA3_CHCR & 0x01000000) {
HW_DMA3_CHCR &= ~0x01000000; HW_DMA3_CHCR &= ~0x01000000;
psxDmaInterrupt(3); psxDmaInterrupt(3);
@ -907,14 +907,13 @@ int cdvdReadSector() {
} }
// decrypt sector's bytes // decrypt sector's bytes
if( cdvd.decSet ) if( cdvd.decSet ) mechaDecryptBytes( HW_DMA3_MADR, cdvd.BlockSize );
mechaDecryptBytes( HW_DMA3_MADR, cdvd.BlockSize );
// Added a clear after memory write .. never seemed to be necessary before but *should* // Added a clear after memory write .. never seemed to be necessary before but *should*
// be more correct. (air) // be more correct. (air)
psxCpu->Clear( HW_DMA3_MADR, cdvd.BlockSize/4 ); psxCpu->Clear( HW_DMA3_MADR, cdvd.BlockSize/4 );
// SysPrintf("sector %x;%x;%x\n", PSXMu8(madr+0), PSXMu8(madr+1), PSXMu8(madr+2)); // Console::WriteLn("sector %x;%x;%x", params PSXMu8(madr+0), PSXMu8(madr+1), PSXMu8(madr+2));
HW_DMA3_BCR_H16-= (cdvd.BlockSize / (HW_DMA3_BCR_L16*4)); HW_DMA3_BCR_H16-= (cdvd.BlockSize / (HW_DMA3_BCR_L16*4));
HW_DMA3_MADR+= cdvd.BlockSize; HW_DMA3_MADR+= cdvd.BlockSize;
@ -962,9 +961,9 @@ __forceinline void cdvdActionInterrupt()
// inlined due to being referenced in only one place. // inlined due to being referenced in only one place.
__forceinline void cdvdReadInterrupt() __forceinline void cdvdReadInterrupt()
{ {
//SysPrintf("cdvdReadInterrupt %x %x %x %x %x\n", cpuRegs.interrupt, cdvd.Readed, cdvd.Reading, cdvd.nSectors, (HW_DMA3_BCR_H16 * HW_DMA3_BCR_L16) *4); //Console::WriteLn("cdvdReadInterrupt %x %x %x %x %x", params cpuRegs.interrupt, cdvd.Readed, cdvd.Reading, cdvd.nSectors, (HW_DMA3_BCR_H16 * HW_DMA3_BCR_L16) *4);
cdvd.Ready = 0x00; cdvd.Ready = 0x00;
if (cdvd.Readed == 0) if (cdvd.Readed == 0)
{ {
// Seeking finished. Process the track we requested before, and // Seeking finished. Process the track we requested before, and
@ -980,7 +979,7 @@ __forceinline void cdvdReadInterrupt()
cdvd.Status = CDVD_STATUS_SEEK_COMPLETE; cdvd.Status = CDVD_STATUS_SEEK_COMPLETE;
cdvd.Sector = cdvd.SeekToSector; cdvd.Sector = cdvd.SeekToSector;
CDR_LOG( "Cdvd Seek Complete > Scheduling block read interrupt at iopcycle=%8.8x.\n", CDR_LOG( "Cdvd Seek Complete > Scheduling block read interrupt at iopcycle=%8.8x.",
psxRegs.cycle + cdvd.ReadTime ); psxRegs.cycle + cdvd.ReadTime );
CDVDREAD_INT(cdvd.ReadTime); CDVDREAD_INT(cdvd.ReadTime);
@ -1068,93 +1067,93 @@ void cdvdVsync() {
u8 cdvdRead04(void) { // NCOMMAND u8 cdvdRead04(void) { // NCOMMAND
CDR_LOG("cdvdRead04(NCMD) %x\n", cdvd.nCommand); CDR_LOG("cdvdRead04(NCMD) %x", cdvd.nCommand);
return cdvd.nCommand; return cdvd.nCommand;
} }
u8 cdvdRead05(void) { // N-READY u8 cdvdRead05(void) { // N-READY
CDR_LOG("cdvdRead05(NReady) %x\n", cdvd.Ready); CDR_LOG("cdvdRead05(NReady) %x", cdvd.Ready);
return cdvd.Ready; return cdvd.Ready;
} }
u8 cdvdRead06(void) { // ERROR u8 cdvdRead06(void) { // ERROR
CDR_LOG("cdvdRead06(Error) %x\n", cdvd.Error); CDR_LOG("cdvdRead06(Error) %x", cdvd.Error);
return cdvd.Error; return cdvd.Error;
} }
u8 cdvdRead07(void) { // BREAK u8 cdvdRead07(void) { // BREAK
CDR_LOG("cdvdRead07(Break) %x\n", 0); CDR_LOG("cdvdRead07(Break) %x", 0);
return 0; return 0;
} }
u8 cdvdRead08(void) { // INTR_STAT u8 cdvdRead08(void) { // INTR_STAT
CDR_LOG("cdvdRead08(IntrReason) %x\n", cdvd.PwOff); CDR_LOG("cdvdRead08(IntrReason) %x", cdvd.PwOff);
return cdvd.PwOff; return cdvd.PwOff;
} }
u8 cdvdRead0A(void) { // STATUS u8 cdvdRead0A(void) { // STATUS
CDR_LOG("cdvdRead0A(Status) %x\n", cdvd.Status); CDR_LOG("cdvdRead0A(Status) %x", cdvd.Status);
return cdvd.Status; return cdvd.Status;
} }
u8 cdvdRead0B(void) { // TRAY-STATE (if tray has been opened) u8 cdvdRead0B(void) { // TRAY-STATE (if tray has been opened)
u8 tray = cdvdGetTrayStatus(); u8 tray = cdvdGetTrayStatus();
CDR_LOG("cdvdRead0B(Tray) %x\n", tray); CDR_LOG("cdvdRead0B(Tray) %x", tray);
return tray; return tray;
} }
u8 cdvdRead0C(void) { // CRT MINUTE u8 cdvdRead0C(void) { // CRT MINUTE
CDR_LOG("cdvdRead0C(Min) %x\n", itob((u8)(cdvd.Sector/(60*75)))); CDR_LOG("cdvdRead0C(Min) %x", itob((u8)(cdvd.Sector/(60*75))));
return itob((u8)(cdvd.Sector/(60*75))); return itob((u8)(cdvd.Sector/(60*75)));
} }
u8 cdvdRead0D(void) { // CRT SECOND u8 cdvdRead0D(void) { // CRT SECOND
CDR_LOG("cdvdRead0D(Sec) %x\n", itob((u8)((cdvd.Sector/75)%60)+2)); CDR_LOG("cdvdRead0D(Sec) %x", itob((u8)((cdvd.Sector/75)%60)+2));
return itob((u8)((cdvd.Sector/75)%60)+2); return itob((u8)((cdvd.Sector/75)%60)+2);
} }
u8 cdvdRead0E(void) { // CRT FRAME u8 cdvdRead0E(void) { // CRT FRAME
CDR_LOG("cdvdRead0E(Frame) %x\n", itob((u8)(cdvd.Sector%75))); CDR_LOG("cdvdRead0E(Frame) %x", itob((u8)(cdvd.Sector%75)));
return itob((u8)(cdvd.Sector%75)); return itob((u8)(cdvd.Sector%75));
} }
u8 cdvdRead0F(void) // TYPE u8 cdvdRead0F(void) // TYPE
{ {
CDR_LOG("cdvdRead0F(Disc Type) %x\n", cdvd.Type); CDR_LOG("cdvdRead0F(Disc Type) %x", cdvd.Type);
cdvdGetDiskType(); cdvdGetDiskType();
return cdvd.Type; return cdvd.Type;
} }
u8 cdvdRead13(void) { // UNKNOWN u8 cdvdRead13(void) { // UNKNOWN
CDR_LOG("cdvdRead13(Unknown) %x\n", 4); CDR_LOG("cdvdRead13(Unknown) %x", 4);
return 4; return 4;
} }
u8 cdvdRead15(void) { // RSV u8 cdvdRead15(void) { // RSV
CDR_LOG("cdvdRead15(RSV)\n"); CDR_LOG("cdvdRead15(RSV)");
return 0x01; // | 0x80 for ATAPI mode return 0x01; // | 0x80 for ATAPI mode
} }
u8 cdvdRead16(void) { // SCOMMAND u8 cdvdRead16(void) { // SCOMMAND
CDR_LOG("cdvdRead16(SCMD) %x\n", cdvd.sCommand); CDR_LOG("cdvdRead16(SCMD) %x", cdvd.sCommand);
return cdvd.sCommand; return cdvd.sCommand;
} }
u8 cdvdRead17(void) { // SREADY u8 cdvdRead17(void) { // SREADY
CDR_LOG("cdvdRead17(SReady) %x\n", cdvd.sDataIn); CDR_LOG("cdvdRead17(SReady) %x", cdvd.sDataIn);
return cdvd.sDataIn; return cdvd.sDataIn;
} }
@ -1169,54 +1168,54 @@ u8 cdvdRead18(void) { // SDATAOUT
ret = cdvd.Result[cdvd.ResultP-1]; ret = cdvd.Result[cdvd.ResultP-1];
} }
} }
CDR_LOG("cdvdRead18(SDataOut) %x (ResultC=%d, ResultP=%d)\n", ret, cdvd.ResultC, cdvd.ResultP); CDR_LOG("cdvdRead18(SDataOut) %x (ResultC=%d, ResultP=%d)", ret, cdvd.ResultC, cdvd.ResultP);
return ret; return ret;
} }
u8 cdvdRead20(void) { u8 cdvdRead20(void) {
CDR_LOG("cdvdRead20(Key0) %x\n", cdvd.Key[0]); CDR_LOG("cdvdRead20(Key0) %x", cdvd.Key[0]);
return cdvd.Key[0]; return cdvd.Key[0];
} }
u8 cdvdRead21(void) { u8 cdvdRead21(void) {
CDR_LOG("cdvdRead21(Key1) %x\n", cdvd.Key[1]); CDR_LOG("cdvdRead21(Key1) %x", cdvd.Key[1]);
return cdvd.Key[1]; return cdvd.Key[1];
} }
u8 cdvdRead22(void) { u8 cdvdRead22(void) {
CDR_LOG("cdvdRead22(Key2) %x\n", cdvd.Key[2]); CDR_LOG("cdvdRead22(Key2) %x", cdvd.Key[2]);
return cdvd.Key[2]; return cdvd.Key[2];
} }
u8 cdvdRead23(void) { u8 cdvdRead23(void) {
CDR_LOG("cdvdRead23(Key3) %x\n", cdvd.Key[3]); CDR_LOG("cdvdRead23(Key3) %x", cdvd.Key[3]);
return cdvd.Key[3]; return cdvd.Key[3];
} }
u8 cdvdRead24(void) { u8 cdvdRead24(void) {
CDR_LOG("cdvdRead24(Key4) %x\n", cdvd.Key[4]); CDR_LOG("cdvdRead24(Key4) %x", cdvd.Key[4]);
return cdvd.Key[4]; return cdvd.Key[4];
} }
u8 cdvdRead28(void) { u8 cdvdRead28(void) {
CDR_LOG("cdvdRead28(Key5) %x\n", cdvd.Key[5]); CDR_LOG("cdvdRead28(Key5) %x", cdvd.Key[5]);
return cdvd.Key[5]; return cdvd.Key[5];
} }
u8 cdvdRead29(void) { u8 cdvdRead29(void) {
CDR_LOG("cdvdRead29(Key6) %x\n", cdvd.Key[6]); CDR_LOG("cdvdRead29(Key6) %x", cdvd.Key[6]);
return cdvd.Key[6]; return cdvd.Key[6];
} }
u8 cdvdRead2A(void) { u8 cdvdRead2A(void) {
CDR_LOG("cdvdRead2A(Key7) %x\n", cdvd.Key[7]); CDR_LOG("cdvdRead2A(Key7) %x", cdvd.Key[7]);
return cdvd.Key[7]; return cdvd.Key[7];
} }
@ -1228,57 +1227,57 @@ u8 cdvdRead2B(void) {
} }
u8 cdvdRead2C(void) { u8 cdvdRead2C(void) {
CDR_LOG("cdvdRead2C(Key9) %x\n", cdvd.Key[9]); CDR_LOG("cdvdRead2C(Key9) %x", cdvd.Key[9]);
return cdvd.Key[9]; return cdvd.Key[9];
} }
u8 cdvdRead30(void) { u8 cdvdRead30(void) {
CDR_LOG("cdvdRead30(Key10) %x\n", cdvd.Key[10]); CDR_LOG("cdvdRead30(Key10) %x", cdvd.Key[10]);
return cdvd.Key[10]; return cdvd.Key[10];
} }
u8 cdvdRead31(void) { u8 cdvdRead31(void) {
CDR_LOG("cdvdRead31(Key11) %x\n", cdvd.Key[11]); CDR_LOG("cdvdRead31(Key11) %x", cdvd.Key[11]);
return cdvd.Key[11]; return cdvd.Key[11];
} }
u8 cdvdRead32(void) { u8 cdvdRead32(void) {
CDR_LOG("cdvdRead32(Key12) %x\n", cdvd.Key[12]); CDR_LOG("cdvdRead32(Key12) %x", cdvd.Key[12]);
return cdvd.Key[12]; return cdvd.Key[12];
} }
u8 cdvdRead33(void) { u8 cdvdRead33(void) {
CDR_LOG("cdvdRead33(Key13) %x\n", cdvd.Key[13]); CDR_LOG("cdvdRead33(Key13) %x", cdvd.Key[13]);
return cdvd.Key[13]; return cdvd.Key[13];
} }
u8 cdvdRead34(void) { u8 cdvdRead34(void) {
CDR_LOG("cdvdRead34(Key14) %x\n", cdvd.Key[14]); CDR_LOG("cdvdRead34(Key14) %x", cdvd.Key[14]);
return cdvd.Key[14]; return cdvd.Key[14];
} }
u8 cdvdRead38(void) { // valid parts of key data (first and last are valid) u8 cdvdRead38(void) { // valid parts of key data (first and last are valid)
CDR_LOG("cdvdRead38(KeysValid) %x\n", cdvd.Key[15]); CDR_LOG("cdvdRead38(KeysValid) %x", cdvd.Key[15]);
return cdvd.Key[15]; return cdvd.Key[15];
} }
u8 cdvdRead39(void) { // KEY-XOR u8 cdvdRead39(void) { // KEY-XOR
CDR_LOG("cdvdRead39(KeyXor) %x\n", cdvd.KeyXor); CDR_LOG("cdvdRead39(KeyXor) %x", cdvd.KeyXor);
return cdvd.KeyXor; return cdvd.KeyXor;
} }
u8 cdvdRead3A(void) { // DEC_SET u8 cdvdRead3A(void) { // DEC_SET
CDR_LOG("cdvdRead3A(DecSet) %x\n", cdvd.decSet); CDR_LOG("cdvdRead3A(DecSet) %x", cdvd.decSet);
SysPrintf("DecSet Read: %02X\n", cdvd.decSet); Console::WriteLn("DecSet Read: %02X", params cdvd.decSet);
return cdvd.decSet; return cdvd.decSet;
} }
@ -1298,7 +1297,7 @@ static uint cdvdStartSeek( uint newsector, CDVD_MODE_TYPE mode )
if( !cdvd.Spinning ) if( !cdvd.Spinning )
{ {
CDR_LOG( "CdSpinUp > Simulating CdRom Spinup Time, and seek to sector %d\n", cdvd.SeekToSector ); CDR_LOG( "CdSpinUp > Simulating CdRom Spinup Time, and seek to sector %d", cdvd.SeekToSector );
seektime = PSXCLK / 3; // 333ms delay seektime = PSXCLK / 3; // 333ms delay
cdvd.Spinning = true; cdvd.Spinning = true;
} }
@ -1309,18 +1308,18 @@ static uint cdvdStartSeek( uint newsector, CDVD_MODE_TYPE mode )
if( delta >= tbl_FastSeekDelta[mode] ) if( delta >= tbl_FastSeekDelta[mode] )
{ {
// Full Seek // Full Seek
CDR_LOG( "CdSeek Begin > to sector %d, from %d - delta=%d [FULL]\n", cdvd.SeekToSector, cdvd.Sector, delta ); CDR_LOG( "CdSeek Begin > to sector %d, from %d - delta=%d [FULL]", cdvd.SeekToSector, cdvd.Sector, delta );
seektime = Cdvd_FullSeek_Cycles; seektime = Cdvd_FullSeek_Cycles;
} }
else else
{ {
CDR_LOG( "CdSeek Begin > to sector %d, from %d - delta=%d [FAST]\n", cdvd.SeekToSector, cdvd.Sector, delta ); CDR_LOG( "CdSeek Begin > to sector %d, from %d - delta=%d [FAST]", cdvd.SeekToSector, cdvd.Sector, delta );
seektime = Cdvd_FastSeek_Cycles; seektime = Cdvd_FastSeek_Cycles;
} }
} }
else else
{ {
CDR_LOG( "CdSeek Begin > Contiguous block without seek - delta=%d sectors\n", delta ); CDR_LOG( "CdSeek Begin > Contiguous block without seek - delta=%d sectors", delta );
// seektime is the time it takes to read to the destination block: // seektime is the time it takes to read to the destination block:
seektime = delta * cdvd.ReadTime; seektime = delta * cdvd.ReadTime;
@ -1342,7 +1341,7 @@ static uint cdvdStartSeek( uint newsector, CDVD_MODE_TYPE mode )
} }
void cdvdWrite04(u8 rt) { // NCOMMAND void cdvdWrite04(u8 rt) { // NCOMMAND
CDR_LOG("cdvdWrite04: NCMD %s (%x) (ParamP = %x)\n", nCmdName[rt], rt, cdvd.ParamP); CDR_LOG("cdvdWrite04: NCMD %s (%x) (ParamP = %x)", nCmdName[rt], rt, cdvd.ParamP);
cdvd.nCommand = rt; cdvd.nCommand = rt;
cdvd.Status = CDVD_STATUS_NONE; cdvd.Status = CDVD_STATUS_NONE;
@ -1394,7 +1393,7 @@ void cdvdWrite04(u8 rt) { // NCOMMAND
case 0: default: cdvd.ReadMode = CDVD_MODE_2048; cdvd.BlockSize = 2048; break; case 0: default: cdvd.ReadMode = CDVD_MODE_2048; cdvd.BlockSize = 2048; break;
} }
CDR_LOG( "CdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)\n", CDR_LOG( "CdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)",
cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074));
if( Config.cdvdPrint ) if( Config.cdvdPrint )
@ -1435,7 +1434,7 @@ void cdvdWrite04(u8 rt) { // NCOMMAND
case 0: cdvd.ReadMode = CDVD_MODE_2352; cdvd.BlockSize = 2352; break; case 0: cdvd.ReadMode = CDVD_MODE_2352; cdvd.BlockSize = 2352; break;
} }
CDR_LOG( "CdReadCDDA > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%xx(%x), ReadMode=%x(%x) (1074=%x)\n", CDR_LOG( "CdReadCDDA > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%xx(%x), ReadMode=%x(%x) (1074=%x)",
cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074));
if( Config.cdvdPrint ) if( Config.cdvdPrint )
@ -1466,7 +1465,7 @@ void cdvdWrite04(u8 rt) { // NCOMMAND
cdvd.ReadMode = CDVD_MODE_2048; cdvd.ReadMode = CDVD_MODE_2048;
cdvd.BlockSize = 2064; // Why oh why was it 2064 cdvd.BlockSize = 2064; // Why oh why was it 2064
CDR_LOG( "DvdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)\n", CDR_LOG( "DvdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)",
cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074)); cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074));
if( Config.cdvdPrint ) if( Config.cdvdPrint )
@ -1505,7 +1504,7 @@ void cdvdWrite04(u8 rt) { // NCOMMAND
u8 arg0 = cdvd.Param[0]; u8 arg0 = cdvd.Param[0];
u16 arg1 = cdvd.Param[1] | (cdvd.Param[2]<<8); u16 arg1 = cdvd.Param[1] | (cdvd.Param[2]<<8);
u32 arg2 = cdvd.Param[3] | (cdvd.Param[4]<<8) | (cdvd.Param[5]<<16) | (cdvd.Param[6]<<24); u32 arg2 = cdvd.Param[3] | (cdvd.Param[4]<<8) | (cdvd.Param[5]<<16) | (cdvd.Param[6]<<24);
DevCon::WriteLn("cdvdReadKey(%d, %d, %d)\n", params arg0, arg1, arg2); DevCon::WriteLn("cdvdReadKey(%d, %d, %d)", params arg0, arg1, arg2);
cdvdReadKey(arg0, arg1, arg2, cdvd.Key); cdvdReadKey(arg0, arg1, arg2, cdvd.Key);
cdvd.KeyXor = 0x00; cdvd.KeyXor = 0x00;
cdvdSetIrq(); cdvdSetIrq();
@ -1527,7 +1526,7 @@ void cdvdWrite04(u8 rt) { // NCOMMAND
} }
void cdvdWrite05(u8 rt) { // NDATAIN void cdvdWrite05(u8 rt) { // NDATAIN
CDR_LOG("cdvdWrite05(NDataIn) %x\n", rt); CDR_LOG("cdvdWrite05(NDataIn) %x", rt);
if (cdvd.ParamP < 32) { if (cdvd.ParamP < 32) {
cdvd.Param[cdvd.ParamP++] = rt; cdvd.Param[cdvd.ParamP++] = rt;
@ -1536,13 +1535,13 @@ void cdvdWrite05(u8 rt) { // NDATAIN
} }
void cdvdWrite06(u8 rt) { // HOWTO void cdvdWrite06(u8 rt) { // HOWTO
CDR_LOG("cdvdWrite06(HowTo) %x\n", rt); CDR_LOG("cdvdWrite06(HowTo) %x", rt);
cdvd.HowTo = rt; cdvd.HowTo = rt;
} }
void cdvdWrite07(u8 rt) // BREAK void cdvdWrite07(u8 rt) // BREAK
{ {
CDR_LOG("cdvdWrite07(Break) %x\n", rt); CDR_LOG("cdvdWrite07(Break) %x", rt);
// If we're already in a Ready state or already Breaking, then do nothing: // If we're already in a Ready state or already Breaking, then do nothing:
if( cdvd.Ready != 0 || cdvd.Action == cdvdAction_Break ) if( cdvd.Ready != 0 || cdvd.Action == cdvdAction_Break )
@ -1566,24 +1565,24 @@ void cdvdWrite07(u8 rt) // BREAK
} }
void cdvdWrite08(u8 rt) { // INTR_STAT void cdvdWrite08(u8 rt) { // INTR_STAT
CDR_LOG("cdvdWrite08(IntrReason) = ACK(%x)\n", rt); CDR_LOG("cdvdWrite08(IntrReason) = ACK(%x)", rt);
cdvd.PwOff &= ~rt; cdvd.PwOff &= ~rt;
} }
void cdvdWrite0A(u8 rt) { // STATUS void cdvdWrite0A(u8 rt) { // STATUS
CDR_LOG("cdvdWrite0A(Status) %x\n", rt); CDR_LOG("cdvdWrite0A(Status) %x", rt);
} }
void cdvdWrite0F(u8 rt) { // TYPE void cdvdWrite0F(u8 rt) { // TYPE
CDR_LOG("cdvdWrite0F(Type) %x\n", rt); CDR_LOG("cdvdWrite0F(Type) %x", rt);
DevCon::WriteLn("*PCSX2*: CDVD TYPE %x\n", params rt); DevCon::WriteLn("*PCSX2*: CDVD TYPE %x", params rt);
} }
void cdvdWrite14(u8 rt) { // PS1 MODE?? void cdvdWrite14(u8 rt) { // PS1 MODE??
u32 cycle = psxRegs.cycle; u32 cycle = psxRegs.cycle;
if (rt == 0xFE) Console::Notice("*PCSX2*: go PS1 mode DISC SPEED = FAST\n"); if (rt == 0xFE) Console::Notice("*PCSX2*: go PS1 mode DISC SPEED = FAST");
else Console::Notice("*PCSX2*: go PS1 mode DISC SPEED = %dX\n", params rt); else Console::Notice("*PCSX2*: go PS1 mode DISC SPEED = %dX", params rt);
psxReset(); psxReset();
psxHu32(0x1f801450) = 0x8; psxHu32(0x1f801450) = 0x8;
@ -1599,7 +1598,7 @@ void cdvdWrite16(u8 rt) // SCOMMAND
int address; int address;
u8 tmp; u8 tmp;
CDR_LOG("cdvdWrite16: SCMD %s (%x) (ParamP = %x)\n", sCmdName[rt], rt, cdvd.ParamP); CDR_LOG("cdvdWrite16: SCMD %s (%x) (ParamP = %x)", sCmdName[rt], rt, cdvd.ParamP);
cdvd.sCommand = rt; cdvd.sCommand = rt;
switch (rt) { switch (rt) {
@ -1642,7 +1641,7 @@ void cdvdWrite16(u8 rt) // SCOMMAND
} else { } else {
SetResultSize(1); SetResultSize(1);
cdvd.Result[0] = 0x80; cdvd.Result[0] = 0x80;
SysPrintf("*Unknown Mecacon Command param[0]=%02X\n", cdvd.Param[0]); Console::WriteLn("*Unknown Mecacon Command param[0]=%02X", params cdvd.Param[0]);
} }
break; break;
@ -1671,9 +1670,9 @@ void cdvdWrite16(u8 rt) // SCOMMAND
if(cdvd.Result[3] <= 7) cdvd.Result[5] += 1; if(cdvd.Result[3] <= 7) cdvd.Result[5] += 1;
cdvd.Result[6] = itob(cdvd.RTC.month)+0x80; //Month cdvd.Result[6] = itob(cdvd.RTC.month)+0x80; //Month
cdvd.Result[7] = itob(cdvd.RTC.year); //Year cdvd.Result[7] = itob(cdvd.RTC.year); //Year
/*SysPrintf("RTC Read Sec %x Min %x Hr %x Day %x Month %x Year %x\n", cdvd.Result[1], cdvd.Result[2], /*Console::WriteLn("RTC Read Sec %x Min %x Hr %x Day %x Month %x Year %x", params cdvd.Result[1], cdvd.Result[2],
cdvd.Result[3], cdvd.Result[5], cdvd.Result[6], cdvd.Result[7]); cdvd.Result[3], cdvd.Result[5], cdvd.Result[6], cdvd.Result[7]);
SysPrintf("RTC Read Real Sec %d Min %d Hr %d Day %d Month %d Year %d\n", cdvd.RTC.second, cdvd.RTC.minute, Console::WriteLn("RTC Read Real Sec %d Min %d Hr %d Day %d Month %d Year %d", params cdvd.RTC.second, cdvd.RTC.minute,
cdvd.RTC.hour, cdvd.RTC.day, cdvd.RTC.month, cdvd.RTC.year);*/ cdvd.RTC.hour, cdvd.RTC.day, cdvd.RTC.month, cdvd.RTC.year);*/
break; break;
@ -1690,9 +1689,9 @@ void cdvdWrite16(u8 rt) // SCOMMAND
if(cdvd.Param[cdvd.ParamP-5] <= 7) cdvd.RTC.day -= 1; if(cdvd.Param[cdvd.ParamP-5] <= 7) cdvd.RTC.day -= 1;
cdvd.RTC.month = btoi(cdvd.Param[cdvd.ParamP-2]-0x80); cdvd.RTC.month = btoi(cdvd.Param[cdvd.ParamP-2]-0x80);
cdvd.RTC.year = btoi(cdvd.Param[cdvd.ParamP-1]); cdvd.RTC.year = btoi(cdvd.Param[cdvd.ParamP-1]);
/*SysPrintf("RTC write incomming Sec %x Min %x Hr %x Day %x Month %x Year %x\n", cdvd.Param[cdvd.ParamP-7], cdvd.Param[cdvd.ParamP-6], /*Console::WriteLn("RTC write incomming Sec %x Min %x Hr %x Day %x Month %x Year %x", params cdvd.Param[cdvd.ParamP-7], cdvd.Param[cdvd.ParamP-6],
cdvd.Param[cdvd.ParamP-5], cdvd.Param[cdvd.ParamP-3], cdvd.Param[cdvd.ParamP-2], cdvd.Param[cdvd.ParamP-1]); cdvd.Param[cdvd.ParamP-5], cdvd.Param[cdvd.ParamP-3], cdvd.Param[cdvd.ParamP-2], cdvd.Param[cdvd.ParamP-1]);
SysPrintf("RTC Write Sec %d Min %d Hr %d Day %d Month %d Year %d\n", cdvd.RTC.second, cdvd.RTC.minute, Console::WriteLn("RTC Write Sec %d Min %d Hr %d Day %d Month %d Year %d", params cdvd.RTC.second, cdvd.RTC.minute,
cdvd.RTC.hour, cdvd.RTC.day, cdvd.RTC.month, cdvd.RTC.year);*/ cdvd.RTC.hour, cdvd.RTC.day, cdvd.RTC.month, cdvd.RTC.year);*/
//memcpy_fast((u8*)&cdvd.RTC, cdvd.Param, 7); //memcpy_fast((u8*)&cdvd.RTC, cdvd.Param, 7);
SetResultSize(1); SetResultSize(1);
@ -1753,7 +1752,7 @@ void cdvdWrite16(u8 rt) // SCOMMAND
break; break;
case 0x15: // sceCdForbidDVDP (0:1) case 0x15: // sceCdForbidDVDP (0:1)
//SysPrintf("sceCdForbidDVDP\n"); //Console::WriteLn("sceCdForbidDVDP");
SetResultSize(1); SetResultSize(1);
cdvd.Result[0] = 5; cdvd.Result[0] = 5;
break; break;
@ -1778,7 +1777,7 @@ void cdvdWrite16(u8 rt) // SCOMMAND
case 0x1A: // sceCdBootCertify (4:1)//(4:16 in psx?) case 0x1A: // sceCdBootCertify (4:1)//(4:16 in psx?)
SetResultSize(1);//on input there are 4 bytes: 1;?10;J;C for 18000; 1;60;E;C for 39002 from ROMVER SetResultSize(1);//on input there are 4 bytes: 1;?10;J;C for 18000; 1;60;E;C for 39002 from ROMVER
cdvd.Result[0]=1;//i guess that means okay cdvd.Result[0] = 1;//i guess that means okay
break; break;
case 0x1B: // sceCdCancelPOffRdy (0:1) - Call73 from Xcdvdman (1:1) case 0x1B: // sceCdCancelPOffRdy (0:1) - Call73 from Xcdvdman (1:1)
@ -1886,7 +1885,7 @@ void cdvdWrite16(u8 rt) // SCOMMAND
SetResultSize(15); SetResultSize(15);
cdvdGetMechaVer(&cdvd.Result[1]); cdvdGetMechaVer(&cdvd.Result[1]);
cdvd.Result[0] = cdvdReadRegionParams(&cdvd.Result[3]);//size==8 cdvd.Result[0] = cdvdReadRegionParams(&cdvd.Result[3]);//size==8
SysPrintf("REGION PARAMS = %s %s\n", mg_zones[cdvd.Result[1]], &cdvd.Result[3]); Console::WriteLn("REGION PARAMS = %s %s", params mg_zones[cdvd.Result[1]], &cdvd.Result[3]);
cdvd.Result[1] = 1 << cdvd.Result[1]; //encryption zone; see offset 0x1C in encrypted headers cdvd.Result[1] = 1 << cdvd.Result[1]; //encryption zone; see offset 0x1C in encrypted headers
////////////////////////////////////////// //////////////////////////////////////////
cdvd.Result[2] = 0; //?? cdvd.Result[2] = 0; //??
@ -2063,7 +2062,7 @@ void cdvdWrite16(u8 rt) // SCOMMAND
if (cdvd.mg_buffer[bit_ofs+5] || cdvd.mg_buffer[bit_ofs+6] || cdvd.mg_buffer[bit_ofs+7])goto fail_pol_cal; if (cdvd.mg_buffer[bit_ofs+5] || cdvd.mg_buffer[bit_ofs+6] || cdvd.mg_buffer[bit_ofs+7])goto fail_pol_cal;
if (cdvd.mg_buffer[bit_ofs+4] * 16 + bit_ofs + 8 + 16 != *(u16*)&cdvd.mg_buffer[0x14]){ if (cdvd.mg_buffer[bit_ofs+4] * 16 + bit_ofs + 8 + 16 != *(u16*)&cdvd.mg_buffer[0x14]){
fail_pol_cal: fail_pol_cal:
SysPrintf("[MG] ERROR - Make sure the file is already decrypted!!!\n"); Console::Error("[MG] ERROR - Make sure the file is already decrypted!!!");
cdvd.Result[0] = 0x80; cdvd.Result[0] = 0x80;
break; break;
} }
@ -2074,7 +2073,7 @@ fail_pol_cal:
case 0x90: // sceMgWriteHeaderStart case 0x90: // sceMgWriteHeaderStart
cdvd.mg_size = 0; cdvd.mg_size = 0;
cdvd.mg_datatype = 1;//header data cdvd.mg_datatype = 1;//header data
SysPrintf("[MG] hcode=%d cnum=%d a2=%d length=0x%X\n", Console::WriteLn("[MG] hcode=%d cnum=%d a2=%d length=0x%X", params
cdvd.Param[0], cdvd.Param[3], cdvd.Param[4], cdvd.mg_maxsize = cdvd.Param[1] | (((int)cdvd.Param[2])<<8)); cdvd.Param[0], cdvd.Param[3], cdvd.Param[4], cdvd.mg_maxsize = cdvd.Param[1] | (((int)cdvd.Param[2])<<8));
SetResultSize(1);//in:5 SetResultSize(1);//in:5
cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error
@ -2088,7 +2087,7 @@ fail_pol_cal:
} }
cdvd.mg_maxsize = 0; // don't allow any write cdvd.mg_maxsize = 0; // don't allow any write
cdvd.mg_size = 8+16*cdvd.mg_buffer[4];//new offset, i just moved the data cdvd.mg_size = 8+16*cdvd.mg_buffer[4];//new offset, i just moved the data
SysPrintf("[MG] BIT count=%d\n", cdvd.mg_buffer[4]); Console::WriteLn("[MG] BIT count=%d", params cdvd.mg_buffer[4]);
cdvd.Result[0] = cdvd.mg_datatype==1 ? 0 : 0x80; // 0 complete ; 1 busy ; 0x80 error cdvd.Result[0] = cdvd.mg_datatype==1 ? 0 : 0x80; // 0 complete ; 1 busy ; 0x80 error
cdvd.Result[1] = (cdvd.mg_size >> 0) & 0xFF; cdvd.Result[1] = (cdvd.mg_size >> 0) & 0xFF;
@ -2143,7 +2142,7 @@ fail_pol_cal:
default: default:
// fake a 'correct' command // fake a 'correct' command
SysPrintf("SCMD Unknown %x\n", rt); Console::WriteLn("SCMD Unknown %x", params rt);
SetResultSize(1); //in:0 SetResultSize(1); //in:0
cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error cdvd.Result[0] = 0; // 0 complete ; 1 busy ; 0x80 error
break; break;
@ -2153,7 +2152,7 @@ fail_pol_cal:
} }
void cdvdWrite17(u8 rt) { // SDATAIN void cdvdWrite17(u8 rt) { // SDATAIN
CDR_LOG("cdvdWrite17(SDataIn) %x\n", rt); CDR_LOG("cdvdWrite17(SDataIn) %x", rt);
if (cdvd.ParamP < 32) { if (cdvd.ParamP < 32) {
cdvd.Param[cdvd.ParamP++] = rt; cdvd.Param[cdvd.ParamP++] = rt;
@ -2162,12 +2161,12 @@ void cdvdWrite17(u8 rt) { // SDATAIN
} }
void cdvdWrite18(u8 rt) { // SDATAOUT void cdvdWrite18(u8 rt) { // SDATAOUT
CDR_LOG("cdvdWrite18(SDataOut) %x\n", rt); CDR_LOG("cdvdWrite18(SDataOut) %x", rt);
SysPrintf("*PCSX2* SDATAOUT\n"); Console::WriteLn("*PCSX2* SDATAOUT");
} }
void cdvdWrite3A(u8 rt) { // DEC-SET void cdvdWrite3A(u8 rt) { // DEC-SET
CDR_LOG("cdvdWrite3A(DecSet) %x\n", rt); CDR_LOG("cdvdWrite3A(DecSet) %x", rt);
cdvd.decSet = rt; cdvd.decSet = rt;
SysPrintf("DecSet Write: %02X\n", cdvd.decSet); Console::WriteLn("DecSet Write: %02X", params cdvd.decSet);
} }

View File

@ -295,13 +295,13 @@ int CDVD_findfile(const char* fname, TocEntry* tocEntry){
// Find the TOC for a specific directory // Find the TOC for a specific directory
if (CDVD_GetVolumeDescriptor() != TRUE){ if (CDVD_GetVolumeDescriptor() != TRUE){
RPC_LOG("Could not get CD Volume Descriptor\n"); RPC_LOG("Could not get CD Volume Descriptor");
return -1; return -1;
} }
// Read the TOC of the root directory // Read the TOC of the root directory
if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){ if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){
RPC_LOG("Couldn't Read from CD !\n"); RPC_LOG("Couldn't Read from CD !");
return -1; return -1;
} }
//CdSync(0x00); //CdSync(0x00);
@ -362,7 +362,7 @@ int CDVD_findfile(const char* fname, TocEntry* tocEntry){
current_sector++; current_sector++;
if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE) if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE)
{ {
SysPrintf("Couldn't Read from CD !\n"); Console::Error("Couldn't Read from CD !");
return -1; return -1;
} }
// CdSync(0x00); // CdSync(0x00);
@ -422,7 +422,7 @@ int CDVD_findfile(const char* fname, TocEntry* tocEntry){
tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); tocEntryPointer = (dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length);
} }
RPC_LOG("[RPC:cdvd] findfile: found dir, now looking for file\n"); RPC_LOG("[RPC:cdvd] findfile: found dir, now looking for file");
tocEntryPointer = (dirTocEntry*)toc; tocEntryPointer = (dirTocEntry*)toc;
@ -502,15 +502,15 @@ int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_d
// Find the TOC for a specific directory // Find the TOC for a specific directory
if (CDVD_GetVolumeDescriptor() != TRUE){ if (CDVD_GetVolumeDescriptor() != TRUE){
RPC_LOG("[RPC:cdvd] Could not get CD Volume Descriptor\n"); RPC_LOG("[RPC:cdvd] Could not get CD Volume Descriptor");
return -1; return -1;
} }
RPC_LOG("[RPC:cdvd] Getting Directory Listing for: \"%s\"\n", pathname); RPC_LOG("[RPC:cdvd] Getting Directory Listing for: \"%s\"", pathname);
// Read the TOC of the root directory // Read the TOC of the root directory
if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){ if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){
RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); RPC_LOG("[RPC: ] Couldn't Read from CD !");
return -1; return -1;
} }
//CdSync(0x00); //CdSync(0x00);
@ -551,7 +551,7 @@ int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_d
current_sector++; current_sector++;
if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE){ if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE){
RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); RPC_LOG("[RPC: ] Couldn't Read from CD !");
return -1; return -1;
} }
@ -573,8 +573,8 @@ int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_d
if (strcmp(dirname,localTocEntry.filename) == 0){ if (strcmp(dirname,localTocEntry.filename) == 0){
// if the name matches then we've found the directory // if the name matches then we've found the directory
found_dir = TRUE; found_dir = TRUE;
RPC_LOG("[RPC: ] Found directory %s in subdir at sector %d\n",dirname,current_sector); RPC_LOG("[RPC: ] Found directory %s in subdir at sector %d",dirname,current_sector);
RPC_LOG("[RPC: ] LBA of found subdirectory = %d\n",localTocEntry.fileLBA); RPC_LOG("[RPC: ] LBA of found subdirectory = %d",localTocEntry.fileLBA);
break; break;
} }
@ -593,7 +593,7 @@ int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_d
// Read the TOC of the found subdirectory // Read the TOC of the found subdirectory
if (CdRead(localTocEntry.fileLBA,1,toc,&cdReadMode) != TRUE){ if (CdRead(localTocEntry.fileLBA,1,toc,&cdReadMode) != TRUE){
RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); RPC_LOG("[RPC: ] Couldn't Read from CD !");
return -1; return -1;
} }
//CdSync(0x00); //CdSync(0x00);
@ -645,7 +645,7 @@ int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_d
getDirTocData.current_sector++; getDirTocData.current_sector++;
if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){
RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); RPC_LOG("[RPC: ] Couldn't Read from CD !");
return -1; return -1;
} }
//CdSync(0x00); //CdSync(0x00);
@ -710,7 +710,7 @@ int CDVD_GetDir_RPC_get_entries(TocEntry tocEntry[], int req_entries){
dirTocEntry* tocEntryPointer; dirTocEntry* tocEntryPointer;
if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){
RPC_LOG("[RPC:cdvd] Couldn't Read from CD !\n"); RPC_LOG("[RPC:cdvd] Couldn't Read from CD !");
return -1; return -1;
} }
//CdSync(0x00); //CdSync(0x00);
@ -741,7 +741,7 @@ int CDVD_GetDir_RPC_get_entries(TocEntry tocEntry[], int req_entries){
getDirTocData.current_sector++; getDirTocData.current_sector++;
if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){
RPC_LOG("[RPC:cdvd] Couldn't Read from CD !\n"); RPC_LOG("[RPC:cdvd] Couldn't Read from CD !");
return -1; return -1;
} }
//CdSync(0x00); //CdSync(0x00);

View File

@ -52,9 +52,9 @@ void CDVDFS_init(){
if (inited) return;//might change in the future as a param; forceInit/Reset if (inited) return;//might change in the future as a param; forceInit/Reset
RPC_LOG("[CDVDisodrv:init] CDVD Filesystem v1.00\n"); RPC_LOG("[CDVDisodrv:init] CDVD Filesystem v1.00");
RPC_LOG("[CDVDisodrv ] \tby A.Lee (aka Hiryu) & Nicholas Van Veen (aka Sjeep)\n"); RPC_LOG("[CDVDisodrv ] \tby A.Lee (aka Hiryu) & Nicholas Van Veen (aka Sjeep)");
RPC_LOG("[CDVDisodrv ] Initializing '%s' file driver.\n", "cdfs"); RPC_LOG("[CDVDisodrv ] Initializing '%s' file driver.", "cdfs");
//CdInit(0); already called by plugin loading system ;) //CdInit(0); already called by plugin loading system ;)
@ -92,13 +92,13 @@ int CDVDFS_open(const char *name, int mode){
fd_used[j] = 1; fd_used[j] = 1;
files_open++; files_open++;
RPC_LOG("[CDVDisodrv:open] internal fd=%d\n", j); RPC_LOG("[CDVDisodrv:open] internal fd=%d", j);
fd_table[j].fileSize = tocEntry.fileSize; fd_table[j].fileSize = tocEntry.fileSize;
fd_table[j].LBA = tocEntry.fileLBA; fd_table[j].LBA = tocEntry.fileLBA;
fd_table[j].filePos = 0; fd_table[j].filePos = 0;
RPC_LOG("[CDVDisodrv ] tocEntry.fileSize = %d\n",tocEntry.fileSize); RPC_LOG("[CDVDisodrv ] tocEntry.fileSize = %d",tocEntry.fileSize);
return j; return j;
} }
@ -109,7 +109,7 @@ int CDVDFS_open(const char *name, int mode){
int CDVDFS_lseek(int fd, int offset, int whence){ int CDVDFS_lseek(int fd, int offset, int whence){
if ((fd >= 16) || (fd_used[fd]==0)){ if ((fd >= 16) || (fd_used[fd]==0)){
RPC_LOG("[CDVDisodrv:lseek] ERROR: File does not appear to be open!\n"); RPC_LOG("[CDVDisodrv:lseek] ERROR: File does not appear to be open!");
return -1; return -1;
} }
@ -155,7 +155,7 @@ int CDVDFS_read( int fd, char *buffer, int size ){
int ssize=0, asize, esize; int ssize=0, asize, esize;
if ((fd >= 16) || (fd_used[fd]==0)){ if ((fd >= 16) || (fd_used[fd]==0)){
RPC_LOG("[CDVDisodrv:read] ERROR: File does not appear to be open!\n"); RPC_LOG("[CDVDisodrv:read] ERROR: File does not appear to be open!");
return -1; return -1;
} }
@ -181,22 +181,22 @@ int CDVDFS_read( int fd, char *buffer, int size ){
esector=asector + (asize >> 11); esector=asector + (asize >> 11);
size += ssize; size += ssize;
RPC_LOG("[CDVDisodrv:read] read sectors 0x%08X to 0x%08X\n", ssector, esector-(esize==0)); RPC_LOG("[CDVDisodrv:read] read sectors 0x%08X to 0x%08X", ssector, esector-(esize==0));
if (ssize){ if (ssize){
if (CdRead(ssector, 1, lb, &cdReadMode) != TRUE){ if (CdRead(ssector, 1, lb, &cdReadMode) != TRUE){
RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason\n"); RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason");
return 0; return 0;
} }
memcpy_fast(buffer, lb + off_sector, ssize); memcpy_fast(buffer, lb + off_sector, ssize);
} }
if (asize) if (CdRead(asector, asize >> 11, buffer+ssize, &cdReadMode) != TRUE){ if (asize) if (CdRead(asector, asize >> 11, buffer+ssize, &cdReadMode) != TRUE){
RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason\n"); RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason");
return 0; return 0;
} }
if (esize){ if (esize){
if (CdRead(esector, 1, lb, &cdReadMode) != TRUE){ if (CdRead(esector, 1, lb, &cdReadMode) != TRUE){
RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason\n"); RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason");
return 0; return 0;
} }
memcpy_fast(buffer+ssize+asize, lb, esize); memcpy_fast(buffer+ssize+asize, lb, esize);
@ -207,13 +207,13 @@ int CDVDFS_read( int fd, char *buffer, int size ){
off_sector = (fd_table[fd].filePos & 0x7FF); off_sector = (fd_table[fd].filePos & 0x7FF);
num_sectors = ((off_sector + size) >> 11) + 1; num_sectors = ((off_sector + size) >> 11) + 1;
RPC_LOG("[CDVDisodrv:read] read sectors 0x%08X to 0x%08X\n",start_sector,start_sector+num_sectors); RPC_LOG("[CDVDisodrv:read] read sectors 0x%08X to 0x%08X",start_sector,start_sector+num_sectors);
// Read the data (we only ever get 16KB max request at once) // Read the data (we only ever get 16KB max request at once)
if (CdRead(start_sector, num_sectors, local_buffer, &cdReadMode) != TRUE){ if (CdRead(start_sector, num_sectors, local_buffer, &cdReadMode) != TRUE){
//RPC_LOG("sector = %d, start sector = %d\n",sector,start_sector); //RPC_LOG("sector = %d, start sector = %d",sector,start_sector);
RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason\n"); RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason");
return 0; return 0;
} }
//CdSync(0); hm, a wait function maybe... //CdSync(0); hm, a wait function maybe...
@ -242,10 +242,10 @@ int CDVDFS_write( int fd, char * buffer, int size ){
int CDVDFS_close( int fd){ int CDVDFS_close( int fd){
if ((fd >= 16) || (fd_used[fd]==0)){ if ((fd >= 16) || (fd_used[fd]==0)){
RPC_LOG("[CDVDisodrv:close] ERROR: File does not appear to be open!\n"); RPC_LOG("[CDVDisodrv:close] ERROR: File does not appear to be open!");
return -1; return -1;
} }
RPC_LOG("[CDVDisodrv:close] internal fd %d\n", fd); RPC_LOG("[CDVDisodrv:close] internal fd %d", fd);
fd_used[fd] = 0; fd_used[fd] = 0;
files_open--; files_open--;

View File

@ -25,15 +25,18 @@
u32 s_iLastCOP0Cycle = 0; u32 s_iLastCOP0Cycle = 0;
u32 s_iLastPERFCycle[2] = { 0, 0 }; u32 s_iLastPERFCycle[2] = { 0, 0 };
void UpdateCP0Status() { __releaseinline void UpdateCP0Status() {
u32 value = cpuRegs.CP0.n.Status.val; //currently the 2 memory modes are not implemented. Given this function is called so much,
//it's commented out for now. Only the interrupt test is needed. (rama)
if (value & 0x06 || //u32 value = cpuRegs.CP0.n.Status.val;
(value & 0x18) == 0) { // Kernel Mode (KSU = 0 | EXL = 1 | ERL = 1)*/
memSetKernelMode(); // Kernel memory always //if (value & 0x06 ||
} else { // User Mode // (value & 0x18) == 0) { // Kernel Mode (KSU = 0 | EXL = 1 | ERL = 1)*/
memSetUserMode(); // memSetKernelMode(); // Kernel memory always
} //} else { // User Mode
// memSetUserMode();
//}
cpuTestHwInts(); cpuTestHwInts();
} }
@ -87,7 +90,7 @@ void MapTLB(int i)
void UnmapTLB(int i) void UnmapTLB(int i)
{ {
//SysPrintf("Clear TLB %d: %08x-> [%08x %08x] S=%d G=%d ASID=%d Mask= %03X\n",i,tlb[i].VPN2,tlb[i].PFN0,tlb[i].PFN1,tlb[i].S,tlb[i].G,tlb[i].ASID,tlb[i].Mask); //Console::WriteLn("Clear TLB %d: %08x-> [%08x %08x] S=%d G=%d ASID=%d Mask= %03X", params i,tlb[i].VPN2,tlb[i].PFN0,tlb[i].PFN1,tlb[i].S,tlb[i].G,tlb[i].ASID,tlb[i].Mask);
u32 mask, addr; u32 mask, addr;
u32 saddr, eaddr; u32 saddr, eaddr;
@ -102,7 +105,7 @@ void UnmapTLB(int i)
mask = ((~tlb[i].Mask) << 1) & 0xfffff; mask = ((~tlb[i].Mask) << 1) & 0xfffff;
saddr = tlb[i].VPN2 >> 12; saddr = tlb[i].VPN2 >> 12;
eaddr = saddr + tlb[i].Mask + 1; eaddr = saddr + tlb[i].Mask + 1;
// SysPrintf("Clear TLB: %08x ~ %08x\n",saddr,eaddr-1); // Console::WriteLn("Clear TLB: %08x ~ %08x",params saddr,eaddr-1);
for (addr=saddr; addr<eaddr; addr++) { for (addr=saddr; addr<eaddr; addr++) {
if ((addr & mask) == ((tlb[i].VPN2 >> 12) & mask)) { //match if ((addr & mask) == ((tlb[i].VPN2 >> 12) & mask)) { //match
memClearPageAddr(addr << 12); memClearPageAddr(addr << 12);
@ -115,7 +118,7 @@ void UnmapTLB(int i)
mask = ((~tlb[i].Mask) << 1) & 0xfffff; mask = ((~tlb[i].Mask) << 1) & 0xfffff;
saddr = (tlb[i].VPN2 >> 12) + tlb[i].Mask + 1; saddr = (tlb[i].VPN2 >> 12) + tlb[i].Mask + 1;
eaddr = saddr + tlb[i].Mask + 1; eaddr = saddr + tlb[i].Mask + 1;
// SysPrintf("Clear TLB: %08x ~ %08x\n",saddr,eaddr-1); // Console::WriteLn("Clear TLB: %08x ~ %08x",params saddr,eaddr-1);
for (addr=saddr; addr<eaddr; addr++) { for (addr=saddr; addr<eaddr; addr++) {
if ((addr & mask) == ((tlb[i].VPN2 >> 12) & mask)) { //match if ((addr & mask) == ((tlb[i].VPN2 >> 12) & mask)) { //match
memClearPageAddr(addr << 12); memClearPageAddr(addr << 12);
@ -306,9 +309,9 @@ void MFC0()
{ {
// Note on _Rd_ Condition 9: CP0.Count should be updated even if _Rt_ is 0. // Note on _Rd_ Condition 9: CP0.Count should be updated even if _Rt_ is 0.
if( (_Rd_ != 9) && !_Rt_ ) return; if( (_Rd_ != 9) && !_Rt_ ) return;
if(_Rd_ != 9) { COP0_LOG("%s\n", disR5900Current.getCString() ); } if(_Rd_ != 9) { COP0_LOG("%s", disR5900Current.getCString() ); }
//if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MFC0 _Rd_ %x = %x\n", _Rd_, cpuRegs.CP0.r[_Rd_]); //if(bExecBIOS == FALSE && _Rd_ == 25) Console::WriteLn("MFC0 _Rd_ %x = %x", params _Rd_, cpuRegs.CP0.r[_Rd_]);
switch (_Rd_) switch (_Rd_)
{ {
case 12: case 12:
@ -332,7 +335,7 @@ void MFC0()
cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pcr1; cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pcr1;
break; break;
} }
/*SysPrintf("MFC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x\n", /*Console::WriteLn("MFC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x", params
cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);*/ cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);*/
break; break;
@ -357,11 +360,24 @@ void MFC0()
void MTC0() void MTC0()
{ {
COP0_LOG("%s\n", disR5900Current.getCString()); COP0_LOG("%s\n", disR5900Current.getCString());
//if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MTC0 _Rd_ %x = %x\n", _Rd_, cpuRegs.CP0.r[_Rd_]); //if(bExecBIOS == FALSE && _Rd_ == 25) Console::WriteLn("MTC0 _Rd_ %x = %x", params _Rd_, cpuRegs.CP0.r[_Rd_]);
switch (_Rd_) switch (_Rd_)
{ {
case 9:
s_iLastCOP0Cycle = cpuRegs.cycle;
cpuRegs.CP0.r[9] = cpuRegs.GPR.r[_Rt_].UL[0];
break;
case 12:
WriteCP0Status(cpuRegs.GPR.r[_Rt_].UL[0]);
break;
case 24:
Console::WriteLn("MTC0 Breakpoint debug Registers code = %x", params cpuRegs.code & 0x3FF);
break;
case 25: case 25:
/*if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MTC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x\n", /*if(bExecBIOS == FALSE && _Rd_ == 25) Console::WriteLn("MTC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x", params
cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);*/ cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);*/
switch(_Imm_ & 0x3F) switch(_Imm_ & 0x3F)
{ {
@ -384,16 +400,6 @@ void MTC0()
} }
break; break;
case 24:
Console::WriteLn("MTC0 Breakpoint debug Registers code = %x", params cpuRegs.code & 0x3FF);
break;
case 12: WriteCP0Status(cpuRegs.GPR.r[_Rt_].UL[0]); break;
case 9:
s_iLastCOP0Cycle = cpuRegs.cycle;
cpuRegs.CP0.r[9] = cpuRegs.GPR.r[_Rt_].UL[0];
break;
default: default:
cpuRegs.CP0.r[_Rd_] = cpuRegs.GPR.r[_Rt_].UL[0]; cpuRegs.CP0.r[_Rd_] = cpuRegs.GPR.r[_Rt_].UL[0];
break; break;

View File

@ -48,7 +48,7 @@ void BC2F()
{ {
if (CP2COND == 0) if (CP2COND == 0)
{ {
SysPrintf("VU0 Macro Branch \n"); Console::WriteLn("VU0 Macro Branch");
intDoBranch(_BranchTarget_); intDoBranch(_BranchTarget_);
} }
} }
@ -56,7 +56,7 @@ void BC2T()
{ {
if (CP2COND == 1) if (CP2COND == 1)
{ {
SysPrintf("VU0 Macro Branch \n"); Console::WriteLn("VU0 Macro Branch");
intDoBranch(_BranchTarget_); intDoBranch(_BranchTarget_);
} }
} }
@ -65,7 +65,7 @@ void BC2FL()
{ {
if (CP2COND == 0) if (CP2COND == 0)
{ {
SysPrintf("VU0 Macro Branch \n"); Console::WriteLn("VU0 Macro Branch");
intDoBranch(_BranchTarget_); intDoBranch(_BranchTarget_);
} }
else else
@ -77,7 +77,7 @@ void BC2TL()
{ {
if (CP2COND == 1) if (CP2COND == 1)
{ {
SysPrintf("VU0 Macro Branch \n"); Console::WriteLn("VU0 Macro Branch");
intDoBranch(_BranchTarget_); intDoBranch(_BranchTarget_);
} }
else else

View File

@ -101,7 +101,7 @@ void writeCache8(u32 mem, u8 value) {
int i, number; int i, number;
i = getFreeCache(mem,1,&number); i = getFreeCache(mem,1,&number);
// CACHE_LOG("writeCache8 %8.8x adding to %d, way %d, value %x\n", mem, i,number,value); // CACHE_LOG("writeCache8 %8.8x adding to %d, way %d, value %x", mem, i,number,value);
pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)] = value; pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)] = value;
} }
@ -110,7 +110,7 @@ void writeCache16(u32 mem, u16 value) {
int i, number; int i, number;
i = getFreeCache(mem,1,&number); i = getFreeCache(mem,1,&number);
// CACHE_LOG("writeCache16 %8.8x adding to %d, way %d, value %x\n", mem, i,number,value); // CACHE_LOG("writeCache16 %8.8x adding to %d, way %d, value %x", mem, i,number,value);
*(u16*)(&pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)]) = value; *(u16*)(&pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)]) = value;
} }
@ -119,7 +119,7 @@ void writeCache32(u32 mem, u32 value) {
int i, number; int i, number;
i = getFreeCache(mem,1,&number); i = getFreeCache(mem,1,&number);
// CACHE_LOG("writeCache32 %8.8x adding to %d, way %d, value %x\n", mem, i,number,value); // CACHE_LOG("writeCache32 %8.8x adding to %d, way %d, value %x", mem, i,number,value);
*(u32*)(&pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)]) = value; *(u32*)(&pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)]) = value;
} }
@ -127,7 +127,7 @@ void writeCache64(u32 mem, u64 value) {
int i, number; int i, number;
i = getFreeCache(mem,1,&number); i = getFreeCache(mem,1,&number);
// CACHE_LOG("writeCache64 %8.8x adding to %d, way %d, value %x\n", mem, i,number,value); // CACHE_LOG("writeCache64 %8.8x adding to %d, way %d, value %x", mem, i,number,value);
*(u64*)(&pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)]) = value; *(u64*)(&pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)]) = value;
} }
@ -135,7 +135,7 @@ void writeCache128(u32 mem, u64 *value) {
int i, number; int i, number;
i = getFreeCache(mem,1,&number); i = getFreeCache(mem,1,&number);
// CACHE_LOG("writeCache128 %8.8x adding to %d\n", mem, i); // CACHE_LOG("writeCache128 %8.8x adding to %d", mem, i);
((u64*)pCache[i].data[number][(mem>>4) & 0x3].b8._8)[0] = value[0]; ((u64*)pCache[i].data[number][(mem>>4) & 0x3].b8._8)[0] = value[0];
((u64*)pCache[i].data[number][(mem>>4) & 0x3].b8._8)[1] = value[1]; ((u64*)pCache[i].data[number][(mem>>4) & 0x3].b8._8)[1] = value[1];
} }
@ -144,7 +144,7 @@ u8 *readCache(u32 mem) {
int i, number; int i, number;
i = getFreeCache(mem,0,&number); i = getFreeCache(mem,0,&number);
// CACHE_LOG("readCache %8.8x from %d, way %d\n", mem, i,number); // CACHE_LOG("readCache %8.8x from %d, way %d", mem, i,number);
return pCache[i].data[number][(mem>>4) & 0x3].b8._8; return pCache[i].data[number][(mem>>4) & 0x3].b8._8;
} }
@ -180,7 +180,7 @@ void CACHE() {
return; return;
} }
CACHE_LOG("CACHE DHIN addr %x, index %d, way %d, Flags %x\n",addr,index,way,pCache[index].tag[way] & 0x78); CACHE_LOG("CACHE DHIN addr %x, index %d, way %d, Flags %x",addr,index,way,pCache[index].tag[way] & 0x78);
pCache[index].tag[way] &= ~(0x6F); pCache[index].tag[way] &= ~(0x6F);
((u64*)pCache[index].data[way][0].b8._8)[0] = 0; ((u64*)pCache[index].data[way][0].b8._8)[0] = 0;
@ -216,7 +216,7 @@ void CACHE() {
return; return;
} }
CACHE_LOG("CACHE DHWBIN addr %x, index %d, way %d, Flags %x\n",addr,index,way,pCache[index].tag[way] & 0x78); CACHE_LOG("CACHE DHWBIN addr %x, index %d, way %d, Flags %x",addr,index,way,pCache[index].tag[way] & 0x78);
if(pCache[index].tag[way] & 0x60) // Valid Dirty if(pCache[index].tag[way] & 0x60) // Valid Dirty
{ {
@ -266,7 +266,7 @@ void CACHE() {
{ {
return; return;
} }
CACHE_LOG("CACHE DHWOIN addr %x, index %d, way %d, Flags %x\n",addr,index,way,pCache[index].tag[way] & 0x78); CACHE_LOG("CACHE DHWOIN addr %x, index %d, way %d, Flags %x",addr,index,way,pCache[index].tag[way] & 0x78);
if(pCache[index].tag[way] & 0x60) // Valid Dirty if(pCache[index].tag[way] & 0x60) // Valid Dirty
{ {
@ -311,7 +311,7 @@ void CACHE() {
u8 * out = pCache[index].data[way][(addr>>4) & 0x3].b8._8; u8 * out = pCache[index].data[way][(addr>>4) & 0x3].b8._8;
cpuRegs.CP0.r[28] = *(u32 *)(out+(addr&0xf)); cpuRegs.CP0.r[28] = *(u32 *)(out+(addr&0xf));
CACHE_LOG("CACHE DXLDT addr %x, index %d, way %d, DATA %x\n",addr,index,way,cpuRegs.CP0.r[28]); CACHE_LOG("CACHE DXLDT addr %x, index %d, way %d, DATA %x",addr,index,way,cpuRegs.CP0.r[28]);
break; break;
} }
@ -323,7 +323,7 @@ void CACHE() {
cpuRegs.CP0.r[28] = 0; cpuRegs.CP0.r[28] = 0;
cpuRegs.CP0.r[28] = pCache[index].tag[way]; cpuRegs.CP0.r[28] = pCache[index].tag[way];
CACHE_LOG("CACHE DXLTG addr %x, index %d, way %d, DATA %x\n",addr,index,way,cpuRegs.CP0.r[28]); CACHE_LOG("CACHE DXLTG addr %x, index %d, way %d, DATA %x",addr,index,way,cpuRegs.CP0.r[28]);
break; break;
} }
@ -334,7 +334,7 @@ void CACHE() {
//u8 * out = pCache[index].data[way][(addr>>4) & 0x3].b8._8; //u8 * out = pCache[index].data[way][(addr>>4) & 0x3].b8._8;
*(u32*)(&pCache[index].data[way][(addr>>4) & 0x3].b8._8[(addr&0xf)]) = cpuRegs.CP0.r[28]; *(u32*)(&pCache[index].data[way][(addr>>4) & 0x3].b8._8[(addr&0xf)]) = cpuRegs.CP0.r[28];
CACHE_LOG("CACHE DXSDT addr %x, index %d, way %d, DATA %x\n",addr,index,way,cpuRegs.CP0.r[28]); CACHE_LOG("CACHE DXSDT addr %x, index %d, way %d, DATA %x",addr,index,way,cpuRegs.CP0.r[28]);
break; break;
} }
@ -344,7 +344,7 @@ void CACHE() {
int way = addr & 0x1; int way = addr & 0x1;
pCache[index].tag[way] = cpuRegs.CP0.r[28]; pCache[index].tag[way] = cpuRegs.CP0.r[28];
CACHE_LOG("CACHE DXSTG addr %x, index %d, way %d, DATA %x\n",addr,index,way,cpuRegs.CP0.r[28] & 0x6F); CACHE_LOG("CACHE DXSTG addr %x, index %d, way %d, DATA %x",addr,index,way,cpuRegs.CP0.r[28] & 0x6F);
break; break;
} }
@ -356,7 +356,7 @@ void CACHE() {
int way = addr & 0x1; int way = addr & 0x1;
CACHE_LOG("CACHE DXWBIN addr %x, index %d, way %d, Flags %x\n",addr,index,way,pCache[index].tag[way] & 0x78); CACHE_LOG("CACHE DXWBIN addr %x, index %d, way %d, Flags %x",addr,index,way,pCache[index].tag[way] & 0x78);
if(pCache[index].tag[way] & 0x60) // Dirty if(pCache[index].tag[way] & 0x60) // Dirty
{ {

View File

@ -140,7 +140,7 @@ void ReadTrack() {
cdr.Prev[1] = itob(cdr.SetSector[1]); cdr.Prev[1] = itob(cdr.SetSector[1]);
cdr.Prev[2] = itob(cdr.SetSector[2]); cdr.Prev[2] = itob(cdr.SetSector[2]);
CDR_LOG("KEY *** %x:%x:%x\n", cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]); CDR_LOG("KEY *** %x:%x:%x", cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]);
cdr.RErr = CDVDreadTrack(MSFtoLSN(cdr.SetSector), CDVD_MODE_2352); cdr.RErr = CDVDreadTrack(MSFtoLSN(cdr.SetSector), CDVD_MODE_2352);
} }
@ -529,7 +529,7 @@ void cdrReadInterrupt() {
memcpy_fast(cdr.Transfer, buf+12, 2340); memcpy_fast(cdr.Transfer, buf+12, 2340);
cdr.Stat = DataReady; cdr.Stat = DataReady;
CDR_LOG(" %x:%x:%x\n", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); CDR_LOG(" %x:%x:%x", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]);
cdr.SetSector[2]++; cdr.SetSector[2]++;
@ -545,7 +545,7 @@ void cdrReadInterrupt() {
cdr.Readed = 0; cdr.Readed = 0;
if ((cdr.Transfer[4+2] & 0x80) && (cdr.Mode & 0x2)) { // EOF if ((cdr.Transfer[4+2] & 0x80) && (cdr.Mode & 0x2)) { // EOF
CDR_LOG("AutoPausing Read\n"); CDR_LOG("AutoPausing Read");
AddIrqQueue(CdlPause, 0x800); AddIrqQueue(CdlPause, 0x800);
} }
else { else {
@ -583,7 +583,7 @@ u8 cdrRead0(void) {
// what means the 0x10 and the 0x08 bits? i only saw it used by the bios // what means the 0x10 and the 0x08 bits? i only saw it used by the bios
cdr.Ctrl|=0x18; cdr.Ctrl|=0x18;
CDR_LOG("CD0 Read: %x\n", cdr.Ctrl); CDR_LOG("CD0 Read: %x", cdr.Ctrl);
return psxHu8(0x1800) = cdr.Ctrl; return psxHu8(0x1800) = cdr.Ctrl;
} }
@ -593,7 +593,7 @@ cdrWrite0:
*/ */
void cdrWrite0(u8 rt) { void cdrWrite0(u8 rt) {
CDR_LOG("CD0 write: %x\n", rt); CDR_LOG("CD0 write: %x", rt);
cdr.Ctrl = rt | (cdr.Ctrl & ~0x3); cdr.Ctrl = rt | (cdr.Ctrl & ~0x3);
@ -612,14 +612,14 @@ u8 cdrRead1(void) {
else else
psxHu8(0x1801) = 0; psxHu8(0x1801) = 0;
CDR_LOG("CD1 Read: %x\n", psxHu8(0x1801)); CDR_LOG("CD1 Read: %x", psxHu8(0x1801));
return psxHu8(0x1801); return psxHu8(0x1801);
} }
void cdrWrite1(u8 rt) { void cdrWrite1(u8 rt) {
int i; int i;
CDR_LOG("CD1 write: %x (%s)\n", rt, CmdName[rt]); CDR_LOG("CD1 write: %x (%s)", rt, CmdName[rt]);
cdr.Cmd = rt; cdr.Cmd = rt;
cdr.OCUP = 0; cdr.OCUP = 0;
@ -744,7 +744,7 @@ void cdrWrite1(u8 rt) {
break; break;
case CdlSetmode: case CdlSetmode:
CDR_LOG("Setmode %x\n", cdr.Param[0]); CDR_LOG("Setmode %x", cdr.Param[0]);
cdr.Mode = cdr.Param[0]; cdr.Mode = cdr.Param[0];
cdr.Ctrl|= 0x80; cdr.Ctrl|= 0x80;
@ -839,12 +839,12 @@ u8 cdrRead2(void) {
ret = *cdr.pTransfer++; ret = *cdr.pTransfer++;
} }
CDR_LOG("CD2 Read: %x\n", ret); CDR_LOG("CD2 Read: %x", ret);
return ret; return ret;
} }
void cdrWrite2(u8 rt) { void cdrWrite2(u8 rt) {
CDR_LOG("CD2 write: %x\n", rt); CDR_LOG("CD2 write: %x", rt);
if (cdr.Ctrl & 0x1) { if (cdr.Ctrl & 0x1) {
switch (rt) { switch (rt) {
@ -877,12 +877,12 @@ u8 cdrRead3(void) {
psxHu8(0x1803) = 0xff; psxHu8(0x1803) = 0xff;
} else psxHu8(0x1803) = 0; } else psxHu8(0x1803) = 0;
CDR_LOG("CD3 Read: %x\n", psxHu8(0x1803)); CDR_LOG("CD3 Read: %x", psxHu8(0x1803));
return psxHu8(0x1803); return psxHu8(0x1803);
} }
void cdrWrite3(u8 rt) { void cdrWrite3(u8 rt) {
CDR_LOG("CD3 write: %x\n", rt); CDR_LOG("CD3 write: %x", rt);
if (rt == 0x07 && cdr.Ctrl & 0x1) { if (rt == 0x07 && cdr.Ctrl & 0x1) {
cdr.Stat = 0; cdr.Stat = 0;
@ -909,13 +909,13 @@ void cdrWrite3(u8 rt) {
void psxDma3(u32 madr, u32 bcr, u32 chcr) { void psxDma3(u32 madr, u32 bcr, u32 chcr) {
u32 cdsize; u32 cdsize;
CDR_LOG("*** DMA 3 *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); CDR_LOG("*** DMA 3 *** %lx addr = %lx size = %lx", chcr, madr, bcr);
switch (chcr) { switch (chcr) {
case 0x11000000: case 0x11000000:
case 0x11400100: case 0x11400100:
if (cdr.Readed == 0) { if (cdr.Readed == 0) {
CDR_LOG("*** DMA 3 *** NOT READY\n"); CDR_LOG("*** DMA 3 *** NOT READY");
return; return;
} }
@ -930,7 +930,7 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
return; return;
default: default:
CDR_LOG("Unknown cddma %lx\n", chcr); CDR_LOG("Unknown cddma %lx", chcr);
break; break;
} }
HW_DMA3_CHCR &= ~0x01000000; HW_DMA3_CHCR &= ~0x01000000;

View File

@ -327,7 +327,7 @@ static __forceinline void frameLimit()
static __forceinline void VSyncStart(u32 sCycle) static __forceinline void VSyncStart(u32 sCycle)
{ {
EECNT_LOG( "///////// EE COUNTER VSYNC START \\\\\\\\\\\\\\\\\\\\ (frame: %d)\n", iFrame ); EECNT_LOG( "///////// EE COUNTER VSYNC START \\\\\\\\\\\\\\\\\\\\ (frame: %d)", iFrame );
vSyncDebugStuff( iFrame ); // EE Profiling and Debug code vSyncDebugStuff( iFrame ); // EE Profiling and Debug code
if ((CSRw & 0x8)) GSCSRr|= 0x8; if ((CSRw & 0x8)) GSCSRr|= 0x8;
@ -361,7 +361,7 @@ static __forceinline void VSyncStart(u32 sCycle)
static __forceinline void VSyncEnd(u32 sCycle) static __forceinline void VSyncEnd(u32 sCycle)
{ {
EECNT_LOG( "///////// EE COUNTER VSYNC END \\\\\\\\\\\\\\\\\\\\ (frame: %d)\n", iFrame ); EECNT_LOG( "///////// EE COUNTER VSYNC END \\\\\\\\\\\\\\\\\\\\ (frame: %d)", iFrame );
iFrame++; iFrame++;
@ -456,7 +456,7 @@ __forceinline bool rcntUpdate_vSync()
if( vblankinc > 1 ) if( vblankinc > 1 )
{ {
if( hsc != vSyncInfo.hScanlinesPerFrame ) if( hsc != vSyncInfo.hScanlinesPerFrame )
SysPrintf( " ** vSync > Abnormal Scanline Count: %d\n", hsc ); Console::WriteLn( " ** vSync > Abnormal Scanline Count: %d", params hsc );
hsc = 0; hsc = 0;
vblankinc = 0; vblankinc = 0;
} }
@ -471,7 +471,7 @@ static __forceinline void __fastcall _cpuTestTarget( int i )
if(counters[i].mode.TargetInterrupt) { if(counters[i].mode.TargetInterrupt) {
EECNT_LOG("EE Counter[%d] TARGET reached - mode=%x, count=%x, target=%x\n", i, counters[i].mode, counters[i].count, counters[i].target); EECNT_LOG("EE Counter[%d] TARGET reached - mode=%x, count=%x, target=%x", i, counters[i].mode, counters[i].count, counters[i].target);
counters[i].mode.TargetReached = 1; counters[i].mode.TargetReached = 1;
hwIntcIrq(counters[i].interrupt); hwIntcIrq(counters[i].interrupt);
@ -489,7 +489,7 @@ static __forceinline void _cpuTestOverflow( int i )
if (counters[i].count <= 0xffff) return; if (counters[i].count <= 0xffff) return;
if (counters[i].mode.OverflowInterrupt) { if (counters[i].mode.OverflowInterrupt) {
EECNT_LOG("EE Counter[%d] OVERFLOW - mode=%x, count=%x\n", i, counters[i].mode, counters[i].count); EECNT_LOG("EE Counter[%d] OVERFLOW - mode=%x, count=%x", i, counters[i].mode, counters[i].count);
counters[i].mode.OverflowReached = 1; counters[i].mode.OverflowReached = 1;
hwIntcIrq(counters[i].interrupt); hwIntcIrq(counters[i].interrupt);
} }
@ -547,7 +547,7 @@ static void _rcntSetGate( int index )
if( !(counters[index].mode.GateSource == 0 && counters[index].mode.ClockSource == 3) ) if( !(counters[index].mode.GateSource == 0 && counters[index].mode.ClockSource == 3) )
{ {
EECNT_LOG( "EE Counter[%d] Using Gate! Source=%s, Mode=%d.\n", EECNT_LOG( "EE Counter[%d] Using Gate! Source=%s, Mode=%d.",
index, counters[index].mode.GateSource ? "vblank" : "hblank", counters[index].mode.GateMode ); index, counters[index].mode.GateSource ? "vblank" : "hblank", counters[index].mode.GateMode );
gates |= (1<<index); gates |= (1<<index);
@ -556,7 +556,7 @@ static void _rcntSetGate( int index )
return; return;
} }
else else
EECNT_LOG( "EE Counter[%d] GATE DISABLED because of hblank source.\n", index ); EECNT_LOG( "EE Counter[%d] GATE DISABLED because of hblank source.", index );
} }
gates &= ~(1<<index); gates &= ~(1<<index);
@ -595,7 +595,7 @@ void __fastcall rcntStartGate(bool isVblank, u32 sCycle)
counters[i].mode.IsCounting = 1; counters[i].mode.IsCounting = 1;
counters[i].sCycleT = sCycle; counters[i].sCycleT = sCycle;
EECNT_LOG("EE Counter[%d] %s StartGate Type0, count = %x\n", EECNT_LOG("EE Counter[%d] %s StartGate Type0, count = %x",
isVblank ? "vblank" : "hblank", i, counters[i].count ); isVblank ? "vblank" : "hblank", i, counters[i].count );
break; break;
@ -609,7 +609,7 @@ void __fastcall rcntStartGate(bool isVblank, u32 sCycle)
counters[i].count = 0; counters[i].count = 0;
counters[i].target &= 0xffff; counters[i].target &= 0xffff;
counters[i].sCycleT = sCycle; counters[i].sCycleT = sCycle;
EECNT_LOG("EE Counter[%d] %s StartGate Type%d, count = %x\n", EECNT_LOG("EE Counter[%d] %s StartGate Type%d, count = %x",
isVblank ? "vblank" : "hblank", i, counters[i].mode.GateMode, counters[i].count ); isVblank ? "vblank" : "hblank", i, counters[i].mode.GateMode, counters[i].count );
break; break;
} }
@ -642,7 +642,7 @@ void __fastcall rcntEndGate(bool isVblank , u32 sCycle)
counters[i].count = rcntRcount(i); counters[i].count = rcntRcount(i);
counters[i].mode.IsCounting = 0; counters[i].mode.IsCounting = 0;
counters[i].sCycleT = sCycle; counters[i].sCycleT = sCycle;
EECNT_LOG("EE Counter[%d] %s EndGate Type0, count = %x\n", EECNT_LOG("EE Counter[%d] %s EndGate Type0, count = %x",
isVblank ? "vblank" : "hblank", i, counters[i].count ); isVblank ? "vblank" : "hblank", i, counters[i].count );
break; break;
@ -656,7 +656,7 @@ void __fastcall rcntEndGate(bool isVblank , u32 sCycle)
counters[i].count = 0; counters[i].count = 0;
counters[i].target &= 0xffff; counters[i].target &= 0xffff;
counters[i].sCycleT = sCycle; counters[i].sCycleT = sCycle;
EECNT_LOG("EE Counter[%d] %s EndGate Type%d, count = %x\n", EECNT_LOG("EE Counter[%d] %s EndGate Type%d, count = %x",
isVblank ? "vblank" : "hblank", i, counters[i].mode.GateMode, counters[i].count ); isVblank ? "vblank" : "hblank", i, counters[i].mode.GateMode, counters[i].count );
break; break;
} }
@ -683,7 +683,7 @@ void __fastcall rcntWmode(int index, u32 value)
counters[index].modeval &= ~(value & 0xc00); //Clear status flags, the ps2 only clears what is given in the value counters[index].modeval &= ~(value & 0xc00); //Clear status flags, the ps2 only clears what is given in the value
counters[index].modeval = (counters[index].modeval & 0xc00) | (value & 0x3ff); counters[index].modeval = (counters[index].modeval & 0xc00) | (value & 0x3ff);
EECNT_LOG("EE Counter[%d] writeMode = %x passed value=%x\n", index, counters[index].modeval, value ); EECNT_LOG("EE Counter[%d] writeMode = %x passed value=%x", index, counters[index].modeval, value );
switch (counters[index].mode.ClockSource) { //Clock rate divisers *2, they use BUSCLK speed not PS2CLK switch (counters[index].mode.ClockSource) { //Clock rate divisers *2, they use BUSCLK speed not PS2CLK
case 0: counters[index].rate = 2; break; case 0: counters[index].rate = 2; break;
@ -698,7 +698,7 @@ void __fastcall rcntWmode(int index, u32 value)
void __fastcall rcntWcount(int index, u32 value) void __fastcall rcntWcount(int index, u32 value)
{ {
EECNT_LOG("EE Counter[%d] writeCount = %x, oldcount=%x, target=%x\n", index, value, counters[index].count, counters[index].target ); EECNT_LOG("EE Counter[%d] writeCount = %x, oldcount=%x, target=%x", index, value, counters[index].count, counters[index].target );
counters[index].count = value & 0xffff; counters[index].count = value & 0xffff;
@ -724,7 +724,7 @@ void __fastcall rcntWcount(int index, u32 value)
void __fastcall rcntWtarget(int index, u32 value) void __fastcall rcntWtarget(int index, u32 value)
{ {
EECNT_LOG("EE Counter[%d] writeTarget = %x\n", index, value); EECNT_LOG("EE Counter[%d] writeTarget = %x", index, value);
counters[index].target = value & 0xffff; counters[index].target = value & 0xffff;
@ -740,7 +740,7 @@ void __fastcall rcntWtarget(int index, u32 value)
void __fastcall rcntWhold(int index, u32 value) void __fastcall rcntWhold(int index, u32 value)
{ {
EECNT_LOG("EE Counter[%d] Hold Write = %x\n", index, value); EECNT_LOG("EE Counter[%d] Hold Write = %x", index, value);
counters[index].hold = value; counters[index].hold = value;
} }
@ -754,7 +754,8 @@ u32 __fastcall rcntRcount(int index)
else else
ret = counters[index].count; ret = counters[index].count;
EECNT_LOG("EE Counter[%d] readCount32 = %x\n", index, ret); // Spams the Console.
EECNT_LOG("EE Counter[%d] readCount32 = %x", index, ret);
return ret; return ret;
} }

View File

@ -278,17 +278,17 @@ struct ElfObject
} }
ELF_LOG("\n"); ELF_LOG("\n");
ELF_LOG("version: %d\n",header.e_version); ELF_LOG("version: %d",header.e_version);
ELF_LOG("entry: %08x\n",header.e_entry); ELF_LOG("entry: %08x",header.e_entry);
ELF_LOG("flags: %08x\n",header.e_flags); ELF_LOG("flags: %08x",header.e_flags);
ELF_LOG("eh size: %08x\n",header.e_ehsize); ELF_LOG("eh size: %08x",header.e_ehsize);
ELF_LOG("ph off: %08x\n",header.e_phoff); ELF_LOG("ph off: %08x",header.e_phoff);
ELF_LOG("ph entsiz: %08x\n",header.e_phentsize); ELF_LOG("ph entsiz: %08x",header.e_phentsize);
ELF_LOG("ph num: %08x\n",header.e_phnum); ELF_LOG("ph num: %08x",header.e_phnum);
ELF_LOG("sh off: %08x\n",header.e_shoff); ELF_LOG("sh off: %08x",header.e_shoff);
ELF_LOG("sh entsiz: %08x\n",header.e_shentsize); ELF_LOG("sh entsiz: %08x",header.e_shentsize);
ELF_LOG("sh num: %08x\n",header.e_shnum); ELF_LOG("sh num: %08x",header.e_shnum);
ELF_LOG("sh strndx: %08x\n",header.e_shstrndx); ELF_LOG("sh strndx: %08x",header.e_shstrndx);
ELF_LOG("\n"); ELF_LOG("\n");
} }
@ -341,7 +341,7 @@ struct ElfObject
for( int i = 0 ; i < header.e_phnum ; i++ ) for( int i = 0 ; i < header.e_phnum ; i++ )
{ {
ELF_LOG( "Elf32 Program Header\n" ); ELF_LOG( "Elf32 Program Header" );
ELF_LOG( "type: " ); ELF_LOG( "type: " );
switch ( proghead[ i ].p_type ) { switch ( proghead[ i ].p_type ) {
@ -379,13 +379,13 @@ struct ElfObject
} }
ELF_LOG("\n"); ELF_LOG("\n");
ELF_LOG("offset: %08x\n",(int)proghead[i].p_offset); ELF_LOG("offset: %08x",(int)proghead[i].p_offset);
ELF_LOG("vaddr: %08x\n",(int)proghead[i].p_vaddr); ELF_LOG("vaddr: %08x",(int)proghead[i].p_vaddr);
ELF_LOG("paddr: %08x\n",proghead[i].p_paddr); ELF_LOG("paddr: %08x",proghead[i].p_paddr);
ELF_LOG("file size: %08x\n",proghead[i].p_filesz); ELF_LOG("file size: %08x",proghead[i].p_filesz);
ELF_LOG("mem size: %08x\n",proghead[i].p_memsz); ELF_LOG("mem size: %08x",proghead[i].p_memsz);
ELF_LOG("flags: %08x\n",proghead[i].p_flags); ELF_LOG("flags: %08x",proghead[i].p_flags);
ELF_LOG("palign: %08x\n",proghead[i].p_align); ELF_LOG("palign: %08x",proghead[i].p_align);
ELF_LOG("\n"); ELF_LOG("\n");
} }
} }
@ -424,14 +424,14 @@ struct ElfObject
} }
ELF_LOG("\n"); ELF_LOG("\n");
ELF_LOG("flags: %08x\n", secthead[i].sh_flags); ELF_LOG("flags: %08x", secthead[i].sh_flags);
ELF_LOG("addr: %08x\n", secthead[i].sh_addr); ELF_LOG("addr: %08x", secthead[i].sh_addr);
ELF_LOG("offset: %08x\n", secthead[i].sh_offset); ELF_LOG("offset: %08x", secthead[i].sh_offset);
ELF_LOG("size: %08x\n", secthead[i].sh_size); ELF_LOG("size: %08x", secthead[i].sh_size);
ELF_LOG("link: %08x\n", secthead[i].sh_link); ELF_LOG("link: %08x", secthead[i].sh_link);
ELF_LOG("info: %08x\n", secthead[i].sh_info); ELF_LOG("info: %08x", secthead[i].sh_info);
ELF_LOG("addralign: %08x\n", secthead[i].sh_addralign); ELF_LOG("addralign: %08x", secthead[i].sh_addralign);
ELF_LOG("entsize: %08x\n", secthead[i].sh_entsize); ELF_LOG("entsize: %08x", secthead[i].sh_entsize);
// dump symbol table // dump symbol table
if( secthead[ i ].sh_type == 0x02 ) if( secthead[ i ].sh_type == 0x02 )
@ -548,7 +548,7 @@ int loadElfFile(const char *filename)
elfobj.loadSectionHeaders(); elfobj.loadSectionHeaders();
cpuRegs.pc = elfobj.header.e_entry; //set pc to proper place cpuRegs.pc = elfobj.header.e_entry; //set pc to proper place
ELF_LOG( "PC set to: %8.8lx\n", cpuRegs.pc ); ELF_LOG( "PC set to: %8.8lx", cpuRegs.pc );
cpuRegs.GPR.n.sp.UL[0] = 0x81f00000; cpuRegs.GPR.n.sp.UL[0] = 0x81f00000;
cpuRegs.GPR.n.gp.UL[0] = 0x81f80000; // might not be 100% ok cpuRegs.GPR.n.gp.UL[0] = 0x81f80000; // might not be 100% ok
@ -562,7 +562,7 @@ int loadElfFile(const char *filename)
} }
ElfCRC = elfobj.GetCRC(); ElfCRC = elfobj.GetCRC();
Console::Status( "loadElfFile: %s; CRC = %8.8X\n", params filename, ElfCRC); Console::Status( "loadElfFile: %s; CRC = %8.8X", params filename, ElfCRC);
ElfApplyPatches(); ElfApplyPatches();
LoadGameSpecificSettings(); LoadGameSpecificSettings();
@ -571,8 +571,7 @@ int loadElfFile(const char *filename)
} }
#include "VU.h" #include "VU.h"
extern int g_FFXHack; extern bool path3hack;
extern int path3hack;
int g_VUGameFixes = 0; int g_VUGameFixes = 0;
// fixme - this should be moved to patches or eliminated // fixme - this should be moved to patches or eliminated
@ -580,42 +579,14 @@ void LoadGameSpecificSettings()
{ {
// default // default
g_VUGameFixes = 0; g_VUGameFixes = 0;
g_FFXHack = 0;
switch(ElfCRC) { switch(ElfCRC) {
case 0xb99379b7: // erementar gerad (discolored chars) case 0xb99379b7: // erementar gerad (discolored chars)
g_VUGameFixes |= VUFIX_XGKICKDELAY2; // Tested - still needed - arcum42 g_VUGameFixes |= VUFIX_XGKICKDELAY2; // Tested - still needed - arcum42
break; break;
case 0xa08c4057: //Sprint Cars (SLUS) //case 0xa08c4057: //Sprint Cars (SLUS)
case 0x8b0725d5: //Flinstones Bedrock Racing (SLES) //case 0x8b0725d5: //Flinstones Bedrock Racing (SLES)
path3hack = 1; // We can move this to patch files right now //path3hack = TRUE; // We can move this to patch files right now
break; //break;
case 0xb4414ea1: // ffx(rus)
case 0xee97db5b: // ffx(rus)
case 0xaec495cc: // ffx(rus)
case 0x6a4efe60: // ffx(j)
case 0xA39517AB: // ffx(e)
case 0xBB3D833A: // ffx(u)
case 0x941bb7d9: // ffx(g)
case 0xD9FC6310: // ffx int(j)
case 0xa39517ae: // ffx(f)
case 0xa39517a9: // ffx(i)
case 0x658597e2: // ffx int
case 0x941BB7DE: // ffx(s)
case 0x3866CA7E: // ffx(asia)
case 0x48FE0C71: // ffx2 (u)
case 0x9aac530d: // ffx2 (g)
case 0x9AAC5309: // ffx2 (e)
case 0x8A6D7F14: // ffx2 (j)
case 0x9AAC530B: // ffx2 (i)
case 0x9AAC530A: // ffx2 (f)
case 0x9aac530c: // ffx2 (f)
case 0xe1fd9a2d: // ffx2 last mission (?)
case 0x93f9b89a: // ffx2 demo (g)
case 0x304C115C: // harvest moon - awl
case 0xF0A6D880: // harvest moon - sth
g_FFXHack = 1;
break;
} }
} }

View File

@ -74,7 +74,17 @@ namespace Exception
virtual ~BaseException() throw()=0; // the =0; syntax forces this class into "abstract" mode. virtual ~BaseException() throw()=0; // the =0; syntax forces this class into "abstract" mode.
explicit BaseException( const std::string& msg="Unhandled exception." ) : explicit BaseException( const std::string& msg="Unhandled exception." ) :
m_message( msg ) m_message( msg )
{} {
// Major hack. After a couple of tries, I'm still not managing to get Linux to catch these exceptions, so that the user actually
// gets the messages. Since Console is unavailable at this level, I'm using a simple printf, which of course, means it doesn't get
// logged. But at least the user sees it.
//
// I'll rip this out once I get Linux to actually catch these exceptions. Say, in BeginExecution or StartGui, like I would expect.
// -- arcum42
#ifdef __LINUX__
printf(msg.c_str());
#endif
}
const std::string& Message() const { return m_message; } const std::string& Message() const { return m_message; }
const char* cMessage() const { return m_message.c_str(); } const char* cMessage() const { return m_message.c_str(); }

View File

@ -83,7 +83,7 @@ using namespace std; // for min / max
// If we have an infinity value, then Overflow has occured. // If we have an infinity value, then Overflow has occured.
#define checkOverflow(xReg, cFlagsToSet, shouldReturn) { \ #define checkOverflow(xReg, cFlagsToSet, shouldReturn) { \
if ( ( xReg & ~0x80000000 ) == PosInfinity ) { \ if ( ( xReg & ~0x80000000 ) == PosInfinity ) { \
/*SysPrintf( "FPU OVERFLOW!: Changing to +/-Fmax!!!!!!!!!!!!\n" );*/ \ /*Console::Notice( "FPU OVERFLOW!: Changing to +/-Fmax!!!!!!!!!!!!\n" );*/ \
xReg = ( xReg & 0x80000000 ) | posFmax; \ xReg = ( xReg & 0x80000000 ) | posFmax; \
_ContVal_ |= cFlagsToSet; \ _ContVal_ |= cFlagsToSet; \
if ( shouldReturn ) { return; } \ if ( shouldReturn ) { return; } \
@ -93,7 +93,7 @@ using namespace std; // for min / max
// If we have a denormal value, then Underflow has occured. // If we have a denormal value, then Underflow has occured.
#define checkUnderflow(xReg, cFlagsToSet, shouldReturn) { \ #define checkUnderflow(xReg, cFlagsToSet, shouldReturn) { \
if ( ( ( xReg & 0x7F800000 ) == 0 ) && ( ( xReg & 0x007FFFFF ) != 0 ) ) { \ if ( ( ( xReg & 0x7F800000 ) == 0 ) && ( ( xReg & 0x007FFFFF ) != 0 ) ) { \
/*SysPrintf( "FPU UNDERFLOW!: Changing to +/-0!!!!!!!!!!!!\n" );*/ \ /*Console::Notice( "FPU UNDERFLOW!: Changing to +/-0!!!!!!!!!!!!\n" );*/ \
xReg &= 0x80000000; \ xReg &= 0x80000000; \
_ContVal_ |= cFlagsToSet; \ _ContVal_ |= cFlagsToSet; \
if ( shouldReturn ) { return; } \ if ( shouldReturn ) { return; } \

View File

@ -55,7 +55,7 @@ void __fastcall ReadFIFO_page_4(u32 mem, u64 *out)
{ {
jASSUME( (mem >= 0x10004000) && (mem < 0x10005000) ); jASSUME( (mem >= 0x10004000) && (mem < 0x10005000) );
VIF_LOG("ReadFIFO/VIF0 0x%08X\n", mem); VIF_LOG("ReadFIFO/VIF0 0x%08X", mem);
//out[0] = psHu64(mem ); //out[0] = psHu64(mem );
//out[1] = psHu64(mem+8); //out[1] = psHu64(mem+8);
@ -67,7 +67,7 @@ void __fastcall ReadFIFO_page_5(u32 mem, u64 *out)
{ {
jASSUME( (mem >= 0x10005000) && (mem < 0x10006000) ); jASSUME( (mem >= 0x10005000) && (mem < 0x10006000) );
VIF_LOG("ReadFIFO/VIF1, addr=0x%08X\n", mem); VIF_LOG("ReadFIFO/VIF1, addr=0x%08X", mem);
if( vif1Regs->stat & (VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS) ) if( vif1Regs->stat & (VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS) )
DevCon::Notice( "Reading from vif1 fifo when stalled" ); DevCon::Notice( "Reading from vif1 fifo when stalled" );
@ -127,7 +127,7 @@ void __fastcall WriteFIFO_page_4(u32 mem, const mem128_t *value)
{ {
jASSUME( (mem >= 0x10004000) && (mem < 0x10005000) ); jASSUME( (mem >= 0x10004000) && (mem < 0x10005000) );
VIF_LOG("WriteFIFO/VIF0, addr=0x%08X\n", mem); VIF_LOG("WriteFIFO/VIF0, addr=0x%08X", mem);
//psHu64(mem ) = value[0]; //psHu64(mem ) = value[0];
//psHu64(mem+8) = value[1]; //psHu64(mem+8) = value[1];
@ -144,7 +144,7 @@ void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value)
{ {
jASSUME( (mem >= 0x10005000) && (mem < 0x10006000) ); jASSUME( (mem >= 0x10005000) && (mem < 0x10006000) );
VIF_LOG("WriteFIFO/VIF1, addr=0x%08X\n", mem); VIF_LOG("WriteFIFO/VIF1, addr=0x%08X", mem);
//psHu64(mem ) = value[0]; //psHu64(mem ) = value[0];
//psHu64(mem+8) = value[1]; //psHu64(mem+8) = value[1];
@ -165,7 +165,7 @@ void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value)
void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value) void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value)
{ {
jASSUME( (mem >= 0x10006000) && (mem < 0x10007000) ); jASSUME( (mem >= 0x10006000) && (mem < 0x10007000) );
GIF_LOG("WriteFIFO/GIF, addr=0x%08X\n", mem); GIF_LOG("WriteFIFO/GIF, addr=0x%08X", mem);
//psHu64(mem ) = value[0]; //psHu64(mem ) = value[0];
//psHu64(mem+8) = value[1]; //psHu64(mem+8) = value[1];
@ -197,7 +197,7 @@ void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value)
// All addresses in this page map to 0x7000 and 0x7010: // All addresses in this page map to 0x7000 and 0x7010:
mem &= 0x10; mem &= 0x10;
IPU_LOG( "WriteFIFO/IPU, addr=0x%x\n", params mem ); IPU_LOG( "WriteFIFO/IPU, addr=0x%x", params mem );
if( mem == 0 ) if( mem == 0 )
{ {
@ -206,7 +206,7 @@ void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value)
} }
else else
{ {
IPU_LOG("WriteFIFO IPU_in[%d] <- %8.8X_%8.8X_%8.8X_%8.8X\n", IPU_LOG("WriteFIFO IPU_in[%d] <- %8.8X_%8.8X_%8.8X_%8.8X",
mem/16, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]); mem/16, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]);
//committing every 16 bytes //committing every 16 bytes

View File

@ -32,16 +32,8 @@ using namespace std;
using namespace R5900; using namespace R5900;
#ifdef DEBUG
#define MTGS_LOG SysPrintf
#else
#define MTGS_LOG 0&&
#endif
static bool m_gsOpened = false; static bool m_gsOpened = false;
int g_FFXHack=0;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
// GS Playback // GS Playback
@ -261,7 +253,7 @@ void gsReset()
memzero_obj(g_RealGSMem); memzero_obj(g_RealGSMem);
Path3transfer = 0; Path3transfer = FALSE;
GSCSRr = 0x551B400F; // Set the FINISH bit to 1 for now GSCSRr = 0x551B400F; // Set the FINISH bit to 1 for now
GSIMR = 0x7f00; GSIMR = 0x7f00;
@ -319,7 +311,7 @@ void gsCSRwrite(u32 value)
// Our emulated GS has no FIFO... // Our emulated GS has no FIFO...
/*if( value & 0x100 ) { // FLUSH /*if( value & 0x100 ) { // FLUSH
//SysPrintf("GS_CSR FLUSH GS fifo: %x (CSRr=%x)\n", value, GSCSRr); //Console::WriteLn("GS_CSR FLUSH GS fifo: %x (CSRr=%x)", params value, GSCSRr);
}*/ }*/
if (value & 0x200) { // resetGS if (value & 0x200) { // resetGS
@ -365,7 +357,7 @@ __forceinline void gsWrite8(u32 mem, u8 value)
if( mtgsThread != NULL ) if( mtgsThread != NULL )
mtgsThread->SendSimplePacket(GS_RINGTYPE_MEMWRITE8, mem&0x13ff, value, 0); mtgsThread->SendSimplePacket(GS_RINGTYPE_MEMWRITE8, mem&0x13ff, value, 0);
} }
GIF_LOG("GS write 8 at %8.8lx with data %8.8lx\n", mem, value); GIF_LOG("GS write 8 at %8.8lx with data %8.8lx", mem, value);
} }
__forceinline void _gsSMODEwrite( u32 mem, u32 value ) __forceinline void _gsSMODEwrite( u32 mem, u32 value )
@ -390,7 +382,7 @@ __forceinline void _gsSMODEwrite( u32 mem, u32 value )
__forceinline void gsWrite16(u32 mem, u16 value) __forceinline void gsWrite16(u32 mem, u16 value)
{ {
GIF_LOG("GS write 16 at %8.8lx with data %8.8lx\n", mem, value); GIF_LOG("GS write 16 at %8.8lx with data %8.8lx", mem, value);
_gsSMODEwrite( mem, value ); _gsSMODEwrite( mem, value );
@ -421,7 +413,7 @@ __forceinline void gsWrite16(u32 mem, u16 value)
__forceinline void gsWrite32(u32 mem, u32 value) __forceinline void gsWrite32(u32 mem, u32 value)
{ {
jASSUME( (mem & 3) == 0 ); jASSUME( (mem & 3) == 0 );
GIF_LOG("GS write 32 at %8.8lx with data %8.8lx\n", mem, value); GIF_LOG("GS write 32 at %8.8lx with data %8.8lx", mem, value);
_gsSMODEwrite( mem, value ); _gsSMODEwrite( mem, value );
@ -470,7 +462,7 @@ void __fastcall gsWrite64_page_01( u32 mem, const mem64_t* value )
void __fastcall gsWrite64_generic( u32 mem, const mem64_t* value ) void __fastcall gsWrite64_generic( u32 mem, const mem64_t* value )
{ {
const u32* const srcval32 = (u32*)value; const u32* const srcval32 = (u32*)value;
GIF_LOG("GS Write64 at %8.8lx with data %8.8x_%8.8x\n", mem, srcval32[1], srcval32[0]); GIF_LOG("GS Write64 at %8.8lx with data %8.8x_%8.8x", mem, srcval32[1], srcval32[0]);
*(u64*)PS2GS_BASE(mem) = *value; *(u64*)PS2GS_BASE(mem) = *value;
@ -507,7 +499,7 @@ void __fastcall gsWrite128_generic( u32 mem, const mem128_t* value )
{ {
const u32* const srcval32 = (u32*)value; const u32* const srcval32 = (u32*)value;
GIF_LOG("GS Write128 at %8.8lx with data %8.8x_%8.8x_%8.8x_%8.8x \n", mem, GIF_LOG("GS Write128 at %8.8lx with data %8.8x_%8.8x_%8.8x_%8.8x", mem,
srcval32[3], srcval32[2], srcval32[1], srcval32[0]); srcval32[3], srcval32[2], srcval32[1], srcval32[0]);
const uint masked_mem = mem & 0x13ff; const uint masked_mem = mem & 0x13ff;
@ -527,7 +519,7 @@ void __fastcall gsWrite128_generic( u32 mem, const mem128_t* value )
// This function is left in for now for debugging/reference purposes. // This function is left in for now for debugging/reference purposes.
__forceinline void gsWrite64(u32 mem, u64 value) __forceinline void gsWrite64(u32 mem, u64 value)
{ {
GIF_LOG("GS write 64 at %8.8lx with data %8.8lx_%8.8lx\n", mem, ((u32*)&value)[1], (u32)value); GIF_LOG("GS write 64 at %8.8lx with data %8.8lx_%8.8lx", mem, ((u32*)&value)[1], (u32)value);
switch (mem) switch (mem)
{ {
@ -558,26 +550,26 @@ __forceinline void gsWrite64(u32 mem, u64 value)
__forceinline u8 gsRead8(u32 mem) __forceinline u8 gsRead8(u32 mem)
{ {
GIF_LOG("GS read 8 from %8.8lx value: %8.8lx\n", mem, *(u8*)PS2GS_BASE(mem)); GIF_LOG("GS read 8 from %8.8lx value: %8.8lx", mem, *(u8*)PS2GS_BASE(mem));
return *(u8*)PS2GS_BASE(mem); return *(u8*)PS2GS_BASE(mem);
} }
__forceinline u16 gsRead16(u32 mem) __forceinline u16 gsRead16(u32 mem)
{ {
GIF_LOG("GS read 16 from %8.8lx value: %8.8lx\n", mem, *(u16*)PS2GS_BASE(mem)); GIF_LOG("GS read 16 from %8.8lx value: %8.8lx", mem, *(u16*)PS2GS_BASE(mem));
return *(u16*)PS2GS_BASE(mem); return *(u16*)PS2GS_BASE(mem);
} }
__forceinline u32 gsRead32(u32 mem) __forceinline u32 gsRead32(u32 mem)
{ {
GIF_LOG("GS read 32 from %8.8lx value: %8.8lx\n", mem, *(u32*)PS2GS_BASE(mem)); GIF_LOG("GS read 32 from %8.8lx value: %8.8lx", mem, *(u32*)PS2GS_BASE(mem));
return *(u32*)PS2GS_BASE(mem); return *(u32*)PS2GS_BASE(mem);
} }
__forceinline u64 gsRead64(u32 mem) __forceinline u64 gsRead64(u32 mem)
{ {
// fixme - PS2GS_BASE(mem+4) = (g_RealGSMem+(mem + 4 & 0x13ff)) // fixme - PS2GS_BASE(mem+4) = (g_RealGSMem+(mem + 4 & 0x13ff))
GIF_LOG("GS read 64 from %8.8lx value: %8.8lx_%8.8lx\n", mem, *(u32*)PS2GS_BASE(mem+4), *(u32*)PS2GS_BASE(mem) ); GIF_LOG("GS read 64 from %8.8lx value: %8.8lx_%8.8lx", mem, *(u32*)PS2GS_BASE(mem+4), *(u32*)PS2GS_BASE(mem) );
return *(u64*)PS2GS_BASE(mem); return *(u64*)PS2GS_BASE(mem);
} }
@ -593,7 +585,7 @@ void gsSyncLimiterLostTime( s32 deltaTime )
if( !m_StrictSkipping ) return; if( !m_StrictSkipping ) return;
//SysPrintf("LostTime on the EE!\n"); //Console::WriteLn("LostTime on the EE!");
if( mtgsThread != NULL ) if( mtgsThread != NULL )
{ {
@ -749,7 +741,7 @@ __forceinline void gsFrameSkip( bool forceskip )
return; return;
} }
//SysPrintf( "Consecutive Frames -- Lateness: %d\n", (int)( sSlowDeltaTime / m_iSlowTicks ) ); //Console::WriteLn( "Consecutive Frames -- Lateness: %d", params (int)( sSlowDeltaTime / m_iSlowTicks ) );
// -- Consecutive frames section -- // -- Consecutive frames section --
// Force-render consecutive frames without skipping. // Force-render consecutive frames without skipping.

View File

@ -146,8 +146,9 @@ class mtgsThreadObject : public Threading::Thread
protected: protected:
// Size of the ringbuffer as a power of 2 -- size is a multiple of simd128s. // Size of the ringbuffer as a power of 2 -- size is a multiple of simd128s.
// (actual size is 1<<m_RingBufferSizeFactor simd vectors [128-bit values]) // (actual size is 1<<m_RingBufferSizeFactor simd vectors [128-bit values])
// A value of 17 is a 4meg ring buffer. 16 would be 2 megs, and 18 would be 8 megs. // A value of 19 is a 8meg ring buffer. 18 would be 4 megs, and 20 would be 16 megs.
static const uint m_RingBufferSizeFactor = 17; // Default was 2mb, but some games with lots of MTGS activity want 8mb to run fast (rama)
static const uint m_RingBufferSizeFactor = 19;
// size of the ringbuffer in simd128's. // size of the ringbuffer in simd128's.
static const uint m_RingBufferSize = 1<<m_RingBufferSizeFactor; static const uint m_RingBufferSize = 1<<m_RingBufferSizeFactor;

View File

@ -28,18 +28,33 @@
using std::min; using std::min;
#define gif ((DMACh*)&psH[0xA000]) #define gif ((DMACh*)&psH[0xA000])
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
enum gifstate_t
{
GIF_STATE_EMPTY = 0,
GIF_STATE_STALL,
GIF_STATE_DONE
};
// A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished).
static gifstate_t gifstate = GIF_STATE_EMPTY;
static u64 s_gstag = 0; // used for querying the last tag static u64 s_gstag = 0; // used for querying the last tag
static int gspath3done=0;
static int gscycles = 0; // This should be a bool, as should the return value of hwDmacSrcChainWithStack.
// Next time I feel like breaking the save state, it will be. --arcum42
static int gspath3done = 0;
static u32 gscycles = 0, prevcycles = 0, mfifocycles = 0;
static u32 gifqwc = 0;
__forceinline void gsInterrupt() { __forceinline void gsInterrupt() {
GIF_LOG("gsInterrupt: %8.8x\n", cpuRegs.cycle); GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle);
if((gif->chcr & 0x100) == 0){ if((gif->chcr & 0x100) == 0){
//SysPrintf("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x\n", gif->chcr, gif->qwc, done); //Console::WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", params gif->chcr, gif->qwc, done);
return; return;
} }
if(gif->qwc > 0 || gspath3done == 0) { if(gif->qwc > 0 || gspath3done == 0) {
@ -52,7 +67,7 @@ __forceinline void gsInterrupt() {
GIFdma(); GIFdma();
#ifdef GSPATH3FIX #ifdef GSPATH3FIX
// re-reaise the IRQ as part of the mysterious Path3fix. // re-raise the IRQ as part of the mysterious Path3fix.
// fixme - this hack *should* have the gs_irq raised from the VIF, I think. It would be // fixme - this hack *should* have the gs_irq raised from the VIF, I think. It would be
// more efficient and more correct. (air) // more efficient and more correct. (air)
/*if (!(vif1Regs->mskpath3 && (vif1ch->chcr & 0x100)) || (psHu32(GIF_MODE) & 0x1)) /*if (!(vif1Regs->mskpath3 && (vif1ch->chcr & 0x100)) || (psHu32(GIF_MODE) & 0x1))
@ -63,11 +78,10 @@ __forceinline void gsInterrupt() {
gspath3done = 0; gspath3done = 0;
gscycles = 0; gscycles = 0;
Path3transfer = 0; Path3transfer = FALSE;
gif->chcr &= ~0x100; gif->chcr &= ~0x100;
GSCSRr &= ~0xC000; //Clear FIFO stuff GSCSRr &= ~0xC000; //Clear FIFO stuff
GSCSRr |= 0x4000; //FIFO empty GSCSRr |= 0x4000; //FIFO empty
//psHu32(GIF_MODE)&= ~0x4;
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0 psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
hwDmacIrq(DMAC_GIF); hwDmacIrq(DMAC_GIF);
@ -78,8 +92,8 @@ static void WRITERING_DMA(u32 *pMem, u32 qwc)
{ {
psHu32(GIF_STAT) |= 0xE00; psHu32(GIF_STAT) |= 0xE00;
// Path3 transfer will be set to zero by the GIFtag handler. // Path3 transfer will be set to false by the GIFtag handler.
Path3transfer = 1; Path3transfer = TRUE;
if( mtgsThread != NULL ) if( mtgsThread != NULL )
{ {
@ -103,29 +117,25 @@ static void WRITERING_DMA(u32 *pMem, u32 qwc)
else else
{ {
GSGIFTRANSFER3(pMem, qwc); GSGIFTRANSFER3(pMem, qwc);
if( GSgetLastTag != NULL ) if (GSgetLastTag != NULL)
{ {
GSgetLastTag(&s_gstag); GSgetLastTag(&s_gstag);
if( s_gstag == 1 ) if (s_gstag == 1) Path3transfer = FALSE; /* fixes SRS and others */
Path3transfer = 0; /* fixes SRS and others */ }
}
} }
} }
int _GIFchain() { int _GIFchain() {
#ifdef GSPATH3FIX #ifdef GSPATH3FIX
u32 qwc = (psHu32(GIF_MODE) & 0x4 && vif1Regs->mskpath3) ? min(8, (int)gif->qwc) : gif->qwc; u32 qwc = ((psHu32(GIF_MODE) & 0x4) && (vif1Regs->mskpath3)) ? min(8, (int)gif->qwc) : gif->qwc;
#else #else
u32 qwc = gif->qwc; u32 qwc = gif->qwc;
#endif #endif
u32 *pMem; u32 *pMem;
//if (gif->qwc == 0) return 0;
pMem = (u32*)dmaGetAddr(gif->madr); pMem = (u32*)dmaGetAddr(gif->madr);
if (pMem == NULL) { if (pMem == NULL) {
// reset path3, fixes dark cloud 2 // reset path3, fixes dark cloud 2
gsGIFSoftReset(4); gsGIFSoftReset(4);
//must increment madr and clear qwc, else it loops //must increment madr and clear qwc, else it loops
@ -136,19 +146,36 @@ int _GIFchain() {
} }
WRITERING_DMA(pMem, qwc); WRITERING_DMA(pMem, qwc);
//if((psHu32(GIF_MODE) & 0x4)) amount -= qwc;
gif->madr+= qwc*16; gif->madr+= qwc*16;
gif->qwc -= qwc; gif->qwc -= qwc;
return (qwc)*2; return (qwc)*2;
} }
#define GIFchain() \ __forceinline void GIFchain()
if (gif->qwc) { \ {
gscycles+= _GIFchain(); /* guessing */ \ FreezeRegs(1);
} if (gif->qwc) gscycles+= _GIFchain(); /* guessing */
FreezeRegs(0);
}
int gscount = 0; static __forceinline void dmaGIFend()
static int prevcycles = 0; {
if ((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0)
CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/);
else
CPU_INT(2, gif->qwc /** BIAS*/);
}
// These could probably be consolidated into one function,
// but I wasn't absolutely sure if there was a good reason
// not to do the gif->qwc != 0 check. --arcum42
static __forceinline void GIFdmaEnd()
{
if (psHu32(GIF_MODE) & 0x4)
CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/);
else
CPU_INT(2, gif->qwc /** BIAS*/);
}
void GIFdma() void GIFdma()
{ {
@ -157,12 +184,12 @@ void GIFdma()
gscycles= prevcycles ? prevcycles: gscycles; gscycles= prevcycles ? prevcycles: gscycles;
if( (psHu32(GIF_CTRL) & 8) ) { // temporarily stop if ((psHu32(GIF_CTRL) & 8)) { // temporarily stop
SysPrintf("Gif dma temp paused?\n"); Console::WriteLn("Gif dma temp paused?");
return; return;
} }
GIF_LOG("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx\n", gif->chcr, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1); GIF_LOG("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gif->chcr, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1);
#ifndef GSPATH3FIX #ifndef GSPATH3FIX
if ( !(psHu32(GIF_MODE) & 0x4) ) { if ( !(psHu32(GIF_MODE) & 0x4) ) {
@ -176,7 +203,7 @@ void GIFdma()
#endif #endif
if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80 && prevcycles != 0) { // STD == GIF if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80 && prevcycles != 0) { // STD == GIF
SysPrintf("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3, gif->madr, psHu32(DMAC_STADR)); Console::WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", params (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3, gif->madr, psHu32(DMAC_STADR));
if( gif->madr + (gif->qwc * 16) > psHu32(DMAC_STADR) ) { if( gif->madr + (gif->qwc * 16) > psHu32(DMAC_STADR) ) {
CPU_INT(2, gscycles); CPU_INT(2, gscycles);
@ -189,11 +216,10 @@ void GIFdma()
GSCSRr &= ~0xC000; //Clear FIFO stuff GSCSRr &= ~0xC000; //Clear FIFO stuff
GSCSRr |= 0x8000; //FIFO full GSCSRr |= 0x8000; //FIFO full
//psHu32(GIF_STAT)|= 0xE00; // OPH=1 | APATH=3 psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [ used to be 0xE00; // OPH=1 | APATH=3]
psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;)
#ifdef GSPATH3FIX #ifdef GSPATH3FIX
if (vif1Regs->mskpath3 || psHu32(GIF_MODE) & 0x1) { if (vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1)) {
if(gif->qwc == 0) { if(gif->qwc == 0) {
if((gif->chcr & 0x10e) == 0x104) { if((gif->chcr & 0x10e) == 0x104) {
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
@ -204,15 +230,15 @@ void GIFdma()
} }
gscycles += 2; gscycles += 2;
gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15
id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
gif->madr = ptag[1]; //MADR = ADDR field gif->madr = ptag[1]; //MADR = ADDR field
gspath3done = hwDmacSrcChainWithStack(gif, id); gspath3done = hwDmacSrcChainWithStack(gif, id);
GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx\n", ptag[1], ptag[0], gif->qwc, id, gif->madr); GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr);
if ((gif->chcr & 0x80) && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag if ((gif->chcr & 0x80) && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag
GIF_LOG("PATH3 MSK dmaIrq Set\n"); GIF_LOG("PATH3 MSK dmaIrq Set");
SysPrintf("GIF TIE\n"); Console::WriteLn("GIF TIE");
gspath3done |= 1; gspath3done |= 1;
} }
} }
@ -220,18 +246,16 @@ void GIFdma()
// When MTGS is enabled, Gifchain calls WRITERING_DMA, which calls GSRINGBUF_DONECOPY, which freezes // When MTGS is enabled, Gifchain calls WRITERING_DMA, which calls GSRINGBUF_DONECOPY, which freezes
// the registers inside of the FreezeXMMRegs calls here and in the other two below.. // the registers inside of the FreezeXMMRegs calls here and in the other two below..
// I'm not really sure that is intentional. --arcum42 // I'm not really sure that is intentional. --arcum42
FreezeRegs(1);
GIFchain(); GIFchain();
FreezeRegs(0); // Theres a comment below that says not to unfreeze the xmm regs, so not sure about this. // Theres a comment below that says not to unfreeze the xmm regs, so not sure about freezing and unfreezing in GIFchain.
if((gspath3done == 1 || (gif->chcr & 0xc) == 0) && gif->qwc == 0){ if((gif->qwc == 0) && ((gspath3done == 1) || (gif->chcr & 0xc) == 0)){
if(gif->qwc > 0) SysPrintf("Hurray\n"); //if(gif->qwc > 0) Console::WriteLn("Hurray!"); // We *know* it is 0!
gspath3done = 0; gspath3done = 0;
gif->chcr &= ~0x100; gif->chcr &= ~0x100;
//psHu32(GIF_MODE)&= ~0x4;
GSCSRr &= ~0xC000; GSCSRr &= ~0xC000;
GSCSRr |= 0x4000; GSCSRr |= 0x4000;
Path3transfer = 0; Path3transfer = FALSE;
psHu32(GIF_STAT)&= ~0x1F000E00; // OPH=0 | APATH=0 | QFC=0 psHu32(GIF_STAT)&= ~0x1F000E00; // OPH=0 | APATH=0 | QFC=0
hwDmacIrq(DMAC_GIF); hwDmacIrq(DMAC_GIF);
} }
@ -239,29 +263,23 @@ void GIFdma()
return; return;
} }
#endif #endif
//gscycles = 0;
// Transfer Dn_QWC from Dn_MADR to GIF // Transfer Dn_QWC from Dn_MADR to GIF
if ((gif->chcr & 0xc) == 0 || gif->qwc > 0) { // Normal Mode if ((gif->chcr & 0xc) == 0 || gif->qwc > 0) { // Normal Mode
//gscount++; if ((((psHu32(DMAC_CTRL) & 0xC0) == 0x80) && ((gif->chcr & 0xc) == 0))) {
if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80 && (gif->chcr & 0xc) == 0) { Console::WriteLn("DMA Stall Control on GIF normal");
SysPrintf("DMA Stall Control on GIF normal\n");
} }
FreezeRegs(1);
GIFchain(); //Transfers the data set by the switch GIFchain(); //Transfers the data set by the switch
FreezeRegs(0);
if(gif->qwc == 0 && (gif->chcr & 0xc) == 0) gspath3done = 1; if (((gif->qwc == 0) && (gif->chcr & 0xc) == 0))
gspath3done = 1;
else else
{ GIFdmaEnd();
if(psHu32(GIF_MODE) & 0x4)
CPU_INT(2, min( 8, (int)gif->qwc )/** BIAS*/);
else
CPU_INT(2, gif->qwc/* * BIAS*/);
}
return; return;
} }
else { else {
// Chain Mode // Chain Mode
while (gspath3done == 0 && gif->qwc == 0) { //Loop if the transfers aren't intermittent while ((gspath3done == 0) && (gif->qwc == 0)) { //Loop if the transfers aren't intermittent
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
if (ptag == NULL) { //Is ptag empty? if (ptag == NULL) { //Is ptag empty?
psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register
@ -269,30 +287,22 @@ void GIFdma()
} }
gscycles+=2; // Add 1 cycles from the QW read for the tag gscycles+=2; // Add 1 cycles from the QW read for the tag
// Transfer dma tag if tte is set // We used to transfer dma tags if tte is set here
if (gif->chcr & 0x40) {
//u32 temptag[4] = {0};
//SysPrintf("GIF TTE: %x_%x\n", ptag[3], ptag[2]);
//temptag[0] = ptag[2]; gif->chcr = ( gif->chcr & 0xFFFF ) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
//temptag[1] = ptag[3];
//GSGIFTRANSFER3(ptag, 1);
}
gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
gif->madr = ptag[1]; //MADR = ADDR field gif->madr = ptag[1]; //MADR = ADDR field
gspath3done = hwDmacSrcChainWithStack(gif, id); gspath3done = hwDmacSrcChainWithStack(gif, id);
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx\n", ptag[1], ptag[0], gif->qwc, id, gif->madr); GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr);
if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80) { // STD == GIF if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80) { // STD == GIF
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall // there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
if(!gspath3done && gif->madr + (gif->qwc * 16) > psHu32(DMAC_STADR) && id == 4) { if(!gspath3done && gif->madr + (gif->qwc * 16) > psHu32(DMAC_STADR) && id == 4) {
// stalled // stalled
SysPrintf("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gif->madr, psHu32(DMAC_STADR)); Console::WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", params (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gif->madr, psHu32(DMAC_STADR));
prevcycles = gscycles; prevcycles = gscycles;
gif->tadr -= 16; gif->tadr -= 16;
hwDmacIrq(13); hwDmacIrq(13);
@ -301,23 +311,20 @@ void GIFdma()
return; return;
} }
} }
FreezeRegs(1);
GIFchain(); //Transfers the data set by the switch GIFchain(); //Transfers the data set by the switch
FreezeRegs(0);
if ((gif->chcr & 0x80) && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag if ((gif->chcr & 0x80) && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag
GIF_LOG("dmaIrq Set\n"); GIF_LOG("dmaIrq Set");
gspath3done = 1; gspath3done = 1;
//gif->qwc = 0;
} }
} }
} }
prevcycles = 0; prevcycles = 0;
if (!(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))) { if (!(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))) {
if(gspath3done == 0) if (gspath3done == 0)
{ {
if((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0) if ((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0)
{ {
CPU_INT(2, min( 8, (int)gif->qwc )/** BIAS*/); CPU_INT(2, min( 8, (int)gif->qwc )/** BIAS*/);
} }
@ -327,31 +334,21 @@ void GIFdma()
gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15
if(psHu32(GIF_MODE) & 0x4) GIFdmaEnd();
CPU_INT(2, min( 8, (int)gif->qwc )/** BIAS*/);
else
CPU_INT(2, gif->qwc /** BIAS*/);
gif->qwc = 0; gif->qwc = 0;
return; return;
} }
} }
//CPU_INT(2, gif->qwc /** BIAS*/);
gscycles = 0; gscycles = 0;
} }
} }
void dmaGIF() { void dmaGIF() {
//if(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1)){ //We used to addd wait time for the buffer to fill here, fixing some timing problems in path 3 masking
// CPU_INT(2, 48); //Wait time for the buffer to fill, fixes some timing problems in path 3 masking //It takes the time of 24 QW for the BUS to become ready - The Punisher, And1 Streetball
//} //It takes the time of 24 QW for the BUS to become ready - The Punisher, And1 Streetball
//else
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) { // GIF MFIFO if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) { // GIF MFIFO
SysPrintf("GIF MFIFO\n"); Console::WriteLn("GIF MFIFO");
gifMFIFOInterrupt(); gifMFIFOInterrupt();
return; return;
} }
@ -360,78 +357,34 @@ void dmaGIF() {
GSCSRr &= ~0xC000; //Clear FIFO stuff GSCSRr &= ~0xC000; //Clear FIFO stuff
GSCSRr |= 0x8000; //FIFO full GSCSRr |= 0x8000; //FIFO full
//psHu32(GIF_STAT)|= 0xE00; // OPH=1 | APATH=3 psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [used to be 0xE00; // OPH=1 | APATH=3]
psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;)
if ((gif->chcr & 0xc) != 0 && gif->qwc == 0){ if ((gif->qwc == 0) && ((gif->chcr & 0xc) != 0)){
u32 *ptag; u32 *ptag;
ptag = (u32*)dmaGetAddr(gif->tadr); ptag = (u32*)dmaGetAddr(gif->tadr);
gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15
if((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0)
{ dmaGIFend();
CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/);
}
else
{
CPU_INT(2, gif->qwc /** BIAS*/);
}
gif->qwc = 0; gif->qwc = 0;
return; return;
} }
if(gif->qwc > 0 && (gif->chcr & 0x4) == 0x4) { //Halflife sets a QWC amount in chain mode, no tadr set.
//SysPrintf("HL Hack\n"); if((gif->qwc > 0) && ((gif->chcr & 0x4) == 0x4)) gspath3done = 1;
gspath3done = 1; //Halflife sets a QWC amount in chain mode, no tadr set.
if((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0)
{
CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/);
}
else
{
CPU_INT(2, gif->qwc /** BIAS*/);
}
return;
}
//GIFdma();
if((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0)
{
CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/);
}
else
{
CPU_INT(2, gif->qwc /** BIAS*/);
}
dmaGIFend();
} }
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
enum gifstate_t
{
GIF_STATE_EMPTY = 0,
GIF_STATE_STALL,
GIF_STATE_DONE
};
static unsigned int mfifocycles;
static unsigned int gifqwc = 0;
// A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished).
static gifstate_t gifstate = GIF_STATE_EMPTY;
// called from only one location, so forceinline it: // called from only one location, so forceinline it:
static __forceinline int mfifoGIFrbTransfer() { static __forceinline int mfifoGIFrbTransfer() {
u32 qwc = (psHu32(GIF_MODE) & 0x4 && vif1Regs->mskpath3) ? min(8, (int)gif->qwc) : gif->qwc; u32 qwc = (psHu32(GIF_MODE) & 0x4 && vif1Regs->mskpath3) ? min(8, (int)gif->qwc) : gif->qwc;
int mfifoqwc = min(gifqwc, qwc); int mfifoqwc = min(gifqwc, qwc);
u32 *src; u32 *src;
/* Check if the transfer should wrap around the ring buffer */ /* Check if the transfer should wrap around the ring buffer */
if ((gif->madr+mfifoqwc*16) > (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16)) { if ((gif->madr+mfifoqwc*16) > (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16))
{
int s1 = ((psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16) - gif->madr) >> 4; int s1 = ((psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16) - gif->madr) >> 4;
// fixme - I don't think these should use WRITERING_DMA, since our source // fixme - I don't think these should use WRITERING_DMA, since our source
@ -447,7 +400,9 @@ static __forceinline int mfifoGIFrbTransfer() {
if (src == NULL) return -1; if (src == NULL) return -1;
WRITERING_DMA(src, (mfifoqwc - s1)); WRITERING_DMA(src, (mfifoqwc - s1));
} else { }
else
{
/* it doesn't, so just transfer 'qwc*16' words /* it doesn't, so just transfer 'qwc*16' words
from 'gif->madr' to GS */ from 'gif->madr' to GS */
src = (u32*)PSM(gif->madr); src = (u32*)PSM(gif->madr);
@ -462,7 +417,6 @@ static __forceinline int mfifoGIFrbTransfer() {
gif->madr+= mfifoqwc*16; gif->madr+= mfifoqwc*16;
mfifocycles+= (mfifoqwc) * 2; /* guessing */ mfifocycles+= (mfifoqwc) * 2; /* guessing */
return 0; return 0;
} }
@ -473,9 +427,12 @@ static __forceinline int mfifoGIFchain() {
if (gif->qwc == 0) return 0; if (gif->qwc == 0) return 0;
if (gif->madr >= psHu32(DMAC_RBOR) && if (gif->madr >= psHu32(DMAC_RBOR) &&
gif->madr <= (psHu32(DMAC_RBOR)+psHu32(DMAC_RBSR))) { gif->madr <= (psHu32(DMAC_RBOR)+psHu32(DMAC_RBSR)))
{
if (mfifoGIFrbTransfer() == -1) return -1; if (mfifoGIFrbTransfer() == -1) return -1;
} else { }
else
{
int mfifoqwc = (psHu32(GIF_MODE) & 0x4 && vif1Regs->mskpath3) ? min(8, (int)gif->qwc) : gif->qwc; int mfifoqwc = (psHu32(GIF_MODE) & 0x4 && vif1Regs->mskpath3) ? min(8, (int)gif->qwc) : gif->qwc;
u32 *pMem = (u32*)dmaGetAddr(gif->madr); u32 *pMem = (u32*)dmaGetAddr(gif->madr);
if (pMem == NULL) return -1; if (pMem == NULL) return -1;
@ -488,7 +445,7 @@ static __forceinline int mfifoGIFchain() {
return 0; return 0;
} }
int gifmfifoirq = 0; bool gifmfifoirq = FALSE;
void mfifoGIFtransfer(int qwc) { void mfifoGIFtransfer(int qwc) {
u32 *ptag; u32 *ptag;
@ -496,80 +453,77 @@ void mfifoGIFtransfer(int qwc) {
u32 temp = 0; u32 temp = 0;
mfifocycles = 0; mfifocycles = 0;
gifmfifoirq = 0; gifmfifoirq = FALSE;
if(qwc > 0 ) { if(qwc > 0 ) {
gifqwc += qwc; gifqwc += qwc;
if(!(gif->chcr & 0x100))return; if(!(gif->chcr & 0x100))return;
if(gifstate == GIF_STATE_STALL) return; if(gifstate == GIF_STATE_STALL) return;
} }
SPR_LOG("mfifoGIFtransfer %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr);
SPR_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr);
if(gif->qwc == 0){ if(gif->qwc == 0){
if(gif->tadr == spr0->madr) { if(gif->tadr == spr0->madr) {
#ifdef PCSX2_DEVBUILD //if( gifqwc > 1 ) DevCon::WriteLn("gif mfifo tadr==madr but qwc = %d", params gifqwc);
/*if( gifqwc > 1 ) //hwDmacIrq(14);
SysPrintf("gif mfifo tadr==madr but qwc = %d\n", gifqwc);*/
#endif
//hwDmacIrq(14);
return; return;
}
gif->tadr = psHu32(DMAC_RBOR) + (gif->tadr & psHu32(DMAC_RBSR));
ptag = (u32*)dmaGetAddr(gif->tadr);
id = (ptag[0] >> 28) & 0x7;
gif->qwc = (ptag[0] & 0xffff);
gif->madr = ptag[1];
mfifocycles += 2;
gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 );
SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x",
ptag[1], ptag[0], gif->qwc, id, gif->madr, gif->tadr, gifqwc, spr0->madr);
gifqwc--;
switch (id) {
case 0: // Refe - Transfer Packet According to ADDR field
gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR));
gifstate = GIF_STATE_DONE; //End Transfer
break;
case 1: // CNT - Transfer QWC following the tag.
gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW after Tag
gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data
gifstate = GIF_STATE_EMPTY;
break;
case 2: // Next - Transfer QWC following tag. TADR = ADDR
temp = gif->madr; //Temporarily Store ADDR
gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW following the tag
gif->tadr = temp; //Copy temporarily stored ADDR to Tag
gifstate = GIF_STATE_EMPTY;
break;
case 3: // Ref - Transfer QWC from ADDR field
case 4: // Refs - Transfer QWC from ADDR field (Stall Control)
gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set TADR to next tag
gifstate = GIF_STATE_EMPTY;
break;
case 7: // End - Transfer QWC following the tag
gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to data following the tag
gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data
gifstate = GIF_STATE_DONE; //End Transfer
break;
} }
gif->tadr = psHu32(DMAC_RBOR) + (gif->tadr & psHu32(DMAC_RBSR));
ptag = (u32*)dmaGetAddr(gif->tadr);
id = (ptag[0] >> 28) & 0x7; if ((gif->chcr & 0x80) && (ptag[0] >> 31)) {
gif->qwc = (ptag[0] & 0xffff); SPR_LOG("dmaIrq Set");
gif->madr = ptag[1]; gifstate = GIF_STATE_DONE;
mfifocycles += 2; gifmfifoirq = TRUE;
}
gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 );
SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x\n",
ptag[1], ptag[0], gif->qwc, id, gif->madr, gif->tadr, gifqwc, spr0->madr);
gifqwc--;
switch (id) {
case 0: // Refe - Transfer Packet According to ADDR field
gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR));
gifstate = GIF_STATE_DONE; //End Transfer
break;
case 1: // CNT - Transfer QWC following the tag.
gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW after Tag
gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data
gifstate = GIF_STATE_EMPTY;
break;
case 2: // Next - Transfer QWC following tag. TADR = ADDR
temp = gif->madr; //Temporarily Store ADDR
gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW following the tag
gif->tadr = temp; //Copy temporarily stored ADDR to Tag
gifstate = GIF_STATE_EMPTY;
break;
case 3: // Ref - Transfer QWC from ADDR field
case 4: // Refs - Transfer QWC from ADDR field (Stall Control)
gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set TADR to next tag
gifstate = GIF_STATE_EMPTY;
break;
case 7: // End - Transfer QWC following the tag
gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to data following the tag
gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data
gifstate = GIF_STATE_DONE; //End Transfer
break;
}
if ((gif->chcr & 0x80) && (ptag[0] >> 31)) {
SPR_LOG("dmaIrq Set\n");
gifstate = GIF_STATE_DONE;
gifmfifoirq = 1;
}
} }
FreezeRegs(1); FreezeRegs(1);
if (mfifoGIFchain() == -1) { if (mfifoGIFchain() == -1) {
SysPrintf("GIF dmaChain error size=%d, madr=%lx, tadr=%lx\n", Console::WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", params
gif->qwc, gif->madr, gif->tadr); gif->qwc, gif->madr, gif->tadr);
gifstate = GIF_STATE_STALL; gifstate = GIF_STATE_STALL;
} }
@ -578,16 +532,20 @@ void mfifoGIFtransfer(int qwc) {
if(gif->qwc == 0 && gifstate == GIF_STATE_DONE) gifstate = GIF_STATE_STALL; if(gif->qwc == 0 && gifstate == GIF_STATE_DONE) gifstate = GIF_STATE_STALL;
CPU_INT(11,mfifocycles); CPU_INT(11,mfifocycles);
SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr); SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr);
} }
void gifMFIFOInterrupt() void gifMFIFOInterrupt()
{ {
if(!(gif->chcr & 0x100)) { SysPrintf("WTF GIFMFIFO\n");cpuRegs.interrupt &= ~(1 << 11); return ; } if (!(gif->chcr & 0x100)) {
Console::WriteLn("WTF GIFMFIFO");
cpuRegs.interrupt &= ~(1 << 11);
return ;
}
if(gifstate != GIF_STATE_STALL) { if(gifstate != GIF_STATE_STALL) {
if(gifqwc <= 0) { if(gifqwc <= 0) {
//SysPrintf("Empty\n"); //Console::WriteLn("Empty");
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
hwDmacIrq(14); hwDmacIrq(14);
return; return;
@ -601,14 +559,13 @@ void gifMFIFOInterrupt()
return; return;
} }
#endif #endif
//if(gifqwc > 0)SysPrintf("GIF MFIFO ending with stuff in it %x\n", gifqwc); //if(gifqwc > 0) Console::WriteLn("GIF MFIFO ending with stuff in it %x", params gifqwc);
if( gifmfifoirq == 0) gifqwc = 0; if (!gifmfifoirq) gifqwc = 0;
gifstate = GIF_STATE_EMPTY; gifstate = GIF_STATE_EMPTY;
gif->chcr &= ~0x100; gif->chcr &= ~0x100;
hwDmacIrq(DMAC_GIF); hwDmacIrq(DMAC_GIF);
GSCSRr &= ~0xC000; //Clear FIFO stuff GSCSRr &= ~0xC000; //Clear FIFO stuff
GSCSRr |= 0x4000; //FIFO empty GSCSRr |= 0x4000; //FIFO empty
//psHu32(GIF_MODE)&= ~0x4;
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0 psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
} }

View File

@ -81,7 +81,7 @@ __forceinline void intcInterrupt()
} }
if ((psHu32(INTC_STAT) & psHu32(INTC_MASK)) == 0) return; if ((psHu32(INTC_STAT) & psHu32(INTC_MASK)) == 0) return;
HW_LOG("intcInterrupt %x\n", psHu32(INTC_STAT) & psHu32(INTC_MASK)); HW_LOG("intcInterrupt %x", psHu32(INTC_STAT) & psHu32(INTC_MASK));
if(psHu32(INTC_STAT) & 0x2){ if(psHu32(INTC_STAT) & 0x2){
counters[0].hold = rcntRcount(0); counters[0].hold = rcntRcount(0);
counters[1].hold = rcntRcount(1); counters[1].hold = rcntRcount(1);
@ -99,7 +99,7 @@ __forceinline void dmacInterrupt()
if((psHu32(DMAC_CTRL) & 0x1) == 0) return; if((psHu32(DMAC_CTRL) & 0x1) == 0) return;
HW_LOG("dmacInterrupt %x\n", (psHu16(0xe012) & psHu16(0xe010) || HW_LOG("dmacInterrupt %x", (psHu16(0xe012) & psHu16(0xe010) ||
psHu16(0xe010) & 0x8000)); psHu16(0xe010) & 0x8000));
cpuException(0x800, cpuRegs.branch); cpuException(0x800, cpuRegs.branch);
@ -188,7 +188,7 @@ int hwDmacSrcChainWithStack(DMACh *dma, int id) {
dma->chcr = (dma->chcr & 0xffffffcf) | 0x20; //2 Addresses in call stack dma->chcr = (dma->chcr & 0xffffffcf) | 0x20; //2 Addresses in call stack
dma->asr1 = dma->madr + (dma->qwc << 4); //If no store Succeeding tag in ASR1 dma->asr1 = dma->madr + (dma->qwc << 4); //If no store Succeeding tag in ASR1
}else { }else {
SysPrintf("Call Stack Overflow (report if it fixes/breaks anything)\n"); Console::Notice("Call Stack Overflow (report if it fixes/breaks anything)");
return 1; //Return done return 1; //Return done
} }
dma->tadr = temp; //Set TADR to temporarily stored ADDR dma->tadr = temp; //Set TADR to temporarily stored ADDR
@ -402,20 +402,20 @@ mem32_t __fastcall hwRead32(u32 mem)
case D2_SADR: regName = "DMA2_SADDR"; break; case D2_SADR: regName = "DMA2_SADDR"; break;
} }
HW_LOG( "Hardware Read32 at 0x%x (%s), value=0x%x\n", mem, regName, psHu32(mem) ); HW_LOG( "Hardware Read32 at 0x%x (%s), value=0x%x", mem, regName, psHu32(mem) );
} }
break; break;
case 0x0b: case 0x0b:
if( mem == D4_CHCR ) if( mem == D4_CHCR )
HW_LOG("Hardware Read32 at 0x%x (IPU1:DMA4_CHCR), value=0x%x\n", mem, psHu32(mem)); HW_LOG("Hardware Read32 at 0x%x (IPU1:DMA4_CHCR), value=0x%x", mem, psHu32(mem));
break; break;
case 0x0c: case 0x0c:
case 0x0d: case 0x0d:
case 0x0e: case 0x0e:
if( mem == DMAC_STAT ) if( mem == DMAC_STAT )
HW_LOG("DMAC_STAT Read32, value=0x%x\n", psHu32(DMAC_STAT)); HW_LOG("DMAC_STAT Read32, value=0x%x", psHu32(DMAC_STAT));
break; break;
jNO_DEFAULT; jNO_DEFAULT;
@ -465,7 +465,7 @@ __forceinline void __fastcall hwWrite32(u32 mem, u32 value)
case 0x10001820: rcntWtarget(3, value); break; case 0x10001820: rcntWtarget(3, value); break;
case GIF_CTRL: case GIF_CTRL:
//SysPrintf("GIF_CTRL write %x\n", value); //Console::WriteLn("GIF_CTRL write %x", params value);
psHu32(mem) = value & 0x8; psHu32(mem) = value & 0x8;
if (value & 0x1) gsGIFReset(); if (value & 0x1) gsGIFReset();
else if( value & 8 ) psHu32(GIF_STAT) |= 8; else if( value & 8 ) psHu32(GIF_STAT) |= 8;
@ -482,167 +482,167 @@ __forceinline void __fastcall hwWrite32(u32 mem, u32 value)
break; break;
case GIF_STAT: // stat is readonly case GIF_STAT: // stat is readonly
SysPrintf("Gifstat write value = %x\n", value); Console::WriteLn("Gifstat write value = %x", params value);
return; return;
case 0x10008000: // dma0 - vif0 case 0x10008000: // dma0 - vif0
DMA_LOG("VIF0dma %lx\n", value); DMA_LOG("VIF0dma %lx", value);
DmaExec(dmaVIF0, mem, value); DmaExec(dmaVIF0, mem, value);
break; break;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x10009000: // dma1 - vif1 - chcr case 0x10009000: // dma1 - vif1 - chcr
DMA_LOG("VIF1dma CHCR %lx\n", value); DMA_LOG("VIF1dma CHCR %lx", value);
DmaExec(dmaVIF1, mem, value); DmaExec(dmaVIF1, mem, value);
break; break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x10009010: // dma1 - vif1 - madr case 0x10009010: // dma1 - vif1 - madr
HW_LOG("VIF1dma Madr %lx\n", value); HW_LOG("VIF1dma Madr %lx", value);
psHu32(mem) = value;//dma1 madr psHu32(mem) = value;//dma1 madr
break; break;
case 0x10009020: // dma1 - vif1 - qwc case 0x10009020: // dma1 - vif1 - qwc
HW_LOG("VIF1dma QWC %lx\n", value); HW_LOG("VIF1dma QWC %lx", value);
psHu32(mem) = value;//dma1 qwc psHu32(mem) = value;//dma1 qwc
break; break;
case 0x10009030: // dma1 - vif1 - tadr case 0x10009030: // dma1 - vif1 - tadr
HW_LOG("VIF1dma TADR %lx\n", value); HW_LOG("VIF1dma TADR %lx", value);
psHu32(mem) = value;//dma1 tadr psHu32(mem) = value;//dma1 tadr
break; break;
case 0x10009040: // dma1 - vif1 - asr0 case 0x10009040: // dma1 - vif1 - asr0
HW_LOG("VIF1dma ASR0 %lx\n", value); HW_LOG("VIF1dma ASR0 %lx", value);
psHu32(mem) = value;//dma1 asr0 psHu32(mem) = value;//dma1 asr0
break; break;
case 0x10009050: // dma1 - vif1 - asr1 case 0x10009050: // dma1 - vif1 - asr1
HW_LOG("VIF1dma ASR1 %lx\n", value); HW_LOG("VIF1dma ASR1 %lx", value);
psHu32(mem) = value;//dma1 asr1 psHu32(mem) = value;//dma1 asr1
break; break;
case 0x10009080: // dma1 - vif1 - sadr case 0x10009080: // dma1 - vif1 - sadr
HW_LOG("VIF1dma SADR %lx\n", value); HW_LOG("VIF1dma SADR %lx", value);
psHu32(mem) = value;//dma1 sadr psHu32(mem) = value;//dma1 sadr
break; break;
#endif #endif
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000a000: // dma2 - gif case 0x1000a000: // dma2 - gif
DMA_LOG("0x%8.8x hwWrite32: GSdma %lx\n", cpuRegs.cycle, value); DMA_LOG("0x%8.8x hwWrite32: GSdma %lx", cpuRegs.cycle, value);
DmaExec(dmaGIF, mem, value); DmaExec(dmaGIF, mem, value);
break; break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x1000a010: case 0x1000a010:
psHu32(mem) = value;//dma2 madr psHu32(mem) = value;//dma2 madr
HW_LOG("Hardware write DMA2_MADR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write DMA2_MADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a020: case 0x1000a020:
psHu32(mem) = value;//dma2 qwc psHu32(mem) = value;//dma2 qwc
HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a030: case 0x1000a030:
psHu32(mem) = value;//dma2 taddr psHu32(mem) = value;//dma2 taddr
HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a040: case 0x1000a040:
psHu32(mem) = value;//dma2 asr0 psHu32(mem) = value;//dma2 asr0
HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a050: case 0x1000a050:
psHu32(mem) = value;//dma2 asr1 psHu32(mem) = value;//dma2 asr1
HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a080: case 0x1000a080:
psHu32(mem) = value;//dma2 saddr psHu32(mem) = value;//dma2 saddr
HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x",mem,value);
break; break;
#endif #endif
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000b000: // dma3 - fromIPU case 0x1000b000: // dma3 - fromIPU
DMA_LOG("IPU0dma %lx\n", value); DMA_LOG("IPU0dma %lx", value);
DmaExec(dmaIPU0, mem, value); DmaExec(dmaIPU0, mem, value);
break; break;
//------------------------------------------------------------------ //------------------------------------------------------------------
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x1000b010: case 0x1000b010:
psHu32(mem) = value;//dma2 madr psHu32(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU0DMA_MADR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU0DMA_MADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b020: case 0x1000b020:
psHu32(mem) = value;//dma2 madr psHu32(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU0DMA_QWC 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU0DMA_QWC 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b030: case 0x1000b030:
psHu32(mem) = value;//dma2 tadr psHu32(mem) = value;//dma2 tadr
HW_LOG("Hardware write IPU0DMA_TADR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU0DMA_TADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b080: case 0x1000b080:
psHu32(mem) = value;//dma2 saddr psHu32(mem) = value;//dma2 saddr
HW_LOG("Hardware write IPU0DMA_SADDR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU0DMA_SADDR 32bit at %x with value %x",mem,value);
break; break;
#endif #endif
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000b400: // dma4 - toIPU case 0x1000b400: // dma4 - toIPU
DMA_LOG("IPU1dma %lx\n", value); DMA_LOG("IPU1dma %lx", value);
DmaExec(dmaIPU1, mem, value); DmaExec(dmaIPU1, mem, value);
break; break;
//------------------------------------------------------------------ //------------------------------------------------------------------
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x1000b410: case 0x1000b410:
psHu32(mem) = value;//dma2 madr psHu32(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU1DMA_MADR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU1DMA_MADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b420: case 0x1000b420:
psHu32(mem) = value;//dma2 madr psHu32(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU1DMA_QWC 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU1DMA_QWC 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b430: case 0x1000b430:
psHu32(mem) = value;//dma2 tadr psHu32(mem) = value;//dma2 tadr
HW_LOG("Hardware write IPU1DMA_TADR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU1DMA_TADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b480: case 0x1000b480:
psHu32(mem) = value;//dma2 saddr psHu32(mem) = value;//dma2 saddr
HW_LOG("Hardware write IPU1DMA_SADDR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU1DMA_SADDR 32bit at %x with value %x",mem,value);
break; break;
#endif #endif
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000c000: // dma5 - sif0 case 0x1000c000: // dma5 - sif0
DMA_LOG("SIF0dma %lx\n", value); DMA_LOG("SIF0dma %lx", value);
//if (value == 0) psxSu32(0x30) = 0x40000; //if (value == 0) psxSu32(0x30) = 0x40000;
DmaExec(dmaSIF0, mem, value); DmaExec(dmaSIF0, mem, value);
break; break;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000c400: // dma6 - sif1 case 0x1000c400: // dma6 - sif1
DMA_LOG("SIF1dma %lx\n", value); DMA_LOG("SIF1dma %lx", value);
DmaExec(dmaSIF1, mem, value); DmaExec(dmaSIF1, mem, value);
break; break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x1000c420: // dma6 - sif1 - qwc case 0x1000c420: // dma6 - sif1 - qwc
HW_LOG("SIF1dma QWC = %lx\n", value); HW_LOG("SIF1dma QWC = %lx", value);
psHu32(mem) = value; psHu32(mem) = value;
break; break;
case 0x1000c430: // dma6 - sif1 - tadr case 0x1000c430: // dma6 - sif1 - tadr
HW_LOG("SIF1dma TADR = %lx\n", value); HW_LOG("SIF1dma TADR = %lx", value);
psHu32(mem) = value; psHu32(mem) = value;
break; break;
#endif #endif
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000c800: // dma7 - sif2 case 0x1000c800: // dma7 - sif2
DMA_LOG("SIF2dma %lx\n", value); DMA_LOG("SIF2dma %lx", value);
DmaExec(dmaSIF2, mem, value); DmaExec(dmaSIF2, mem, value);
break; break;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000d000: // dma8 - fromSPR case 0x1000d000: // dma8 - fromSPR
DMA_LOG("fromSPRdma %lx\n", value); DMA_LOG("fromSPRdma %lx", value);
DmaExec(dmaSPR0, mem, value); DmaExec(dmaSPR0, mem, value);
break; break;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000d400: // dma9 - toSPR case 0x1000d400: // dma9 - toSPR
DMA_LOG("toSPRdma %lx\n", value); DMA_LOG("toSPRdma %lx", value);
DmaExec(dmaSPR1, mem, value); DmaExec(dmaSPR1, mem, value);
break; break;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000e000: // DMAC_CTRL case 0x1000e000: // DMAC_CTRL
HW_LOG("DMAC_CTRL Write 32bit %x\n", value); HW_LOG("DMAC_CTRL Write 32bit %x", value);
psHu32(0xe000) = value; psHu32(0xe000) = value;
break; break;
case 0x1000e010: // DMAC_STAT case 0x1000e010: // DMAC_STAT
HW_LOG("DMAC_STAT Write 32bit %x\n", value); HW_LOG("DMAC_STAT Write 32bit %x", value);
psHu16(0xe010)&= ~(value & 0xffff); // clear on 1 psHu16(0xe010)&= ~(value & 0xffff); // clear on 1
psHu16(0xe012) ^= (u16)(value >> 16); psHu16(0xe012) ^= (u16)(value >> 16);
@ -650,13 +650,13 @@ __forceinline void __fastcall hwWrite32(u32 mem, u32 value)
break; break;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000f000: // INTC_STAT case 0x1000f000: // INTC_STAT
HW_LOG("INTC_STAT Write 32bit %x\n", value); HW_LOG("INTC_STAT Write 32bit %x", value);
psHu32(0xf000)&=~value; psHu32(0xf000)&=~value;
//cpuTestINTCInts(); //cpuTestINTCInts();
break; break;
case 0x1000f010: // INTC_MASK case 0x1000f010: // INTC_MASK
HW_LOG("INTC_MASK Write 32bit %x\n", value); HW_LOG("INTC_MASK Write 32bit %x", value);
psHu32(0xf010) ^= (u16)value; psHu32(0xf010) ^= (u16)value;
cpuTestINTCInts(); cpuTestINTCInts();
break; break;
@ -672,7 +672,7 @@ __forceinline void __fastcall hwWrite32(u32 mem, u32 value)
break; break;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000f590: // DMAC_ENABLEW case 0x1000f590: // DMAC_ENABLEW
HW_LOG("DMAC_ENABLEW Write 32bit %lx\n", value); HW_LOG("DMAC_ENABLEW Write 32bit %lx", value);
psHu32(0xf590) = value; psHu32(0xf590) = value;
psHu32(0xf520) = value; psHu32(0xf520) = value;
return; return;
@ -698,12 +698,12 @@ __forceinline void __fastcall hwWrite32(u32 mem, u32 value)
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000f130: case 0x1000f130:
case 0x1000f410: case 0x1000f410:
HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)\n", mem, value, cpuRegs.CP0.n.Status.val); HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)", mem, value, cpuRegs.CP0.n.Status.val);
break; break;
//------------------------------------------------------------------ //------------------------------------------------------------------
default: default:
psHu32(mem) = value; psHu32(mem) = value;
HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)\n", mem, value, cpuRegs.CP0.n.Status.val); HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)", mem, value, cpuRegs.CP0.n.Status.val);
break; break;
} }
} }
@ -745,7 +745,7 @@ __forceinline void hwWrite64(u32 mem, u64 value)
case GIF_MODE: case GIF_MODE:
#ifdef GSPATH3FIX #ifdef GSPATH3FIX
Console::Status("GIFMODE64 %x\n", params value); Console::Status("GIFMODE64 %x", params value);
#endif #endif
psHu64(GIF_MODE) = value; psHu64(GIF_MODE) = value;
if (value & 0x1) psHu32(GIF_STAT)|= 0x1; if (value & 0x1) psHu32(GIF_STAT)|= 0x1;
@ -758,17 +758,17 @@ __forceinline void hwWrite64(u32 mem, u64 value)
return; return;
case 0x1000a000: // dma2 - gif case 0x1000a000: // dma2 - gif
DMA_LOG("0x%8.8x hwWrite64: GSdma %lx\n", cpuRegs.cycle, value); DMA_LOG("0x%8.8x hwWrite64: GSdma %lx", cpuRegs.cycle, value);
DmaExec(dmaGIF, mem, value); DmaExec(dmaGIF, mem, value);
break; break;
case 0x1000e000: // DMAC_CTRL case 0x1000e000: // DMAC_CTRL
HW_LOG("DMAC_CTRL Write 64bit %x\n", value); HW_LOG("DMAC_CTRL Write 64bit %x", value);
psHu64(mem) = value; psHu64(mem) = value;
break; break;
case 0x1000e010: // DMAC_STAT case 0x1000e010: // DMAC_STAT
HW_LOG("DMAC_STAT Write 64bit %x\n", value); HW_LOG("DMAC_STAT Write 64bit %x", value);
val32 = (u32)value; val32 = (u32)value;
psHu16(0xe010)&= ~(val32 & 0xffff); // clear on 1 psHu16(0xe010)&= ~(val32 & 0xffff); // clear on 1
val32 = val32 >> 16; val32 = val32 >> 16;
@ -789,13 +789,13 @@ __forceinline void hwWrite64(u32 mem, u64 value)
break; break;
case 0x1000f000: // INTC_STAT case 0x1000f000: // INTC_STAT
HW_LOG("INTC_STAT Write 64bit %x\n", value); HW_LOG("INTC_STAT Write 64bit %x", value);
psHu32(INTC_STAT)&=~value; psHu32(INTC_STAT)&=~value;
cpuTestINTCInts(); cpuTestINTCInts();
break; break;
case 0x1000f010: // INTC_MASK case 0x1000f010: // INTC_MASK
HW_LOG("INTC_MASK Write 32bit %x\n", value); HW_LOG("INTC_MASK Write 32bit %x", value);
for (i=0; i<16; i++) { // reverse on 1 for (i=0; i<16; i++) { // reverse on 1
const int s = (1<<i); const int s = (1<<i);
if (value & s) { if (value & s) {
@ -816,7 +816,7 @@ __forceinline void hwWrite64(u32 mem, u64 value)
default: default:
psHu64(mem) = value; psHu64(mem) = value;
HW_LOG("Unknown Hardware write 64 at %x with value %x (status=%x)\n",mem,value, cpuRegs.CP0.n.Status.val); HW_LOG("Unknown Hardware write 64 at %x with value %x (status=%x)",mem,value, cpuRegs.CP0.n.Status.val);
break; break;
} }
} }
@ -842,7 +842,7 @@ __forceinline void hwWrite128(u32 mem, const u64 *value)
psHu64(mem ) = value[0]; psHu64(mem ) = value[0];
psHu64(mem+8) = value[1]; psHu64(mem+8) = value[1];
HW_LOG("Unknown Hardware write 128 at %x with value %x_%x (status=%x)\n", mem, value[1], value[0], cpuRegs.CP0.n.Status.val); HW_LOG("Unknown Hardware write 128 at %x with value %x_%x (status=%x)", mem, value[1], value[0], cpuRegs.CP0.n.Status.val);
break; break;
} }
} }

View File

@ -320,7 +320,7 @@ static __forceinline u8* dmaGetAddr(u32 mem)
mem &= ~0xf; mem &= ~0xf;
if( (mem&0xffff0000) == 0x50000000 ) {// reserved scratch pad mem if( (mem&0xffff0000) == 0x50000000 ) {// reserved scratch pad mem
SysPrintf("dmaGetAddr: reserved scratch pad mem\n"); Console::WriteLn("dmaGetAddr: reserved scratch pad mem");
return NULL;//(u8*)&PS2MEM_SCRATCH[(mem) & 0x3ff0]; return NULL;//(u8*)&PS2MEM_SCRATCH[(mem) & 0x3ff0];
} }
@ -330,13 +330,12 @@ static __forceinline u8* dmaGetAddr(u32 mem)
// do manual LUT since IPU/SPR seems to use addrs 0x3000xxxx quite often // do manual LUT since IPU/SPR seems to use addrs 0x3000xxxx quite often
// linux doesn't suffer from this because it has better vm support // linux doesn't suffer from this because it has better vm support
if( memLUT[ (p-PS2MEM_BASE)>>12 ].aPFNs == NULL ) { if( memLUT[ (p-PS2MEM_BASE)>>12 ].aPFNs == NULL ) {
SysPrintf("dmaGetAddr: memLUT PFN warning\n"); Console::WriteLn("dmaGetAddr: memLUT PFN warning");
return NULL;//p; return NULL;//p;
} }
pbase = (u8*)memLUT[ (p-PS2MEM_BASE)>>12 ].aVFNs[0]; pbase = (u8*)memLUT[ (p-PS2MEM_BASE)>>12 ].aVFNs[0];
if( pbase != NULL ) if( pbase != NULL ) p = pbase + ((u32)p&0xfff);
p = pbase + ((u32)p&0xfff);
#endif #endif
return p; return p;
@ -348,7 +347,7 @@ static __forceinline u8* dmaGetAddr(u32 mem)
static __forceinline void *dmaGetAddr(u32 addr) { static __forceinline void *dmaGetAddr(u32 addr) {
u8 *ptr; u8 *ptr;
// if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x\n", addr); } // if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); }
if (addr & 0x80000000) { // teh sux why the f00k 0xE0000000 if (addr & 0x80000000) { // teh sux why the f00k 0xE0000000
return (void*)&psS[addr & 0x3ff0]; return (void*)&psS[addr & 0x3ff0];

View File

@ -106,7 +106,7 @@ __forceinline u8 hwRead8(u32 mem)
} }
ret = psHu8(mem); ret = psHu8(mem);
HW_LOG("Unknown Hardware Read 8 from 0x%x = 0x%x\n", mem, ret); HW_LOG("Unknown Hardware Read 8 from 0x%x = 0x%x", mem, ret);
break; break;
} }
@ -156,7 +156,7 @@ __forceinline u16 hwRead16(u32 mem)
return (u16)ret; return (u16)ret;
} }
ret = psHu16(mem); ret = psHu16(mem);
HW_LOG("Hardware Read16 at 0x%x, value= 0x%x\n", ret, mem); HW_LOG("Hardware Read16 at 0x%x, value= 0x%x", ret, mem);
break; break;
} }
return ret; return ret;
@ -217,11 +217,11 @@ static __forceinline mem32_t __hwRead32_page_0F( u32 mem, bool intchack )
case 0xf000: case 0xf000:
if( intchack ) IntCHackCheck(); if( intchack ) IntCHackCheck();
// This one is checked alot, so leave it commented out unless you love 600 meg logfiles. // This one is checked alot, so leave it commented out unless you love 600 meg logfiles.
//HW_LOG("INTC_STAT Read 32bit %x\n", psHu32(0xf010)); //HW_LOG("INTC_STAT Read 32bit %x", psHu32(0xf010));
break; break;
case 0xf010: case 0xf010:
HW_LOG("INTC_MASK Read32, value=0x%x\n", psHu32(INTC_MASK)); HW_LOG("INTC_MASK Read32, value=0x%x", psHu32(INTC_MASK));
break; break;
case 0xf130: // 0x1000f130 case 0xf130: // 0x1000f130
@ -314,19 +314,19 @@ mem32_t __fastcall hwRead32_generic(u32 mem)
case D2_SADR: regName = "DMA2_SADDR"; break; case D2_SADR: regName = "DMA2_SADDR"; break;
} }
HW_LOG( "Hardware Read32 at 0x%x (%s), value=0x%x\n", mem, regName, psHu32(mem) ); HW_LOG( "Hardware Read32 at 0x%x (%s), value=0x%x", mem, regName, psHu32(mem) );
} }
break; break;
case 0x0b: case 0x0b:
if( mem == D4_CHCR ) if( mem == D4_CHCR )
HW_LOG("Hardware Read32 at 0x%x (IPU1:DMA4_CHCR), value=0x%x\n", mem, psHu32(mem)); HW_LOG("Hardware Read32 at 0x%x (IPU1:DMA4_CHCR), value=0x%x", mem, psHu32(mem));
break; break;
case 0x0c: case 0x0c:
case 0x0e: case 0x0e:
if( mem == DMAC_STAT) if( mem == DMAC_STAT)
HW_LOG("DMAC_STAT Read32, value=0x%x\n", psHu32(DMAC_STAT)); HW_LOG("DMAC_STAT Read32, value=0x%x", psHu32(DMAC_STAT));
break; break;
jNO_DEFAULT; jNO_DEFAULT;
@ -358,13 +358,13 @@ void __fastcall hwRead64_generic_INTC_HACK(u32 mem, mem64_t* result )
if( mem == INTC_STAT ) IntCHackCheck(); if( mem == INTC_STAT ) IntCHackCheck();
*result = psHu64(mem); *result = psHu64(mem);
HW_LOG("Unknown Hardware Read 64 at %x\n",mem); HW_LOG("Unknown Hardware Read 64 at %x",mem);
} }
void __fastcall hwRead64_generic(u32 mem, mem64_t* result ) void __fastcall hwRead64_generic(u32 mem, mem64_t* result )
{ {
*result = psHu64(mem); *result = psHu64(mem);
HW_LOG("Unknown Hardware Read 64 at %x\n",mem); HW_LOG("Unknown Hardware Read 64 at %x",mem);
} }
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
@ -385,7 +385,7 @@ void __fastcall hwRead128_page_01(u32 mem, mem128_t* result )
void __fastcall hwRead128_page_02(u32 mem, mem128_t* result ) void __fastcall hwRead128_page_02(u32 mem, mem128_t* result )
{ {
// IPU is currently unhandled in 128 bit mode. // IPU is currently unhandled in 128 bit mode.
HW_LOG("Unknown Hardware Read 128 at %x (IPU)\n",mem); HW_LOG("Unknown Hardware Read 128 at %x (IPU)",mem);
} }
void __fastcall hwRead128_generic(u32 mem, mem128_t* out) void __fastcall hwRead128_generic(u32 mem, mem128_t* out)
@ -393,5 +393,5 @@ void __fastcall hwRead128_generic(u32 mem, mem128_t* out)
out[0] = psHu64(mem); out[0] = psHu64(mem);
out[1] = psHu64(mem+8); out[1] = psHu64(mem+8);
HW_LOG("Unknown Hardware Read 128 at %x\n",mem); HW_LOG("Unknown Hardware Read 128 at %x",mem);
} }

View File

@ -48,7 +48,7 @@ static __forceinline void DmaExec8( void (*func)(), u32 mem, u8 value )
psHu8(mem) = (u8)value; psHu8(mem) = (u8)value;
if ((psHu8(mem) & 0x1) && (psHu32(DMAC_CTRL) & 0x1)) if ((psHu8(mem) & 0x1) && (psHu32(DMAC_CTRL) & 0x1))
{ {
/*SysPrintf("Running DMA 8 %x\n", psHu32(mem & ~0x1));*/ /*Console::WriteLn("Running DMA 8 %x", params psHu32(mem & ~0x1));*/
func(); func();
} }
} }
@ -63,7 +63,7 @@ static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value )
psHu16(mem) = (u16)value; psHu16(mem) = (u16)value;
if ((psHu16(mem) & 0x100) && (psHu32(DMAC_CTRL) & 0x1)) if ((psHu16(mem) & 0x100) && (psHu32(DMAC_CTRL) & 0x1))
{ {
//SysPrintf("16bit DMA Start\n"); //Console::WriteLn("16bit DMA Start");
func(); func();
} }
} }
@ -83,8 +83,6 @@ static void DmaExec( void (*func)(), u32 mem, u32 value )
if ((psHu32(mem) & 0x100) && (psHu32(DMAC_CTRL) & 0x1)) if ((psHu32(mem) & 0x100) && (psHu32(DMAC_CTRL) & 0x1))
func(); func();
} }
@ -93,6 +91,7 @@ static void DmaExec( void (*func)(), u32 mem, u32 value )
char sio_buffer[1024]; char sio_buffer[1024];
int sio_count; int sio_count;
u16 QueuedDMA = 0;
void hwWrite8(u32 mem, u8 value) { void hwWrite8(u32 mem, u8 value) {
@ -151,54 +150,104 @@ void hwWrite8(u32 mem, u8 value) {
// vif1Write32(mem & ~0x2, value << 16); // vif1Write32(mem & ~0x2, value << 16);
// break; // break;
case 0x10008001: // dma0 - vif0 case 0x10008001: // dma0 - vif0
DMA_LOG("VIF0dma EXECUTE, value=0x%x\n", value); DMA_LOG("VIF0dma EXECUTE, value=0x%x", value);
if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("8 bit VIF0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x1;
}
DmaExec8(dmaVIF0, mem, value); DmaExec8(dmaVIF0, mem, value);
break; break;
case 0x10009001: // dma1 - vif1 case 0x10009001: // dma1 - vif1
DMA_LOG("VIF1dma EXECUTE, value=0x%x\n", value); DMA_LOG("VIF1dma EXECUTE, value=0x%x", value);
if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("8 bit VIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x2;
}
if(value & 0x1) vif1.done = 0; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO if(value & 0x1) vif1.done = 0; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO
DmaExec8(dmaVIF1, mem, value); DmaExec8(dmaVIF1, mem, value);
break; break;
case 0x1000a001: // dma2 - gif case 0x1000a001: // dma2 - gif
DMA_LOG("GSdma EXECUTE, value=0x%x\n", value); DMA_LOG("GSdma EXECUTE, value=0x%x", value);
if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("8 bit GIF DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x4;
}
DmaExec8(dmaGIF, mem, value); DmaExec8(dmaGIF, mem, value);
break; break;
case 0x1000b001: // dma3 - fromIPU case 0x1000b001: // dma3 - fromIPU
DMA_LOG("IPU0dma EXECUTE, value=0x%x\n", value); DMA_LOG("IPU0dma EXECUTE, value=0x%x", value);
if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("8 bit IPU0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x8;
}
DmaExec8(dmaIPU0, mem, value); DmaExec8(dmaIPU0, mem, value);
break; break;
case 0x1000b401: // dma4 - toIPU case 0x1000b401: // dma4 - toIPU
DMA_LOG("IPU1dma EXECUTE, value=0x%x\n", value); DMA_LOG("IPU1dma EXECUTE, value=0x%x", value);
if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("8 bit IPU1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x10;
}
DmaExec8(dmaIPU1, mem, value); DmaExec8(dmaIPU1, mem, value);
break; break;
case 0x1000c001: // dma5 - sif0 case 0x1000c001: // dma5 - sif0
DMA_LOG("SIF0dma EXECUTE, value=0x%x\n", value); DMA_LOG("SIF0dma EXECUTE, value=0x%x", value);
// if (value == 0) psxSu32(0x30) = 0x40000; // if (value == 0) psxSu32(0x30) = 0x40000;
if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("8 bit SIF0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x20;
}
DmaExec8(dmaSIF0, mem, value); DmaExec8(dmaSIF0, mem, value);
break; break;
case 0x1000c401: // dma6 - sif1 case 0x1000c401: // dma6 - sif1
DMA_LOG("SIF1dma EXECUTE, value=0x%x\n", value); DMA_LOG("SIF1dma EXECUTE, value=0x%x", value);
if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("8 bit SIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x40;
}
DmaExec8(dmaSIF1, mem, value); DmaExec8(dmaSIF1, mem, value);
break; break;
case 0x1000c801: // dma7 - sif2 case 0x1000c801: // dma7 - sif2
DMA_LOG("SIF2dma EXECUTE, value=0x%x\n", value); DMA_LOG("SIF2dma EXECUTE, value=0x%x", value);
if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("8 bit SIF2 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x80;
}
DmaExec8(dmaSIF2, mem, value); DmaExec8(dmaSIF2, mem, value);
break; break;
case 0x1000d001: // dma8 - fromSPR case 0x1000d001: // dma8 - fromSPR
DMA_LOG("fromSPRdma8 EXECUTE, value=0x%x\n", value); DMA_LOG("fromSPRdma8 EXECUTE, value=0x%x", value);
if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("8 bit SPR0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x100;
}
DmaExec8(dmaSPR0, mem, value); DmaExec8(dmaSPR0, mem, value);
break; break;
case 0x1000d401: // dma9 - toSPR case 0x1000d401: // dma9 - toSPR
DMA_LOG("toSPRdma8 EXECUTE, value=0x%x\n", value); DMA_LOG("toSPRdma8 EXECUTE, value=0x%x", value);
if ((value & 0x1) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("8 bit SPR1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x200;
}
DmaExec8(dmaSPR1, mem, value); DmaExec8(dmaSPR1, mem, value);
break; break;
@ -227,7 +276,7 @@ void hwWrite8(u32 mem, u8 value) {
default: default:
psHu8(mem) = value; psHu8(mem) = value;
} }
HW_LOG("Unknown Hardware write 8 at %x with value %x\n", mem, value); HW_LOG("Unknown Hardware write 8 at %x with value %x", mem, value);
break; break;
} }
} }
@ -258,126 +307,156 @@ __forceinline void hwWrite16(u32 mem, u16 value)
case 0x10001820: rcntWtarget(3, value); break; case 0x10001820: rcntWtarget(3, value); break;
case 0x10008000: // dma0 - vif0 case 0x10008000: // dma0 - vif0
DMA_LOG("VIF0dma %lx\n", value); DMA_LOG("VIF0dma %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("16 bit VIF0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x1;
}
DmaExec16(dmaVIF0, mem, value); DmaExec16(dmaVIF0, mem, value);
break; break;
case 0x10009000: // dma1 - vif1 - chcr case 0x10009000: // dma1 - vif1 - chcr
DMA_LOG("VIF1dma CHCR %lx\n", value); DMA_LOG("VIF1dma CHCR %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("16 bit VIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x2;
}
if(value & 0x100) vif1.done = 0; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO if(value & 0x100) vif1.done = 0; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO
DmaExec16(dmaVIF1, mem, value); DmaExec16(dmaVIF1, mem, value);
break; break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x10009010: // dma1 - vif1 - madr case 0x10009010: // dma1 - vif1 - madr
HW_LOG("VIF1dma Madr %lx\n", value); HW_LOG("VIF1dma Madr %lx", value);
psHu16(mem) = value;//dma1 madr psHu16(mem) = value;//dma1 madr
break; break;
case 0x10009020: // dma1 - vif1 - qwc case 0x10009020: // dma1 - vif1 - qwc
HW_LOG("VIF1dma QWC %lx\n", value); HW_LOG("VIF1dma QWC %lx", value);
psHu16(mem) = value;//dma1 qwc psHu16(mem) = value;//dma1 qwc
break; break;
case 0x10009030: // dma1 - vif1 - tadr case 0x10009030: // dma1 - vif1 - tadr
HW_LOG("VIF1dma TADR %lx\n", value); HW_LOG("VIF1dma TADR %lx", value);
psHu16(mem) = value;//dma1 tadr psHu16(mem) = value;//dma1 tadr
break; break;
case 0x10009040: // dma1 - vif1 - asr0 case 0x10009040: // dma1 - vif1 - asr0
HW_LOG("VIF1dma ASR0 %lx\n", value); HW_LOG("VIF1dma ASR0 %lx", value);
psHu16(mem) = value;//dma1 asr0 psHu16(mem) = value;//dma1 asr0
break; break;
case 0x10009050: // dma1 - vif1 - asr1 case 0x10009050: // dma1 - vif1 - asr1
HW_LOG("VIF1dma ASR1 %lx\n", value); HW_LOG("VIF1dma ASR1 %lx", value);
psHu16(mem) = value;//dma1 asr1 psHu16(mem) = value;//dma1 asr1
break; break;
case 0x10009080: // dma1 - vif1 - sadr case 0x10009080: // dma1 - vif1 - sadr
HW_LOG("VIF1dma SADR %lx\n", value); HW_LOG("VIF1dma SADR %lx", value);
psHu16(mem) = value;//dma1 sadr psHu16(mem) = value;//dma1 sadr
break; break;
#endif #endif
// --------------------------------------------------- // ---------------------------------------------------
case 0x1000a000: // dma2 - gif case 0x1000a000: // dma2 - gif
DMA_LOG("0x%8.8x hwWrite32: GSdma %lx\n", cpuRegs.cycle, value); DMA_LOG("0x%8.8x hwWrite32: GSdma %lx", cpuRegs.cycle, value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("16 bit GIF DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x4;
}
DmaExec16(dmaGIF, mem, value); DmaExec16(dmaGIF, mem, value);
break; break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x1000a010: case 0x1000a010:
psHu16(mem) = value;//dma2 madr psHu16(mem) = value;//dma2 madr
HW_LOG("Hardware write DMA2_MADR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write DMA2_MADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a020: case 0x1000a020:
psHu16(mem) = value;//dma2 qwc psHu16(mem) = value;//dma2 qwc
HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a030: case 0x1000a030:
psHu16(mem) = value;//dma2 taddr psHu16(mem) = value;//dma2 taddr
HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a040: case 0x1000a040:
psHu16(mem) = value;//dma2 asr0 psHu16(mem) = value;//dma2 asr0
HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a050: case 0x1000a050:
psHu16(mem) = value;//dma2 asr1 psHu16(mem) = value;//dma2 asr1
HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a080: case 0x1000a080:
psHu16(mem) = value;//dma2 saddr psHu16(mem) = value;//dma2 saddr
HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x",mem,value);
break; break;
#endif #endif
case 0x1000b000: // dma3 - fromIPU case 0x1000b000: // dma3 - fromIPU
DMA_LOG("IPU0dma %lx\n", value); DMA_LOG("IPU0dma %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("16 bit IPU0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x8;
}
DmaExec16(dmaIPU0, mem, value); DmaExec16(dmaIPU0, mem, value);
break; break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x1000b010: case 0x1000b010:
psHu16(mem) = value;//dma2 madr psHu16(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU0DMA_MADR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU0DMA_MADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b020: case 0x1000b020:
psHu16(mem) = value;//dma2 madr psHu16(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU0DMA_QWC 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU0DMA_QWC 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b030: case 0x1000b030:
psHu16(mem) = value;//dma2 tadr psHu16(mem) = value;//dma2 tadr
HW_LOG("Hardware write IPU0DMA_TADR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU0DMA_TADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b080: case 0x1000b080:
psHu16(mem) = value;//dma2 saddr psHu16(mem) = value;//dma2 saddr
HW_LOG("Hardware write IPU0DMA_SADDR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU0DMA_SADDR 32bit at %x with value %x",mem,value);
break; break;
#endif #endif
case 0x1000b400: // dma4 - toIPU case 0x1000b400: // dma4 - toIPU
DMA_LOG("IPU1dma %lx\n", value); DMA_LOG("IPU1dma %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("16 bit IPU1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x10;
}
DmaExec16(dmaIPU1, mem, value); DmaExec16(dmaIPU1, mem, value);
break; break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x1000b410: case 0x1000b410:
psHu16(mem) = value;//dma2 madr psHu16(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU1DMA_MADR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU1DMA_MADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b420: case 0x1000b420:
psHu16(mem) = value;//dma2 madr psHu16(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU1DMA_QWC 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU1DMA_QWC 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b430: case 0x1000b430:
psHu16(mem) = value;//dma2 tadr psHu16(mem) = value;//dma2 tadr
HW_LOG("Hardware write IPU1DMA_TADR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU1DMA_TADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b480: case 0x1000b480:
psHu16(mem) = value;//dma2 saddr psHu16(mem) = value;//dma2 saddr
HW_LOG("Hardware write IPU1DMA_SADDR 32bit at %x with value %x\n",mem,value); HW_LOG("Hardware write IPU1DMA_SADDR 32bit at %x with value %x",mem,value);
break; break;
#endif #endif
case 0x1000c000: // dma5 - sif0 case 0x1000c000: // dma5 - sif0
DMA_LOG("SIF0dma %lx\n", value); DMA_LOG("SIF0dma %lx", value);
// if (value == 0) psxSu32(0x30) = 0x40000; // if (value == 0) psxSu32(0x30) = 0x40000;
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("16 bit SIF0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x20;
}
DmaExec16(dmaSIF0, mem, value); DmaExec16(dmaSIF0, mem, value);
break; break;
@ -385,36 +464,56 @@ __forceinline void hwWrite16(u32 mem, u16 value)
//? //?
break; break;
case 0x1000c400: // dma6 - sif1 case 0x1000c400: // dma6 - sif1
DMA_LOG("SIF1dma %lx\n", value); DMA_LOG("SIF1dma %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("16 bit SIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x40;
}
DmaExec16(dmaSIF1, mem, value); DmaExec16(dmaSIF1, mem, value);
break; break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x1000c420: // dma6 - sif1 - qwc case 0x1000c420: // dma6 - sif1 - qwc
HW_LOG("SIF1dma QWC = %lx\n", value); HW_LOG("SIF1dma QWC = %lx", value);
psHu16(mem) = value; psHu16(mem) = value;
break; break;
case 0x1000c430: // dma6 - sif1 - tadr case 0x1000c430: // dma6 - sif1 - tadr
HW_LOG("SIF1dma TADR = %lx\n", value); HW_LOG("SIF1dma TADR = %lx", value);
psHu16(mem) = value; psHu16(mem) = value;
break; break;
#endif #endif
case 0x1000c800: // dma7 - sif2 case 0x1000c800: // dma7 - sif2
DMA_LOG("SIF2dma %lx\n", value); DMA_LOG("SIF2dma %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("16 bit SIF2 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x80;
}
DmaExec16(dmaSIF2, mem, value); DmaExec16(dmaSIF2, mem, value);
break; break;
case 0x1000c802: case 0x1000c802:
//? //?
break; break;
case 0x1000d000: // dma8 - fromSPR case 0x1000d000: // dma8 - fromSPR
DMA_LOG("fromSPRdma %lx\n", value); DMA_LOG("fromSPRdma %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("16 bit SPR0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x100;
}
DmaExec16(dmaSPR0, mem, value); DmaExec16(dmaSPR0, mem, value);
break; break;
case 0x1000d400: // dma9 - toSPR case 0x1000d400: // dma9 - toSPR
DMA_LOG("toSPRdma %lx\n", value); DMA_LOG("toSPRdma %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("16 bit SPR1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x200;
}
DmaExec16(dmaSPR1, mem, value); DmaExec16(dmaSPR1, mem, value);
break; break;
case 0x1000f592: // DMAC_ENABLEW case 0x1000f592: // DMAC_ENABLEW
@ -451,7 +550,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
default: default:
psHu16(mem) = value; psHu16(mem) = value;
HW_LOG("Unknown Hardware write 16 at %x with value %x\n",mem,value); HW_LOG("Unknown Hardware write 16 at %x with value %x",mem,value);
} }
} }
@ -553,6 +652,11 @@ void __fastcall hwWrite32_page_0B( u32 mem, u32 value )
{ {
case D3_CHCR: // dma3 - fromIPU case D3_CHCR: // dma3 - fromIPU
DMA_LOG("IPU0dma EXECUTE, value=0x%x\n", value); DMA_LOG("IPU0dma EXECUTE, value=0x%x\n", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("32 bit IPU0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x8;
}
DmaExec(dmaIPU0, mem, value); DmaExec(dmaIPU0, mem, value);
return; return;
@ -565,6 +669,11 @@ void __fastcall hwWrite32_page_0B( u32 mem, u32 value )
case D4_CHCR: // dma4 - toIPU case D4_CHCR: // dma4 - toIPU
DMA_LOG("IPU1dma EXECUTE, value=0x%x\n", value); DMA_LOG("IPU1dma EXECUTE, value=0x%x\n", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("32 bit IPU1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x10;
}
DmaExec(dmaIPU1, mem, value); DmaExec(dmaIPU1, mem, value);
return; return;
@ -574,19 +683,40 @@ void __fastcall hwWrite32_page_0B( u32 mem, u32 value )
case D4_SADR: regName = "IPU1DMA_SADDR"; break; case D4_SADR: regName = "IPU1DMA_SADDR"; break;
} }
HW_LOG( "Hardware Write32 at 0x%x (%s), value=0x%x\n", mem, regName, value ); HW_LOG( "Hardware Write32 at 0x%x (%s), value=0x%x", mem, regName, value );
psHu32(mem) = value; psHu32(mem) = value;
} }
void __fastcall StartQueuedDMA()
{
if(QueuedDMA & 0x1) { QueuedDMA &= ~0x1; dmaVIF0(); }
if(QueuedDMA & 0x2) { QueuedDMA &= ~0x2; dmaVIF1(); }
if(QueuedDMA & 0x4) { QueuedDMA &= ~0x4; dmaGIF(); }
if(QueuedDMA & 0x8) { QueuedDMA &= ~0x8; dmaIPU0(); }
if(QueuedDMA & 0x10) { QueuedDMA &= ~0x10; dmaIPU1(); }
if(QueuedDMA & 0x20) { QueuedDMA &= ~0x20; dmaSIF0(); }
if(QueuedDMA & 0x40) { QueuedDMA &= ~0x40; dmaSIF1(); }
if(QueuedDMA & 0x80) { QueuedDMA &= ~0x80; dmaSIF2(); }
if(QueuedDMA & 0x100) { QueuedDMA &= ~0x100; dmaSPR0(); }
if(QueuedDMA & 0x200) { QueuedDMA &= ~0x200; dmaSPR1(); }
}
void __fastcall hwWrite32_page_0E( u32 mem, u32 value ) void __fastcall hwWrite32_page_0E( u32 mem, u32 value )
{ {
if( mem == DMAC_CTRL ) if( mem == DMAC_CTRL )
{ {
HW_LOG("DMAC_CTRL Write 32bit %x\n", value); HW_LOG("DMAC_CTRL Write 32bit %x", value);
//Check for DMAS that were started while the DMAC was disabled
if((psHu32(mem) & 0x1) == 0 && (value & 0x1) == 1)
{
psHu32(mem) = value;
if(QueuedDMA != 0) StartQueuedDMA();
return;
}
} }
else if( mem == DMAC_STAT ) else if( mem == DMAC_STAT )
{ {
HW_LOG("DMAC_STAT Write 32bit %x\n", value); HW_LOG("DMAC_STAT Write 32bit %x", value);
// lower 16 bits: clear on 1 // lower 16 bits: clear on 1
// upper 16 bits: reverse on 1 // upper 16 bits: reverse on 1
@ -611,13 +741,13 @@ void __fastcall hwWrite32_page_0F( u32 mem, u32 value )
switch( HELPSWITCH(mem) ) switch( HELPSWITCH(mem) )
{ {
case HELPSWITCH(INTC_STAT): case HELPSWITCH(INTC_STAT):
HW_LOG("INTC_STAT Write 32bit %x\n", value); HW_LOG("INTC_STAT Write 32bit %x", value);
psHu32(INTC_STAT) &= ~value; psHu32(INTC_STAT) &= ~value;
//cpuTestINTCInts(); //cpuTestINTCInts();
break; break;
case HELPSWITCH(INTC_MASK): case HELPSWITCH(INTC_MASK):
HW_LOG("INTC_MASK Write 32bit %x\n", value); HW_LOG("INTC_MASK Write 32bit %x", value);
psHu32(INTC_MASK) ^= (u16)value; psHu32(INTC_MASK) ^= (u16)value;
cpuTestINTCInts(); cpuTestINTCInts();
break; break;
@ -653,7 +783,7 @@ void __fastcall hwWrite32_page_0F( u32 mem, u32 value )
break; break;
case HELPSWITCH(0x1000f590): // DMAC_ENABLEW case HELPSWITCH(0x1000f590): // DMAC_ENABLEW
HW_LOG("DMAC_ENABLEW Write 32bit %lx\n", value); HW_LOG("DMAC_ENABLEW Write 32bit %lx", value);
psHu32(0xf590) = value; psHu32(0xf590) = value;
psHu32(0xf520) = value; psHu32(0xf520) = value;
break; break;
@ -661,7 +791,7 @@ void __fastcall hwWrite32_page_0F( u32 mem, u32 value )
//------------------------------------------------------------------ //------------------------------------------------------------------
case HELPSWITCH(0x1000f130): case HELPSWITCH(0x1000f130):
case HELPSWITCH(0x1000f410): case HELPSWITCH(0x1000f410):
HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)\n", mem, value, cpuRegs.CP0.n.Status.val); HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)", mem, value, cpuRegs.CP0.n.Status.val);
break; break;
default: default:
@ -677,13 +807,23 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
switch (mem) switch (mem)
{ {
case D0_CHCR: // dma0 - vif0 case D0_CHCR: // dma0 - vif0
DMA_LOG("VIF0dma EXECUTE, value=0x%x\n", value); DMA_LOG("VIF0dma EXECUTE, value=0x%x", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("32 bit VIF0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x1;
}
DmaExec(dmaVIF0, mem, value); DmaExec(dmaVIF0, mem, value);
return; return;
//------------------------------------------------------------------ //------------------------------------------------------------------
case D1_CHCR: // dma1 - vif1 - chcr case D1_CHCR: // dma1 - vif1 - chcr
DMA_LOG("VIF1dma EXECUTE, value=0x%x\n", value); DMA_LOG("VIF1dma EXECUTE, value=0x%x", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("32 bit VIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x2;
}
if(value & 0x100) if(value & 0x100)
{ {
vif1.done = 0; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO vif1.done = 0; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO
@ -701,6 +841,11 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
//------------------------------------------------------------------ //------------------------------------------------------------------
case D2_CHCR: // dma2 - gif case D2_CHCR: // dma2 - gif
DMA_LOG("GIFdma EXECUTE, value=0x%x", value); DMA_LOG("GIFdma EXECUTE, value=0x%x", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("32 bit GIF DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x4;
}
DmaExec(dmaGIF, mem, value); DmaExec(dmaGIF, mem, value);
return; return;
@ -713,13 +858,23 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000c000: // dma5 - sif0 case 0x1000c000: // dma5 - sif0
DMA_LOG("SIF0dma EXECUTE, value=0x%x\n", value); DMA_LOG("SIF0dma EXECUTE, value=0x%x", value);
//if (value == 0) psxSu32(0x30) = 0x40000; //if (value == 0) psxSu32(0x30) = 0x40000;
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("32 bit SIF0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x20;
}
DmaExec(dmaSIF0, mem, value); DmaExec(dmaSIF0, mem, value);
return; return;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000c400: // dma6 - sif1 case 0x1000c400: // dma6 - sif1
DMA_LOG("SIF1dma EXECUTE, value=0x%x\n", value); DMA_LOG("SIF1dma EXECUTE, value=0x%x", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("32 bit SIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x40;
}
DmaExec(dmaSIF1, mem, value); DmaExec(dmaSIF1, mem, value);
return; return;
@ -728,21 +883,36 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000c800: // dma7 - sif2 case 0x1000c800: // dma7 - sif2
DMA_LOG("SIF2dma EXECUTE, value=0x%x\n", value); DMA_LOG("SIF2dma EXECUTE, value=0x%x", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("32 bit SIF2 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x80;
}
DmaExec(dmaSIF2, mem, value); DmaExec(dmaSIF2, mem, value);
return; return;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000d000: // dma8 - fromSPR case 0x1000d000: // dma8 - fromSPR
DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x\n", value); DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("32 bit SPR0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x100;
}
DmaExec(dmaSPR0, mem, value); DmaExec(dmaSPR0, mem, value);
return; return;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000d400: // dma9 - toSPR case 0x1000d400: // dma9 - toSPR
DMA_LOG("SPR1dma EXECUTE (toSPR), value=0x%x\n", value); DMA_LOG("SPR1dma EXECUTE (toSPR), value=0x%x", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{
DevCon::Notice("32 bit SPR1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x200;
}
DmaExec(dmaSPR1, mem, value); DmaExec(dmaSPR1, mem, value);
return; return;
} }
HW_LOG( "Hardware Write32 at 0x%x (%s), value=0x%x\n", mem, regName, value ); HW_LOG( "Hardware Write32 at 0x%x (%s), value=0x%x", mem, regName, value );
psHu32(mem) = value; psHu32(mem) = value;
} }
@ -789,7 +959,7 @@ void __fastcall hwWrite64_page_03( u32 mem, const mem64_t* srcval )
case GIF_MODE: case GIF_MODE:
{ {
#ifdef GSPATH3FIX #ifdef GSPATH3FIX
Console::Status("GIFMODE64 %x\n", params value); Console::Status("GIFMODE64 %x", params value);
#endif #endif
psHu64(GIF_MODE) = value; psHu64(GIF_MODE) = value;
@ -812,11 +982,17 @@ void __fastcall hwWrite64_page_0E( u32 mem, const mem64_t* srcval )
if( mem == DMAC_CTRL ) if( mem == DMAC_CTRL )
{ {
HW_LOG("DMAC_CTRL Write 64bit %x\n", value); HW_LOG("DMAC_CTRL Write 64bit %x", value);
if((psHu32(mem) & 0x1) == 0 && (value & 0x1) == 1)
{
psHu64(mem) = value;
if(QueuedDMA != 0) StartQueuedDMA();
return;
}
} }
else if( mem == DMAC_STAT ) else if( mem == DMAC_STAT )
{ {
HW_LOG("DMAC_STAT Write 64bit %x\n", value); HW_LOG("DMAC_STAT Write 64bit %x", value);
// lower 16 bits: clear on 1 // lower 16 bits: clear on 1
// upper 16 bits: reverse on 1 // upper 16 bits: reverse on 1
@ -840,18 +1016,18 @@ void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval )
switch (mem) switch (mem)
{ {
case 0x1000a000: // dma2 - gif case 0x1000a000: // dma2 - gif
DMA_LOG("0x%8.8x hwWrite64: GSdma %x\n", cpuRegs.cycle, value); DMA_LOG("0x%8.8x hwWrite64: GSdma %x", cpuRegs.cycle, value);
DmaExec(dmaGIF, mem, value); DmaExec(dmaGIF, mem, value);
break; break;
case INTC_STAT: case INTC_STAT:
HW_LOG("INTC_STAT Write 64bit %x\n", (u32)value); HW_LOG("INTC_STAT Write 64bit %x", (u32)value);
psHu32(INTC_STAT) &= ~value; psHu32(INTC_STAT) &= ~value;
//cpuTestINTCInts(); //cpuTestINTCInts();
break; break;
case INTC_MASK: case INTC_MASK:
HW_LOG("INTC_MASK Write 64bit %x\n", (u32)value); HW_LOG("INTC_MASK Write 64bit %x", (u32)value);
psHu32(INTC_MASK) ^= (u16)value; psHu32(INTC_MASK) ^= (u16)value;
cpuTestINTCInts(); cpuTestINTCInts();
break; break;
@ -868,7 +1044,7 @@ void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval )
default: default:
psHu64(mem) = value; psHu64(mem) = value;
HW_LOG("Unknown Hardware write 64 at %x with value %x (status=%x)\n",mem,value, cpuRegs.CP0.n.Status.val); HW_LOG("Unknown Hardware write 64 at %x with value %x (status=%x)",mem,value, cpuRegs.CP0.n.Status.val);
break; break;
} }
} }
@ -883,13 +1059,13 @@ void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval)
switch (mem) switch (mem)
{ {
case INTC_STAT: case INTC_STAT:
HW_LOG("INTC_STAT Write 64bit %x\n", (u32)srcval[0]); HW_LOG("INTC_STAT Write 64bit %x", (u32)srcval[0]);
psHu32(INTC_STAT) &= ~srcval[0]; psHu32(INTC_STAT) &= ~srcval[0];
//cpuTestINTCInts(); //cpuTestINTCInts();
break; break;
case INTC_MASK: case INTC_MASK:
HW_LOG("INTC_MASK Write 64bit %x\n", (u32)srcval[0]); HW_LOG("INTC_MASK Write 64bit %x", (u32)srcval[0]);
psHu32(INTC_MASK) ^= (u16)srcval[0]; psHu32(INTC_MASK) ^= (u16)srcval[0];
cpuTestINTCInts(); cpuTestINTCInts();
break; break;
@ -908,7 +1084,7 @@ void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval)
psHu64(mem ) = srcval[0]; psHu64(mem ) = srcval[0];
psHu64(mem+8) = srcval[1]; psHu64(mem+8) = srcval[1];
HW_LOG("Unknown Hardware write 128 at %x with value %x_%x (status=%x)\n", mem, srcval[1], srcval[0], cpuRegs.CP0.n.Status.val); HW_LOG("Unknown Hardware write 128 at %x with value %x_%x (status=%x)", mem, srcval[1], srcval[0], cpuRegs.CP0.n.Status.val);
break; break;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -255,6 +255,8 @@ extern void IPUProcessInterrupt();
extern void ipu0Interrupt(); extern void ipu0Interrupt();
extern void ipu1Interrupt(); extern void ipu1Interrupt();
extern void dmaIPU0();
extern void dmaIPU1();
extern u16 __fastcall FillInternalBuffer(u32 * pointer, u32 advance, u32 size); extern u16 __fastcall FillInternalBuffer(u32 * pointer, u32 advance, u32 size);
extern u8 __fastcall getBits32(u8 *address, u32 advance); extern u8 __fastcall getBits32(u8 *address, u32 advance);
extern u8 __fastcall getBits16(u8 *address, u32 advance); extern u8 __fastcall getBits16(u8 *address, u32 advance);

View File

@ -41,36 +41,33 @@ coroutine* g_pCurrentRoutine;
coroutine_t so_create(void (*func)(void *), void *data, void *stack, int size) coroutine_t so_create(void (*func)(void *), void *data, void *stack, int size)
{ {
void* endstack; void* endstack;
int alloc = 0; // r = CO_STK_COROSIZE; int alloc = 0; // r = CO_STK_COROSIZE;
coroutine *co; coroutine *co;
if ((size &= ~(sizeof(long) - 1)) < CO_MIN_SIZE) if ((size &= ~(sizeof(long) - 1)) < CO_MIN_SIZE) return NULL;
return NULL;
if (!stack) { if (!stack) {
size = (size + sizeof(coroutine) + CO_STK_ALIGN - 1) & ~(CO_STK_ALIGN - 1); size = (size + sizeof(coroutine) + CO_STK_ALIGN - 1) & ~(CO_STK_ALIGN - 1);
stack = malloc(size); stack = malloc(size);
if (!stack) if (!stack) return NULL;
return NULL;
alloc = size; alloc = size;
} }
endstack = (char*)stack + size - 64; endstack = (char*)stack + size - 64;
co = (coroutine*)stack; co = (coroutine*)stack;
stack = (char *) stack + CO_STK_COROSIZE; stack = (char *) stack + CO_STK_COROSIZE;
*(void**)endstack = NULL; *(void**)endstack = NULL;
*(void**)((char*)endstack+sizeof(void*)) = data; *(void**)((char*)endstack+sizeof(void*)) = data;
co->alloc = alloc; co->alloc = alloc;
co->pcalladdr = (void*)func; co->pcalladdr = (void*)func;
co->pcurstack = endstack; co->pcurstack = endstack;
return co; return co;
} }
void so_delete(coroutine_t coro) void so_delete(coroutine_t coro)
{ {
coroutine *co = (coroutine *) coro; coroutine *co = (coroutine *) coro;
assert( co != NULL ); assert( co != NULL );
if (co->alloc) if (co->alloc) free(co);
free(co);
} }
// see acoroutines.S and acoroutines.asm for other asm implementations // see acoroutines.S and acoroutines.asm for other asm implementations

View File

@ -53,14 +53,14 @@ static void execI()
//runs++; //runs++;
//if (runs > 1599999999){ //leave some time to startup the testgame //if (runs > 1599999999){ //leave some time to startup the testgame
// if (opcode.Name[0] == 'L') { //find all opcodes beginning with "L" // if (opcode.Name[0] == 'L') { //find all opcodes beginning with "L"
// SysPrintf ("Load %s\n",opcode.Name); // Console::WriteLn ("Load %s", params opcode.Name);
// } // }
//} //}
// Another method of instruction dumping: // Another method of instruction dumping:
/*if( cpuRegs.cycle > 0x4f24d714 ) /*if( cpuRegs.cycle > 0x4f24d714 )
{ {
//CPU_LOG( "%s\n", disR5900Current.getCString()); //CPU_LOG( "%s", disR5900Current.getCString());
disOut.clear(); disOut.clear();
opcode.disasm( disOut ); opcode.disasm( disOut );
disOut += '\n'; disOut += '\n';
@ -101,7 +101,7 @@ static void __fastcall doBranch( u32 target )
void __fastcall intDoBranch(u32 target) void __fastcall intDoBranch(u32 target)
{ {
//SysPrintf("Interpreter Branch \n"); //Console::WriteLn("Interpreter Branch ");
_doBranch_shared( target ); _doBranch_shared( target );
if( Cpu == &intCpu ) if( Cpu == &intCpu )

View File

@ -182,7 +182,7 @@ void bios_write() { // 0x35/0x03
} }
pc0 = ra; return; pc0 = ra; return;
} }
PSXBIOS_LOG("bios_%s: %x,%x,%x\n", biosB0n[0x35], a0, a1, a2); PSXBIOS_LOG("bios_%s: %x,%x,%x", biosB0n[0x35], a0, a1, a2);
v0 = -1; v0 = -1;
pc0 = ra; pc0 = ra;

View File

@ -154,7 +154,7 @@ static void __fastcall _rcntTestTarget( int i )
{ {
if( psxCounters[i].count < psxCounters[i].target ) return; if( psxCounters[i].count < psxCounters[i].target ) return;
PSXCNT_LOG("IOP Counter[%d] target 0x%I64x >= 0x%I64x (mode: %x)\n", PSXCNT_LOG("IOP Counter[%d] target 0x%I64x >= 0x%I64x (mode: %x)",
i, psxCounters[i].count, psxCounters[i].target, psxCounters[i].mode); i, psxCounters[i].count, psxCounters[i].target, psxCounters[i].mode);
if (psxCounters[i].mode & IOPCNT_INT_TARGET) if (psxCounters[i].mode & IOPCNT_INT_TARGET)
@ -174,7 +174,7 @@ static void __fastcall _rcntTestTarget( int i )
psxCounters[i].count -= psxCounters[i].target; psxCounters[i].count -= psxCounters[i].target;
if(!(psxCounters[i].mode & 0x40)) if(!(psxCounters[i].mode & 0x40))
{ {
SysPrintf("Counter %x repeat intr not set on zero ret, ignoring target\n", i); Console::WriteLn("Counter %x repeat intr not set on zero ret, ignoring target", params i);
psxCounters[i].target |= IOPCNT_FUTURE_TARGET; psxCounters[i].target |= IOPCNT_FUTURE_TARGET;
} }
} else psxCounters[i].target |= IOPCNT_FUTURE_TARGET; } else psxCounters[i].target |= IOPCNT_FUTURE_TARGET;
@ -186,7 +186,7 @@ static __forceinline void _rcntTestOverflow( int i )
u64 maxTarget = ( i < 3 ) ? 0xffff : 0xfffffffful; u64 maxTarget = ( i < 3 ) ? 0xffff : 0xfffffffful;
if( psxCounters[i].count <= maxTarget ) return; if( psxCounters[i].count <= maxTarget ) return;
PSXCNT_LOG("IOP Counter[%d] overflow 0x%I64x >= 0x%I64x (mode: %x)\n", PSXCNT_LOG("IOP Counter[%d] overflow 0x%I64x >= 0x%I64x (mode: %x)",
i, psxCounters[i].count, maxTarget, psxCounters[i].mode ); i, psxCounters[i].count, maxTarget, psxCounters[i].mode );
if(psxCounters[i].mode & IOPCNT_INT_OVERFLOW) if(psxCounters[i].mode & IOPCNT_INT_OVERFLOW)
@ -461,7 +461,7 @@ void psxRcntWcount16(int index, u32 value)
u32 change; u32 change;
assert( index < 3 ); assert( index < 3 );
PSXCNT_LOG("IOP Counter[%d] writeCount16 = %x\n", index, value); PSXCNT_LOG("IOP Counter[%d] writeCount16 = %x", index, value);
if(psxCounters[index].rate != PSXHBLANK) if(psxCounters[index].rate != PSXHBLANK)
{ {
@ -482,7 +482,7 @@ void psxRcntWcount32(int index, u32 value)
u32 change; u32 change;
assert( index >= 3 && index < 6 ); assert( index >= 3 && index < 6 );
PSXCNT_LOG("IOP Counter[%d] writeCount32 = %x\n", index, value); PSXCNT_LOG("IOP Counter[%d] writeCount32 = %x", index, value);
if(psxCounters[index].rate != PSXHBLANK) if(psxCounters[index].rate != PSXHBLANK)
{ {
@ -500,7 +500,7 @@ void psxRcntWcount32(int index, u32 value)
void psxRcnt0Wmode(u32 value) void psxRcnt0Wmode(u32 value)
{ {
PSXCNT_LOG("IOP Counter[0] writeMode = %lx\n", value); PSXCNT_LOG("IOP Counter[0] writeMode = %lx", value);
psxCounters[0].mode = value; psxCounters[0].mode = value;
psxCounters[0].mode|= 0x0400; psxCounters[0].mode|= 0x0400;
@ -512,7 +512,7 @@ void psxRcnt0Wmode(u32 value)
if(psxCounters[0].mode & IOPCNT_ENABLE_GATE) if(psxCounters[0].mode & IOPCNT_ENABLE_GATE)
{ {
// gated counters are added up as per the h/vblank timers. // gated counters are added up as per the h/vblank timers.
PSXCNT_LOG("IOP Counter[0] Gate Check set, value = %x\n", value); PSXCNT_LOG("IOP Counter[0] Gate Check set, value = %x", value);
psxhblankgate |= 1; psxhblankgate |= 1;
} }
else psxhblankgate &= ~1; else psxhblankgate &= ~1;
@ -526,7 +526,7 @@ void psxRcnt0Wmode(u32 value)
void psxRcnt1Wmode(u32 value) void psxRcnt1Wmode(u32 value)
{ {
PSXCNT_LOG("IOP Counter[0] writeMode = %lx\n", value); PSXCNT_LOG("IOP Counter[0] writeMode = %lx", value);
psxCounters[1].mode = value; psxCounters[1].mode = value;
psxCounters[1].mode|= 0x0400; psxCounters[1].mode|= 0x0400;
@ -537,7 +537,7 @@ void psxRcnt1Wmode(u32 value)
if(psxCounters[1].mode & IOPCNT_ENABLE_GATE) if(psxCounters[1].mode & IOPCNT_ENABLE_GATE)
{ {
PSXCNT_LOG("IOP Counter[1] Gate Check set, value = %x\n", value); PSXCNT_LOG("IOP Counter[1] Gate Check set, value = %x", value);
psxvblankgate |= 1<<1; psxvblankgate |= 1<<1;
} }
else psxvblankgate &= ~(1<<1); else psxvblankgate &= ~(1<<1);
@ -550,7 +550,7 @@ void psxRcnt1Wmode(u32 value)
void psxRcnt2Wmode(u32 value) void psxRcnt2Wmode(u32 value)
{ {
PSXCNT_LOG("IOP Counter[0] writeMode = %lx\n", value); PSXCNT_LOG("IOP Counter[0] writeMode = %lx", value);
psxCounters[2].mode = value; psxCounters[2].mode = value;
psxCounters[2].mode|= 0x0400; psxCounters[2].mode|= 0x0400;
@ -563,7 +563,7 @@ void psxRcnt2Wmode(u32 value)
if((psxCounters[2].mode & 0x7) == 0x7 || (psxCounters[2].mode & 0x7) == 0x1) if((psxCounters[2].mode & 0x7) == 0x7 || (psxCounters[2].mode & 0x7) == 0x1)
{ {
//SysPrintf("Gate set on IOP C2, disabling\n"); //Console::WriteLn("Gate set on IOP C2, disabling");
psxCounters[2].mode |= IOPCNT_STOPPED; psxCounters[2].mode |= IOPCNT_STOPPED;
} }
@ -575,7 +575,7 @@ void psxRcnt2Wmode(u32 value)
void psxRcnt3Wmode(u32 value) void psxRcnt3Wmode(u32 value)
{ {
PSXCNT_LOG("IOP Counter[3] writeMode = %lx\n", value); PSXCNT_LOG("IOP Counter[3] writeMode = %lx", value);
psxCounters[3].mode = value; psxCounters[3].mode = value;
psxCounters[3].rate = 1; psxCounters[3].rate = 1;
@ -586,7 +586,7 @@ void psxRcnt3Wmode(u32 value)
if(psxCounters[3].mode & IOPCNT_ENABLE_GATE) if(psxCounters[3].mode & IOPCNT_ENABLE_GATE)
{ {
PSXCNT_LOG("IOP Counter[3] Gate Check set, value = %x\n", value); PSXCNT_LOG("IOP Counter[3] Gate Check set, value = %x", value);
psxvblankgate |= 1<<3; psxvblankgate |= 1<<3;
} }
else psxvblankgate &= ~(1<<3); else psxvblankgate &= ~(1<<3);
@ -599,7 +599,7 @@ void psxRcnt3Wmode(u32 value)
void psxRcnt4Wmode(u32 value) void psxRcnt4Wmode(u32 value)
{ {
PSXCNT_LOG("IOP Counter[4] writeMode = %lx\n", value); PSXCNT_LOG("IOP Counter[4] writeMode = %lx", value);
psxCounters[4].mode = value; psxCounters[4].mode = value;
psxCounters[4].mode|= 0x0400; psxCounters[4].mode|= 0x0400;
@ -614,7 +614,7 @@ void psxRcnt4Wmode(u32 value)
// Need to set a rate and target // Need to set a rate and target
if((psxCounters[4].mode & 0x7) == 0x7 || (psxCounters[4].mode & 0x7) == 0x1) if((psxCounters[4].mode & 0x7) == 0x7 || (psxCounters[4].mode & 0x7) == 0x1)
{ {
SysPrintf("Gate set on IOP C4, disabling\n"); Console::WriteLn("Gate set on IOP C4, disabling");
psxCounters[4].mode |= IOPCNT_STOPPED; psxCounters[4].mode |= IOPCNT_STOPPED;
} }
@ -626,7 +626,7 @@ void psxRcnt4Wmode(u32 value)
void psxRcnt5Wmode(u32 value) void psxRcnt5Wmode(u32 value)
{ {
PSXCNT_LOG("IOP Counter[5] writeMode = %lx\n", value); PSXCNT_LOG("IOP Counter[5] writeMode = %lx", value);
psxCounters[5].mode = value; psxCounters[5].mode = value;
psxCounters[5].mode|= 0x0400; psxCounters[5].mode|= 0x0400;
@ -641,7 +641,7 @@ void psxRcnt5Wmode(u32 value)
// Need to set a rate and target // Need to set a rate and target
if((psxCounters[5].mode & 0x7) == 0x7 || (psxCounters[5].mode & 0x7) == 0x1) if((psxCounters[5].mode & 0x7) == 0x7 || (psxCounters[5].mode & 0x7) == 0x1)
{ {
SysPrintf("Gate set on IOP C5, disabling\n"); Console::WriteLn("Gate set on IOP C5, disabling");
psxCounters[5].mode |= IOPCNT_STOPPED; psxCounters[5].mode |= IOPCNT_STOPPED;
} }
@ -654,7 +654,7 @@ void psxRcnt5Wmode(u32 value)
void psxRcntWtarget16(int index, u32 value) void psxRcntWtarget16(int index, u32 value)
{ {
assert( index < 3 ); assert( index < 3 );
PSXCNT_LOG("IOP Counter[%d] writeTarget16 = %lx\n", index, value); PSXCNT_LOG("IOP Counter[%d] writeTarget16 = %lx", index, value);
psxCounters[index].target = value & 0xffff; psxCounters[index].target = value & 0xffff;
// protect the target from an early arrival. // protect the target from an early arrival.
@ -670,7 +670,7 @@ void psxRcntWtarget16(int index, u32 value)
void psxRcntWtarget32(int index, u32 value) void psxRcntWtarget32(int index, u32 value)
{ {
assert( index >= 3 && index < 6); assert( index >= 3 && index < 6);
PSXCNT_LOG("IOP Counter[%d] writeTarget32 = %lx\n", index, value); PSXCNT_LOG("IOP Counter[%d] writeTarget32 = %lx", index, value);
psxCounters[index].target = value; psxCounters[index].target = value;
@ -690,7 +690,7 @@ u16 psxRcntRcount16(int index)
assert( index < 3 ); assert( index < 3 );
PSXCNT_LOG("IOP Counter[%d] readCount16 = %lx\n", index, (u16)retval ); PSXCNT_LOG("IOP Counter[%d] readCount16 = %lx", index, (u16)retval );
// Don't count HBLANK timers // Don't count HBLANK timers
// Don't count stopped gates either. // Don't count stopped gates either.
@ -700,7 +700,7 @@ u16 psxRcntRcount16(int index)
{ {
u32 delta = (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate); u32 delta = (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate);
retval += delta; retval += delta;
PSXCNT_LOG(" (delta = %lx)\n", delta ); PSXCNT_LOG(" (delta = %lx)", delta );
} }
return (u16)retval; return (u16)retval;
@ -712,14 +712,14 @@ u32 psxRcntRcount32(int index)
assert( index >= 3 && index < 6 ); assert( index >= 3 && index < 6 );
PSXCNT_LOG("IOP Counter[%d] readCount32 = %lx\n", index, retval ); PSXCNT_LOG("IOP Counter[%d] readCount32 = %lx", index, retval );
if( !( psxCounters[index].mode & IOPCNT_STOPPED ) && if( !( psxCounters[index].mode & IOPCNT_STOPPED ) &&
( psxCounters[index].rate != PSXHBLANK ) ) ( psxCounters[index].rate != PSXHBLANK ) )
{ {
u32 delta = (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate); u32 delta = (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate);
retval += delta; retval += delta;
PSXCNT_LOG(" (delta = %lx)\n", delta ); PSXCNT_LOG(" (delta = %lx)", delta );
} }
return retval; return retval;

View File

@ -17,7 +17,6 @@
*/ */
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "IopCommon.h" #include "IopCommon.h"
using namespace R3000A; using namespace R3000A;
@ -27,21 +26,22 @@ using namespace R3000A;
// Dma8 in PsxSpd.c // Dma8 in PsxSpd.c
// Dma11/12 in PsxSio2.c // Dma11/12 in PsxSio2.c
// Should be a bool, and will be next time I break savestate. --arcum42
int iopsifbusy[2] = { 0, 0 }; int iopsifbusy[2] = { 0, 0 };
static void __fastcall psxDmaGeneric(u32 madr, u32 bcr, u32 chcr, u32 spuCore, _SPU2writeDMA4Mem spu2WriteFunc, _SPU2readDMA4Mem spu2ReadFunc ) static void __fastcall psxDmaGeneric(u32 madr, u32 bcr, u32 chcr, u32 spuCore, _SPU2writeDMA4Mem spu2WriteFunc, _SPU2readDMA4Mem spu2ReadFunc)
{ {
const char dmaNum = spuCore ? '7' : '4'; const char dmaNum = spuCore ? '7' : '4';
/*if (chcr & 0x400) DevCon::Status("SPU 2 DMA %c linked list chain mode! chcr = %x madr = %x bcr = %x\n", dmaNum, chcr, madr, bcr); /*if (chcr & 0x400) DevCon::Status("SPU 2 DMA %c linked list chain mode! chcr = %x madr = %x bcr = %x\n", dmaNum, chcr, madr, bcr);
if (chcr & 0x40000000) DevCon::Notice("SPU 2 DMA %c Unusual bit set on 'to' direction chcr = %x madr = %x bcr = %x\n", dmaNum, chcr, madr, bcr); if (chcr & 0x40000000) DevCon::Notice("SPU 2 DMA %c Unusual bit set on 'to' direction chcr = %x madr = %x bcr = %x\n", dmaNum, chcr, madr, bcr);
if ((chcr & 0x1) == 0) DevCon::Status("SPU 2 DMA %c loading from spu2 memory chcr = %x madr = %x bcr = %x\n", dmaNum, chcr, madr, bcr);*/ if ((chcr & 0x1) == 0) DevCon::Status("SPU 2 DMA %c loading from spu2 memory chcr = %x madr = %x bcr = %x\n", dmaNum, chcr, madr, bcr);*/
const int size = (bcr >> 16) * (bcr & 0xFFFF); const int size = (bcr >> 16) * (bcr & 0xFFFF);
// Update the spu2 to the current cycle before initiating the DMA // Update the spu2 to the current cycle before initiating the DMA
if(SPU2async) if (SPU2async)
{ {
SPU2async(psxRegs.cycle - psxCounters[6].sCycleT); SPU2async(psxRegs.cycle - psxCounters[6].sCycleT);
//Console::Status("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT); //Console::Status("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT);
@ -49,41 +49,41 @@ static void __fastcall psxDmaGeneric(u32 madr, u32 bcr, u32 chcr, u32 spuCore, _
psxCounters[6].sCycleT = psxRegs.cycle; psxCounters[6].sCycleT = psxRegs.cycle;
psxCounters[6].CycleT = size * 3; psxCounters[6].CycleT = size * 3;
psxNextCounter -= (psxRegs.cycle-psxNextsCounter); psxNextCounter -= (psxRegs.cycle - psxNextsCounter);
psxNextsCounter = psxRegs.cycle; psxNextsCounter = psxRegs.cycle;
if(psxCounters[6].CycleT < psxNextCounter) if (psxCounters[6].CycleT < psxNextCounter)
psxNextCounter = psxCounters[6].CycleT; psxNextCounter = psxCounters[6].CycleT;
} }
switch (chcr) switch (chcr)
{ {
case 0x01000201: //cpu to spu2 transfer case 0x01000201: //cpu to spu2 transfer
PSXDMA_LOG("*** DMA %c - mem2spu *** %x addr = %x size = %x\n", dmaNum, chcr, madr, bcr); PSXDMA_LOG("*** DMA %c - mem2spu *** %x addr = %x size = %x", dmaNum, chcr, madr, bcr);
spu2WriteFunc((u16 *)iopPhysMem(madr), size*2); spu2WriteFunc((u16 *)iopPhysMem(madr), size*2);
break; break;
case 0x01000200: //spu2 to cpu transfer case 0x01000200: //spu2 to cpu transfer
PSXDMA_LOG("*** DMA %c - spu2mem *** %x addr = %x size = %x\n", dmaNum, chcr, madr, bcr); PSXDMA_LOG("*** DMA %c - spu2mem *** %x addr = %x size = %x", dmaNum, chcr, madr, bcr);
spu2ReadFunc((u16 *)iopPhysMem(madr), size*2); spu2ReadFunc((u16 *)iopPhysMem(madr), size*2);
psxCpu->Clear(spuCore ? HW_DMA7_MADR : HW_DMA4_MADR, size); psxCpu->Clear(spuCore ? HW_DMA7_MADR : HW_DMA4_MADR, size);
break; break;
default: default:
Console::Error("*** DMA %c - SPU unknown *** %x addr = %x size = %x\n", params dmaNum, chcr, madr, bcr); Console::Error("*** DMA %c - SPU unknown *** %x addr = %x size = %x", params dmaNum, chcr, madr, bcr);
break; break;
} }
} }
void psxDma4(u32 madr, u32 bcr, u32 chcr) // SPU2's Core 0 void psxDma4(u32 madr, u32 bcr, u32 chcr) // SPU2's Core 0
{ {
psxDmaGeneric( madr, bcr, chcr, 0, SPU2writeDMA4Mem, SPU2readDMA4Mem ); psxDmaGeneric(madr, bcr, chcr, 0, SPU2writeDMA4Mem, SPU2readDMA4Mem);
} }
int psxDma4Interrupt() int psxDma4Interrupt()
{ {
HW_DMA4_CHCR &= ~0x01000000; HW_DMA4_CHCR &= ~0x01000000;
psxDmaInterrupt(4); psxDmaInterrupt(4);
iopIntcIrq( 9 ); iopIntcIrq(9);
return 1; return 1;
} }
@ -97,17 +97,22 @@ void psxDma6(u32 madr, u32 bcr, u32 chcr)
{ {
u32 *mem = (u32 *)iopPhysMem(madr); u32 *mem = (u32 *)iopPhysMem(madr);
PSXDMA_LOG("*** DMA 6 - OT *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); PSXDMA_LOG("*** DMA 6 - OT *** %lx addr = %lx size = %lx", chcr, madr, bcr);
if (chcr == 0x11000002) { if (chcr == 0x11000002)
while (bcr--) { {
while (bcr--)
{
*mem-- = (madr - 4) & 0xffffff; *mem-- = (madr - 4) & 0xffffff;
madr -= 4; madr -= 4;
} }
mem++; *mem = 0xffffff; mem++;
} else { *mem = 0xffffff;
}
else
{
// Unknown option // Unknown option
PSXDMA_LOG("*** DMA 6 - OT unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); PSXDMA_LOG("*** DMA 6 - OT unknown *** %lx addr = %lx size = %lx", chcr, madr, bcr);
} }
HW_DMA6_CHCR &= ~0x01000000; HW_DMA6_CHCR &= ~0x01000000;
psxDmaInterrupt(6); psxDmaInterrupt(6);
@ -115,39 +120,41 @@ void psxDma6(u32 madr, u32 bcr, u32 chcr)
void psxDma7(u32 madr, u32 bcr, u32 chcr) // SPU2's Core 1 void psxDma7(u32 madr, u32 bcr, u32 chcr) // SPU2's Core 1
{ {
psxDmaGeneric( madr, bcr, chcr, 1, SPU2writeDMA7Mem, SPU2readDMA7Mem ); psxDmaGeneric(madr, bcr, chcr, 1, SPU2writeDMA7Mem, SPU2readDMA7Mem);
} }
int psxDma7Interrupt() int psxDma7Interrupt()
{ {
HW_DMA7_CHCR &= ~0x01000000; HW_DMA7_CHCR &= ~0x01000000;
psxDmaInterrupt2(0); psxDmaInterrupt2(0);
//iopIntcIrq( 9 );
return 1; return 1;
} }
extern int eesifbusy[2]; extern int eesifbusy[2];
void psxDma9(u32 madr, u32 bcr, u32 chcr) void psxDma9(u32 madr, u32 bcr, u32 chcr)
{ {
SIF_LOG("IOP: dmaSIF0 chcr = %lx, madr = %lx, bcr = %lx, tadr = %lx\n", chcr, madr, bcr, HW_DMA9_TADR); SIF_LOG("IOP: dmaSIF0 chcr = %lx, madr = %lx, bcr = %lx, tadr = %lx", chcr, madr, bcr, HW_DMA9_TADR);
iopsifbusy[0] = 1; iopsifbusy[0] = 1;
psHu32(0x1000F240) |= 0x2000; psHu32(0x1000F240) |= 0x2000;
if (eesifbusy[0] == 1) { if (eesifbusy[0] == 1)
{
SIF0Dma(); SIF0Dma();
psHu32(0x1000F240) &= ~0x20; psHu32(0x1000F240) &= ~0x20;
psHu32(0x1000F240) &= ~0x2000; psHu32(0x1000F240) &= ~0x2000;
} }
} }
void psxDma10(u32 madr, u32 bcr, u32 chcr) { void psxDma10(u32 madr, u32 bcr, u32 chcr)
SIF_LOG("IOP: dmaSIF1 chcr = %lx, madr = %lx, bcr = %lx\n", chcr, madr, bcr); {
SIF_LOG("IOP: dmaSIF1 chcr = %lx, madr = %lx, bcr = %lx", chcr, madr, bcr);
iopsifbusy[1] = 1; iopsifbusy[1] = 1;
psHu32(0x1000F240) |= 0x4000; psHu32(0x1000F240) |= 0x4000;
if (eesifbusy[1] == 1) { if (eesifbusy[1] == 1)
{
FreezeXMMRegs(1); FreezeXMMRegs(1);
SIF1Dma(); SIF1Dma();
psHu32(0x1000F240) &= ~0x40; psHu32(0x1000F240) &= ~0x40;
@ -157,80 +164,86 @@ void psxDma10(u32 madr, u32 bcr, u32 chcr) {
} }
} }
void psxDma8(u32 madr, u32 bcr, u32 chcr) { void psxDma8(u32 madr, u32 bcr, u32 chcr)
{
const int size = (bcr >> 16) * (bcr & 0xFFFF) * 8; const int size = (bcr >> 16) * (bcr & 0xFFFF) * 8;
switch (chcr & 0x01000201) { switch (chcr & 0x01000201)
{
case 0x01000201: //cpu to dev9 transfer case 0x01000201: //cpu to dev9 transfer
PSXDMA_LOG("*** DMA 8 - DEV9 mem2dev9 *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); PSXDMA_LOG("*** DMA 8 - DEV9 mem2dev9 *** %lx addr = %lx size = %lx", chcr, madr, bcr);
DEV9writeDMA8Mem((u32*)iopPhysMem(madr), size); DEV9writeDMA8Mem((u32*)iopPhysMem(madr), size);
break; break;
case 0x01000200: //dev9 to cpu transfer case 0x01000200: //dev9 to cpu transfer
PSXDMA_LOG("*** DMA 8 - DEV9 dev9mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); PSXDMA_LOG("*** DMA 8 - DEV9 dev9mem *** %lx addr = %lx size = %lx", chcr, madr, bcr);
DEV9readDMA8Mem((u32*)iopPhysMem(madr), size); DEV9readDMA8Mem((u32*)iopPhysMem(madr), size);
break; break;
default: default:
PSXDMA_LOG("*** DMA 8 - DEV9 unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); PSXDMA_LOG("*** DMA 8 - DEV9 unknown *** %lx addr = %lx size = %lx", chcr, madr, bcr);
break; break;
} }
HW_DMA8_CHCR &= ~0x01000000; HW_DMA8_CHCR &= ~0x01000000;
psxDmaInterrupt2(1); psxDmaInterrupt2(1);
} }
void dev9Interrupt() { void dev9Interrupt()
if( (dev9Handler != NULL) && (dev9Handler() != 1) ) {
return; if ((dev9Handler != NULL) && (dev9Handler() != 1)) return;
iopIntcIrq( 13 ); iopIntcIrq(13);
hwIntcIrq(INTC_SBUS); hwIntcIrq(INTC_SBUS);
} }
void dev9Irq(int cycles) { void dev9Irq(int cycles)
{
PSX_INT(IopEvt_DEV9, cycles); PSX_INT(IopEvt_DEV9, cycles);
} }
void usbInterrupt() { void usbInterrupt()
if( usbHandler != NULL && (usbHandler() != 1) ) {
return; if (usbHandler != NULL && (usbHandler() != 1)) return;
iopIntcIrq( 22 ); iopIntcIrq(22);
hwIntcIrq(INTC_SBUS); hwIntcIrq(INTC_SBUS);
} }
void usbIrq(int cycles) { void usbIrq(int cycles)
{
PSX_INT(IopEvt_USB, cycles); PSX_INT(IopEvt_USB, cycles);
} }
void fwIrq() { void fwIrq()
iopIntcIrq( 24 ); {
iopIntcIrq(24);
hwIntcIrq(INTC_SBUS); hwIntcIrq(INTC_SBUS);
} }
void spu2DMA4Irq() { void spu2DMA4Irq()
{
SPU2interruptDMA4(); SPU2interruptDMA4();
//HW_DMA4_BCR = 0;
HW_DMA4_CHCR &= ~0x01000000; HW_DMA4_CHCR &= ~0x01000000;
psxDmaInterrupt(4); psxDmaInterrupt(4);
} }
void spu2DMA7Irq() { void spu2DMA7Irq()
{
SPU2interruptDMA7(); SPU2interruptDMA7();
//HW_DMA7_BCR = 0;
HW_DMA7_CHCR &= ~0x01000000; HW_DMA7_CHCR &= ~0x01000000;
psxDmaInterrupt2(0); psxDmaInterrupt2(0);
} }
void spu2Irq() { void spu2Irq()
iopIntcIrq( 9 ); {
iopIntcIrq(9);
hwIntcIrq(INTC_SBUS); hwIntcIrq(INTC_SBUS);
} }
void iopIntcIrq( uint irqType ) void iopIntcIrq(uint irqType)
{ {
psxHu32(0x1070)|= 1<<irqType; psxHu32(0x1070) |= 1 << irqType;
iopTestIntc(); iopTestIntc();
} }
@ -238,21 +251,25 @@ void iopIntcIrq( uint irqType )
// //
// Gigaherz's "Improved DMA Handling" Engine WIP... // Gigaherz's "Improved DMA Handling" Engine WIP...
// //
// fixme: Is this in progress?
#if FALSE #if FALSE
typedef s32 (* DmaHandler) (s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed); typedef s32(* DmaHandler)(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed);
typedef void (* DmaIHandler)(s32 channel); typedef void (* DmaIHandler)(s32 channel);
s32 errDmaWrite (s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed); s32 errDmaWrite(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed);
s32 errDmaRead (s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed); s32 errDmaRead(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed);
struct DmaHandlerInfo { struct DmaHandlerInfo
{
DmaHandler Read; DmaHandler Read;
DmaHandler Write; DmaHandler Write;
DmaIHandler Interrupt; DmaIHandler Interrupt;
}; };
struct DmaStatusInfo { struct DmaStatusInfo
{
u32 Control; u32 Control;
u32 Width; // bytes/word, for timing purposes u32 Width; // bytes/word, for timing purposes
u32 MemAddr; u32 MemAddr;
@ -268,7 +285,8 @@ struct DmaStatusInfo {
DmaStatusInfo IopChannels[DMA_CHANNEL_MAX]; // I dont' knwo how many there are, 10? DmaStatusInfo IopChannels[DMA_CHANNEL_MAX]; // I dont' knwo how many there are, 10?
DmaHandlerInfo IopDmaHandlers[DMA_CHANNEL_MAX] = { DmaHandlerInfo IopDmaHandlers[DMA_CHANNEL_MAX] =
{
{0}, //0 {0}, //0
{0}, //1 {0}, //1
{0}, //2 {0}, //2
@ -284,7 +302,8 @@ DmaHandlerInfo IopDmaHandlers[DMA_CHANNEL_MAX] = {
{0}, // Sio2 {0}, // Sio2
}; };
const char* IopDmaNames[DMA_CHANNEL_MAX] = { const char* IopDmaNames[DMA_CHANNEL_MAX] =
{
"Ps1 Mdec", "Ps1 Mdec",
"Ps1 Mdec", "Ps1 Mdec",
"Ps1 Gpu", "Ps1 Gpu",
@ -298,7 +317,8 @@ const char* IopDmaNames[DMA_CHANNEL_MAX] = {
"Sif1", //10: SIF1 "Sif1", //10: SIF1
"Sio2",//... "Sio2",//...
"Sio2", "Sio2",
"?","?","?"}; "?", "?", "?"
};
}; };
// Prototypes. To be implemented later (or in other parts of the emulator) // Prototypes. To be implemented later (or in other parts of the emulator)
@ -320,16 +340,16 @@ void IopDmaUpdate(u32 elapsed)
{ {
u32 MinDelay = 0xFFFFFFFF; u32 MinDelay = 0xFFFFFFFF;
for(int i=0;i<DMA_CHANNEL_MAX;i++) for (int i = 0;i < DMA_CHANNEL_MAX;i++)
{ {
DmaStatusInfo *ch = IopChannels+i; DmaStatusInfo *ch = IopChannels + i;
if(ch->Control&DMA_CTRL_ACTIVE) if (ch->Control&DMA_CTRL_ACTIVE)
{ {
ch->Target-=elapsed; ch->Target -= elapsed;
if(ch->Target<=0) if (ch->Target <= 0)
{ {
if(ch->ByteCount<=0) if (ch->ByteCount <= 0)
{ {
ch->Control &= ~DMA_CTRL_ACTIVE; ch->Control &= ~DMA_CTRL_ACTIVE;
RaiseDmaIrq(i); RaiseDmaIrq(i);
@ -338,17 +358,17 @@ void IopDmaUpdate(u32 elapsed)
else else
{ {
// TODO: Make sure it's the right order // TODO: Make sure it's the right order
DmaHandler handler = (ch->Control&DMA_CTRL_DIRECTION)?IopDmaHandlers[i].Read:IopDmaHandlers[i].Write; DmaHandler handler = (ch->Control & DMA_CTRL_DIRECTION) ? IopDmaHandlers[i].Read : IopDmaHandlers[i].Write;
u32 BCount = 0; u32 BCount = 0;
s32 Target = (handler)?handler(i,(u32*)PSXM(ch->MemAddr),ch->ByteCount,&BCount):0; s32 Target = (handler) ? handler(i, (u32*)PSXM(ch->MemAddr), ch->ByteCount, &BCount) : 0;
ch->Target = 100; ch->Target = 100;
if(Target<0) if (Target < 0)
{ {
// TODO: ... What to do if the plugin errors? :P // TODO: ... What to do if the plugin errors? :P
} }
else if(BCount!=0) else if (BCount != 0)
{ {
ch->MemAddr += BCount; ch->MemAddr += BCount;
ch->ByteCount -= BCount; ch->ByteCount -= BCount;
@ -356,24 +376,24 @@ void IopDmaUpdate(u32 elapsed)
ch->Target = BCount / ch->Width; ch->Target = BCount / ch->Width;
} }
if (Target!=0) ch->Target=Target; if (Target != 0) ch->Target = Target;
} }
} }
} }
} }
} }
s32 errDmaRead (s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed) s32 errDmaRead(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed)
{ {
Console::Error("ERROR: Tried to read using DMA %d (%s). Ignoring.",0,channel,IopDmaNames[channel]); Console::Error("ERROR: Tried to read using DMA %d (%s). Ignoring.", 0, channel, IopDmaNames[channel]);
*wordsProcessed = wordsLeft; *wordsProcessed = wordsLeft;
return 0; return 0;
} }
s32 errDmaWrite (s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed) s32 errDmaWrite(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed)
{ {
Console::Error("ERROR: Tried to write using DMA %d (%s). Ignoring.",0,channel,IopDmaNames[channel]); Console::Error("ERROR: Tried to write using DMA %d (%s). Ignoring.", 0, channel, IopDmaNames[channel]);
*wordsProcessed = wordsLeft; *wordsProcessed = wordsLeft;
return 0; return 0;

File diff suppressed because it is too large Load Diff

View File

@ -156,7 +156,7 @@ u8 iopMemRead8(u32 mem)
{ {
if (t == 0x1000) if (t == 0x1000)
return DEV9read8(mem); return DEV9read8(mem);
PSXMEM_LOG("err lb %8.8lx\n", mem); PSXMEM_LOG("err lb %8.8lx", mem);
return 0; return 0;
} }
} }
@ -200,7 +200,7 @@ u16 iopMemRead16(u32 mem)
ret = psxHu16(mem); ret = psxHu16(mem);
break; break;
} }
SIF_LOG("Sif reg read %x value %x\n", mem, ret); SIF_LOG("Sif reg read %x value %x", mem, ret);
return ret; return ret;
} }
return *(const u16 *)(p + (mem & 0xffff)); return *(const u16 *)(p + (mem & 0xffff));
@ -211,7 +211,7 @@ u16 iopMemRead16(u32 mem)
return SPU2read(mem); return SPU2read(mem);
if (t == 0x1000) if (t == 0x1000)
return DEV9read16(mem); return DEV9read16(mem);
PSXMEM_LOG("err lh %8.8lx\n", mem); PSXMEM_LOG("err lh %8.8lx", mem);
return 0; return 0;
} }
} }
@ -261,7 +261,7 @@ u32 iopMemRead32(u32 mem)
ret = psxHu32(mem); ret = psxHu32(mem);
break; break;
} }
SIF_LOG("Sif reg read %x value %x\n", mem, ret); SIF_LOG("Sif reg read %x value %x", mem, ret);
return ret; return ret;
} }
return *(const u32 *)(p + (mem & 0xffff)); return *(const u32 *)(p + (mem & 0xffff));
@ -301,14 +301,17 @@ void iopMemWrite8(u32 mem, u8 value)
} }
else else
{ {
if (t == 0x1D00) SysPrintf("sw8 [0x%08X]=0x%08X\n", mem, value); if (t == 0x1d00)
if (t == 0x1d00) { {
psxSu8(mem) = value; return; Console::WriteLn("sw8 [0x%08X]=0x%08X", params mem, value);
psxSu8(mem) = value;
return;
} }
if (t == 0x1000) { if (t == 0x1000)
{
DEV9write8(mem, value); return; DEV9write8(mem, value); return;
} }
PSXMEM_LOG("err sb %8.8lx = %x\n", mem, value); PSXMEM_LOG("err sb %8.8lx = %x", mem, value);
} }
} }
} }
@ -329,7 +332,7 @@ void iopMemWrite16(u32 mem, u16 value)
u8* p = (u8 *)(psxMemWLUT[mem >> 16]); u8* p = (u8 *)(psxMemWLUT[mem >> 16]);
if (p != NULL && !(psxRegs.CP0.n.Status & 0x10000) ) if (p != NULL && !(psxRegs.CP0.n.Status & 0x10000) )
{ {
if( t==0x1D00 ) SysPrintf("sw16 [0x%08X]=0x%08X\n", mem, value); if( t==0x1D00 ) Console::WriteLn("sw16 [0x%08X]=0x%08X", params mem, value);
*(u16 *)(p + (mem & 0xffff)) = value; *(u16 *)(p + (mem & 0xffff)) = value;
psxCpu->Clear(mem&~3, 1); psxCpu->Clear(mem&~3, 1);
} }
@ -371,7 +374,7 @@ void iopMemWrite16(u32 mem, u16 value)
if (t == 0x1000) { if (t == 0x1000) {
DEV9write16(mem, value); return; DEV9write16(mem, value); return;
} }
PSXMEM_LOG("err sh %8.8lx = %x\n", mem, value); PSXMEM_LOG("err sh %8.8lx = %x", mem, value);
} }
} }
} }
@ -400,7 +403,7 @@ void iopMemWrite32(u32 mem, u32 value)
{ {
if (t == 0x1d00) if (t == 0x1d00)
{ {
MEM_LOG("iop Sif reg write %x value %x\n", mem, value); MEM_LOG("iop Sif reg write %x value %x", mem, value);
switch (mem & 0xf0) switch (mem & 0xf0)
{ {
case 0x00: // EE write path (EE/IOP readable) case 0x00: // EE write path (EE/IOP readable)

View File

@ -60,13 +60,13 @@ void sio2Reset() {
} }
u32 sio2_getRecv1() { u32 sio2_getRecv1() {
PAD_LOG("Reading Recv1 = %x\n",sio2.packet.recvVal1); PAD_LOG("Reading Recv1 = %x",sio2.packet.recvVal1);
return sio2.packet.recvVal1; return sio2.packet.recvVal1;
} }
u32 sio2_getRecv2() { u32 sio2_getRecv2() {
PAD_LOG("Reading Recv2 = %x\n",0xF); PAD_LOG("Reading Recv2 = %x",0xF);
return 0xf; return 0xf;
}//0, 0x10, 0x20, 0x10 | 0x20; bits 4 & 5 }//0, 0x10, 0x20, 0x10 | 0x20; bits 4 & 5
@ -75,7 +75,7 @@ u32 sio2_getRecv3() {
if(sio2.packet.recvVal3 == 0x8C || sio2.packet.recvVal3 == 0x8b || if(sio2.packet.recvVal3 == 0x8C || sio2.packet.recvVal3 == 0x8b ||
sio2.packet.recvVal3 == 0x83) sio2.packet.recvVal3 == 0x83)
{ {
PAD_LOG("Reading Recv3 = %x\n",sio2.packet.recvVal3); PAD_LOG("Reading Recv3 = %x",sio2.packet.recvVal3);
sio.packetsize = sio2.packet.recvVal3; sio.packetsize = sio2.packet.recvVal3;
sio2.packet.recvVal3 = 0; // Reset sio2.packet.recvVal3 = 0; // Reset
@ -83,7 +83,7 @@ u32 sio2_getRecv3() {
} }
else else
{ {
PAD_LOG("Reading Recv3 = %x\n",sio.packetsize << 16); PAD_LOG("Reading Recv3 = %x",sio.packetsize << 16);
return sio.packetsize << 16; return sio.packetsize << 16;
} }
@ -103,7 +103,7 @@ void sio2_setSend3(u32 index, u32 value)
// for (i=0; i<4; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray2[i]);}PAD_LOG("\n"); // for (i=0; i<4; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray2[i]);}PAD_LOG("\n");
// for (i=0; i<8; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray3[i]);}PAD_LOG("\n"); // for (i=0; i<8; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray3[i]);}PAD_LOG("\n");
// for ( ; i<16; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray3[i]);}PAD_LOG("\n"); // for ( ; i<16; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray3[i]);}PAD_LOG("\n");
PAD_LOG("[%d] : 0x%08X\n", index,sio2.packet.sendArray3[index]); PAD_LOG("[%d] : 0x%08X", index,sio2.packet.sendArray3[index]);
// } // }
} //0->15 } //0->15
@ -148,7 +148,7 @@ void sio2_serialIn(u8 value){
ctrl |= (sio2.packet.sendArray3[sio2.cmdport] & 1) << 13; ctrl |= (sio2.packet.sendArray3[sio2.cmdport] & 1) << 13;
//sioWriteCtrl16(SIO_RESET); //sioWriteCtrl16(SIO_RESET);
sioWriteCtrl16(ctrl); sioWriteCtrl16(ctrl);
PSXDMA_LOG("sio2_fifoIn: ctrl = %x, cmdlength = %x, cmdport = %d (%x)\n", ctrl, sio2.cmdlength, sio2.cmdport, sio2.packet.sendArray3[sio2.cmdport]); PSXDMA_LOG("sio2_fifoIn: ctrl = %x, cmdlength = %x, cmdport = %d (%x)", ctrl, sio2.cmdlength, sio2.cmdport, sio2.packet.sendArray3[sio2.cmdport]);
sio2.cmdport++; sio2.cmdport++;
} }
@ -175,7 +175,7 @@ void sio2_fifoIn(u8 value){
ctrl |= (sio2.packet.sendArray3[sio2.cmdport] & 1) << 13; ctrl |= (sio2.packet.sendArray3[sio2.cmdport] & 1) << 13;
//sioWriteCtrl16(SIO_RESET); //sioWriteCtrl16(SIO_RESET);
sioWriteCtrl16(ctrl); sioWriteCtrl16(ctrl);
PSXDMA_LOG("sio2_fifoIn: ctrl = %x, cmdlength = %x, cmdport = %d (%x)\n", ctrl, sio2.cmdlength, sio2.cmdport, sio2.packet.sendArray3[sio2.cmdport]); PSXDMA_LOG("sio2_fifoIn: ctrl = %x, cmdlength = %x, cmdport = %d (%x)", ctrl, sio2.cmdlength, sio2.cmdport, sio2.packet.sendArray3[sio2.cmdport]);
sio2.cmdport++; sio2.cmdport++;
} }
@ -184,7 +184,7 @@ void sio2_fifoIn(u8 value){
SIODMAWrite(value); SIODMAWrite(value);
if (sio2.packet.sendSize > BUFSIZE) {//asadr if (sio2.packet.sendSize > BUFSIZE) {//asadr
SysPrintf("*PCSX2*: sendSize >= %d\n", BUFSIZE); Console::WriteLn("*PCSX2*: sendSize >= %d", params BUFSIZE);
} else { } else {
sio2.buf[sio2.packet.sendSize] = sioRead8(); sio2.buf[sio2.packet.sendSize] = sioRead8();
sio2.packet.sendSize++; sio2.packet.sendSize++;
@ -214,7 +214,7 @@ void SaveState::sio2Freeze()
void psxDma11(u32 madr, u32 bcr, u32 chcr) { void psxDma11(u32 madr, u32 bcr, u32 chcr) {
unsigned int i, j; unsigned int i, j;
int size = (bcr >> 16) * (bcr & 0xffff); int size = (bcr >> 16) * (bcr & 0xffff);
PSXDMA_LOG("*** DMA 11 - SIO2 in *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); PSXDMA_LOG("*** DMA 11 - SIO2 in *** %lx addr = %lx size = %lx", chcr, madr, bcr);
if (chcr != 0x01000201) return; if (chcr != 0x01000201) return;
@ -243,7 +243,7 @@ void psxDMA11Interrupt()
void psxDma12(u32 madr, u32 bcr, u32 chcr) { void psxDma12(u32 madr, u32 bcr, u32 chcr) {
int size = ((bcr >> 16) * (bcr & 0xFFFF)) * 4; int size = ((bcr >> 16) * (bcr & 0xFFFF)) * 4;
PSXDMA_LOG("*** DMA 12 - SIO2 out *** %lx addr = %lx size = %lx\n", chcr, madr, size); PSXDMA_LOG("*** DMA 12 - SIO2 out *** %lx addr = %lx size = %lx", chcr, madr, size);
if (chcr != 0x41000200) return; if (chcr != 0x41000200) return;

View File

@ -24,8 +24,10 @@ GtkWidget *GameFixDlg, *SpeedHacksDlg;
{ {
GameFixDlg = create_GameFixDlg(); GameFixDlg = create_GameFixDlg();
set_checked(GameFixDlg, "check_FPU_Compare", (Config.GameFixes & FLAG_FPU_Compare));
set_checked(GameFixDlg, "check_VU_Add_Sub", (Config.GameFixes & FLAG_VU_ADD_SUB)); set_checked(GameFixDlg, "check_VU_Add_Sub", (Config.GameFixes & FLAG_VU_ADD_SUB));
set_checked(GameFixDlg, "check_VU_Clip", (Config.GameFixes & FLAG_VU_CLIP));
set_checked(GameFixDlg, "check_FPU_Compare", (Config.GameFixes & FLAG_FPU_Compare));
set_checked(GameFixDlg, "check_FPU_Mul", (Config.GameFixes & FLAG_FPU_MUL)); set_checked(GameFixDlg, "check_FPU_Mul", (Config.GameFixes & FLAG_FPU_MUL));
gtk_widget_show_all(GameFixDlg); gtk_widget_show_all(GameFixDlg);
@ -37,11 +39,15 @@ void on_Game_Fix_OK(GtkButton *button, gpointer user_data)
{ {
Config.GameFixes = 0; Config.GameFixes = 0;
Config.GameFixes |= is_checked(GameFixDlg, "check_FPU_Compare") ? FLAG_FPU_Compare : 0;
Config.GameFixes |= is_checked(GameFixDlg, "check_VU_Add_Sub") ? FLAG_VU_ADD_SUB : 0; Config.GameFixes |= is_checked(GameFixDlg, "check_VU_Add_Sub") ? FLAG_VU_ADD_SUB : 0;
Config.GameFixes |= is_checked(GameFixDlg, "check_VU_Clip") ? FLAG_VU_CLIP : 0;
Config.GameFixes |= is_checked(GameFixDlg, "check_FPU_Compare") ? FLAG_FPU_Compare : 0;
Config.GameFixes |= is_checked(GameFixDlg, "check_FPU_Mul") ? FLAG_FPU_MUL : 0; Config.GameFixes |= is_checked(GameFixDlg, "check_FPU_Mul") ? FLAG_FPU_MUL : 0;
SaveConfig(); SaveConfig();
gtk_widget_destroy(GameFixDlg); gtk_widget_destroy(GameFixDlg);
gtk_widget_set_sensitive(MainWindow, TRUE); gtk_widget_set_sensitive(MainWindow, TRUE);
gtk_main_quit(); gtk_main_quit();

View File

@ -100,8 +100,12 @@ char iop_log_names[9][32] =
"Cdr Log", "Cdr Log",
"GPU Log" "GPU Log"
}; };
//Tri-Ace - IDC_GAMEFIX2 //Tri-Ace - IDC_GAMEFIX2
#define FLAG_VU_ADD_SUB 0x1 #define FLAG_VU_ADD_SUB 0x1
// Persona3/4 - IDC_GAMEFIX4
#define FLAG_VU_CLIP 0x2
// Digimon Rumble Arena - IDC_GAMEFIX3 // Digimon Rumble Arena - IDC_GAMEFIX3
#define FLAG_FPU_Compare 0x4 #define FLAG_FPU_Compare 0x4
//Tales of Destiny - IDC_GAMEFIX5 //Tales of Destiny - IDC_GAMEFIX5

View File

@ -55,11 +55,11 @@ void Close()
__forceinline bool __fastcall Newline() __forceinline bool __fastcall Newline()
{ {
if (Config.PsxOut) if (Config.PsxOut)
puts("\n"); printf("\n");
if (emuLog != NULL) if (emuLog != NULL)
{ {
fputs("\n", emuLog); fprintf(emuLog,"\n");
fflush(emuLog); fflush(emuLog);
} }
@ -68,23 +68,25 @@ __forceinline bool __fastcall Newline()
__forceinline bool __fastcall Write(const char* fmt) __forceinline bool __fastcall Write(const char* fmt)
{ {
if (Config.PsxOut) // By using fputs, append a newline automatically.
fputs(fmt, stdout); if (Config.PsxOut) fputs(fmt, stdout);
if (emuLog != NULL) // Color changing should not use this function, as we don't want the color codes logged, or new lines inserted.
fputs(fmt, emuLog); if (emuLog != NULL) fputs(fmt, emuLog);
return false; return false;
} }
void __fastcall SetColor(Colors color) void __fastcall SetColor(Colors color)
{ {
Write(tbl_color_codes[color]); // Don't log the color change, and don't insert a new line afterwards.
printf(tbl_color_codes[color]);
} }
void ClearColor() void ClearColor()
{ {
Write(COLOR_RESET); // Don't log the color change, and don't insert a new line afterwards.
printf(COLOR_RESET);
} }
} }

View File

@ -891,6 +891,7 @@ create_GameFixDlg (void)
GtkWidget *check_FPU_Compare; GtkWidget *check_FPU_Compare;
GtkWidget *check_VU_Add_Sub; GtkWidget *check_VU_Add_Sub;
GtkWidget *check_FPU_Mul; GtkWidget *check_FPU_Mul;
GtkWidget *check_VU_Clip;
GtkWidget *label42; GtkWidget *label42;
GtkWidget *dialog_action_area1; GtkWidget *dialog_action_area1;
GtkWidget *cancelbutton1; GtkWidget *cancelbutton1;
@ -937,6 +938,11 @@ create_GameFixDlg (void)
gtk_widget_show (check_FPU_Mul); gtk_widget_show (check_FPU_Mul);
gtk_box_pack_start (GTK_BOX (vbox30), check_FPU_Mul, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox30), check_FPU_Mul, FALSE, TRUE, 0);
check_VU_Clip = gtk_check_button_new_with_mnemonic (_("VU Clip Hack - Fixes missing ground geometry in Persona."));
gtk_widget_set_name (check_VU_Clip, "check_VU_Clip");
gtk_widget_show (check_VU_Clip);
gtk_box_pack_start (GTK_BOX (vbox30), check_VU_Clip, FALSE, FALSE, 0);
label42 = gtk_label_new (_("<b>Some games need special settings.\nConfigure them here.</b>")); label42 = gtk_label_new (_("<b>Some games need special settings.\nConfigure them here.</b>"));
gtk_widget_set_name (label42, "label42"); gtk_widget_set_name (label42, "label42");
gtk_widget_show (label42); gtk_widget_show (label42);
@ -976,6 +982,7 @@ create_GameFixDlg (void)
GLADE_HOOKUP_OBJECT (GameFixDlg, check_FPU_Compare, "check_FPU_Compare"); GLADE_HOOKUP_OBJECT (GameFixDlg, check_FPU_Compare, "check_FPU_Compare");
GLADE_HOOKUP_OBJECT (GameFixDlg, check_VU_Add_Sub, "check_VU_Add_Sub"); GLADE_HOOKUP_OBJECT (GameFixDlg, check_VU_Add_Sub, "check_VU_Add_Sub");
GLADE_HOOKUP_OBJECT (GameFixDlg, check_FPU_Mul, "check_FPU_Mul"); GLADE_HOOKUP_OBJECT (GameFixDlg, check_FPU_Mul, "check_FPU_Mul");
GLADE_HOOKUP_OBJECT (GameFixDlg, check_VU_Clip, "check_VU_Clip");
GLADE_HOOKUP_OBJECT (GameFixDlg, label42, "label42"); GLADE_HOOKUP_OBJECT (GameFixDlg, label42, "label42");
GLADE_HOOKUP_OBJECT_NO_REF (GameFixDlg, dialog_action_area1, "dialog_action_area1"); GLADE_HOOKUP_OBJECT_NO_REF (GameFixDlg, dialog_action_area1, "dialog_action_area1");
GLADE_HOOKUP_OBJECT (GameFixDlg, cancelbutton1, "cancelbutton1"); GLADE_HOOKUP_OBJECT (GameFixDlg, cancelbutton1, "cancelbutton1");

View File

@ -1923,6 +1923,25 @@ Known to work well with a couple games, namely Shadow of the Colossus (but break
<property name="fill">True</property> <property name="fill">True</property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkCheckButton" id="check_VU_Clip">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">VU Clip Hack - Fixes missing ground geometry in Persona.</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget> </widget>
</child> </child>
</widget> </widget>

View File

@ -114,10 +114,21 @@ namespace OpcodeImpl {
} }
void DIV1() { void DIV1() {
if (cpuRegs.GPR.r[_Rt_].SL[0] != 0) { if (cpuRegs.GPR.r[_Rs_].UL[0] == 0x80000000 && cpuRegs.GPR.r[_Rt_].UL[0] == 0xffffffff)
{
cpuRegs.LO.SD[1] = (s32)0x80000000;
cpuRegs.HI.SD[1] = (s32)0x0;
}
else if (cpuRegs.GPR.r[_Rt_].SL[0] != 0)
{
cpuRegs.LO.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0] / cpuRegs.GPR.r[_Rt_].SL[0]; cpuRegs.LO.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0] / cpuRegs.GPR.r[_Rt_].SL[0];
cpuRegs.HI.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0] % cpuRegs.GPR.r[_Rt_].SL[0]; cpuRegs.HI.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0] % cpuRegs.GPR.r[_Rt_].SL[0];
} }
else
{
cpuRegs.LO.SD[1] = (cpuRegs.GPR.r[_Rs_].SL[0] < 0) ? 1 : -1;
cpuRegs.HI.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0];
}
} }
void DIVU1() void DIVU1()
@ -129,6 +140,11 @@ namespace OpcodeImpl {
cpuRegs.LO.SD[1] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] / cpuRegs.GPR.r[_Rt_].UL[0]); cpuRegs.LO.SD[1] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] / cpuRegs.GPR.r[_Rt_].UL[0]);
cpuRegs.HI.SD[1] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] % cpuRegs.GPR.r[_Rt_].UL[0]); cpuRegs.HI.SD[1] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] % cpuRegs.GPR.r[_Rt_].UL[0]);
} }
else
{
cpuRegs.LO.SD[1] = -1;
cpuRegs.HI.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0];
}
} }
namespace MMI { namespace MMI {
@ -187,19 +203,19 @@ void PMFHL() {
case 0x02: // SLW case 0x02: // SLW
{ {
u64 TempU64 = ((u64)cpuRegs.HI.UL[0] << 32) | (u64)cpuRegs.LO.UL[0]; s64 TempS64 = ((u64)cpuRegs.HI.UL[0] << 32) | (u64)cpuRegs.LO.UL[0];
if (TempU64 >= 0x000000007fffffffLL) { if (TempS64 >= 0x000000007fffffffLL) {
cpuRegs.GPR.r[_Rd_].UD[0] = 0x000000007fffffffLL; cpuRegs.GPR.r[_Rd_].UD[0] = 0x000000007fffffffLL;
} else if (TempU64 <= 0xffffffff80000000LL) { } else if (TempS64 <= 0xffffffff80000000LL) {
cpuRegs.GPR.r[_Rd_].UD[0] = 0xffffffff80000000LL; cpuRegs.GPR.r[_Rd_].UD[0] = 0xffffffff80000000LL;
} else { } else {
cpuRegs.GPR.r[_Rd_].UD[0] = (s64)cpuRegs.LO.SL[0]; cpuRegs.GPR.r[_Rd_].UD[0] = (s64)cpuRegs.LO.SL[0];
} }
TempU64 = ((u64)cpuRegs.HI.UL[2] << 32) | (u64)cpuRegs.LO.UL[2]; TempS64 = ((u64)cpuRegs.HI.UL[2] << 32) | (u64)cpuRegs.LO.UL[2];
if (TempU64 >= 0x000000007fffffffLL) { if (TempS64 >= 0x000000007fffffffLL) {
cpuRegs.GPR.r[_Rd_].UD[1] = 0x000000007fffffffLL; cpuRegs.GPR.r[_Rd_].UD[1] = 0x000000007fffffffLL;
} else if (TempU64 <= 0xffffffff80000000LL) { } else if (TempS64 <= 0xffffffff80000000LL) {
cpuRegs.GPR.r[_Rd_].UD[1] = 0xffffffff80000000LL; cpuRegs.GPR.r[_Rd_].UD[1] = 0xffffffff80000000LL;
} else { } else {
cpuRegs.GPR.r[_Rd_].UD[1] = (s64)cpuRegs.LO.SL[2]; cpuRegs.GPR.r[_Rd_].UD[1] = (s64)cpuRegs.LO.SL[2];
@ -603,7 +619,7 @@ __forceinline void _PADDSB(int n)
if (sTemp16 > 0x7F) if (sTemp16 > 0x7F)
cpuRegs.GPR.r[_Rd_].UC[n] = 0x7F; cpuRegs.GPR.r[_Rd_].UC[n] = 0x7F;
else if ((sTemp16 < 0x180) && (sTemp16 >= 0x100)) else if (sTemp16 < (s16)0xff80)
cpuRegs.GPR.r[_Rd_].UC[n] = 0x80; cpuRegs.GPR.r[_Rd_].UC[n] = 0x80;
else else
cpuRegs.GPR.r[_Rd_].UC[n] = (s8)sTemp16; cpuRegs.GPR.r[_Rd_].UC[n] = (s8)sTemp16;
@ -624,7 +640,7 @@ static __forceinline void _PSUBSB( u8 n )
if (sTemp16 >= 0x7F) if (sTemp16 >= 0x7F)
cpuRegs.GPR.r[_Rd_].UC[n] = 0x7F; cpuRegs.GPR.r[_Rd_].UC[n] = 0x7F;
else if ((sTemp16 < 0x180) && (sTemp16 >= 0x100)) else if (sTemp16 <= (s16)0xff80)
cpuRegs.GPR.r[_Rd_].UC[n] = 0x80; cpuRegs.GPR.r[_Rd_].UC[n] = 0x80;
else else
cpuRegs.GPR.r[_Rd_].UC[n] = (s8)sTemp16; cpuRegs.GPR.r[_Rd_].UC[n] = (s8)sTemp16;
@ -727,7 +743,12 @@ void PPAC5() {
__forceinline void _PABSW(int n) __forceinline void _PABSW(int n)
{ {
cpuRegs.GPR.r[_Rd_].UL[n] = abs(cpuRegs.GPR.r[_Rt_].SL[n]); if (cpuRegs.GPR.r[_Rt_].UL[n] == 0x80000000)
cpuRegs.GPR.r[_Rd_].UL[n] = 0x7fffffff; //clamp
else if (cpuRegs.GPR.r[_Rt_].SL[n] < 0)
cpuRegs.GPR.r[_Rd_].UL[n] = - cpuRegs.GPR.r[_Rt_].SL[n];
else
cpuRegs.GPR.r[_Rd_].UL[n] = cpuRegs.GPR.r[_Rt_].SL[n];
} }
void PABSW() { void PABSW() {
@ -773,7 +794,12 @@ void PADSBH() {
__forceinline void _PABSH(int n) __forceinline void _PABSH(int n)
{ {
cpuRegs.GPR.r[_Rd_].US[n] = abs(cpuRegs.GPR.r[_Rt_].SS[n]); if (cpuRegs.GPR.r[_Rt_].US[n] == 0x8000)
cpuRegs.GPR.r[_Rd_].US[n] = 0x7fff; //clamp
else if (cpuRegs.GPR.r[_Rt_].SS[n] < 0)
cpuRegs.GPR.r[_Rd_].US[n] = - cpuRegs.GPR.r[_Rt_].SS[n];
else
cpuRegs.GPR.r[_Rd_].US[n] = cpuRegs.GPR.r[_Rt_].SS[n];
} }
void PABSH() { void PABSH() {
@ -994,38 +1020,39 @@ void QFSRV() { // JayteeMaster: changed a bit to avoid screw up
GPR_reg Rd; GPR_reg Rd;
if (!_Rd_) return; if (!_Rd_) return;
if (cpuRegs.sa == 0) { u32 sa_amt = cpuRegs.sa << 3;
if (sa_amt == 0) {
cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[0]; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[0];
cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rt_].UD[1]; cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rt_].UD[1];
//saZero++; //saZero++;
//if( saZero >= 388800 ) //if( saZero >= 388800 )
//Console::WriteLn( "SA Is Zero, Bitch: %d zeros and counting.", params saZero ); //Console::WriteLn( "SA Is Zero, Bitch: %d zeros and counting.", params saZero );
} else { } else {
//Console::WriteLn( "SA Properly Valued at: %d (after %d zeros)", params cpuRegs.sa, saZero ); //Console::WriteLn( "SA Properly Valued at: %d (after %d zeros)", params sa_amt, saZero );
//saZero = 0; //saZero = 0;
if (cpuRegs.sa < 64) { if (sa_amt < 64) {
/* /*
cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[0] >> cpuRegs.sa; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[0] >> sa_amt;
cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rt_].UD[1] >> cpuRegs.sa; cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rt_].UD[1] >> sa_amt;
cpuRegs.GPR.r[_Rd_].UD[0]|= cpuRegs.GPR.r[_Rt_].UD[1] << (64 - cpuRegs.sa); cpuRegs.GPR.r[_Rd_].UD[0]|= cpuRegs.GPR.r[_Rt_].UD[1] << (64 - sa_amt);
cpuRegs.GPR.r[_Rd_].UD[1]|= cpuRegs.GPR.r[_Rs_].UD[0] << (64 - cpuRegs.sa); cpuRegs.GPR.r[_Rd_].UD[1]|= cpuRegs.GPR.r[_Rs_].UD[0] << (64 - sa_amt);
*/ */
Rd.UD[0] = cpuRegs.GPR.r[_Rt_].UD[0] >> cpuRegs.sa; Rd.UD[0] = cpuRegs.GPR.r[_Rt_].UD[0] >> sa_amt;
Rd.UD[1] = cpuRegs.GPR.r[_Rt_].UD[1] >> cpuRegs.sa; Rd.UD[1] = cpuRegs.GPR.r[_Rt_].UD[1] >> sa_amt;
Rd.UD[0]|= cpuRegs.GPR.r[_Rt_].UD[1] << (64 - cpuRegs.sa); Rd.UD[0]|= cpuRegs.GPR.r[_Rt_].UD[1] << (64 - sa_amt);
Rd.UD[1]|= cpuRegs.GPR.r[_Rs_].UD[0] << (64 - cpuRegs.sa); Rd.UD[1]|= cpuRegs.GPR.r[_Rs_].UD[0] << (64 - sa_amt);
cpuRegs.GPR.r[_Rd_] = Rd; cpuRegs.GPR.r[_Rd_] = Rd;
} else { } else {
/* /*
cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[1] >> (cpuRegs.sa - 64); cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[1] >> (sa_amt - 64);
cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rs_].UD[0] >> (cpuRegs.sa - 64); cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rs_].UD[0] >> (sa_amt - 64);
cpuRegs.GPR.r[_Rd_].UD[0]|= cpuRegs.GPR.r[_Rs_].UD[0] << (128 - cpuRegs.sa); cpuRegs.GPR.r[_Rd_].UD[0]|= cpuRegs.GPR.r[_Rs_].UD[0] << (128 - sa_amt);
cpuRegs.GPR.r[_Rd_].UD[1]|= cpuRegs.GPR.r[_Rs_].UD[1] << (128 - cpuRegs.sa); cpuRegs.GPR.r[_Rd_].UD[1]|= cpuRegs.GPR.r[_Rs_].UD[1] << (128 - sa_amt);
*/ */
Rd.UD[0] = cpuRegs.GPR.r[_Rt_].UD[1] >> (cpuRegs.sa - 64); Rd.UD[0] = cpuRegs.GPR.r[_Rt_].UD[1] >> (sa_amt - 64);
Rd.UD[1] = cpuRegs.GPR.r[_Rs_].UD[0] >> (cpuRegs.sa - 64); Rd.UD[1] = cpuRegs.GPR.r[_Rs_].UD[0] >> (sa_amt - 64);
Rd.UD[0]|= cpuRegs.GPR.r[_Rs_].UD[0] << (128 - cpuRegs.sa); Rd.UD[0]|= cpuRegs.GPR.r[_Rs_].UD[0] << (128 - sa_amt);
Rd.UD[1]|= cpuRegs.GPR.r[_Rs_].UD[1] << (128 - cpuRegs.sa); Rd.UD[1]|= cpuRegs.GPR.r[_Rs_].UD[1] << (128 - sa_amt);
cpuRegs.GPR.r[_Rd_] = Rd; cpuRegs.GPR.r[_Rd_] = Rd;
} }
} }
@ -1132,11 +1159,21 @@ void PMULTW() {
__forceinline void _PDIVW(int dd, int ss) __forceinline void _PDIVW(int dd, int ss)
{ {
if (cpuRegs.GPR.r[_Rt_].UL[ss] != 0) if (cpuRegs.GPR.r[_Rs_].UL[ss] == 0x80000000 && cpuRegs.GPR.r[_Rt_].UL[ss] == 0xffffffff)
{
cpuRegs.LO.SD[dd] = (s32)0x80000000;
cpuRegs.HI.SD[dd] = (s32)0;
}
else if (cpuRegs.GPR.r[_Rt_].SL[ss] != 0)
{ {
cpuRegs.LO.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss] / cpuRegs.GPR.r[_Rt_].SL[ss]; cpuRegs.LO.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss] / cpuRegs.GPR.r[_Rt_].SL[ss];
cpuRegs.HI.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss] % cpuRegs.GPR.r[_Rt_].SL[ss]; cpuRegs.HI.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss] % cpuRegs.GPR.r[_Rt_].SL[ss];
} }
else
{
cpuRegs.LO.SD[dd] = (cpuRegs.GPR.r[_Rs_].SL[ss] < 0) ? 1 : -1;
cpuRegs.HI.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss];
}
} }
void PDIVW() { void PDIVW() {
@ -1196,18 +1233,20 @@ void PMADDH() { // JayteeMaster: changed a bit to avoid screw up
// JayteeMaster: changed a bit to avoid screw up // JayteeMaster: changed a bit to avoid screw up
__forceinline void _PHMADH_LO(int dd, int n) __forceinline void _PHMADH_LO(int dd, int n)
{ {
s32 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1] + \ s32 firsttemp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1];
(s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n]; s32 temp = firsttemp + (s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
cpuRegs.LO.UL[dd] = temp; cpuRegs.LO.UL[dd] = temp;
cpuRegs.LO.UL[dd+1] = firsttemp;
} }
__forceinline void _PHMADH_HI(int dd, int n) __forceinline void _PHMADH_HI(int dd, int n)
{ {
s32 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1] + \ s32 firsttemp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1];
(s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n]; s32 temp = firsttemp + (s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
cpuRegs.HI.UL[dd] = temp; cpuRegs.HI.UL[dd] = temp;
cpuRegs.HI.UL[dd+1] = firsttemp;
} }
void PHMADH() { // JayteeMaster: changed a bit to avoid screw up. Also used 0,2,4,6 instead of 0,1,2,3 void PHMADH() { // JayteeMaster: changed a bit to avoid screw up. Also used 0,2,4,6 instead of 0,1,2,3
@ -1279,17 +1318,19 @@ void PMSUBH() { // JayteeMaster: changed a bit to avoid screw up
// JayteeMaster: changed a bit to avoid screw up // JayteeMaster: changed a bit to avoid screw up
__forceinline void _PHMSBH_LO(int dd, int n, int rdd) __forceinline void _PHMSBH_LO(int dd, int n, int rdd)
{ {
s32 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1] - \ s32 firsttemp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1];
(s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n]; s32 temp = firsttemp - (s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
cpuRegs.LO.UL[dd] = temp; cpuRegs.LO.UL[dd] = temp;
cpuRegs.LO.UL[dd+1] = ~firsttemp;
} }
__forceinline void _PHMSBH_HI(int dd, int n, int rdd) __forceinline void _PHMSBH_HI(int dd, int n, int rdd)
{ {
s32 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1] - \ s32 firsttemp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1];
(s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n]; s32 temp = firsttemp - (s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
cpuRegs.HI.UL[dd] = temp; cpuRegs.HI.UL[dd] = temp;
cpuRegs.HI.UL[dd+1] = ~firsttemp;
} }
void PHMSBH() { // JayteeMaster: changed a bit to avoid screw up void PHMSBH() { // JayteeMaster: changed a bit to avoid screw up
@ -1378,13 +1419,24 @@ void PMULTH() { // JayteeMaster: changed a bit to avoid screw up
__forceinline void _PDIVBW(int n) __forceinline void _PDIVBW(int n)
{ {
cpuRegs.LO.UL[n] = (s32)(cpuRegs.GPR.r[_Rs_].SL[n] / cpuRegs.GPR.r[_Rt_].SS[0]); if (cpuRegs.GPR.r[_Rs_].UL[n] == 0x80000000 && cpuRegs.GPR.r[_Rt_].US[0] == 0xffff)
cpuRegs.HI.UL[n] = (s16)(cpuRegs.GPR.r[_Rs_].SL[n] % cpuRegs.GPR.r[_Rt_].SS[0]); {
cpuRegs.LO.SL[n] = (s32)0x80000000;
cpuRegs.HI.SL[n] = (s32)0x0;
}
else if (cpuRegs.GPR.r[_Rt_].US[0] != 0)
{
cpuRegs.LO.SL[n] = cpuRegs.GPR.r[_Rs_].SL[n] / cpuRegs.GPR.r[_Rt_].SS[0];
cpuRegs.HI.SL[n] = cpuRegs.GPR.r[_Rs_].SL[n] % cpuRegs.GPR.r[_Rt_].SS[0];
}
else
{
cpuRegs.LO.SL[n] = (cpuRegs.GPR.r[_Rs_].SL[n] < 0) ? 1 : -1;
cpuRegs.HI.SL[n] = cpuRegs.GPR.r[_Rs_].SL[n];
}
} }
void PDIVBW() { void PDIVBW() {
if (cpuRegs.GPR.r[_Rt_].US[0] == 0) return;
_PDIVBW(0); _PDIVBW(1); _PDIVBW(2); _PDIVBW(3); _PDIVBW(0); _PDIVBW(1); _PDIVBW(2); _PDIVBW(3);
} }
@ -1486,8 +1538,13 @@ void PMULTUW() {
__forceinline void _PDIVUW(int dd, int ss) __forceinline void _PDIVUW(int dd, int ss)
{ {
if (cpuRegs.GPR.r[_Rt_].UL[ss] != 0) { if (cpuRegs.GPR.r[_Rt_].UL[ss] != 0) {
cpuRegs.LO.UD[dd] = (u64)cpuRegs.GPR.r[_Rs_].UL[ss] / (u64)cpuRegs.GPR.r[_Rt_].UL[ss]; cpuRegs.LO.SD[dd] = (s32)(cpuRegs.GPR.r[_Rs_].UL[ss] / cpuRegs.GPR.r[_Rt_].UL[ss]);
cpuRegs.HI.UD[dd] = (u64)cpuRegs.GPR.r[_Rs_].UL[ss] % (u64)cpuRegs.GPR.r[_Rt_].UL[ss]; cpuRegs.HI.SD[dd] = (s32)(cpuRegs.GPR.r[_Rs_].UL[ss] % cpuRegs.GPR.r[_Rt_].UL[ss]);
}
else
{
cpuRegs.LO.SD[dd] = -1;
cpuRegs.HI.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss];
} }
} }

View File

@ -290,7 +290,7 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u
--size; --size;
if(pathidx == 2 && path.tag.eop) if(pathidx == 2 && path.tag.eop)
Path3transfer = 0; Path3transfer = FALSE;
if( pathidx == 0 ) if( pathidx == 0 )
{ {
@ -327,7 +327,7 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u
} }
else if(path.tag.nloop == 0) else if(path.tag.nloop == 0)
{ {
if(pathidx == 0 && g_FFXHack) if(pathidx == 0)
continue; continue;
eop = true; eop = true;
@ -952,7 +952,7 @@ int mtgsThreadObject::PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 s
else // always true - if( writepos + size == MTGS_RINGBUFFEREND ) else // always true - if( writepos + size == MTGS_RINGBUFFEREND )
{ {
// Yay. Perfect fit. What are the odds? // Yay. Perfect fit. What are the odds?
//SysPrintf( "MTGS > Perfect Fit!\n"); //Console::WriteLn( "MTGS > Perfect Fit!");
PrepEventWait(); PrepEventWait();
while( true ) while( true )

View File

@ -156,7 +156,7 @@ void mdecInit(void) {
void mdecWrite0(u32 data) { void mdecWrite0(u32 data) {
CDR_LOG("mdec0 write %lx\n", data); CDR_LOG("mdec0 write %lx", data);
mdec.command = data; mdec.command = data;
if ((data&0xf5ff0000)==0x30000000) { if ((data&0xf5ff0000)==0x30000000) {
@ -165,7 +165,7 @@ void mdecWrite0(u32 data) {
} }
void mdecWrite1(u32 data) { void mdecWrite1(u32 data) {
CDR_LOG("mdec1 write %lx\n", data); CDR_LOG("mdec1 write %lx", data);
if (data&0x80000000) { // mdec reset if (data&0x80000000) { // mdec reset
round_init(); round_init();
@ -174,14 +174,14 @@ void mdecWrite1(u32 data) {
} }
u32 mdecRead0(void) { u32 mdecRead0(void) {
CDR_LOG("mdec0 read %lx\n", mdec.command); CDR_LOG("mdec0 read %lx", mdec.command);
return mdec.command; return mdec.command;
} }
u32 mdecRead1(void) { u32 mdecRead1(void) {
#ifdef CDR_LOG #ifdef CDR_LOG
CDR_LOG("mdec1 read %lx\n", mdec.status); CDR_LOG("mdec1 read %lx", mdec.status);
#endif #endif
return mdec.status; return mdec.status;
} }
@ -190,7 +190,7 @@ void psxDma0(u32 adr, u32 bcr, u32 chcr) {
int cmd = mdec.command; int cmd = mdec.command;
int size; int size;
CDR_LOG("DMA0 %lx %lx %lx\n", adr, bcr, chcr); CDR_LOG("DMA0 %lx %lx %lx", adr, bcr, chcr);
if (chcr!=0x01000201) return; if (chcr!=0x01000201) return;
@ -214,7 +214,7 @@ void psxDma1(u32 adr, u32 bcr, u32 chcr) {
unsigned short *image; unsigned short *image;
int size; int size;
CDR_LOG("DMA1 %lx %lx %lx (cmd = %lx)\n", adr, bcr, chcr, mdec.command); CDR_LOG("DMA1 %lx %lx %lx (cmd = %lx)", adr, bcr, chcr, mdec.command);
if (chcr!=0x01000200) return; if (chcr!=0x01000200) return;

View File

@ -71,7 +71,7 @@ void memSetUserMode() {
u16 ba0R16(u32 mem) u16 ba0R16(u32 mem)
{ {
//MEM_LOG("ba00000 Memory read16 address %x\n", mem); //MEM_LOG("ba00000 Memory read16 address %x", mem);
if (mem == 0x1a000006) { if (mem == 0x1a000006) {
static int ba6; static int ba6;
@ -132,7 +132,7 @@ u8 *psS = NULL; //0.015 mb, scratch pad
void MyMemCheck(u32 mem) void MyMemCheck(u32 mem)
{ {
if( mem == 0x1c02f2a0 ) if( mem == 0x1c02f2a0 )
SysPrintf("yo\n"); Console::WriteLn("yo; (mem == 0x1c02f2a0) in MyMemCheck...");
} }
///////////////////////////// /////////////////////////////
@ -254,12 +254,12 @@ mem8_t __fastcall _ext_memRead8 (u32 mem)
case 7: // dev9 case 7: // dev9
{ {
mem8_t retval = DEV9read8(mem & ~0xa4000000); mem8_t retval = DEV9read8(mem & ~0xa4000000);
SysPrintf("DEV9 read8 %8.8lx: %2.2lx\n", mem & ~0xa4000000, retval); Console::WriteLn("DEV9 read8 %8.8lx: %2.2lx", params mem & ~0xa4000000, retval);
return retval; return retval;
} }
} }
MEM_LOG("Unknown Memory Read8 from address %8.8x\n", mem); MEM_LOG("Unknown Memory Read8 from address %8.8x", mem);
cpuTlbMissR(mem, cpuRegs.branch); cpuTlbMissR(mem, cpuRegs.branch);
return 0; return 0;
} }
@ -274,7 +274,7 @@ mem16_t __fastcall _ext_memRead16(u32 mem)
case 2: // psh case 2: // psh
return psxHwRead16(mem); return psxHwRead16(mem);
case 4: // b80 case 4: // b80
MEM_LOG("b800000 Memory read16 address %x\n", mem); MEM_LOG("b800000 Memory read16 address %x", mem);
return 0; return 0;
case 5: // ba0 case 5: // ba0
return ba0R16(mem); return ba0R16(mem);
@ -284,14 +284,14 @@ mem16_t __fastcall _ext_memRead16(u32 mem)
case 7: // dev9 case 7: // dev9
{ {
mem16_t retval = DEV9read16(mem & ~0xa4000000); mem16_t retval = DEV9read16(mem & ~0xa4000000);
SysPrintf("DEV9 read16 %8.8lx: %4.4lx\n", mem & ~0xa4000000, retval); Console::WriteLn("DEV9 read16 %8.8lx: %4.4lx", params mem & ~0xa4000000, retval);
return retval; return retval;
} }
case 8: // spu2 case 8: // spu2
return SPU2read(mem); return SPU2read(mem);
} }
MEM_LOG("Unknown Memory read16 from address %8.8x\n", mem); MEM_LOG("Unknown Memory read16 from address %8.8x", mem);
cpuTlbMissR(mem, cpuRegs.branch); cpuTlbMissR(mem, cpuRegs.branch);
return 0; return 0;
} }
@ -308,12 +308,12 @@ mem32_t __fastcall _ext_memRead32(u32 mem)
case 7: // dev9 case 7: // dev9
{ {
mem32_t retval = DEV9read32(mem & ~0xa4000000); mem32_t retval = DEV9read32(mem & ~0xa4000000);
SysPrintf("DEV9 read32 %8.8lx: %8.8lx\n", mem & ~0xa4000000, retval); Console::WriteLn("DEV9 read32 %8.8lx: %8.8lx", params mem & ~0xa4000000, retval);
return retval; return retval;
} }
} }
MEM_LOG("Unknown Memory read32 from address %8.8x (Status=%8.8x)\n", mem, cpuRegs.CP0.n.Status.val); MEM_LOG("Unknown Memory read32 from address %8.8x (Status=%8.8x)", mem, cpuRegs.CP0.n.Status.val);
cpuTlbMissR(mem, cpuRegs.branch); cpuTlbMissR(mem, cpuRegs.branch);
return 0; return 0;
} }
@ -327,7 +327,7 @@ void __fastcall _ext_memRead64(u32 mem, mem64_t *out)
*out = gsRead64(mem); return; *out = gsRead64(mem); return;
} }
MEM_LOG("Unknown Memory read64 from address %8.8x\n", mem); MEM_LOG("Unknown Memory read64 from address %8.8x", mem);
cpuTlbMissR(mem, cpuRegs.branch); cpuTlbMissR(mem, cpuRegs.branch);
} }
@ -343,7 +343,7 @@ void __fastcall _ext_memRead128(u32 mem, mem128_t *out)
out[1] = gsRead64(mem+8); return; out[1] = gsRead64(mem+8); return;
} }
MEM_LOG("Unknown Memory read128 from address %8.8x\n", mem); MEM_LOG("Unknown Memory read128 from address %8.8x", mem);
cpuTlbMissR(mem, cpuRegs.branch); cpuTlbMissR(mem, cpuRegs.branch);
} }
@ -362,11 +362,11 @@ void __fastcall _ext_memWrite8 (u32 mem, u8 value)
gsWrite8(mem, value); return; gsWrite8(mem, value); return;
case 7: // dev9 case 7: // dev9
DEV9write8(mem & ~0xa4000000, value); DEV9write8(mem & ~0xa4000000, value);
SysPrintf("DEV9 write8 %8.8lx: %2.2lx\n", mem & ~0xa4000000, value); Console::WriteLn("DEV9 write8 %8.8lx: %2.2lx", params mem & ~0xa4000000, value);
return; return;
} }
MEM_LOG("Unknown Memory write8 to address %x with data %2.2x\n", mem, value); MEM_LOG("Unknown Memory write8 to address %x with data %2.2x", mem, value);
cpuTlbMissW(mem, cpuRegs.branch); cpuTlbMissW(mem, cpuRegs.branch);
} }
template<int p> template<int p>
@ -379,18 +379,18 @@ void __fastcall _ext_memWrite16(u32 mem, u16 value)
case 2: // psh case 2: // psh
psxHwWrite16(mem, value); return; psxHwWrite16(mem, value); return;
case 5: // ba0 case 5: // ba0
MEM_LOG("ba00000 Memory write16 to address %x with data %x\n", mem, value); MEM_LOG("ba00000 Memory write16 to address %x with data %x", mem, value);
return; return;
case 6: // gsm case 6: // gsm
gsWrite16(mem, value); return; gsWrite16(mem, value); return;
case 7: // dev9 case 7: // dev9
DEV9write16(mem & ~0xa4000000, value); DEV9write16(mem & ~0xa4000000, value);
SysPrintf("DEV9 write16 %8.8lx: %4.4lx\n", mem & ~0xa4000000, value); Console::WriteLn("DEV9 write16 %8.8lx: %4.4lx", params mem & ~0xa4000000, value);
return; return;
case 8: // spu2 case 8: // spu2
SPU2write(mem, value); return; SPU2write(mem, value); return;
} }
MEM_LOG("Unknown Memory write16 to address %x with data %4.4x\n", mem, value); MEM_LOG("Unknown Memory write16 to address %x with data %4.4x", mem, value);
cpuTlbMissW(mem, cpuRegs.branch); cpuTlbMissW(mem, cpuRegs.branch);
} }
@ -404,10 +404,10 @@ void __fastcall _ext_memWrite32(u32 mem, u32 value)
gsWrite32(mem, value); return; gsWrite32(mem, value); return;
case 7: // dev9 case 7: // dev9
DEV9write32(mem & ~0xa4000000, value); DEV9write32(mem & ~0xa4000000, value);
SysPrintf("DEV9 write32 %8.8lx: %8.8lx\n", mem & ~0xa4000000, value); Console::WriteLn("DEV9 write32 %8.8lx: %8.8lx", params mem & ~0xa4000000, value);
return; return;
} }
MEM_LOG("Unknown Memory write32 to address %x with data %8.8x\n", mem, value); MEM_LOG("Unknown Memory write32 to address %x with data %8.8x", mem, value);
cpuTlbMissW(mem, cpuRegs.branch); cpuTlbMissW(mem, cpuRegs.branch);
} }
@ -423,7 +423,7 @@ void __fastcall _ext_memWrite64(u32 mem, const u64* value)
// gsWrite64(mem & ~0xa0000000, *value); return; // gsWrite64(mem & ~0xa0000000, *value); return;
}*/ }*/
MEM_LOG("Unknown Memory write64 to address %x with data %8.8x_%8.8x\n", mem, (u32)(*value>>32), (u32)*value); MEM_LOG("Unknown Memory write64 to address %x with data %8.8x_%8.8x", mem, (u32)(*value>>32), (u32)*value);
cpuTlbMissW(mem, cpuRegs.branch); cpuTlbMissW(mem, cpuRegs.branch);
} }
@ -440,7 +440,7 @@ void __fastcall _ext_memWrite128(u32 mem, const u64 *value)
// gsWrite64(mem+8, value[1]); return; // gsWrite64(mem+8, value[1]); return;
}*/ }*/
MEM_LOG("Unknown Memory write128 to address %x with data %8.8x_%8.8x_%8.8x_%8.8x\n", mem, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]); MEM_LOG("Unknown Memory write128 to address %x with data %8.8x_%8.8x_%8.8x_%8.8x", mem, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]);
cpuTlbMissW(mem, cpuRegs.branch); cpuTlbMissW(mem, cpuRegs.branch);
} }
@ -588,7 +588,7 @@ void __fastcall vuMicroWrite128(u32 addr,const mem128_t* data)
void memSetPageAddr(u32 vaddr, u32 paddr) void memSetPageAddr(u32 vaddr, u32 paddr)
{ {
//SysPrintf("memSetPageAddr: %8.8x -> %8.8x\n", vaddr, paddr); //Console::WriteLn("memSetPageAddr: %8.8x -> %8.8x", params vaddr, paddr);
vtlb_VMap(vaddr,paddr,0x1000); vtlb_VMap(vaddr,paddr,0x1000);
@ -596,7 +596,7 @@ void memSetPageAddr(u32 vaddr, u32 paddr)
void memClearPageAddr(u32 vaddr) void memClearPageAddr(u32 vaddr)
{ {
//SysPrintf("memClearPageAddr: %8.8x\n", vaddr); //Console::WriteLn("memClearPageAddr: %8.8x", params vaddr);
vtlb_VMapUnmap(vaddr,0x1000); // -> whut ? vtlb_VMapUnmap(vaddr,0x1000); // -> whut ?

View File

@ -653,7 +653,8 @@ int AddPatch(int Mode, int Place, int Address, int Size, u64 data)
void patchFunc_ffxhack( char * cmd, char * param ) void patchFunc_ffxhack( char * cmd, char * param )
{ {
g_FFXHack = 1; //Keeping this as a dummy a while :p
//g_FFXHack = 1;
} }
void patchFunc_xkickdelay( char * cmd, char * param ) void patchFunc_xkickdelay( char * cmd, char * param )
@ -674,7 +675,7 @@ void patchFunc_vunanmode( char * cmd, char * param )
void patchFunc_path3hack( char * cmd, char * param ) void patchFunc_path3hack( char * cmd, char * param )
{ {
path3hack = 1; path3hack = TRUE;
} }
void patchFunc_roundmode( char * cmd, char * param ) void patchFunc_roundmode( char * cmd, char * param )

View File

@ -109,8 +109,7 @@ int AddPatch(int Mode, int Place, int Address, int Size, u64 data);
extern void SetFastMemory(int); // iR5900LoadStore.c extern void SetFastMemory(int); // iR5900LoadStore.c
extern int path3hack; extern bool path3hack;
extern int g_FFXHack;
//extern int g_VUGameFixes; //extern int g_VUGameFixes;
extern int g_ZeroGSOptions; extern int g_ZeroGSOptions;
extern u32 g_sseMXCSR; extern u32 g_sseMXCSR;

View File

@ -72,6 +72,8 @@ _PADconfigure PAD1configure;
_PADtest PAD1test; _PADtest PAD1test;
_PADabout PAD1about; _PADabout PAD1about;
_PADfreeze PAD1freeze; _PADfreeze PAD1freeze;
_PADsetSlot PAD1setSlot;
_PADqueryMtap PAD1queryMtap;
// PAD2 // PAD2
_PADinit PAD2init; _PADinit PAD2init;
@ -89,6 +91,8 @@ _PADconfigure PAD2configure;
_PADtest PAD2test; _PADtest PAD2test;
_PADabout PAD2about; _PADabout PAD2about;
_PADfreeze PAD2freeze; _PADfreeze PAD2freeze;
_PADsetSlot PAD2setSlot;
_PADqueryMtap PAD2queryMtap;
// SIO[2] // SIO[2]
_SIOinit SIOinit[2][9]; _SIOinit SIOinit[2][9];
@ -269,7 +273,7 @@ void CALLBACK GS_printf(int timeout, char *fmt, ...) {
vsprintf(msg, fmt, list); vsprintf(msg, fmt, list);
va_end(list); va_end(list);
SysPrintf(msg); Console::WriteLn(msg);
} }
s32 CALLBACK GS_freeze(int mode, freezeData *data) { data->size = 0; return 0; } s32 CALLBACK GS_freeze(int mode, freezeData *data) { data->size = 0; return 0; }
@ -332,7 +336,9 @@ void *PAD1plugin;
void CALLBACK PAD1_configure() {} void CALLBACK PAD1_configure() {}
void CALLBACK PAD1_about() {} void CALLBACK PAD1_about() {}
s32 CALLBACK PAD1_test() { return 0; } s32 CALLBACK PAD1_test() { return 0; }
s32 CALLBACK PAD1_freeze(int mode, freezeData *data) { data->size = 0; return 0; } s32 CALLBACK PAD1_freeze(int mode, freezeData *data) { if (mode == FREEZE_SIZE) data->size = 0; return 0; }
s32 CALLBACK PAD1_setSlot(u8 port, u8 slot) { return slot == 1; }
s32 CALLBACK PAD1_queryMtap(u8 port) { return 0; }
int LoadPAD1plugin(const string& filename) { int LoadPAD1plugin(const string& filename) {
void *drv; void *drv;
@ -356,6 +362,8 @@ int LoadPAD1plugin(const string& filename) {
MapSymbolPAD_Fallback(PAD1,PAD,about); MapSymbolPAD_Fallback(PAD1,PAD,about);
MapSymbolPAD_Fallback(PAD1,PAD,test); MapSymbolPAD_Fallback(PAD1,PAD,test);
MapSymbolPAD_Fallback(PAD1,PAD,freeze); MapSymbolPAD_Fallback(PAD1,PAD,freeze);
MapSymbolPAD_Fallback(PAD1,PAD,setSlot);
MapSymbolPAD_Fallback(PAD1,PAD,queryMtap);
return 0; return 0;
} }
@ -365,7 +373,9 @@ void *PAD2plugin;
void CALLBACK PAD2_configure() {} void CALLBACK PAD2_configure() {}
void CALLBACK PAD2_about() {} void CALLBACK PAD2_about() {}
s32 CALLBACK PAD2_test() { return 0; } s32 CALLBACK PAD2_test() { return 0; }
s32 CALLBACK PAD2_freeze(int mode, freezeData *data) { data->size = 0; return 0; } s32 CALLBACK PAD2_freeze(int mode, freezeData *data) { if (mode == FREEZE_SIZE) data->size = 0; return 0; }
s32 CALLBACK PAD2_setSlot(u8 port, u8 slot) { return slot == 1; }
s32 CALLBACK PAD2_queryMtap(u8 port) { return 0; }
int LoadPAD2plugin(const string& filename) { int LoadPAD2plugin(const string& filename) {
void *drv; void *drv;
@ -389,6 +399,8 @@ int LoadPAD2plugin(const string& filename) {
MapSymbolPAD_Fallback(PAD2,PAD,about); MapSymbolPAD_Fallback(PAD2,PAD,about);
MapSymbolPAD_Fallback(PAD2,PAD,test); MapSymbolPAD_Fallback(PAD2,PAD,test);
MapSymbolPAD_Fallback(PAD2,PAD,freeze); MapSymbolPAD_Fallback(PAD2,PAD,freeze);
MapSymbolPAD_Fallback(PAD2,PAD,setSlot);
MapSymbolPAD_Fallback(PAD2,PAD,queryMtap);
return 0; return 0;
} }

View File

@ -75,8 +75,8 @@ void psxShutdown() {
} }
void psxException(u32 code, u32 bd) { void psxException(u32 code, u32 bd) {
// PSXCPU_LOG("psxException %x: %x, %x\n", code, psxHu32(0x1070), psxHu32(0x1074)); // PSXCPU_LOG("psxException %x: %x, %x", code, psxHu32(0x1070), psxHu32(0x1074));
//SysPrintf("!! psxException %x: %x, %x\n", code, psxHu32(0x1070), psxHu32(0x1074)); //Console::WriteLn("!! psxException %x: %x, %x", params code, psxHu32(0x1070), psxHu32(0x1074));
// Set the Cause // Set the Cause
psxRegs.CP0.n.Cause &= ~0x7f; psxRegs.CP0.n.Cause &= ~0x7f;
psxRegs.CP0.n.Cause |= code; psxRegs.CP0.n.Cause |= code;
@ -84,7 +84,7 @@ void psxException(u32 code, u32 bd) {
// Set the EPC & PC // Set the EPC & PC
if (bd) if (bd)
{ {
PSXCPU_LOG("bd set\n"); PSXCPU_LOG("bd set");
psxRegs.CP0.n.Cause|= 0x80000000; psxRegs.CP0.n.Cause|= 0x80000000;
psxRegs.CP0.n.EPC = (psxRegs.pc - 4); psxRegs.CP0.n.EPC = (psxRegs.pc - 4);
} }
@ -111,7 +111,7 @@ void psxException(u32 code, u32 bd) {
case 0xa0: case 0xa0:
if (call != 0x28 && call != 0xe) if (call != 0x28 && call != 0xe)
PSXBIOS_LOG("Bios call a0: %s (%x) %x,%x,%x,%x\n", biosA0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); PSXBIOS_LOG("Bios call a0: %s (%x) %x,%x,%x,%x", biosA0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3);
if (biosA0[call]) if (biosA0[call])
biosA0[call](); biosA0[call]();
@ -119,14 +119,14 @@ void psxException(u32 code, u32 bd) {
case 0xb0: case 0xb0:
if (call != 0x17 && call != 0xb) if (call != 0x17 && call != 0xb)
PSXBIOS_LOG("Bios call b0: %s (%x) %x,%x,%x,%x\n", biosB0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); PSXBIOS_LOG("Bios call b0: %s (%x) %x,%x,%x,%x", biosB0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3);
if (biosB0[call]) if (biosB0[call])
biosB0[call](); biosB0[call]();
break; break;
case 0xc0: case 0xc0:
PSXBIOS_LOG("Bios call c0: %s (%x) %x,%x,%x,%x\n", biosC0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); PSXBIOS_LOG("Bios call c0: %s (%x) %x,%x,%x,%x", biosC0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3);
if (biosC0[call]) if (biosC0[call])
biosC0[call](); biosC0[call]();
@ -169,7 +169,7 @@ __forceinline void PSX_INT( IopEventId n, s32 ecycle )
// Exception: IRQ16 - SIO - it drops ints like crazy when handling PAD stuff. // Exception: IRQ16 - SIO - it drops ints like crazy when handling PAD stuff.
//if( /*n!=16 &&*/ psxRegs.interrupt & (1<<n) ) //if( /*n!=16 &&*/ psxRegs.interrupt & (1<<n) )
// SysPrintf( "***** IOP > Twice-thrown int on IRQ %d\n", n ); // Console::WriteLn( "***** IOP > Twice-thrown int on IRQ %d", n );
psxRegs.interrupt |= 1 << n; psxRegs.interrupt |= 1 << n;
@ -248,7 +248,7 @@ void psxBranchTest()
if ((psxRegs.CP0.n.Status & 0xFE01) >= 0x401) if ((psxRegs.CP0.n.Status & 0xFE01) >= 0x401)
{ {
PSXCPU_LOG("Interrupt: %x %x\n", psxHu32(0x1070), psxHu32(0x1074)); PSXCPU_LOG("Interrupt: %x %x", psxHu32(0x1070), psxHu32(0x1074));
psxException(0, 0); psxException(0, 0);
iopBranchAction = true; iopBranchAction = true;
} }
@ -278,6 +278,6 @@ void iopTestIntc()
void psxExecuteBios() { void psxExecuteBios() {
/* while (psxRegs.pc != 0x80030000) /* while (psxRegs.pc != 0x80030000)
psxCpu->ExecuteBlock(); psxCpu->ExecuteBlock();
PSX_LOG("*BIOS END*\n"); PSX_LOG("*BIOS END*");
*/ */
} }

View File

@ -127,13 +127,13 @@ extern s32 psxCycleEE; // tracks IOP's current sych status with the EE
#ifndef _PC_ #ifndef _PC_
#define _i32(x) (s32)x #define _i32(x) (s32)x
#define _u32(x) x #define _u32(x) (u32)x
#define _i16(x) (short)x #define _i16(x) (s16)x
#define _u16(x) (unsigned short)x #define _u16(x) (u16)x
#define _i8(x) (char)x #define _i8(x) (s8)x
#define _u8(x) (unsigned char)x #define _u8(x) (u8)x
/**** R3000A Instruction Macros ****/ /**** R3000A Instruction Macros ****/
#define _PC_ psxRegs.pc // The next PC to be executed #define _PC_ psxRegs.pc // The next PC to be executed
@ -143,7 +143,7 @@ extern s32 psxCycleEE; // tracks IOP's current sych status with the EE
#define _Rt_ ((psxRegs.code >> 16) & 0x1F) // The rt part of the instruction register #define _Rt_ ((psxRegs.code >> 16) & 0x1F) // The rt part of the instruction register
#define _Rs_ ((psxRegs.code >> 21) & 0x1F) // The rs part of the instruction register #define _Rs_ ((psxRegs.code >> 21) & 0x1F) // The rs part of the instruction register
#define _Sa_ ((psxRegs.code >> 6) & 0x1F) // The sa part of the instruction register #define _Sa_ ((psxRegs.code >> 6) & 0x1F) // The sa part of the instruction register
#define _Im_ ((unsigned short)psxRegs.code) // The immediate part of the instruction register #define _Im_ ((u16)psxRegs.code) // The immediate part of the instruction register
#define _Target_ (psxRegs.code & 0x03ffffff) // The target part of the instruction register #define _Target_ (psxRegs.code & 0x03ffffff) // The target part of the instruction register
#define _Imm_ ((short)psxRegs.code) // sign-extended immediate #define _Imm_ ((short)psxRegs.code) // sign-extended immediate

View File

@ -221,7 +221,7 @@ void zeroEx()
fname = irxlibs[i].names[code]; fname = irxlibs[i].names[code];
//if( strcmp(fname, "setIOPrcvaddr") == 0 ) { //if( strcmp(fname, "setIOPrcvaddr") == 0 ) {
// SysPrintf("yo\n"); // Console::WriteLn("yo");
// varLog |= 0x100000; // varLog |= 0x100000;
// Log = 1; // Log = 1;
// } // }
@ -291,7 +291,7 @@ void zeroEx()
pc = psxRegs.GPR.n.ra; pc = psxRegs.GPR.n.ra;
while (psxRegs.pc != pc) psxCpu->ExecuteBlock(); while (psxRegs.pc != pc) psxCpu->ExecuteBlock();
PSXBIOS_LOG("%s: %s (%x) END\n", lib, fname == NULL ? "unknown" : fname, code);*/ PSXBIOS_LOG("%s: %s (%x) END", lib, fname == NULL ? "unknown" : fname, code);*/
#endif #endif
} }
@ -305,7 +305,7 @@ char* getName(char *file, u32 addr){
name[0]=0; name[0]=0;
else{ else{
while (!feof(f)){ while (!feof(f)){
fscanf(f, "%08X %s\n", &a, name); fscanf(f, "%08X %s", &a, name);
if (a==addr)break; if (a==addr)break;
} }
fclose(f); fclose(f);
@ -324,13 +324,13 @@ void spyFunctions(){
if (strncmp("__push_params", name, 13)==0){ if (strncmp("__push_params", name, 13)==0){
PAD_LOG(PSXM(psxRegs.GPR.n.a0), psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); PAD_LOG(PSXM(psxRegs.GPR.n.a0), psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3);
}else{ }else{
PAD_LOG("secrman: %s (ra=%06X cycle=%d)\n", name, psxRegs.GPR.n.ra-iii->vaddr, psxRegs.cycle);}}else PAD_LOG("secrman: %s (ra=%06X cycle=%d)", name, psxRegs.GPR.n.ra-iii->vaddr, psxRegs.cycle);}}else
if (strcmp("mcman", PSXM(iii->name))==0){ if (strcmp("mcman", PSXM(iii->name))==0){
PAD_LOG("mcman: %s (ra=%06X cycle=%d)\n", getName("mcman.fun", psxRegs.pc-iii->vaddr), psxRegs.GPR.n.ra-iii->vaddr, psxRegs.cycle);}else PAD_LOG("mcman: %s (ra=%06X cycle=%d)", getName("mcman.fun", psxRegs.pc-iii->vaddr), psxRegs.GPR.n.ra-iii->vaddr, psxRegs.cycle);}else
if (strcmp("padman", PSXM(iii->name))==0){ if (strcmp("padman", PSXM(iii->name))==0){
PAD_LOG("padman: %s (ra=%06X cycle=%d)\n", getName("padman.fun", psxRegs.pc-iii->vaddr), psxRegs.GPR.n.ra-iii->vaddr, psxRegs.cycle);}else PAD_LOG("padman: %s (ra=%06X cycle=%d)", getName("padman.fun", psxRegs.pc-iii->vaddr), psxRegs.GPR.n.ra-iii->vaddr, psxRegs.cycle);}else
if (strcmp("sio2man", PSXM(iii->name))==0){ if (strcmp("sio2man", PSXM(iii->name))==0){
PAD_LOG("sio2man: %s (ra=%06X cycle=%d)\n", getName("sio2man.fun", psxRegs.pc-iii->vaddr), psxRegs.GPR.n.ra-iii->vaddr, psxRegs.cycle);} PAD_LOG("sio2man: %s (ra=%06X cycle=%d)", getName("sio2man.fun", psxRegs.pc-iii->vaddr), psxRegs.GPR.n.ra-iii->vaddr, psxRegs.cycle);}
break; break;
} }
} }
@ -381,7 +381,7 @@ static __forceinline void execI()
psxRegs.code = iopMemRead32(psxRegs.pc); psxRegs.code = iopMemRead32(psxRegs.pc);
//if( (psxRegs.pc >= 0x1200 && psxRegs.pc <= 0x1400) || (psxRegs.pc >= 0x0b40 && psxRegs.pc <= 0x1000)) //if( (psxRegs.pc >= 0x1200 && psxRegs.pc <= 0x1400) || (psxRegs.pc >= 0x0b40 && psxRegs.pc <= 0x1000))
PSXCPU_LOG("%s\n", disR3000AF(psxRegs.code, psxRegs.pc)); PSXCPU_LOG("%s", disR3000AF(psxRegs.code, psxRegs.pc));
psxRegs.pc+= 4; psxRegs.pc+= 4;
psxRegs.cycle++; psxRegs.cycle++;

View File

@ -159,7 +159,7 @@ void psxSYSCALL() {
} }
void psxRFE() { void psxRFE() {
// SysPrintf("RFE\n"); // Console::WriteLn("RFE\n");
psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) | psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) |
((psxRegs.CP0.n.Status & 0x3c) >> 2); ((psxRegs.CP0.n.Status & 0x3c) >> 2);
// Log=0; // Log=0;
@ -299,11 +299,11 @@ void psxMTC0() { _rFs_ = _u32(_rRt_); }
void psxCTC0() { _rFs_ = _u32(_rRt_); } void psxCTC0() { _rFs_ = _u32(_rRt_); }
/********************************************************* /*********************************************************
* Unknow instruction (would generate an exception) * * Unknown instruction (would generate an exception) *
* Format: ? * * Format: ? *
*********************************************************/ *********************************************************/
void psxNULL() { void psxNULL() {
SysPrintf("psx: Unimplemented op %x\n", psxRegs.code); Console::Notice("psx: Unimplemented op %x", params psxRegs.code);
} }
void psxSPECIAL() { void psxSPECIAL() {

View File

@ -91,7 +91,7 @@ void cpuReset()
hwReset(); hwReset();
vif0Reset(); vif0Reset();
vif1Reset(); vif1Reset();
rcntInit(); rcntInit();
psxReset(); psxReset();
} }
@ -106,82 +106,86 @@ void cpuShutdown()
disR5900FreeSyms(); disR5900FreeSyms();
} }
void cpuException(u32 code, u32 bd) __releaseinline void __fastcall cpuException(u32 code, u32 bd)
{ {
cpuRegs.branch = 0; // Tells the interpreter that an exception occurred during a branch. cpuRegs.branch = 0; // Tells the interpreter that an exception occurred during a branch.
bool errLevel2, checkStatus;
u32 offset; u32 offset;
cpuRegs.CP0.n.Cause = code & 0xffff; cpuRegs.CP0.n.Cause = code & 0xffff;
if(cpuRegs.CP0.n.Status.b.ERL == 0){ //Error Level 0-1 if(cpuRegs.CP0.n.Status.b.ERL == 0)
if(((code & 0x7C) >= 0x8) && ((code & 0x7C) <= 0xC)) offset = 0x0; //TLB Refill {
else if ((code & 0x7C) == 0x0) offset = 0x200; //Interrupt //Error Level 0-1
else offset = 0x180; // Everything else errLevel2 = FALSE;
checkStatus = (cpuRegs.CP0.n.Status.b.BEV == 0); // for TLB/general exceptions
if (((code & 0x7C) >= 0x8) && ((code & 0x7C) <= 0xC))
offset = 0x0; //TLB Refill
else if ((code & 0x7C) == 0x0)
offset = 0x200; //Interrupt
else
offset = 0x180; // Everything else
}
else
{
//Error Level 2
errLevel2 = TRUE;
checkStatus = (cpuRegs.CP0.n.Status.b.DEV == 0); // for perf/debug exceptions
if (cpuRegs.CP0.n.Status.b.EXL == 0) {
cpuRegs.CP0.n.Status.b.EXL = 1;
if (bd) {
Console::Notice("branch delay!!");
cpuRegs.CP0.n.EPC = cpuRegs.pc - 4;
cpuRegs.CP0.n.Cause |= 0x80000000;
} else {
cpuRegs.CP0.n.EPC = cpuRegs.pc;
cpuRegs.CP0.n.Cause &= ~0x80000000;
}
} else {
offset = 0x180; //Overrride the cause
//Console::Notice("cpuException: Status.EXL = 1 cause %x", params code);
}
if (cpuRegs.CP0.n.Status.b.BEV == 0) {
cpuRegs.pc = 0x80000000 + offset;
} else {
cpuRegs.pc = 0xBFC00200 + offset;
}
} else { //Error Level 2
Console::Error("*PCSX2* FIX ME: Level 2 cpuException"); Console::Error("*PCSX2* FIX ME: Level 2 cpuException");
if((code & 0x38000) <= 0x8000 ) { //Reset / NMI if ((code & 0x38000) <= 0x8000 )
{
//Reset / NMI
cpuRegs.pc = 0xBFC00000; cpuRegs.pc = 0xBFC00000;
Console::Notice("Reset request"); Console::Notice("Reset request");
UpdateCP0Status(); UpdateCP0Status();
return; return;
} else if((code & 0x38000) == 0x10000) offset = 0x80; //Performance Counter
else if((code & 0x38000) == 0x18000) offset = 0x100; //Debug
else Console::Error("Unknown Level 2 Exception!! Cause %x", params code);
if (cpuRegs.CP0.n.Status.b.EXL == 0) {
cpuRegs.CP0.n.Status.b.EXL = 1;
if (bd) {
Console::Notice("branch delay!!");
cpuRegs.CP0.n.EPC = cpuRegs.pc - 4;
cpuRegs.CP0.n.Cause |= 0x80000000;
} else {
cpuRegs.CP0.n.EPC = cpuRegs.pc;
cpuRegs.CP0.n.Cause &= ~0x80000000;
}
} else {
offset = 0x180; //Overrride the cause
Console::Notice("cpuException: Status.EXL = 1 cause %x", params code);
} }
else if((code & 0x38000) == 0x10000)
offset = 0x80; //Performance Counter
else if((code & 0x38000) == 0x18000)
offset = 0x100; //Debug
else
Console::Error("Unknown Level 2 Exception!! Cause %x", params code);
}
if (cpuRegs.CP0.n.Status.b.DEV == 0) { if (cpuRegs.CP0.n.Status.b.EXL == 0)
cpuRegs.pc = 0x80000000 + offset; {
} else { cpuRegs.CP0.n.Status.b.EXL = 1;
cpuRegs.pc = 0xBFC00200 + offset; if (bd)
{
Console::Notice("branch delay!!");
cpuRegs.CP0.n.EPC = cpuRegs.pc - 4;
cpuRegs.CP0.n.Cause |= 0x80000000;
}
else
{
cpuRegs.CP0.n.EPC = cpuRegs.pc;
cpuRegs.CP0.n.Cause &= ~0x80000000;
} }
} }
else
{
offset = 0x180; //Override the cause
if (errLevel2) Console::Notice("cpuException: Status.EXL = 1 cause %x", params code);
}
if (checkStatus)
cpuRegs.pc = 0x80000000 + offset;
else
cpuRegs.pc = 0xBFC00200 + offset;
UpdateCP0Status(); UpdateCP0Status();
} }
void cpuTlbMiss(u32 addr, u32 bd, u32 excode) { void cpuTlbMiss(u32 addr, u32 bd, u32 excode)
{
Console::Error("cpuTlbMiss pc:%x, cycl:%x, addr: %x, status=%x, code=%x", Console::Error("cpuTlbMiss pc:%x, cycl:%x, addr: %x, status=%x, code=%x",
params cpuRegs.pc, cpuRegs.cycle, addr, cpuRegs.CP0.n.Status.val, excode); params cpuRegs.pc, cpuRegs.cycle, addr, cpuRegs.CP0.n.Status.val, excode);
if (bd) { if (bd) Console::Notice("branch delay!!");
Console::Notice("branch delay!!");
}
assert(0); // temporary assert(0); // temporary
cpuRegs.CP0.n.BadVAddr = addr; cpuRegs.CP0.n.BadVAddr = addr;
cpuRegs.CP0.n.Context &= 0xFF80000F; cpuRegs.CP0.n.Context &= 0xFF80000F;
@ -212,55 +216,11 @@ void cpuTlbMissW(u32 addr, u32 bd) {
cpuTlbMiss(addr, bd, EXC_CODE_TLBS); cpuTlbMiss(addr, bd, EXC_CODE_TLBS);
} }
void JumpCheckSym(u32 addr, u32 pc) {
#if 0
// if (addr == 0x80051770) { SysPrintf("Log!: %s\n", PSM(cpuRegs.GPR.n.a0.UL[0])); Log=1; varLog|= 0x40000000; }
if (addr == 0x8002f150) { SysPrintf("printk: %s\n", PSM(cpuRegs.GPR.n.a0.UL[0])); }
if (addr == 0x8002aba0) return;
if (addr == 0x8002f450) return;
if (addr == 0x800dd520) return;
// if (addr == 0x80049300) SysPrintf("register_blkdev: %x\n", cpuRegs.GPR.n.a0.UL[0]);
if (addr == 0x8013cb70) { SysPrintf("change_root: %x\n", cpuRegs.GPR.n.a0.UL[0]); }
// if (addr == 0x8013d1e8) { SysPrintf("Log!\n"); Log++; if (Log==2) exit(0); varLog|= 0x40000000; }
// if (addr == 0x00234e88) { SysPrintf("StoreImage\n"); Log=1; /*psMu32(0x234e88) = 0x03e00008; psMu32(0x234e8c) = 0;*/ }
#endif
/* if ((pc >= 0x00131D50 &&
pc < 0x00132454) ||
(pc >= 0x00786a90 &&
pc < 0x00786ac8))*/
/*if (varLog & 0x40000000) {
char *str;
char *strf;
str = disR5900GetSym(addr);
if (str != NULL) {
strf = disR5900GetUpperSym(pc);
if (strf) {
SysPrintf("Func %8.8x: %s (called by %8.8x: %s)\n", addr, str, pc, strf);
} else {
SysPrintf("Func %8.8x: %s (called by %x)\n", addr, str, pc);
}
if (!strcmp(str, "printf")) { SysPrintf("%s\n", (char*)PSM(cpuRegs.GPR.n.a0.UL[0])); }
if (!strcmp(str, "printk")) { SysPrintf("%s\n", (char*)PSM(cpuRegs.GPR.n.a0.UL[0])); }
}
}*/
}
void JumpCheckSymRet(u32 addr) {
/*if (varLog & 0x40000000) {
char *str;
str = disR5900GetUpperSym(addr);
if (str != NULL) {
SysPrintf("Return : %s, v0=%8.8x\n", str, cpuRegs.GPR.n.v0.UL[0]);
}
}*/
}
__forceinline void _cpuTestMissingINTC() { __forceinline void _cpuTestMissingINTC() {
if (cpuRegs.CP0.n.Status.val & 0x400 && if (cpuRegs.CP0.n.Status.val & 0x400 &&
psHu32(INTC_STAT) & psHu32(INTC_MASK)) { psHu32(INTC_STAT) & psHu32(INTC_MASK)) {
if ((cpuRegs.interrupt & (1 << 30)) == 0) { if ((cpuRegs.interrupt & (1 << 30)) == 0) {
SysPrintf("*PCSX2*: Error, missing INTC Interrupt\n"); Console::Error("*PCSX2*: Error, missing INTC Interrupt");
} }
} }
} }
@ -270,7 +230,7 @@ __forceinline void _cpuTestMissingDMAC() {
(psHu16(0xe012) & psHu16(0xe010) || (psHu16(0xe012) & psHu16(0xe010) ||
psHu16(0xe010) & 0x8000)) { psHu16(0xe010) & 0x8000)) {
if ((cpuRegs.interrupt & (1 << 31)) == 0) { if ((cpuRegs.interrupt & (1 << 31)) == 0) {
SysPrintf("*PCSX2*: Error, missing DMAC Interrupt\n"); Console::Error("*PCSX2*: Error, missing DMAC Interrupt");
} }
} }
} }
@ -284,7 +244,7 @@ void cpuTestMissingHwInts() {
} }
// sets a branch test to occur some time from an arbitrary starting point. // sets a branch test to occur some time from an arbitrary starting point.
__forceinline int cpuSetNextBranch( u32 startCycle, s32 delta ) __forceinline int __fastcall cpuSetNextBranch( u32 startCycle, s32 delta )
{ {
// typecast the conditional to signed so that things don't blow up // typecast the conditional to signed so that things don't blow up
// if startCycle is greater than our next branch cycle. // if startCycle is greater than our next branch cycle.
@ -298,14 +258,14 @@ __forceinline int cpuSetNextBranch( u32 startCycle, s32 delta )
} }
// sets a branch to occur some time from the current cycle // sets a branch to occur some time from the current cycle
__forceinline int cpuSetNextBranchDelta( s32 delta ) __forceinline int __fastcall cpuSetNextBranchDelta( s32 delta )
{ {
return cpuSetNextBranch( cpuRegs.cycle, delta ); return cpuSetNextBranch( cpuRegs.cycle, delta );
} }
// tests the cpu cycle agaisnt the given start and delta values. // tests the cpu cycle agaisnt the given start and delta values.
// Returns true if the delta time has passed. // Returns true if the delta time has passed.
__forceinline int cpuTestCycle( u32 startCycle, s32 delta ) __forceinline int __fastcall cpuTestCycle( u32 startCycle, s32 delta )
{ {
// typecast the conditional to signed so that things don't explode // typecast the conditional to signed so that things don't explode
// if the startCycle is ahead of our current cpu cycle. // if the startCycle is ahead of our current cpu cycle.
@ -544,7 +504,7 @@ __forceinline bool _cpuBranchTest_Shared()
return vsyncEvent; return vsyncEvent;
} }
void cpuTestINTCInts() __releaseinline void cpuTestINTCInts()
{ {
if( cpuRegs.interrupt & (1 << 30) ) return; if( cpuRegs.interrupt & (1 << 30) ) return;
//if( (cpuRegs.CP0.n.Status.val & 0x10407) != 0x10401 ) return; //if( (cpuRegs.CP0.n.Status.val & 0x10407) != 0x10401 ) return;
@ -596,7 +556,7 @@ __forceinline void cpuTestTIMRInts() {
} }
} }
void cpuTestHwInts() { __forceinline void cpuTestHwInts() {
cpuTestINTCInts(); cpuTestINTCInts();
cpuTestDMACInts(); cpuTestDMACInts();
cpuTestTIMRInts(); cpuTestTIMRInts();

View File

@ -219,9 +219,6 @@ struct tlbs
#endif #endif
void JumpCheckSym(u32 addr, u32 pc);
void JumpCheckSymRet(u32 addr);
PCSX2_ALIGNED16_EXTERN(cpuRegisters cpuRegs); PCSX2_ALIGNED16_EXTERN(cpuRegisters cpuRegs);
PCSX2_ALIGNED16_EXTERN(fpuRegisters fpuRegs); PCSX2_ALIGNED16_EXTERN(fpuRegisters fpuRegs);
PCSX2_ALIGNED16_EXTERN(tlbs tlb[48]); PCSX2_ALIGNED16_EXTERN(tlbs tlb[48]);
@ -260,14 +257,14 @@ extern void cpuInit();
extern void cpuReset(); // can throw Exception::FileNotFound. extern void cpuReset(); // can throw Exception::FileNotFound.
extern void cpuShutdown(); extern void cpuShutdown();
extern void cpuExecuteBios(); extern void cpuExecuteBios();
extern void cpuException(u32 code, u32 bd); extern void __fastcall cpuException(u32 code, u32 bd);
extern void cpuTlbMissR(u32 addr, u32 bd); extern void cpuTlbMissR(u32 addr, u32 bd);
extern void cpuTlbMissW(u32 addr, u32 bd); extern void cpuTlbMissW(u32 addr, u32 bd);
extern void cpuTestHwInts(); extern void cpuTestHwInts();
extern int cpuSetNextBranch( u32 startCycle, s32 delta ); extern int __fastcall cpuSetNextBranch( u32 startCycle, s32 delta );
extern int cpuSetNextBranchDelta( s32 delta ); extern int __fastcall cpuSetNextBranchDelta( s32 delta );
extern int cpuTestCycle( u32 startCycle, s32 delta ); extern int __fastcall cpuTestCycle( u32 startCycle, s32 delta );
extern void cpuSetBranch(); extern void cpuSetBranch();
extern bool _cpuBranchTest_Shared(); // for internal use by the Dynarecs and Ints inside R5900: extern bool _cpuBranchTest_Shared(); // for internal use by the Dynarecs and Ints inside R5900:

View File

@ -130,12 +130,12 @@ void COP2()
//std::string disOut; //std::string disOut;
//disR5900Fasm(disOut, cpuRegs.code, cpuRegs.pc); //disR5900Fasm(disOut, cpuRegs.code, cpuRegs.pc);
//VU0_LOG("%s\n", disOut.c_str()); //VU0_LOG("%s", disOut.c_str());
Int_COP2PrintTable[_Rs_](); Int_COP2PrintTable[_Rs_]();
} }
void Unknown() { void Unknown() {
CPU_LOG("%8.8lx: Unknown opcode called\n", cpuRegs.pc); CPU_LOG("%8.8lx: Unknown opcode called", cpuRegs.pc);
} }
void MMI_Unknown() { Console::Notice("Unknown MMI opcode called"); } void MMI_Unknown() { Console::Notice("Unknown MMI opcode called"); }
@ -247,14 +247,29 @@ void SLTU() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (cpuRegs.GPR.r[_Rs
* Format: OP rs, rt * * Format: OP rs, rt *
*********************************************************/ *********************************************************/
// Signed division "overflows" on (0x80000000 / -1), here (LO = 0x80000000, HI = 0) is returned by MIPS
// in division by zero on MIPS, it appears that:
// LO gets 1 if rs is negative (and the division is signed) and -1 otherwise.
// HI gets the value of rs.
// Result is stored in HI/LO [no arithmetic exceptions] // Result is stored in HI/LO [no arithmetic exceptions]
void DIV() void DIV()
{ {
if (cpuRegs.GPR.r[_Rt_].SL[0] != 0) if (cpuRegs.GPR.r[_Rs_].UL[0] == 0x80000000 && cpuRegs.GPR.r[_Rt_].UL[0] == 0xffffffff)
{
cpuRegs.LO.SD[0] = (s32)0x80000000;
cpuRegs.HI.SD[0] = (s32)0x0;
}
else if (cpuRegs.GPR.r[_Rt_].SL[0] != 0)
{ {
cpuRegs.LO.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0] / cpuRegs.GPR.r[_Rt_].SL[0]; cpuRegs.LO.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0] / cpuRegs.GPR.r[_Rt_].SL[0];
cpuRegs.HI.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0] % cpuRegs.GPR.r[_Rt_].SL[0]; cpuRegs.HI.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0] % cpuRegs.GPR.r[_Rt_].SL[0];
} }
else
{
cpuRegs.LO.SD[0] = (cpuRegs.GPR.r[_Rs_].SL[0] < 0) ? 1 : -1;
cpuRegs.HI.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0];
}
} }
// Result is stored in HI/LO [no arithmetic exceptions] // Result is stored in HI/LO [no arithmetic exceptions]
@ -267,6 +282,11 @@ void DIVU()
cpuRegs.LO.SD[0] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] / cpuRegs.GPR.r[_Rt_].UL[0]); cpuRegs.LO.SD[0] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] / cpuRegs.GPR.r[_Rt_].UL[0]);
cpuRegs.HI.SD[0] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] % cpuRegs.GPR.r[_Rt_].UL[0]); cpuRegs.HI.SD[0] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] % cpuRegs.GPR.r[_Rt_].UL[0]);
} }
else
{
cpuRegs.LO.SD[0] = -1;
cpuRegs.HI.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0];
}
} }
// Result is written to both HI/LO and to the _Rd_ (Lo only) // Result is written to both HI/LO and to the _Rd_ (Lo only)
@ -738,7 +758,7 @@ int __Deci2Call(int call, u32 *addr)
if( addr != NULL ) if( addr != NULL )
{ {
deci2addr = (u32*)PSM(addr[1]); deci2addr = (u32*)PSM(addr[1]);
BIOS_LOG("deci2open: %x,%x,%x,%x\n", BIOS_LOG("deci2open: %x,%x,%x,%x",
addr[3], addr[2], addr[1], addr[0]); addr[3], addr[2], addr[1], addr[0]);
deci2handler = addr[2]; deci2handler = addr[2];
} }
@ -758,13 +778,13 @@ int __Deci2Call(int call, u32 *addr)
if( addr != NULL ) if( addr != NULL )
sprintf( reqaddr, "%x %x %x %x", addr[3], addr[2], addr[1], addr[0] ); sprintf( reqaddr, "%x %x %x %x", addr[3], addr[2], addr[1], addr[0] );
BIOS_LOG("deci2reqsend: %s: deci2addr: %x,%x,%x,buf=%x %x,%x,len=%x,%x\n", BIOS_LOG("deci2reqsend: %s: deci2addr: %x,%x,%x,buf=%x %x,%x,len=%x,%x",
(( addr == NULL ) ? "NULL" : reqaddr), (( addr == NULL ) ? "NULL" : reqaddr),
deci2addr[7], deci2addr[6], deci2addr[5], deci2addr[4], deci2addr[7], deci2addr[6], deci2addr[5], deci2addr[4],
deci2addr[3], deci2addr[2], deci2addr[1], deci2addr[0]); deci2addr[3], deci2addr[2], deci2addr[1], deci2addr[0]);
// cpuRegs.pc = deci2handler; // cpuRegs.pc = deci2handler;
// SysPrintf("deci2msg: %s", (char*)PSM(deci2addr[4]+0xc)); // Console::WriteLn("deci2msg: %s", params (char*)PSM(deci2addr[4]+0xc));
if (deci2addr == NULL) return 1; if (deci2addr == NULL) return 1;
if (deci2addr[1]>0xc){ if (deci2addr[1]>0xc){
u8* pdeciaddr = (u8*)dmaGetAddr(deci2addr[4]+0xc); u8* pdeciaddr = (u8*)dmaGetAddr(deci2addr[4]+0xc);
@ -810,7 +830,7 @@ void SYSCALL()
else else
call = cpuRegs.GPR.n.v1.UC[0]; call = cpuRegs.GPR.n.v1.UC[0];
BIOS_LOG("Bios call: %s (%x)\n", bios[call], call); BIOS_LOG("Bios call: %s (%x)", bios[call], call);
if (call == 0x7c) if (call == 0x7c)
{ {
@ -836,7 +856,7 @@ void SYSCALL()
addr = cpuRegs.GPR.n.a0.UL[0] + n_transfer * sizeof(t_sif_dma_transfer); addr = cpuRegs.GPR.n.a0.UL[0] + n_transfer * sizeof(t_sif_dma_transfer);
dmat = (t_sif_dma_transfer*)PSM(addr); dmat = (t_sif_dma_transfer*)PSM(addr);
BIOS_LOG("bios_%s: n_transfer=%d, size=%x, attr=%x, dest=%x, src=%x\n", BIOS_LOG("bios_%s: n_transfer=%d, size=%x, attr=%x, dest=%x, src=%x",
bios[cpuRegs.GPR.n.v1.UC[0]], n_transfer, bios[cpuRegs.GPR.n.v1.UC[0]], n_transfer,
dmat->size, dmat->attr, dmat->size, dmat->attr,
dmat->dest, dmat->src); dmat->dest, dmat->src);
@ -858,7 +878,7 @@ void MFSA( void ) {
} }
void MTSA( void ) { void MTSA( void ) {
cpuRegs.sa = (s32)cpuRegs.GPR.r[_Rs_].SD[0]; cpuRegs.sa = (s32)cpuRegs.GPR.r[_Rs_].SD[0] & 0xf;
} }
// SNY supports three basic modes, two which synchronize memory accesses (related // SNY supports three basic modes, two which synchronize memory accesses (related
@ -907,11 +927,11 @@ void TLTIU() { if (cpuRegs.GPR.r[_Rs_].UD[0] < (u64)_Imm_) throw R5900Exception
*********************************************************/ *********************************************************/
void MTSAB() { void MTSAB() {
cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF)) << 3; cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF));
} }
void MTSAH() { void MTSAH() {
cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 4; cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 1;
} }
} } } // end namespace R5900::Interpreter::OpcodeImpl } } } // end namespace R5900::Interpreter::OpcodeImpl

View File

@ -25,63 +25,58 @@
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000]) #define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
#define spr1 ((DMACh*)&PS2MEM_HW[0xD400]) #define spr1 ((DMACh*)&PS2MEM_HW[0xD400])
#define gif ((DMACh*)&PS2MEM_HW[0xA000])
extern void mfifoGIFtransfer(int);
/* Both of these should be bools. Again, next savestate break. --arcum42 */
static int spr0finished = 0; static int spr0finished = 0;
static int spr1finished = 0; static int spr1finished = 0;
static u32 mfifotransferred = 0; static u32 mfifotransferred = 0;
void sprInit() { void sprInit()
{
} }
//__forceinline static void SPR0transfer(u32 *data, int size) {
///* while (size > 0) {
// SPR_LOG("SPR1transfer: %x\n", *data);
// data++; size--;
// }*/
// size <<= 2;
// if ((psHu32(DMAC_CTRL) & 0xC) == 0xC || // GIF MFIFO
// (psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO
// hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], size);
// } else {
// u32 * p = (u32*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff];
// //WriteCodeSSE2(p,data,size >> 4);
// memcpy_fast((u8*)data, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], size);
// }
// spr0->sadr+= size;
//}
static void TestClearVUs(u32 madr, u32 size) static void TestClearVUs(u32 madr, u32 size)
{ {
if( madr >= 0x11000000 ) { if (madr >= 0x11000000)
if( madr < 0x11004000 ) { {
DbgCon::Notice("scratch pad clearing vu0\n"); if (madr < 0x11004000)
{
DbgCon::Notice("scratch pad clearing vu0");
CpuVU0.Clear(madr&0xfff, size); CpuVU0.Clear(madr&0xfff, size);
} }
else if( madr >= 0x11008000 && madr < 0x1100c000 ) { else if (madr >= 0x11008000 && madr < 0x1100c000)
DbgCon::Notice("scratch pad clearing vu1\n"); {
DbgCon::Notice("scratch pad clearing vu1");
CpuVU1.Clear(madr&0x3fff, size); CpuVU1.Clear(madr&0x3fff, size);
} }
} }
} }
int _SPR0chain() { int _SPR0chain()
{
u32 *pMem; u32 *pMem;
if (spr0->qwc == 0) return 0; if (spr0->qwc == 0) return 0;
pMem = (u32*)dmaGetAddr(spr0->madr); pMem = (u32*)dmaGetAddr(spr0->madr);
if (pMem == NULL) return -1; if (pMem == NULL) return -1;
//SPR0transfer(pMem, qwc << 2); if ((psHu32(DMAC_CTRL) & 0xC) >= 0x8) // 0x8 VIF1 MFIFO, 0xC GIF MFIFO
{
if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("SPR MFIFO Write outside MFIFO area");
if ((psHu32(DMAC_CTRL) & 0xC) >= 0x8) { // 0x8 VIF1 MFIFO, 0xC GIF MFIFO
if((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) SysPrintf("SPR MFIFO Write outside MFIFO area\n");
hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
spr0->madr += spr0->qwc << 4; spr0->madr += spr0->qwc << 4;
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR)); spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
mfifotransferred += spr0->qwc; mfifotransferred += spr0->qwc;
} else { }
else
{
memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
//Cpu->Clear(spr0->madr, spr0->qwc<<2);
// clear VU mem also! // clear VU mem also!
TestClearVUs(spr0->madr, spr0->qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes) TestClearVUs(spr0->madr, spr0->qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes)
@ -90,7 +85,7 @@ int _SPR0chain() {
spr0->sadr += spr0->qwc << 4; spr0->sadr += spr0->qwc << 4;
return (spr0->qwc) * BIAS; // bus is 1/2 the ee speed return (spr0->qwc) * BIAS; // bus is 1/2 the ee speed
} }
#define SPR0chain() \ #define SPR0chain() \
@ -98,97 +93,98 @@ int _SPR0chain() {
spr0->qwc = 0; spr0->qwc = 0;
void _SPR0interleave() { void _SPR0interleave()
{
int qwc = spr0->qwc; int qwc = spr0->qwc;
int sqwc = psHu32(DMAC_SQWC) & 0xff; int sqwc = psHu32(DMAC_SQWC) & 0xff;
int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff; int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff;
int cycles = 0; int cycles = 0;
u32 *pMem; u32 *pMem;
if(tqwc == 0) tqwc = qwc;
//SysPrintf("dmaSPR0 interleave\n");
SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx\n",
spr0->qwc, tqwc, sqwc, spr0->madr, spr0->sadr);
while (qwc > 0) { if (tqwc == 0) tqwc = qwc;
spr0->qwc = std::min(tqwc, qwc); qwc-= spr0->qwc; //Console::WriteLn("dmaSPR0 interleave");
SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
spr0->qwc, tqwc, sqwc, spr0->madr, spr0->sadr);
while (qwc > 0)
{
spr0->qwc = std::min(tqwc, qwc);
qwc -= spr0->qwc;
pMem = (u32*)dmaGetAddr(spr0->madr); pMem = (u32*)dmaGetAddr(spr0->madr);
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC || // GIF MFIFO if ((psHu32(DMAC_CTRL) & 0xC) == 0xC || // GIF MFIFO
(psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO (psHu32(DMAC_CTRL) & 0xC) == 0x8) // VIF1 MFIFO
hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc<<4); {
hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
mfifotransferred += spr0->qwc; mfifotransferred += spr0->qwc;
} else { }
//Cpu->Clear(spr0->madr, spr0->qwc<<2); else
{
// clear VU mem also! // clear VU mem also!
TestClearVUs(spr0->madr, spr0->qwc<<2); TestClearVUs(spr0->madr, spr0->qwc << 2);
memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc<<4); memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
} }
cycles += tqwc * BIAS; cycles += tqwc * BIAS;
spr0->sadr+= spr0->qwc * 16; spr0->sadr += spr0->qwc * 16;
spr0->madr+= (sqwc+spr0->qwc)*16; //qwc-= sqwc; spr0->madr += (sqwc + spr0->qwc) * 16; //qwc-= sqwc;
} }
spr0->qwc = 0; spr0->qwc = 0;
spr0finished = 1; spr0finished = 1;
//CPU_INT(8, cycles);
} }
static __forceinline void _dmaSPR0() { static __forceinline void _dmaSPR0()
{
if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) // STS == fromSPR
if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) { // STS == fromSPR {
SysPrintf("SPR0 stall %d\n", (psHu32(DMAC_CTRL)>>6)&3); Console::WriteLn("SPR0 stall %d", params(psHu32(DMAC_CTRL) >> 6)&3);
} }
// Transfer Dn_QWC from SPR to Dn_MADR // Transfer Dn_QWC from SPR to Dn_MADR
if ((spr0->chcr & 0xc) == 0x0) // Normal Mode
{
if ((spr0->chcr & 0xc) == 0x0) { // Normal Mode
int cycles = 0; int cycles = 0;
SPR0chain(); SPR0chain();
//CPU_INT(8, cycles);
spr0finished = 1; spr0finished = 1;
return; return;
} else if ((spr0->chcr & 0xc) == 0x4) { }
int cycles = 0; else if ((spr0->chcr & 0xc) == 0x4)
u32 *ptag; {
int id; int cycles = 0;
int done = 0; u32 *ptag;
int id;
int done = 0;
if(spr0->qwc > 0){ if (spr0->qwc > 0)
SPR0chain(); {
//CPU_INT(8, cycles); SPR0chain();
spr0finished = 1; spr0finished = 1;
return; return;
} }
// Destination Chain Mode // Destination Chain Mode
ptag = (u32*) & PS2MEM_SCRATCH[spr0->sadr & 0x3fff];
//while (done == 0) { // Loop while Dn_CHCR.STR is 1 spr0->sadr += 16;
ptag = (u32*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff];
spr0->sadr+= 16;
// Transfer dma tag if tte is set // Transfer dma tag if tte is set
// if (spr0->chcr & 0x40) SPR0transfer(ptag, 4);
spr0->chcr = ( spr0->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 spr0->chcr = (spr0->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
spr0->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag spr0->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
spr0->madr = ptag[1]; //MADR = ADDR field spr0->madr = ptag[1]; //MADR = ADDR field
SPR_LOG("spr0 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx\n", SPR_LOG("spr0 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
ptag[1], ptag[0], spr0->qwc, id, spr0->madr, spr0->sadr); ptag[1], ptag[0], spr0->qwc, id, spr0->madr, spr0->sadr);
if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) { // STS == fromSPR if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) // STS == fromSPR
SysPrintf("SPR stall control\n"); {
Console::WriteLn("SPR stall control");
} }
switch (id) { switch (id)
{
case 0: // CNTS - Transfer QWC following the tag (Stall Control) case 0: // CNTS - Transfer QWC following the tag (Stall Control)
if ((psHu32(DMAC_CTRL) & 0x30) == 0x20 ) psHu32(DMAC_STADR) = spr0->madr + (spr0->qwc * 16); //Copy MADR to DMAC_STADR stall addr register if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) psHu32(DMAC_STADR) = spr0->madr + (spr0->qwc * 16); //Copy MADR to DMAC_STADR stall addr register
break; break;
case 1: // CNT - Transfer QWC following the tag. case 1: // CNT - Transfer QWC following the tag.
@ -200,34 +196,27 @@ static __forceinline void _dmaSPR0() {
break; break;
} }
SPR0chain(); SPR0chain();
if (spr0->chcr & 0x80 && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag if (spr0->chcr & 0x80 && ptag[0] >> 31) //Check TIE bit of CHCR and IRQ bit of tag
//SysPrintf("SPR0 TIE\n"); {
//Console::WriteLn("SPR0 TIE");
done = 1; done = 1;
spr0->qwc = 0; spr0->qwc = 0;
//break;
} }
/* if (spr0->chcr & 0x80 && ptag[0] >> 31) {
SPR_LOG("dmaIrq Set\n");
spr0->chcr&= ~0x100;
hwDmacIrq(8);
return;
}*/
//}
spr0finished = done; spr0finished = done;
if(done == 0) { if (done == 0)
ptag = (u32*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; //Set memory pointer to SADR {
ptag = (u32*) & PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; //Set memory pointer to SADR
spr0->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag spr0->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
CPU_INT(8, spr0->qwc / BIAS); CPU_INT(8, spr0->qwc / BIAS);
spr0->qwc = 0; spr0->qwc = 0;
return; return;
} }
SPR_LOG("spr0 dmaChain complete %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx\n", SPR_LOG("spr0 dmaChain complete %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
ptag[1], ptag[0], spr0->qwc, id, spr0->madr); ptag[1], ptag[0], spr0->qwc, id, spr0->madr);
//CPU_INT(8, cycles); }
} else { // Interleave Mode else // Interleave Mode
{
_SPR0interleave(); _SPR0interleave();
} }
@ -235,72 +224,62 @@ static __forceinline void _dmaSPR0() {
} }
extern void mfifoGIFtransfer(int);
#define gif ((DMACh*)&PS2MEM_HW[0xA000])
void SPRFROMinterrupt() void SPRFROMinterrupt()
{ {
//int qwc = spr0->qwc;
_dmaSPR0(); _dmaSPR0();
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC) { // GIF MFIFO if ((psHu32(DMAC_CTRL) & 0xC) == 0xC) // GIF MFIFO
if((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) SysPrintf("GIF MFIFO Write outside MFIFO area\n"); {
if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("GIF MFIFO Write outside MFIFO area");
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR)); spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
//SysPrintf("mfifoGIFtransfer %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr); //Console::WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", params gif->chcr, gif->madr, gif->tadr);
mfifoGIFtransfer(mfifotransferred); mfifoGIFtransfer(mfifotransferred);
mfifotransferred = 0; mfifotransferred = 0;
} else
if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO
if((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) SysPrintf("VIF MFIFO Write outside MFIFO area\n");
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
//SysPrintf("mfifoVIF1transfer %x madr %x, tadr %x\n", vif1ch->chcr, vif1ch->madr, vif1ch->tadr);
//vifqwc+= qwc;
mfifoVIF1transfer(mfifotransferred);
mfifotransferred = 0;
} }
if(spr0finished == 0) return; else
spr0->chcr&= ~0x100; if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) // VIF1 MFIFO
{
if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("VIF MFIFO Write outside MFIFO area");
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
//Console::WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", params vif1ch->chcr, vif1ch->madr, vif1ch->tadr);
mfifoVIF1transfer(mfifotransferred);
mfifotransferred = 0;
}
if (spr0finished == 0) return;
spr0->chcr &= ~0x100;
hwDmacIrq(8); hwDmacIrq(8);
} }
void dmaSPR0() { // fromSPR void dmaSPR0() // fromSPR
{
SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx\n", SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx",
spr0->chcr, spr0->madr, spr0->qwc, spr0->sadr); spr0->chcr, spr0->madr, spr0->qwc, spr0->sadr);
if ((spr0->chcr & 0xc) == 0x4 && spr0->qwc == 0){ if ((spr0->chcr & 0xc) == 0x4 && spr0->qwc == 0)
u32 *ptag; {
ptag = (u32*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; //Set memory pointer to SADR u32 *ptag;
CPU_INT(8, (ptag[0] & 0xffff) / BIAS); ptag = (u32*) & PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; //Set memory pointer to SADR
// spr0->qwc = 0; CPU_INT(8, (ptag[0] & 0xffff) / BIAS);
return; return;
} }
// COMPLETE HACK!!! For now at least.. FFX Videos dont rely on interrupts or reading DMA values // COMPLETE HACK!!! For now at least.. FFX Videos dont rely on interrupts or reading DMA values
// It merely assumes that the last one has finished then starts another one (broke with the DMA fix) // It merely assumes that the last one has finished then starts another one (broke with the DMA fix)
// This "shouldn't" cause any problems as SPR is generally faster than the other DMAS anyway. (Refraction) // This "shouldn't" cause any problems as SPR is generally faster than the other DMAS anyway. (Refraction)
CPU_INT(8, spr0->qwc / BIAS); CPU_INT(8, spr0->qwc / BIAS);
} }
__forceinline static void SPR1transfer(u32 *data, int size) { __forceinline static void SPR1transfer(u32 *data, int size)
/* { {
int i;
for (i=0; i<size; i++) {
SPR_LOG( "SPR1transfer[0x%x]: 0x%x\n", (spr1->sadr+i*4) & 0x3fff, data[i] );
}
}*/
//Cpu->Clear(spr1->sadr, size); // why?
memcpy_fast(&PS2MEM_SCRATCH[spr1->sadr & 0x3fff], (u8*)data, size << 2); memcpy_fast(&PS2MEM_SCRATCH[spr1->sadr & 0x3fff], (u8*)data, size << 2);
spr1->sadr+= size << 2; spr1->sadr += size << 2;
} }
int _SPR1chain() { int _SPR1chain()
{
u32 *pMem; u32 *pMem;
if (spr1->qwc == 0) return 0; if (spr1->qwc == 0) return 0;
@ -309,7 +288,7 @@ int _SPR1chain() {
if (pMem == NULL) return -1; if (pMem == NULL) return -1;
SPR1transfer(pMem, spr1->qwc << 2); SPR1transfer(pMem, spr1->qwc << 2);
spr1->madr+= spr1->qwc << 4; spr1->madr += spr1->qwc << 4;
return (spr1->qwc) * BIAS; return (spr1->qwc) * BIAS;
} }
@ -319,142 +298,144 @@ int _SPR1chain() {
spr1->qwc = 0; spr1->qwc = 0;
void _SPR1interleave() { void _SPR1interleave()
{
int qwc = spr1->qwc; int qwc = spr1->qwc;
int sqwc = psHu32(DMAC_SQWC) & 0xff; int sqwc = psHu32(DMAC_SQWC) & 0xff;
int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff; int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff;
int cycles = 0; int cycles = 0;
u32 *pMem; u32 *pMem;
if(tqwc == 0) tqwc = qwc;
SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx\n",
spr1->qwc, tqwc, sqwc, spr1->madr, spr1->sadr);
while (qwc > 0) { if (tqwc == 0) tqwc = qwc;
spr1->qwc = std::min(tqwc, qwc); qwc-= spr1->qwc; SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
spr1->qwc, tqwc, sqwc, spr1->madr, spr1->sadr);
while (qwc > 0)
{
spr1->qwc = std::min(tqwc, qwc);
qwc -= spr1->qwc;
pMem = (u32*)dmaGetAddr(spr1->madr); pMem = (u32*)dmaGetAddr(spr1->madr);
memcpy_fast(&PS2MEM_SCRATCH[spr1->sadr & 0x3fff], (u8*)pMem, spr1->qwc <<4); memcpy_fast(&PS2MEM_SCRATCH[spr1->sadr & 0x3fff], (u8*)pMem, spr1->qwc << 4);
spr1->sadr += spr1->qwc * 16; spr1->sadr += spr1->qwc * 16;
cycles += spr1->qwc * BIAS; cycles += spr1->qwc * BIAS;
spr1->madr+= (sqwc + spr1->qwc) * 16; //qwc-= sqwc; spr1->madr += (sqwc + spr1->qwc) * 16; //qwc-= sqwc;
} }
spr1->qwc = 0; spr1->qwc = 0;
spr1finished = 1; spr1finished = 1;
//CPU_INT(9, cycles);
} }
void _dmaSPR1() { // toSPR work function void _dmaSPR1() // toSPR work function
if ((spr1->chcr & 0xc) == 0) { // Normal Mode {
if ((spr1->chcr & 0xc) == 0) // Normal Mode
{
int cycles = 0; int cycles = 0;
//if(spr1->qwc == 0 && (spr1->chcr & 0xc) == 1) spr1->qwc = 0xffff;
// Transfer Dn_QWC from Dn_MADR to SPR1 // Transfer Dn_QWC from Dn_MADR to SPR1
SPR1chain(); SPR1chain();
spr1finished = 1; spr1finished = 1;
//CPU_INT(9, cycles);
return; return;
} else }
if ((spr1->chcr & 0xc) == 0x4){ else if ((spr1->chcr & 0xc) == 0x4)
int cycles = 0; {
u32 *ptag; int cycles = 0;
int id, done=0; u32 *ptag;
int id, done = 0;
if (spr1->qwc > 0)
if(spr1->qwc > 0){ {
//if(spr1->qwc == 0 && (spr1->chcr & 0xc) == 1) spr1->qwc = 0xffff;
// Transfer Dn_QWC from Dn_MADR to SPR1 // Transfer Dn_QWC from Dn_MADR to SPR1
SPR1chain(); SPR1chain();
spr1finished = 1; spr1finished = 1;
//CPU_INT(9, cycles);
return; return;
} }
// Chain Mode // Chain Mode
// while (done == 0) { // Loop while Dn_CHCR.STR is 1
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
if (ptag == NULL) { //Is ptag empty? if (ptag == NULL) //Is ptag empty?
SysPrintf("SPR1 Tag BUSERR\n"); {
spr1->chcr = ( spr1->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 Console::WriteLn("SPR1 Tag BUSERR");
psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register spr1->chcr = (spr1->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
psHu32(DMAC_STAT) |= 1 << 15; //If yes, set BEIS (BUSERR) in DMAC_STAT register
done = 1; done = 1;
spr1finished = done; spr1finished = done;
return; return;
} }
spr1->chcr = ( spr1->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 spr1->chcr = (spr1->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
spr1->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag spr1->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
spr1->madr = ptag[1]; //MADR = ADDR field spr1->madr = ptag[1]; //MADR = ADDR field
// Transfer dma tag if tte is set // Transfer dma tag if tte is set
if (spr1->chcr & 0x40) { if (spr1->chcr & 0x40)
{
SPR_LOG("SPR TTE: %x_%x\n", ptag[3], ptag[2]); SPR_LOG("SPR TTE: %x_%x\n", ptag[3], ptag[2]);
SPR1transfer(ptag, 4); //Transfer Tag SPR1transfer(ptag, 4); //Transfer Tag
} }
SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx\n", SPR_LOG("spr1 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx",
ptag[1], ptag[0], spr1->qwc, id, spr1->madr); ptag[1], ptag[0], spr1->qwc, id, spr1->madr);
done = hwDmacSrcChain(spr1, id); done = hwDmacSrcChain(spr1, id);
SPR1chain(); //Transfers the data set by the switch SPR1chain(); //Transfers the data set by the switch
if (spr1->chcr & 0x80 && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag if (spr1->chcr & 0x80 && ptag[0] >> 31) //Check TIE bit of CHCR and IRQ bit of tag
SPR_LOG("dmaIrq Set\n"); {
SPR_LOG("dmaIrq Set");
//SysPrintf("SPR1 TIE\n"); //Console::WriteLn("SPR1 TIE");
spr1->qwc = 0; spr1->qwc = 0;
done = 1; done = 1;
// break;
} }
//}
spr1finished = done; spr1finished = done;
if(done == 0) { if (done == 0)
{
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
spr1->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag spr1->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
CPU_INT(9, spr1->qwc / BIAS); CPU_INT(9, spr1->qwc / BIAS);
spr1->qwc = 0; spr1->qwc = 0;
} }
} else { // Interleave Mode }
else // Interleave Mode
{
_SPR1interleave(); _SPR1interleave();
} }
} }
void dmaSPR1() { // toSPR void dmaSPR1() // toSPR
{
#ifdef SPR_LOG
SPR_LOG("dmaSPR1 chcr = 0x%x, madr = 0x%x, qwc = 0x%x\n" SPR_LOG("dmaSPR1 chcr = 0x%x, madr = 0x%x, qwc = 0x%x\n"
" tadr = 0x%x, sadr = 0x%x\n", " tadr = 0x%x, sadr = 0x%x",
spr1->chcr, spr1->madr, spr1->qwc, spr1->chcr, spr1->madr, spr1->qwc,
spr1->tadr, spr1->sadr); spr1->tadr, spr1->sadr);
#endif
if ((spr1->chcr & 0xc) == 0x4 && spr1->qwc == 0){ if ((spr1->chcr & 0xc) == 0x4 && spr1->qwc == 0)
u32 *ptag; {
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR u32 *ptag;
CPU_INT(9, (ptag[0] & 0xffff) / BIAS); ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
//spr1->qwc = 0; CPU_INT(9, (ptag[0] & 0xffff) / BIAS);
return; //spr1->qwc = 0;
} return;
}
// COMPLETE HACK!!! For now at least.. FFX Videos dont rely on interrupts or reading DMA values // COMPLETE HACK!!! For now at least.. FFX Videos dont rely on interrupts or reading DMA values
// It merely assumes that the last one has finished then starts another one (broke with the DMA fix) // It merely assumes that the last one has finished then starts another one (broke with the DMA fix)
// This "shouldn't" cause any problems as SPR is generally faster than the other DMAS anyway. (Refraction) // This "shouldn't" cause any problems as SPR is generally faster than the other DMAS anyway. (Refraction)
CPU_INT(9, spr1->qwc / BIAS); CPU_INT(9, spr1->qwc / BIAS);
} }
void SPRTOinterrupt() void SPRTOinterrupt()
{ {
_dmaSPR1(); _dmaSPR1();
if( spr1finished == 0 ) return; if (spr1finished == 0) return;
spr1->chcr &= ~0x100; spr1->chcr &= ~0x100;
hwDmacIrq(9); hwDmacIrq(9);
} }
void SaveState::sprFreeze() void SaveState::sprFreeze()
{ {
FreezeTag( "SPRdma" ); FreezeTag("SPRdma");
Freeze(spr0finished); Freeze(spr0finished);
Freeze(spr1finished); Freeze(spr1finished);

View File

@ -207,6 +207,7 @@ gzSavingState::gzSavingState( const string& filename ) :
if( m_file == NULL ) if( m_file == NULL )
throw Exception::FileNotFound(); throw Exception::FileNotFound();
gzsetparams( m_file, Z_BEST_SPEED, Z_DEFAULT_STRATEGY );
Freeze( m_version ); Freeze( m_version );
} }

View File

@ -31,7 +31,7 @@
// the lower 16 bit value. IF the change is breaking of all compatibility with old // the lower 16 bit value. IF the change is breaking of all compatibility with old
// states, increment the upper 16 bit value, and clear the lower 16 bits to 0. // states, increment the upper 16 bit value, and clear the lower 16 bits to 0.
static const u32 g_SaveVersion = 0x8b410000; static const u32 g_SaveVersion = 0x8b410001;
// this function is meant to be used in the place of GSfreeze, and provides a safe layer // this function is meant to be used in the place of GSfreeze, and provides a safe layer
// between the GS saving function and the MTGS's needs. :) // between the GS saving function and the MTGS's needs. :)

View File

@ -37,7 +37,8 @@ DMACh *sif2ch;
#define FIFO_SIF0_W 128 #define FIFO_SIF0_W 128
#define FIFO_SIF1_W 128 #define FIFO_SIF1_W 128
struct _sif0{ struct _sif0
{
u32 fifoData[FIFO_SIF0_W]; u32 fifoData[FIFO_SIF0_W];
int fifoReadPos; int fifoReadPos;
int fifoWritePos; int fifoWritePos;
@ -49,7 +50,8 @@ struct _sif0{
struct sifData sifData; struct sifData sifData;
}; };
struct _sif1 { struct _sif1
{
u32 fifoData[FIFO_SIF1_W]; u32 fifoData[FIFO_SIF1_W];
int fifoReadPos; int fifoReadPos;
int fifoWritePos; int fifoWritePos;
@ -76,284 +78,213 @@ void sifInit()
static __forceinline void SIF0write(u32 *from, int words) static __forceinline void SIF0write(u32 *from, int words)
{ {
/*if(FIFO_SIF0_W < (words+sif0.fifoWritePos)) {*/ const int wP0 = min((FIFO_SIF0_W - sif0.fifoWritePos), words);
const int wP1 = words - wP0;
const int wP0 = min((FIFO_SIF0_W-sif0.fifoWritePos),words); memcpy(&sif0.fifoData[sif0.fifoWritePos], from, wP0 << 2);
const int wP1 = words - wP0; memcpy(&sif0.fifoData[0], &from[wP0], wP1 << 2);
memcpy(&sif0.fifoData[sif0.fifoWritePos], from, wP0 << 2); sif0.fifoWritePos = (sif0.fifoWritePos + words) & (FIFO_SIF0_W - 1);
memcpy(&sif0.fifoData[0], &from[wP0], wP1 << 2);
sif0.fifoWritePos = (sif0.fifoWritePos + words) & (FIFO_SIF0_W-1);
/*}
else
{
memcpy_fast(&sif0.fifoData[sif0.fifoWritePos], from, words << 2);
sif0.fifoWritePos += words;
}*/
sif0.fifoSize += words; sif0.fifoSize += words;
SIF_LOG(" SIF0 + %d = %d (pos=%d)\n", words, sif0.fifoSize, sif0.fifoWritePos); SIF_LOG(" SIF0 + %d = %d (pos=%d)", words, sif0.fifoSize, sif0.fifoWritePos);
} }
static __forceinline void SIF0read(u32 *to, int words) static __forceinline void SIF0read(u32 *to, int words)
{ {
/*if(FIFO_SIF0_W < (words+sif0.fifoReadPos)) const int wP0 = min((FIFO_SIF0_W - sif0.fifoReadPos), words);
{*/ const int wP1 = words - wP0;
const int wP0 = min((FIFO_SIF0_W-sif0.fifoReadPos),words);
const int wP1 = words - wP0;
memcpy(to, &sif0.fifoData[sif0.fifoReadPos], wP0 << 2); memcpy(to, &sif0.fifoData[sif0.fifoReadPos], wP0 << 2);
memcpy(&to[wP0], &sif0.fifoData[0], wP1 << 2); memcpy(&to[wP0], &sif0.fifoData[0], wP1 << 2);
sif0.fifoReadPos = (sif0.fifoReadPos + words) & (FIFO_SIF0_W-1);
/*}
else
{
memcpy_fast(to, &sif0.fifoData[sif0.fifoReadPos], words << 2);
sif0.fifoReadPos += words;
}*/
sif0.fifoReadPos = (sif0.fifoReadPos + words) & (FIFO_SIF0_W - 1);
sif0.fifoSize -= words; sif0.fifoSize -= words;
SIF_LOG(" SIF0 - %d = %d (pos=%d)\n", words, sif0.fifoSize, sif0.fifoReadPos); SIF_LOG(" SIF0 - %d = %d (pos=%d)", words, sif0.fifoSize, sif0.fifoReadPos);
} }
__forceinline void SIF1write(u32 *from, int words) __forceinline void SIF1write(u32 *from, int words)
{ {
/*if(FIFO_SIF1_W < (words+sif1.fifoWritePos)) const int wP0 = min((FIFO_SIF1_W - sif1.fifoWritePos), words);
{*/ const int wP1 = words - wP0;
const int wP0 = min((FIFO_SIF1_W-sif1.fifoWritePos),words);
const int wP1 = words - wP0;
memcpy(&sif1.fifoData[sif1.fifoWritePos], from, wP0 << 2); memcpy(&sif1.fifoData[sif1.fifoWritePos], from, wP0 << 2);
memcpy(&sif1.fifoData[0], &from[wP0], wP1 << 2); memcpy(&sif1.fifoData[0], &from[wP0], wP1 << 2);
sif1.fifoWritePos = (sif1.fifoWritePos + words) & (FIFO_SIF1_W-1);
/*}
else
{
memcpy_fast(&sif1.fifoData[sif1.fifoWritePos], from, words << 2);
sif1.fifoWritePos += words;
}*/
sif1.fifoWritePos = (sif1.fifoWritePos + words) & (FIFO_SIF1_W - 1);
sif1.fifoSize += words; sif1.fifoSize += words;
SIF_LOG(" SIF1 + %d = %d (pos=%d)\n", words, sif1.fifoSize, sif1.fifoWritePos); SIF_LOG(" SIF1 + %d = %d (pos=%d)", words, sif1.fifoSize, sif1.fifoWritePos);
} }
static __forceinline void SIF1read(u32 *to, int words) static __forceinline void SIF1read(u32 *to, int words)
{ {
/*if(FIFO_SIF1_W < (words+sif1.fifoReadPos)) const int wP0 = min((FIFO_SIF1_W - sif1.fifoReadPos), words);
{*/ const int wP1 = words - wP0;
const int wP0 = min((FIFO_SIF1_W-sif1.fifoReadPos),words);
const int wP1 = words - wP0;
memcpy(to, &sif1.fifoData[sif1.fifoReadPos], wP0 << 2); memcpy(to, &sif1.fifoData[sif1.fifoReadPos], wP0 << 2);
memcpy(&to[wP0], &sif1.fifoData[0], wP1 << 2); memcpy(&to[wP0], &sif1.fifoData[0], wP1 << 2);
sif1.fifoReadPos = (sif1.fifoReadPos + words) & (FIFO_SIF1_W-1);
/*}
else
{
memcpy_fast(to, &sif1.fifoData[sif1.fifoReadPos], words << 2);
sif1.fifoReadPos += words;
}*/
sif1.fifoReadPos = (sif1.fifoReadPos + words) & (FIFO_SIF1_W - 1);
sif1.fifoSize -= words; sif1.fifoSize -= words;
SIF_LOG(" SIF1 - %d = %d (pos=%d)\n", words, sif1.fifoSize, sif1.fifoReadPos); SIF_LOG(" SIF1 - %d = %d (pos=%d)", words, sif1.fifoSize, sif1.fifoReadPos);
} }
__forceinline void SIF0Dma() __forceinline void SIF0Dma()
{ {
u32 *ptag; u32 *ptag;
int notDone = 1; int notDone = TRUE;
int cycles = 0, psxCycles = 0; int cycles = 0, psxCycles = 0;
SIF_LOG("SIF0 DMA start...\n"); SIF_LOG("SIF0 DMA start...");
do do
{ {
if (iopsifbusy[0] == 1) // If EE SIF0 is enabled
/*if ((psHu32(DMAC_CTRL) & 0xC0)) {
SysPrintf("DMA Stall Control %x\n",(psHu32(DMAC_CTRL) & 0xC0));
}*/
if(iopsifbusy[0] == 1) // If EE SIF0 is enabled
{ {
//int size = sif0.counter; //HW_DMA9_BCR >> 16; if (sif0.counter == 0) // If there's no more to transfer
if(sif0.counter == 0) // If there's no more to transfer
{ {
// Note.. add normal mode here // Note.. add normal mode here
if (sif0.sifData.data & 0xC0000000) // If NORMAL mode or end of CHAIN, or interrupt then stop DMA if (sif0.sifData.data & 0xC0000000) // If NORMAL mode or end of CHAIN, or interrupt then stop DMA
{ {
SIF_LOG(" IOP SIF Stopped\n"); SIF_LOG(" IOP SIF Stopped");
// Stop & signal interrupts on IOP // Stop & signal interrupts on IOP
//HW_DMA9_CHCR &= ~0x01000000; //reset TR flag
//psxDmaInterrupt2(2);
iopsifbusy[0] = 0; iopsifbusy[0] = 0;
PSX_INT(IopEvt_SIF0, psxCycles);
// iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords) // iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords)
// So when we're all done, the equation looks like thus: // So when we're all done, the equation looks like thus:
//PSX_INT(IopEvt_SIF0, ( ( psxCycles*BIAS ) / 4 ) / 8); //PSX_INT(IopEvt_SIF0, ( ( psxCycles*BIAS ) / 4 ) / 8);
PSX_INT(IopEvt_SIF0, psxCycles);
//hwIntcIrq(INTC_SBUS);
sif0.sifData.data = 0; sif0.sifData.data = 0;
notDone = 0; notDone = FALSE;
} }
else // Chain mode else // Chain mode
{ {
// Process DMA tag at HW_DMA9_TADR // Process DMA tag at HW_DMA9_TADR
sif0.sifData = *(sifData *)iopPhysMem( HW_DMA9_TADR ); sif0.sifData = *(sifData *)iopPhysMem(HW_DMA9_TADR);
sif0.sifData.words = (sif0.sifData.words + 3) & 0xfffffffc; // Round up to nearest 4. sif0.sifData.words = (sif0.sifData.words + 3) & 0xfffffffc; // Round up to nearest 4.
SIF0write((u32*)iopPhysMem(HW_DMA9_TADR+8), 4); SIF0write((u32*)iopPhysMem(HW_DMA9_TADR + 8), 4);
//psxCycles += 2; HW_DMA9_MADR = sif0.sifData.data & 0xFFFFFF;
HW_DMA9_MADR = sif0.sifData.data & 0xFFFFFF;
HW_DMA9_TADR += 16; ///HW_DMA9_MADR + 16 + sif0.sifData.words << 2; HW_DMA9_TADR += 16; ///HW_DMA9_MADR + 16 + sif0.sifData.words << 2;
//HW_DMA9_BCR = (sif0.sifData.words << 16) | 1;
sif0.counter = sif0.sifData.words & 0xFFFFFF; sif0.counter = sif0.sifData.words & 0xFFFFFF;
notDone = 1; notDone = TRUE;
SIF_LOG(" SIF0 Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)\n", HW_DMA9_MADR, HW_DMA9_TADR, sif0.counter, sif0.sifData.words, sif0.sifData.data); SIF_LOG(" SIF0 Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)", HW_DMA9_MADR, HW_DMA9_TADR, sif0.counter, sif0.sifData.words, sif0.sifData.data);
if(sif0.sifData.data & 0x40000000) if (sif0.sifData.data & 0x40000000)
SIF_LOG(" END\n"); SIF_LOG(" END");
else else
SIF_LOG(" CNT %08X, %08X\n", sif0.sifData.data, sif0.sifData.words); SIF_LOG(" CNT %08X, %08X", sif0.sifData.data, sif0.sifData.words);
} }
} }
else // There's some data ready to transfer into the fifo.. else // There's some data ready to transfer into the fifo..
{ {
int wTransfer = min(sif0.counter, FIFO_SIF0_W-sif0.fifoSize); // HW_DMA9_BCR >> 16; int wTransfer = min(sif0.counter, FIFO_SIF0_W - sif0.fifoSize); // HW_DMA9_BCR >> 16;
SIF_LOG("+++++++++++ %lX of %lX\n", wTransfer, sif0.counter /*(HW_DMA9_BCR >> 16)*/ ); SIF_LOG("+++++++++++ %lX of %lX", wTransfer, sif0.counter /*(HW_DMA9_BCR >> 16)*/);
SIF0write((u32*)iopPhysMem(HW_DMA9_MADR), wTransfer); SIF0write((u32*)iopPhysMem(HW_DMA9_MADR), wTransfer);
HW_DMA9_MADR += wTransfer << 2; HW_DMA9_MADR += wTransfer << 2;
//HW_DMA9_BCR = (HW_DMA9_BCR & 0xFFFF) | (((HW_DMA9_BCR >> 16) - wTransfer)<<16);
psxCycles += (wTransfer / 4) * BIAS; // fixme : should be / 16 psxCycles += (wTransfer / 4) * BIAS; // fixme : should be / 16
//psxCycles += wTransfer;
sif0.counter -= wTransfer; sif0.counter -= wTransfer;
//notDone = 1;
} }
} }
if(eesifbusy[0] == 1) // If EE SIF enabled and there's something to transfer if (eesifbusy[0] == 1) // If EE SIF enabled and there's something to transfer
{ {
int size = sif0dma->qwc; int size = sif0dma->qwc;
if ((psHu32(DMAC_CTRL) & 0x30) == 0x10) { // STS == fromSIF0 if ((psHu32(DMAC_CTRL) & 0x30) == 0x10) // STS == fromSIF0
SIF_LOG("SIF0 stall control\n");
}
if(size > 0) // If we're reading something continue to do so
{ {
/*if(sif0.fifoSize > 0) SIF_LOG("SIF0 stall control");
{*/ }
int readSize = min(size, (sif0.fifoSize>>2)); if (size > 0) // If we're reading something continue to do so
{
int readSize = min(size, (sif0.fifoSize >> 2));
//SIF_LOG(" EE SIF doing transfer %04Xqw to %08X\n", readSize, sif0dma->madr); //SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr);
SIF_LOG("----------- %lX of %lX\n", readSize << 2, size << 2 ); SIF_LOG("----------- %lX of %lX", readSize << 2, size << 2);
_dmaGetAddr(sif0dma, ptag, sif0dma->madr, 5); _dmaGetAddr(sif0dma, ptag, sif0dma->madr, 5);
SIF0read((u32*)ptag, readSize<<2); SIF0read((u32*)ptag, readSize << 2);
// {
// int i;
// for(i = 0; i < readSize; ++i) {
// SIF_LOG("EE SIF0 read madr: %x %x %x %x\n", ((u32*)ptag)[4*i+0], ((u32*)ptag)[4*i+1], ((u32*)ptag)[4*i+2], ((u32*)ptag)[4*i+3]);
// }
// }
Cpu->Clear(sif0dma->madr, readSize*4); Cpu->Clear(sif0dma->madr, readSize*4);
cycles += readSize * BIAS; // fixme : BIAS is factored in below cycles += readSize * BIAS; // fixme : BIAS is factored in below
//cycles += readSize; sif0dma->qwc -= readSize;
sif0dma->qwc -= readSize; sif0dma->madr += readSize << 4;
sif0dma->madr += readSize << 4;
//notDone = 1;
//}
} }
if(sif0dma->qwc == 0) if (sif0dma->qwc == 0)
{ {
if((sif0dma->chcr & 0x80000080) == 0x80000080) // Stop on tag IRQ if ((sif0dma->chcr & 0x80000080) == 0x80000080) // Stop on tag IRQ
{ {
// Tag interrupt // Tag interrupt
SIF_LOG(" EE SIF interrupt\n"); SIF_LOG(" EE SIF interrupt");
//sif0dma->chcr &= ~0x100;
eesifbusy[0] = 0; eesifbusy[0] = 0;
CPU_INT(5, cycles*BIAS); CPU_INT(5, cycles*BIAS);
//hwDmacIrq(5); notDone = FALSE;
notDone = 0;
} }
else if(sif0.end) // Stop on tag END else if (sif0.end) // Stop on tag END
{ {
// End tag. // End tag.
SIF_LOG(" EE SIF end\n"); SIF_LOG(" EE SIF end");
//sif0dma->chcr &= ~0x100;
//hwDmacIrq(5);
eesifbusy[0] = 0; eesifbusy[0] = 0;
CPU_INT(5, cycles*BIAS); CPU_INT(5, cycles*BIAS);
notDone = 0; notDone = FALSE;
} }
else if(sif0.fifoSize >= 4) // Read a tag else if (sif0.fifoSize >= 4) // Read a tag
{ {
static PCSX2_ALIGNED16(u32 tag[4]); static PCSX2_ALIGNED16(u32 tag[4]);
SIF0read((u32*)&tag[0], 4); // Tag SIF0read((u32*)&tag[0], 4); // Tag
SIF_LOG(" EE SIF read tag: %x %x %x %x\n", tag[0], tag[1], tag[2], tag[3]); SIF_LOG(" EE SIF read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]);
sif0dma->qwc = (u16)tag[0]; sif0dma->qwc = (u16)tag[0];
sif0dma->madr = tag[1]; sif0dma->madr = tag[1];
sif0dma->chcr = (sif0dma->chcr & 0xffff) | (tag[0] & 0xffff0000); sif0dma->chcr = (sif0dma->chcr & 0xffff) | (tag[0] & 0xffff0000);
/*if ((sif0dma->chcr & 0x80) && (tag[0] >> 31)) { SIF_LOG(" EE SIF dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)", sif0dma->madr, sif0dma->qwc, (tag[0] >> 28)&3, (tag[0] >> 31)&1, tag[1], tag[0]);
SysPrintf("SIF0 TIE\n");
}*/
SIF_LOG(" EE SIF dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)\n", sif0dma->madr, sif0dma->qwc, (tag[0]>>28)&3, (tag[0]>>31)&1, tag[1], tag[0]);
if ((psHu32(DMAC_CTRL) & 0x30) != 0 && ((tag[0]>>28)&3) == 0) if ((psHu32(DMAC_CTRL) & 0x30) != 0 && ((tag[0] >> 28)&3) == 0)
psHu32(DMAC_STADR) = sif0dma->madr + (sif0dma->qwc * 16); psHu32(DMAC_STADR) = sif0dma->madr + (sif0dma->qwc * 16);
notDone = 1; notDone = TRUE;
sif0.chain = 1; sif0.chain = 1;
if(tag[0] & 0x40000000) if (tag[0] & 0x40000000) sif0.end = 1;
sif0.end = 1;
} }
} }
} }
}while(notDone); }
while (notDone);
} }
__forceinline void SIF1Dma() __forceinline void SIF1Dma()
{ {
int id; int id;
u32 *ptag; u32 *ptag;
int notDone; bool notDone = true;
int cycles = 0, psxCycles = 0; int cycles = 0, psxCycles = 0;
notDone = 1;
do do
{ {
if(eesifbusy[1] == 1) // If EE SIF1 is enabled if (eesifbusy[1] == 1) // If EE SIF1 is enabled
{ {
if ((psHu32(DMAC_CTRL) & 0xC0) == 0xC0) if ((psHu32(DMAC_CTRL) & 0xC0) == 0xC0)
SIF_LOG("SIF1 stall control\n"); // STS == fromSIF1 SIF_LOG("SIF1 stall control"); // STS == fromSIF1
if(sif1dma->qwc == 0) // If there's no more to transfer if (sif1dma->qwc == 0) // If there's no more to transfer
{ {
if ((sif1dma->chcr & 0xc) == 0 || sif1.end) // If NORMAL mode or end of CHAIN then stop DMA if ((sif1dma->chcr & 0xc) == 0 || sif1.end) // If NORMAL mode or end of CHAIN then stop DMA
{ {
// Stop & signal interrupts on EE // Stop & signal interrupts on EE
//sif1dma->chcr &= ~0x100; SIF_LOG("EE SIF1 End %x", sif1.end);
//hwDmacIrq(6);
SIF_LOG("EE SIF1 End %x\n", sif1.end);
eesifbusy[1] = 0; eesifbusy[1] = 0;
notDone = 0; notDone = FALSE;
CPU_INT(6, cycles*BIAS); CPU_INT(6, cycles*BIAS);
sif1.chain = 0; sif1.chain = 0;
sif1.end = 0; sif1.end = 0;
@ -361,59 +292,61 @@ __forceinline void SIF1Dma()
else // Chain mode else // Chain mode
{ {
// Process DMA tag at sif1dma->tadr // Process DMA tag at sif1dma->tadr
notDone = 1; notDone = TRUE;
_dmaGetAddr(sif1dma, ptag, sif1dma->tadr, 6); _dmaGetAddr(sif1dma, ptag, sif1dma->tadr, 6);
sif1dma->chcr = ( sif1dma->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); // Copy the tag sif1dma->chcr = (sif1dma->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); // Copy the tag
sif1dma->qwc = (u16)ptag[0]; sif1dma->qwc = (u16)ptag[0];
if (sif1dma->chcr & 0x40) { if (sif1dma->chcr & 0x40)
SysPrintf("SIF1 TTE\n"); {
SIF1write(ptag+2, 2); Console::WriteLn("SIF1 TTE");
SIF1write(ptag + 2, 2);
} }
sif1.chain = 1; sif1.chain = 1;
id = (ptag[0] >> 28) & 0x7; id = (ptag[0] >> 28) & 0x7;
switch(id) switch (id)
{ {
case 0: // refe case 0: // refe
SIF_LOG(" REFE %08X\n", ptag[1]); SIF_LOG(" REFE %08X", ptag[1]);
sif1.end = 1; sif1.end = 1;
sif1dma->madr = ptag[1]; sif1dma->madr = ptag[1];
sif1dma->tadr += 16; sif1dma->tadr += 16;
break; break;
case 1: // cnt case 1: // cnt
SIF_LOG(" CNT\n"); SIF_LOG(" CNT");
sif1dma->madr = sif1dma->tadr + 16; sif1dma->madr = sif1dma->tadr + 16;
sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4); sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4);
break; break;
case 2: // next case 2: // next
SIF_LOG(" NEXT %08X\n", ptag[1]); SIF_LOG(" NEXT %08X", ptag[1]);
sif1dma->madr = sif1dma->tadr + 16; sif1dma->madr = sif1dma->tadr + 16;
sif1dma->tadr = ptag[1]; sif1dma->tadr = ptag[1];
break; break;
case 3: // ref case 3: // ref
case 4: // refs case 4: // refs
SIF_LOG(" REF %08X\n", ptag[1]); SIF_LOG(" REF %08X", ptag[1]);
sif1dma->madr = ptag[1]; sif1dma->madr = ptag[1];
sif1dma->tadr += 16; sif1dma->tadr += 16;
break; break;
case 7: // end case 7: // end
SIF_LOG(" END\n"); SIF_LOG(" END");
sif1.end = 1; sif1.end = 1;
sif1dma->madr = sif1dma->tadr + 16; sif1dma->madr = sif1dma->tadr + 16;
sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4); sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4);
break; break;
default: default:
SysPrintf("Bad addr1 source chain\n"); Console::WriteLn("Bad addr1 source chain");
} }
if ((sif1dma->chcr & 0x80) && (ptag[0] >> 31)) { if ((sif1dma->chcr & 0x80) && (ptag[0] >> 31))
SysPrintf("SIF1 TIE\n"); {
Console::WriteLn("SIF1 TIE");
sif1.end = 1; sif1.end = 1;
} }
} }
@ -423,124 +356,112 @@ __forceinline void SIF1Dma()
int qwTransfer = sif1dma->qwc; int qwTransfer = sif1dma->qwc;
u32 *data; u32 *data;
//notDone = 1;
_dmaGetAddr(sif1dma, data, sif1dma->madr, 6); _dmaGetAddr(sif1dma, data, sif1dma->madr, 6);
if(qwTransfer > (FIFO_SIF1_W-sif1.fifoSize)/4) // Copy part of sif1dma into FIFO if (qwTransfer > (FIFO_SIF1_W - sif1.fifoSize) / 4) // Copy part of sif1dma into FIFO
qwTransfer = (FIFO_SIF1_W-sif1.fifoSize)/4; qwTransfer = (FIFO_SIF1_W - sif1.fifoSize) / 4;
SIF1write(data, qwTransfer << 2); SIF1write(data, qwTransfer << 2);
sif1dma->madr += qwTransfer << 4; sif1dma->madr += qwTransfer << 4;
cycles += qwTransfer * BIAS; // fixme : BIAS is factored in above cycles += qwTransfer * BIAS; // fixme : BIAS is factored in above
//cycles += qwTransfer; // 1 cycle per quadword (BIAS is factored later)
sif1dma->qwc -= qwTransfer; sif1dma->qwc -= qwTransfer;
} }
} }
if(iopsifbusy[1] == 1) // If IOP SIF enabled and there's something to transfer if (iopsifbusy[1] == 1) // If IOP SIF enabled and there's something to transfer
{ {
int size = sif1.counter; int size = sif1.counter;
if(size > 0) // If we're reading something continue to do so if (size > 0) // If we're reading something continue to do so
{ {
/*if(sif1.fifoSize > 0) int readSize = size;
{*/
int readSize = size;
if(readSize > sif1.fifoSize) readSize = sif1.fifoSize; if (readSize > sif1.fifoSize) readSize = sif1.fifoSize;
SIF_LOG(" IOP SIF doing transfer %04X to %08X\n", readSize, HW_DMA10_MADR); SIF_LOG(" IOP SIF doing transfer %04X to %08X", readSize, HW_DMA10_MADR);
SIF1read((u32*)iopPhysMem(HW_DMA10_MADR), readSize); SIF1read((u32*)iopPhysMem(HW_DMA10_MADR), readSize);
psxCpu->Clear(HW_DMA10_MADR, readSize); psxCpu->Clear(HW_DMA10_MADR, readSize);
psxCycles += readSize / 4; // fixme: should be / 16 psxCycles += readSize / 4; // fixme: should be / 16
sif1.counter = size-readSize; sif1.counter = size - readSize;
HW_DMA10_MADR += readSize << 2; HW_DMA10_MADR += readSize << 2;
//notDone = 1;
//}
} }
if(sif1.counter <= 0) if (sif1.counter <= 0)
{ {
if(sif1.tagMode & 0x80) // Stop on tag IRQ if (sif1.tagMode & 0x80) // Stop on tag IRQ
{ {
// Tag interrupt // Tag interrupt
SIF_LOG(" IOP SIF interrupt\n"); SIF_LOG(" IOP SIF interrupt");
//HW_DMA10_CHCR &= ~0x01000000; //reset TR flag
//psxDmaInterrupt2(3);
iopsifbusy[1] = 0; iopsifbusy[1] = 0;
PSX_INT(IopEvt_SIF1, psxCycles); PSX_INT(IopEvt_SIF1, psxCycles);
//hwIntcIrq(INTC_SBUS);
sif1.tagMode = 0; sif1.tagMode = 0;
notDone = 0; notDone = FALSE;
} }
else if(sif1.tagMode & 0x40) // Stop on tag END else if (sif1.tagMode & 0x40) // Stop on tag END
{ {
// End tag. // End tag.
SIF_LOG(" IOP SIF end\n"); SIF_LOG(" IOP SIF end");
//HW_DMA10_CHCR &= ~0x01000000; //reset TR flag
//psxDmaInterrupt2(3);
iopsifbusy[1] = 0; iopsifbusy[1] = 0;
PSX_INT(IopEvt_SIF1, psxCycles); PSX_INT(IopEvt_SIF1, psxCycles);
//hwIntcIrq(INTC_SBUS);
sif1.tagMode = 0; sif1.tagMode = 0;
notDone = 0; notDone = FALSE;
} }
else if(sif1.fifoSize >= 4) // Read a tag else if (sif1.fifoSize >= 4) // Read a tag
{ {
struct sifData d; struct sifData d;
SIF1read((u32*)&d, 4); SIF1read((u32*)&d, 4);
SIF_LOG(" IOP SIF dest chain tag madr:%08X wc:%04X id:%X irq:%d\n", d.data & 0xffffff, d.words, (d.data>>28)&7, (d.data>>31)&1); SIF_LOG(" IOP SIF dest chain tag madr:%08X wc:%04X id:%X irq:%d", d.data & 0xffffff, d.words, (d.data >> 28)&7, (d.data >> 31)&1);
HW_DMA10_MADR = d.data & 0xffffff; HW_DMA10_MADR = d.data & 0xffffff;
sif1.counter = d.words; sif1.counter = d.words;
sif1.tagMode = (d.data >> 24) & 0xFF; sif1.tagMode = (d.data >> 24) & 0xFF;
notDone = 1; notDone = TRUE;
} }
} }
} }
} while (notDone); }
while (notDone);
} }
__forceinline void sif0Interrupt() { __forceinline void sif0Interrupt()
{
HW_DMA9_CHCR &= ~0x01000000; HW_DMA9_CHCR &= ~0x01000000;
psxDmaInterrupt2(2); psxDmaInterrupt2(2);
//hwIntcIrq(INTC_SBUS);
} }
__forceinline void sif1Interrupt() { __forceinline void sif1Interrupt()
{
HW_DMA10_CHCR &= ~0x01000000; //reset TR flag HW_DMA10_CHCR &= ~0x01000000; //reset TR flag
psxDmaInterrupt2(3); psxDmaInterrupt2(3);
//hwIntcIrq(INTC_SBUS);
} }
__forceinline void EEsif0Interrupt() { __forceinline void EEsif0Interrupt()
{
sif0dma->chcr &= ~0x100; sif0dma->chcr &= ~0x100;
hwDmacIrq(DMAC_SIF0); hwDmacIrq(DMAC_SIF0);
} }
__forceinline void EEsif1Interrupt() { __forceinline void EEsif1Interrupt()
{
hwDmacIrq(DMAC_SIF1); hwDmacIrq(DMAC_SIF1);
sif1dma->chcr &= ~0x100; sif1dma->chcr &= ~0x100;
} }
__forceinline void dmaSIF0() { __forceinline void dmaSIF0()
SIF_LOG("EE: dmaSIF0 chcr = %lx, madr = %lx, qwc = %lx, tadr = %lx\n", {
sif0dma->chcr, sif0dma->madr, sif0dma->qwc, sif0dma->tadr); SIF_LOG("EE: dmaSIF0 chcr = %lx, madr = %lx, qwc = %lx, tadr = %lx",
sif0dma->chcr, sif0dma->madr, sif0dma->qwc, sif0dma->tadr);
if (sif0.fifoReadPos != sif0.fifoWritePos) { if (sif0.fifoReadPos != sif0.fifoWritePos)
SIF_LOG("warning, sif0.fifoReadPos != sif0.fifoWritePos\n"); {
SIF_LOG("warning, sif0.fifoReadPos != sif0.fifoWritePos");
} }
// if(sif0dma->qwc > 0 & (sif0dma->chcr & 0x4) == 0x4) {
// sif0dma->chcr &= ~4; //Halflife sets a QWC amount in chain mode, no tadr set.
// SysPrintf("yo\n");
// }
psHu32(0x1000F240) |= 0x2000; psHu32(0x1000F240) |= 0x2000;
eesifbusy[0] = 1; eesifbusy[0] = 1;
if(eesifbusy[0] == 1 && iopsifbusy[0] == 1) { if (eesifbusy[0] == 1 && iopsifbusy[0] == 1)
{
FreezeXMMRegs(1); FreezeXMMRegs(1);
hwIntcIrq(INTC_SBUS); hwIntcIrq(INTC_SBUS);
SIF0Dma(); SIF0Dma();
@ -550,22 +471,20 @@ __forceinline void dmaSIF0() {
} }
} }
__forceinline void dmaSIF1() { __forceinline void dmaSIF1()
SIF_LOG("EE: dmaSIF1 chcr = %lx, madr = %lx, qwc = %lx, tadr = %lx\n", {
sif1dma->chcr, sif1dma->madr, sif1dma->qwc, sif1dma->tadr); SIF_LOG("EE: dmaSIF1 chcr = %lx, madr = %lx, qwc = %lx, tadr = %lx",
sif1dma->chcr, sif1dma->madr, sif1dma->qwc, sif1dma->tadr);
if (sif1.fifoReadPos != sif1.fifoWritePos) { if (sif1.fifoReadPos != sif1.fifoWritePos)
SIF_LOG("warning, sif1.fifoReadPos != sif1.fifoWritePos\n"); {
SIF_LOG("warning, sif1.fifoReadPos != sif1.fifoWritePos");
} }
// if(sif1dma->qwc > 0 & (sif1dma->chcr & 0x4) == 0x4) {
// sif1dma->chcr &= ~4; //Halflife sets a QWC amount in chain mode, no tadr set.
// SysPrintf("yo2\n");
// }
psHu32(0x1000F240) |= 0x4000; psHu32(0x1000F240) |= 0x4000;
eesifbusy[1] = 1; eesifbusy[1] = 1;
if(eesifbusy[1] == 1 && iopsifbusy[1] == 1) { if (eesifbusy[1] == 1 && iopsifbusy[1] == 1)
{
FreezeXMMRegs(1); FreezeXMMRegs(1);
SIF1Dma(); SIF1Dma();
psHu32(0x1000F240) &= ~0x40; psHu32(0x1000F240) &= ~0x40;
@ -576,19 +495,20 @@ __forceinline void dmaSIF1() {
} }
__forceinline void dmaSIF2() { __forceinline void dmaSIF2()
SIF_LOG("dmaSIF2 chcr = %lx, madr = %lx, qwc = %lx\n", {
sif2dma->chcr, sif2dma->madr, sif2dma->qwc); SIF_LOG("dmaSIF2 chcr = %lx, madr = %lx, qwc = %lx",
sif2dma->chcr, sif2dma->madr, sif2dma->qwc);
sif2dma->chcr&= ~0x100; sif2dma->chcr &= ~0x100;
hwDmacIrq(7); hwDmacIrq(7);
SysPrintf("*PCSX2*: dmaSIF2\n"); Console::WriteLn("*PCSX2*: dmaSIF2");
} }
void SaveState::sifFreeze() void SaveState::sifFreeze()
{ {
FreezeTag( "SIFdma" ); FreezeTag("SIFdma");
Freeze(sif0); Freeze(sif0);
Freeze(sif1); Freeze(sif1);

View File

@ -45,6 +45,17 @@ __forceinline void SIO_INT()
#define SIO_FORCEINLINE __forceinline #define SIO_FORCEINLINE __forceinline
#endif #endif
// Currently only check if pad wants mtap to be active.
// Could lets PCSX2 have its own options, if anyone ever
// wants to add support for using the extra memcard slots.
static bool IsMtapPresent( uint port ) {
switch(port) {
case 1: return 0 != PAD1queryMtap(port);
case 2: return 0 != PAD2queryMtap(port);
}
return 0;
}
static void _ReadMcd(u8 *data, u32 adr, int size) { static void _ReadMcd(u8 *data, u32 adr, int size) {
MemoryCard::Read(sio.GetMemcardIndex(), data, adr, size); MemoryCard::Read(sio.GetMemcardIndex(), data, adr, size);
} }
@ -99,12 +110,12 @@ u8 sioRead8() {
}*/ }*/
} }
} }
//PAD_LOG("sio read8 ;ret = %x\n", ret); //PAD_LOG("sio read8 ;ret = %x", ret);
return ret; return ret;
} }
void SIO_CommandWrite(u8 value,int way) { void SIO_CommandWrite(u8 value,int way) {
PAD_LOG("sio write8 %x\n", value); PAD_LOG("sio write8 %x", value);
// PAD COMMANDS // PAD COMMANDS
switch (sio.padst) { switch (sio.padst) {
@ -138,6 +149,13 @@ void SIO_CommandWrite(u8 value,int way) {
if (sio.parp == sio.bufcount) { sio.padst = 0; return; } if (sio.parp == sio.bufcount) { sio.padst = 0; return; }
SIO_INT(); SIO_INT();
return; return;
case 3:
// No pad connected.
sio.parp++;
sio.bufcount = 6;
if (sio.parp == sio.bufcount) { sio.padst = 0; return; }
SIO_INT();
return;
} }
// MEMORY CARD COMMANDS // MEMORY CARD COMMANDS
@ -149,7 +167,7 @@ void SIO_CommandWrite(u8 value,int way) {
sio.parp = 1; sio.parp = 1;
switch (value) { switch (value) {
case 0x11: // RESET case 0x11: // RESET
PAD_LOG("RESET MEMORY CARD\n"); PAD_LOG("RESET MEMORY CARD");
sio.bufcount = 8; sio.bufcount = 8;
memset8_obj<0xff>(sio.buf); memset8_obj<0xff>(sio.buf);
@ -166,7 +184,7 @@ void SIO_CommandWrite(u8 value,int way) {
sio.mcdst = 99; sio.mcdst = 99;
sio2.packet.recvVal3 = 0x8c; sio2.packet.recvVal3 = 0x8c;
MEMCARDS_LOG("MC(%d) command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break; break;
case 0x81: // COMMIT case 0x81: // COMMIT
sio.bufcount = 8; sio.bufcount = 8;
@ -180,7 +198,7 @@ void SIO_CommandWrite(u8 value,int way) {
sio2.packet.recvVal1 = 0x1600; // Writing sio2.packet.recvVal1 = 0x1600; // Writing
else if(sio.mc_command==0x43) sio2.packet.recvVal1 = 0x1700; // Reading else if(sio.mc_command==0x43) sio2.packet.recvVal1 = 0x1700; // Reading
} }
MEMCARDS_LOG("MC(%d) command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break; break;
case 0x21: case 0x21:
case 0x22: case 0x22:
@ -190,20 +208,20 @@ void SIO_CommandWrite(u8 value,int way) {
sio2.packet.recvVal3 = 0x8c; sio2.packet.recvVal3 = 0x8c;
sio.buf[8]=sio.terminator; sio.buf[8]=sio.terminator;
sio.buf[7]='+'; sio.buf[7]='+';
MEMCARDS_LOG("MC(%d) command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break; break;
case 0x24: case 0x24:
MEMCARDS_LOG("MC(%d) command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break; break;
case 0x25: case 0x25:
MEMCARDS_LOG("MC(%d) command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break; break;
case 0x26: case 0x26:
sio.bufcount = 12; sio.mcdst = 99; sio2.packet.recvVal3 = 0x83; sio.bufcount = 12; sio.mcdst = 99; sio2.packet.recvVal3 = 0x83;
memset8_obj<0xff>(sio.buf); memset8_obj<0xff>(sio.buf);
memcpy(&sio.buf[2], &mc_command_0x26, sizeof(mc_command_0x26)); memcpy(&sio.buf[2], &mc_command_0x26, sizeof(mc_command_0x26));
sio.buf[12]=sio.terminator; sio.buf[12]=sio.terminator;
MEMCARDS_LOG("MC(%d) command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break; break;
case 0x27: case 0x27:
case 0x28: case 0x28:
@ -212,7 +230,7 @@ void SIO_CommandWrite(u8 value,int way) {
memset8_obj<0xff>(sio.buf); memset8_obj<0xff>(sio.buf);
sio.buf[4]=sio.terminator; sio.buf[4]=sio.terminator;
sio.buf[3]='+'; sio.buf[3]='+';
MEMCARDS_LOG("MC(%d) command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break; break;
case 0x42: // WRITE case 0x42: // WRITE
case 0x43: // READ case 0x43: // READ
@ -225,13 +243,13 @@ void SIO_CommandWrite(u8 value,int way) {
memset8_obj<0xff>(sio.buf); memset8_obj<0xff>(sio.buf);
sio.buf[133]=sio.terminator; sio.buf[133]=sio.terminator;
sio.buf[132]='+'; sio.buf[132]='+';
MEMCARDS_LOG("MC(%d) command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break; break;
case 0xf0: case 0xf0:
case 0xf1: case 0xf1:
case 0xf2: case 0xf2:
sio.mcdst = 99; sio.mcdst = 99;
MEMCARDS_LOG("MC(%d) command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break; break;
case 0xf3: case 0xf3:
case 0xf7: case 0xf7:
@ -239,23 +257,23 @@ void SIO_CommandWrite(u8 value,int way) {
memset8_obj<0xff>(sio.buf); memset8_obj<0xff>(sio.buf);
sio.buf[4]=sio.terminator; sio.buf[4]=sio.terminator;
sio.buf[3]='+'; sio.buf[3]='+';
MEMCARDS_LOG("MC(%d) command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break; break;
case 0x52: case 0x52:
sio.rdwr = 1; memset8_obj<0xff>(sio.buf); sio.rdwr = 1; memset8_obj<0xff>(sio.buf);
sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+'; sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+';
MEMCARDS_LOG("MC(%d) command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break; break;
case 0x57: case 0x57:
sio.rdwr = 2; memset8_obj<0xff>(sio.buf); sio.rdwr = 2; memset8_obj<0xff>(sio.buf);
sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+'; sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+';
MEMCARDS_LOG("MC(%d) command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break; break;
default: default:
sio.mcdst = 0; sio.mcdst = 0;
memset8_obj<0xff>(sio.buf); memset8_obj<0xff>(sio.buf);
sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+'; sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+';
MEMCARDS_LOG("Unknown MC(%d) command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("Unknown MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
} }
sio.mc_command=value; sio.mc_command=value;
return; return;
@ -278,10 +296,10 @@ void SIO_CommandWrite(u8 value,int way) {
if (sio.parp==6) if (sio.parp==6)
{ {
if (sio_xor((u8 *)&sio.sector, 4) == value) if (sio_xor((u8 *)&sio.sector, 4) == value)
MEMCARDS_LOG("MC(%d) SET PAGE sio.sector 0x%04X\n", MEMCARDS_LOG("MC(%d) SET PAGE sio.sector 0x%04X",
sio.GetMemcardIndex()+1, sio.sector); sio.GetMemcardIndex()+1, sio.sector);
else else
MEMCARDS_LOG("MC(%d) SET PAGE XOR value ERROR 0x%02X != ^0x%02X\n", MEMCARDS_LOG("MC(%d) SET PAGE XOR value ERROR 0x%02X != ^0x%02X",
sio.GetMemcardIndex()+1, value, sio_xor((u8 *)&sio.sector, 4)); sio.GetMemcardIndex()+1, value, sio_xor((u8 *)&sio.sector, 4));
} }
break; break;
@ -291,7 +309,7 @@ void SIO_CommandWrite(u8 value,int way) {
if(sio.parp==2) { if(sio.parp==2) {
sio.terminator = value; sio.terminator = value;
sio.buf[4] = value; sio.buf[4] = value;
MEMCARDS_LOG("MC(%d) SET TERMINATOR command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) SET TERMINATOR command 0x%02X", sio.GetMemcardIndex()+1, value);
} }
break; break;
@ -305,7 +323,7 @@ void SIO_CommandWrite(u8 value,int way) {
//if(value == 0) sio.buf[4] = 0xFF; //if(value == 0) sio.buf[4] = 0xFF;
sio.buf[4] = 0x55; sio.buf[4] = 0x55;
MEMCARDS_LOG("MC(%d) GET TERMINATOR command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) GET TERMINATOR command 0x%02X", sio.GetMemcardIndex()+1, value);
} }
break; break;
// WRITE DATA // WRITE DATA
@ -315,12 +333,12 @@ void SIO_CommandWrite(u8 value,int way) {
memset8_obj<0xff>(sio.buf); memset8_obj<0xff>(sio.buf);
sio.buf[sio.bufcount-1]='+'; sio.buf[sio.bufcount-1]='+';
sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount]=sio.terminator;
MEMCARDS_LOG("MC(%d) WRITE command 0x%02X\n\n\n\n\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) WRITE command 0x%02X\n\n\n\n", sio.GetMemcardIndex()+1, value);
} }
else else
if ((sio.parp>2) && (sio.parp<sio.bufcount-2)) { if ((sio.parp>2) && (sio.parp<sio.bufcount-2)) {
sio.buf[sio.parp]=value; sio.buf[sio.parp]=value;
//MEMCARDS_LOG("MC(%d) WRITING 0x%02X\n", sio.GetMemcardIndex()+1, value); //MEMCARDS_LOG("MC(%d) WRITING 0x%02X", sio.GetMemcardIndex()+1, value);
} else } else
if (sio.parp==sio.bufcount-2) { if (sio.parp==sio.bufcount-2) {
if (sio_xor(&sio.buf[3], sio.bufcount-5)==value) { if (sio_xor(&sio.buf[3], sio.bufcount-5)==value) {
@ -328,7 +346,7 @@ void SIO_CommandWrite(u8 value,int way) {
sio.buf[sio.bufcount-1]=value; sio.buf[sio.bufcount-1]=value;
sio.k+=sio.bufcount-5; sio.k+=sio.bufcount-5;
}else { }else {
MEMCARDS_LOG("MC(%d) write XOR value error 0x%02X != ^0x%02X\n", MEMCARDS_LOG("MC(%d) write XOR value error 0x%02X != ^0x%02X",
sio.GetMemcardIndex()+1, value, sio_xor(&sio.buf[3], sio.bufcount-5)); sio.GetMemcardIndex()+1, value, sio_xor(&sio.buf[3], sio.bufcount-5));
} }
} }
@ -339,7 +357,7 @@ void SIO_CommandWrite(u8 value,int way) {
//int i; //int i;
sio.bufcount=value+5; sio.bufcount=value+5;
sio.buf[3]='+'; sio.buf[3]='+';
MEMCARDS_LOG("MC(%d) READ command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) READ command 0x%02X", sio.GetMemcardIndex()+1, value);
_ReadMcd(&sio.buf[4], (512+16)*sio.sector+sio.k, value); _ReadMcd(&sio.buf[4], (512+16)*sio.sector+sio.k, value);
/*if(sio.mode==2) /*if(sio.mode==2)
{ {
@ -370,14 +388,14 @@ void SIO_CommandWrite(u8 value,int way) {
sio.buf[2]='+'; sio.buf[2]='+';
sio.buf[3]=sio.terminator;*/ sio.buf[3]=sio.terminator;*/
//sio.buf[sio.bufcount] = sio.terminator; //sio.buf[sio.bufcount] = sio.terminator;
MEMCARDS_LOG("MC(%d) INTERNAL ERASE command 0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) INTERNAL ERASE command 0x%02X", sio.GetMemcardIndex()+1, value);
} }
break; break;
// CARD AUTHENTICATION CHECKS // CARD AUTHENTICATION CHECKS
case 0xF0: case 0xF0:
if (sio.parp==2) if (sio.parp==2)
{ {
MEMCARDS_LOG("MC(%d) CARD AUTH :0x%02X\n", sio.GetMemcardIndex()+1, value); MEMCARDS_LOG("MC(%d) CARD AUTH :0x%02X", sio.GetMemcardIndex()+1, value);
switch(value){ switch(value){
case 1: case 1:
case 2: case 2:
@ -419,12 +437,33 @@ void SIO_CommandWrite(u8 value,int way) {
sio.parp = 1; sio.parp = 1;
SIO_INT(); SIO_INT();
switch(value) { switch(value) {
case 0x12: sio.mtapst = 2; sio.bufcount = 5; break; case 0x12:
case 0x13: sio.mtapst = 2; sio.bufcount = 5; break; // Query number of pads supported.
case 0x21: sio.mtapst = 2; sio.bufcount = 6; break; sio.buf[3] = 4;
sio.mtapst = 2;
sio.bufcount = 5;
break;
case 0x13:
// Query number of memcards supported.
sio.buf[3] = 4;
sio.mtapst = 2;
sio.bufcount = 5;
break;
case 0x21:
// Set pad slot.
sio.mtapst = 0x21;
sio.bufcount = 6; // No idea why this is 6, saved from old code.
break;
case 0x22:
// Set memcard slot.
sio.mtapst = 0x22;
sio.bufcount = 6; // No idea why this is 6, saved from old code.
break;
} }
sio.buf[sio.bufcount]='Z'; // These were taken from old code. No idea if they're needed.
// Don't seem to break anything, at least.
sio.buf[sio.bufcount-1]='+'; sio.buf[sio.bufcount-1]='+';
sio.buf[sio.bufcount]='Z';
return; return;
case 0x2: case 0x2:
sio.packetsize++; sio.packetsize++;
@ -432,6 +471,44 @@ void SIO_CommandWrite(u8 value,int way) {
if (sio.bufcount<=sio.parp) sio.mcdst = 0; if (sio.bufcount<=sio.parp) sio.mcdst = 0;
SIO_INT(); SIO_INT();
return; return;
case 0x21:
// Set pad slot.
sio.packetsize++;
sio.parp++;
sio.mtapst = 2;
switch (sio.CtrlReg&0x2002) {
case 0x0002:
// Not sure if these checks are absolutely needed, but
// prefer to be safe.
if (IsMtapPresent(1))
sio.activePadSlot[0] = value;
break;
case 0x2002:
if (IsMtapPresent(2))
sio.activePadSlot[1] = value;
break;
}
SIO_INT();
return;
case 0x22:
// Set memcard slot.
sio.packetsize++;
sio.parp++;
sio.mtapst = 2;
switch (sio.CtrlReg&0x2002) {
case 0x0002:
// Not sure if these checks are absolutely needed, but
// prefer to be safe.
if (IsMtapPresent(1))
sio.activeMemcardSlot[0] = value;
break;
case 0x2002:
if (IsMtapPresent(2))
sio.activeMemcardSlot[1] = value;
break;
}
SIO_INT();
return;
} }
if(sio.count == 1 || way == 0) InitializeSIO(value); if(sio.count == 1 || way == 0) InitializeSIO(value);
@ -444,17 +521,36 @@ void InitializeSIO(u8 value)
sio.StatReg &= ~TX_EMPTY; // Now the Buffer is not empty sio.StatReg &= ~TX_EMPTY; // Now the Buffer is not empty
sio.StatReg |= RX_RDY; // Transfer is Ready sio.StatReg |= RX_RDY; // Transfer is Ready
switch (sio.CtrlReg&0x2002) {
case 0x0002: sio.buf[0] = PAD1startPoll(1); break;
case 0x2002: sio.buf[0] = PAD2startPoll(2); break;
}
sio.bufcount = 2; sio.bufcount = 2;
sio.parp = 0; sio.parp = 0;
sio.padst = 1; sio.padst = 1;
sio.packetsize = 1; sio.packetsize = 1;
sio.count = 0; sio.count = 0;
sio2.packet.recvVal1 = 0x1100; // Pad is present sio2.packet.recvVal1 = 0x1100; // Pad is present
switch (sio.CtrlReg&0x2002) {
case 0x0002:
if (!PAD1setSlot(1, 1+sio.activePadSlot[0])) {
// Pad is not present. Don't send poll, just return a bunch of 0's.
sio2.packet.recvVal1 = 0x1D100;
sio.padst = 3;
}
else {
sio.buf[0] = PAD1startPoll(1);
}
break;
case 0x2002:
if (!PAD2setSlot(1, 1+sio.activePadSlot[1])) {
// Pad is not present. Don't send poll, just return a bunch of 0's.
sio2.packet.recvVal1 = 0x1D100;
sio.padst = 3;
}
else {
sio.buf[0] = PAD2startPoll(2);
}
break;
}
SIO_INT(); SIO_INT();
return; return;
@ -465,7 +561,35 @@ void InitializeSIO(u8 value)
sio.packetsize = 1; sio.packetsize = 1;
sio.mtapst = 1; sio.mtapst = 1;
sio.count = 0; sio.count = 0;
sio2.packet.recvVal1 = 0x1D100; // Mtap is not connected :) sio2.packet.recvVal1 = 0x1D100; // Mtap is not connected :(
switch (sio.CtrlReg&0x2002) {
case 0x0002:
if (!IsMtapPresent(1)) {
// If "unplug" multitap, set slots to 0.
sio.activePadSlot[0] = 0;
sio.activeMemcardSlot[0] = 0;
break;
}
sio.bufcount = 3;
sio.buf[0] = 0xFF;
sio.buf[1] = 0x80; // Have no idea if this is correct. From PSX mtap.
sio.buf[2] = 0x5A;
sio2.packet.recvVal1 = 0x1100; // Mtap is connected :)
break;
case 0x2002:
if (!IsMtapPresent(2)) {
// If "unplug" multitap, set slots to 0.
sio.activePadSlot[1] = 0;
sio.activeMemcardSlot[1] = 0;
break;
}
sio.bufcount = 3;
sio.buf[0] = 0xFF;
sio.buf[1] = 0x80; // Have no idea if this is correct. From PSX mtap.
sio.buf[2] = 0x5A;
sio2.packet.recvVal1 = 0x1100; // Mtap is connected :)
break;
}
SIO_INT(); SIO_INT();
return; return;
@ -502,16 +626,24 @@ void InitializeSIO(u8 value)
const int mcidx = sio.GetMemcardIndex(); const int mcidx = sio.GetMemcardIndex();
if( m_PostSavestateCards[mcidx] ) if( sio.activeMemcardSlot[mcidx] )
{
// Might want to more agressively declare a card's non-existence here.
// As non-zero slots always report a failure, and have to read
// the FAT before writing, think this should be fine.
sio2.packet.recvVal1 = 0x1D100;
PAD_LOG( "START MEMCARD[%d][%d] - Only one memcard supported per slot - reported as missing.", sio.GetMemcardIndex(), sio.activeMemcardSlot[mcidx]);
}
else if( m_PostSavestateCards[mcidx] )
{ {
m_PostSavestateCards[mcidx]--; m_PostSavestateCards[mcidx]--;
sio2.packet.recvVal1 = 0x1D100; sio2.packet.recvVal1 = 0x1D100;
PAD_LOG( "START MEMCARD[%d] - post-savestate ejection - reported as missing!\n", sio.GetMemcardIndex() ); PAD_LOG( "START MEMCARD[%d] - post-savestate ejection - reported as missing!", sio.GetMemcardIndex() );
} }
else else
{ {
sio2.packet.recvVal1 = MemoryCard::IsPresent( sio.GetMemcardIndex() ) ? 0x1100 : 0x1D100; sio2.packet.recvVal1 = MemoryCard::IsPresent( sio.GetMemcardIndex() ) ? 0x1100 : 0x1D100;
PAD_LOG("START MEMCARD [%d] - %s\n", PAD_LOG("START MEMCARD [%d] - %s",
sio.GetMemcardIndex(), MemoryCard::IsPresent( sio.GetMemcardIndex() ) ? "Present" : "Missing" ); sio.GetMemcardIndex(), MemoryCard::IsPresent( sio.GetMemcardIndex() ) ? "Present" : "Missing" );
} }
@ -543,7 +675,7 @@ void sioWriteCtrl16(u16 value) {
} }
void SIO_FORCEINLINE sioInterrupt() { void SIO_FORCEINLINE sioInterrupt() {
PAD_LOG("Sio Interrupt\n"); PAD_LOG("Sio Interrupt");
sio.StatReg|= IRQ; sio.StatReg|= IRQ;
psxHu32(0x1070)|=0x80; psxHu32(0x1070)|=0x80;
} }
@ -567,7 +699,14 @@ void SaveState::sioFreeze()
u64 m_mcdCRCs[2]; u64 m_mcdCRCs[2];
FreezeTag( "sio" ); FreezeTag( "sio" );
Freeze( sio ); if (GetVersion() == 0) {
FreezeMem( &sio, sizeof( sio ) - 4);
memset(sio.activePadSlot, 0, sizeof(sio.activePadSlot));
memset(sio.activeMemcardSlot, 0, sizeof(sio.activeMemcardSlot));
}
else {
Freeze( sio );
}
if( IsSaving() ) if( IsSaving() )
{ {

View File

@ -61,6 +61,11 @@ struct _sio {
u32 k; u32 k;
u32 count; u32 count;
// Active pad slot for each port. Not sure if these automatically reset after each read or not.
u8 activePadSlot[2];
// Active memcard slot for each port. Not sure if these automatically reset after each read or not.
u8 activeMemcardSlot[2];
int GetMemcardIndex() const int GetMemcardIndex() const
{ {
return (CtrlReg&0x2000) >> 13; return (CtrlReg&0x2000) >> 13;

View File

@ -76,6 +76,7 @@ void __Log( const char* fmt, ... )
else if( emuLog != NULL ) // manually write to the logfile. else if( emuLog != NULL ) // manually write to the logfile.
{ {
fputs( tmp, emuLog ); fputs( tmp, emuLog );
fputs( "\n", emuLog );
//fputs( "\r\n", emuLog ); //fputs( "\r\n", emuLog );
fflush( emuLog ); fflush( emuLog );
} }
@ -113,7 +114,7 @@ static __forceinline void _vSourceLog( u16 protocol, u8 source, u32 cpuPc, u32 c
} else if( emuLog != NULL ) // manually write to the logfile. } else if( emuLog != NULL ) // manually write to the logfile.
{ {
fputs( tmp, emuLog ); fputs( tmp, emuLog );
//fputs( "\r\n", emuLog ); fputs( "\n", emuLog );
fflush( emuLog ); fflush( emuLog );
} }
#endif #endif

View File

@ -44,7 +44,7 @@ void statsClose() {
#else #else
f = fopen(LOGS_DIR "/stats.txt", "w"); f = fopen(LOGS_DIR "/stats.txt", "w");
#endif #endif
if (!f) { SysPrintf("Can't open stats.txt\n"); return; } if (!f) { Console::WriteLn("Can't open stats.txt"); return; }
fprintf(f, "-- PCSX2 v%s statics--\n\n", PCSX2_VERSION); fprintf(f, "-- PCSX2 v%s statics--\n\n", PCSX2_VERSION);
fprintf(f, "Ran for %d seconds\n", t); fprintf(f, "Ran for %d seconds\n", t);
fprintf(f, "Total VSyncs: %d (%s)\n", stats.vsyncCount, Config.PsxType ? "PAL" : "NTSC"); fprintf(f, "Total VSyncs: %d (%s)\n", stats.vsyncCount, Config.PsxType ? "PAL" : "NTSC");

View File

@ -62,7 +62,7 @@ void COP2_SPECIAL2() {
void COP2_Unknown() void COP2_Unknown()
{ {
CPU_LOG("Unknown COP2 opcode called\n"); CPU_LOG("Unknown COP2 opcode called");
} }
//**************************************************************************** //****************************************************************************
@ -165,14 +165,14 @@ void CTC2() {
Console::Error("fixme: VU0 Force Break"); Console::Error("fixme: VU0 Force Break");
} }
if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x2) { // VU0 Reset if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x2) { // VU0 Reset
//SysPrintf("fixme: VU0 Reset\n"); //Console::WriteLn("fixme: VU0 Reset");
vu0ResetRegs(); vu0ResetRegs();
} }
if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x100) { // VU1 Force Break if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x100) { // VU1 Force Break
Console::Error("fixme: VU1 Force Break"); Console::Error("fixme: VU1 Force Break");
} }
if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x200) { // VU1 Reset if (cpuRegs.GPR.r[_Rt_].UL[0] & 0x200) { // VU1 Reset
// SysPrintf("fixme: VU1 Reset\n"); // Console::WriteLn("fixme: VU1 Reset");
vu1ResetRegs(); vu1ResetRegs();
} }
break; break;

View File

@ -73,7 +73,7 @@ void VU0MI_XTOP() {
} }
void vu0ExecMicro(u32 addr) { void vu0ExecMicro(u32 addr) {
VUM_LOG("vu0ExecMicro %x\n", addr); VUM_LOG("vu0ExecMicro %x", addr);
if(VU0.VI[REG_VPU_STAT].UL & 0x1) { if(VU0.VI[REG_VPU_STAT].UL & 0x1) {
DevCon::Notice("vu0ExecMicro > Stalling for previous microprogram to finish"); DevCon::Notice("vu0ExecMicro > Stalling for previous microprogram to finish");
@ -95,13 +95,13 @@ void vu0ExecMicro(u32 addr) {
void VU0unknown() { void VU0unknown() {
assert(0); assert(0);
CPU_LOG("Unknown VU micromode opcode called\n"); CPU_LOG("Unknown VU micromode opcode called");
} }
void VU0regsunknown(_VURegsNum *VUregsn) { void VU0regsunknown(_VURegsNum *VUregsn) {
assert(0); assert(0);
CPU_LOG("Unknown VU micromode opcode called\n"); CPU_LOG("Unknown VU micromode opcode called");
} }
_vuRegsTables(VU0, VU0regs); _vuRegsTables(VU0, VU0regs);

View File

@ -54,7 +54,7 @@ static void _vu0Exec(VURegs* VU)
if(VU0.VI[REG_TPC].UL >= VU0.maxmicro){ if(VU0.VI[REG_TPC].UL >= VU0.maxmicro){
#ifdef CPU_LOG #ifdef CPU_LOG
SysPrintf("VU0 memory overflow!!: %x\n", VU->VI[REG_TPC].UL); Console::WriteLn("VU0 memory overflow!!: %x", params VU->VI[REG_TPC].UL);
#endif #endif
VU0.VI[REG_VPU_STAT].UL&= ~0x1; VU0.VI[REG_VPU_STAT].UL&= ~0x1;
VU->cycle++; VU->cycle++;
@ -69,7 +69,7 @@ static void _vu0Exec(VURegs* VU)
} }
if (ptr[1] & 0x20000000) { /* M flag */ if (ptr[1] & 0x20000000) { /* M flag */
VU->flags|= VUFLAG_MFLAGSET; VU->flags|= VUFLAG_MFLAGSET;
// SysPrintf("fixme: M flag set\n"); // Console::WriteLn("fixme: M flag set");
} }
if (ptr[1] & 0x10000000) { /* D flag */ if (ptr[1] & 0x10000000) { /* D flag */
if (VU0.VI[REG_FBRST].UL & 0x4) { if (VU0.VI[REG_FBRST].UL & 0x4) {
@ -108,19 +108,19 @@ static void _vu0Exec(VURegs* VU)
vfreg = 0; vireg = 0; vfreg = 0; vireg = 0;
if (uregs.VFwrite) { if (uregs.VFwrite) {
if (lregs.VFwrite == uregs.VFwrite) { if (lregs.VFwrite == uregs.VFwrite) {
// SysPrintf("*PCSX2*: Warning, VF write to the same reg in both lower/upper cycle\n"); // Console::Notice("*PCSX2*: Warning, VF write to the same reg in both lower/upper cycle");
discard = 1; discard = 1;
} }
if (lregs.VFread0 == uregs.VFwrite || if (lregs.VFread0 == uregs.VFwrite ||
lregs.VFread1 == uregs.VFwrite) { lregs.VFread1 == uregs.VFwrite) {
// SysPrintf("saving reg %d at pc=%x\n", i, VU->VI[REG_TPC].UL); // Console::WriteLn("saving reg %d at pc=%x", params i, VU->VI[REG_TPC].UL);
_VF = VU->VF[uregs.VFwrite]; _VF = VU->VF[uregs.VFwrite];
vfreg = uregs.VFwrite; vfreg = uregs.VFwrite;
} }
} }
if (uregs.VIread & (1 << REG_CLIP_FLAG)) { if (uregs.VIread & (1 << REG_CLIP_FLAG)) {
if (lregs.VIwrite & (1 << REG_CLIP_FLAG)) { if (lregs.VIwrite & (1 << REG_CLIP_FLAG)) {
SysPrintf("*PCSX2*: Warning, VI write to the same reg in both lower/upper cycle\n"); Console::Notice("*PCSX2*: Warning, VI write to the same reg in both lower/upper cycle");
discard = 1; discard = 1;
} }
if (lregs.VIread & (1 << REG_CLIP_FLAG)) { if (lregs.VIread & (1 << REG_CLIP_FLAG)) {
@ -178,7 +178,7 @@ void vu0Exec(VURegs* VU)
{ {
if (VU->VI[REG_TPC].UL >= VU->maxmicro) { if (VU->VI[REG_TPC].UL >= VU->maxmicro) {
#ifdef CPU_LOG #ifdef CPU_LOG
SysPrintf("VU0 memory overflow!!: %x\n", VU->VI[REG_TPC].UL); Console::Notice("VU0 memory overflow!!: %x", params VU->VI[REG_TPC].UL);
#endif #endif
VU0.VI[REG_VPU_STAT].UL&= ~0x1; VU0.VI[REG_VPU_STAT].UL&= ~0x1;
} else { } else {

View File

@ -77,8 +77,8 @@ void vu1ExecMicro(u32 addr)
CpuVU1.ExecuteBlock(); CpuVU1.ExecuteBlock();
} }
VUM_LOG("vu1ExecMicro %x\n", addr); VUM_LOG("vu1ExecMicro %x", addr);
VUM_LOG("vu1ExecMicro %x (count=%d)\n", addr, count++); VUM_LOG("vu1ExecMicro %x (count=%d)", addr, count++);
VU0.VI[REG_VPU_STAT].UL|= 0x100; VU0.VI[REG_VPU_STAT].UL|= 0x100;
VU0.VI[REG_VPU_STAT].UL&= ~0x7E000; VU0.VI[REG_VPU_STAT].UL&= ~0x7E000;
@ -93,12 +93,12 @@ _vuRegsTables(VU1, VU1regs);
void VU1unknown() { void VU1unknown() {
//assert(0); //assert(0);
CPU_LOG("Unknown VU micromode opcode called\n"); CPU_LOG("Unknown VU micromode opcode called");
} }
void VU1regsunknown(_VURegsNum *VUregsn) { void VU1regsunknown(_VURegsNum *VUregsn) {
//assert(0); //assert(0);
CPU_LOG("Unknown VU micromode opcode called\n"); CPU_LOG("Unknown VU micromode opcode called");
} }

View File

@ -54,7 +54,7 @@ static void _vu1Exec(VURegs* VU)
int discard=0; int discard=0;
if(VU->VI[REG_TPC].UL >= VU->maxmicro){ if(VU->VI[REG_TPC].UL >= VU->maxmicro){
CPU_LOG("VU1 memory overflow!!: %x\n", VU->VI[REG_TPC].UL); CPU_LOG("VU1 memory overflow!!: %x", VU->VI[REG_TPC].UL);
VU->VI[REG_TPC].UL &= 0x3FFF; VU->VI[REG_TPC].UL &= 0x3FFF;
/*VU0.VI[REG_VPU_STAT].UL&= ~0x100; /*VU0.VI[REG_VPU_STAT].UL&= ~0x100;
VU->cycle++; VU->cycle++;
@ -79,7 +79,7 @@ static void _vu1Exec(VURegs* VU)
} }
} }
VUM_LOG("VU->cycle = %d (flags st=%x;mac=%x;clip=%x,q=%f)\n", VU->cycle, VU->statusflag, VU->macflag, VU->clipflag, VU->q.F); VUM_LOG("VU->cycle = %d (flags st=%x;mac=%x;clip=%x,q=%f)", VU->cycle, VU->statusflag, VU->macflag, VU->clipflag, VU->q.F);
VU->code = ptr[1]; VU->code = ptr[1];
VU1regs_UPPER_OPCODE[VU->code & 0x3f](&uregs); VU1regs_UPPER_OPCODE[VU->code & 0x3f](&uregs);
@ -104,19 +104,19 @@ static void _vu1Exec(VURegs* VU)
vfreg = 0; vireg = 0; vfreg = 0; vireg = 0;
if (uregs.VFwrite) { if (uregs.VFwrite) {
if (lregs.VFwrite == uregs.VFwrite) { if (lregs.VFwrite == uregs.VFwrite) {
// SysPrintf("*PCSX2*: Warning, VF write to the same reg in both lower/upper cycle\n"); // Console::Notice("*PCSX2*: Warning, VF write to the same reg in both lower/upper cycle");
discard = 1; discard = 1;
} }
if (lregs.VFread0 == uregs.VFwrite || if (lregs.VFread0 == uregs.VFwrite ||
lregs.VFread1 == uregs.VFwrite) { lregs.VFread1 == uregs.VFwrite) {
// SysPrintf("saving reg %d at pc=%x\n", i, VU->VI[REG_TPC].UL); // Console::WriteLn("saving reg %d at pc=%x", params i, VU->VI[REG_TPC].UL);
_VF = VU->VF[uregs.VFwrite]; _VF = VU->VF[uregs.VFwrite];
vfreg = uregs.VFwrite; vfreg = uregs.VFwrite;
} }
} }
if (uregs.VIread & (1 << REG_CLIP_FLAG)) { if (uregs.VIread & (1 << REG_CLIP_FLAG)) {
if (lregs.VIwrite & (1 << REG_CLIP_FLAG)) { if (lregs.VIwrite & (1 << REG_CLIP_FLAG)) {
SysPrintf("*PCSX2*: Warning, VI write to the same reg in both lower/upper cycle\n"); Console::Notice("*PCSX2*: Warning, VI write to the same reg in both lower/upper cycle");
discard = 1; discard = 1;
} }
if (lregs.VIread & (1 << REG_CLIP_FLAG)) { if (lregs.VIread & (1 << REG_CLIP_FLAG)) {

View File

@ -1290,9 +1290,9 @@ void (*PREFIX##_LOWER_OPCODE[128])(_VURegsNum *VUregsn) = { \
#ifdef VUM_LOG #ifdef VUM_LOG
#define IdebugUPPER(VU) \ #define IdebugUPPER(VU) \
VUM_LOG("%s\n", dis##VU##MicroUF(VU.code, VU.VI[REG_TPC].UL)); VUM_LOG("%s", dis##VU##MicroUF(VU.code, VU.VI[REG_TPC].UL));
#define IdebugLOWER(VU) \ #define IdebugLOWER(VU) \
VUM_LOG("%s\n", dis##VU##MicroLF(VU.code, VU.VI[REG_TPC].UL)); VUM_LOG("%s", dis##VU##MicroLF(VU.code, VU.VI[REG_TPC].UL));
#else #else
@ -1303,7 +1303,7 @@ void (*PREFIX##_LOWER_OPCODE[128])(_VURegsNum *VUregsn) = { \
#ifdef VUM_LOG #ifdef VUM_LOG
#define _vuExecMicroDebug(VU) \ #define _vuExecMicroDebug(VU) \
VUM_LOG("_vuExecMicro: %8.8x\n", VU.VI[REG_TPC].UL); VUM_LOG("_vuExecMicro: %8.8x", VU.VI[REG_TPC].UL);
#else #else
#define _vuExecMicroDebug(VU) #define _vuExecMicroDebug(VU)
#endif #endif

View File

@ -54,7 +54,7 @@ void _vuFMACflush(VURegs * VU) {
if (VU->fmac[i].enable == 0) continue; if (VU->fmac[i].enable == 0) continue;
if ((VU->cycle - VU->fmac[i].sCycle) >= VU->fmac[i].Cycle) { if ((VU->cycle - VU->fmac[i].sCycle) >= VU->fmac[i].Cycle) {
VUM_LOG("flushing FMAC pipe[%d] (macflag=%x)\n", i, VU->fmac[i].macflag); VUM_LOG("flushing FMAC pipe[%d] (macflag=%x)", i, VU->fmac[i].macflag);
VU->fmac[i].enable = 0; VU->fmac[i].enable = 0;
VU->VI[REG_MAC_FLAG].UL = VU->fmac[i].macflag; VU->VI[REG_MAC_FLAG].UL = VU->fmac[i].macflag;
@ -68,7 +68,7 @@ void _vuFDIVflush(VURegs * VU) {
if (VU->fdiv.enable == 0) return; if (VU->fdiv.enable == 0) return;
if ((VU->cycle - VU->fdiv.sCycle) >= VU->fdiv.Cycle) { if ((VU->cycle - VU->fdiv.sCycle) >= VU->fdiv.Cycle) {
VUM_LOG("flushing FDIV pipe\n"); VUM_LOG("flushing FDIV pipe");
VU->fdiv.enable = 0; VU->fdiv.enable = 0;
VU->VI[REG_Q].UL = VU->fdiv.reg.UL; VU->VI[REG_Q].UL = VU->fdiv.reg.UL;
@ -80,7 +80,7 @@ void _vuEFUflush(VURegs * VU) {
if (VU->efu.enable == 0) return; if (VU->efu.enable == 0) return;
if ((VU->cycle - VU->efu.sCycle) >= VU->efu.Cycle) { if ((VU->cycle - VU->efu.sCycle) >= VU->efu.Cycle) {
// VUM_LOG("flushing EFU pipe\n"); // VUM_LOG("flushing EFU pipe");
VU->efu.enable = 0; VU->efu.enable = 0;
VU->VI[REG_P].UL = VU->efu.reg.UL; VU->VI[REG_P].UL = VU->efu.reg.UL;
@ -101,7 +101,7 @@ void _vuFlushAll(VURegs* VU)
nRepeat = 1; nRepeat = 1;
if ((VU->cycle - VU->fmac[i].sCycle) >= VU->fmac[i].Cycle) { if ((VU->cycle - VU->fmac[i].sCycle) >= VU->fmac[i].Cycle) {
VUM_LOG("flushing FMAC pipe[%d] (macflag=%x)\n", i, VU->fmac[i].macflag); VUM_LOG("flushing FMAC pipe[%d] (macflag=%x)", i, VU->fmac[i].macflag);
VU->fmac[i].enable = 0; VU->fmac[i].enable = 0;
VU->VI[REG_MAC_FLAG].UL = VU->fmac[i].macflag; VU->VI[REG_MAC_FLAG].UL = VU->fmac[i].macflag;
@ -115,7 +115,7 @@ void _vuFlushAll(VURegs* VU)
nRepeat = 1; nRepeat = 1;
if ((VU->cycle - VU->fdiv.sCycle) >= VU->fdiv.Cycle) { if ((VU->cycle - VU->fdiv.sCycle) >= VU->fdiv.Cycle) {
VUM_LOG("flushing FDIV pipe\n"); VUM_LOG("flushing FDIV pipe");
nRepeat = 1; nRepeat = 1;
VU->fdiv.enable = 0; VU->fdiv.enable = 0;
@ -129,7 +129,7 @@ void _vuFlushAll(VURegs* VU)
nRepeat = 1; nRepeat = 1;
if ((VU->cycle - VU->efu.sCycle) >= VU->efu.Cycle) { if ((VU->cycle - VU->efu.sCycle) >= VU->efu.Cycle) {
// VUM_LOG("flushing EFU pipe\n"); // VUM_LOG("flushing EFU pipe");
nRepeat = 1; nRepeat = 1;
VU->efu.enable = 0; VU->efu.enable = 0;
@ -165,7 +165,7 @@ void _vuFMACTestStall(VURegs * VU, int reg, int xyzw) {
VU->VI[REG_MAC_FLAG].UL = VU->fmac[i].macflag; VU->VI[REG_MAC_FLAG].UL = VU->fmac[i].macflag;
VU->VI[REG_STATUS_FLAG].UL = VU->fmac[i].statusflag; VU->VI[REG_STATUS_FLAG].UL = VU->fmac[i].statusflag;
VU->VI[REG_CLIP_FLAG].UL = VU->fmac[i].clipflag; VU->VI[REG_CLIP_FLAG].UL = VU->fmac[i].clipflag;
VUM_LOG("FMAC[%d] stall %d\n", i, cycle); VUM_LOG("FMAC[%d] stall %d", i, cycle);
VU->cycle+= cycle; VU->cycle+= cycle;
_vuTestPipes(VU); _vuTestPipes(VU);
@ -179,11 +179,10 @@ void _vuFMACAdd(VURegs * VU, int reg, int xyzw) {
if (VU->fmac[i].enable == 1) continue; if (VU->fmac[i].enable == 1) continue;
break; break;
} }
if (i==8) { //if (i==8) Console::Error("*PCSX2*: error , out of fmacs %d", params VU->cycle);
// SysPrintf("*PCSX2*: error , out of fmacs %d\n", VU->cycle);
}
VUM_LOG("adding FMAC pipe[%d]; xyzw=%x\n", i, xyzw);
VUM_LOG("adding FMAC pipe[%d]; xyzw=%x", i, xyzw);
VU->fmac[i].enable = 1; VU->fmac[i].enable = 1;
VU->fmac[i].sCycle = VU->cycle; VU->fmac[i].sCycle = VU->cycle;
@ -196,7 +195,7 @@ void _vuFMACAdd(VURegs * VU, int reg, int xyzw) {
} }
void _vuFDIVAdd(VURegs * VU, int cycles) { void _vuFDIVAdd(VURegs * VU, int cycles) {
VUM_LOG("adding FDIV pipe\n"); VUM_LOG("adding FDIV pipe");
VU->fdiv.enable = 1; VU->fdiv.enable = 1;
VU->fdiv.sCycle = VU->cycle; VU->fdiv.sCycle = VU->cycle;
@ -220,7 +219,7 @@ void _vuFlushFDIV(VURegs * VU) {
if (VU->fdiv.enable == 0) return; if (VU->fdiv.enable == 0) return;
cycle = VU->fdiv.Cycle - (VU->cycle - VU->fdiv.sCycle); cycle = VU->fdiv.Cycle - (VU->cycle - VU->fdiv.sCycle);
VUM_LOG("waiting FDIV pipe %d\n", cycle); VUM_LOG("waiting FDIV pipe %d", cycle);
VU->fdiv.enable = 0; VU->fdiv.enable = 0;
VU->cycle+= cycle; VU->cycle+= cycle;
@ -234,7 +233,7 @@ void _vuFlushEFU(VURegs * VU) {
if (VU->efu.enable == 0) return; if (VU->efu.enable == 0) return;
cycle = VU->efu.Cycle - (VU->cycle - VU->efu.sCycle); cycle = VU->efu.Cycle - (VU->cycle - VU->efu.sCycle);
// VUM_LOG("waiting EFU pipe %d\n", cycle); // VUM_LOG("waiting EFU pipe %d", cycle);
VU->efu.enable = 0; VU->efu.enable = 0;
VU->cycle+= cycle; VU->cycle+= cycle;
@ -317,7 +316,6 @@ void _vuAddLowerStalls(VURegs * VU, _VURegsNum *VUregsn) {
/* VU Upper instructions */ /* VU Upper instructions */
/******************************/ /******************************/
#ifndef INT_VUDOUBLEHACK #ifndef INT_VUDOUBLEHACK
static u32 d;
float vuDouble(u32 f) float vuDouble(u32 f)
{ {
switch(f & 0x7f800000){ switch(f & 0x7f800000){
@ -326,9 +324,12 @@ float vuDouble(u32 f)
return *(float*)&f; return *(float*)&f;
break; break;
case 0x7f800000: case 0x7f800000:
{
u32 d;
d = (f & 0x80000000)|0x7f7fffff; d = (f & 0x80000000)|0x7f7fffff;
return *(float*)&d; return *(float*)&d;
break; break;
}
default: default:
return *(float*)&f; return *(float*)&f;
break; break;
@ -2719,7 +2720,7 @@ void _vuRegsFSSET(VURegs * VU, _VURegsNum *VUregsn) {
VUregsn->VFread0 = 0; VUregsn->VFread0 = 0;
VUregsn->VFread1 = 0; VUregsn->VFread1 = 0;
VUregsn->VIwrite = 1 << REG_STATUS_FLAG; VUregsn->VIwrite = 1 << REG_STATUS_FLAG;
VUregsn->VIread = 0;//1 << REG_STATUS_FLAG; this kills speed VUregsn->VIread = 0;
} }
void _vuRegsFMAND(VURegs * VU, _VURegsNum *VUregsn) { void _vuRegsFMAND(VURegs * VU, _VURegsNum *VUregsn) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -34,9 +34,12 @@ struct vifStruct {
int cl; int cl;
int wl; int wl;
u8 usn; u8 usn;
// The next three should be boolean, and will be next time I break savestate compatability. --arcum42
u8 done; u8 done;
u8 vifstalled; u8 vifstalled;
u8 stallontag; u8 stallontag;
u8 irqoffset; // 32bit offset where next vif code is u8 irqoffset; // 32bit offset where next vif code is
u32 savedtag; // need this for backwards compat with save states u32 savedtag; // need this for backwards compat with save states
u32 vifpacketsize; u32 vifpacketsize;
@ -45,7 +48,7 @@ struct vifStruct {
}; };
extern vifStruct vif0, vif1; extern vifStruct vif0, vif1;
extern int Path3transfer; extern bool Path3transfer;
#define vif0ch ((DMACh*)&PS2MEM_HW[0x8000]) #define vif0ch ((DMACh*)&PS2MEM_HW[0x8000])
#define vif1ch ((DMACh*)&PS2MEM_HW[0x9000]) #define vif1ch ((DMACh*)&PS2MEM_HW[0x9000])

View File

@ -1,5 +1,5 @@
AC_INIT(pcsx2,0.9.5,zerofrog@gmail.com) AC_INIT(pcsx2,0.9.6,zerofrog@gmail.com)
AM_INIT_AUTOMAKE(pcsx2,0.9.5) AM_INIT_AUTOMAKE(pcsx2,0.9.6)
AC_PROG_CC([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) AC_PROG_CC([gcc g++ cl KCC CC cxx cc++ xlC aCC c++])
AC_PROG_CXX([gcc g++ cl KCC CC cxx cc++ xlC aCC c++]) AC_PROG_CXX([gcc g++ cl KCC CC cxx cc++ xlC aCC c++])

View File

@ -104,7 +104,7 @@ __forceinline DataType __fastcall MemOp_r0(u32 addr)
//has to: translate, find function, call function //has to: translate, find function, call function
u32 hand=(u8)vmv; u32 hand=(u8)vmv;
u32 paddr=ppf-hand+0x80000000; u32 paddr=ppf-hand+0x80000000;
//SysPrintf("Translated 0x%08X to 0x%08X\n",addr,paddr); //Console::WriteLn("Translated 0x%08X to 0x%08X",params addr,paddr);
//return reinterpret_cast<TemplateHelper<DataSize,false>::HandlerType*>(vtlbdata.RWFT[TemplateHelper<DataSize,false>::sidx][0][hand])(paddr,data); //return reinterpret_cast<TemplateHelper<DataSize,false>::HandlerType*>(vtlbdata.RWFT[TemplateHelper<DataSize,false>::sidx][0][hand])(paddr,data);
switch( DataSize ) switch( DataSize )
@ -135,7 +135,7 @@ __forceinline void __fastcall MemOp_r1(u32 addr, DataType* data)
//has to: translate, find function, call function //has to: translate, find function, call function
u32 hand=(u8)vmv; u32 hand=(u8)vmv;
u32 paddr=ppf-hand+0x80000000; u32 paddr=ppf-hand+0x80000000;
//SysPrintf("Translated 0x%08X to 0x%08X\n",addr,paddr); //Console::WriteLn("Translated 0x%08X to 0x%08X",params addr,paddr);
//return reinterpret_cast<TemplateHelper<DataSize,false>::HandlerType*>(RWFT[TemplateHelper<DataSize,false>::sidx][0][hand])(paddr,data); //return reinterpret_cast<TemplateHelper<DataSize,false>::HandlerType*>(RWFT[TemplateHelper<DataSize,false>::sidx][0][hand])(paddr,data);
switch( DataSize ) switch( DataSize )
@ -162,7 +162,7 @@ __forceinline void __fastcall MemOp_w0(u32 addr, DataType data)
//has to: translate, find function, call function //has to: translate, find function, call function
u32 hand=(u8)vmv; u32 hand=(u8)vmv;
u32 paddr=ppf-hand+0x80000000; u32 paddr=ppf-hand+0x80000000;
//SysPrintf("Translated 0x%08X to 0x%08X\n",addr,paddr); //Console::WriteLn("Translated 0x%08X to 0x%08X",params addr,paddr);
switch( DataSize ) switch( DataSize )
{ {
@ -191,7 +191,7 @@ __forceinline void __fastcall MemOp_w1(u32 addr,const DataType* data)
//has to: translate, find function, call function //has to: translate, find function, call function
u32 hand=(u8)vmv; u32 hand=(u8)vmv;
u32 paddr=ppf-hand+0x80000000; u32 paddr=ppf-hand+0x80000000;
//SysPrintf("Translated 0x%08X to 0x%08X\n",addr,paddr); //Console::WriteLn("Translated 0x%08X to 0x%08X",params addr,paddr);
switch( DataSize ) switch( DataSize )
{ {
case 64: return ((vtlbMemW64FP*)vtlbdata.RWFT[3][1][hand])(paddr, data); case 64: return ((vtlbMemW64FP*)vtlbdata.RWFT[3][1][hand])(paddr, data);

View File

@ -20,8 +20,9 @@
<Configurations> <Configurations>
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1" ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;..\..\..\common\vsprops\BaseProperties.vsprops;..\..\..\common\vsprops\3rdpartyDeps.vsprops;.\vsprops\debug.vsprops;.\vsprops\devbuild.vsprops;..\..\..\common\vsprops\pthreads.vsprops" InheritedPropertySheets=".\vsprops\common.vsprops;..\..\..\common\vsprops\BaseProperties.vsprops;..\..\..\common\vsprops\3rdpartyDeps.vsprops;.\vsprops\debug.vsprops;.\vsprops\devbuild.vsprops;..\..\..\common\vsprops\pthreads.vsprops;..\..\..\common\vsprops\IncrementalLinking.vsprops"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false" ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2" CharacterSet="2"
@ -52,10 +53,8 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
MinimalRebuild="true"
ExceptionHandling="2" ExceptionHandling="2"
SmallerTypeCheck="false" SmallerTypeCheck="false"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2" UsePrecompiledHeader="2"
PrecompiledHeaderThrough="PrecompiledHeader.h" PrecompiledHeaderThrough="PrecompiledHeader.h"
PrecompiledHeaderFile="$(IntDir)\$(TargetName).pch" PrecompiledHeaderFile="$(IntDir)\$(TargetName).pch"
@ -75,7 +74,6 @@
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="zlib.lib rpcrt4.lib" AdditionalDependencies="zlib.lib rpcrt4.lib"
OutputFile="$(OutDir)\$(ProjectName)-dbg.exe" OutputFile="$(OutDir)\$(ProjectName)-dbg.exe"
LinkIncremental="2"
/> />
<Tool <Tool
Name="VCALinkTool" Name="VCALinkTool"
@ -102,7 +100,7 @@
<Configuration <Configuration
Name="Devel|Win32" Name="Devel|Win32"
ConfigurationType="1" ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;..\..\..\common\vsprops\BaseProperties.vsprops;..\..\..\common\vsprops\3rdpartyDeps.vsprops;.\vsprops\devbuild.vsprops;..\..\..\common\vsprops\pthreads.vsprops" InheritedPropertySheets=".\vsprops\common.vsprops;..\..\..\common\vsprops\BaseProperties.vsprops;..\..\..\common\vsprops\3rdpartyDeps.vsprops;.\vsprops\devbuild.vsprops;..\..\..\common\vsprops\pthreads.vsprops;..\..\..\common\vsprops\IncrementalLinking.vsprops"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false" ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2" CharacterSet="2"
@ -134,9 +132,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="3" Optimization="3"
InlineFunctionExpansion="0"
FavorSizeOrSpeed="1" FavorSizeOrSpeed="1"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions="NDEBUG" PreprocessorDefinitions="NDEBUG"
StringPooling="true" StringPooling="true"
@ -191,7 +187,7 @@
<Configuration <Configuration
Name="Release|Win32" Name="Release|Win32"
ConfigurationType="1" ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;..\..\..\common\vsprops\BaseProperties.vsprops;..\..\..\common\vsprops\3rdpartyDeps.vsprops;.\vsprops\release.vsprops;..\..\..\common\vsprops\pthreads.vsprops" InheritedPropertySheets=".\vsprops\common.vsprops;..\..\..\common\vsprops\BaseProperties.vsprops;..\..\..\common\vsprops\3rdpartyDeps.vsprops;..\..\..\common\vsprops\pthreads.vsprops;..\..\..\common\vsprops\GlobalLinking.vsprops"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false" ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2" CharacterSet="2"
@ -2331,6 +2327,10 @@
RelativePath="..\..\x86\microVU_Alloc.inl" RelativePath="..\..\x86\microVU_Alloc.inl"
> >
</File> </File>
<File
RelativePath="..\..\x86\microVU_Analyze.inl"
>
</File>
<File <File
RelativePath="..\..\x86\microVU_Compile.inl" RelativePath="..\..\x86\microVU_Compile.inl"
> >

View File

@ -8,11 +8,8 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalIncludeDirectories="./;../../;../../x86;&quot;../../x86/ix86-32&quot;;../libs;../../IPU" AdditionalIncludeDirectories="./;../../;../../x86;&quot;../../x86/ix86-32&quot;;../libs;../../IPU"
PreprocessorDefinitions="__i386__;ENABLE_NLS;PACKAGE=\&quot;pcsx2\&quot;;TIXML_USE_STL" PreprocessorDefinitions="__i386__;ENABLE_NLS;PACKAGE=\&quot;pcsx2\&quot;;TIXML_USE_STL"
StructMemberAlignment="5"
RuntimeTypeInfo="false" RuntimeTypeInfo="false"
PrecompiledHeaderFile="$(IntDir)/pcsx2.pch" PrecompiledHeaderFile="$(IntDir)/pcsx2.pch"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="0" CompileAs="0"
/> />
<Tool <Tool

View File

@ -529,6 +529,7 @@ BOOL APIENTRY GameFixes(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
case WM_INITDIALOG: case WM_INITDIALOG:
if(Config.GameFixes & 0x1) CheckDlgButton(hDlg, IDC_GAMEFIX2, TRUE);//Tri-Ace fix if(Config.GameFixes & 0x1) CheckDlgButton(hDlg, IDC_GAMEFIX2, TRUE);//Tri-Ace fix
if(Config.GameFixes & 0x4) CheckDlgButton(hDlg, IDC_GAMEFIX3, TRUE);//Digimon FPU compare fix if(Config.GameFixes & 0x4) CheckDlgButton(hDlg, IDC_GAMEFIX3, TRUE);//Digimon FPU compare fix
if(Config.GameFixes & 0x2) CheckDlgButton(hDlg, IDC_GAMEFIX4, TRUE);//Persona3/4 fix
if(Config.GameFixes & 0x8) CheckDlgButton(hDlg, IDC_GAMEFIX5, TRUE);//Tales of Destiny fix if(Config.GameFixes & 0x8) CheckDlgButton(hDlg, IDC_GAMEFIX5, TRUE);//Tales of Destiny fix
return TRUE; return TRUE;
@ -538,6 +539,7 @@ BOOL APIENTRY GameFixes(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
uint newfixes = 0; uint newfixes = 0;
newfixes |= IsDlgButtonChecked(hDlg, IDC_GAMEFIX2) ? 0x1 : 0; newfixes |= IsDlgButtonChecked(hDlg, IDC_GAMEFIX2) ? 0x1 : 0;
newfixes |= IsDlgButtonChecked(hDlg, IDC_GAMEFIX3) ? 0x4 : 0; newfixes |= IsDlgButtonChecked(hDlg, IDC_GAMEFIX3) ? 0x4 : 0;
newfixes |= IsDlgButtonChecked(hDlg, IDC_GAMEFIX4) ? 0x2 : 0;
newfixes |= IsDlgButtonChecked(hDlg, IDC_GAMEFIX5) ? 0x8 : 0; newfixes |= IsDlgButtonChecked(hDlg, IDC_GAMEFIX5) ? 0x8 : 0;
EndDialog(hDlg, TRUE); EndDialog(hDlg, TRUE);

View File

@ -74,21 +74,23 @@ LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
// Dialog // Dialog
// //
IDD_GAMEFIXES DIALOGEX 0, 0, 279, 118 IDD_GAMEFIXES DIALOGEX 0, 0, 279, 123
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Game Special Fixes" CAPTION "Game Special Fixes"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
DEFPUSHBUTTON "OK",IDOK,87,89,50,14 DEFPUSHBUTTON "OK",IDOK,87,96,50,14
PUSHBUTTON "Cancel",IDCANCEL,142,89,50,14 PUSHBUTTON "Cancel",IDCANCEL,142,96,50,14
CTEXT "Some games need special settings.\nConfigure them here.",IDC_STATIC,7,7,265,17 CTEXT "Some games need special settings.\nConfigure them here.",IDC_STATIC,7,7,265,17
GROUPBOX "PCSX2 Gamefixes",IDC_STATIC,7,28,265,83 GROUPBOX "PCSX2 Gamefixes",IDC_STATIC,7,22,265,94
CONTROL "FPU Compare Hack - Special fix for Digimon Rumble Arena 2.",IDC_GAMEFIX3, CONTROL "FPU Compare Hack - Special fix for Digimon Rumble Arena 2.",IDC_GAMEFIX3,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,43,249,10 "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,36,249,10
CONTROL "VU Add Hack - Special fix for Tri-Ace games!",IDC_GAMEFIX2, CONTROL "VU Add Hack - Special fix for Tri-Ace games!",IDC_GAMEFIX2,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,72,252,10 "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,65,252,10
CONTROL "FPU Mul Hack - Special fix for Tales of Destiny (possibly other games).",IDC_GAMEFIX5, CONTROL "VU Clip Hack - Fixes missing ground geometry in Persona.",IDC_GAMEFIX4,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,57,249,10 "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,79,238,10
CONTROL "FPU Mul Hack - Special fix for Tales of Destiny.",IDC_GAMEFIX5,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,50,249,10
END END
@ -106,7 +108,7 @@ BEGIN
RIGHTMARGIN, 272 RIGHTMARGIN, 272
VERTGUIDE, 14 VERTGUIDE, 14
TOPMARGIN, 7 TOPMARGIN, 7
BOTTOMMARGIN, 111 BOTTOMMARGIN, 116
HORZGUIDE, 103 HORZGUIDE, 103
END END
END END

View File

@ -1167,39 +1167,39 @@ void iDumpRegisters(u32 startpc, u32 temp)
psymb = disR5900GetSym(startpc); psymb = disR5900GetSym(startpc);
if( psymb != NULL ) if( psymb != NULL )
__Log("%sreg(%s): %x %x c:%x\n", pstr, psymb, startpc, cpuRegs.interrupt, cpuRegs.cycle); __Log("%sreg(%s): %x %x c:%x", pstr, psymb, startpc, cpuRegs.interrupt, cpuRegs.cycle);
else else
__Log("%sreg: %x %x c:%x\n", pstr, startpc, cpuRegs.interrupt, cpuRegs.cycle); __Log("%sreg: %x %x c:%x", pstr, startpc, cpuRegs.interrupt, cpuRegs.cycle);
for(i = 1; i < 32; ++i) __Log("%s: %x_%x_%x_%x\n", disRNameGPR[i], cpuRegs.GPR.r[i].UL[3], cpuRegs.GPR.r[i].UL[2], cpuRegs.GPR.r[i].UL[1], cpuRegs.GPR.r[i].UL[0]); for(i = 1; i < 32; ++i) __Log("%s: %x_%x_%x_%x", disRNameGPR[i], cpuRegs.GPR.r[i].UL[3], cpuRegs.GPR.r[i].UL[2], cpuRegs.GPR.r[i].UL[1], cpuRegs.GPR.r[i].UL[0]);
//for(i = 0; i < 32; i+=4) __Log("cp%d: %x_%x_%x_%x\n", i, cpuRegs.CP0.r[i], cpuRegs.CP0.r[i+1], cpuRegs.CP0.r[i+2], cpuRegs.CP0.r[i+3]); //for(i = 0; i < 32; i+=4) __Log("cp%d: %x_%x_%x_%x", i, cpuRegs.CP0.r[i], cpuRegs.CP0.r[i+1], cpuRegs.CP0.r[i+2], cpuRegs.CP0.r[i+3]);
//for(i = 0; i < 32; ++i) __Log("%sf%d: %f %x\n", pstr, i, fpuRegs.fpr[i].f, fpuRegs.fprc[i]); //for(i = 0; i < 32; ++i) __Log("%sf%d: %f %x", pstr, i, fpuRegs.fpr[i].f, fpuRegs.fprc[i]);
//for(i = 1; i < 32; ++i) __Log("%svf%d: %f %f %f %f, vi: %x\n", pstr, i, VU0.VF[i].F[3], VU0.VF[i].F[2], VU0.VF[i].F[1], VU0.VF[i].F[0], VU0.VI[i].UL); //for(i = 1; i < 32; ++i) __Log("%svf%d: %f %f %f %f, vi: %x", pstr, i, VU0.VF[i].F[3], VU0.VF[i].F[2], VU0.VF[i].F[1], VU0.VF[i].F[0], VU0.VI[i].UL);
for(i = 0; i < 32; ++i) __Log("%sf%d: %x %x\n", pstr, i, fpuRegs.fpr[i].UL, fpuRegs.fprc[i]); for(i = 0; i < 32; ++i) __Log("%sf%d: %x %x", pstr, i, fpuRegs.fpr[i].UL, fpuRegs.fprc[i]);
for(i = 1; i < 32; ++i) __Log("%svf%d: %x %x %x %x, vi: %x\n", pstr, i, VU0.VF[i].UL[3], VU0.VF[i].UL[2], VU0.VF[i].UL[1], VU0.VF[i].UL[0], VU0.VI[i].UL); for(i = 1; i < 32; ++i) __Log("%svf%d: %x %x %x %x, vi: %x", pstr, i, VU0.VF[i].UL[3], VU0.VF[i].UL[2], VU0.VF[i].UL[1], VU0.VF[i].UL[0], VU0.VI[i].UL);
__Log("%svfACC: %x %x %x %x\n", pstr, VU0.ACC.UL[3], VU0.ACC.UL[2], VU0.ACC.UL[1], VU0.ACC.UL[0]); __Log("%svfACC: %x %x %x %x", pstr, VU0.ACC.UL[3], VU0.ACC.UL[2], VU0.ACC.UL[1], VU0.ACC.UL[0]);
__Log("%sLO: %x_%x_%x_%x, HI: %x_%x_%x_%x\n", pstr, cpuRegs.LO.UL[3], cpuRegs.LO.UL[2], cpuRegs.LO.UL[1], cpuRegs.LO.UL[0], __Log("%sLO: %x_%x_%x_%x, HI: %x_%x_%x_%x", pstr, cpuRegs.LO.UL[3], cpuRegs.LO.UL[2], cpuRegs.LO.UL[1], cpuRegs.LO.UL[0],
cpuRegs.HI.UL[3], cpuRegs.HI.UL[2], cpuRegs.HI.UL[1], cpuRegs.HI.UL[0]); cpuRegs.HI.UL[3], cpuRegs.HI.UL[2], cpuRegs.HI.UL[1], cpuRegs.HI.UL[0]);
__Log("%sCycle: %x %x, Count: %x\n", pstr, cpuRegs.cycle, g_nextBranchCycle, cpuRegs.CP0.n.Count); __Log("%sCycle: %x %x, Count: %x", pstr, cpuRegs.cycle, g_nextBranchCycle, cpuRegs.CP0.n.Count);
iDumpPsxRegisters(psxRegs.pc, temp); iDumpPsxRegisters(psxRegs.pc, temp);
__Log("f410,30,40: %x %x %x, %d %d\n", psHu32(0xf410), psHu32(0xf430), psHu32(0xf440), rdram_sdevid, rdram_devices); __Log("f410,30,40: %x %x %x, %d %d", psHu32(0xf410), psHu32(0xf430), psHu32(0xf440), rdram_sdevid, rdram_devices);
__Log("cyc11: %x %x; vu0: %x, vu1: %x\n", cpuRegs.sCycle[1], cpuRegs.eCycle[1], VU0.cycle, VU1.cycle); __Log("cyc11: %x %x; vu0: %x, vu1: %x", cpuRegs.sCycle[1], cpuRegs.eCycle[1], VU0.cycle, VU1.cycle);
__Log("%scounters: %x %x; psx: %x %x\n", pstr, nextsCounter, nextCounter, psxNextsCounter, psxNextCounter); __Log("%scounters: %x %x; psx: %x %x", pstr, nextsCounter, nextCounter, psxNextsCounter, psxNextCounter);
for(i = 0; i < 4; ++i) { for(i = 0; i < 4; ++i) {
__Log("eetimer%d: count: %x mode: %x target: %x %x; %x %x; %x %x %x %x\n", i, __Log("eetimer%d: count: %x mode: %x target: %x %x; %x %x; %x %x %x %x", i,
counters[i].count, counters[i].mode, counters[i].target, counters[i].hold, counters[i].rate, counters[i].count, counters[i].mode, counters[i].target, counters[i].hold, counters[i].rate,
counters[i].interrupt, counters[i].Cycle, counters[i].sCycle, counters[i].CycleT, counters[i].sCycleT); counters[i].interrupt, counters[i].Cycle, counters[i].sCycle, counters[i].CycleT, counters[i].sCycleT);
} }
__Log("VIF0_STAT = %x, VIF1_STAT = %x\n", psHu32(0x3800), psHu32(0x3C00)); __Log("VIF0_STAT = %x, VIF1_STAT = %x", psHu32(0x3800), psHu32(0x3C00));
__Log("ipu %x %x %x %x; bp: %x %x %x %x\n", psHu32(0x2000), psHu32(0x2010), psHu32(0x2020), psHu32(0x2030), g_BP.BP, g_BP.bufferhasnew, g_BP.FP, g_BP.IFC); __Log("ipu %x %x %x %x; bp: %x %x %x %x", psHu32(0x2000), psHu32(0x2010), psHu32(0x2020), psHu32(0x2030), g_BP.BP, g_BP.bufferhasnew, g_BP.FP, g_BP.IFC);
__Log("gif: %x %x %x\n", psHu32(0x3000), psHu32(0x3010), psHu32(0x3020)); __Log("gif: %x %x %x", psHu32(0x3000), psHu32(0x3010), psHu32(0x3020));
for(i = 0; i < ARRAYSIZE(dmacs); ++i) { for(i = 0; i < ARRAYSIZE(dmacs); ++i) {
DMACh* p = (DMACh*)(PS2MEM_HW+dmacs[i]); DMACh* p = (DMACh*)(PS2MEM_HW+dmacs[i]);
__Log("dma%d c%x m%x q%x t%x s%x\n", i, p->chcr, p->madr, p->qwc, p->tadr, p->sadr); __Log("dma%d c%x m%x q%x t%x s%x", i, p->chcr, p->madr, p->qwc, p->tadr, p->sadr);
} }
__Log("dmac %x %x %x %x\n", psHu32(DMAC_CTRL), psHu32(DMAC_STAT), psHu32(DMAC_RBSR), psHu32(DMAC_RBOR)); __Log("dmac %x %x %x %x", psHu32(DMAC_CTRL), psHu32(DMAC_STAT), psHu32(DMAC_RBSR), psHu32(DMAC_RBOR));
__Log("intc %x %x\n", psHu32(INTC_STAT), psHu32(INTC_MASK)); __Log("intc %x %x", psHu32(INTC_STAT), psHu32(INTC_MASK));
__Log("sif: %x %x %x %x %x\n", psHu32(0xf200), psHu32(0xf220), psHu32(0xf230), psHu32(0xf240), psHu32(0xf260)); __Log("sif: %x %x %x %x %x", psHu32(0xf200), psHu32(0xf220), psHu32(0xf230), psHu32(0xf240), psHu32(0xf260));
#endif #endif
} }

View File

@ -681,7 +681,7 @@ static void (*recComOpXMM_to_XMM[] )(x86SSERegType, x86SSERegType) = {
int recCommutativeOp(int info, int regd, int op) int recCommutativeOp(int info, int regd, int op)
{ {
int t0reg = _allocTempXMMreg(XMMT_FPS, -1); int t0reg = _allocTempXMMreg(XMMT_FPS, -1);
//if (t0reg == -1) {SysPrintf("FPU: CommutativeOp Allocation Error!\n");} //if (t0reg == -1) {Console::WriteLn("FPU: CommutativeOp Allocation Error!");}
switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) { switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) {
case PROCESS_EE_S: case PROCESS_EE_S:
@ -805,7 +805,7 @@ void recC_EQ_xmm(int info)
int tempReg; int tempReg;
int t0reg; int t0reg;
//SysPrintf("recC_EQ_xmm()\n"); //Console::WriteLn("recC_EQ_xmm()");
switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) { switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) {
case PROCESS_EE_S: case PROCESS_EE_S:
@ -875,7 +875,7 @@ void recC_LE_xmm(int info )
int tempReg; //tempX86reg int tempReg; //tempX86reg
int t0reg; //tempXMMreg int t0reg; //tempXMMreg
//SysPrintf("recC_LE_xmm()\n"); //Console::WriteLn("recC_LE_xmm()");
switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) { switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) {
case PROCESS_EE_S: case PROCESS_EE_S:
@ -949,7 +949,7 @@ void recC_LT_xmm(int info)
int tempReg; int tempReg;
int t0reg; int t0reg;
//SysPrintf("recC_LT_xmm()\n"); //Console::WriteLn("recC_LT_xmm()");
switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) { switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) {
case PROCESS_EE_S: case PROCESS_EE_S:
@ -1141,10 +1141,10 @@ void recDIV_S_xmm(int info)
int roundmodeFlag = 0; int roundmodeFlag = 0;
int t0reg = _allocTempXMMreg(XMMT_FPS, -1); int t0reg = _allocTempXMMreg(XMMT_FPS, -1);
//if (t0reg == -1) {Console::Error("FPU: DIV Allocation Error!");} //if (t0reg == -1) {Console::Error("FPU: DIV Allocation Error!");}
//SysPrintf("DIV\n"); //Console::WriteLn("DIV");
if ((g_sseMXCSR & 0x00006000) != 0x00000000) { // Set roundmode to nearest if it isn't already if ((g_sseMXCSR & 0x00006000) != 0x00000000) { // Set roundmode to nearest if it isn't already
//SysPrintf("div to nearest\n"); //Console::WriteLn("div to nearest");
roundmode_temp[0] = (g_sseMXCSR & 0xFFFF9FFF); // Set new roundmode roundmode_temp[0] = (g_sseMXCSR & 0xFFFF9FFF); // Set new roundmode
roundmode_temp[1] = g_sseMXCSR; // Backup old Roundmode roundmode_temp[1] = g_sseMXCSR; // Backup old Roundmode
SSE_LDMXCSR ((uptr)&roundmode_temp[0]); // Recompile Roundmode Change SSE_LDMXCSR ((uptr)&roundmode_temp[0]); // Recompile Roundmode Change
@ -1153,14 +1153,14 @@ void recDIV_S_xmm(int info)
switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) { switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) {
case PROCESS_EE_S: case PROCESS_EE_S:
//SysPrintf("FPU: DIV case 1\n"); //Console::WriteLn("FPU: DIV case 1");
SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S);
SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Ft_]); SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Ft_]);
if (CHECK_FPU_EXTRA_FLAGS) recDIVhelper1(EEREC_D, t0reg); if (CHECK_FPU_EXTRA_FLAGS) recDIVhelper1(EEREC_D, t0reg);
else recDIVhelper2(EEREC_D, t0reg); else recDIVhelper2(EEREC_D, t0reg);
break; break;
case PROCESS_EE_T: case PROCESS_EE_T:
//SysPrintf("FPU: DIV case 2\n"); //Console::WriteLn("FPU: DIV case 2");
if (EEREC_D == EEREC_T) { if (EEREC_D == EEREC_T) {
SSE_MOVSS_XMM_to_XMM(t0reg, EEREC_T); SSE_MOVSS_XMM_to_XMM(t0reg, EEREC_T);
SSE_MOVSS_M32_to_XMM(EEREC_D, (uptr)&fpuRegs.fpr[_Fs_]); SSE_MOVSS_M32_to_XMM(EEREC_D, (uptr)&fpuRegs.fpr[_Fs_]);
@ -1174,7 +1174,7 @@ void recDIV_S_xmm(int info)
} }
break; break;
case (PROCESS_EE_S|PROCESS_EE_T): case (PROCESS_EE_S|PROCESS_EE_T):
//SysPrintf("FPU: DIV case 3\n"); //Console::WriteLn("FPU: DIV case 3");
if (EEREC_D == EEREC_T) { if (EEREC_D == EEREC_T) {
SSE_MOVSS_XMM_to_XMM(t0reg, EEREC_T); SSE_MOVSS_XMM_to_XMM(t0reg, EEREC_T);
SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S);
@ -1188,7 +1188,7 @@ void recDIV_S_xmm(int info)
} }
break; break;
default: default:
//SysPrintf("FPU: DIV case 4\n"); //Console::WriteLn("FPU: DIV case 4");
SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Ft_]); SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Ft_]);
SSE_MOVSS_M32_to_XMM(EEREC_D, (uptr)&fpuRegs.fpr[_Fs_]); SSE_MOVSS_M32_to_XMM(EEREC_D, (uptr)&fpuRegs.fpr[_Fs_]);
if (CHECK_FPU_EXTRA_FLAGS) recDIVhelper1(EEREC_D, t0reg); if (CHECK_FPU_EXTRA_FLAGS) recDIVhelper1(EEREC_D, t0reg);
@ -1626,19 +1626,19 @@ void recSUBhelper(int regd, int regt)
void recSUBop(int info, int regd) void recSUBop(int info, int regd)
{ {
int t0reg = _allocTempXMMreg(XMMT_FPS, -1); int t0reg = _allocTempXMMreg(XMMT_FPS, -1);
//if (t0reg == -1) {SysPrintf("FPU: SUB Allocation Error!\n");} //if (t0reg == -1) {Console::Error("FPU: SUB Allocation Error!");}
//AND32ItoM((uptr)&fpuRegs.fprc[31], ~(FPUflagO|FPUflagU)); // Clear O and U flags //AND32ItoM((uptr)&fpuRegs.fprc[31], ~(FPUflagO|FPUflagU)); // Clear O and U flags
switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) { switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) {
case PROCESS_EE_S: case PROCESS_EE_S:
//SysPrintf("FPU: SUB case 1\n"); //Console::WriteLn("FPU: SUB case 1");
if (regd != EEREC_S) SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); if (regd != EEREC_S) SSE_MOVSS_XMM_to_XMM(regd, EEREC_S);
SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Ft_]); SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Ft_]);
recSUBhelper(regd, t0reg); recSUBhelper(regd, t0reg);
break; break;
case PROCESS_EE_T: case PROCESS_EE_T:
//SysPrintf("FPU: SUB case 2\n"); //Console::WriteLn("FPU: SUB case 2");
if (regd == EEREC_T) { if (regd == EEREC_T) {
SSE_MOVSS_XMM_to_XMM(t0reg, EEREC_T); SSE_MOVSS_XMM_to_XMM(t0reg, EEREC_T);
SSE_MOVSS_M32_to_XMM(regd, (uptr)&fpuRegs.fpr[_Fs_]); SSE_MOVSS_M32_to_XMM(regd, (uptr)&fpuRegs.fpr[_Fs_]);
@ -1650,7 +1650,7 @@ void recSUBop(int info, int regd)
} }
break; break;
case (PROCESS_EE_S|PROCESS_EE_T): case (PROCESS_EE_S|PROCESS_EE_T):
//SysPrintf("FPU: SUB case 3\n"); //Console::WriteLn("FPU: SUB case 3");
if (regd == EEREC_T) { if (regd == EEREC_T) {
SSE_MOVSS_XMM_to_XMM(t0reg, EEREC_T); SSE_MOVSS_XMM_to_XMM(t0reg, EEREC_T);
SSE_MOVSS_XMM_to_XMM(regd, EEREC_S); SSE_MOVSS_XMM_to_XMM(regd, EEREC_S);
@ -1698,10 +1698,10 @@ void recSQRT_S_xmm(int info)
u8* pjmp; u8* pjmp;
static u32 PCSX2_ALIGNED16(roundmode_temp[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; static u32 PCSX2_ALIGNED16(roundmode_temp[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
int roundmodeFlag = 0; int roundmodeFlag = 0;
//SysPrintf("FPU: SQRT\n"); //Console::WriteLn("FPU: SQRT");
if ((g_sseMXCSR & 0x00006000) != 0x00000000) { // Set roundmode to nearest if it isn't already if ((g_sseMXCSR & 0x00006000) != 0x00000000) { // Set roundmode to nearest if it isn't already
//SysPrintf("sqrt to nearest\n"); //Console::WriteLn("sqrt to nearest");
roundmode_temp[0] = (g_sseMXCSR & 0xFFFF9FFF); // Set new roundmode roundmode_temp[0] = (g_sseMXCSR & 0xFFFF9FFF); // Set new roundmode
roundmode_temp[1] = g_sseMXCSR; // Backup old Roundmode roundmode_temp[1] = g_sseMXCSR; // Backup old Roundmode
SSE_LDMXCSR ((uptr)&roundmode_temp[0]); // Recompile Roundmode Change SSE_LDMXCSR ((uptr)&roundmode_temp[0]); // Recompile Roundmode Change
@ -1749,6 +1749,7 @@ void recRSQRThelper1(int regd, int t0reg) // Preforms the RSQRT function when re
{ {
u8 *pjmp1, *pjmp2; u8 *pjmp1, *pjmp2;
u32 *pjmp32; u32 *pjmp32;
u8 *qjmp1, *qjmp2;
int t1reg = _allocTempXMMreg(XMMT_FPS, -1); int t1reg = _allocTempXMMreg(XMMT_FPS, -1);
int tempReg = _allocX86reg(-1, X86TYPE_TEMP, 0, 0); int tempReg = _allocX86reg(-1, X86TYPE_TEMP, 0, 0);
//if (t1reg == -1) {Console::Error("FPU: RSQRT Allocation Error!");} //if (t1reg == -1) {Console::Error("FPU: RSQRT Allocation Error!");}
@ -1756,20 +1757,7 @@ void recRSQRThelper1(int regd, int t0reg) // Preforms the RSQRT function when re
AND32ItoM((uptr)&fpuRegs.fprc[31], ~(FPUflagI|FPUflagD)); // Clear I and D flags AND32ItoM((uptr)&fpuRegs.fprc[31], ~(FPUflagI|FPUflagD)); // Clear I and D flags
/*--- Check for zero ---*/ /*--- (first) Check for negative SQRT ---*/
SSE_XORPS_XMM_to_XMM(t1reg, t1reg);
SSE_CMPEQSS_XMM_to_XMM(t1reg, t0reg);
SSE_MOVMSKPS_XMM_to_R32(tempReg, t1reg);
AND32ItoR(tempReg, 1); //Check sign (if t0reg == zero, sign will be set)
pjmp1 = JZ8(0); //Skip if not set
OR32ItoM((uptr)&fpuRegs.fprc[31], FPUflagD|FPUflagSD); // Set D and SD flags
SSE_XORPS_XMM_to_XMM(regd, t0reg); // Make regd Positive or Negative
SSE_ANDPS_M128_to_XMM(regd, (uptr)&s_neg[0]); // Get the sign bit
SSE_ORPS_M128_to_XMM(regd, (uptr)&g_maxvals[0]); // regd = +/- Maximum
pjmp32 = JMP32(0);
x86SetJ8(pjmp1);
/*--- Check for negative SQRT ---*/
SSE_MOVMSKPS_XMM_to_R32(tempReg, t0reg); SSE_MOVMSKPS_XMM_to_R32(tempReg, t0reg);
AND32ItoR(tempReg, 1); //Check sign AND32ItoR(tempReg, 1); //Check sign
pjmp2 = JZ8(0); //Skip if not set pjmp2 = JZ8(0); //Skip if not set
@ -1777,6 +1765,30 @@ void recRSQRThelper1(int regd, int t0reg) // Preforms the RSQRT function when re
SSE_ANDPS_M128_to_XMM(t0reg, (uptr)&s_pos[0]); // Make t0reg Positive SSE_ANDPS_M128_to_XMM(t0reg, (uptr)&s_pos[0]); // Make t0reg Positive
x86SetJ8(pjmp2); x86SetJ8(pjmp2);
/*--- Check for zero ---*/
SSE_XORPS_XMM_to_XMM(t1reg, t1reg);
SSE_CMPEQSS_XMM_to_XMM(t1reg, t0reg);
SSE_MOVMSKPS_XMM_to_R32(tempReg, t1reg);
AND32ItoR(tempReg, 1); //Check sign (if t0reg == zero, sign will be set)
pjmp1 = JZ8(0); //Skip if not set
/*--- Check for 0/0 ---*/
SSE_XORPS_XMM_to_XMM(t1reg, t1reg);
SSE_CMPEQSS_XMM_to_XMM(t1reg, regd);
SSE_MOVMSKPS_XMM_to_R32(tempReg, t1reg);
AND32ItoR(tempReg, 1); //Check sign (if regd == zero, sign will be set)
qjmp1 = JZ8(0); //Skip if not set
OR32ItoM((uptr)&fpuRegs.fprc[31], FPUflagI|FPUflagSI); // Set I and SI flags ( 0/0 )
qjmp2 = JMP8(0);
x86SetJ8(qjmp1); //x/0 but not 0/0
OR32ItoM((uptr)&fpuRegs.fprc[31], FPUflagD|FPUflagSD); // Set D and SD flags ( x/0 )
x86SetJ8(qjmp2);
/*--- Make regd +/- Maximum ---*/
SSE_ANDPS_M128_to_XMM(regd, (uptr)&s_neg[0]); // Get the sign bit
SSE_ORPS_M128_to_XMM(regd, (uptr)&g_maxvals[0]); // regd = +/- Maximum
pjmp32 = JMP32(0);
x86SetJ8(pjmp1);
if (CHECK_FPU_EXTRA_OVERFLOW) { if (CHECK_FPU_EXTRA_OVERFLOW) {
SSE_MINSS_M32_to_XMM(t0reg, (uptr)&g_maxvals[0]); // Only need to do positive clamp, since t0reg is positive SSE_MINSS_M32_to_XMM(t0reg, (uptr)&g_maxvals[0]); // Only need to do positive clamp, since t0reg is positive
fpuFloat2(regd); fpuFloat2(regd);
@ -1808,32 +1820,32 @@ void recRSQRT_S_xmm(int info)
{ {
int t0reg = _allocTempXMMreg(XMMT_FPS, -1); int t0reg = _allocTempXMMreg(XMMT_FPS, -1);
//if (t0reg == -1) {Console::Error("FPU: RSQRT Allocation Error!");} //if (t0reg == -1) {Console::Error("FPU: RSQRT Allocation Error!");}
//SysPrintf("FPU: RSQRT\n"); //Console::WriteLn("FPU: RSQRT");
switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) { switch(info & (PROCESS_EE_S|PROCESS_EE_T) ) {
case PROCESS_EE_S: case PROCESS_EE_S:
//SysPrintf("FPU: RSQRT case 1\n"); //Console::WriteLn("FPU: RSQRT case 1");
SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S);
SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Ft_]); SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Ft_]);
if (CHECK_FPU_EXTRA_FLAGS) recRSQRThelper1(EEREC_D, t0reg); if (CHECK_FPU_EXTRA_FLAGS) recRSQRThelper1(EEREC_D, t0reg);
else recRSQRThelper2(EEREC_D, t0reg); else recRSQRThelper2(EEREC_D, t0reg);
break; break;
case PROCESS_EE_T: case PROCESS_EE_T:
//SysPrintf("FPU: RSQRT case 2\n"); //Console::WriteLn("FPU: RSQRT case 2");
SSE_MOVSS_XMM_to_XMM(t0reg, EEREC_T); SSE_MOVSS_XMM_to_XMM(t0reg, EEREC_T);
SSE_MOVSS_M32_to_XMM(EEREC_D, (uptr)&fpuRegs.fpr[_Fs_]); SSE_MOVSS_M32_to_XMM(EEREC_D, (uptr)&fpuRegs.fpr[_Fs_]);
if (CHECK_FPU_EXTRA_FLAGS) recRSQRThelper1(EEREC_D, t0reg); if (CHECK_FPU_EXTRA_FLAGS) recRSQRThelper1(EEREC_D, t0reg);
else recRSQRThelper2(EEREC_D, t0reg); else recRSQRThelper2(EEREC_D, t0reg);
break; break;
case (PROCESS_EE_S|PROCESS_EE_T): case (PROCESS_EE_S|PROCESS_EE_T):
//SysPrintf("FPU: RSQRT case 3\n"); //Console::WriteLn("FPU: RSQRT case 3");
SSE_MOVSS_XMM_to_XMM(t0reg, EEREC_T); SSE_MOVSS_XMM_to_XMM(t0reg, EEREC_T);
SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S); SSE_MOVSS_XMM_to_XMM(EEREC_D, EEREC_S);
if (CHECK_FPU_EXTRA_FLAGS) recRSQRThelper1(EEREC_D, t0reg); if (CHECK_FPU_EXTRA_FLAGS) recRSQRThelper1(EEREC_D, t0reg);
else recRSQRThelper2(EEREC_D, t0reg); else recRSQRThelper2(EEREC_D, t0reg);
break; break;
default: default:
//SysPrintf("FPU: RSQRT case 4\n"); //Console::WriteLn("FPU: RSQRT case 4");
SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Ft_]); SSE_MOVSS_M32_to_XMM(t0reg, (uptr)&fpuRegs.fpr[_Ft_]);
SSE_MOVSS_M32_to_XMM(EEREC_D, (uptr)&fpuRegs.fpr[_Fs_]); SSE_MOVSS_M32_to_XMM(EEREC_D, (uptr)&fpuRegs.fpr[_Fs_]);
if (CHECK_FPU_EXTRA_FLAGS) recRSQRThelper1(EEREC_D, t0reg); if (CHECK_FPU_EXTRA_FLAGS) recRSQRThelper1(EEREC_D, t0reg);

View File

@ -191,7 +191,7 @@ void ToDouble(int reg)
// converts really large normal numbers to PS2 signed max // converts really large normal numbers to PS2 signed max
// converts really small normal numbers to zero (flush) // converts really small normal numbers to zero (flush)
// doesn't handle inf/nan/denormal // doesn't handle inf/nan/denormal
void ToPS2FPU_Full(int reg, bool flags, int absreg, bool acc) void ToPS2FPU_Full(int reg, bool flags, int absreg, bool acc, bool addsub)
{ {
if (flags) if (flags)
AND32ItoM((uptr)&fpuRegs.fprc[31], ~(FPUflagO | FPUflagU)); AND32ItoM((uptr)&fpuRegs.fprc[31], ~(FPUflagO | FPUflagU));
@ -229,6 +229,7 @@ void ToPS2FPU_Full(int reg, bool flags, int absreg, bool acc)
u8 *end3 = JMP8(0); u8 *end3 = JMP8(0);
x86SetJ8(to_underflow); x86SetJ8(to_underflow);
u8 *end4;
if (flags && FPU_FLAGS_UNDERFLOW) //set underflow flags if not zero if (flags && FPU_FLAGS_UNDERFLOW) //set underflow flags if not zero
{ {
SSE2_XORPD_XMM_to_XMM(absreg, absreg); SSE2_XORPD_XMM_to_XMM(absreg, absreg);
@ -236,6 +237,19 @@ void ToPS2FPU_Full(int reg, bool flags, int absreg, bool acc)
u8 *is_zero = JE8(0); u8 *is_zero = JE8(0);
OR32ItoM((uptr)&fpuRegs.fprc[31], (FPUflagU | FPUflagSU)); OR32ItoM((uptr)&fpuRegs.fprc[31], (FPUflagU | FPUflagSU));
if (addsub)
{
//On ADD/SUB, the PS2 simply leaves the mantissa bits as they are (after normalization)
//IEEE either clears them (FtZ) or returns the denormalized result.
//not thoroughly tested : other operations such as MUL and DIV seem to clear all mantissa bits?
SSE_MOVAPS_XMM_to_XMM(absreg, reg);
SSE2_PSLLQ_I8_to_XMM(reg, 12); //mantissa bits
SSE2_PSRLQ_I8_to_XMM(reg, 41);
SSE2_PSRLQ_I8_to_XMM(absreg, 63); //sign bit
SSE2_PSLLQ_I8_to_XMM(absreg, 31);
SSE2_POR_XMM_to_XMM(reg, absreg);
end4 = JMP8(0);
}
x86SetJ8(is_zero); x86SetJ8(is_zero);
} }
@ -245,13 +259,15 @@ void ToPS2FPU_Full(int reg, bool flags, int absreg, bool acc)
x86SetJ8(end); x86SetJ8(end);
x86SetJ8(end2); x86SetJ8(end2);
x86SetJ8(end3); x86SetJ8(end3);
if (flags && FPU_FLAGS_UNDERFLOW && addsub)
x86SetJ8(end4);
} }
//mustn't use EAX/ECX/EDX/x86regs (MUL) //mustn't use EAX/ECX/EDX/x86regs (MUL)
void ToPS2FPU(int reg, bool flags, int absreg, bool acc) void ToPS2FPU(int reg, bool flags, int absreg, bool acc, bool addsub = false)
{ {
if (FPU_RESULT) if (FPU_RESULT)
ToPS2FPU_Full(reg, flags, absreg, acc); ToPS2FPU_Full(reg, flags, absreg, acc, addsub);
else else
{ {
SSE2_CVTSD2SS_XMM_to_XMM(reg, reg); //clamp SSE2_CVTSD2SS_XMM_to_XMM(reg, reg); //clamp
@ -415,24 +431,24 @@ void FPU_MUL(int info, int regd, int sreg, int treg, bool acc)
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
// CommutativeOp XMM (used for ADD, MUL, MAX, MIN and SUB opcodes) // CommutativeOp XMM (used for ADD and SUB opcodes. that's it.)
//------------------------------------------------------------------ //------------------------------------------------------------------
static void (*recFPUOpXMM_to_XMM[] )(x86SSERegType, x86SSERegType) = { static void (*recFPUOpXMM_to_XMM[] )(x86SSERegType, x86SSERegType) = {
SSE2_ADDSD_XMM_to_XMM, NULL, NULL, NULL, SSE2_SUBSD_XMM_to_XMM }; SSE2_ADDSD_XMM_to_XMM, SSE2_SUBSD_XMM_to_XMM };
void recFPUOp(int info, int regd, int op, bool acc) void recFPUOp(int info, int regd, int op, bool acc)
{ {
int sreg, treg; int sreg, treg;
ALLOC_S(sreg); ALLOC_T(treg); ALLOC_S(sreg); ALLOC_T(treg);
if (FPU_ADD_SUB_HACK && (op == 0 || op == 4)) //ADD or SUB if (FPU_ADD_SUB_HACK) //ADD or SUB
FPU_ADD_SUB(sreg, treg); FPU_ADD_SUB(sreg, treg);
ToDouble(sreg); ToDouble(treg); ToDouble(sreg); ToDouble(treg);
recFPUOpXMM_to_XMM[op](sreg, treg); recFPUOpXMM_to_XMM[op](sreg, treg);
ToPS2FPU(sreg, true, treg, acc); ToPS2FPU(sreg, true, treg, acc, true);
SSE_MOVSS_XMM_to_XMM(regd, sreg); SSE_MOVSS_XMM_to_XMM(regd, sreg);
_freeXMMreg(sreg); _freeXMMreg(treg); _freeXMMreg(sreg); _freeXMMreg(treg);
@ -629,10 +645,10 @@ void recDIV_S_xmm(int info)
static u32 PCSX2_ALIGNED16(roundmode_temp[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; static u32 PCSX2_ALIGNED16(roundmode_temp[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
int roundmodeFlag = 0; int roundmodeFlag = 0;
//if (t0reg == -1) {Console::Error("FPU: DIV Allocation Error!");} //if (t0reg == -1) {Console::Error("FPU: DIV Allocation Error!");}
//SysPrintf("DIV\n"); //Console::WriteLn("DIV");
if ((g_sseMXCSR & 0x00006000) != 0x00000000) { // Set roundmode to nearest if it isn't already if ((g_sseMXCSR & 0x00006000) != 0x00000000) { // Set roundmode to nearest if it isn't already
//SysPrintf("div to nearest\n"); //Console::WriteLn("div to nearest");
roundmode_temp[0] = (g_sseMXCSR & 0xFFFF9FFF); // Set new roundmode roundmode_temp[0] = (g_sseMXCSR & 0xFFFF9FFF); // Set new roundmode
roundmode_temp[1] = g_sseMXCSR; // Backup old Roundmode roundmode_temp[1] = g_sseMXCSR; // Backup old Roundmode
SSE_LDMXCSR ((uptr)&roundmode_temp[0]); // Recompile Roundmode Change SSE_LDMXCSR ((uptr)&roundmode_temp[0]); // Recompile Roundmode Change
@ -715,7 +731,7 @@ void recMaddsub(int info, int regd, int op, bool acc)
else else
SSE2_ADDSD_XMM_to_XMM(treg, sreg); SSE2_ADDSD_XMM_to_XMM(treg, sreg);
ToPS2FPU(treg, true, sreg, acc); ToPS2FPU(treg, true, sreg, acc, true);
x86SetJ32(skipall); x86SetJ32(skipall);
SSE_MOVSS_XMM_to_XMM(regd, treg); SSE_MOVSS_XMM_to_XMM(regd, treg);
@ -865,7 +881,7 @@ FPURECOMPILE_CONSTCODE(NEG_S, XMMINFO_WRITED|XMMINFO_READS);
void recSUB_S_xmm(int info) void recSUB_S_xmm(int info)
{ {
recFPUOp(info, EEREC_D, 4, false); recFPUOp(info, EEREC_D, 1, false);
} }
FPURECOMPILE_CONSTCODE(SUB_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT); FPURECOMPILE_CONSTCODE(SUB_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT);
@ -873,7 +889,7 @@ FPURECOMPILE_CONSTCODE(SUB_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT);
void recSUBA_S_xmm(int info) void recSUBA_S_xmm(int info)
{ {
recFPUOp(info, EEREC_ACC, 4, true); recFPUOp(info, EEREC_ACC, 1, true);
} }
FPURECOMPILE_CONSTCODE(SUBA_S, XMMINFO_WRITEACC|XMMINFO_READS|XMMINFO_READT); FPURECOMPILE_CONSTCODE(SUBA_S, XMMINFO_WRITEACC|XMMINFO_READS|XMMINFO_READT);
@ -886,17 +902,16 @@ FPURECOMPILE_CONSTCODE(SUBA_S, XMMINFO_WRITEACC|XMMINFO_READS|XMMINFO_READT);
void recSQRT_S_xmm(int info) void recSQRT_S_xmm(int info)
{ {
u8 *pjmp; u8 *pjmp;
u32 *pjmpx;
static u32 PCSX2_ALIGNED16(roundmode_temp[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; static u32 PCSX2_ALIGNED16(roundmode_temp[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
int roundmodeFlag = 0; int roundmodeFlag = 0;
int tempReg = _allocX86reg(-1, X86TYPE_TEMP, 0, 0); int tempReg = _allocX86reg(-1, X86TYPE_TEMP, 0, 0);
if (tempReg == -1) {Console::Error("FPU: SQRT Allocation Error!"); tempReg = EAX;} if (tempReg == -1) {Console::Error("FPU: SQRT Allocation Error!"); tempReg = EAX;}
int t1reg = _allocTempXMMreg(XMMT_FPS, -1); int t1reg = _allocTempXMMreg(XMMT_FPS, -1);
if (t1reg == -1) {Console::Error("FPU: SQRT Allocation Error!");} if (t1reg == -1) {Console::Error("FPU: SQRT Allocation Error!");}
//SysPrintf("FPU: SQRT\n"); //Console::WriteLn("FPU: SQRT");
if ((g_sseMXCSR & 0x00006000) != 0x00000000) { // Set roundmode to nearest if it isn't already if ((g_sseMXCSR & 0x00006000) != 0x00000000) { // Set roundmode to nearest if it isn't already
//SysPrintf("sqrt to nearest\n"); //Console::WriteLn("sqrt to nearest");
roundmode_temp[0] = (g_sseMXCSR & 0xFFFF9FFF); // Set new roundmode roundmode_temp[0] = (g_sseMXCSR & 0xFFFF9FFF); // Set new roundmode
roundmode_temp[1] = g_sseMXCSR; // Backup old Roundmode roundmode_temp[1] = g_sseMXCSR; // Backup old Roundmode
SSE_LDMXCSR ((uptr)&roundmode_temp[0]); // Recompile Roundmode Change SSE_LDMXCSR ((uptr)&roundmode_temp[0]); // Recompile Roundmode Change
@ -908,14 +923,7 @@ void recSQRT_S_xmm(int info)
if (FPU_FLAGS_ID) { if (FPU_FLAGS_ID) {
AND32ItoM((uptr)&fpuRegs.fprc[31], ~(FPUflagI|FPUflagD)); // Clear I and D flags AND32ItoM((uptr)&fpuRegs.fprc[31], ~(FPUflagI|FPUflagD)); // Clear I and D flags
//--- Check for zero (skip sqrt if zero) //--- Check for negative SQRT --- (sqrt(-0) = 0, unlike what the docs say)
SSE_XORPS_XMM_to_XMM(t1reg, t1reg);
SSE_CMPEQSS_XMM_to_XMM(t1reg, EEREC_D);
SSE_MOVMSKPS_XMM_to_R32(tempReg, t1reg);
AND32ItoR(tempReg, 1);
pjmpx = JNE32(0);
//--- Check for negative SQRT ---
SSE_MOVMSKPS_XMM_to_R32(tempReg, EEREC_D); SSE_MOVMSKPS_XMM_to_R32(tempReg, EEREC_D);
AND32ItoR(tempReg, 1); //Check sign AND32ItoR(tempReg, 1); //Check sign
pjmp = JZ8(0); //Skip if none are pjmp = JZ8(0); //Skip if none are
@ -935,8 +943,6 @@ void recSQRT_S_xmm(int info)
ToPS2FPU(EEREC_D, false, t1reg, false); ToPS2FPU(EEREC_D, false, t1reg, false);
x86SetJ32(pjmpx);
if (roundmodeFlag == 1) { // Set roundmode back if it was changed if (roundmodeFlag == 1) { // Set roundmode back if it was changed
SSE_LDMXCSR ((uptr)&roundmode_temp[1]); SSE_LDMXCSR ((uptr)&roundmode_temp[1]);
} }
@ -954,6 +960,7 @@ FPURECOMPILE_CONSTCODE(SQRT_S, XMMINFO_WRITED|XMMINFO_READT);
void recRSQRThelper1(int regd, int regt) // Preforms the RSQRT function when regd <- Fs and regt <- Ft (Sets correct flags) void recRSQRThelper1(int regd, int regt) // Preforms the RSQRT function when regd <- Fs and regt <- Ft (Sets correct flags)
{ {
u8 *pjmp1, *pjmp2; u8 *pjmp1, *pjmp2;
u8 *qjmp1, *qjmp2;
u32 *pjmp32; u32 *pjmp32;
int t1reg = _allocTempXMMreg(XMMT_FPS, -1); int t1reg = _allocTempXMMreg(XMMT_FPS, -1);
int tempReg = _allocX86reg(-1, X86TYPE_TEMP, 0, 0); int tempReg = _allocX86reg(-1, X86TYPE_TEMP, 0, 0);
@ -962,19 +969,7 @@ void recRSQRThelper1(int regd, int regt) // Preforms the RSQRT function when reg
AND32ItoM((uptr)&fpuRegs.fprc[31], ~(FPUflagI|FPUflagD)); // Clear I and D flags AND32ItoM((uptr)&fpuRegs.fprc[31], ~(FPUflagI|FPUflagD)); // Clear I and D flags
//--- Check for zero --- //--- (first) Check for negative SQRT ---
SSE_XORPS_XMM_to_XMM(t1reg, t1reg);
SSE_CMPEQSS_XMM_to_XMM(t1reg, regt);
SSE_MOVMSKPS_XMM_to_R32(tempReg, t1reg);
AND32ItoR(tempReg, 1); //Check sign (if regt == zero, sign will be set)
pjmp1 = JZ8(0); //Skip if not set
OR32ItoM((uptr)&fpuRegs.fprc[31], FPUflagD|FPUflagSD); // Set D and SD flags (even when 0/0)
SSE_XORPS_XMM_to_XMM(regd, regt); // Make regd Positive or Negative
SetMaxValue(regd); //clamp to max
pjmp32 = JMP32(0);
x86SetJ8(pjmp1);
//--- Check for negative SQRT ---
SSE_MOVMSKPS_XMM_to_R32(tempReg, regt); SSE_MOVMSKPS_XMM_to_R32(tempReg, regt);
AND32ItoR(tempReg, 1); //Check sign AND32ItoR(tempReg, 1); //Check sign
pjmp2 = JZ8(0); //Skip if not set pjmp2 = JZ8(0); //Skip if not set
@ -982,6 +977,29 @@ void recRSQRThelper1(int regd, int regt) // Preforms the RSQRT function when reg
SSE_ANDPS_M128_to_XMM(regt, (uptr)&s_pos[0]); // Make regt Positive SSE_ANDPS_M128_to_XMM(regt, (uptr)&s_pos[0]); // Make regt Positive
x86SetJ8(pjmp2); x86SetJ8(pjmp2);
//--- Check for zero ---
SSE_XORPS_XMM_to_XMM(t1reg, t1reg);
SSE_CMPEQSS_XMM_to_XMM(t1reg, regt);
SSE_MOVMSKPS_XMM_to_R32(tempReg, t1reg);
AND32ItoR(tempReg, 1); //Check sign (if regt == zero, sign will be set)
pjmp1 = JZ8(0); //Skip if not set
//--- Check for 0/0 ---
SSE_XORPS_XMM_to_XMM(t1reg, t1reg);
SSE_CMPEQSS_XMM_to_XMM(t1reg, regd);
SSE_MOVMSKPS_XMM_to_R32(tempReg, t1reg);
AND32ItoR(tempReg, 1); //Check sign (if regd == zero, sign will be set)
qjmp1 = JZ8(0); //Skip if not set
OR32ItoM((uptr)&fpuRegs.fprc[31], FPUflagI|FPUflagSI); // Set I and SI flags ( 0/0 )
qjmp2 = JMP8(0);
x86SetJ8(qjmp1); //x/0 but not 0/0
OR32ItoM((uptr)&fpuRegs.fprc[31], FPUflagD|FPUflagSD); // Set D and SD flags ( x/0 )
x86SetJ8(qjmp2);
SetMaxValue(regd); //clamp to max
pjmp32 = JMP32(0);
x86SetJ8(pjmp1);
ToDouble(regt); ToDouble(regd); ToDouble(regt); ToDouble(regd);
SSE2_SQRTSD_XMM_to_XMM(regt, regt); SSE2_SQRTSD_XMM_to_XMM(regt, regt);
@ -1013,7 +1031,7 @@ void recRSQRT_S_xmm(int info)
static u32 PCSX2_ALIGNED16(roundmode_temp[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; static u32 PCSX2_ALIGNED16(roundmode_temp[4]) = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
int roundmodeFlag = 0; int roundmodeFlag = 0;
if ((g_sseMXCSR & 0x00006000) != 0x00000000) { // Set roundmode to nearest if it isn't already if ((g_sseMXCSR & 0x00006000) != 0x00000000) { // Set roundmode to nearest if it isn't already
//SysPrintf("rsqrt to nearest\n"); //Console::WriteLn("rsqrt to nearest");
roundmode_temp[0] = (g_sseMXCSR & 0xFFFF9FFF); // Set new roundmode roundmode_temp[0] = (g_sseMXCSR & 0xFFFF9FFF); // Set new roundmode
roundmode_temp[1] = g_sseMXCSR; // Backup old Roundmode roundmode_temp[1] = g_sseMXCSR; // Backup old Roundmode
SSE_LDMXCSR ((uptr)&roundmode_temp[0]); // Recompile Roundmode Change SSE_LDMXCSR ((uptr)&roundmode_temp[0]); // Recompile Roundmode Change

View File

@ -1497,7 +1497,7 @@ CPU_SSE_XMMCACHE_END
_deleteEEreg(_Rd_, 0); _deleteEEreg(_Rd_, 0);
//Done - Refraction - Crude but quicker than int //Done - Refraction - Crude but quicker than int
//SysPrintf("PEXTLB\n"); //Console::WriteLn("PEXTLB");
//Rs = cpuRegs.GPR.r[_Rs_]; Rt = cpuRegs.GPR.r[_Rt_]; //Rs = cpuRegs.GPR.r[_Rs_]; Rt = cpuRegs.GPR.r[_Rt_];
MOV8MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rs_].UC[7]); MOV8MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rs_].UC[7]);
MOV8RtoM((uptr)&cpuRegs.GPR.r[_Rd_].UC[15], EAX); MOV8RtoM((uptr)&cpuRegs.GPR.r[_Rd_].UC[15], EAX);
@ -1617,23 +1617,29 @@ REC_FUNC_DEL( QFSRV, _Rd_);
PCSX2_ALIGNED16(int s_MaskHighBitD[4]) = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; PCSX2_ALIGNED16(int s_MaskHighBitD[4]) = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
PCSX2_ALIGNED16(int s_MaskHighBitW[4]) = { 0x80008000, 0x80008000, 0x80008000, 0x80008000 }; PCSX2_ALIGNED16(int s_MaskHighBitW[4]) = { 0x80008000, 0x80008000, 0x80008000, 0x80008000 };
void recPABSW() void recPABSW() //needs clamping
{ {
if( !_Rd_ ) return; if( !_Rd_ ) return;
CPU_SSE2_XMMCACHE_START(XMMINFO_READT|XMMINFO_WRITED) CPU_SSE2_XMMCACHE_START(XMMINFO_READT|XMMINFO_WRITED)
int t0reg = _allocTempXMMreg(XMMT_INT, -1);
SSE2_PCMPEQD_XMM_to_XMM(t0reg, t0reg);
SSE2_PSLLD_I8_to_XMM(t0reg, 31);
SSE2_PCMPEQD_XMM_to_XMM(t0reg, EEREC_T); //0xffffffff if equal to 0x80000000
if( cpucaps.hasSupplementalStreamingSIMD3Extensions ) { if( cpucaps.hasSupplementalStreamingSIMD3Extensions ) {
SSSE3_PABSD_XMM_to_XMM(EEREC_D, EEREC_T); SSSE3_PABSD_XMM_to_XMM(EEREC_D, EEREC_T); //0x80000000 -> 0x80000000
} }
else { else {
int t0reg = _allocTempXMMreg(XMMT_INT, -1); int t1reg = _allocTempXMMreg(XMMT_INT, -1);
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_T); SSEX_MOVDQA_XMM_to_XMM(t1reg, EEREC_T);
SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_T); SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_T);
SSE2_PSRAD_I8_to_XMM(t0reg, 31); SSE2_PSRAD_I8_to_XMM(t1reg, 31);
SSEX_PXOR_XMM_to_XMM(EEREC_D, t0reg); SSEX_PXOR_XMM_to_XMM(EEREC_D, t1reg);
SSE2_PSUBD_XMM_to_XMM(EEREC_D, t0reg); SSE2_PSUBD_XMM_to_XMM(EEREC_D, t1reg); //0x80000000 -> 0x80000000
_freeXMMreg(t0reg); _freeXMMreg(t1reg);
} }
SSE2_PXOR_XMM_to_XMM(EEREC_D, t0reg); //0x80000000 -> 0x7fffffff
_freeXMMreg(t0reg);
CPU_SSE_XMMCACHE_END CPU_SSE_XMMCACHE_END
_deleteEEreg(_Rt_, 1); _deleteEEreg(_Rt_, 1);
@ -1645,24 +1651,31 @@ CPU_SSE_XMMCACHE_END
CALLFunc( (uptr)R5900::Interpreter::OpcodeImpl::MMI::PABSW ); CALLFunc( (uptr)R5900::Interpreter::OpcodeImpl::MMI::PABSW );
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recPABSH() void recPABSH()
{ {
if( !_Rd_ ) return; if( !_Rd_ ) return;
CPU_SSE2_XMMCACHE_START(XMMINFO_READT|XMMINFO_WRITED) CPU_SSE2_XMMCACHE_START(XMMINFO_READT|XMMINFO_WRITED)
int t0reg = _allocTempXMMreg(XMMT_INT, -1);
SSE2_PCMPEQW_XMM_to_XMM(t0reg, t0reg);
SSE2_PSLLW_I8_to_XMM(t0reg, 15);
SSE2_PCMPEQW_XMM_to_XMM(t0reg, EEREC_T); //0xffff if equal to 0x8000
if( cpucaps.hasSupplementalStreamingSIMD3Extensions ) { if( cpucaps.hasSupplementalStreamingSIMD3Extensions ) {
SSSE3_PABSW_XMM_to_XMM(EEREC_D, EEREC_T); SSSE3_PABSW_XMM_to_XMM(EEREC_D, EEREC_T); //0x8000 -> 0x8000
} }
else { else {
int t0reg = _allocTempXMMreg(XMMT_INT, -1); int t1reg = _allocTempXMMreg(XMMT_INT, -1);
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_T); SSEX_MOVDQA_XMM_to_XMM(t1reg, EEREC_T);
SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_T); SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_T);
SSE2_PSRAW_I8_to_XMM(t0reg, 15); SSE2_PSRAW_I8_to_XMM(t1reg, 15);
SSEX_PXOR_XMM_to_XMM(EEREC_D, t0reg); SSEX_PXOR_XMM_to_XMM(EEREC_D, t1reg);
SSE2_PSUBW_XMM_to_XMM(EEREC_D, t0reg); SSE2_PSUBW_XMM_to_XMM(EEREC_D, t1reg); //0x8000 -> 0x8000
_freeXMMreg(t0reg); _freeXMMreg(t1reg);
} }
SSE2_PXOR_XMM_to_XMM(EEREC_D, t0reg); //0x8000 -> 0x7fff
_freeXMMreg(t0reg);
CPU_SSE_XMMCACHE_END CPU_SSE_XMMCACHE_END
_deleteEEreg(_Rt_, 1); _deleteEEreg(_Rt_, 1);
@ -1956,7 +1969,7 @@ CPU_SSE_XMMCACHE_END
void recQFSRV() void recQFSRV()
{ {
if ( !_Rd_ ) return; if ( !_Rd_ ) return;
//SysPrintf("recQFSRV()\n"); //Console::WriteLn("recQFSRV()");
CPU_SSE2_XMMCACHE_START( XMMINFO_READS | XMMINFO_READT | XMMINFO_WRITED ) CPU_SSE2_XMMCACHE_START( XMMINFO_READS | XMMINFO_READT | XMMINFO_WRITED )
@ -1968,7 +1981,7 @@ void recQFSRV()
SSE2_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_T); SSE2_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_T);
MOV32MtoR(EAX, (uptr)&cpuRegs.sa); MOV32MtoR(EAX, (uptr)&cpuRegs.sa);
SHL32ItoR(EAX, 1); // Multiply SA bytes by 16 bytes (the amount of bytes in QFSRVhelper() macros) SHL32ItoR(EAX, 4); // Multiply SA bytes by 16 bytes (the amount of bytes in QFSRVhelper() macros)
AND32I8toR(EAX, 0xf0); // This can possibly be removed but keeping it incase theres garbage in SA (cottonvibes) AND32I8toR(EAX, 0xf0); // This can possibly be removed but keeping it incase theres garbage in SA (cottonvibes)
ADD32ItoEAX((uptr)x86Ptr[0] + 7); // ADD32 = 5 bytes, JMPR = 2 bytes ADD32ItoEAX((uptr)x86Ptr[0] + 7); // ADD32 = 5 bytes, JMPR = 2 bytes
JMPR(EAX); // Jumps to a QFSRVhelper() case below (a total of 16 different cases) JMPR(EAX); // Jumps to a QFSRVhelper() case below (a total of 16 different cases)
@ -2402,8 +2415,8 @@ CPU_SSE2_XMMCACHE_START((_Rs_?XMMINFO_READS:0)|(_Rt_?XMMINFO_READT:0)|XMMINFO_WR
// shamt is 5-bit // shamt is 5-bit
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S); SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
SSE2_PSLLQ_I8_to_XMM(t0reg, 27); SSE2_PSLLQ_I8_to_XMM(t0reg, 27+32);
SSE2_PSRLQ_I8_to_XMM(t0reg, 27); SSE2_PSRLQ_I8_to_XMM(t0reg, 27+32);
// EEREC_D[0] <- Rt[0], t1reg[0] <- Rt[2] // EEREC_D[0] <- Rt[0], t1reg[0] <- Rt[2]
SSE_MOVHLPS_XMM_to_XMM(t1reg, EEREC_T); SSE_MOVHLPS_XMM_to_XMM(t1reg, EEREC_T);
@ -2470,8 +2483,8 @@ CPU_SSE2_XMMCACHE_START((_Rs_?XMMINFO_READS:0)|(_Rt_?XMMINFO_READT:0)|XMMINFO_WR
// shamt is 5-bit // shamt is 5-bit
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S); SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
SSE2_PSLLQ_I8_to_XMM(t0reg, 27); SSE2_PSLLQ_I8_to_XMM(t0reg, 27+32);
SSE2_PSRLQ_I8_to_XMM(t0reg, 27); SSE2_PSRLQ_I8_to_XMM(t0reg, 27+32);
// EEREC_D[0] <- Rt[0], t1reg[0] <- Rt[2] // EEREC_D[0] <- Rt[0], t1reg[0] <- Rt[2]
SSE_MOVHLPS_XMM_to_XMM(t1reg, EEREC_T); SSE_MOVHLPS_XMM_to_XMM(t1reg, EEREC_T);
@ -2619,9 +2632,18 @@ void recPDIVBW()
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
PCSX2_ALIGNED16(int s_mask1[4]) = {~0, 0, ~0, 0}; PCSX2_ALIGNED16(int s_mask1[4]) = {~0, 0, ~0, 0};
//upper word of each doubleword in LO and HI is undocumented/undefined
//contains the upper multiplication result (before the addition with the lower multiplication result)
void recPHMADH() void recPHMADH()
{ {
CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRITEHI) CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRITEHI)
int t0reg = _allocTempXMMreg(XMMT_INT, -1);
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
SSE2_PSRLD_I8_to_XMM(t0reg, 16);
SSE2_PSLLD_I8_to_XMM(t0reg, 16);
SSE2_PMADDWD_XMM_to_XMM(t0reg, EEREC_T);
if( _Rd_ ) { if( _Rd_ ) {
if( EEREC_D == EEREC_S ) { if( EEREC_D == EEREC_S ) {
SSE2_PMADDWD_XMM_to_XMM(EEREC_D, EEREC_T); SSE2_PMADDWD_XMM_to_XMM(EEREC_D, EEREC_T);
@ -2641,14 +2663,22 @@ CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMI
} }
SSEX_MOVDQA_XMM_to_XMM(EEREC_HI, EEREC_LO); SSEX_MOVDQA_XMM_to_XMM(EEREC_HI, EEREC_LO);
SSE2_PSRLQ_I8_to_XMM(EEREC_HI, 32);
SSE_SHUFPS_XMM_to_XMM(EEREC_LO, t0reg, 0x88);
SSE_SHUFPS_XMM_to_XMM(EEREC_LO, EEREC_LO, 0xd8);
SSE_SHUFPS_XMM_to_XMM(EEREC_HI, t0reg, 0xdd);
SSE_SHUFPS_XMM_to_XMM(EEREC_HI, EEREC_HI, 0xd8);
_freeXMMreg(t0reg);
CPU_SSE_XMMCACHE_END CPU_SSE_XMMCACHE_END
recCall( Interp::PHMADH, _Rd_ ); recCall( Interp::PHMADH, _Rd_ );
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
//upper word of each doubleword in LO and HI is undocumented/undefined
//contains the NOT of the upper multiplication result (before the substraction of the lower multiplication result)
void recPMSUBH() void recPMSUBH()
{ {
CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_READLO|XMMINFO_READHI|XMMINFO_WRITELO|XMMINFO_WRITEHI) CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_READLO|XMMINFO_READHI|XMMINFO_WRITELO|XMMINFO_WRITEHI)
@ -2710,22 +2740,41 @@ CPU_SSE_XMMCACHE_END
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
// rs = ... a1 a0
// rt = ... b1 b0
// rd = ... a1*b1 - a0*b0
// hi = ...
// lo = ... (undefined by doc)NOT(a1*b1), a1*b1 - a0*b0
void recPHMSBH() void recPHMSBH()
{ {
CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRITEHI) CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRITEHI)
int t0reg = _allocTempXMMreg(XMMT_INT, -1);
SSE2_PCMPEQD_XMM_to_XMM(EEREC_LO, EEREC_LO); SSE2_PCMPEQD_XMM_to_XMM(EEREC_LO, EEREC_LO);
SSE2_PSRLD_XMM_to_XMM(EEREC_LO, 16); SSE2_PSRLD_I8_to_XMM(EEREC_LO, 16);
SSEX_MOVDQA_XMM_to_XMM(EEREC_HI, EEREC_S); SSEX_MOVDQA_XMM_to_XMM(EEREC_HI, EEREC_S);
SSE2_PAND_XMM_to_XMM(EEREC_HI, EEREC_LO); SSE2_PAND_XMM_to_XMM(EEREC_HI, EEREC_LO);
SSE2_PMADDWD_XMM_to_XMM(EEREC_HI, EEREC_T); SSE2_PMADDWD_XMM_to_XMM(EEREC_HI, EEREC_T);
SSE2_PSLLD_XMM_to_XMM(EEREC_LO, 16); SSE2_PSLLD_I8_to_XMM(EEREC_LO, 16);
SSE2_PAND_XMM_to_XMM(EEREC_LO, EEREC_S); SSE2_PAND_XMM_to_XMM(EEREC_LO, EEREC_S);
SSE2_PMADDWD_XMM_to_XMM(EEREC_LO, EEREC_T); SSE2_PMADDWD_XMM_to_XMM(EEREC_LO, EEREC_T);
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_LO);
SSE2_PSUBD_XMM_to_XMM(EEREC_LO, EEREC_HI); SSE2_PSUBD_XMM_to_XMM(EEREC_LO, EEREC_HI);
if( _Rd_ ) SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_LO); if( _Rd_ ) SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_LO);
SSE2_PCMPEQD_XMM_to_XMM(EEREC_HI, EEREC_HI);
SSE2_PXOR_XMM_to_XMM(t0reg, EEREC_HI);
SSEX_MOVDQA_XMM_to_XMM(EEREC_HI, EEREC_LO); SSEX_MOVDQA_XMM_to_XMM(EEREC_HI, EEREC_LO);
SSE2_PSRLQ_I8_to_XMM(EEREC_HI, 32);
SSE_SHUFPS_XMM_to_XMM(EEREC_LO, t0reg, 0x88);
SSE_SHUFPS_XMM_to_XMM(EEREC_LO, EEREC_LO, 0xd8);
SSE_SHUFPS_XMM_to_XMM(EEREC_HI, t0reg, 0xdd);
SSE_SHUFPS_XMM_to_XMM(EEREC_HI, EEREC_HI, 0xd8);
_freeXMMreg(t0reg);
CPU_SSE_XMMCACHE_END CPU_SSE_XMMCACHE_END
recCall( Interp::PHMSBH, _Rd_ ); recCall( Interp::PHMSBH, _Rd_ );
@ -3278,8 +3327,8 @@ CPU_SSE2_XMMCACHE_START((_Rs_?XMMINFO_READS:0)|(_Rt_?XMMINFO_READT:0)|XMMINFO_WR
// shamt is 5-bit // shamt is 5-bit
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S); SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
SSE2_PSLLQ_I8_to_XMM(t0reg, 27); SSE2_PSLLQ_I8_to_XMM(t0reg, 27+32);
SSE2_PSRLQ_I8_to_XMM(t0reg, 27); SSE2_PSRLQ_I8_to_XMM(t0reg, 27+32);
// EEREC_D[0] <- Rt[0], t1reg[0] <- Rt[2] // EEREC_D[0] <- Rt[0], t1reg[0] <- Rt[2]
SSE_MOVHLPS_XMM_to_XMM(t1reg, EEREC_T); SSE_MOVHLPS_XMM_to_XMM(t1reg, EEREC_T);

View File

@ -116,7 +116,7 @@ static void iIopDumpBlock( int startpc, u8 * ptr )
u8 used[34]; u8 used[34];
int numused, count; int numused, count;
SysPrintf( "dump1 %x:%x, %x\n", startpc, psxpc, psxRegs.cycle ); Console::WriteLn( "dump1 %x:%x, %x", params startpc, psxpc, psxRegs.cycle );
Path::CreateDirectory( "dumps" ); Path::CreateDirectory( "dumps" );
string filename( Path::Combine( "dumps", fmt_string( "psxdump%.8X.txt", startpc ) ) ); string filename( Path::Combine( "dumps", fmt_string( "psxdump%.8X.txt", startpc ) ) );
@ -847,7 +847,7 @@ static void checkcodefn()
#else #else
__asm__("movl %%eax, %[pctemp]" : : [pctemp]"m"(pctemp) ); __asm__("movl %%eax, %[pctemp]" : : [pctemp]"m"(pctemp) );
#endif #endif
SysPrintf("iop code changed! %x\n", pctemp); Console::WriteLn("iop code changed! %x", params pctemp);
} }
#endif #endif
@ -940,23 +940,23 @@ void iDumpPsxRegisters(u32 startpc, u32 temp)
int i; int i;
const char* pstr = temp ? "t" : ""; const char* pstr = temp ? "t" : "";
__Log("%spsxreg: %x %x ra:%x k0: %x %x\n", pstr, startpc, psxRegs.cycle, psxRegs.GPR.n.ra, psxRegs.GPR.n.k0, *(int*)PSXM(0x13c128)); __Log("%spsxreg: %x %x ra:%x k0: %x %x", pstr, startpc, psxRegs.cycle, psxRegs.GPR.n.ra, psxRegs.GPR.n.k0, *(int*)PSXM(0x13c128));
for(i = 0; i < 34; i+=2) __Log("%spsx%s: %x %x\n", pstr, disRNameGPR[i], psxRegs.GPR.r[i], psxRegs.GPR.r[i+1]); for(i = 0; i < 34; i+=2) __Log("%spsx%s: %x %x", pstr, disRNameGPR[i], psxRegs.GPR.r[i], psxRegs.GPR.r[i+1]);
__Log("%scycle: %x %x %x; counters %x %x\n", pstr, psxRegs.cycle, g_psxNextBranchCycle, EEsCycle, __Log("%scycle: %x %x %x; counters %x %x", pstr, psxRegs.cycle, g_psxNextBranchCycle, EEsCycle,
psxNextsCounter, psxNextCounter); psxNextsCounter, psxNextCounter);
__Log("psxdma%d c%x b%x m%x t%x\n", 2, HW_DMA2_CHCR, HW_DMA2_BCR, HW_DMA2_MADR, HW_DMA2_TADR); __Log("psxdma%d c%x b%x m%x t%x", 2, HW_DMA2_CHCR, HW_DMA2_BCR, HW_DMA2_MADR, HW_DMA2_TADR);
__Log("psxdma%d c%x b%x m%x\n", 3, HW_DMA3_CHCR, HW_DMA3_BCR, HW_DMA3_MADR); __Log("psxdma%d c%x b%x m%x", 3, HW_DMA3_CHCR, HW_DMA3_BCR, HW_DMA3_MADR);
__Log("psxdma%d c%x b%x m%x t%x\n", 4, HW_DMA4_CHCR, HW_DMA4_BCR, HW_DMA4_MADR, HW_DMA4_TADR); __Log("psxdma%d c%x b%x m%x t%x", 4, HW_DMA4_CHCR, HW_DMA4_BCR, HW_DMA4_MADR, HW_DMA4_TADR);
__Log("psxdma%d c%x b%x m%x\n", 6, HW_DMA6_CHCR, HW_DMA6_BCR, HW_DMA6_MADR); __Log("psxdma%d c%x b%x m%x", 6, HW_DMA6_CHCR, HW_DMA6_BCR, HW_DMA6_MADR);
__Log("psxdma%d c%x b%x m%x\n", 7, HW_DMA7_CHCR, HW_DMA7_BCR, HW_DMA7_MADR); __Log("psxdma%d c%x b%x m%x", 7, HW_DMA7_CHCR, HW_DMA7_BCR, HW_DMA7_MADR);
__Log("psxdma%d c%x b%x m%x\n", 8, HW_DMA8_CHCR, HW_DMA8_BCR, HW_DMA8_MADR); __Log("psxdma%d c%x b%x m%x", 8, HW_DMA8_CHCR, HW_DMA8_BCR, HW_DMA8_MADR);
__Log("psxdma%d c%x b%x m%x t%x\n", 9, HW_DMA9_CHCR, HW_DMA9_BCR, HW_DMA9_MADR, HW_DMA9_TADR); __Log("psxdma%d c%x b%x m%x t%x", 9, HW_DMA9_CHCR, HW_DMA9_BCR, HW_DMA9_MADR, HW_DMA9_TADR);
__Log("psxdma%d c%x b%x m%x\n", 10, HW_DMA10_CHCR, HW_DMA10_BCR, HW_DMA10_MADR); __Log("psxdma%d c%x b%x m%x", 10, HW_DMA10_CHCR, HW_DMA10_BCR, HW_DMA10_MADR);
__Log("psxdma%d c%x b%x m%x\n", 11, HW_DMA11_CHCR, HW_DMA11_BCR, HW_DMA11_MADR); __Log("psxdma%d c%x b%x m%x", 11, HW_DMA11_CHCR, HW_DMA11_BCR, HW_DMA11_MADR);
__Log("psxdma%d c%x b%x m%x\n", 12, HW_DMA12_CHCR, HW_DMA12_BCR, HW_DMA12_MADR); __Log("psxdma%d c%x b%x m%x", 12, HW_DMA12_CHCR, HW_DMA12_BCR, HW_DMA12_MADR);
for(i = 0; i < 7; ++i) for(i = 0; i < 7; ++i)
__Log("%scounter%d: mode %x count %I64x rate %x scycle %x target %I64x\n", pstr, i, psxCounters[i].mode, psxCounters[i].count, psxCounters[i].rate, psxCounters[i].sCycleT, psxCounters[i].target); __Log("%scounter%d: mode %x count %I64x rate %x scycle %x target %I64x", pstr, i, psxCounters[i].mode, psxCounters[i].count, psxCounters[i].rate, psxCounters[i].sCycleT, psxCounters[i].target);
#endif #endif
} }

View File

@ -1775,7 +1775,7 @@ static void rpsxCOP0() { rpsxCP0[_Rs_](); }
//static void rpsxBASIC() { rpsxCP2BSC[_Rs_](); } //static void rpsxBASIC() { rpsxCP2BSC[_Rs_](); }
static void rpsxNULL() { static void rpsxNULL() {
SysPrintf("psxUNK: %8.8x\n", psxRegs.code); Console::WriteLn("psxUNK: %8.8x", params psxRegs.code);
} }
void (*rpsxBSC[64])() = { void (*rpsxBSC[64])() = {

View File

@ -94,10 +94,11 @@ void recMFSA( void )
} }
} }
// SA is 4-bit and contains the amount of bytes to shift
void recMTSA( void ) void recMTSA( void )
{ {
if( GPR_IS_CONST1(_Rs_) ) { if( GPR_IS_CONST1(_Rs_) ) {
MOV32ItoM((uptr)&cpuRegs.sa, g_cpuConstRegs[_Rs_].UL[0] ); MOV32ItoM((uptr)&cpuRegs.sa, g_cpuConstRegs[_Rs_].UL[0] & 0xf );
} }
else { else {
int mmreg; int mmreg;
@ -113,19 +114,19 @@ void recMTSA( void )
MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rs_].UL[0]); MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rs_].UL[0]);
MOV32RtoM((uptr)&cpuRegs.sa, EAX); MOV32RtoM((uptr)&cpuRegs.sa, EAX);
} }
AND32ItoM((uptr)&cpuRegs.sa, 0xf);
} }
} }
void recMTSAB( void ) void recMTSAB( void )
{ {
if( GPR_IS_CONST1(_Rs_) ) { if( GPR_IS_CONST1(_Rs_) ) {
MOV32ItoM((uptr)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF)) << 3); MOV32ItoM((uptr)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF)) );
} }
else { else {
_eeMoveGPRtoR(EAX, _Rs_); _eeMoveGPRtoR(EAX, _Rs_);
AND32ItoR(EAX, 0xF); AND32ItoR(EAX, 0xF);
XOR32ItoR(EAX, _Imm_&0xf); XOR32ItoR(EAX, _Imm_&0xf);
SHL32ItoR(EAX, 3);
MOV32RtoM((uptr)&cpuRegs.sa, EAX); MOV32RtoM((uptr)&cpuRegs.sa, EAX);
} }
} }
@ -133,13 +134,13 @@ void recMTSAB( void )
void recMTSAH( void ) void recMTSAH( void )
{ {
if( GPR_IS_CONST1(_Rs_) ) { if( GPR_IS_CONST1(_Rs_) ) {
MOV32ItoM((uptr)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 4); MOV32ItoM((uptr)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 1);
} }
else { else {
_eeMoveGPRtoR(EAX, _Rs_); _eeMoveGPRtoR(EAX, _Rs_);
AND32ItoR(EAX, 0x7); AND32ItoR(EAX, 0x7);
XOR32ItoR(EAX, _Imm_&0x7); XOR32ItoR(EAX, _Imm_&0x7);
SHL32ItoR(EAX, 4); SHL32ItoR(EAX, 1);
MOV32RtoM((uptr)&cpuRegs.sa, EAX); MOV32RtoM((uptr)&cpuRegs.sa, EAX);
} }
} }

View File

@ -63,7 +63,7 @@ namespace VU1micro
mkdir("dumps", 0755); mkdir("dumps", 0755);
sprintf( filename, "dumps/vu%.4X.txt", VU1.VI[ REG_TPC ].UL ); sprintf( filename, "dumps/vu%.4X.txt", VU1.VI[ REG_TPC ].UL );
#endif #endif
SysPrintf( "dump1 %x => %x (%s)\n", VU1.VI[ REG_TPC ].UL, pc, filename ); Console::WriteLn( "dump1 %x => %x (%s)", params VU1.VI[ REG_TPC ].UL, pc, filename );
f = fopen( filename, "wb" ); f = fopen( filename, "wb" );
for ( i = VU1.VI[REG_TPC].UL; i < pc; i += 8 ) { for ( i = VU1.VI[REG_TPC].UL; i < pc; i += 8 ) {
@ -97,11 +97,11 @@ namespace VU1micro
#ifdef _DEBUG #ifdef _DEBUG
static u32 vuprogcount = 0; static u32 vuprogcount = 0;
vuprogcount++; vuprogcount++;
if( vudump & 8 ) __Log("start vu1: %x %x\n", VU1.VI[ REG_TPC ].UL, vuprogcount); if( vudump & 8 ) __Log("start vu1: %x %x", VU1.VI[ REG_TPC ].UL, vuprogcount);
#endif #endif
if((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0){ if((VU0.VI[REG_VPU_STAT].UL & 0x100) == 0){
//SysPrintf("Execute block VU1, VU1 not busy\n"); //Console::WriteLn("Execute block VU1, VU1 not busy");
return; return;
} }

View File

@ -144,13 +144,13 @@ void _recvuFMACflush(VURegs * VU, bool intermediate) {
if( intermediate ) { if( intermediate ) {
if ((vucycle - VU->fmac[i].sCycle) > VU->fmac[i].Cycle) { if ((vucycle - VU->fmac[i].sCycle) > VU->fmac[i].Cycle) {
// VUM_LOG("flushing FMAC pipe[%d]\n", i); // VUM_LOG("flushing FMAC pipe[%d]", i);
VU->fmac[i].enable = 0; VU->fmac[i].enable = 0;
} }
} }
else { else {
if ((vucycle - VU->fmac[i].sCycle) >= VU->fmac[i].Cycle) { if ((vucycle - VU->fmac[i].sCycle) >= VU->fmac[i].Cycle) {
// VUM_LOG("flushing FMAC pipe[%d]\n", i); // VUM_LOG("flushing FMAC pipe[%d]", i);
VU->fmac[i].enable = 0; VU->fmac[i].enable = 0;
} }
} }
@ -162,13 +162,13 @@ void _recvuFDIVflush(VURegs * VU, bool intermediate) {
if( intermediate ) { if( intermediate ) {
if ((vucycle - VU->fdiv.sCycle) > VU->fdiv.Cycle) { if ((vucycle - VU->fdiv.sCycle) > VU->fdiv.Cycle) {
// SysPrintf("flushing FDIV pipe\n"); // Console::WriteLn("flushing FDIV pipe");
VU->fdiv.enable = 0; VU->fdiv.enable = 0;
} }
} }
else { else {
if ((vucycle - VU->fdiv.sCycle) >= VU->fdiv.Cycle) { if ((vucycle - VU->fdiv.sCycle) >= VU->fdiv.Cycle) {
// SysPrintf("flushing FDIV pipe\n"); // Console::WriteLn("flushing FDIV pipe");
VU->fdiv.enable = 0; VU->fdiv.enable = 0;
} }
} }
@ -179,13 +179,13 @@ void _recvuEFUflush(VURegs * VU, bool intermediate) {
if( intermediate ) { if( intermediate ) {
if ((vucycle - VU->efu.sCycle) > VU->efu.Cycle) { if ((vucycle - VU->efu.sCycle) > VU->efu.Cycle) {
// SysPrintf("flushing FDIV pipe\n"); // Console::WriteLn("flushing FDIV pipe");
VU->efu.enable = 0; VU->efu.enable = 0;
} }
} }
else { else {
if ((vucycle - VU->efu.sCycle) >= VU->efu.Cycle) { if ((vucycle - VU->efu.sCycle) >= VU->efu.Cycle) {
// SysPrintf("flushing FDIV pipe\n"); // Console::WriteLn("flushing FDIV pipe");
VU->efu.enable = 0; VU->efu.enable = 0;
} }
} }
@ -199,13 +199,13 @@ void _recvuIALUflush(VURegs * VU, bool intermediate) {
if( intermediate ) { if( intermediate ) {
if ((vucycle - VU->ialu[i].sCycle) > VU->ialu[i].Cycle) { if ((vucycle - VU->ialu[i].sCycle) > VU->ialu[i].Cycle) {
// VUM_LOG("flushing IALU pipe[%d]\n", i); // VUM_LOG("flushing IALU pipe[%d]", i);
VU->ialu[i].enable = 0; VU->ialu[i].enable = 0;
} }
} }
else { else {
if ((vucycle - VU->ialu[i].sCycle) >= VU->ialu[i].Cycle) { if ((vucycle - VU->ialu[i].sCycle) >= VU->ialu[i].Cycle) {
// VUM_LOG("flushing IALU pipe[%d]\n", i); // VUM_LOG("flushing IALU pipe[%d]", i);
VU->ialu[i].enable = 0; VU->ialu[i].enable = 0;
} }
} }
@ -291,8 +291,8 @@ void _recvuFMACAdd(VURegs * VU, int reg, int xyzw) {
break; break;
} }
if (i==8) SysPrintf("*PCSX2*: error , out of fmacs\n"); if (i==8) Console::Error("*PCSX2*: error , out of fmacs");
// VUM_LOG("adding FMAC pipe[%d]; reg %d\n", i, reg); // VUM_LOG("adding FMAC pipe[%d]; reg %d", i, reg);
VU->fmac[i].enable = 1; VU->fmac[i].enable = 1;
VU->fmac[i].sCycle = vucycle; VU->fmac[i].sCycle = vucycle;
@ -302,14 +302,14 @@ void _recvuFMACAdd(VURegs * VU, int reg, int xyzw) {
} }
void _recvuFDIVAdd(VURegs * VU, int cycles) { void _recvuFDIVAdd(VURegs * VU, int cycles) {
// SysPrintf("adding FDIV pipe\n"); // Console::WriteLn("adding FDIV pipe");
VU->fdiv.enable = 1; VU->fdiv.enable = 1;
VU->fdiv.sCycle = vucycle; VU->fdiv.sCycle = vucycle;
VU->fdiv.Cycle = cycles; VU->fdiv.Cycle = cycles;
} }
void _recvuEFUAdd(VURegs * VU, int cycles) { void _recvuEFUAdd(VURegs * VU, int cycles) {
// SysPrintf("adding EFU pipe\n"); // Console::WriteLn("adding EFU pipe");
VU->efu.enable = 1; VU->efu.enable = 1;
VU->efu.sCycle = vucycle; VU->efu.sCycle = vucycle;
VU->efu.Cycle = cycles; VU->efu.Cycle = cycles;
@ -324,7 +324,7 @@ void _recvuIALUAdd(VURegs * VU, int reg, int cycles) {
break; break;
} }
if (i==8) SysPrintf("*PCSX2*: error , out of ialus\n"); if (i==8) Console::Error("*PCSX2*: error , out of ialus");
VU->ialu[i].enable = 1; VU->ialu[i].enable = 1;
VU->ialu[i].sCycle = vucycle; VU->ialu[i].sCycle = vucycle;
@ -388,7 +388,7 @@ void _recvuFlushFDIV(VURegs * VU) {
if (VU->fdiv.enable == 0) return; if (VU->fdiv.enable == 0) return;
cycle = VU->fdiv.Cycle - (vucycle - VU->fdiv.sCycle); cycle = VU->fdiv.Cycle - (vucycle - VU->fdiv.sCycle);
// SysPrintf("waiting FDIV pipe %d\n", cycle); // Console::WriteLn("waiting FDIV pipe %d", params cycle);
VU->fdiv.enable = 0; VU->fdiv.enable = 0;
vucycle+= cycle; vucycle+= cycle;
} }
@ -399,7 +399,7 @@ void _recvuFlushEFU(VURegs * VU) {
if (VU->efu.enable == 0) return; if (VU->efu.enable == 0) return;
cycle = VU->efu.Cycle - (vucycle - VU->efu.sCycle); cycle = VU->efu.Cycle - (vucycle - VU->efu.sCycle);
// SysPrintf("waiting FDIV pipe %d\n", cycle); // Console::WriteLn("waiting FDIV pipe %d", params cycle);
VU->efu.enable = 0; VU->efu.enable = 0;
vucycle+= cycle; vucycle+= cycle;
} }
@ -1724,9 +1724,9 @@ void testPrintOverflow() {
tempRegX[2] &= 0xff800000; tempRegX[2] &= 0xff800000;
tempRegX[3] &= 0xff800000; tempRegX[3] &= 0xff800000;
if ( (tempRegX[0] == 0x7f800000) || (tempRegX[1] == 0x7f800000) || (tempRegX[2] == 0x7f800000) || (tempRegX[3] == 0x7f800000) ) if ( (tempRegX[0] == 0x7f800000) || (tempRegX[1] == 0x7f800000) || (tempRegX[2] == 0x7f800000) || (tempRegX[3] == 0x7f800000) )
SysPrintf( "VU OVERFLOW!: Changing to +Fmax!!!!!!!!!!!!\n" ); Console::Notice( "VU OVERFLOW!: Changing to +Fmax!!!!!!!!!!!!" );
if ( (tempRegX[0] == 0xff800000) || (tempRegX[1] == 0xff800000) || (tempRegX[2] == 0xff800000) || (tempRegX[3] == 0xff800000) ) if ( (tempRegX[0] == 0xff800000) || (tempRegX[1] == 0xff800000) || (tempRegX[2] == 0xff800000) || (tempRegX[3] == 0xff800000) )
SysPrintf( "VU OVERFLOW!: Changing to -Fmax!!!!!!!!!!!!\n" ); Console::Notice( "VU OVERFLOW!: Changing to -Fmax!!!!!!!!!!!!" );
} }
// Outputs to the console when overflow has occured. // Outputs to the console when overflow has occured.

View File

@ -91,7 +91,7 @@ void recVUMI_DIV(VURegs *VU, int info)
u8 *pjmp, *pjmp1; u8 *pjmp, *pjmp1;
u32 *ajmp32, *bjmp32; u32 *ajmp32, *bjmp32;
//SysPrintf("recVUMI_DIV()\n"); //Console::WriteLn("recVUMI_DIV()");
AND32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0xFCF); // Clear D/I flags AND32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0xFCF); // Clear D/I flags
// FT can be zero here! so we need to check if its zero and set the correct flag. // FT can be zero here! so we need to check if its zero and set the correct flag.
@ -154,7 +154,7 @@ void recVUMI_DIV(VURegs *VU, int info)
void recVUMI_SQRT( VURegs *VU, int info ) void recVUMI_SQRT( VURegs *VU, int info )
{ {
u8* pjmp; u8* pjmp;
//SysPrintf("recVUMI_SQRT()\n"); //Console::WriteLn("recVUMI_SQRT()");
_unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, _Ftf_); _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, _Ftf_);
AND32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0xFCF); // Clear D/I flags AND32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0xFCF); // Clear D/I flags
@ -181,8 +181,9 @@ PCSX2_ALIGNED16(u64 RSQRT_TEMP_XMM[2]);
void recVUMI_RSQRT(VURegs *VU, int info) void recVUMI_RSQRT(VURegs *VU, int info)
{ {
u8 *ajmp8, *bjmp8; u8 *ajmp8, *bjmp8;
u8 *qjmp1, *qjmp2;
int t1reg, t1boolean; int t1reg, t1boolean;
//SysPrintf("recVUMI_RSQRT()\n"); //Console::WriteLn("recVUMI_RSQRT()");
_unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, _Ftf_); _unpackVFSS_xyzw(EEREC_TEMP, EEREC_T, _Ftf_);
AND32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0xFCF); // Clear D/I flags AND32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0xFCF); // Clear D/I flags
@ -215,11 +216,24 @@ void recVUMI_RSQRT(VURegs *VU, int info)
AND32ItoR( EAX, 0x01 ); // Grab "Is Zero" bits from the previous calculation AND32ItoR( EAX, 0x01 ); // Grab "Is Zero" bits from the previous calculation
ajmp8 = JZ8(0); // Skip if none are ajmp8 = JZ8(0); // Skip if none are
OR32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x820); // Zero divide flag
//check for 0/0
_unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_);
SSE_XORPS_XMM_to_XMM(t1reg, t1reg); // Clear EEREC_TEMP
SSE_CMPEQPS_XMM_to_XMM(t1reg, EEREC_TEMP); // Set all F's if each vector is zero
SSE_MOVMSKPS_XMM_to_R32(EAX, t1reg); // Move the sign bits of the previous calculation
AND32ItoR( EAX, 0x01 ); // Grab "Is Zero" bits from the previous calculation
qjmp1 = JZ8(0);
OR32ItoM( VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x410 ); // Set invalid flag (0/0)
qjmp2 = JMP8(0);
x86SetJ8(qjmp1);
OR32ItoM( VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x820 ); // Zero divide (only when not 0/0)
x86SetJ8(qjmp2);
SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]); SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)&const_clip[4]);
SSE_ORPS_M128_to_XMM(EEREC_TEMP, (uptr)&g_maxvals[0]); // EEREC_TEMP = +/-Max SSE_ORPS_M128_to_XMM(EEREC_TEMP, (uptr)&g_maxvals[0]); // If division by zero, then EEREC_TEMP = +/- fmax
SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_Q, 0), EEREC_TEMP); SSE_MOVSS_XMM_to_M32(VU_VI_ADDR(REG_Q, 0), EEREC_TEMP);
bjmp8 = JMP8(0); bjmp8 = JMP8(0);
x86SetJ8(ajmp8); x86SetJ8(ajmp8);
@ -278,7 +292,7 @@ void recVUMI_IADDI(VURegs *VU, int info)
s16 imm; s16 imm;
if ( _Ft_ == 0 ) return; if ( _Ft_ == 0 ) return;
//SysPrintf("recVUMI_IADDI \n"); //Console::WriteLn("recVUMI_IADDI");
imm = ( VU->code >> 6 ) & 0x1f; imm = ( VU->code >> 6 ) & 0x1f;
imm = ( imm & 0x10 ? 0xfff0 : 0) | ( imm & 0xf ); imm = ( imm & 0x10 ? 0xfff0 : 0) | ( imm & 0xf );
_addISIMMtoIT(VU, imm, info); _addISIMMtoIT(VU, imm, info);
@ -294,7 +308,7 @@ void recVUMI_IADDIU(VURegs *VU, int info)
s16 imm; s16 imm;
if ( _Ft_ == 0 ) return; if ( _Ft_ == 0 ) return;
//SysPrintf("recVUMI_IADDIU \n"); //Console::WriteLn("recVUMI_IADDIU");
imm = ( ( VU->code >> 10 ) & 0x7800 ) | ( VU->code & 0x7ff ); imm = ( ( VU->code >> 10 ) & 0x7800 ) | ( VU->code & 0x7ff );
_addISIMMtoIT(VU, imm, info); _addISIMMtoIT(VU, imm, info);
} }
@ -308,7 +322,7 @@ void recVUMI_IADD( VURegs *VU, int info )
{ {
int fdreg, fsreg = -1, ftreg = -1; int fdreg, fsreg = -1, ftreg = -1;
if ( _Fd_ == 0 ) return; if ( _Fd_ == 0 ) return;
//SysPrintf("recVUMI_IADD \n"); //Console::WriteLn("recVUMI_IADD");
if ( ( _Ft_ == 0 ) && ( _Fs_ == 0 ) ) { if ( ( _Ft_ == 0 ) && ( _Fs_ == 0 ) ) {
fdreg = ALLOCVI(_Fd_, MODE_WRITE); fdreg = ALLOCVI(_Fd_, MODE_WRITE);
XOR32RtoR(fdreg, fdreg); XOR32RtoR(fdreg, fdreg);
@ -354,7 +368,7 @@ void recVUMI_IAND( VURegs *VU, int info )
{ {
int fdreg, fsreg = -1, ftreg = -1; int fdreg, fsreg = -1, ftreg = -1;
if ( _Fd_ == 0 ) return; if ( _Fd_ == 0 ) return;
//SysPrintf("recVUMI_IAND \n"); //Console::WriteLn("recVUMI_IAND");
if ( ( _Fs_ == 0 ) || ( _Ft_ == 0 ) ) { if ( ( _Fs_ == 0 ) || ( _Ft_ == 0 ) ) {
fdreg = ALLOCVI(_Fd_, MODE_WRITE); fdreg = ALLOCVI(_Fd_, MODE_WRITE);
XOR32RtoR(fdreg, fdreg); XOR32RtoR(fdreg, fdreg);
@ -385,7 +399,7 @@ void recVUMI_IOR( VURegs *VU, int info )
{ {
int fdreg, fsreg = -1, ftreg = -1; int fdreg, fsreg = -1, ftreg = -1;
if ( _Fd_ == 0 ) return; if ( _Fd_ == 0 ) return;
//SysPrintf("recVUMI_IOR \n"); //Console::WriteLn("recVUMI_IOR");
if ( ( _Ft_ == 0 ) && ( _Fs_ == 0 ) ) { if ( ( _Ft_ == 0 ) && ( _Fs_ == 0 ) ) {
fdreg = ALLOCVI(_Fd_, MODE_WRITE); fdreg = ALLOCVI(_Fd_, MODE_WRITE);
XOR32RtoR(fdreg, fdreg); XOR32RtoR(fdreg, fdreg);
@ -433,7 +447,7 @@ void recVUMI_ISUB( VURegs *VU, int info )
{ {
int fdreg, fsreg = -1, ftreg = -1; int fdreg, fsreg = -1, ftreg = -1;
if ( _Fd_ == 0 ) return; if ( _Fd_ == 0 ) return;
//SysPrintf("recVUMI_ISUB \n"); //Console::WriteLn("recVUMI_ISUB");
if ( ( _Ft_ == 0 ) && ( _Fs_ == 0 ) ) { if ( ( _Ft_ == 0 ) && ( _Fs_ == 0 ) ) {
fdreg = ALLOCVI(_Fd_, MODE_WRITE); fdreg = ALLOCVI(_Fd_, MODE_WRITE);
XOR32RtoR(fdreg, fdreg); XOR32RtoR(fdreg, fdreg);
@ -485,7 +499,7 @@ void recVUMI_ISUBIU( VURegs *VU, int info )
s16 imm; s16 imm;
if ( _Ft_ == 0 ) return; if ( _Ft_ == 0 ) return;
//SysPrintf("recVUMI_ISUBIU \n"); //Console::WriteLn("recVUMI_ISUBIU");
imm = ( ( VU->code >> 10 ) & 0x7800 ) | ( VU->code & 0x7ff ); imm = ( ( VU->code >> 10 ) & 0x7800 ) | ( VU->code & 0x7ff );
imm = -imm; imm = -imm;
_addISIMMtoIT(VU, imm, info); _addISIMMtoIT(VU, imm, info);
@ -499,7 +513,7 @@ void recVUMI_ISUBIU( VURegs *VU, int info )
void recVUMI_MOVE( VURegs *VU, int info ) void recVUMI_MOVE( VURegs *VU, int info )
{ {
if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return;
//SysPrintf("recVUMI_MOVE \n"); //Console::WriteLn("recVUMI_MOVE");
if (_X_Y_Z_W == 0x8) SSE_MOVSS_XMM_to_XMM(EEREC_T, EEREC_S); if (_X_Y_Z_W == 0x8) SSE_MOVSS_XMM_to_XMM(EEREC_T, EEREC_S);
else if (_X_Y_Z_W == 0xf) SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_S); else if (_X_Y_Z_W == 0xf) SSE_MOVAPS_XMM_to_XMM(EEREC_T, EEREC_S);
else { else {
@ -516,7 +530,7 @@ void recVUMI_MOVE( VURegs *VU, int info )
void recVUMI_MFIR( VURegs *VU, int info ) void recVUMI_MFIR( VURegs *VU, int info )
{ {
if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return;
//SysPrintf("recVUMI_MFIR \n"); //Console::WriteLn("recVUMI_MFIR");
_deleteX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Fs_, 1); _deleteX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Fs_, 1);
if( _XYZW_SS ) { if( _XYZW_SS ) {
@ -547,7 +561,7 @@ void recVUMI_MFIR( VURegs *VU, int info )
void recVUMI_MTIR( VURegs *VU, int info ) void recVUMI_MTIR( VURegs *VU, int info )
{ {
if ( _Ft_ == 0 ) return; if ( _Ft_ == 0 ) return;
//SysPrintf("recVUMI_MTIR \n"); //Console::WriteLn("recVUMI_MTIR");
_deleteX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Ft_, 2); _deleteX86reg(X86TYPE_VI|((VU==&VU1)?X86TYPE_VU1:0), _Ft_, 2);
if( _Fsf_ == 0 ) { if( _Fsf_ == 0 ) {
@ -569,7 +583,7 @@ void recVUMI_MTIR( VURegs *VU, int info )
void recVUMI_MR32( VURegs *VU, int info ) void recVUMI_MR32( VURegs *VU, int info )
{ {
if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return;
//SysPrintf("recVUMI_MR32 \n"); //Console::WriteLn("recVUMI_MR32");
if (_X_Y_Z_W != 0xf) { if (_X_Y_Z_W != 0xf) {
SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S); SSE_MOVAPS_XMM_to_XMM(EEREC_TEMP, EEREC_S);
SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x39); SSE_SHUFPS_XMM_to_XMM(EEREC_TEMP, EEREC_TEMP, 0x39);
@ -707,7 +721,7 @@ void recVUMI_LQ(VURegs *VU, int info)
{ {
s16 imm; s16 imm;
if ( _Ft_ == 0 ) return; if ( _Ft_ == 0 ) return;
//SysPrintf("recVUMI_LQ \n"); //Console::WriteLn("recVUMI_LQ");
imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff);
if (_Fs_ == 0) { if (_Fs_ == 0) {
_loadEAX(VU, -1, (uptr)GET_VU_MEM(VU, (u32)imm*16), info); _loadEAX(VU, -1, (uptr)GET_VU_MEM(VU, (u32)imm*16), info);
@ -726,7 +740,7 @@ void recVUMI_LQ(VURegs *VU, int info)
void recVUMI_LQD( VURegs *VU, int info ) void recVUMI_LQD( VURegs *VU, int info )
{ {
int fsreg; int fsreg;
//SysPrintf("recVUMI_LQD \n"); //Console::WriteLn("recVUMI_LQD");
if ( _Fs_ != 0 ) { if ( _Fs_ != 0 ) {
fsreg = ALLOCVI(_Fs_, MODE_READ|MODE_WRITE); fsreg = ALLOCVI(_Fs_, MODE_READ|MODE_WRITE);
SUB16ItoR( fsreg, 1 ); SUB16ItoR( fsreg, 1 );
@ -746,7 +760,7 @@ void recVUMI_LQD( VURegs *VU, int info )
void recVUMI_LQI(VURegs *VU, int info) void recVUMI_LQI(VURegs *VU, int info)
{ {
int fsreg; int fsreg;
//SysPrintf("recVUMI_LQI \n"); //Console::WriteLn("recVUMI_LQI");
if ( _Ft_ == 0 ) { if ( _Ft_ == 0 ) {
if( _Fs_ != 0 ) { if( _Fs_ != 0 ) {
if( (fsreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_WRITE|MODE_READ)) >= 0 ) { if( (fsreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_WRITE|MODE_READ)) >= 0 ) {
@ -937,7 +951,7 @@ void _saveEAX(VURegs *VU, int x86reg, uptr offset, int info)
void recVUMI_SQ(VURegs *VU, int info) void recVUMI_SQ(VURegs *VU, int info)
{ {
s16 imm; s16 imm;
//SysPrintf("recVUMI_SQ \n"); //Console::WriteLn("recVUMI_SQ");
imm = ( VU->code & 0x400) ? ( VU->code & 0x3ff) | 0xfc00 : ( VU->code & 0x3ff); imm = ( VU->code & 0x400) ? ( VU->code & 0x3ff) | 0xfc00 : ( VU->code & 0x3ff);
if ( _Ft_ == 0 ) _saveEAX(VU, -1, (uptr)GET_VU_MEM(VU, (int)imm * 16), info); if ( _Ft_ == 0 ) _saveEAX(VU, -1, (uptr)GET_VU_MEM(VU, (int)imm * 16), info);
else { else {
@ -953,7 +967,7 @@ void recVUMI_SQ(VURegs *VU, int info)
//------------------------------------------------------------------ //------------------------------------------------------------------
void recVUMI_SQD(VURegs *VU, int info) void recVUMI_SQD(VURegs *VU, int info)
{ {
//SysPrintf("recVUMI_SQD \n"); //Console::WriteLn("recVUMI_SQD");
if (_Ft_ == 0) _saveEAX(VU, -1, (uptr)VU->Mem, info); if (_Ft_ == 0) _saveEAX(VU, -1, (uptr)VU->Mem, info);
else { else {
int ftreg = ALLOCVI(_Ft_, MODE_READ|MODE_WRITE); int ftreg = ALLOCVI(_Ft_, MODE_READ|MODE_WRITE);
@ -969,7 +983,7 @@ void recVUMI_SQD(VURegs *VU, int info)
//------------------------------------------------------------------ //------------------------------------------------------------------
void recVUMI_SQI(VURegs *VU, int info) void recVUMI_SQI(VURegs *VU, int info)
{ {
//SysPrintf("recVUMI_SQI \n"); //Console::WriteLn("recVUMI_SQI");
if (_Ft_ == 0) _saveEAX(VU, -1, (uptr)VU->Mem, info); if (_Ft_ == 0) _saveEAX(VU, -1, (uptr)VU->Mem, info);
else { else {
int ftreg = ALLOCVI(_Ft_, MODE_READ|MODE_WRITE); int ftreg = ALLOCVI(_Ft_, MODE_READ|MODE_WRITE);
@ -989,7 +1003,7 @@ void recVUMI_ILW(VURegs *VU, int info)
s16 imm, off; s16 imm, off;
if ( ( _Ft_ == 0 ) || ( _X_Y_Z_W == 0 ) ) return; if ( ( _Ft_ == 0 ) || ( _X_Y_Z_W == 0 ) ) return;
//SysPrintf("recVUMI_ILW \n"); //Console::WriteLn("recVUMI_ILW");
imm = ( VU->code & 0x400) ? ( VU->code & 0x3ff) | 0xfc00 : ( VU->code & 0x3ff); imm = ( VU->code & 0x400) ? ( VU->code & 0x3ff) | 0xfc00 : ( VU->code & 0x3ff);
if (_X) off = 0; if (_X) off = 0;
else if (_Y) off = 4; else if (_Y) off = 4;
@ -1016,7 +1030,7 @@ void recVUMI_ILW(VURegs *VU, int info)
void recVUMI_ISW( VURegs *VU, int info ) void recVUMI_ISW( VURegs *VU, int info )
{ {
s16 imm; s16 imm;
//SysPrintf("recVUMI_ISW \n"); //Console::WriteLn("recVUMI_ISW");
imm = ( VU->code & 0x400) ? ( VU->code & 0x3ff) | 0xfc00 : ( VU->code & 0x3ff); imm = ( VU->code & 0x400) ? ( VU->code & 0x3ff) | 0xfc00 : ( VU->code & 0x3ff);
if (_Fs_ == 0) { if (_Fs_ == 0) {
@ -1054,7 +1068,7 @@ void recVUMI_ILWR( VURegs *VU, int info )
int off, ftreg; int off, ftreg;
if ( ( _Ft_ == 0 ) || ( _X_Y_Z_W == 0 ) ) return; if ( ( _Ft_ == 0 ) || ( _X_Y_Z_W == 0 ) ) return;
//SysPrintf("recVUMI_ILWR \n"); //Console::WriteLn("recVUMI_ILWR");
if (_X) off = 0; if (_X) off = 0;
else if (_Y) off = 4; else if (_Y) off = 4;
else if (_Z) off = 8; else if (_Z) off = 8;
@ -1080,7 +1094,7 @@ void recVUMI_ILWR( VURegs *VU, int info )
void recVUMI_ISWR( VURegs *VU, int info ) void recVUMI_ISWR( VURegs *VU, int info )
{ {
int ftreg; int ftreg;
//SysPrintf("recVUMI_ISWR \n"); //Console::WriteLn("recVUMI_ISWR");
ADD_VI_NEEDED(_Fs_); ADD_VI_NEEDED(_Fs_);
ftreg = ALLOCVI(_Ft_, MODE_READ); ftreg = ALLOCVI(_Ft_, MODE_READ);
@ -1109,7 +1123,7 @@ void recVUMI_ISWR( VURegs *VU, int info )
//------------------------------------------------------------------ //------------------------------------------------------------------
void recVUMI_RINIT(VURegs *VU, int info) void recVUMI_RINIT(VURegs *VU, int info)
{ {
//SysPrintf("recVUMI_RINIT()\n"); //Console::WriteLn("recVUMI_RINIT()");
if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode & MODE_NOFLUSH) ) { if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode & MODE_NOFLUSH) ) {
_deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 2); _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 2);
_unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_);
@ -1141,7 +1155,7 @@ void recVUMI_RINIT(VURegs *VU, int info)
//------------------------------------------------------------------ //------------------------------------------------------------------
void recVUMI_RGET(VURegs *VU, int info) void recVUMI_RGET(VURegs *VU, int info)
{ {
//SysPrintf("recVUMI_RGET()\n"); //Console::WriteLn("recVUMI_RGET()");
if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return;
_deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1); _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1);
@ -1165,7 +1179,7 @@ void recVUMI_RGET(VURegs *VU, int info)
void recVUMI_RNEXT( VURegs *VU, int info ) void recVUMI_RNEXT( VURegs *VU, int info )
{ {
int rreg, x86temp0, x86temp1; int rreg, x86temp0, x86temp1;
//SysPrintf("recVUMI_RNEXT()\n"); //Console::WriteLn("recVUMI_RNEXT()");
rreg = ALLOCVI(REG_R, MODE_WRITE|MODE_READ); rreg = ALLOCVI(REG_R, MODE_WRITE|MODE_READ);
@ -1206,7 +1220,7 @@ void recVUMI_RNEXT( VURegs *VU, int info )
//------------------------------------------------------------------ //------------------------------------------------------------------
void recVUMI_RXOR( VURegs *VU, int info ) void recVUMI_RXOR( VURegs *VU, int info )
{ {
//SysPrintf("recVUMI_RXOR()\n"); //Console::WriteLn("recVUMI_RXOR()");
if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode & MODE_NOFLUSH) ) { if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode & MODE_NOFLUSH) ) {
_deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1); _deleteX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), REG_R, 1);
_unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_);
@ -1239,7 +1253,7 @@ void recVUMI_RXOR( VURegs *VU, int info )
//------------------------------------------------------------------ //------------------------------------------------------------------
void recVUMI_WAITQ( VURegs *VU, int info ) void recVUMI_WAITQ( VURegs *VU, int info )
{ {
//SysPrintf("recVUMI_WAITQ \n"); //Console::WriteLn("recVUMI_WAITQ");
// if( info & PROCESS_VU_SUPER ) { // if( info & PROCESS_VU_SUPER ) {
// //CALLFunc(waitqfn); // //CALLFunc(waitqfn);
// SuperVUFlush(0, 1); // SuperVUFlush(0, 1);
@ -1255,7 +1269,7 @@ void recVUMI_FSAND( VURegs *VU, int info )
{ {
int ftreg; int ftreg;
u16 imm; u16 imm;
//SysPrintf("recVUMI_FSAND \n"); //Console::WriteLn("recVUMI_FSAND");
imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff);
if(_Ft_ == 0) return; if(_Ft_ == 0) return;
@ -1274,7 +1288,7 @@ void recVUMI_FSEQ( VURegs *VU, int info )
int ftreg; int ftreg;
u16 imm; u16 imm;
if ( _Ft_ == 0 ) return; if ( _Ft_ == 0 ) return;
//SysPrintf("recVUMI_FSEQ\n"); //Console::WriteLn("recVUMI_FSEQ");
imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff);
ftreg = ALLOCVI(_Ft_, MODE_WRITE|MODE_8BITREG); ftreg = ALLOCVI(_Ft_, MODE_WRITE|MODE_8BITREG);
@ -1295,7 +1309,7 @@ void recVUMI_FSOR( VURegs *VU, int info )
int ftreg; int ftreg;
u32 imm; u32 imm;
if(_Ft_ == 0) return; if(_Ft_ == 0) return;
//SysPrintf("recVUMI_FSOR \n"); //Console::WriteLn("recVUMI_FSOR");
imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff); imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7ff);
ftreg = ALLOCVI(_Ft_, MODE_WRITE); ftreg = ALLOCVI(_Ft_, MODE_WRITE);
@ -1315,7 +1329,7 @@ void recVUMI_FSSET(VURegs *VU, int info)
u32 prevaddr = VU_VI_ADDR(REG_STATUS_FLAG, 2); u32 prevaddr = VU_VI_ADDR(REG_STATUS_FLAG, 2);
u16 imm = 0; u16 imm = 0;
//SysPrintf("recVUMI_FSSET \n"); //Console::WriteLn("recVUMI_FSSET");
imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7FF); imm = (((VU->code >> 21 ) & 0x1) << 11) | (VU->code & 0x7FF);
// keep the low 6 bits ONLY if the upper instruction is an fmac instruction (otherwise rewrite) - metal gear solid 3 // keep the low 6 bits ONLY if the upper instruction is an fmac instruction (otherwise rewrite) - metal gear solid 3
@ -1339,7 +1353,7 @@ void recVUMI_FMAND( VURegs *VU, int info )
{ {
int fsreg, ftreg; int fsreg, ftreg;
if ( _Ft_ == 0 ) return; if ( _Ft_ == 0 ) return;
//SysPrintf("recVUMI_FMAND \n"); //Console::WriteLn("recVUMI_FMAND");
fsreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_READ); fsreg = _checkX86reg(X86TYPE_VI|(VU==&VU1?X86TYPE_VU1:0), _Fs_, MODE_READ);
ftreg = ALLOCVI(_Ft_, MODE_WRITE);//|MODE_8BITREG); ftreg = ALLOCVI(_Ft_, MODE_WRITE);//|MODE_8BITREG);
@ -1360,7 +1374,7 @@ void recVUMI_FMEQ( VURegs *VU, int info )
{ {
int ftreg, fsreg; int ftreg, fsreg;
if ( _Ft_ == 0 ) return; if ( _Ft_ == 0 ) return;
//SysPrintf("recVUMI_FMEQ \n"); //Console::WriteLn("recVUMI_FMEQ");
if( _Ft_ == _Fs_ ) { if( _Ft_ == _Fs_ ) {
ftreg = ALLOCVI(_Ft_, MODE_WRITE|MODE_READ);//|MODE_8BITREG ftreg = ALLOCVI(_Ft_, MODE_WRITE|MODE_READ);//|MODE_8BITREG
@ -1389,7 +1403,7 @@ void recVUMI_FMOR( VURegs *VU, int info )
{ {
int fsreg, ftreg; int fsreg, ftreg;
if ( _Ft_ == 0 ) return; if ( _Ft_ == 0 ) return;
//SysPrintf("recVUMI_FMOR \n"); //Console::WriteLn("recVUMI_FMOR");
if( _Fs_ == 0 ) { if( _Fs_ == 0 ) {
ftreg = ALLOCVI(_Ft_, MODE_WRITE);//|MODE_8BITREG); ftreg = ALLOCVI(_Ft_, MODE_WRITE);//|MODE_8BITREG);
MOVZX32M16toR( ftreg, VU_VI_ADDR(REG_MAC_FLAG, 1) ); MOVZX32M16toR( ftreg, VU_VI_ADDR(REG_MAC_FLAG, 1) );
@ -1419,7 +1433,7 @@ void recVUMI_FMOR( VURegs *VU, int info )
void recVUMI_FCAND( VURegs *VU, int info ) void recVUMI_FCAND( VURegs *VU, int info )
{ {
int ftreg = ALLOCVI(1, MODE_WRITE|MODE_8BITREG); int ftreg = ALLOCVI(1, MODE_WRITE|MODE_8BITREG);
//SysPrintf("recVUMI_FCAND \n"); //Console::WriteLn("recVUMI_FCAND");
MOV32MtoR( EAX, VU_VI_ADDR(REG_CLIP_FLAG, 1) ); MOV32MtoR( EAX, VU_VI_ADDR(REG_CLIP_FLAG, 1) );
XOR32RtoR( ftreg, ftreg ); XOR32RtoR( ftreg, ftreg );
AND32ItoR( EAX, VU->code & 0xFFFFFF ); AND32ItoR( EAX, VU->code & 0xFFFFFF );
@ -1435,7 +1449,7 @@ void recVUMI_FCAND( VURegs *VU, int info )
void recVUMI_FCEQ( VURegs *VU, int info ) void recVUMI_FCEQ( VURegs *VU, int info )
{ {
int ftreg = ALLOCVI(1, MODE_WRITE|MODE_8BITREG); int ftreg = ALLOCVI(1, MODE_WRITE|MODE_8BITREG);
//SysPrintf("recVUMI_FCEQ \n"); //Console::WriteLn("recVUMI_FCEQ");
MOV32MtoR( EAX, VU_VI_ADDR(REG_CLIP_FLAG, 1) ); MOV32MtoR( EAX, VU_VI_ADDR(REG_CLIP_FLAG, 1) );
AND32ItoR( EAX, 0xffffff ); AND32ItoR( EAX, 0xffffff );
XOR32RtoR( ftreg, ftreg ); XOR32RtoR( ftreg, ftreg );
@ -1452,7 +1466,7 @@ void recVUMI_FCEQ( VURegs *VU, int info )
void recVUMI_FCOR( VURegs *VU, int info ) void recVUMI_FCOR( VURegs *VU, int info )
{ {
int ftreg; int ftreg;
//SysPrintf("recVUMI_FCOR\n"); //Console::WriteLn("recVUMI_FCOR");
ftreg = ALLOCVI(1, MODE_WRITE); ftreg = ALLOCVI(1, MODE_WRITE);
MOV32MtoR( ftreg, VU_VI_ADDR(REG_CLIP_FLAG, 1) ); MOV32MtoR( ftreg, VU_VI_ADDR(REG_CLIP_FLAG, 1) );
OR32ItoR ( ftreg, VU->code ); OR32ItoR ( ftreg, VU->code );
@ -1469,7 +1483,7 @@ void recVUMI_FCOR( VURegs *VU, int info )
void recVUMI_FCSET( VURegs *VU, int info ) void recVUMI_FCSET( VURegs *VU, int info )
{ {
u32 addr = VU_VI_ADDR(REG_CLIP_FLAG, 0); u32 addr = VU_VI_ADDR(REG_CLIP_FLAG, 0);
//SysPrintf("recVUMI_FCSET \n"); //Console::WriteLn("recVUMI_FCSET");
MOV32ItoM(addr ? addr : VU_VI_ADDR(REG_CLIP_FLAG, 2), VU->code&0xffffff ); MOV32ItoM(addr ? addr : VU_VI_ADDR(REG_CLIP_FLAG, 2), VU->code&0xffffff );
if( !(info & (PROCESS_VU_SUPER|PROCESS_VU_COP2)) ) if( !(info & (PROCESS_VU_SUPER|PROCESS_VU_COP2)) )
@ -1485,7 +1499,7 @@ void recVUMI_FCGET( VURegs *VU, int info )
{ {
int ftreg; int ftreg;
if(_Ft_ == 0) return; if(_Ft_ == 0) return;
//SysPrintf("recVUMI_FCGET \n"); //Console::WriteLn("recVUMI_FCGET");
ftreg = ALLOCVI(_Ft_, MODE_WRITE); ftreg = ALLOCVI(_Ft_, MODE_WRITE);
MOV32MtoR(ftreg, VU_VI_ADDR(REG_CLIP_FLAG, 1)); MOV32MtoR(ftreg, VU_VI_ADDR(REG_CLIP_FLAG, 1));
@ -1507,7 +1521,7 @@ void recVUMI_FCGET( VURegs *VU, int info )
void recVUMI_MFP(VURegs *VU, int info) void recVUMI_MFP(VURegs *VU, int info)
{ {
if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return; if ( (_Ft_ == 0) || (_X_Y_Z_W == 0) ) return;
//SysPrintf("recVUMI_MFP \n"); //Console::WriteLn("recVUMI_MFP");
if( _XYZW_SS ) { if( _XYZW_SS ) {
_vuFlipRegSS(VU, EEREC_T); _vuFlipRegSS(VU, EEREC_T);
SSE_MOVSS_M32_to_XMM(EEREC_TEMP, VU_VI_ADDR(REG_P, 1)); SSE_MOVSS_M32_to_XMM(EEREC_TEMP, VU_VI_ADDR(REG_P, 1));
@ -1533,7 +1547,7 @@ void recVUMI_MFP(VURegs *VU, int info)
static PCSX2_ALIGNED16(float s_tempmem[4]); static PCSX2_ALIGNED16(float s_tempmem[4]);
void recVUMI_WAITP(VURegs *VU, int info) void recVUMI_WAITP(VURegs *VU, int info)
{ {
//SysPrintf("recVUMI_WAITP \n"); //Console::WriteLn("recVUMI_WAITP");
// if( info & PROCESS_VU_SUPER ) // if( info & PROCESS_VU_SUPER )
// SuperVUFlush(1, 1); // SuperVUFlush(1, 1);
} }
@ -1547,7 +1561,7 @@ void recVUMI_WAITP(VURegs *VU, int info)
//------------------------------------------------------------------ //------------------------------------------------------------------
void vuSqSumXYZ(int regd, int regs, int regtemp) // regd.x = x ^ 2 + y ^ 2 + z ^ 2 void vuSqSumXYZ(int regd, int regs, int regtemp) // regd.x = x ^ 2 + y ^ 2 + z ^ 2
{ {
//SysPrintf("VU: SUMXYZ\n"); //Console::WriteLn("VU: SUMXYZ");
if( cpucaps.hasStreamingSIMD4Extensions ) if( cpucaps.hasStreamingSIMD4Extensions )
{ {
SSE_MOVAPS_XMM_to_XMM(regd, regs); SSE_MOVAPS_XMM_to_XMM(regd, regs);
@ -1582,7 +1596,7 @@ void vuSqSumXYZ(int regd, int regs, int regtemp) // regd.x = x ^ 2 + y ^ 2 + z
//------------------------------------------------------------------ //------------------------------------------------------------------
void recVUMI_ESADD( VURegs *VU, int info) void recVUMI_ESADD( VURegs *VU, int info)
{ {
//SysPrintf("VU: ESADD\n"); //Console::WriteLn("VU: ESADD");
assert( VU == &VU1 ); assert( VU == &VU1 );
if( EEREC_TEMP == EEREC_D ) { // special code to reset P ( FixMe: don't know if this is still needed! (cottonvibes) ) if( EEREC_TEMP == EEREC_D ) { // special code to reset P ( FixMe: don't know if this is still needed! (cottonvibes) )
Console::Notice("ESADD: Resetting P reg!!!\n"); Console::Notice("ESADD: Resetting P reg!!!\n");
@ -1601,7 +1615,7 @@ void recVUMI_ESADD( VURegs *VU, int info)
//------------------------------------------------------------------ //------------------------------------------------------------------
void recVUMI_ERSADD( VURegs *VU, int info ) void recVUMI_ERSADD( VURegs *VU, int info )
{ {
//SysPrintf("VU: ERSADD\n"); //Console::WriteLn("VU: ERSADD");
assert( VU == &VU1 ); assert( VU == &VU1 );
vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP); vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP);
// don't use RCPSS (very bad precision) // don't use RCPSS (very bad precision)
@ -1618,7 +1632,7 @@ void recVUMI_ERSADD( VURegs *VU, int info )
//------------------------------------------------------------------ //------------------------------------------------------------------
void recVUMI_ELENG( VURegs *VU, int info ) void recVUMI_ELENG( VURegs *VU, int info )
{ {
//SysPrintf("VU: ELENG\n"); //Console::WriteLn("VU: ELENG");
assert( VU == &VU1 ); assert( VU == &VU1 );
vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP); vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP);
if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_D, (uptr)g_maxvals); // Only need to do positive clamp since (x ^ 2 + y ^ 2 + z ^ 2) is positive if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_D, (uptr)g_maxvals); // Only need to do positive clamp since (x ^ 2 + y ^ 2 + z ^ 2) is positive
@ -1633,7 +1647,7 @@ void recVUMI_ELENG( VURegs *VU, int info )
//------------------------------------------------------------------ //------------------------------------------------------------------
void recVUMI_ERLENG( VURegs *VU, int info ) void recVUMI_ERLENG( VURegs *VU, int info )
{ {
//SysPrintf("VU: ERLENG\n"); //Console::WriteLn("VU: ERLENG");
assert( VU == &VU1 ); assert( VU == &VU1 );
vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP); vuSqSumXYZ(EEREC_D, EEREC_S, EEREC_TEMP);
if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_D, (uptr)g_maxvals); // Only need to do positive clamp since (x ^ 2 + y ^ 2 + z ^ 2) is positive if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_D, (uptr)g_maxvals); // Only need to do positive clamp since (x ^ 2 + y ^ 2 + z ^ 2) is positive
@ -1652,7 +1666,7 @@ void recVUMI_ERLENG( VURegs *VU, int info )
void recVUMI_EATANxy( VURegs *VU, int info ) void recVUMI_EATANxy( VURegs *VU, int info )
{ {
assert( VU == &VU1 ); assert( VU == &VU1 );
//SysPrintf("recVUMI_EATANxy \n"); //Console::WriteLn("recVUMI_EATANxy");
if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) {
SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S); SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S);
FLD32((uptr)&s_tempmem[0]); FLD32((uptr)&s_tempmem[0]);
@ -1680,7 +1694,7 @@ void recVUMI_EATANxy( VURegs *VU, int info )
void recVUMI_EATANxz( VURegs *VU, int info ) void recVUMI_EATANxz( VURegs *VU, int info )
{ {
assert( VU == &VU1 ); assert( VU == &VU1 );
//SysPrintf("recVUMI_EATANxz \n"); //Console::WriteLn("recVUMI_EATANxz");
if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) {
SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S); SSE_MOVLPS_XMM_to_M64((uptr)s_tempmem, EEREC_S);
FLD32((uptr)&s_tempmem[0]); FLD32((uptr)&s_tempmem[0]);
@ -1706,7 +1720,7 @@ void recVUMI_EATANxz( VURegs *VU, int info )
//------------------------------------------------------------------ //------------------------------------------------------------------
void recVUMI_ESUM( VURegs *VU, int info ) void recVUMI_ESUM( VURegs *VU, int info )
{ {
//SysPrintf("VU: ESUM\n"); //Console::WriteLn("VU: ESUM");
assert( VU == &VU1 ); assert( VU == &VU1 );
if( cpucaps.hasStreamingSIMD3Extensions ) { if( cpucaps.hasStreamingSIMD3Extensions ) {
@ -1735,7 +1749,7 @@ void recVUMI_ESUM( VURegs *VU, int info )
void recVUMI_ERCPR( VURegs *VU, int info ) void recVUMI_ERCPR( VURegs *VU, int info )
{ {
assert( VU == &VU1 ); assert( VU == &VU1 );
//SysPrintf("VU1: ERCPR\n"); //Console::WriteLn("VU1: ERCPR");
// don't use RCPSS (very bad precision) // don't use RCPSS (very bad precision)
switch ( _Fsf_ ) { switch ( _Fsf_ ) {
@ -1780,7 +1794,7 @@ void recVUMI_ESQRT( VURegs *VU, int info )
{ {
assert( VU == &VU1 ); assert( VU == &VU1 );
//SysPrintf("VU1: ESQRT\n"); //Console::WriteLn("VU1: ESQRT");
_unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_);
SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)const_clip); // abs(x) SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)const_clip); // abs(x)
if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Only need to do positive clamp if (CHECK_VU_OVERFLOW) SSE_MINSS_M32_to_XMM(EEREC_TEMP, (uptr)g_maxvals); // Only need to do positive clamp
@ -1799,7 +1813,7 @@ void recVUMI_ERSQRT( VURegs *VU, int info )
int t1reg = _vuGetTempXMMreg(info); int t1reg = _vuGetTempXMMreg(info);
assert( VU == &VU1 ); assert( VU == &VU1 );
//SysPrintf("VU1: ERSQRT\n"); //Console::WriteLn("VU1: ERSQRT");
_unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_); _unpackVFSS_xyzw(EEREC_TEMP, EEREC_S, _Fsf_);
SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)const_clip); // abs(x) SSE_ANDPS_M128_to_XMM(EEREC_TEMP, (uptr)const_clip); // abs(x)
@ -1833,7 +1847,7 @@ void recVUMI_ESIN( VURegs *VU, int info )
{ {
assert( VU == &VU1 ); assert( VU == &VU1 );
//SysPrintf("recVUMI_ESIN \n"); //Console::WriteLn("recVUMI_ESIN");
if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) {
switch(_Fsf_) { switch(_Fsf_) {
case 0: SSE_MOVSS_XMM_to_M32((uptr)s_tempmem, EEREC_S); case 0: SSE_MOVSS_XMM_to_M32((uptr)s_tempmem, EEREC_S);
@ -1864,7 +1878,7 @@ void recVUMI_EATAN( VURegs *VU, int info )
{ {
assert( VU == &VU1 ); assert( VU == &VU1 );
//SysPrintf("recVUMI_EATAN \n"); //Console::WriteLn("recVUMI_EATAN");
if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) {
switch(_Fsf_) { switch(_Fsf_) {
case 0: SSE_MOVSS_XMM_to_M32((uptr)s_tempmem, EEREC_S); case 0: SSE_MOVSS_XMM_to_M32((uptr)s_tempmem, EEREC_S);
@ -1894,7 +1908,7 @@ void recVUMI_EATAN( VURegs *VU, int info )
void recVUMI_EEXP( VURegs *VU, int info ) void recVUMI_EEXP( VURegs *VU, int info )
{ {
assert( VU == &VU1 ); assert( VU == &VU1 );
//SysPrintf("recVUMI_EEXP \n"); //Console::WriteLn("recVUMI_EEXP");
FLDL2E(); FLDL2E();
if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) { if( (xmmregs[EEREC_S].mode & MODE_WRITE) && (xmmregs[EEREC_S].mode&MODE_NOFLUSH) ) {
@ -1937,7 +1951,7 @@ void recVUMI_XITOP( VURegs *VU, int info )
{ {
int ftreg; int ftreg;
if (_Ft_ == 0) return; if (_Ft_ == 0) return;
//SysPrintf("recVUMI_XITOP \n"); //Console::WriteLn("recVUMI_XITOP");
ftreg = ALLOCVI(_Ft_, MODE_WRITE); ftreg = ALLOCVI(_Ft_, MODE_WRITE);
MOVZX32M16toR( ftreg, (uptr)&VU->vifRegs->itop ); MOVZX32M16toR( ftreg, (uptr)&VU->vifRegs->itop );
} }
@ -1951,7 +1965,7 @@ void recVUMI_XTOP( VURegs *VU, int info )
{ {
int ftreg; int ftreg;
if ( _Ft_ == 0 ) return; if ( _Ft_ == 0 ) return;
//SysPrintf("recVUMI_XTOP \n"); //Console::WriteLn("recVUMI_XTOP");
ftreg = ALLOCVI(_Ft_, MODE_WRITE); ftreg = ALLOCVI(_Ft_, MODE_WRITE);
MOVZX32M16toR( ftreg, (uptr)&VU->vifRegs->top ); MOVZX32M16toR( ftreg, (uptr)&VU->vifRegs->top );
} }

Some files were not shown because too many files have changed in this diff Show More