* synched with trunk to pick up all new cdvdiso fixes.
 * configuration wizard now starts if pcsx2.ini is missing/deleted.
 * changed GetWindowChild (MSW specific?) to FindWindow.

git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@1696 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-08-28 13:06:06 +00:00
commit 396783957e
64 changed files with 1842 additions and 657 deletions

View File

@ -59,6 +59,7 @@ extern SessionOverrideFlags g_Session;
//------------ CPU Options!!! ---------------
#define CHECK_MICROVU0 (Config.Options&PCSX2_MICROVU0)
#define CHECK_MICROVU1 (Config.Options&PCSX2_MICROVU1)
//#define CHECK_MACROVU0 // ifndef = Use sVU for VU macro, ifdef = Use mVU for VU macro
#define CHECK_EEREC (!g_Session.ForceDisableEErec && Config.Options&PCSX2_EEREC)
#define CHECK_VU0REC (!g_Session.ForceDisableVU0rec && Config.Options&PCSX2_VU0REC)
#define CHECK_VU1REC (!g_Session.ForceDisableVU1rec && (Config.Options&PCSX2_VU1REC))

View File

@ -334,7 +334,7 @@ void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) {
u8 key_4, key_14;
// get main elf name
GetPS2ElfName(fname);
bool IsPs2 = (GetPS2ElfName(fname) == 2);
const wxCharBuffer crap( fname.ToAscii() );
const char* str = crap.data();
sprintf(exeName, "%c%c%c%c%c%c%c%c%c%c%c",str[8],str[9],str[10],str[11],str[12],str[13],str[14],str[15],str[16],str[17],str[18]);
@ -397,11 +397,12 @@ void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) {
cdvd.Key[0],cdvd.Key[1],cdvd.Key[2],cdvd.Key[3],cdvd.Key[4],cdvd.Key[14],cdvd.Key[15] );
// Now's a good time to reload the ELF info...
if( ElfCRC == 0 )
if( IsPs2 && (ElfCRC == 0) )
{
ElfCRC = loadElfCRC( str );
ElfApplyPatches();
GSsetGameCRC( ElfCRC, 0 );
if( GSsetGameCRC != NULL )
GSsetGameCRC( ElfCRC, 0 );
}
}
@ -527,10 +528,10 @@ void cdvdDetectDisk()
cdvd.Type = DoCDVDdetectDiskType();
wxString str;
GetPS2ElfName(str);
bool IsPs2 = (GetPS2ElfName(str) == 2);
// Now's a good time to reload the ELF info...
if( ElfCRC == 0 )
if( IsPs2 && (ElfCRC == 0) )
{
ElfCRC = loadElfCRC( str.ToAscii().data() );
ElfApplyPatches();
@ -627,24 +628,7 @@ int cdvdReadSector() {
mdest[11] = 0;
// normal 2048 bytes of sector data
if (cdr.pTransfer == NULL)
{
// Unlike CDVDiso, the internal IsoReadTrack function will pass an error if lsn is more
// then the number of blocks in the iso. If this happens, cdr.pTransfer will be NULL.
//
// Passing null to memcpy is a bad thing, and will result in, for example, the start of
// Final Fantasy X-2 crashing. So we won't.
DevCon::WriteLn("Bad Transfer!");
for (int i = 12; i <= 2060; i++)
{
mdest[i] = 0;
}
}
else
{
memcpy_fast( &mdest[12], cdr.pTransfer, 2048);
}
memcpy_fast( &mdest[12], cdr.Transfer, 2048);
// 4 bytes of edc (not calculated at present)
mdest[2060] = 0;
@ -654,7 +638,7 @@ int cdvdReadSector() {
}
else
{
memcpy_fast( mdest, cdr.pTransfer, cdvd.BlockSize);
memcpy_fast( mdest, cdr.Transfer, cdvd.BlockSize);
}
// decrypt sector's bytes
@ -741,15 +725,8 @@ __forceinline void cdvdReadInterrupt()
if (cdvd.RErr == 0)
{
cdr.RErr = DoCDVDgetBuffer(cdr.Transfer);
cdr.pTransfer = cdr.Transfer;
}
else
{
DevCon::WriteLn("Error reading track.");
cdr.pTransfer = NULL;
}
if (cdr.RErr == -1)
else if (cdr.RErr == -1)
{
cdvd.RetryCntP++;
Console::Error("CDVD READ ERROR, sector=%d", params cdvd.Sector);

View File

@ -140,7 +140,7 @@ struct CDVD_API
// Don't need init or shutdown. iso/nodisc have no init/shutdown and plugin's
// is handled by the PluginManager.
// Don't need pluign specific things like freeze, test, or other stuff here.
// Don't need plugin specific things like freeze, test, or other stuff here.
// Those are handled by the plugin manager specifically.
_CDVDopen open;
@ -180,11 +180,16 @@ extern void cdvdWrite(u8 key, u8 rt);
// used to provide internal CDVDiso and NoDisc, and external plugin interfaces.
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Multiple interface system for CDVD
// used to provide internal CDVDiso and NoDisc, and external plugin interfaces.
// ---------------------------------------------------------------------------
enum CDVD_SourceType
{
CDVDsrc_Iso, // use built in ISO api
CDVDsrc_NoDisc, // use built in CDVDnull
CDVDsrc_Iso = 0, // use built in ISO api
CDVDsrc_Plugin, // use external plugin
CDVDsrc_NoDisc, // use built in CDVDnull
};
extern void CDVDsys_ChangeSource( CDVD_SourceType type );

View File

@ -25,6 +25,7 @@
#endif
#include <ctype.h>
#include <time.h>
#include <wx/datetime.h>
#include "IopCommon.h"
@ -38,18 +39,18 @@
// performed quite liberally by many games (perhaps intended to keep the PS2 DVD
// from spinning down due to idle activity?).
// Cache is set to -1 for init and when the disc is removed/changed, which invokes
// a new DiskTypeCheck. Al subsequent checks use the non-negative value here.
// a new DiskTypeCheck. All subsequent checks use the non-negative value here.
//
static int diskTypeCached=-1;
static int diskTypeCached = -1;
// used to bridge the gap between the old getBuffer api and the new getBuffer2 api.
int lastReadSize;
// Records last read block length for block dumping
static int plsn = 0;
static isoFile *blockDumpFile;
static isoFile *blockDumpFile = NULL;
// Assertion check for CDVD != NULL (in devel and debgu builds), because its handier than
// Assertion check for CDVD != NULL (in devel and debug builds), because its handier than
// relying on DEP exceptions -- and a little more reliable too.
static void CheckNullCDVD()
{
@ -103,8 +104,6 @@ int CheckDiskTypeFS(int baseType)
return CDVD_TYPE_ILLEGAL; // << Only for discs which aren't ps2 at all.
}
static char bleh[2352];
static int FindDiskType(int mType)
{
int dataTracks = 0;
@ -120,6 +119,7 @@ static int FindDiskType(int mType)
}
else if (mType < 0)
{
static u8 bleh[2352];
cdvdTD td;
CDVD->getTD(0,&td);
@ -127,14 +127,14 @@ static int FindDiskType(int mType)
{
iCDType = CDVD_TYPE_DETCTDVDS;
}
else if (DoCDVDreadSector((u8*)bleh,16,CDVD_MODE_2048) == 0)
else
{
struct cdVolDesc* volDesc=(struct cdVolDesc *)bleh;
if (volDesc)
{
if(volDesc->rootToc.tocSize==2048)
if (DoCDVDreadSector(bleh, 16, CDVD_MODE_2048) == 0)
{
const cdVolDesc& volDesc = (cdVolDesc&)bleh;
if(volDesc.rootToc.tocSize == 2048)
iCDType = CDVD_TYPE_DETCTCD;
else
else
iCDType = CDVD_TYPE_DETCTDVDS;
}
}
@ -264,8 +264,8 @@ static void DetectDiskType()
//
void CDVDsys_ChangeSource( CDVD_SourceType type )
{
if( CDVD != NULL )
DoCDVDclose();
if( g_plugins != NULL )
g_plugins->Close( PluginId_CDVD );
switch( type )
{
@ -349,6 +349,8 @@ void DoCDVDclose()
if(blockDumpFile) isoClose(blockDumpFile);
if( CDVD->close != NULL )
CDVD->close();
DoCDVDresetDiskTypeCache();
}
s32 DoCDVDreadSector(u8* buffer, u32 lsn, int mode)

View File

@ -16,11 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __CDVD_ACCESS_H__
#define __CDVD_ACCESS_H__
extern void CDVDsys_Init();
extern void CDVDsys_Shutdown();
#pragma once
extern s32 DoCDVDopen(const char* pTitleFilename);
extern void DoCDVDclose();
@ -32,4 +28,3 @@ extern void DoCDVDnewDiskCB(void (*callback)());
extern s32 DoCDVDdetectDiskType();
extern void DoCDVDresetDiskTypeCache();
#endif /* __CDVD_H__ */

View File

@ -29,25 +29,26 @@
#include "CDVDisoReader.h"
char isoFileName[g_MaxPath];
u8 *pbuffer;
u8 cdbuffer[2352] = {0};
isoFile *iso;
static char isoFileName[g_MaxPath];
static u8 *pbuffer;
static u8 cdbuffer[2352] = {0};
static isoFile *iso = NULL;
static int psize, cdtype;
void CALLBACK ISOclose()
{
isoClose(iso);
iso = NULL;
}
s32 CALLBACK ISOopen(const char* pTitle)
{
ISOclose(); // just in case
if ((pTitle != NULL) && (strlen(pTitle) > 0))
strcpy(isoFileName, pTitle);
ISOclose(); // just in case
iso = isoOpen(isoFileName);
if (iso == NULL)
{

View File

@ -29,7 +29,4 @@
#include "IsoFStools.h"
#include "IsoFileFormats.h"
extern char isoFileName[g_MaxPath];
extern isoFile *iso;
#endif

View File

@ -27,7 +27,7 @@
//#define PSXCLK 186864000 /* 36.864 Mhz */
#define PS2CLK 294912000 //hz /* 294.912 mhz */
#define PCSX2_VERSION "(beta)"
#define PCSX2_VERSION "beta"
#include "System.h"

View File

@ -72,10 +72,10 @@ void __fastcall ReadFIFO_page_5(u32 mem, u64 *out)
if( vif1Regs->stat & (VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS) )
DevCon::Notice( "Reading from vif1 fifo when stalled" );
if (vif1Regs->stat & 0x800000)
if (vif1Regs->stat & VIF1_STAT_FDR)
{
if (--psHu32(D1_QWC) == 0)
vif1Regs->stat&= ~0x1f000000;
vif1Regs->stat&= ~VIF1_STAT_FQC;
}
//out[0] = psHu64(mem );
@ -154,7 +154,7 @@ void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value)
if(vif1Regs->stat & VIF1_STAT_FDR)
DevCon::Notice("writing to fifo when fdr is set!");
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("writing to vif1 fifo when stalled");
vif1ch->qwc += 1;

View File

@ -347,21 +347,18 @@ void gsConstRead64(u32 mem, int mmreg);
void gsConstRead128(u32 mem, int xmmreg);
void gsIrq();
extern void gsInterrupt();
void dmaGIF();
void GIFdma();
void mfifoGIFtransfer(int qwc);
int _GIFchain();
void gifMFIFOInterrupt();
extern u32 CSRw;
extern u64 m_iSlowStart;
// GS Playback
#define GSRUN_TRANS1 1
#define GSRUN_TRANS2 2
#define GSRUN_TRANS3 3
#define GSRUN_VSYNC 4
enum gsrun
{
GSRUN_TRANS1 = 1,
GSRUN_TRANS2,
GSRUN_TRANS3,
GSRUN_VSYNC
};
#ifdef PCSX2_DEVBUILD

View File

@ -21,6 +21,7 @@
#include "Common.h"
#include "VU.h"
#include "GS.h"
#include "Gif.h"
#include "iR5900.h"
#include "Counters.h"
@ -29,15 +30,6 @@
using std::min;
#define gifsplit 0x10000
enum gifstate_t
{
GIF_STATE_READY = 0,
GIF_STATE_STALL = 1,
GIF_STATE_DONE = 2,
GIF_STATE_EMPTY = 0x10
};
// A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished).
// Should be a gifstate_t rather then int, but I don't feel like possibly interfering with savestates right now.
static int gifstate = GIF_STATE_READY;
@ -97,9 +89,7 @@ __forceinline void gsInterrupt()
CHCR::clearSTR(gif);
vif1Regs->stat &= ~VIF1_STAT_VGW;
psHu32(GIF_STAT)&= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0
psHu32(GIF_STAT) &= ~GIF_STAT_P3Q;
psHu32(GIF_STAT) &= ~0x1F000000; // QFC=0
psHu32(GIF_STAT) &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH | GIF_STAT_P3Q | GIF_STAT_FQC);
clearFIFOstuff(false);
hwDmacIrq(DMAC_GIF);
@ -227,18 +217,17 @@ void GIFdma()
psHu32(GIF_STAT) |= 0x10000000; // FQC=31, hack ;) [ used to be 0xE00; // OPH=1 | APATH=3]
//Path2 gets priority in intermittent mode
if (((psHu32(GIF_STAT) & 0x100) || (vif1.cmd & 0x7f) == 0x50) && (psHu32(GIF_MODE) & 0x4) && (Path3progress == IMAGE_MODE))
if (((psHu32(GIF_STAT) & GIF_STAT_P1Q) || (vif1.cmd & 0x7f) == 0x50) && (psHu32(GIF_MODE) & GIF_MODE_IMT) && (Path3progress == IMAGE_MODE))
{
GIF_LOG("Waiting VU %x, PATH2 %x, GIFMODE %x Progress %x", psHu32(GIF_STAT) & 0x100, (vif1.cmd & 0x7f), psHu32(GIF_MODE), Path3progress);
CPU_INT(2, 16);
return;
}
if (vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))
if (vif1Regs->mskpath3 || (psHu32(GIF_MODE) & GIF_MODE_M3R))
{
if (gif->qwc == 0)
{
//if ((gif->chcr & 0x10c) == 0x104)
if ((CHCR::MOD(gif) == CHAIN_MODE) && CHCR::STR(gif))
{
if (!ReadTag(ptag, id)) return;
@ -290,7 +279,7 @@ void GIFdma()
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;
gif->tadr -= 16;
hwDmacIrq(DMAC_13);
hwDmacIrq(DMAC_STALL_SIS);
CPU_INT(2, gscycles);
gscycles = 0;
return;
@ -455,7 +444,7 @@ void mfifoGIFtransfer(int qwc)
if (gif->tadr == spr0->madr)
{
//if( gifqwc > 1 ) DevCon::WriteLn("gif mfifo tadr==madr but qwc = %d", params gifqwc);
hwDmacIrq(DMAC_14);
hwDmacIrq(DMAC_MFIFO_EMPTY);
gifstate |= GIF_STATE_EMPTY;
return;
}
@ -547,7 +536,7 @@ void gifMFIFOInterrupt()
return;
}
if (((psHu32(GIF_STAT) & 0x100) || (vif1.cmd & 0x7f) == 0x50) && (psHu32(GIF_MODE) & 0x4) && Path3progress == IMAGE_MODE) //Path2 gets priority in intermittent mode
if (((psHu32(GIF_STAT) & GIF_STAT_P1Q) || (vif1.cmd & 0x7f) == 0x50) && (psHu32(GIF_MODE) & GIF_MODE_IMT) && Path3progress == IMAGE_MODE) //Path2 gets priority in intermittent mode
{
//GIF_LOG("Waiting VU %x, PATH2 %x, GIFMODE %x Progress %x", psHu32(GIF_STAT) & 0x100, (vif1.cmd & 0x7f), psHu32(GIF_MODE), Path3progress);
CPU_INT(11,mfifocycles);
@ -560,8 +549,8 @@ void gifMFIFOInterrupt()
{
//Console::WriteLn("Empty");
gifstate |= GIF_STATE_EMPTY;
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
hwDmacIrq(DMAC_14);
psHu32(GIF_STAT) &= ~GIF_STAT_IMT; // OPH=0 | APATH=0
hwDmacIrq(DMAC_MFIFO_EMPTY);
return;
}
mfifoGIFtransfer(0);
@ -581,9 +570,7 @@ void gifMFIFOInterrupt()
gspath3done = 0;
gscycles = 0;
psHu32(GIF_STAT) &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0
psHu32(GIF_STAT) &= ~GIF_STAT_P3Q;
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
psHu32(GIF_STAT) &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH | GIF_STAT_P3Q | GIF_STAT_FQC); // OPH, APATH, P3Q, FQC = 0
vif1Regs->stat &= ~VIF1_STAT_VGW;
CHCR::clearSTR(gif);

223
pcsx2/Gif.h Normal file
View File

@ -0,0 +1,223 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __GIF_H__
#define __GIF_H__
#define gifsplit 0x10000
enum gifstate_t
{
GIF_STATE_READY = 0,
GIF_STATE_STALL = 1,
GIF_STATE_DONE = 2,
GIF_STATE_EMPTY = 0x10
};
extern void gsInterrupt();
int _GIFchain();
void GIFdma();
void dmaGIF();
void mfifoGIFtransfer(int qwc);
void gifMFIFOInterrupt();
// Under construction; use with caution.
union tGIF_CTRL
{
struct
{
u32 RST : 1;
u32 reserved1 : 2;
u32 PSE : 1;
u32 reserved2 : 28;
};
u32 value;
tGIF_CTRL( u32 val ) : value( val )
{
}
};
union tGIF_MODE
{
struct
{
u32 M3R : 1;
u32 reserved1 : 1;
u32 IMT : 1;
u32 reserved2 : 29;
};
u32 value;
tGIF_MODE( u32 val ) : value( val )
{
}
};
union tGIF_STAT
{
struct
{
u32 M3R : 1;
u32 M3P : 1;
u32 IMT : 1;
u32 PSE : 1;
u32 reserved1 : 1;
u32 IP3 : 1;
u32 P3Q : 1;
u32 P2Q : 1;
u32 P1Q : 1;
u32 OPH : 1;
u32 APATH : 2;
u32 DIR : 1;
u32 reserved2 : 11;
u32 FQC : 5;
u32 reserved3 : 3;
};
u32 value;
tGIF_STAT( u32 val ) : value( val )
{
}
};
union tGIF_TAG0
{
struct
{
u32 NLOOP : 15;
u32 EOP : 1;
u32 TAG : 16;
};
u32 value;
tGIF_TAG0( u32 val ) : value( val )
{
}
};
union tGIF_TAG1
{
struct
{
u32 TAG : 14;
u32 PRE : 1;
u32 PRIM : 11;
u32 FLG : 2;
u32 NREG : 4;
};
u32 value;
tGIF_TAG1( u32 val ) : value( val )
{
}
};
union tGIF_CNT
{
struct
{
u32 LOOPCNT : 15;
u32 reserved1 : 1;
u32 REGCNT : 4;
u32 VUADDR : 2;
u32 reserved2 : 10;
};
u32 value;
tGIF_CNT( u32 val ) : value( val )
{
}
};
union tGIF_P3CNT
{
struct
{
u32 P3CNT : 15;
u32 reserved1 : 17;
};
u32 value;
tGIF_P3CNT( u32 val ) : value( val )
{
}
};
union tGIF_P3TAG
{
struct
{
u32 LOOPCNT : 15;
u32 EOP : 1;
u32 reserved1 : 16;
};
u32 value;
tGIF_P3TAG( u32 val ) : value( val )
{
}
};
struct GIFregisters
{
// To do: Pad to the correct positions and hook up.
tGIF_CTRL ctrl;
u32 padding[3];
tGIF_MODE mode;
u32 padding1[3];
tGIF_STAT stat;
u32 padding2[7];
tGIF_TAG0 tag0;
u32 padding3[3];
tGIF_TAG1 tag1;
u32 padding4[3];
u32 tag2;
u32 padding5[3];
u32 tag3;
u32 padding6[3];
tGIF_CNT cnt;
u32 padding7[3];
tGIF_P3CNT p3cnt;
u32 padding8[3];
tGIF_P3TAG p3tag;
u32 padding9[3];
};
#define gifRegs ((GIFregisters*)(PS2MEM_HW+0x3000))
// Quick function to see if everythings in the write position.
/*static void checkGifRegs()
{
Console::WriteLn("psHu32(GIF_CTRL) == 0x%x; gifRegs->ctrl == 0x%x", params &psHu32(GIF_CTRL),&gifRegs->ctrl);
Console::WriteLn("psHu32(GIF_MODE) == 0x%x; gifRegs->mode == 0x%x", params &psHu32(GIF_MODE),&gifRegs->mode);
Console::WriteLn("psHu32(GIF_STAT) == 0x%x; gifRegs->stat == 0x%x", params &psHu32(GIF_STAT),&gifRegs->stat);
Console::WriteLn("psHu32(GIF_TAG0) == 0x%x; gifRegs->tag0 == 0x%x", params &psHu32(GIF_TAG0),&gifRegs->tag0);
Console::WriteLn("psHu32(GIF_TAG1) == 0x%x; gifRegs->tag1 == 0x%x", params &psHu32(GIF_TAG1),&gifRegs->tag1);
Console::WriteLn("psHu32(GIF_TAG2) == 0x%x; gifRegs->tag2 == 0x%x", params &psHu32(GIF_TAG2),&gifRegs->tag2);
Console::WriteLn("psHu32(GIF_TAG3) == 0x%x; gifRegs->tag3 == 0x%x", params &psHu32(GIF_TAG3),&gifRegs->tag3);
Console::WriteLn("psHu32(GIF_CNT) == 0x%x; gifRegs->cnt == 0x%x", params &psHu32(GIF_CNT),&gifRegs->cnt);
Console::WriteLn("psHu32(GIF_P3CNT) == 0x%x; gifRegs->p3cnt == 0x%x", params &psHu32(GIF_P3CNT),&gifRegs->p3cnt);
Console::WriteLn("psHu32(GIF_P3TAG) == 0x%x; gifRegs->p3tag == 0x%x", params &psHu32(GIF_P3TAG),&gifRegs->p3tag);
}*/
#endif

View File

@ -17,33 +17,36 @@
*/
#pragma once
#include "CDVD/CDVD.h"
//////////////////////////////////////////////////////////////////////////////////////////
// Startup Parameters.
enum StartupMode
enum StartupModeType
{
BootMode_Normal = 0,
BootMode_Elf = 1, // not compatible with bios flag, probably
BootMode_Iso = 2,
BootMode_NoDisc = 3, // nodisc implies bios.
BootMode_Quick = 0,
BootMode_Bios = 0x10000,
BootMode_ModeMask = 0xFFFF,
Startup_FromCDVD = 0,
Startup_FromELF = 1, // not compatible with bios flag, probably
};
enum CDVD_SourceType;
class StartupParams
{
public:
// Name of the CDVD or ELF image to load.
// if NULL, the CDVD configured settings are used.
// Name of the CDVD image to load.
// if NULL, the CDVD plugin configured settings are used.
const char* ImageName;
// Name of the ELF file to load. If null, the CDVD is booted instead.
const char* ElfFile;
bool NoGui;
bool Enabled;
StartupMode BootMode;
bool NoGui;
bool Enabled;
StartupModeType StartupMode;
CDVD_SourceType CdvdSource;
// Ignored when booting ELFs.
bool SkipBios;
// Plugin overrides
const char* gsdll, *cdvddll, *spudll;

View File

@ -286,17 +286,22 @@ enum INTCIrqs
INTC_TIM1,
INTC_TIM2,
INTC_TIM3,
INTC_SFIFO,
INTVU0_WD
};
enum dmac_conditions
{
DMAC_STAT_SIS = (1<<13), // stall condition
DMAC_STAT_MEIS = (1<<14), // mfifo empty
DMAC_STAT_BEIS = (1<<15), // bus error
DMAC_STAT_SIM = (1<<29), // stall mask
DMAC_STAT_MEIM = (1<<30) // mfifo mask
};
#define DMAC_STAT_SIS (1<<13) // stall condition
#define DMAC_STAT_MEIS (1<<14) // mfifo empty
#define DMAC_STAT_BEIS (1<<15) // bus error
#define DMAC_STAT_SIM (1<<29) // stall mask
#define DMAC_STAT_MEIM (1<<30) // mfifo mask
enum DMACIrqs
{
DMAC_VIF0 = 0,
DMAC_VIF0 = 0,
DMAC_VIF1,
DMAC_GIF,
DMAC_FROM_IPU,
@ -306,73 +311,94 @@ enum DMACIrqs
DMAC_SIF2,
DMAC_FROM_SPR,
DMAC_TO_SPR,
DMAC_13 = 13, // Stall?
DMAC_14 = 14, // Transfer?
DMAC_ERROR = 15,
// We're setting error conditions through hwDmacIrq, so these correspond to the conditions above.
DMAC_STALL_SIS = 13,
DMAC_MFIFO_EMPTY = 14, // Transfer?
DMAC_BUS_ERROR = 15
};
#define VIF0_STAT_VPS_W (1)
#define VIF0_STAT_VPS_D (2)
#define VIF0_STAT_VPS_T (3)
#define VIF0_STAT_VPS (3)
#define VIF0_STAT_VEW (1<<2)
#define VIF0_STAT_MRK (1<<6)
#define VIF0_STAT_DBF (1<<7)
#define VIF0_STAT_VSS (1<<8)
#define VIF0_STAT_VFS (1<<9)
#define VIF0_STAT_VIS (1<<10)
#define VIF0_STAT_INT (1<<11)
#define VIF0_STAT_ER0 (1<<12)
#define VIF0_STAT_ER1 (1<<13)
enum vif0_stat_flags
{
VIF0_STAT_VPS_W = (1),
VIF0_STAT_VPS_D = (2),
VIF0_STAT_VPS_T = (3),
VIF0_STAT_VPS = (3),
VIF0_STAT_VEW = (1<<2),
VIF0_STAT_MRK = (1<<6),
VIF0_STAT_DBF = (1<<7),
VIF0_STAT_VSS = (1<<8),
VIF0_STAT_VFS = (1<<9),
VIF0_STAT_VIS = (1<<10),
VIF0_STAT_INT = (1<<11),
VIF0_STAT_ER0 = (1<<12),
VIF0_STAT_ER1 = (1<<13),
VIF0_STAT_FQC = (15<<24)
};
#define VIF1_STAT_VPS_W (1)
#define VIF1_STAT_VPS_D (2)
#define VIF1_STAT_VPS_T (3)
#define VIF1_STAT_VPS (3)
#define VIF1_STAT_VEW (1<<2)
#define VIF1_STAT_VGW (1<<3)
#define VIF1_STAT_MRK (1<<6)
#define VIF1_STAT_DBF (1<<7)
#define VIF1_STAT_VSS (1<<8)
#define VIF1_STAT_VFS (1<<9)
#define VIF1_STAT_VIS (1<<10)
#define VIF1_STAT_INT (1<<11)
#define VIF1_STAT_ER0 (1<<12)
#define VIF1_STAT_ER1 (1<<13)
#define VIF1_STAT_FDR (1<<23)
enum vif1_stat_flags
{
VIF1_STAT_VPS_W = (1),
VIF1_STAT_VPS_D = (2),
VIF1_STAT_VPS_T = (3),
VIF1_STAT_VPS = (3),
VIF1_STAT_VEW = (1<<2),
VIF1_STAT_VGW = (1<<3),
VIF1_STAT_MRK = (1<<6),
VIF1_STAT_DBF = (1<<7),
VIF1_STAT_VSS = (1<<8),
VIF1_STAT_VFS = (1<<9),
VIF1_STAT_VIS = (1<<10),
VIF1_STAT_INT = (1<<11),
VIF1_STAT_ER0 = (1<<12),
VIF1_STAT_ER1 = (1<<13),
VIF1_STAT_FDR = (1<<23),
VIF1_STAT_FQC = (31<<24)
};
#define VIF_STAT_VPS_W (1)
#define VIF_STAT_VPS_D (2)
#define VIF_STAT_VPS_T (3)
#define VIF_STAT_VPS (3)
#define VIF_STAT_VEW (1<<2)
#define VIF_STAT_VGW (1<<3)
#define VIF_STAT_MRK (1<<6)
#define VIF_STAT_DBF (1<<7)
#define VIF_STAT_VSS (1<<8)
#define VIF_STAT_VFS (1<<9)
#define VIF_STAT_VIS (1<<10)
#define VIF_STAT_INT (1<<11)
#define VIF_STAT_ER0 (1<<12)
#define VIF_STAT_ER1 (1<<13)
#define VIF_STAT_FDR (1<<23)
// These are the stat flags that are the same for vif0 & vif1,
// for occassions where we don't neccessarily know which we are using.
enum vif_stat_flags
{
VIF_STAT_VPS_W = (1),
VIF_STAT_VPS_D = (2),
VIF_STAT_VPS_T = (3),
VIF_STAT_VPS = (3),
VIF_STAT_VEW = (1<<2),
VIF_STAT_MRK = (1<<6),
VIF_STAT_DBF = (1<<7),
VIF_STAT_VSS = (1<<8),
VIF_STAT_VFS = (1<<9),
VIF_STAT_VIS = (1<<10),
VIF_STAT_INT = (1<<11),
VIF_STAT_ER0 = (1<<12),
VIF_STAT_ER1 = (1<<13)
};
//GIF_STAT
enum gif_stat_flags
{
GIF_STAT_M3R = (1), // GIF_MODE Mask
GIF_STAT_M3P = (1<<1), // VIF PATH3 Mask
GIF_STAT_IMT = (1<<2), // Intermittent Transfer Mode
GIF_STAT_PSE = (1<<3), // Temporary Transfer Stop
GIF_STAT_IP3 = (1<<5), // Interrupted PATH3
GIF_STAT_P3Q = (1<<6), // PATH3 request Queued
GIF_STAT_P2Q = (1<<7), // PATH2 request Queued
GIF_STAT_P1Q = (1<<8), // PATH1 request Queued
GIF_STAT_OPH = (1<<9), // Output Path (Outputting Data)
GIF_STAT_APATH1 = (1<<10), // Data Transfer Path 1 (In progress)
GIF_STAT_APATH2 = (2<<10), // Data Transfer Path 2 (In progress)
GIF_STAT_APATH3 = (3<<10), // Data Transfer Path 3 (In progress) (Mask too)
GIF_STAT_DIR = (1<<12), // Transfer Direction
GIF_STAT_FQC = (31<<24) // QWC in GIF-FIFO
};
#define GIF_STAT_M3R (1) //GIF_MODE Mask
#define GIF_STAT_M3P (1<<1) //VIF PATH3 Mask
#define GIF_STAT_IMT (1<<2) //Intermittent Transfer Mode
#define GIF_STAT_PSE (1<<3) //Temporary Transfer Stop
#define GIF_STAT_IP3 (1<<5) //Interrupted PATH3
#define GIF_STAT_P3Q (1<<6) //PATH3 request Queued
#define GIF_STAT_P2Q (1<<7) //PATH2 request Queued
#define GIF_STAT_P1Q (1<<8) //PATH1 request Queued
#define GIF_STAT_OPH (1<<9) //Output Path (Outputting Data)
#define GIF_STAT_APATH1 (1<<10) //Data Transfer Path 1 (In progress)
#define GIF_STAT_APATH2 (2<<10) //Data Transfer Path 2 (In progress)
#define GIF_STAT_APATH3 (3<<10) //Data Transfer Path 3 (In progress) (Mask too)
#define GIF_STAT_DIR (1<<12) //Transfer Direction
#define GIF_STAT_FQC (31<<24) //QWC in GIF-FIFO
enum gif_mode_flags
{
GIF_MODE_M3R = (1),
GIF_MODE_IMT = (1<<2)
};
//DMA interrupts & masks
enum DMAInter

View File

@ -26,6 +26,7 @@
// The full suite of hardware APIs:
#include "IPU/IPU.h"
#include "GS.h"
#include "Gif.h"
#include "Counters.h"
#include "Vif.h"
#include "VifDma.h"
@ -726,10 +727,10 @@ void __fastcall hwWrite32_page_03( u32 mem, u32 value )
if (value & 0x1)
gsGIFReset();
else if( value & 8 )
psHu32(GIF_STAT) |= 8;
else if ( value & 8 )
psHu32(GIF_STAT) |= GIF_STAT_PSE;
else
psHu32(GIF_STAT) &= ~8;
psHu32(GIF_STAT) &= ~GIF_STAT_PSE;
break;
case GIF_MODE:
@ -738,7 +739,7 @@ void __fastcall hwWrite32_page_03( u32 mem, u32 value )
psHu32(GIF_MODE) = value;
// set/clear bits 0 and 2 as per the GIF_MODE value.
const u32 bitmask = 0x1 | 0x4;
const u32 bitmask = GIF_MODE_M3R | GIF_MODE_IMT;
psHu32(GIF_STAT) &= ~bitmask;
psHu32(GIF_STAT) |= (u32)value & bitmask;
}
@ -1076,16 +1077,16 @@ void __fastcall hwWrite64_page_03( u32 mem, const mem64_t* srcval )
else
{
if( value & 8 )
psHu32(GIF_STAT) |= 8;
psHu32(GIF_STAT) |= GIF_STAT_PSE;
else
psHu32(GIF_STAT) &= ~8;
psHu32(GIF_STAT) &= ~GIF_STAT_PSE;
}
break;
case GIF_MODE:
{
// set/clear bits 0 and 2 as per the GIF_MODE value.
const u32 bitmask = 0x1 | 0x4;
const u32 bitmask = GIF_MODE_M3R | GIF_MODE_IMT;
Console::Status("GIFMODE64 %x", params value);

View File

@ -687,7 +687,7 @@ static BOOL __fastcall ipuCSC(u32 val)
if (g_nCmdPos[0] < 3072 / 8) return FALSE;
ipu_csc(&mb8, &rgb32, 0);
if (csc.OFM) ipu_dither2(&rgb32, &rgb16, csc.DTE);
if (csc.OFM) ipu_dither(&rgb32, &rgb16, csc.DTE);
}
if (csc.OFM)
@ -741,7 +741,7 @@ static BOOL ipuPACK(u32 val)
if (g_nCmdPos[0] < 64) return FALSE;
ipu_csc(&mb8, &rgb32, 0);
ipu_dither2(&rgb32, &rgb16, csc.DTE);
ipu_dither(&rgb32, &rgb16, csc.DTE);
if (csc.OFM) ipu_vq(&rgb16, indx4);
}
@ -1278,7 +1278,7 @@ void __fastcall ipu_csc(macroblock_8 *mb8, macroblock_rgb32 *rgb32, int sgn)
}
}
void __fastcall ipu_dither2(const macroblock_rgb32* rgb32, macroblock_rgb16 *rgb16, int dte)
void __fastcall ipu_dither(const macroblock_rgb32* rgb32, macroblock_rgb16 *rgb16, int dte)
{
int i, j;
for (i = 0; i < 16; ++i)
@ -1293,11 +1293,6 @@ void __fastcall ipu_dither2(const macroblock_rgb32* rgb32, macroblock_rgb16 *rgb
}
}
void __fastcall ipu_dither(macroblock_8 *mb8, macroblock_rgb16 *rgb16, int dte)
{
//Console::Error("IPU: Dither not implemented");
}
void __fastcall ipu_vq(macroblock_rgb16 *rgb16, u8* indx4)
{
Console::Error("IPU: VQ not implemented");

View File

@ -60,34 +60,39 @@ union tIPU_CMD {
};
};
#define IPU_CTRL_IFC_M (0x0f<< 0)
#define IPU_CTRL_OFC_M (0x0f<< 4)
#define IPU_CTRL_CBP_M (0x3f<< 8)
#define IPU_CTRL_ECD_M (0x01<<14)
#define IPU_CTRL_SCD_M (0x01<<15)
#define IPU_CTRL_IDP_M (0x03<<16)
#define IPU_CTRL_AS_M (0x01<<20)
#define IPU_CTRL_IVF_M (0x01<<21)
#define IPU_CTRL_QST_M (0x01<<22)
#define IPU_CTRL_MP1_M (0x01<<23)
#define IPU_CTRL_PCT_M (0x07<<24)
#define IPU_CTRL_RST_M (0x01<<30)
#define IPU_CTRL_BUSY_M (0x01<<31)
#define IPU_CTRL_IFC_O ( 0)
#define IPU_CTRL_OFC_O ( 4)
#define IPU_CTRL_CBP_O ( 8)
#define IPU_CTRL_ECD_O (14)
#define IPU_CTRL_SCD_O (15)
#define IPU_CTRL_IDP_O (16)
#define IPU_CTRL_AS_O (20)
#define IPU_CTRL_IVF_O (21)
#define IPU_CTRL_QST_O (22)
#define IPU_CTRL_MP1_O (23)
#define IPU_CTRL_PCT_O (24)
#define IPU_CTRL_RST_O (30)
#define IPU_CTRL_BUSY_O (31)
enum ipu_ctrl_m_flags
{
IPU_CTRL_IFC_M = (0x0f<< 0),
IPU_CTRL_OFC_M = (0x0f<< 4),
IPU_CTRL_CBP_M = (0x3f<< 8),
IPU_CTRL_ECD_M = (0x01<<14),
IPU_CTRL_SCD_M = (0x01<<15),
IPU_CTRL_IDP_M = (0x03<<16),
IPU_CTRL_AS_M = (0x01<<20),
IPU_CTRL_IVF_M = (0x01<<21),
IPU_CTRL_QST_M = (0x01<<22),
IPU_CTRL_MP1_M = (0x01<<23),
IPU_CTRL_PCT_M = (0x07<<24),
IPU_CTRL_RST_M = (0x01<<30),
IPU_CTRL_BUSY_M = (0x01<<31)
};
enum ipu_ctrl_o_flags
{
IPU_CTRL_IFC_O = ( 0),
IPU_CTRL_OFC_O = ( 4),
IPU_CTRL_CBP_O = ( 8),
IPU_CTRL_ECD_O = (14),
IPU_CTRL_SCD_O = (15),
IPU_CTRL_IDP_O = (16),
IPU_CTRL_AS_O = (20),
IPU_CTRL_IVF_O = (21),
IPU_CTRL_QST_O = (22),
IPU_CTRL_MP1_O = (23),
IPU_CTRL_PCT_O = (24),
IPU_CTRL_RST_O = (30),
IPU_CTRL_BUSY_O = (31)
};
//
// Bitfield Structure
@ -104,7 +109,7 @@ union tIPU_CTRL {
u32 AS : 1; // Alternate scan
u32 IVF : 1; // Intra VLC format
u32 QST : 1; // Q scale step
u32 MP1 : 1; // MPEG1 bit strea
u32 MP1 : 1; // MPEG1 bit stream
u32 PCT : 3; // Picture Type
u32 resv1 : 3;
u32 RST : 1; // Reset
@ -113,14 +118,19 @@ union tIPU_CTRL {
u32 _u32;
};
#define IPU_BP_BP_M (0x7f<< 0)
#define IPU_BP_IFC_M (0x0f<< 8)
#define IPU_BP_FP_M (0x03<<16)
#define IPU_BP_BP_O ( 0)
#define IPU_BP_IFC_O ( 8)
#define IPU_BP_FP_O (16)
enum ipu_bp_m_flags
{
IPU_BP_BP_M = (0x7f<< 0),
IPU_BP_IFC_M = (0x0f<< 8),
IPU_BP_FP_M = (0x03<<16)
};
enum ipu_bp_o_flags
{
IPU_BP_BP_O = ( 0),
IPU_BP_IFC_O = ( 8),
IPU_BP_FP_O = (16)
};
//
// Bitfield Structure

View File

@ -1210,9 +1210,8 @@ void mpeg2sliceIDEC(void* pdone)
}
else
{
//ipu_dither(decoder->mb8, decoder->rgb16, decoder->dte);
ipu_csc(decoder->mb8, decoder->rgb32, decoder->dte);
ipu_dither2(decoder->rgb32, decoder->rgb16, decoder->dte);
ipu_dither(decoder->rgb32, decoder->rgb16, decoder->dte);
g_nIPU0Data = 32;
g_pIPU0Pointer = (u8*)decoder->rgb16;

View File

@ -185,8 +185,7 @@ extern int non_linear_quantizer_scale[];
extern decoder_t g_decoder;
void __fastcall ipu_csc(macroblock_8 *mb8, macroblock_rgb32 *rgb32, int sgn);
void __fastcall ipu_dither(macroblock_8 *mb8, macroblock_rgb16 *rgb16, int dte);
void __fastcall ipu_dither2(const macroblock_rgb32* rgb32, macroblock_rgb16 *rgb16, int dte);
void __fastcall ipu_dither(const macroblock_rgb32* rgb32, macroblock_rgb16 *rgb16, int dte);
void __fastcall ipu_vq(macroblock_rgb16 *rgb16, u8* indx4);
void __fastcall ipu_copy(const macroblock_8 *mb8, macroblock_16 *mb16);

View File

@ -109,7 +109,7 @@ int GetPS2ElfName( wxString& name )
// check if the file exists
if (IsoFS_findFile("SYSTEM.CNF;1", &tocEntry) != TRUE){
Console::Error("Boot Error > SYSTEM.CNF not found");
Console::Status("GetElfName: SYSTEM.CNF not found; invalid cd image or no disc present.");
return 0;//could not find; not a PS/PS2 cdvd
}
@ -123,7 +123,7 @@ int GetPS2ElfName( wxString& name )
if (pos==NULL){
pos=strstr(buffer, "BOOT");
if (pos==NULL) {
Console::Error("Boot failed: This is not a Playstation or PS2 game!");
Console::Error("PCSX2 Boot Error: This is not a Playstation or PS2 game!");
return 0;
}
return 1;

View File

@ -322,7 +322,7 @@ static const LegacyApi_OptMethod s_MethMessOpt_PAD[] =
void CALLBACK CDVD_newDiskCB(void (*callback)()) {}
extern int lastReadSize;
s32 CALLBACK CDVD_getBuffer2(u8* buffer)
static s32 CALLBACK CDVD_getBuffer2(u8* buffer)
{
int ret;
@ -338,8 +338,7 @@ s32 CALLBACK CDVD_getBuffer2(u8* buffer)
return ret;
}
s32 CALLBACK CDVD_readSector(u8* buffer, u32 lsn, int mode)
static s32 CALLBACK CDVD_readSector(u8* buffer, u32 lsn, int mode)
{
if(CDVD->readTrack(lsn,mode) < 0)
return -1;
@ -363,7 +362,7 @@ s32 CALLBACK CDVD_readSector(u8* buffer, u32 lsn, int mode)
return CDVD->getBuffer2(buffer);
}
s32 CALLBACK CDVD_getDualInfo(s32* dualType, u32* layer1Start)
static s32 CALLBACK CDVD_getDualInfo(s32* dualType, u32* layer1Start)
{
u8 toc[2064];
@ -964,28 +963,30 @@ bool OpenGS()
return true;
}
bool OpenCDVD(const char* pTitleFilename)
bool OpenCDVD( const char* pTitleFilename )
{
// if this assertion fails it means you didn't call CDVDsys_ChangeSource. You should.
// You really should. Really.
jASSUME( CDVD != NULL );
// Don't repetitively open the CDVD plugin if directly loading an elf file and open failed once already.
if (!OpenStatus.CDVD && !only_loading_elf)
if (!OpenStatus.CDVD)
{
//First, we need the data.
CDVD->newDiskCB(cdvdNewDiskCB);
CDVD->newDiskCB( cdvdNewDiskCB );
if( (pTitleFilename == NULL) && !cdvd_FileNameParam.IsEmpty() )
pTitleFilename = cdvd_FileNameParam.c_str();
if (DoCDVDopen(pTitleFilename) != 0)
{
if (g_Startup.BootMode != BootMode_Elf)
{
Msgbox::Alert("Error Opening CDVD Plugin");
ClosePlugins(true);
return false;
}
else
{
Console::Notice("Running ELF File Without CDVD Plugin Support!");
only_loading_elf = true;
}
{
Msgbox::Alert("Error Opening CDVD Plugin");
ClosePlugins(true);
return false;
}
if( cdvd_FileNameParam.IsEmpty() && (pTitleFilename != NULL) )
cdvd_FileNameParam = pTitleFilename;
OpenStatus.CDVD = true;
}
return true;
@ -1088,22 +1089,19 @@ bool OpenFW()
return true;
}
int OpenPlugins(const char* pTitleFilename)
// Note: If the CDVD has not already been manually opened, then it will be opened here
// using NULL as the source file (defaults to whatever's been previously configured into
// the CDVD plugin, which is typically a drive letter)
int OpenPlugins()
{
if (!plugins_initialized)
{
// prevent a crash
if(CDVD.init == NULL)
CDVD = ISO; // CDVD_plugin;
if( InitPlugins() == -1 ) return -1;
if( InitPlugins() == -1 ) return -1;
}
if ((!OpenCDVD(pTitleFilename)) || (!OpenGS()) || (!OpenPAD1()) || (!OpenPAD2()) ||
(!OpenSPU2()) || (!OpenDEV9()) || (!OpenUSB()) || (!OpenFW()))
if( !OpenGS() || !OpenPAD1() || !OpenPAD2() || !OpenCDVD(NULL) ||
!OpenSPU2() || !OpenDEV9() || !OpenUSB() || !OpenFW()
)
return -1;
if (!only_loading_elf) cdvdDetectDisk();
cdvdDetectDisk();
return 0;
}
@ -1145,10 +1143,12 @@ void ClosePlugins( bool closegs )
}
}
CloseCDVD();
if( OpenStatus.CDVD )
{
DoCDVDclose();
OpenStatus.CDVD=false;
OpenStatus.CDVD = false;
}
CLOSE_PLUGIN( DEV9 );
@ -1176,6 +1176,4 @@ void PluginsResetGS()
if (ret != 0) { Msgbox::Alert("GSinit error: %d", params ret); }
}
#else
#endif

View File

@ -65,7 +65,6 @@ void psxReset()
psxHwReset();
psxBiosInit();
//psxExecuteBios();
}
void psxShutdown() {
@ -136,7 +135,7 @@ void psxException(u32 code, u32 bd) {
}
/*if (psxRegs.CP0.n.Cause == 0x400 && (!(psxHu32(0x1450) & 0x8))) {
hwIntcIrq(1);
hwIntcIrq(INTC_SBUS);
}*/
}
@ -279,9 +278,3 @@ void iopTestIntc()
psxSetNextBranchDelta( 2 );
}
void psxExecuteBios() {
/* while (psxRegs.pc != 0x80030000)
psxCpu->ExecuteBlock();
PSX_LOG("*BIOS END*");
*/
}

View File

@ -201,7 +201,6 @@ void psxReset();
void psxShutdown();
void psxException(u32 code, u32 step);
extern void psxBranchTest();
void psxExecuteBios();
void psxMemReset();
// Subsets

View File

@ -29,6 +29,7 @@
#include "COP0.h"
#include "GS.h"
#include "Gif.h"
#include "IPU/IPU.h"
#include "Vif.h"
#include "VifDma.h"

View File

@ -305,8 +305,8 @@ namespace D_CTRL
{
return (std_type)((psHu32(DMAC_CTRL) & CTRL_STD) >> 6);
}
static __forceinline int RCLC()
{
static __forceinline int RCYC()
{
return ((((psHu32(DMAC_CTRL) & CTRL_RCYC) >> 3) + 1) * 8);
}
}

View File

@ -78,14 +78,17 @@ void _vu0WaitMicro() {
VU0.flags|= VUFLAG_BREAKONMFLAG;
VU0.flags&= ~VUFLAG_MFLAGSET;
do {
CpuVU0.ExecuteBlock();
// knockout kings 2002 loops here
if( VU0.cycle-startcycle > 0x1000 ) {
Console::Notice("VU0 perma-stall, breaking execution..."); // (email zero if gfx are bad)
break;
}
} while ((VU0.VI[REG_VPU_STAT].UL & 0x1) && (VU0.flags & VUFLAG_MFLAGSET) == 0);
if (!CHECK_MICROVU0) {
do {
CpuVU0.ExecuteBlock();
// knockout kings 2002 loops here
if( VU0.cycle-startcycle > 0x1000 ) {
Console::Notice("VU0 perma-stall, breaking execution..."); // (email zero if gfx are bad)
break;
}
} while ((VU0.VI[REG_VPU_STAT].UL & 0x1) && (VU0.flags & VUFLAG_MFLAGSET) == 0);
}
else CpuVU0.ExecuteBlock(); // Note: Need to test Knockout Kings 2002 with mVU!
//NEW
cpuRegs.cycle += (VU0.cycle-startcycle)*2;

View File

@ -43,7 +43,7 @@ void vu0ResetRegs()
{
VU0.VI[REG_VPU_STAT].UL &= ~0xff; // stop vu0
VU0.VI[REG_FBRST].UL &= ~0xff; // stop vu0
vif0Regs->stat &= ~4;
vif0Regs->stat &= ~VIF0_STAT_VEW;
}
void VU0MI_XGKICK() {

View File

@ -169,7 +169,7 @@ static void _vu0Exec(VURegs* VU)
if( VU->ebit-- == 1 ) {
_vuFlushAll(VU);
VU0.VI[REG_VPU_STAT].UL&= ~0x1; /* E flag */
vif0Regs->stat&= ~0x4;
vif0Regs->stat&= ~VIF0_STAT_VEW;
}
}
}

View File

@ -43,7 +43,7 @@ void vu1ResetRegs()
{
VU0.VI[REG_VPU_STAT].UL &= ~0xff00; // stop vu1
VU0.VI[REG_FBRST].UL &= ~0xff00; // stop vu1
vif1Regs->stat &= ~4;
vif1Regs->stat &= ~VIF1_STAT_VEW;
}
static int count;
@ -61,7 +61,7 @@ void vu1ExecMicro(u32 addr)
VU0.VI[REG_VPU_STAT].UL|= 0x100;
VU0.VI[REG_VPU_STAT].UL&= ~0x7E000;
vif1Regs->stat|= 0x4;
vif1Regs->stat|= VIF1_STAT_VEW;
if (addr != -1) VU1.VI[REG_TPC].UL = addr;
_vuExecMicroDebug(VU1);

View File

@ -162,7 +162,7 @@ static void _vu1Exec(VURegs* VU)
if( VU->ebit-- == 1 ) {
_vuFlushAll(VU);
VU0.VI[REG_VPU_STAT].UL&= ~0x100;
vif1Regs->stat&= ~0x4;
vif1Regs->stat&= ~VIF1_STAT_VEW;
}
}
}

View File

@ -32,7 +32,7 @@ VUmicroCpu CpuVU1; // contains a working copy of the VU1 cpu functions/API
static void DummyExecuteVU1Block(void)
{
VU0.VI[ REG_VPU_STAT ].UL &= ~0x100;
VU1.vifRegs->stat &= ~4; // also reset the bit (grandia 3 works)
VU1.vifRegs->stat &= ~VIF1_STAT_VEW; // also reset the bit (grandia 3 works)
}
void vuMicroCpuReset()

View File

@ -558,7 +558,7 @@ void vifMFIFOInterrupt()
--vif1.irq;
if (vif1Regs->stat & (VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
{
vif1Regs->stat &= ~0x1F000000; // FQC=0
vif1Regs->stat &= ~VIF1_STAT_FQC; // FQC=0
CHCR::clearSTR(vif1ch);
return;
}
@ -576,8 +576,8 @@ void vifMFIFOInterrupt()
// Console::WriteLn("Empty 1");
vifqwc = 0;
vif1.inprogress |= 0x10;
vif1Regs->stat &= ~0x1F000000; // FQC=0
hwDmacIrq(DMAC_14);
vif1Regs->stat &= ~VIF1_STAT_FQC; // FQC=0
hwDmacIrq(DMAC_MFIFO_EMPTY);
return;
}
@ -600,8 +600,8 @@ void vifMFIFOInterrupt()
{
//Console::WriteLn("Empty 2");
//vif1.inprogress |= 0x10;
vif1Regs->stat &= ~0x1F000000; // FQC=0
hwDmacIrq(DMAC_14);
vif1Regs->stat &= ~VIF1_STAT_FQC; // FQC=0
hwDmacIrq(DMAC_MFIFO_EMPTY);
}*/
vif1.done = 1;
@ -610,6 +610,6 @@ void vifMFIFOInterrupt()
hwDmacIrq(DMAC_VIF1);
VIF_LOG("vif mfifo dma end");
vif1Regs->stat &= ~0x1F000000; // FQC=0
vif1Regs->stat &= ~VIF1_STAT_FQC; // FQC=0
}

View File

@ -24,6 +24,30 @@ struct vifCycle {
u8 pad[2];
};
//
// Bitfield Structure
//
union tVIF_STAT {
struct {
u32 VPS : 2;
u32 VEW : 1;
u32 VGW : 1;
u32 reserved : 2;
u32 MRK : 1;
u32 DBF : 1;
u32 VSS : 1;
u32 VFS : 1;
u32 VIS : 1;
u32 INT : 1;
u32 ER0 : 1;
u32 ER1 : 1;
u32 reserved2 : 9;
u32 FDR : 1;
u32 FQC : 5;
};
u32 _u32;
};
// r0-r3 and c0-c3 would be more managable as arrays.
struct VIFregisters {
u32 stat;
@ -78,6 +102,26 @@ struct VIFregisters {
u32 addr;
};
enum vif_errors
{
VIF_ERR_MII = 0x1,
VIF_ERR_ME0 = 0x2,
VIF_ERR_ME1 = 0x4
};
// Masks or unmasks errors
namespace VIF_ERR
{
// If true, interrupts by the i bit of Vifcode are masked.
static __forceinline bool MII(VIFregisters *tag) { return !!(tag->err & VIF_ERR_MII); }
// If true, DMAtag Mismatch errors are masked. (We never check for this?)
static __forceinline bool ME0(VIFregisters *tag) { return !!(tag->err & VIF_ERR_ME0); }
// If true, VifCode errors are masked.
static __forceinline bool ME1(VIFregisters *tag) { return !!(tag->err & VIF_ERR_ME1); }
}
extern "C"
{
// these use cdecl for Asm code references.

View File

@ -890,17 +890,17 @@ static void vuExecMicro(u32 addr, const u32 VIFdmanum)
VU->vifRegs->top = VU->vifRegs->tops & 0x3ff;
/* is DBF flag set in VIF_STAT? */
if (VU->vifRegs->stat & 0x80)
if (VU->vifRegs->stat & VIF_STAT_DBF)
{
/* it is, so set tops with base, and set the stat DBF flag */
VU->vifRegs->tops = VU->vifRegs->base;
VU->vifRegs->stat &= ~0x80;
VU->vifRegs->stat &= ~VIF_STAT_DBF;
}
else
{
/* it is not, so set tops with base + ofst, and clear stat DBF flag */
VU->vifRegs->tops = VU->vifRegs->base + VU->vifRegs->ofst;
VU->vifRegs->stat |= 0x80;
VU->vifRegs->stat |= VIF_STAT_DBF;
}
}
@ -1222,10 +1222,10 @@ static void Vif0CMDMPGTransfer() // MPG
static void Vif0CMDNull() // invalid opcode
{
// if ME1, then force the vif to interrupt
if ((vif0Regs->err & 0x4) == 0) //Ignore vifcode and tag mismatch error
if (!(VIF_ERR::ME1(vif0Regs))) //Ignore vifcode and tag mismatch error
{
Console::WriteLn("UNKNOWN VifCmd: %x", params vif0.cmd);
vif0Regs->stat |= 1 << 13;
vif0Regs->stat |= VIF0_STAT_ER1;
vif0.irq++;
}
vif0.cmd &= ~0x7f;
@ -1274,10 +1274,10 @@ int VIF0transfer(u32 *data, int size, int istag)
if ((vif0.cmd & 0x7f) > 0x4A)
{
if ((vif0Regs->err & 0x4) == 0) //Ignore vifcode and tag mismatch error
if (!(VIF_ERR::ME1(vif0Regs))) //Ignore vifcode and tag mismatch error
{
Console::WriteLn("UNKNOWN VifCmd: %x", params vif0.cmd);
vif0Regs->stat |= 1 << 13;
vif0Regs->stat |= VIF0_STAT_ER1;
vif0.irq++;
}
vif0.cmd = 0;
@ -1294,7 +1294,7 @@ int VIF0transfer(u32 *data, int size, int istag)
{
vif0.cmd &= 0x7f;
if (!(vif0Regs->err & 0x1)) //i bit on vifcode and not masked by VIF0_ERR
if (!(VIF_ERR::MII(vif0Regs))) //i bit on vifcode and not masked by VIF0_ERR
{
VIF_LOG("Interrupt on VIFcmd: %x (INTC_MASK = %x)", vif0.cmd, psHu32(INTC_MASK));
@ -1425,7 +1425,7 @@ void vif0Interrupt()
if (vif0Regs->stat & (VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
{
vif0Regs->stat &= ~0xF000000; // FQC=0
vif0Regs->stat &= ~VIF0_STAT_FQC; // FQC=0
CHCR::clearSTR(vif0ch);
return;
}
@ -1467,7 +1467,7 @@ void vif0Interrupt()
CHCR::clearSTR(vif0ch);
hwDmacIrq(DMAC_VIF0);
vif0Regs->stat &= ~0xF000000; // FQC=0
vif0Regs->stat &= ~VIF0_STAT_FQC; // FQC=0
}
// Vif1 Data Transfer Table
@ -1559,10 +1559,10 @@ void vif0Write32(u32 mem, u32 value)
vif0ch->qwc = 0; //?
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
psHu64(VIF0_FIFO) = 0;
psHu64(0x10004008) = 0; // VIF0_FIFO + 8
psHu64(VIF0_FIFO + 8) = 0; // VIF0_FIFO + 8
vif0.done = true;
vif0Regs->err = 0;
vif0Regs->stat &= ~(0xF000000 | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0
vif0Regs->stat &= ~(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0
}
if (value & 0x2)
@ -1657,7 +1657,7 @@ void vif0Reset()
psHu64(VIF0_FIFO + 8) = 0;
vif0Regs->stat &= ~VIF0_STAT_VPS;
vif0.done = true;
vif0Regs->stat &= ~0xF000000; // FQC=0
vif0Regs->stat &= ~VIF0_STAT_FQC; // FQC=0
}
void SaveState::vif0Freeze()
@ -2009,7 +2009,7 @@ static void Vif1CMDSTCycl() // STCYCL
static void Vif1CMDOffset() // OFFSET
{
vif1Regs->ofst = vif1Regs->code & 0x3ff;
vif1Regs->stat &= ~0x80;
vif1Regs->stat &= ~VIF1_STAT_DBF;
vif1Regs->tops = vif1Regs->base;
vif1.cmd &= ~0x7f;
}
@ -2041,13 +2041,13 @@ void Vif1MskPath3() // MSKPATH3
if (vif1Regs->mskpath3)
{
psHu32(GIF_STAT) |= 0x2;
psHu32(GIF_STAT) |= GIF_STAT_M3P;
}
else
{
//Let the Gif know it can transfer again (making sure any vif stall isnt unset prematurely)
Path3progress = TRANSFER_MODE;
psHu32(GIF_STAT) &= ~0x2;
psHu32(GIF_STAT) &= ~GIF_STAT_IMT;
CPU_INT(2, 4);
}
@ -2144,10 +2144,10 @@ static void Vif1CMDNull() // invalid opcode
{
// if ME1, then force the vif to interrupt
if ((vif1Regs->err & 0x4) == 0) //Ignore vifcode and tag mismatch error
if (!(VIF_ERR::ME1(vif1Regs))) //Ignore vifcode and tag mismatch error
{
Console::WriteLn("UNKNOWN VifCmd: %x\n", params vif1.cmd);
vif1Regs->stat |= 1 << 13;
vif1Regs->stat |= VIF1_STAT_ER1;
vif1.irq++;
}
vif1.cmd = 0;
@ -2242,10 +2242,10 @@ int VIF1transfer(u32 *data, int size, int istag)
if ((vif1.cmd & 0x7f) > 0x51)
{
if ((vif1Regs->err & 0x4) == 0) //Ignore vifcode and tag mismatch error
if (!(VIF_ERR::ME1(vif1Regs))) //Ignore vifcode and tag mismatch error
{
Console::WriteLn("UNKNOWN VifCmd: %x", params vif1.cmd);
vif1Regs->stat |= 1 << 13;
vif1Regs->stat |= VIF1_STAT_ER1;
vif1.irq++;
}
vif1.cmd = 0;
@ -2260,7 +2260,7 @@ int VIF1transfer(u32 *data, int size, int istag)
{
vif1.cmd &= 0x7f;
if (!(vif1Regs->err & 0x1)) //i bit on vifcode and not masked by VIF1_ERR
if (!(VIF_ERR::MII(vif1Regs))) //i bit on vifcode and not masked by VIF1_ERR
{
VIF_LOG("Interrupt on VIFcmd: %x (INTC_MASK = %x)", vif1.cmd, psHu32(INTC_MASK));
@ -2333,7 +2333,7 @@ void vif1TransferFromMemory()
Console::WriteLn("Vif1 Tag BUSERR");
psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register
vif1.done = true;
vif1Regs->stat &= ~0x1f000000;
vif1Regs->stat &= ~VIF1_STAT_FQC;
vif1ch->qwc = 0;
CPU_INT(1, 0);
@ -2454,7 +2454,7 @@ __forceinline void vif1SetupTransfer()
if ((vif1ch->madr + vif1ch->qwc * 16) >= psHu32(DMAC_STADR))
{
// stalled
hwDmacIrq(DMAC_13);
hwDmacIrq(DMAC_STALL_SIS);
return;
}
}
@ -2519,7 +2519,7 @@ __forceinline void vif1Interrupt()
--vif1.irq;
if (vif1Regs->stat & (VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
{
vif1Regs->stat &= ~0x1F000000; // FQC=0
vif1Regs->stat &= ~VIF1_STAT_FQC; // FQC=0
// One game doesnt like vif stalling at end, cant remember what. Spiderman isnt keen on it tho
CHCR::clearSTR(vif1ch);
@ -2658,13 +2658,13 @@ void vif1Write32(u32 mem, u32 value)
if(vif1Regs->mskpath3)
{
vif1Regs->mskpath3 = 0;
psHu32(GIF_STAT) &= ~0x2;
psHu32(GIF_STAT) &= ~GIF_STAT_IMT;
if (CHCR::STR(gif)) CPU_INT(2, 4);
}
vif1Regs->err = 0;
vif1.inprogress = 0;
vif1Regs->stat &= ~(0x1F800000 | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS); // FQC=0
vif1Regs->stat &= ~(VIF1_STAT_FQC | VIF1_STAT_FDR | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS); // FQC=0
}
if (value & 0x2)
@ -2749,14 +2749,14 @@ void vif1Write32(u32 mem, u32 value)
vif1Regs->stat = (vif1Regs->stat & ~VIF1_STAT_FDR) | (value & VIF1_STAT_FDR);
if (vif1Regs->stat & VIF1_STAT_FDR)
{
vif1Regs->stat |= 0x01000000; // FQC=1 - hack but it checks this is true before tranfer? (fatal frame)
vif1Regs->stat |= 0x01000000; // FQC=1 - hack but it checks this is true before transfer? (fatal frame)
}
else
{
vif1ch->qwc = 0;
vif1.vifstalled = false;
vif1.done = true;
vif1Regs->stat &= ~0x1F000000; // FQC=0
vif1Regs->stat &= ~VIF1_STAT_FQC; // FQC=0
}
break;
@ -2796,11 +2796,11 @@ void vif1Reset()
memzero_obj(*vif1Regs);
SetNewMask(g_vif1Masks, g_vif1HasMask3, 0, 0xffffffff);
psHu64(VIF1_FIFO) = 0;
psHu64(0x10005008) = 0; // VIF1_FIFO + 8
psHu64(VIF1_FIFO + 8) = 0;
vif1Regs->stat &= ~VIF1_STAT_VPS;
vif1.done = true;
cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
vif1Regs->stat &= ~0x1F000000; // FQC=0
vif1Regs->stat &= ~VIF1_STAT_FQC; // FQC=0
}
void SaveState::vif1Freeze()

View File

@ -78,7 +78,7 @@ Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
mainSizer.Add( &m_listbook );
AddOkCancel( mainSizer, true );
GetWindowChild( wxID_APPLY )->Disable();
FindWindow( wxID_APPLY )->Disable();
SetSizerAndFit( &mainSizer );
CenterOnScreen();
@ -130,7 +130,7 @@ void Dialogs::ConfigurationDialog::OnOk_Click( wxCommandEvent& evt )
void Dialogs::ConfigurationDialog::OnApply_Click( wxCommandEvent& evt )
{
GetWindowChild( wxID_APPLY )->Disable();
FindWindow( wxID_APPLY )->Disable();
g_ApplyState.ApplyAll();
}

View File

@ -46,7 +46,7 @@ namespace Dialogs
evt.Skip();
if( (evt.GetId() != wxID_OK) && (evt.GetId() != wxID_CANCEL) && (evt.GetId() != wxID_APPLY) )
{
GetWindowChild( wxID_APPLY )->Enable();
FindWindow( wxID_APPLY )->Enable();
}
}
};

View File

@ -118,6 +118,7 @@ FirstTimeWizard::FirstTimeWizard( wxWindow* parent ) :
m_page_plugins.SetNext ( &m_page_bios );
GetPageAreaSizer()->Add( &m_page_usermode );
GetPageAreaSizer()->Add( &m_page_plugins );
CenterOnScreen();
Connect( wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler( FirstTimeWizard::OnPageChanged ) );

View File

@ -52,7 +52,13 @@ public:
FirstTimeWizard( wxWindow* parent );
virtual ~FirstTimeWizard();
wxWizardPage *GetFirstPage() const { return &m_page_usermode; }
wxWizardPage *GetUsermodePage() const { return &m_page_usermode; }
wxWizardPage *GetPostUsermodePage() const { return &m_page_plugins; }
void ForceEnumPlugins()
{
m_panel_PluginSel.OnShown();
}
protected:
virtual void OnPageChanging( wxWizardEvent& evt );

View File

@ -278,6 +278,12 @@ void Panels::PluginSelectorPanel::CancelRefresh()
void Panels::PluginSelectorPanel::DoRefresh()
{
// Disable all controls until enumeration is complete.
// Show status bar for plugin enumeration.
// fixme: the status bar doesn't always fit itself to the window correctly because
// sometimes this gets called before the parent window has been fully created. I'm
// not quite sure how to fix (a delayed event/message might work tho implementing it
// may not be trivial) -- air
m_ComponentBoxes.Hide();
m_StatusPanel.SetSize( m_ComponentBoxes.GetSize().GetWidth() - 8, wxDefaultCoord );
@ -316,7 +322,6 @@ bool Panels::PluginSelectorPanel::ValidateEnumerationStatus()
return validated;
}
// ------------------------------------------------------------------------
void Panels::PluginSelectorPanel::OnConfigure_Clicked( wxCommandEvent& evt )
{
PluginsEnum_t pid = (PluginsEnum_t)(int)((wxEvtHandler*)evt.GetEventObject())->GetClientData();

View File

@ -84,7 +84,7 @@ void Pcsx2App::ReadUserModeSettings()
{
// first time startup, so give the user the choice of user mode:
FirstTimeWizard wiz( NULL );
if( !wiz.RunWizard( wiz.GetFirstPage() ) )
if( !wiz.RunWizard( wiz.GetUsermodePage() ) )
throw Exception::StartupAborted( L"Startup aborted: User canceled FirstTime Wizard." );
// Save user's new settings
@ -100,6 +100,21 @@ void Pcsx2App::ReadUserModeSettings()
IniLoader loader( *conf_usermode );
g_Conf->LoadSaveUserMode( loader, groupname );
if( !wxFile::Exists( g_Conf->FullPathToConfig() ) )
{
// user wiped their pcsx2.ini -- needs a reconfiguration via wizard!
// (we skip the first page since it's a usermode.ini thing)
FirstTimeWizard wiz( NULL );
if( !wiz.RunWizard( wiz.GetPostUsermodePage() ) )
throw Exception::StartupAborted( L"Startup aborted: User canceled Configuration Wizard." );
// Save user's new settings
IniSaver saver( *conf_usermode );
g_Conf->LoadSaveUserMode( saver, groupname );
g_Conf->Save();
}
}
}

View File

@ -593,6 +593,7 @@
<ClInclude Include="..\..\Dump.h" />
<ClInclude Include="..\..\Elfheader.h" />
<ClInclude Include="..\..\Exceptions.h" />
<ClInclude Include="..\..\Gif.h" />
<ClInclude Include="..\..\GS.h" />
<ClInclude Include="..\..\HashMap.h" />
<ClInclude Include="..\..\HostGui.h" />

View File

@ -214,7 +214,7 @@
PreprocessorDefinitions="NDEBUG;wxUSE_UNICODE=1"
ExceptionHandling="2"
EnableEnhancedInstructionSet="0"
UsePrecompiledHeader="0"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="PrecompiledHeader.h"
PrecompiledHeaderFile="$(IntDir)\$(TargetName).pch"
CompileAs="2"
@ -1502,6 +1502,10 @@
RelativePath="..\..\x86\microVU_Lower.inl"
>
</File>
<File
RelativePath="..\..\x86\microVU_Macro.inl"
>
</File>
<File
RelativePath="..\..\x86\microVU_Misc.h"
>

View File

@ -22,6 +22,7 @@
#include <winnt.h>
#include "Common.h"
#include "cdvd/CDVD.h"
int SysPageFaultExceptionFilter( EXCEPTION_POINTERS* eps )
{

View File

@ -31,6 +31,8 @@
extern void _vu0WaitMicro();
#ifndef CHECK_MACROVU0
#define _Ft_ _Rt_
#define _Fs_ _Rd_
#define _Fd_ _Sa_
@ -39,60 +41,36 @@ extern void _vu0WaitMicro();
#define _Ftf_ ((cpuRegs.code >> 23) & 0x03)
#define _Cc_ (cpuRegs.code & 0x03)
void recCop2BranchCall( void (*func)() )
{
SetFPUstate();
recBranchCall( func );
_freeX86regs();
}
#define REC_COP2_FUNC( f ) \
void rec##f(s32 info) \
{ \
Console::Notice("Warning > cop2 "#f" called"); \
recCop2BranchCall( f ); \
#define REC_COP2_VU0(f) \
void recV##f( s32 info ) { \
recVUMI_##f( &VU0, info ); \
}
#define INTERPRETATE_COP2_FUNC(f) \
void recV##f(s32 info) { \
MOV32ItoM((uptr)&cpuRegs.code, cpuRegs.code); \
MOV32ItoM((uptr)&cpuRegs.pc, pc); \
iFlushCall(FLUSH_EVERYTHING); \
CALLFunc((uptr)V##f); \
_freeX86regs(); \
}
#define REC_COP2_VU0(f) \
void recV##f( s32 info ) { \
recVUMI_##f( &VU0, info ); \
}
#define REC_COP2_VU0_Q(f) \
void recV##f( s32 info ) { \
recVUMI_##f( &VU0, info ); \
}
void rec_C2UNK( s32 info )
{
Console::Error("Cop2 bad opcode: %x", params cpuRegs.code);
}
void _vuRegs_C2UNK(VURegs * VU, _VURegsNum *VUregsn)
{
Console::Error("Cop2 bad _vuRegs code:%x", params cpuRegs.code);
#define INTERPRETATE_COP2_FUNC(f) \
void recV##f(s32 info) { \
MOV32ItoM((uptr)&cpuRegs.code, cpuRegs.code); \
MOV32ItoM((uptr)&cpuRegs.pc, pc); \
iFlushCall(FLUSH_EVERYTHING); \
CALLFunc((uptr)V##f); \
_freeX86regs(); \
}
void recCOP2(s32 info);
void recCOP2_SPECIAL(s32 info);
void recCOP2_BC2(s32 info);
void recCOP2_SPECIAL2(s32 info);
void rec_C2UNK( s32 info ) {
Console::Error("Cop2 bad opcode: %x", params cpuRegs.code);
}
void _vuRegs_C2UNK(VURegs * VU, _VURegsNum *VUregsn) {
Console::Error("Cop2 bad _vuRegs code:%x", params cpuRegs.code);
}
static void recCFC2(s32 info)
{
int mmreg;
if (cpuRegs.code & 1)
{
if (cpuRegs.code & 1) {
iFlushCall(FLUSH_NOCONST);
CALLFunc((uptr)_vu0WaitMicro);
}
@ -102,48 +80,30 @@ static void recCFC2(s32 info)
_deleteGPRtoXMMreg(_Rt_, 2);
mmreg = _checkMMXreg(MMX_GPR+_Rt_, MODE_WRITE);
if( mmreg >= 0 )
{
if( _Fs_ >= 16 )
{
MOVDMtoMMX(mmreg, (uptr)&VU0.VI[ _Fs_ ].UL);
if( EEINST_ISLIVE1(_Rt_) )
{
_signExtendGPRtoMMX(mmreg, _Rt_, 0);
}
else
{
EEINST_RESETHASLIVE1(_Rt_);
}
}
else
{
if (mmreg >= 0) {
if( _Fs_ >= 16 ) {
MOVDMtoMMX(mmreg, (uptr)&VU0.VI[ _Fs_ ].UL);
if (EEINST_ISLIVE1(_Rt_)) { _signExtendGPRtoMMX(mmreg, _Rt_, 0); }
else { EEINST_RESETHASLIVE1(_Rt_); }
}
else MOVDMtoMMX(mmreg, (uptr)&VU0.VI[ _Fs_ ].UL);
SetMMXstate();
}
else
{
else {
MOV32MtoR(EAX, (uptr)&VU0.VI[ _Fs_ ].UL);
MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0],EAX);
if(EEINST_ISLIVE1(_Rt_))
{
if( _Fs_ < 16 )
{
if(EEINST_ISLIVE1(_Rt_)) {
if( _Fs_ < 16 ) {
// no sign extending
MOV32ItoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[1],0);
}
else
{
else {
CDQ();
MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[1], EDX);
}
}
else
{
EEINST_RESETHASLIVE1(_Rt_);
}
else { EEINST_RESETHASLIVE1(_Rt_); }
}
_eeOnWriteReg(_Rt_, 1);
@ -253,8 +213,7 @@ static void recQMFC2(s32 info)
{
int t0reg, fsreg;
if (cpuRegs.code & 1)
{
if (cpuRegs.code & 1) {
iFlushCall(FLUSH_NOCONST);
CALLFunc((uptr)_vu0WaitMicro);
}
@ -269,8 +228,7 @@ static void recQMFC2(s32 info)
fsreg = _checkXMMreg(XMMTYPE_VFREG, _Fs_, MODE_READ);
if( fsreg >= 0 ) {
if( xmmregs[fsreg].mode & MODE_WRITE )
{
if ( xmmregs[fsreg].mode & MODE_WRITE ) {
_xmmregs temp;
t0reg = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE);
@ -281,8 +239,7 @@ static void recQMFC2(s32 info)
xmmregs[t0reg] = xmmregs[fsreg];
xmmregs[fsreg] = temp;
}
else
{
else {
// swap regs
t0reg = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE);
@ -293,10 +250,8 @@ static void recQMFC2(s32 info)
else {
t0reg = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE);
if( t0reg >= 0 )
SSE_MOVAPS_M128_to_XMM( t0reg, (uptr)&VU0.VF[_Fs_].UD[0]);
else
_recMove128MtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], (uptr)&VU0.VF[_Fs_].UL[0]);
if (t0reg >= 0) SSE_MOVAPS_M128_to_XMM( t0reg, (uptr)&VU0.VF[_Fs_].UD[0]);
else _recMove128MtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], (uptr)&VU0.VF[_Fs_].UL[0]);
}
_clearNeededXMMregs();
@ -378,10 +333,6 @@ static void recQMTC2(s32 info)
//////////////////////////////////////////////////////////////////////////
// BC2: Instructions
//////////////////////////////////////////////////////////////////////////
//REC_COP2_FUNC(BC2F);
//REC_COP2_FUNC(BC2T);
//REC_COP2_FUNC(BC2FL);
//REC_COP2_FUNC(BC2TL);
using namespace R5900::Dynarec;
@ -393,8 +344,7 @@ static void _setupBranchTest()
// ((VU0.VI[REG_VPU_STAT].US[0] >> 8) & 1)
// BC2F checks if the statement is false, BC2T checks if the statement is true.
MOV32MtoR( EAX, (uptr)&VU0.VI[REG_VPU_STAT].UL );
TEST32ItoR( EAX, 0x100 );
TEST32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, 0x100);
}
void recBC2F( s32 info )
@ -421,10 +371,10 @@ void recBC2TL( s32 info )
recDoBranchImm_Likely(JZ32(0));
}
//////////////////////////////////////////////////////////////////////////
// Special1 instructions
//////////////////////////////////////////////////////////////////////////
//TODO: redirect all the opcodes to the ivu0micro same functions
REC_COP2_VU0(IADD);
REC_COP2_VU0(IADDI);
@ -551,9 +501,9 @@ REC_COP2_VU0(MULAz);
REC_COP2_VU0(MULAw);
REC_COP2_VU0(OPMULA);
REC_COP2_VU0(MOVE);
REC_COP2_VU0_Q(DIV);
REC_COP2_VU0_Q(SQRT);
REC_COP2_VU0_Q(RSQRT);
REC_COP2_VU0(DIV);
REC_COP2_VU0(SQRT);
REC_COP2_VU0(RSQRT);
REC_COP2_VU0(MR32);
REC_COP2_VU0(ABS);
@ -718,3 +668,4 @@ void recCOP2_SPECIAL2(s32 info)
recCOP2SPECIAL2t[opc](info);
}
#endif // CHECK_MACROVU0

View File

@ -96,12 +96,16 @@ PCSX2_ALIGNED16(u8 backVUmem [0x4000]);
PCSX2_ALIGNED16(u8 cmpVUmem [0x4000]);
static u32 runCount = 0;
#define VU3 ((VURegs)*((VURegs*)cmpVUregs))
#define fABS(aInt) (aInt & 0x7fffffff)
//#define cmpU(uA, uB) (fABS(uA) != fABS(uB))
#define cmpU(uA, uB) (uA != uB)
#define cmpA Console::Error
#define cmpB Console::WriteLn
#define cmpPrint(cond) { \
if (cond) { \
cmpA("%s", params str1); \
cmpA("%s", params str2); \
mVUdebugNow = 1; \
} \
else { \
cmpB("%s", params str1); \
@ -163,12 +167,12 @@ namespace VU1micro
for (int i = 0; i < 32; i++) {
sprintf(str1, "VF%02d = {%f, %f, %f, %f}", i, VU3.VF[i].F[0], VU3.VF[i].F[1], VU3.VF[i].F[2], VU3.VF[i].F[3]);
sprintf(str2, "VF%02d = {%f, %f, %f, %f}", i, VU1.VF[i].F[0], VU1.VF[i].F[1], VU1.VF[i].F[2], VU1.VF[i].F[3]);
cmpPrint(((VU1.VF[i].UL[0] != VU3.VF[i].UL[0]) || (VU1.VF[i].UL[1] != VU3.VF[i].UL[1]) || (VU1.VF[i].UL[2] != VU3.VF[i].UL[2]) || (VU1.VF[i].UL[3] != VU3.VF[i].UL[3])));
cmpPrint((cmpU(VU1.VF[i].UL[0], VU3.VF[i].UL[0]) || cmpU(VU1.VF[i].UL[1], VU3.VF[i].UL[1]) || cmpU(VU1.VF[i].UL[2], VU3.VF[i].UL[2]) || cmpU(VU1.VF[i].UL[3], VU3.VF[i].UL[3])));
}
sprintf(str1, "ACC = {%f, %f, %f, %f}", VU3.ACC.F[0], VU3.ACC.F[1], VU3.ACC.F[2], VU3.ACC.F[3]);
sprintf(str2, "ACC = {%f, %f, %f, %f}", VU1.ACC.F[0], VU1.ACC.F[1], VU1.ACC.F[2], VU1.ACC.F[3]);
cmpPrint(((VU1.ACC.F[0] != VU3.ACC.F[0]) || (VU1.ACC.F[1] != VU3.ACC.F[1]) || (VU1.ACC.F[2] != VU3.ACC.F[2]) || (VU1.ACC.F[3] != VU3.ACC.F[3])));
cmpPrint((cmpU(VU1.ACC.UL[0], VU3.ACC.UL[0]) || cmpU(VU1.ACC.UL[1], VU3.ACC.UL[1]) || cmpU(VU1.ACC.UL[2], VU3.ACC.UL[2]) || cmpU(VU1.ACC.UL[3], VU3.ACC.UL[3])));
for (int i = 0; i < 16; i++) {
sprintf(str1, "VI%02d = % 8d ($%08x)", i, (s16)VU3.VI[i].UL, VU3.VI[i].UL);
@ -227,18 +231,21 @@ namespace VU1micro
cmpPrint((VU1.VI[REG_TPC].UL != VU3.VI[REG_TPC].UL));
SysPrintf("-----------------------------------------------\n\n");
if (mVUdebugNow) {
mVUdebugNow = 1;
resetVUrec(1);
memcpy_fast((u8*)&VU1, (u8*)backVUregs, sizeof(VURegs));
memcpy_fast((u8*)VU1.Mem, (u8*)backVUmem, 0x4000);
resetVUrec(1);
memcpy_fast((u8*)&VU1, (u8*)backVUregs, sizeof(VURegs));
memcpy_fast((u8*)VU1.Mem, (u8*)backVUmem, 0x4000);
runVUrec(VU1.VI[REG_TPC].UL, 300000 /*0x7fffffff*/, 1);
runVUrec(VU1.VI[REG_TPC].UL, 300000 /*0x7fffffff*/, 1);
for (int i = 0; i < 10000000; i++) {
Sleep(1000);
for (int i = 0; i < 10000000; i++) {
Sleep(1000);
}
}
}
VUtestPause();
FreezeXMMRegs(0);
}

View File

@ -96,6 +96,15 @@ public:
}
return NULL;
}
void printInfo() {
microBlockLink* linkI = &blockList;
for (int i = 0; i <= listI; i++) {
DevCon::Status("[Block #%d][q=%02d][p=%02d][xgkick=%d][vi15=%08x][viBackup=%02d][flags=%02x][exactMatch=%x]",
params i, linkI->block->pState.q, linkI->block->pState.p, linkI->block->pState.xgkick, linkI->block->pState.vi15,
linkI->block->pState.viBackUp, linkI->block->pState.flags, linkI->block->pState.needExactMatch);
linkI = linkI->next;
}
}
};
#define mMaxRanges 128
@ -213,3 +222,4 @@ typedef void (__fastcall *mVUrecCall)(u32, u32);
#include "microVU_Branch.inl"
#include "microVU_Compile.inl"
#include "microVU_Execute.inl"
#include "microVU_Macro.inl"

View File

@ -68,7 +68,7 @@ microVUt(void) mVUendProgram(mV, microFlagCycles* mFC, int isEbit) {
if (isEbit || isVU1) { // Clear 'is busy' Flags
AND32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, (isVU1 ? ~0x100 : ~0x001)); // VBS0/VBS1 flag
AND32ItoM((uptr)&mVU->regs->vifRegs->stat, ~0x4); // Clear VU 'is busy' signal for vif
AND32ItoM((uptr)&mVU->regs->vifRegs->stat, ~VIF1_STAT_VEW); // Clear VU 'is busy' signal for vif
}
if (isEbit != 2) { // Save PC, and Jump to Exit Point

View File

@ -285,16 +285,19 @@ void __fastcall mVUprintPC1(u32 PC) { Console::Write("Block PC [%04x] ", params
void __fastcall mVUprintPC2(u32 PC) { Console::Write("[%04x]\n", params PC); }
microVUt(void) mVUtestCycles(mV) {
u32* vu0jmp;
iPC = mVUstartPC;
mVUdebugNOW(0);
SUB32ItoM((uptr)&mVU->cycles, mVUcycles);
if (IsDevBuild || !isVU1) {
u32* jmp32 = JG32(0);
if (!isVU1) { TEST32ItoM((uptr)&mVU->regs->flags, VUFLAG_MFLAGSET); vu0jmp = JZ32(0); }
MOV32ItoR(gprT2, (uptr)mVU);
if (isVU1) CALLFunc((uptr)mVUwarning1);
//else CALLFunc((uptr)mVUwarning0); // VU0 is allowed early exit for COP2 Interlock Simulation
MOV32ItoR(gprR, Roffset); // Restore gprR
mVUendProgram(mVU, NULL, 0);
if (!isVU1) x86SetJ32(vu0jmp);
x86SetJ32(jmp32);
}
}

View File

@ -130,6 +130,14 @@ microVUx(void) mVUcleanUp() {
mVU->cycles = mVU->totalCycles - mVU->cycles;
mVU->regs->cycle += mVU->cycles;
cpuRegs.cycle += ((mVU->cycles < 3000) ? mVU->cycles : 3000) * EmuConfig.Speedhacks.VUCycleSteal;
//static int ax = 0; ax++;
//if (!(ax % 100000)) {
// for (u32 i = 0; i < (mVU->progSize / 2); i++) {
// if (mVUcurProg.block[i]) {
// mVUcurProg.block[i]->printInfo();
// }
// }
//}
}
//------------------------------------------------------------------

View File

@ -74,7 +74,8 @@ int sortFlag(int* fFlag, int* bFlag, int cycles) {
return x; // Returns the number of Valid Flag Instances
}
#define sFlagCond ((sFLAG.doFlag && !mVUsFlagHack) || mVUlow.isFSSET || mVUinfo.doDivFlag)
#define sFlagCond (sFLAG.doFlag || mVUlow.isFSSET || mVUinfo.doDivFlag)
#define sHackCond (mVUsFlagHack && !sFLAG.doNonSticky)
// Note: Flag handling is 'very' complex, it requires full knowledge of how microVU recs work, so don't touch!
microVUt(void) mVUsetFlags(mV, microFlagCycles& mFC) {
@ -143,6 +144,7 @@ microVUt(void) mVUsetFlags(mV, microFlagCycles& mFC) {
mFLAG.lastWrite = (xM-1) & 3;
cFLAG.lastWrite = (xC-1) & 3;
if (sHackCond) { sFLAG.doFlag = 0; }
if (sFlagCond) { mFC.xStatus[xS] = mFC.cycles + 4; xS = (xS+1) & 3; }
if (mFLAG.doFlag) { mFC.xMac [xM] = mFC.cycles + 4; xM = (xM+1) & 3; }
if (cFLAG.doFlag) { mFC.xClip [xC] = mFC.cycles + 4; xC = (xC+1) & 3; }
@ -238,8 +240,9 @@ void mVUflagPass(mV, u32 startPC, u32 xCount) {
iPC = startPC / 4;
mVUcount = 0;
mVUbranch = 0;
for (int branch = 0; mVUcount < xCount; mVUcount++) {
for (int branch = 0; mVUcount < xCount; mVUcount=(mVUregs.needExactMatch&8)?(mVUcount+1):mVUcount) {
incPC(1);
mVUopU(mVU, 3);
if ( curI & _Ebit_ ) { branch = 1; }
if ( curI & _DTbit_ ) { branch = 6; }
if (!(curI & _Ibit_) ) { incPC(-1); mVUopL(mVU, 3); incPC(1); }
@ -263,18 +266,19 @@ void mVUflagPass(mV, u32 startPC, u32 xCount) {
microVUt(void) mVUsetFlagInfo(mV) {
branchType1 { incPC(-1); mVUflagPass(mVU, branchAddr, 4); incPC(1); }
branchType2 {
if (!mVUlow.constJump.isValid) { mVUregs.needExactMatch |= 0x7; }
if (!mVUlow.constJump.isValid || CHECK_VU_CONSTHACK) { mVUregs.needExactMatch |= 0x7; }
else { mVUflagPass(mVU, (mVUlow.constJump.regValue*8)&(mVU->microMemSize-8), 4); }
}
branchType3 {
incPC(-1);
incPC(-1);
mVUflagPass(mVU, branchAddr, 4);
int backupFlagInfo = mVUregs.needExactMatch;
mVUregs.needExactMatch = 0;
incPC(4); // Branch Not Taken
mVUflagPass(mVU, xPC, 4);
incPC(-3);
incPC(-3);
mVUregs.needExactMatch |= backupFlagInfo;
}
mVUregs.needExactMatch &= 0x7;
}

View File

@ -520,7 +520,7 @@ mVUop(mVU_FMAND) {
mVUallocVIb(mVU, gprT1, _It_);
}
pass3 { mVUlog("FMAND vi%02d, vi%02d", _Ft_, _Fs_); }
pass4 { mVUregs.needExactMatch |= 2; }
pass4 { mVUregs.needExactMatch |= 2; }
}
mVUop(mVU_FMEQ) {
@ -534,7 +534,7 @@ mVUop(mVU_FMEQ) {
mVUallocVIb(mVU, gprT1, _It_);
}
pass3 { mVUlog("FMEQ vi%02d, vi%02d", _Ft_, _Fs_); }
pass4 { mVUregs.needExactMatch |= 2; }
pass4 { mVUregs.needExactMatch |= 2; }
}
mVUop(mVU_FMOR) {
@ -546,7 +546,7 @@ mVUop(mVU_FMOR) {
mVUallocVIb(mVU, gprT1, _It_);
}
pass3 { mVUlog("FMOR vi%02d, vi%02d", _Ft_, _Fs_); }
pass4 { mVUregs.needExactMatch |= 2; }
pass4 { mVUregs.needExactMatch |= 2; }
}
//------------------------------------------------------------------

671
pcsx2/x86/microVU_Macro.inl Normal file
View File

@ -0,0 +1,671 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifdef CHECK_MACROVU0
#pragma once
#include "iR5900.h"
#include "R5900OpcodeTables.h"
extern void _vu0WaitMicro();
//------------------------------------------------------------------
// Macro VU - Helper Macros
//------------------------------------------------------------------
#undef _Ft_
#undef _Fs_
#undef _Fd_
#undef _Fsf_
#undef _Ftf_
#undef _Cc_
#define _Ft_ _Rt_
#define _Fs_ _Rd_
#define _Fd_ _Sa_
#define _Fsf_ ((cpuRegs.code >> 21) & 0x03)
#define _Ftf_ ((cpuRegs.code >> 23) & 0x03)
#define _Cc_ (cpuRegs.code & 0x03)
#define REC_COP2_VU0(f) \
void recV##f( s32 info ) { \
recVUMI_##f( &VU0, info ); \
}
#define INTERPRETATE_COP2_FUNC(f) \
void recV##f(s32 info) { \
MOV32ItoM((uptr)&cpuRegs.code, cpuRegs.code); \
MOV32ItoM((uptr)&cpuRegs.pc, pc); \
iFlushCall(FLUSH_EVERYTHING); \
CALLFunc((uptr)V##f); \
_freeX86regs(); \
}
void recCOP2(s32 info);
void recCOP2_SPECIAL(s32 info);
void recCOP2_BC2(s32 info);
void recCOP2_SPECIAL2(s32 info);
void rec_C2UNK( s32 info ) {
Console::Error("Cop2 bad opcode: %x", params cpuRegs.code);
}
void _vuRegs_C2UNK(VURegs * VU, _VURegsNum *VUregsn) {
Console::Error("Cop2 bad _vuRegs code:%x", params cpuRegs.code);
}
static void recCFC2(s32 info)
{
int mmreg;
if (cpuRegs.code & 1) {
iFlushCall(FLUSH_NOCONST);
CALLFunc((uptr)_vu0WaitMicro);
}
if(!_Rt_) return;
_deleteGPRtoXMMreg(_Rt_, 2);
mmreg = _checkMMXreg(MMX_GPR+_Rt_, MODE_WRITE);
if (mmreg >= 0) {
if( _Fs_ >= 16 ) {
MOVDMtoMMX(mmreg, (uptr)&VU0.VI[ _Fs_ ].UL);
if (EEINST_ISLIVE1(_Rt_)) { _signExtendGPRtoMMX(mmreg, _Rt_, 0); }
else { EEINST_RESETHASLIVE1(_Rt_); }
}
else MOVDMtoMMX(mmreg, (uptr)&VU0.VI[ _Fs_ ].UL);
SetMMXstate();
}
else {
MOV32MtoR(EAX, (uptr)&VU0.VI[ _Fs_ ].UL);
MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0],EAX);
if(EEINST_ISLIVE1(_Rt_)) {
if( _Fs_ < 16 ) {
// no sign extending
MOV32ItoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[1],0);
}
else {
CDQ();
MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[1], EDX);
}
}
else { EEINST_RESETHASLIVE1(_Rt_); }
}
_eeOnWriteReg(_Rt_, 1);
}
static void recCTC2(s32 info)
{
if (cpuRegs.code & 1) {
iFlushCall(FLUSH_NOCONST);
CALLFunc((uptr)_vu0WaitMicro);
}
if(!_Fs_) return;
if( GPR_IS_CONST1(_Rt_) )
{
switch(_Fs_) {
case REG_MAC_FLAG: // read-only
case REG_TPC: // read-only
case REG_VPU_STAT: // read-only
break;
case REG_FBRST:
if( g_cpuConstRegs[_Rt_].UL[0] & 0x202 )
iFlushCall(FLUSH_FREE_TEMPX86);
_deleteX86reg(X86TYPE_VI, REG_FBRST, 2);
if( g_cpuConstRegs[_Rt_].UL[0] & 2 )
CALLFunc((uptr)vu0ResetRegs);
if( g_cpuConstRegs[_Rt_].UL[0] & 0x200 )
CALLFunc((uptr)vu1ResetRegs);
MOV16ItoM((uptr)&VU0.VI[REG_FBRST].UL,g_cpuConstRegs[_Rt_].UL[0]&0x0c0c);
break;
case REG_CMSAR1: // REG_CMSAR1
iFlushCall(FLUSH_NOCONST);// since CALLFunc
assert( _checkX86reg(X86TYPE_VI, REG_VPU_STAT, 0) < 0 &&
_checkX86reg(X86TYPE_VI, REG_TPC, 0) < 0 );
// Execute VU1 Micro SubRoutine
_callFunctionArg1((uptr)vu1ExecMicro, MEM_CONSTTAG, g_cpuConstRegs[_Rt_].UL[0]&0xffff);
break;
default:
{
if( _Fs_ < 16 )
assert( (g_cpuConstRegs[_Rt_].UL[0]&0xffff0000)==0);
// a lot of games have vu0 spinning on some integer
// then they modify the register and expect vu0 to stop spinning within 10 cycles (donald duck)
// Use vu0ExecMicro instead because it properly stalls for already-running micro
// instructions, and also sets the nextBranchCycle as needed. (air)
MOV32ItoM((uptr)&VU0.VI[_Fs_].UL,g_cpuConstRegs[_Rt_].UL[0]);
//PUSH32I( -1 );
iFlushCall(FLUSH_NOCONST);
CALLFunc((uptr)CpuVU0.ExecuteBlock);
//CALLFunc((uptr)vu0ExecMicro);
//ADD32ItoR( ESP, 4 );
break;
}
}
}
else
{
switch(_Fs_) {
case REG_MAC_FLAG: // read-only
case REG_TPC: // read-only
case REG_VPU_STAT: // read-only
break;
case REG_FBRST:
iFlushCall(FLUSH_FREE_TEMPX86);
assert( _checkX86reg(X86TYPE_VI, REG_FBRST, 0) < 0 );
_eeMoveGPRtoR(EAX, _Rt_);
TEST32ItoR(EAX,0x2);
j8Ptr[0] = JZ8(0);
CALLFunc((uptr)vu0ResetRegs);
_eeMoveGPRtoR(EAX, _Rt_);
x86SetJ8(j8Ptr[0]);
TEST32ItoR(EAX,0x200);
j8Ptr[0] = JZ8(0);
CALLFunc((uptr)vu1ResetRegs);
_eeMoveGPRtoR(EAX, _Rt_);
x86SetJ8(j8Ptr[0]);
AND32ItoR(EAX,0x0C0C);
MOV16RtoM((uptr)&VU0.VI[REG_FBRST].UL,EAX);
break;
case REG_CMSAR1: // REG_CMSAR1
iFlushCall(FLUSH_NOCONST);
_eeMoveGPRtoR(EAX, _Rt_);
_callFunctionArg1((uptr)vu1ExecMicro, MEM_X86TAG|EAX, 0); // Execute VU1 Micro SubRoutine
break;
default:
_eeMoveGPRtoM((uptr)&VU0.VI[_Fs_].UL,_Rt_);
// a lot of games have vu0 spinning on some integer
// then they modify the register and expect vu0 to stop spinning within 10 cycles (donald duck)
iFlushCall(FLUSH_NOCONST);
break;
}
}
}
static void recQMFC2(s32 info)
{
int t0reg, fsreg;
if (cpuRegs.code & 1) {
iFlushCall(FLUSH_NOCONST);
CALLFunc((uptr)_vu0WaitMicro);
}
if(!_Rt_) return;
_deleteMMXreg(MMX_GPR+_Rt_, 2);
_deleteX86reg(X86TYPE_GPR, _Rt_, 2);
_eeOnWriteReg(_Rt_, 0);
// could 'borrow' the reg
fsreg = _checkXMMreg(XMMTYPE_VFREG, _Fs_, MODE_READ);
if( fsreg >= 0 ) {
if ( xmmregs[fsreg].mode & MODE_WRITE ) {
_xmmregs temp;
t0reg = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE);
SSEX_MOVDQA_XMM_to_XMM(t0reg, fsreg);
// change regs
temp = xmmregs[t0reg];
xmmregs[t0reg] = xmmregs[fsreg];
xmmregs[fsreg] = temp;
}
else {
// swap regs
t0reg = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE);
xmmregs[fsreg] = xmmregs[t0reg];
xmmregs[t0reg].inuse = 0;
}
}
else {
t0reg = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE);
if (t0reg >= 0) SSE_MOVAPS_M128_to_XMM( t0reg, (uptr)&VU0.VF[_Fs_].UD[0]);
else _recMove128MtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], (uptr)&VU0.VF[_Fs_].UL[0]);
}
_clearNeededXMMregs();
}
static void recQMTC2(s32 info)
{
int mmreg;
if (cpuRegs.code & 1) {
iFlushCall(FLUSH_NOCONST);
CALLFunc((uptr)_vu0WaitMicro);
}
if (!_Fs_) return;
mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rt_, MODE_READ);
if( mmreg >= 0) {
int fsreg = _checkXMMreg(XMMTYPE_VFREG, _Fs_, MODE_WRITE);
int flag = ((xmmregs[mmreg].mode&MODE_WRITE) && (g_pCurInstInfo->regs[_Rt_]&(EEINST_LIVE0|EEINST_LIVE1|EEINST_LIVE2)));
if( fsreg >= 0 ) {
if (flag) {
SSE_MOVAPS_XMM_to_XMM(fsreg, mmreg);
}
else {
// swap regs
xmmregs[mmreg] = xmmregs[fsreg];
xmmregs[mmreg].mode = MODE_WRITE;
xmmregs[fsreg].inuse = 0;
g_xmmtypes[mmreg] = XMMT_FPS;
}
}
else {
if (flag) SSE_MOVAPS_XMM_to_M128((uptr)&cpuRegs.GPR.r[_Rt_], mmreg);
// swap regs
xmmregs[mmreg].type = XMMTYPE_VFREG;
xmmregs[mmreg].VU = 0;
xmmregs[mmreg].reg = _Fs_;
xmmregs[mmreg].mode = MODE_WRITE;
g_xmmtypes[mmreg] = XMMT_FPS;
}
}
else {
int fsreg = _allocVFtoXMMreg(&VU0, -1, _Fs_, MODE_WRITE);
if( fsreg >= 0 ) {
mmreg = _checkMMXreg(MMX_GPR+_Rt_, MODE_READ);
if( mmreg >= 0) {
SetMMXstate();
SSE2_MOVQ2DQ_MM_to_XMM(fsreg, mmreg);
SSE_MOVHPS_M64_to_XMM(fsreg, (uptr)&cpuRegs.GPR.r[_Rt_].UL[2]);
}
else {
if( GPR_IS_CONST1( _Rt_ ) ) {
assert( _checkXMMreg(XMMTYPE_GPRREG, _Rt_, MODE_READ) == -1 );
_flushConstReg(_Rt_);
}
SSE_MOVAPS_M128_to_XMM(fsreg, (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]);
}
}
else {
_deleteEEreg(_Rt_, 0);
_recMove128MtoM((uptr)&VU0.VF[_Fs_].UL[0], (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]);
}
}
_clearNeededXMMregs();
}
//------------------------------------------------------------------
// Macro VU - Instructions
//------------------------------------------------------------------
using namespace R5900::Dynarec;
void printCOP2(const char* text) {
Console::Status(text);
}
//------------------------------------------------------------------
// Macro VU - Branches
//------------------------------------------------------------------
static void _setupBranchTest() {
_eeFlushAllUnused();
TEST32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, 0x100);
printCOP2("_setupBranchTest()");
}
void recBC2F(s32 info) {
_setupBranchTest();
recDoBranchImm(JNZ32(0));
}
void recBC2T(s32 info) {
_setupBranchTest();
recDoBranchImm(JZ32(0));
}
void recBC2FL(s32 info) {
_setupBranchTest();
recDoBranchImm_Likely(JNZ32(0));
}
void recBC2TL(s32 info) {
_setupBranchTest();
recDoBranchImm_Likely(JZ32(0));
}
#define REC_COP2_mVU0(f, opName) \
void recV##f(s32 info) { \
microVU0.prog.IRinfo.curPC = 0; \
microVU0.code = cpuRegs.code; \
memset(&microVU0.prog.IRinfo.info[0], 0, sizeof(microVU0.prog.IRinfo.info[0])); \
iFlushCall(FLUSH_EVERYTHING); \
microVU0.regAlloc->reset(); \
/*mVU_##f(&microVU0, 0);*/ \
mVU_##f(&microVU0, 1); \
microVU0.regAlloc->flushAll(); \
printCOP2(opName); \
}
//------------------------------------------------------------------
// Macro VU - Redirect Upper Instructions
//------------------------------------------------------------------
REC_COP2_mVU0(ABS, "ABS");
REC_COP2_mVU0(ITOF0, "ITOF0");
REC_COP2_mVU0(ITOF4, "ITOF4");
REC_COP2_mVU0(ITOF12, "ITOF12");
REC_COP2_mVU0(ITOF15, "ITOF15");
REC_COP2_mVU0(FTOI0, "FTOI0");
REC_COP2_mVU0(FTOI4, "FTOI4");
REC_COP2_mVU0(FTOI12, "FTOI12");
REC_COP2_mVU0(FTOI15, "FTOI15");
REC_COP2_mVU0(ADD, "ADD");
REC_COP2_mVU0(ADDi, "ADDi");
REC_COP2_VU0 (ADDq);
REC_COP2_mVU0(ADDx, "ADDx");
REC_COP2_mVU0(ADDy, "ADDy");
REC_COP2_mVU0(ADDz, "ADDz");
REC_COP2_mVU0(ADDw, "ADDw");
REC_COP2_mVU0(ADDA, "ADDA");
REC_COP2_mVU0(ADDAi, "ADDAi");
REC_COP2_VU0 (ADDAq);
REC_COP2_mVU0(ADDAx, "ADDAx");
REC_COP2_mVU0(ADDAy, "ADDAy");
REC_COP2_mVU0(ADDAz, "ADDAz");
REC_COP2_mVU0(ADDAw, "ADDAw");
REC_COP2_mVU0(SUB, "SUB");
REC_COP2_mVU0(SUBi, "SUBi");
REC_COP2_VU0 (SUBq);
REC_COP2_mVU0(SUBx, "SUBx");
REC_COP2_mVU0(SUBy, "SUBy");
REC_COP2_mVU0(SUBz, "SUBz");
REC_COP2_mVU0(SUBw, "SUBw");
REC_COP2_mVU0(SUBA, "SUBA");
REC_COP2_mVU0(SUBAi, "SUBAi");
REC_COP2_VU0 (SUBAq);
REC_COP2_mVU0(SUBAx, "SUBAx");
REC_COP2_mVU0(SUBAy, "SUBAy");
REC_COP2_mVU0(SUBAz, "SUBAz");
REC_COP2_mVU0(SUBAw, "SUBAw");
REC_COP2_mVU0(MUL, "MUL");
REC_COP2_mVU0(MULi, "MULi");
REC_COP2_VU0 (MULq);
REC_COP2_mVU0(MULx, "MULx");
REC_COP2_mVU0(MULy, "MULy");
REC_COP2_mVU0(MULz, "MULz");
REC_COP2_mVU0(MULw, "MULw");
REC_COP2_mVU0(MULA, "MULA");
REC_COP2_mVU0(MULAi, "MULAi");
REC_COP2_VU0 (MULAq);
REC_COP2_mVU0(MULAx, "MULAx");
REC_COP2_mVU0(MULAy, "MULAy");
REC_COP2_mVU0(MULAz, "MULAz");
REC_COP2_mVU0(MULAw, "MULAw");
REC_COP2_mVU0(MAX, "MAX");
REC_COP2_mVU0(MAXi, "MAXi");
REC_COP2_mVU0(MAXx, "MAXx");
REC_COP2_mVU0(MAXy, "MAXy");
REC_COP2_mVU0(MAXz, "MAXz");
REC_COP2_mVU0(MAXw, "MAXw");
REC_COP2_mVU0(MINI, "MINI");
REC_COP2_mVU0(MINIi, "MINIi");
REC_COP2_mVU0(MINIx, "MINIx");
REC_COP2_mVU0(MINIy, "MINIy");
REC_COP2_mVU0(MINIz, "MINIz");
REC_COP2_mVU0(MINIw, "MINIw");
REC_COP2_mVU0(MADD, "MADD");
REC_COP2_mVU0(MADDi, "MADDi");
REC_COP2_VU0 (MADDq);
REC_COP2_mVU0(MADDx, "MADDx");
REC_COP2_mVU0(MADDy, "MADDy");
REC_COP2_mVU0(MADDz, "MADDz");
REC_COP2_mVU0(MADDw, "MADDw");
REC_COP2_mVU0(MADDA, "MADDA");
REC_COP2_mVU0(MADDAi, "MADDAi");
REC_COP2_VU0 (MADDAq);
REC_COP2_mVU0(MADDAx, "MADDAx");
REC_COP2_mVU0(MADDAy, "MADDAy");
REC_COP2_mVU0(MADDAz, "MADDAz");
REC_COP2_mVU0(MADDAw, "MADDAw");
REC_COP2_mVU0(MSUB, "MSUB");
REC_COP2_mVU0(MSUBi, "MSUBi");
REC_COP2_VU0 (MSUBq);
REC_COP2_mVU0(MSUBx, "MSUBx");
REC_COP2_mVU0(MSUBy, "MSUBy");
REC_COP2_mVU0(MSUBz, "MSUBz");
REC_COP2_mVU0(MSUBw, "MSUBw");
REC_COP2_mVU0(MSUBA, "MSUBA");
REC_COP2_mVU0(MSUBAi, "MSUBAi");
REC_COP2_VU0 (MSUBAq);
REC_COP2_mVU0(MSUBAx, "MSUBAx");
REC_COP2_mVU0(MSUBAy, "MSUBAy");
REC_COP2_mVU0(MSUBAz, "MSUBAz");
REC_COP2_mVU0(MSUBAw, "MSUBAw");
REC_COP2_mVU0(OPMULA, "OPMULA");
REC_COP2_mVU0(OPMSUB, "OPMSUB");
REC_COP2_VU0 (CLIP);
//------------------------------------------------------------------
// Macro VU - Redirect Lower Instructions
//------------------------------------------------------------------
REC_COP2_VU0(DIV);
REC_COP2_VU0(SQRT);
REC_COP2_VU0(RSQRT);
REC_COP2_VU0(IADD);
REC_COP2_VU0(IADDI);
REC_COP2_VU0(IAND);
REC_COP2_VU0(IOR);
REC_COP2_VU0(ISUB);
REC_COP2_VU0(ILWR);
REC_COP2_VU0(ISWR);
REC_COP2_VU0(LQI);
REC_COP2_VU0(LQD);
REC_COP2_VU0(SQI);
REC_COP2_VU0(SQD);
REC_COP2_VU0(MOVE);
REC_COP2_VU0(MFIR);
REC_COP2_VU0(MTIR);
REC_COP2_VU0(MR32);
REC_COP2_VU0(RINIT);
REC_COP2_VU0(RGET);
REC_COP2_VU0(RNEXT);
REC_COP2_VU0(RXOR);
/*
REC_COP2_mVU0(IADD, "IADD");
REC_COP2_mVU0(IADDI, "IADDI");
REC_COP2_mVU0(IAND, "IAND");
REC_COP2_mVU0(IOR, "IOR");
REC_COP2_mVU0(ISUB, "ISUB");
REC_COP2_mVU0(ILWR, "ILWR");
REC_COP2_mVU0(ISWR, "ISWR");
REC_COP2_mVU0(LQI, "LQI");
REC_COP2_mVU0(LQD, "LQD");
REC_COP2_mVU0(SQI, "SQI");
REC_COP2_mVU0(SQD, "SQD");
REC_COP2_mVU0(MOVE, "MOVE");
REC_COP2_mVU0(MFIR, "MFIR");
REC_COP2_mVU0(MTIR, "MTIR");
REC_COP2_mVU0(MR32, "MR32");
REC_COP2_mVU0(RINIT, "RINIT");
REC_COP2_mVU0(RGET, "RGET");
REC_COP2_mVU0(RNEXT, "RNEXT");
REC_COP2_mVU0(RXOR, "RXOR");
*/
void recVNOP(s32 info){}
void recVWAITQ(s32 info){}
INTERPRETATE_COP2_FUNC(CALLMS);
INTERPRETATE_COP2_FUNC(CALLMSR);
void _vuRegsCOP2_SPECIAL (VURegs * VU, _VURegsNum *VUregsn);
void _vuRegsCOP2_SPECIAL2(VURegs * VU, _VURegsNum *VUregsn);
// information
void _vuRegsQMFC2(VURegs * VU, _VURegsNum *VUregsn) {
VUregsn->VFread0 = _Fs_;
VUregsn->VFr0xyzw= 0xf;
}
void _vuRegsCFC2(VURegs * VU, _VURegsNum *VUregsn) {
VUregsn->VIread = 1<<_Fs_;
}
void _vuRegsQMTC2(VURegs * VU, _VURegsNum *VUregsn) {
VUregsn->VFwrite = _Fs_;
VUregsn->VFwxyzw= 0xf;
}
void _vuRegsCTC2(VURegs * VU, _VURegsNum *VUregsn) {
VUregsn->VIwrite = 1<<_Fs_;
}
void (*_vuRegsCOP2t[32])(VURegs * VU, _VURegsNum *VUregsn) = {
_vuRegs_C2UNK, _vuRegsQMFC2, _vuRegsCFC2, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegsQMTC2, _vuRegsCTC2, _vuRegs_C2UNK,
_vuRegsNOP, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegs_C2UNK,
_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,
_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,_vuRegsCOP2_SPECIAL,
};
void (*_vuRegsCOP2SPECIAL1t[64])(VURegs * VU, _VURegsNum *VUregsn) = {
_vuRegsADDx, _vuRegsADDy, _vuRegsADDz, _vuRegsADDw, _vuRegsSUBx, _vuRegsSUBy, _vuRegsSUBz, _vuRegsSUBw,
_vuRegsMADDx, _vuRegsMADDy, _vuRegsMADDz, _vuRegsMADDw, _vuRegsMSUBx, _vuRegsMSUBy, _vuRegsMSUBz, _vuRegsMSUBw,
_vuRegsMAXx, _vuRegsMAXy, _vuRegsMAXz, _vuRegsMAXw, _vuRegsMINIx, _vuRegsMINIy, _vuRegsMINIz, _vuRegsMINIw,
_vuRegsMULx, _vuRegsMULy, _vuRegsMULz, _vuRegsMULw, _vuRegsMULq, _vuRegsMAXi, _vuRegsMULi, _vuRegsMINIi,
_vuRegsADDq, _vuRegsMADDq, _vuRegsADDi, _vuRegsMADDi, _vuRegsSUBq, _vuRegsMSUBq, _vuRegsSUBi, _vuRegsMSUBi,
_vuRegsADD, _vuRegsMADD, _vuRegsMUL, _vuRegsMAX, _vuRegsSUB, _vuRegsMSUB, _vuRegsOPMSUB, _vuRegsMINI,
_vuRegsIADD, _vuRegsISUB, _vuRegsIADDI, _vuRegs_C2UNK, _vuRegsIAND, _vuRegsIOR, _vuRegs_C2UNK, _vuRegs_C2UNK,
_vuRegsNOP, _vuRegsNOP, _vuRegs_C2UNK, _vuRegs_C2UNK, _vuRegsCOP2_SPECIAL2,_vuRegsCOP2_SPECIAL2,_vuRegsCOP2_SPECIAL2,_vuRegsCOP2_SPECIAL2,
};
void (*_vuRegsCOP2SPECIAL2t[128])(VURegs * VU, _VURegsNum *VUregsn) = {
_vuRegsADDAx ,_vuRegsADDAy ,_vuRegsADDAz ,_vuRegsADDAw ,_vuRegsSUBAx ,_vuRegsSUBAy ,_vuRegsSUBAz ,_vuRegsSUBAw,
_vuRegsMADDAx ,_vuRegsMADDAy ,_vuRegsMADDAz ,_vuRegsMADDAw ,_vuRegsMSUBAx ,_vuRegsMSUBAy ,_vuRegsMSUBAz ,_vuRegsMSUBAw,
_vuRegsITOF0 ,_vuRegsITOF4 ,_vuRegsITOF12 ,_vuRegsITOF15 ,_vuRegsFTOI0 ,_vuRegsFTOI4 ,_vuRegsFTOI12 ,_vuRegsFTOI15,
_vuRegsMULAx ,_vuRegsMULAy ,_vuRegsMULAz ,_vuRegsMULAw ,_vuRegsMULAq ,_vuRegsABS ,_vuRegsMULAi ,_vuRegsCLIP,
_vuRegsADDAq ,_vuRegsMADDAq ,_vuRegsADDAi ,_vuRegsMADDAi ,_vuRegsSUBAq ,_vuRegsMSUBAq ,_vuRegsSUBAi ,_vuRegsMSUBAi,
_vuRegsADDA ,_vuRegsMADDA ,_vuRegsMULA ,_vuRegs_C2UNK ,_vuRegsSUBA ,_vuRegsMSUBA ,_vuRegsOPMULA ,_vuRegsNOP,
_vuRegsMOVE ,_vuRegsMR32 ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegsLQI ,_vuRegsSQI ,_vuRegsLQD ,_vuRegsSQD,
_vuRegsDIV ,_vuRegsSQRT ,_vuRegsRSQRT ,_vuRegsWAITQ ,_vuRegsMTIR ,_vuRegsMFIR ,_vuRegsILWR ,_vuRegsISWR,
_vuRegsRNEXT ,_vuRegsRGET ,_vuRegsRINIT ,_vuRegsRXOR ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK,
_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK,
_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK,
_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK,
_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK,
_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK,
_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK,
_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK ,_vuRegs_C2UNK,
};
#define cParams VURegs* VU, _VURegsNum* VUregsn
void _vuRegsCOP22(cParams) { _vuRegsCOP2t[_Rs_](VU, VUregsn); }
void _vuRegsCOP2_SPECIAL (cParams) { _vuRegsCOP2SPECIAL1t[_Funct_](VU, VUregsn); }
void _vuRegsCOP2_SPECIAL2(cParams) { _vuRegsCOP2SPECIAL2t[(cpuRegs.code&3)|((cpuRegs.code>>4)&0x7c)](VU, VUregsn); }
// recompilation
void (*recCOP2t[32])(s32 info) = {
rec_C2UNK, recQMFC2, recCFC2, rec_C2UNK, rec_C2UNK, recQMTC2, recCTC2, rec_C2UNK,
recCOP2_BC2, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK,
recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,
recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,recCOP2_SPECIAL,
};
void (*recCOP2_BC2t[32])(s32 info) = {
recBC2F, recBC2T, recBC2FL, recBC2TL, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK,
rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK,
rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK,
rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK, rec_C2UNK,
};
void (*recCOP2SPECIAL1t[64])(s32 info) = {
recVADDx, recVADDy, recVADDz, recVADDw, recVSUBx, recVSUBy, recVSUBz, recVSUBw,
recVMADDx, recVMADDy, recVMADDz, recVMADDw, recVMSUBx, recVMSUBy, recVMSUBz, recVMSUBw,
recVMAXx, recVMAXy, recVMAXz, recVMAXw, recVMINIx, recVMINIy, recVMINIz, recVMINIw,
recVMULx, recVMULy, recVMULz, recVMULw, recVMULq, recVMAXi, recVMULi, recVMINIi,
recVADDq, recVMADDq, recVADDi, recVMADDi, recVSUBq, recVMSUBq, recVSUBi, recVMSUBi,
recVADD, recVMADD, recVMUL, recVMAX, recVSUB, recVMSUB, recVOPMSUB, recVMINI,
recVIADD, recVISUB, recVIADDI, rec_C2UNK, recVIAND, recVIOR, rec_C2UNK, rec_C2UNK,
recVCALLMS, recVCALLMSR, rec_C2UNK, rec_C2UNK, recCOP2_SPECIAL2,recCOP2_SPECIAL2,recCOP2_SPECIAL2,recCOP2_SPECIAL2,
};
void (*recCOP2SPECIAL2t[128])(s32 info) = {
recVADDAx ,recVADDAy ,recVADDAz ,recVADDAw ,recVSUBAx ,recVSUBAy ,recVSUBAz ,recVSUBAw,
recVMADDAx ,recVMADDAy ,recVMADDAz ,recVMADDAw ,recVMSUBAx ,recVMSUBAy ,recVMSUBAz ,recVMSUBAw,
recVITOF0 ,recVITOF4 ,recVITOF12 ,recVITOF15 ,recVFTOI0 ,recVFTOI4 ,recVFTOI12 ,recVFTOI15,
recVMULAx ,recVMULAy ,recVMULAz ,recVMULAw ,recVMULAq ,recVABS ,recVMULAi ,recVCLIP,
recVADDAq ,recVMADDAq ,recVADDAi ,recVMADDAi ,recVSUBAq ,recVMSUBAq ,recVSUBAi ,recVMSUBAi,
recVADDA ,recVMADDA ,recVMULA ,rec_C2UNK ,recVSUBA ,recVMSUBA ,recVOPMULA ,recVNOP,
recVMOVE ,recVMR32 ,rec_C2UNK ,rec_C2UNK ,recVLQI ,recVSQI ,recVLQD ,recVSQD,
recVDIV ,recVSQRT ,recVRSQRT ,recVWAITQ ,recVMTIR ,recVMFIR ,recVILWR ,recVISWR,
recVRNEXT ,recVRGET ,recVRINIT ,recVRXOR ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK,
rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK,
rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK,
rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK,
rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK,
rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK,
rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK,
rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK ,rec_C2UNK,
};
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl
{
void recCOP2()
{
VU0.code = cpuRegs.code;
g_pCurInstInfo->vuregs.pipe = 0xff; // to notify eeVURecompileCode that COP2
s32 info = eeVURecompileCode(&VU0, &g_pCurInstInfo->vuregs);
info |= PROCESS_VU_COP2;
info |= PROCESS_VU_UPDATEFLAGS;
recCOP2t[_Rs_]( info );
_freeX86regs();
}
}}}
void recCOP2_BC2(s32 info) { recCOP2_BC2t[_Rt_](info); }
void recCOP2_SPECIAL(s32 info) { recCOP2SPECIAL1t[_Funct_]( info ); }
void recCOP2_SPECIAL2(s32 info) { recCOP2SPECIAL2t[(cpuRegs.code&3)|((cpuRegs.code>>4)&0x7c)](info); }
#endif // CHECK_MACROVU0

View File

@ -263,7 +263,7 @@ typedef u32 (__fastcall *mVUCall)(void*, void*);
#define doRegAlloc 1 // Set to 0 to flush every 64bit Instruction (Turns off regAlloc)
// Speed Hacks
#define CHECK_VU_CONSTHACK 0 // Only use for GoW (will be slower on other games)
#define CHECK_VU_CONSTHACK 1 // Disables Constant Propagation for Jumps
#define CHECK_VU_FLAGHACK (EmuConfig.Speedhacks.vuFlagHack) // (Can cause Infinite loops, SPS, etc...)
#define CHECK_VU_MINMAXHACK (EmuConfig.Speedhacks.vuMinMax) // (Can cause SPS, Black Screens, etc...)

View File

@ -21,8 +21,6 @@
//------------------------------------------------------------------
// Declarations
//------------------------------------------------------------------
#define mVUgetCode (mVU->code)
mVUop(mVU_UPPER_FD_00);
mVUop(mVU_UPPER_FD_01);
mVUop(mVU_UPPER_FD_10);
@ -38,207 +36,185 @@ mVUop(mVUunknown);
//------------------------------------------------------------------
// Opcode Tables
//------------------------------------------------------------------
#define microVU_LOWER_OPCODE(x) void (*mVULOWER_OPCODE##x [128])(mP) = { \
mVU_LQ , mVU_SQ , mVUunknown , mVUunknown, \
mVU_ILW , mVU_ISW , mVUunknown , mVUunknown, \
mVU_IADDIU , mVU_ISUBIU , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVU_FCEQ , mVU_FCSET , mVU_FCAND , mVU_FCOR, /* 0x10 */ \
mVU_FSEQ , mVU_FSSET , mVU_FSAND , mVU_FSOR, \
mVU_FMEQ , mVUunknown , mVU_FMAND , mVU_FMOR, \
mVU_FCGET , mVUunknown , mVUunknown , mVUunknown, \
mVU_B , mVU_BAL , mVUunknown , mVUunknown, /* 0x20 */ \
mVU_JR , mVU_JALR , mVUunknown , mVUunknown, \
mVU_IBEQ , mVU_IBNE , mVUunknown , mVUunknown, \
mVU_IBLTZ , mVU_IBGTZ , mVU_IBLEZ , mVU_IBGEZ, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x30 */ \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVULowerOP , mVUunknown , mVUunknown , mVUunknown, /* 0x40*/ \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x50 */ \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x60 */ \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x70 */ \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
void (*mVULOWER_OPCODE [128])(mP) = {
mVU_LQ , mVU_SQ , mVUunknown , mVUunknown,
mVU_ILW , mVU_ISW , mVUunknown , mVUunknown,
mVU_IADDIU , mVU_ISUBIU , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVU_FCEQ , mVU_FCSET , mVU_FCAND , mVU_FCOR,
mVU_FSEQ , mVU_FSSET , mVU_FSAND , mVU_FSOR,
mVU_FMEQ , mVUunknown , mVU_FMAND , mVU_FMOR,
mVU_FCGET , mVUunknown , mVUunknown , mVUunknown,
mVU_B , mVU_BAL , mVUunknown , mVUunknown,
mVU_JR , mVU_JALR , mVUunknown , mVUunknown,
mVU_IBEQ , mVU_IBNE , mVUunknown , mVUunknown,
mVU_IBLTZ , mVU_IBGTZ , mVU_IBLEZ , mVU_IBGEZ,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVULowerOP , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
};
#define microVU_LowerOP_T3_00_OPCODE(x) void (*mVULowerOP_T3_00_OPCODE##x [32])(mP) = { \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVU_MOVE , mVU_LQI , mVU_DIV , mVU_MTIR, \
mVU_RNEXT , mVUunknown , mVUunknown , mVUunknown, /* 0x10 */ \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVU_MFP , mVU_XTOP , mVU_XGKICK, \
mVU_ESADD , mVU_EATANxy , mVU_ESQRT , mVU_ESIN, \
void (*mVULowerOP_T3_00_OPCODE [32])(mP) = {
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVU_MOVE , mVU_LQI , mVU_DIV , mVU_MTIR,
mVU_RNEXT , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVU_MFP , mVU_XTOP , mVU_XGKICK,
mVU_ESADD , mVU_EATANxy , mVU_ESQRT , mVU_ESIN,
};
#define microVU_LowerOP_T3_01_OPCODE(x) void (*mVULowerOP_T3_01_OPCODE##x [32])(mP) = { \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVU_MR32 , mVU_SQI , mVU_SQRT , mVU_MFIR, \
mVU_RGET , mVUunknown , mVUunknown , mVUunknown, /* 0x10 */ \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVU_XITOP , mVUunknown, \
mVU_ERSADD , mVU_EATANxz , mVU_ERSQRT , mVU_EATAN, \
void (*mVULowerOP_T3_01_OPCODE [32])(mP) = {
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVU_MR32 , mVU_SQI , mVU_SQRT , mVU_MFIR,
mVU_RGET , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVU_XITOP , mVUunknown,
mVU_ERSADD , mVU_EATANxz , mVU_ERSQRT , mVU_EATAN,
};
#define microVU_LowerOP_T3_10_OPCODE(x) void (*mVULowerOP_T3_10_OPCODE##x [32])(mP) = { \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVU_LQD , mVU_RSQRT , mVU_ILWR, \
mVU_RINIT , mVUunknown , mVUunknown , mVUunknown, /* 0x10 */ \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVU_ELENG , mVU_ESUM , mVU_ERCPR , mVU_EEXP, \
void (*mVULowerOP_T3_10_OPCODE [32])(mP) = {
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVU_LQD , mVU_RSQRT , mVU_ILWR,
mVU_RINIT , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVU_ELENG , mVU_ESUM , mVU_ERCPR , mVU_EEXP,
};
#define microVU_LowerOP_T3_11_OPCODE(x) void (*mVULowerOP_T3_11_OPCODE##x [32])(mP) = { \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVU_SQD , mVU_WAITQ , mVU_ISWR, \
mVU_RXOR , mVUunknown , mVUunknown , mVUunknown, /* 0x10 */ \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVU_ERLENG , mVUunknown , mVU_WAITP , mVUunknown, \
void (*mVULowerOP_T3_11_OPCODE [32])(mP) = {
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVU_SQD , mVU_WAITQ , mVU_ISWR,
mVU_RXOR , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVU_ERLENG , mVUunknown , mVU_WAITP , mVUunknown,
};
#define microVU_LowerOP_OPCODE(x) void (*mVULowerOP_OPCODE##x [64])(mP) = { \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x10 */ \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x20 */ \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVU_IADD , mVU_ISUB , mVU_IADDI , mVUunknown, /* 0x30 */ \
mVU_IAND , mVU_IOR , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVULowerOP_T3_00, mVULowerOP_T3_01, mVULowerOP_T3_10, mVULowerOP_T3_11, \
void (*mVULowerOP_OPCODE [64])(mP) = {
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVU_IADD , mVU_ISUB , mVU_IADDI , mVUunknown,
mVU_IAND , mVU_IOR , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVULowerOP_T3_00, mVULowerOP_T3_01, mVULowerOP_T3_10, mVULowerOP_T3_11,
};
#define microVU_UPPER_OPCODE(x) void (*mVU_UPPER_OPCODE##x [64])(mP) = { \
mVU_ADDx , mVU_ADDy , mVU_ADDz , mVU_ADDw, \
mVU_SUBx , mVU_SUBy , mVU_SUBz , mVU_SUBw, \
mVU_MADDx , mVU_MADDy , mVU_MADDz , mVU_MADDw, \
mVU_MSUBx , mVU_MSUBy , mVU_MSUBz , mVU_MSUBw, \
mVU_MAXx , mVU_MAXy , mVU_MAXz , mVU_MAXw, /* 0x10 */ \
mVU_MINIx , mVU_MINIy , mVU_MINIz , mVU_MINIw, \
mVU_MULx , mVU_MULy , mVU_MULz , mVU_MULw, \
mVU_MULq , mVU_MAXi , mVU_MULi , mVU_MINIi, \
mVU_ADDq , mVU_MADDq , mVU_ADDi , mVU_MADDi, /* 0x20 */ \
mVU_SUBq , mVU_MSUBq , mVU_SUBi , mVU_MSUBi, \
mVU_ADD , mVU_MADD , mVU_MUL , mVU_MAX, \
mVU_SUB , mVU_MSUB , mVU_OPMSUB , mVU_MINI, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, /* 0x30 */ \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVU_UPPER_FD_00, mVU_UPPER_FD_01, mVU_UPPER_FD_10, mVU_UPPER_FD_11, \
void (*mVU_UPPER_OPCODE [64])(mP) = {
mVU_ADDx , mVU_ADDy , mVU_ADDz , mVU_ADDw,
mVU_SUBx , mVU_SUBy , mVU_SUBz , mVU_SUBw,
mVU_MADDx , mVU_MADDy , mVU_MADDz , mVU_MADDw,
mVU_MSUBx , mVU_MSUBy , mVU_MSUBz , mVU_MSUBw,
mVU_MAXx , mVU_MAXy , mVU_MAXz , mVU_MAXw,
mVU_MINIx , mVU_MINIy , mVU_MINIz , mVU_MINIw,
mVU_MULx , mVU_MULy , mVU_MULz , mVU_MULw,
mVU_MULq , mVU_MAXi , mVU_MULi , mVU_MINIi,
mVU_ADDq , mVU_MADDq , mVU_ADDi , mVU_MADDi,
mVU_SUBq , mVU_MSUBq , mVU_SUBi , mVU_MSUBi,
mVU_ADD , mVU_MADD , mVU_MUL , mVU_MAX,
mVU_SUB , mVU_MSUB , mVU_OPMSUB , mVU_MINI,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVU_UPPER_FD_00, mVU_UPPER_FD_01, mVU_UPPER_FD_10, mVU_UPPER_FD_11,
};
#define microVU_UPPER_FD_00_TABLE(x) void (*mVU_UPPER_FD_00_TABLE##x [32])(mP) = { \
mVU_ADDAx , mVU_SUBAx , mVU_MADDAx , mVU_MSUBAx, \
mVU_ITOF0 , mVU_FTOI0 , mVU_MULAx , mVU_MULAq, \
mVU_ADDAq , mVU_SUBAq , mVU_ADDA , mVU_SUBA, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
void (*mVU_UPPER_FD_00_TABLE [32])(mP) = {
mVU_ADDAx , mVU_SUBAx , mVU_MADDAx , mVU_MSUBAx,
mVU_ITOF0 , mVU_FTOI0 , mVU_MULAx , mVU_MULAq,
mVU_ADDAq , mVU_SUBAq , mVU_ADDA , mVU_SUBA,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
};
#define microVU_UPPER_FD_01_TABLE(x) void (* mVU_UPPER_FD_01_TABLE##x [32])(mP) = { \
mVU_ADDAy , mVU_SUBAy , mVU_MADDAy , mVU_MSUBAy, \
mVU_ITOF4 , mVU_FTOI4 , mVU_MULAy , mVU_ABS, \
mVU_MADDAq , mVU_MSUBAq , mVU_MADDA , mVU_MSUBA, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
void (* mVU_UPPER_FD_01_TABLE [32])(mP) = {
mVU_ADDAy , mVU_SUBAy , mVU_MADDAy , mVU_MSUBAy,
mVU_ITOF4 , mVU_FTOI4 , mVU_MULAy , mVU_ABS,
mVU_MADDAq , mVU_MSUBAq , mVU_MADDA , mVU_MSUBA,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
};
#define microVU_UPPER_FD_10_TABLE(x) void (* mVU_UPPER_FD_10_TABLE##x [32])(mP) = { \
mVU_ADDAz , mVU_SUBAz , mVU_MADDAz , mVU_MSUBAz, \
mVU_ITOF12 , mVU_FTOI12 , mVU_MULAz , mVU_MULAi, \
mVU_ADDAi , mVU_SUBAi , mVU_MULA , mVU_OPMULA, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
void (* mVU_UPPER_FD_10_TABLE [32])(mP) = {
mVU_ADDAz , mVU_SUBAz , mVU_MADDAz , mVU_MSUBAz,
mVU_ITOF12 , mVU_FTOI12 , mVU_MULAz , mVU_MULAi,
mVU_ADDAi , mVU_SUBAi , mVU_MULA , mVU_OPMULA,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
};
#define microVU_UPPER_FD_11_TABLE(x) void (* mVU_UPPER_FD_11_TABLE##x [32])(mP) = { \
mVU_ADDAw , mVU_SUBAw , mVU_MADDAw , mVU_MSUBAw, \
mVU_ITOF15 , mVU_FTOI15 , mVU_MULAw , mVU_CLIP, \
mVU_MADDAi , mVU_MSUBAi , mVUunknown , mVU_NOP, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
mVUunknown , mVUunknown , mVUunknown , mVUunknown, \
void (* mVU_UPPER_FD_11_TABLE [32])(mP) = {
mVU_ADDAw , mVU_SUBAw , mVU_MADDAw , mVU_MSUBAw,
mVU_ITOF15 , mVU_FTOI15 , mVU_MULAw , mVU_CLIP,
mVU_MADDAi , mVU_MSUBAi , mVUunknown , mVU_NOP,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
mVUunknown , mVUunknown , mVUunknown , mVUunknown,
};
//------------------------------------------------------------------
//------------------------------------------------------------------
// Create Table Instances
//------------------------------------------------------------------
#define mVUcreateTable(x) \
microVU_LOWER_OPCODE(x) \
microVU_LowerOP_T3_00_OPCODE(x) \
microVU_LowerOP_T3_01_OPCODE(x) \
microVU_LowerOP_T3_10_OPCODE(x) \
microVU_LowerOP_T3_11_OPCODE(x) \
microVU_LowerOP_OPCODE(x) \
microVU_UPPER_OPCODE(x) \
microVU_UPPER_FD_00_TABLE(x) \
microVU_UPPER_FD_01_TABLE(x) \
microVU_UPPER_FD_10_TABLE(x) \
microVU_UPPER_FD_11_TABLE(x)
mVUcreateTable(0)
//------------------------------------------------------------------
// Table Functions
//------------------------------------------------------------------
#define doTableStuff(tableName, args) { \
tableName##0[ args ](mX); \
}
mVUop(mVU_UPPER_FD_00) { doTableStuff(mVU_UPPER_FD_00_TABLE, ((mVUgetCode >> 6) & 0x1f)); }
mVUop(mVU_UPPER_FD_01) { doTableStuff(mVU_UPPER_FD_01_TABLE, ((mVUgetCode >> 6) & 0x1f)); }
mVUop(mVU_UPPER_FD_10) { doTableStuff(mVU_UPPER_FD_10_TABLE, ((mVUgetCode >> 6) & 0x1f)); }
mVUop(mVU_UPPER_FD_11) { doTableStuff(mVU_UPPER_FD_11_TABLE, ((mVUgetCode >> 6) & 0x1f)); }
mVUop(mVULowerOP) { doTableStuff(mVULowerOP_OPCODE, (mVUgetCode & 0x3f)); }
mVUop(mVULowerOP_T3_00) { doTableStuff(mVULowerOP_T3_00_OPCODE, ((mVUgetCode >> 6) & 0x1f)); }
mVUop(mVULowerOP_T3_01) { doTableStuff(mVULowerOP_T3_01_OPCODE, ((mVUgetCode >> 6) & 0x1f)); }
mVUop(mVULowerOP_T3_10) { doTableStuff(mVULowerOP_T3_10_OPCODE, ((mVUgetCode >> 6) & 0x1f)); }
mVUop(mVULowerOP_T3_11) { doTableStuff(mVULowerOP_T3_11_OPCODE, ((mVUgetCode >> 6) & 0x1f)); }
mVUop(mVUopU) { doTableStuff(mVU_UPPER_OPCODE, (mVUgetCode & 0x3f)); } // Gets Upper Opcode
mVUop(mVUopL) { doTableStuff(mVULOWER_OPCODE, (mVUgetCode >> 25)); } // Gets Lower Opcode
mVUop(mVUunknown) {
pass2 { Console::Error("microVU%d: Unknown Micro VU opcode called (%x) [%04x]\n", params getIndex, mVUgetCode, xPC); }
pass3 { mVUlog("Unknown", mVUgetCode); }
mVUop(mVU_UPPER_FD_00) { mVU_UPPER_FD_00_TABLE [((mVU->code >> 6) & 0x1f)](mX); }
mVUop(mVU_UPPER_FD_01) { mVU_UPPER_FD_01_TABLE [((mVU->code >> 6) & 0x1f)](mX); }
mVUop(mVU_UPPER_FD_10) { mVU_UPPER_FD_10_TABLE [((mVU->code >> 6) & 0x1f)](mX); }
mVUop(mVU_UPPER_FD_11) { mVU_UPPER_FD_11_TABLE [((mVU->code >> 6) & 0x1f)](mX); }
mVUop(mVULowerOP) { mVULowerOP_OPCODE [ (mVU->code & 0x3f) ](mX); }
mVUop(mVULowerOP_T3_00) { mVULowerOP_T3_00_OPCODE [((mVU->code >> 6) & 0x1f)](mX); }
mVUop(mVULowerOP_T3_01) { mVULowerOP_T3_01_OPCODE [((mVU->code >> 6) & 0x1f)](mX); }
mVUop(mVULowerOP_T3_10) { mVULowerOP_T3_10_OPCODE [((mVU->code >> 6) & 0x1f)](mX); }
mVUop(mVULowerOP_T3_11) { mVULowerOP_T3_11_OPCODE [((mVU->code >> 6) & 0x1f)](mX); }
mVUop(mVUopU) { mVU_UPPER_OPCODE [ (mVU->code & 0x3f) ](mX); } // Gets Upper Opcode
mVUop(mVUopL) { mVULOWER_OPCODE [ (mVU->code >> 25) ](mX); } // Gets Lower Opcode
mVUop(mVUunknown) {
pass2 { Console::Error("microVU%d: Unknown Micro VU opcode called (%x) [%04x]\n", params getIndex, mVU->code, xPC); }
pass3 { mVUlog("Unknown", mVU->code); }
}

View File

@ -33,7 +33,6 @@ microVUt(void) mVUupdateFlags(mV, int reg, int regT1 = -1, int regT2 = -1, bool
static const u16 flipMask[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
//SysPrintf("Status = %d; Mac = %d\n", sFLAG.doFlag, mFLAG.doFlag);
if (mVUsFlagHack) { sFLAG.doFlag = 0; }
if (!sFLAG.doFlag && !mFLAG.doFlag) { return; }
if ((mFLAG.doFlag && !(_XYZW_SS && modXYZW))) {
if (regT2 < 0) { regT2 = mVU->regAlloc->allocReg(); regT2b = 1; }
@ -173,6 +172,7 @@ void mVU_FMACa(microVU* mVU, int recPass, int opCase, int opType, bool isACC, co
mVU->regAlloc->clearNeeded(Ft);
}
pass3 { mVU_printOP(mVU, opCase, opName, isACC); }
pass4 { if ((opType != 3) && (opType != 4)) mVUregs.needExactMatch |= 8; }
}
// MADDA/MSUBA Opcodes
@ -211,6 +211,7 @@ void mVU_FMACb(microVU* mVU, int recPass, int opCase, int opType, const char* op
mVU->regAlloc->clearNeeded(Ft);
}
pass3 { mVU_printOP(mVU, opCase, opName, 1); }
pass4 { mVUregs.needExactMatch |= 8; }
}
// MADD Opcodes
@ -238,6 +239,7 @@ void mVU_FMACc(microVU* mVU, int recPass, int opCase, const char* opName) {
mVU->regAlloc->clearNeeded(ACC);
}
pass3 { mVU_printOP(mVU, opCase, opName, 0); }
pass4 { mVUregs.needExactMatch |= 8; }
}
// MSUB Opcodes
@ -260,6 +262,7 @@ void mVU_FMACd(microVU* mVU, int recPass, int opCase, const char* opName) {
mVU->regAlloc->clearNeeded(Fs);
}
pass3 { mVU_printOP(mVU, opCase, opName, 0); }
pass4 { mVUregs.needExactMatch |= 8; }
}
// ABS Opcode
@ -289,6 +292,7 @@ mVUop(mVU_OPMULA) {
mVU->regAlloc->clearNeeded(Fs);
}
pass3 { mVUlog("OPMULA"); mVUlogACC(); mVUlogFt(); }
pass4 { mVUregs.needExactMatch |= 8; }
}
// OPMSUB Opcode
@ -310,6 +314,7 @@ mVUop(mVU_OPMSUB) {
}
pass3 { mVUlog("OPMSUB"); mVUlogFd(); mVUlogFt(); }
pass4 { mVUregs.needExactMatch |= 8; }
}
// FTOI0/FTIO4/FTIO12/FTIO15 Opcodes

View File

@ -2749,7 +2749,7 @@ static void SuperVURecompile()
assert(pchild->blocks.size() == 0);
AND32ItoM((uptr)&VU0.VI[ REG_VPU_STAT ].UL, s_vu ? ~0x100 : ~0x001); // E flag
AND32ItoM((uptr)&VU->vifRegs->stat, ~0x4);
AND32ItoM((uptr)&VU->vifRegs->stat, ~VIF1_STAT_VEW);
MOV32ItoM((uptr)&VU->VI[REG_TPC], pchild->endpc);
JMP32((uptr)SuperVUEndProgram - ((uptr)x86Ptr + 5));
@ -3046,7 +3046,7 @@ void VuBaseBlock::Recompile()
_freeXMMregs();
_freeX86regs();
AND32ItoM((uptr)&VU0.VI[ REG_VPU_STAT ].UL, s_vu ? ~0x100 : ~0x001); // E flag
AND32ItoM((uptr)&VU->vifRegs->stat, ~0x4);
AND32ItoM((uptr)&VU->vifRegs->stat, ~VIF1_STAT_VEW);
if (!branch) MOV32ItoM((uptr)&VU->VI[REG_TPC], endpc);

View File

@ -30,10 +30,10 @@
enum GIF_FLG
{
GIF_FLG_PACKED = 0,
GIF_FLG_REGLIST = 1,
GIF_FLG_IMAGE = 2,
GIF_FLG_IMAGE2 = 3
GIF_FLG_PACKED = 0,
GIF_FLG_REGLIST = 1,
GIF_FLG_IMAGE = 2,
GIF_FLG_IMAGE2 = 3
};
enum GIF_PATH
@ -45,20 +45,20 @@ enum GIF_PATH
enum GIF_REG
{
GIF_REG_PRIM = 0x00,
GIF_REG_RGBA = 0x01,
GIF_REG_PRIM = 0x00,
GIF_REG_RGBA = 0x01,
GIF_REG_STQ = 0x02,
GIF_REG_UV = 0x03,
GIF_REG_XYZF2 = 0x04,
GIF_REG_XYZ2 = 0x05,
GIF_REG_TEX0_1 = 0x06,
GIF_REG_TEX0_2 = 0x07,
GIF_REG_UV = 0x03,
GIF_REG_XYZF2 = 0x04,
GIF_REG_XYZ2 = 0x05,
GIF_REG_TEX0_1 = 0x06,
GIF_REG_TEX0_2 = 0x07,
GIF_REG_CLAMP_1 = 0x08,
GIF_REG_CLAMP_2 = 0x09,
GIF_REG_FOG = 0x0a,
GIF_REG_XYZF3 = 0x0c,
GIF_REG_XYZ3 = 0x0d,
GIF_REG_A_D = 0x0e,
GIF_REG_XYZF3 = 0x0c,
GIF_REG_XYZ3 = 0x0d,
GIF_REG_A_D = 0x0e,
GIF_REG_NOP = 0x0f,
};

View File

@ -0,0 +1,94 @@
/* GSnull
* Copyright (C) 2004-2009 PCSX2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* GSnull
* Copyright (C) 2004-2009 PCSX2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
struct GIF_CTRL
{
u32 RST:1, // GIF reset
u32 reserved:2,
u32 PSE:1, // Temporary Transfer Stop
u32 reserved2:28
};
struct GIF_MODE
{
u32 M3R:1,
u32 reserved:1,
u32 IMT:1,
u32 reserved2:29
};
struct GIF_STAT
{
u32 M3R:1,
u32 M3P:1,
u32 IMT:1,
u32 PSE:1,
u32 reserved:1,
u32 IP3:1,
u32 P3Q:1,
u32 P2Q:1,
u32 P1Q:1,
u32 OPH:1,
u32 APATH:2,
u32 DIR:1,
u32 reserved2:11,
u32 FQC:5,
y32 reserved3:3
};
struct GIF_CNT
{
u32 LOOPCNT:15,
u32 reserved:1,
u32 REGCNT:4,
u32 VUADDR:10,
u32 rese3rved2:2
};
struct GIF_P3CNT
{
u32 PS3CNT:15,
u32 reserved:17
};
struct GIF_P3TAG
{
u32 LOOPCNT:15,
u32 EOP:1,
u32 reserved:16
};

View File

@ -1519,7 +1519,7 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM l
dm->Update(&info);
dm->PostRead();
// Workaround for things that return 0 on first poll and something else ever after.
Sleep(40);
Sleep(80);
dm->Update(&info);
dm->PostRead();
SetTimer(hWnd, 1, 30, 0);

View File

@ -0,0 +1,111 @@
#include "Global.h"
#include "HidDevice.h"
#include <setupapi.h>
// Tons of annoying junk to avoid the hid dependencies, so no one has to download the
// DDK to compile.
#define HIDP_STATUS_SUCCESS 0x110000
struct HIDD_ATTRIBUTES {
ULONG Size;
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
};
struct HIDP_PREPARSED_DATA;
typedef BOOLEAN (__stdcall *_HidD_GetAttributes) (HANDLE HidDeviceObject, HIDD_ATTRIBUTES *Attributes);
typedef void (__stdcall *_HidD_GetHidGuid) (GUID* HidGuid);
typedef BOOLEAN (__stdcall *_HidD_GetPreparsedData) (HANDLE HidDeviceObject, HIDP_PREPARSED_DATA **PreparsedData);
typedef NTSTATUS (__stdcall *_HidP_GetCaps) (HIDP_PREPARSED_DATA* PreparsedData, HIDP_CAPS *caps);
typedef BOOLEAN (__stdcall *_HidD_FreePreparsedData) (HIDP_PREPARSED_DATA *PreparsedData);
GUID GUID_DEVINTERFACE_HID;
_HidD_GetHidGuid pHidD_GetHidGuid;
_HidD_GetAttributes pHidD_GetAttributes;
_HidD_GetPreparsedData pHidD_GetPreparsedData;
_HidP_GetCaps pHidP_GetCaps;
_HidD_FreePreparsedData pHidD_FreePreparsedData;
HMODULE hModHid = 0;
int InitHid() {
if (hModHid) {
return 1;
}
hModHid = LoadLibraryA("hid.dll");
if (hModHid) {
if ((pHidD_GetHidGuid = (_HidD_GetHidGuid) GetProcAddress(hModHid, "HidD_GetHidGuid")) &&
(pHidD_GetAttributes = (_HidD_GetAttributes) GetProcAddress(hModHid, "HidD_GetAttributes")) &&
(pHidD_GetPreparsedData = (_HidD_GetPreparsedData) GetProcAddress(hModHid, "HidD_GetPreparsedData")) &&
(pHidP_GetCaps = (_HidP_GetCaps) GetProcAddress(hModHid, "HidP_GetCaps")) &&
(pHidD_FreePreparsedData = (_HidD_FreePreparsedData) GetProcAddress(hModHid, "HidD_FreePreparsedData"))) {
pHidD_GetHidGuid(&GUID_DEVINTERFACE_HID);
return 1;
}
UninitHid();
}
return 0;
}
int FindHids(HidDeviceInfo **foundDevs, int vid, int pid) {
if (!InitHid()) return 0;
int numFoundDevs = 0;
*foundDevs = 0;
HDEVINFO hdev = SetupDiGetClassDevsW(&GUID_DEVINTERFACE_HID, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hdev != INVALID_HANDLE_VALUE) {
SP_DEVICE_INTERFACE_DATA devInterfaceData;
devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
for (int i=0; SetupDiEnumDeviceInterfaces(hdev, 0, &GUID_DEVINTERFACE_HID, i, &devInterfaceData); i++) {
DWORD size = 0;
SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, 0, 0, &size, 0);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || !size) continue;
SP_DEVICE_INTERFACE_DETAIL_DATA *devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA *) malloc(size);
if (!devInterfaceDetails) continue;
devInterfaceDetails->cbSize = sizeof(*devInterfaceDetails);
SP_DEVINFO_DATA devInfoData;
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, devInterfaceDetails, size, &size, &devInfoData)) continue;
HANDLE hfile = CreateFileW(devInterfaceDetails->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (hfile != INVALID_HANDLE_VALUE) {
HIDD_ATTRIBUTES attributes;
attributes.Size = sizeof(attributes);
if (pHidD_GetAttributes(hfile, &attributes)) {
if (attributes.VendorID == vid && attributes.ProductID == pid) {
HIDP_PREPARSED_DATA *pData;
HIDP_CAPS caps;
if (pHidD_GetPreparsedData(hfile, &pData)) {
if (HIDP_STATUS_SUCCESS == pHidP_GetCaps(pData, &caps)) {
if (numFoundDevs % 32 == 0) {
*foundDevs = (HidDeviceInfo*) realloc(foundDevs, sizeof(HidDeviceInfo) * (32 + numFoundDevs));
}
HidDeviceInfo *dev = &foundDevs[0][numFoundDevs++];
dev->caps = caps;
dev->vid = attributes.VendorID;
dev->pid = attributes.ProductID;
dev->path = wcsdup(devInterfaceDetails->DevicePath);
}
pHidD_FreePreparsedData(pData);
}
}
}
CloseHandle(hfile);
}
free(devInterfaceDetails);
}
SetupDiDestroyDeviceInfoList(hdev);
}
return numFoundDevs;
}
void UninitHid() {
if (hModHid) {
FreeLibrary(hModHid);
hModHid = 0;
}
}

View File

@ -0,0 +1,39 @@
#ifndef HID_DEVICE_H
#define HID_DEVICE_H
int InitHid();
typedef USHORT USAGE;
struct HIDP_CAPS {
USAGE Usage;
USAGE UsagePage;
USHORT InputReportByteLength;
USHORT OutputReportByteLength;
USHORT FeatureReportByteLength;
USHORT Reserved[17];
USHORT NumberLinkCollectionNodes;
USHORT NumberInputButtonCaps;
USHORT NumberInputValueCaps;
USHORT NumberInputDataIndices;
USHORT NumberOutputButtonCaps;
USHORT NumberOutputValueCaps;
USHORT NumberOutputDataIndices;
USHORT NumberFeatureButtonCaps;
USHORT NumberFeatureValueCaps;
USHORT NumberFeatureDataIndices;
};
struct HidDeviceInfo {
HIDP_CAPS caps;
wchar_t *path;
unsigned short vid;
unsigned short pid;
};
void UninitHid();
#endif

View File

@ -379,12 +379,8 @@ Device *InputDeviceManager::GetActiveDevice(void *info, unsigned int *uid, int *
for (j=0; j<devices[i]->numVirtualControls; j++) {
if (devices[i]->virtualControlState[j] == devices[i]->oldVirtualControlState[j]) continue;
if (devices[i]->virtualControls[j].uid & UID_POV) continue;
// Fix for two things:
// Releasing button used to click on bind button, and
// DirectInput not updating control state.
//Note: Handling latter not great for pressure sensitive button handling, but should still work...
// with some effort.
if (!(devices[i]->virtualControls[j].uid & (POV|RELAXIS))) {
// Fix for releasing button used to click on bind button
if (!((devices[i]->virtualControls[j].uid>>16) & (POV|RELAXIS|ABSAXIS))) {
if (abs(devices[i]->oldVirtualControlState[j]) > abs(devices[i]->virtualControlState[j])) {
devices[i]->oldVirtualControlState[j] = 0;
}
@ -398,11 +394,16 @@ Device *InputDeviceManager::GetActiveDevice(void *info, unsigned int *uid, int *
if (devices[i]->virtualControls[j].uid & UID_AXIS) {
if ((((devices[i]->virtualControls[j].uid>>16)&0xFF) != ABSAXIS)) continue;
// Very picky when binding entire axes. Prefer binding half-axes.
if (!((devices[i]->oldVirtualControlState[j] < FULLY_DOWN/16 && devices[i]->virtualControlState[j] > FULLY_DOWN/8) ||
(devices[i]->oldVirtualControlState[j] > 15*FULLY_DOWN/16 && devices[i]->virtualControlState[j] < 7*FULLY_DOWN/8)))
if (!((devices[i]->oldVirtualControlState[j] < FULLY_DOWN/32 && devices[i]->virtualControlState[j] > FULLY_DOWN/8) ||
(devices[i]->oldVirtualControlState[j] > 31*FULLY_DOWN/32 && devices[i]->virtualControlState[j] < 7*FULLY_DOWN/8))) {
continue;
}
devices[i]->virtualControls[j].uid = devices[i]->virtualControls[j].uid;
}
else if ((((devices[i]->virtualControls[j].uid>>16)&0xFF) == ABSAXIS)) {
if (devices[i]->oldVirtualControlState[j] > 15*FULLY_DOWN/16)
continue;
}
bestDiff = diff;
*uid = devices[i]->virtualControls[j].uid;
*index = j;

View File

@ -608,6 +608,14 @@
RelativePath=".\DirectInput.h"
>
</File>
<File
RelativePath=".\HidDevice.cpp"
>
</File>
<File
RelativePath=".\HidDevice.h"
>
</File>
<File
RelativePath=".\KeyboardHook.cpp"
>

View File

@ -65,7 +65,7 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Winmm.lib setupapi.lib ole32.lib advapi32.lib user32.lib kernel32.lib Comdlg32.lib dinput8.lib dxguid.lib comctl32.lib"
AdditionalDependencies="Setupapi.lib Winmm.lib ole32.lib advapi32.lib user32.lib kernel32.lib Comdlg32.lib dinput8.lib dxguid.lib comctl32.lib"
OutputFile="$(OutDir)\$(ProjectName)-dbg.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
@ -148,7 +148,7 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Winmm.lib ole32.lib advapi32.lib user32.lib kernel32.lib Comdlg32.lib dinput8.lib dxguid.lib comctl32.lib"
AdditionalDependencies="Setupapi.lib Winmm.lib ole32.lib advapi32.lib user32.lib kernel32.lib Comdlg32.lib dinput8.lib dxguid.lib comctl32.lib"
LinkIncremental="1"
SuppressStartupBanner="true"
ModuleDefinitionFile=".\LilyPad.def"
@ -542,6 +542,14 @@
RelativePath=".\DirectInput.h"
>
</File>
<File
RelativePath=".\HidDevice.cpp"
>
</File>
<File
RelativePath=".\HidDevice.h"
>
</File>
<File
RelativePath=".\KeyboardHook.cpp"
>