diff --git a/common/include/Pcsx2Config.h b/common/include/Pcsx2Config.h index 94cdec2542..f5337a7421 100644 --- a/common/include/Pcsx2Config.h +++ b/common/include/Pcsx2Config.h @@ -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)) diff --git a/pcsx2/CDVD/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp index d6770cc988..074195187a 100644 --- a/pcsx2/CDVD/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -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); diff --git a/pcsx2/CDVD/CDVD.h b/pcsx2/CDVD/CDVD.h index f7c890af2e..fee4fd0cfa 100644 --- a/pcsx2/CDVD/CDVD.h +++ b/pcsx2/CDVD/CDVD.h @@ -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 ); diff --git a/pcsx2/CDVD/CDVDaccess.cpp b/pcsx2/CDVD/CDVDaccess.cpp index 2e0e7cb369..12f33241a8 100644 --- a/pcsx2/CDVD/CDVDaccess.cpp +++ b/pcsx2/CDVD/CDVDaccess.cpp @@ -25,6 +25,7 @@ #endif #include +#include #include #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) diff --git a/pcsx2/CDVD/CDVDaccess.h b/pcsx2/CDVD/CDVDaccess.h index 4af11f74dd..36bb633ec3 100644 --- a/pcsx2/CDVD/CDVDaccess.h +++ b/pcsx2/CDVD/CDVDaccess.h @@ -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__ */ diff --git a/pcsx2/CDVD/CDVDisoReader.cpp b/pcsx2/CDVD/CDVDisoReader.cpp index c4a9e52d80..874e4c98e4 100644 --- a/pcsx2/CDVD/CDVDisoReader.cpp +++ b/pcsx2/CDVD/CDVDisoReader.cpp @@ -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) { diff --git a/pcsx2/CDVD/CDVDisoReader.h b/pcsx2/CDVD/CDVDisoReader.h index 8e988acee9..65b75abc5a 100644 --- a/pcsx2/CDVD/CDVDisoReader.h +++ b/pcsx2/CDVD/CDVDisoReader.h @@ -29,7 +29,4 @@ #include "IsoFStools.h" #include "IsoFileFormats.h" -extern char isoFileName[g_MaxPath]; -extern isoFile *iso; - #endif \ No newline at end of file diff --git a/pcsx2/Common.h b/pcsx2/Common.h index 1995b786c4..0b6b44dc58 100644 --- a/pcsx2/Common.h +++ b/pcsx2/Common.h @@ -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" diff --git a/pcsx2/FiFo.cpp b/pcsx2/FiFo.cpp index c9a530623d..7f52477d0d 100644 --- a/pcsx2/FiFo.cpp +++ b/pcsx2/FiFo.cpp @@ -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; diff --git a/pcsx2/GS.h b/pcsx2/GS.h index 02b539758e..aeed1b7d2c 100644 --- a/pcsx2/GS.h +++ b/pcsx2/GS.h @@ -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 diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index c3eeb0d10a..ed8f1c1abd 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -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); diff --git a/pcsx2/Gif.h b/pcsx2/Gif.h new file mode 100644 index 0000000000..33c73f7fee --- /dev/null +++ b/pcsx2/Gif.h @@ -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 \ No newline at end of file diff --git a/pcsx2/HostGui.h b/pcsx2/HostGui.h index 53f6b8a7e8..7005389755 100644 --- a/pcsx2/HostGui.h +++ b/pcsx2/HostGui.h @@ -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; diff --git a/pcsx2/Hw.h b/pcsx2/Hw.h index c0c093574b..ae8d43038b 100644 --- a/pcsx2/Hw.h +++ b/pcsx2/Hw.h @@ -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 diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index 17924fdada..9ba5dc4c12 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -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); diff --git a/pcsx2/IPU/IPU.cpp b/pcsx2/IPU/IPU.cpp index d5ca82144b..852ea8c863 100644 --- a/pcsx2/IPU/IPU.cpp +++ b/pcsx2/IPU/IPU.cpp @@ -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"); diff --git a/pcsx2/IPU/IPU.h b/pcsx2/IPU/IPU.h index 536540aae5..bfc9d3c2f1 100644 --- a/pcsx2/IPU/IPU.h +++ b/pcsx2/IPU/IPU.h @@ -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 diff --git a/pcsx2/IPU/mpeg2lib/Mpeg.cpp b/pcsx2/IPU/mpeg2lib/Mpeg.cpp index 6b5fcefd6e..8a5254b150 100644 --- a/pcsx2/IPU/mpeg2lib/Mpeg.cpp +++ b/pcsx2/IPU/mpeg2lib/Mpeg.cpp @@ -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; diff --git a/pcsx2/IPU/mpeg2lib/Mpeg.h b/pcsx2/IPU/mpeg2lib/Mpeg.h index e31e2b6769..3168853ad5 100644 --- a/pcsx2/IPU/mpeg2lib/Mpeg.h +++ b/pcsx2/IPU/mpeg2lib/Mpeg.h @@ -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); diff --git a/pcsx2/Misc.cpp b/pcsx2/Misc.cpp index ce0b735f9c..1b64c31e0e 100644 --- a/pcsx2/Misc.cpp +++ b/pcsx2/Misc.cpp @@ -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; diff --git a/pcsx2/Plugins.cpp b/pcsx2/Plugins.cpp index 423ef63976..481f45f7b4 100644 --- a/pcsx2/Plugins.cpp +++ b/pcsx2/Plugins.cpp @@ -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 diff --git a/pcsx2/R3000A.cpp b/pcsx2/R3000A.cpp index ec25a6f0d8..5f62935a17 100644 --- a/pcsx2/R3000A.cpp +++ b/pcsx2/R3000A.cpp @@ -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*"); -*/ -} diff --git a/pcsx2/R3000A.h b/pcsx2/R3000A.h index 49aee70828..93f64074e7 100644 --- a/pcsx2/R3000A.h +++ b/pcsx2/R3000A.h @@ -201,7 +201,6 @@ void psxReset(); void psxShutdown(); void psxException(u32 code, u32 step); extern void psxBranchTest(); -void psxExecuteBios(); void psxMemReset(); // Subsets diff --git a/pcsx2/R5900.cpp b/pcsx2/R5900.cpp index 1c3afe1b6d..51d350d265 100644 --- a/pcsx2/R5900.cpp +++ b/pcsx2/R5900.cpp @@ -29,6 +29,7 @@ #include "COP0.h" #include "GS.h" +#include "Gif.h" #include "IPU/IPU.h" #include "Vif.h" #include "VifDma.h" diff --git a/pcsx2/Tags.h b/pcsx2/Tags.h index 1f6e46c7db..56923d7aa8 100644 --- a/pcsx2/Tags.h +++ b/pcsx2/Tags.h @@ -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); } } diff --git a/pcsx2/VU0.cpp b/pcsx2/VU0.cpp index 823d4827a2..8659d12603 100644 --- a/pcsx2/VU0.cpp +++ b/pcsx2/VU0.cpp @@ -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; diff --git a/pcsx2/VU0micro.cpp b/pcsx2/VU0micro.cpp index 1502e2cdb2..967fb6ad51 100644 --- a/pcsx2/VU0micro.cpp +++ b/pcsx2/VU0micro.cpp @@ -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() { diff --git a/pcsx2/VU0microInterp.cpp b/pcsx2/VU0microInterp.cpp index da5c9b8bcd..c67297a85b 100644 --- a/pcsx2/VU0microInterp.cpp +++ b/pcsx2/VU0microInterp.cpp @@ -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; } } } diff --git a/pcsx2/VU1micro.cpp b/pcsx2/VU1micro.cpp index 0f8098947c..001b7115c1 100644 --- a/pcsx2/VU1micro.cpp +++ b/pcsx2/VU1micro.cpp @@ -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); diff --git a/pcsx2/VU1microInterp.cpp b/pcsx2/VU1microInterp.cpp index 8ec7bc3cca..7a56f46b87 100644 --- a/pcsx2/VU1microInterp.cpp +++ b/pcsx2/VU1microInterp.cpp @@ -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; } } } diff --git a/pcsx2/VUmicroMem.cpp b/pcsx2/VUmicroMem.cpp index 907d15a8ae..da7e353d92 100644 --- a/pcsx2/VUmicroMem.cpp +++ b/pcsx2/VUmicroMem.cpp @@ -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() diff --git a/pcsx2/Vif.cpp b/pcsx2/Vif.cpp index 99409a647f..9989358acb 100644 --- a/pcsx2/Vif.cpp +++ b/pcsx2/Vif.cpp @@ -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 } diff --git a/pcsx2/Vif.h b/pcsx2/Vif.h index 64335c4dde..5e06ef38af 100644 --- a/pcsx2/Vif.h +++ b/pcsx2/Vif.h @@ -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. diff --git a/pcsx2/VifDma.cpp b/pcsx2/VifDma.cpp index 56a9cc1275..274eb5ffa7 100644 --- a/pcsx2/VifDma.cpp +++ b/pcsx2/VifDma.cpp @@ -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() diff --git a/pcsx2/gui/Dialogs/ConfigurationDialog.cpp b/pcsx2/gui/Dialogs/ConfigurationDialog.cpp index 6b291cfc08..22f8f187aa 100644 --- a/pcsx2/gui/Dialogs/ConfigurationDialog.cpp +++ b/pcsx2/gui/Dialogs/ConfigurationDialog.cpp @@ -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(); } diff --git a/pcsx2/gui/Dialogs/ConfigurationDialog.h b/pcsx2/gui/Dialogs/ConfigurationDialog.h index 793c6dc1b1..e119046fb4 100644 --- a/pcsx2/gui/Dialogs/ConfigurationDialog.h +++ b/pcsx2/gui/Dialogs/ConfigurationDialog.h @@ -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(); } } }; diff --git a/pcsx2/gui/Dialogs/FirstTimeWizard.cpp b/pcsx2/gui/Dialogs/FirstTimeWizard.cpp index b4ca51f30e..3a75d6565f 100644 --- a/pcsx2/gui/Dialogs/FirstTimeWizard.cpp +++ b/pcsx2/gui/Dialogs/FirstTimeWizard.cpp @@ -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 ) ); diff --git a/pcsx2/gui/Dialogs/ModalPopups.h b/pcsx2/gui/Dialogs/ModalPopups.h index 79173807fb..e7b67c0311 100644 --- a/pcsx2/gui/Dialogs/ModalPopups.h +++ b/pcsx2/gui/Dialogs/ModalPopups.h @@ -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 ); diff --git a/pcsx2/gui/Panels/PluginSelectorPanel.cpp b/pcsx2/gui/Panels/PluginSelectorPanel.cpp index e4dcb78236..d52b20a819 100644 --- a/pcsx2/gui/Panels/PluginSelectorPanel.cpp +++ b/pcsx2/gui/Panels/PluginSelectorPanel.cpp @@ -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(); diff --git a/pcsx2/gui/main.cpp b/pcsx2/gui/main.cpp index fde0e8974f..b785ca4e99 100644 --- a/pcsx2/gui/main.cpp +++ b/pcsx2/gui/main.cpp @@ -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(); + } } } diff --git a/pcsx2/windows/VCprojects/pcsx2.vcxproj b/pcsx2/windows/VCprojects/pcsx2.vcxproj index 54cc63b2d6..324794735b 100644 --- a/pcsx2/windows/VCprojects/pcsx2.vcxproj +++ b/pcsx2/windows/VCprojects/pcsx2.vcxproj @@ -593,6 +593,7 @@ + diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index 5a77b743ab..8d1b5904d0 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -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" > + + diff --git a/pcsx2/windows/WinSysExec.cpp b/pcsx2/windows/WinSysExec.cpp index b21b625a7a..6892fe4219 100644 --- a/pcsx2/windows/WinSysExec.cpp +++ b/pcsx2/windows/WinSysExec.cpp @@ -22,6 +22,7 @@ #include #include "Common.h" +#include "cdvd/CDVD.h" int SysPageFaultExceptionFilter( EXCEPTION_POINTERS* eps ) { diff --git a/pcsx2/x86/iCOP2.cpp b/pcsx2/x86/iCOP2.cpp index dabe4440f6..654f315c15 100644 --- a/pcsx2/x86/iCOP2.cpp +++ b/pcsx2/x86/iCOP2.cpp @@ -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 \ No newline at end of file diff --git a/pcsx2/x86/iVU1micro.cpp b/pcsx2/x86/iVU1micro.cpp index 16f2bdf99d..ad70d406f1 100644 --- a/pcsx2/x86/iVU1micro.cpp +++ b/pcsx2/x86/iVU1micro.cpp @@ -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); } diff --git a/pcsx2/x86/microVU.h b/pcsx2/x86/microVU.h index 39f25c7574..f9efc5d4a5 100644 --- a/pcsx2/x86/microVU.h +++ b/pcsx2/x86/microVU.h @@ -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" diff --git a/pcsx2/x86/microVU_Branch.inl b/pcsx2/x86/microVU_Branch.inl index efd66e0265..3e574abd64 100644 --- a/pcsx2/x86/microVU_Branch.inl +++ b/pcsx2/x86/microVU_Branch.inl @@ -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 diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index 9113ffbf9d..cec2b5b6e4 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -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); } } diff --git a/pcsx2/x86/microVU_Execute.inl b/pcsx2/x86/microVU_Execute.inl index 0031992557..7d057d752a 100644 --- a/pcsx2/x86/microVU_Execute.inl +++ b/pcsx2/x86/microVU_Execute.inl @@ -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(); + // } + // } + //} } //------------------------------------------------------------------ diff --git a/pcsx2/x86/microVU_Flags.inl b/pcsx2/x86/microVU_Flags.inl index ddc58d5fe0..dd9ccfcb68 100644 --- a/pcsx2/x86/microVU_Flags.inl +++ b/pcsx2/x86/microVU_Flags.inl @@ -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; } diff --git a/pcsx2/x86/microVU_Lower.inl b/pcsx2/x86/microVU_Lower.inl index 113cccf5d1..0172d79f3e 100644 --- a/pcsx2/x86/microVU_Lower.inl +++ b/pcsx2/x86/microVU_Lower.inl @@ -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; } } //------------------------------------------------------------------ diff --git a/pcsx2/x86/microVU_Macro.inl b/pcsx2/x86/microVU_Macro.inl new file mode 100644 index 0000000000..962507f95a --- /dev/null +++ b/pcsx2/x86/microVU_Macro.inl @@ -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(µVU0.prog.IRinfo.info[0], 0, sizeof(microVU0.prog.IRinfo.info[0])); \ + iFlushCall(FLUSH_EVERYTHING); \ + microVU0.regAlloc->reset(); \ + /*mVU_##f(µVU0, 0);*/ \ + mVU_##f(µVU0, 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 diff --git a/pcsx2/x86/microVU_Misc.h b/pcsx2/x86/microVU_Misc.h index 5c4fc500a2..bba43ca2e8 100644 --- a/pcsx2/x86/microVU_Misc.h +++ b/pcsx2/x86/microVU_Misc.h @@ -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...) diff --git a/pcsx2/x86/microVU_Tables.inl b/pcsx2/x86/microVU_Tables.inl index de99062f58..486c7f3233 100644 --- a/pcsx2/x86/microVU_Tables.inl +++ b/pcsx2/x86/microVU_Tables.inl @@ -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); } } diff --git a/pcsx2/x86/microVU_Upper.inl b/pcsx2/x86/microVU_Upper.inl index 4029675009..36f5e5a755 100644 --- a/pcsx2/x86/microVU_Upper.inl +++ b/pcsx2/x86/microVU_Upper.inl @@ -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 diff --git a/pcsx2/x86/sVU_zerorec.cpp b/pcsx2/x86/sVU_zerorec.cpp index c6cd0f238e..927c4d6926 100644 --- a/pcsx2/x86/sVU_zerorec.cpp +++ b/pcsx2/x86/sVU_zerorec.cpp @@ -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); diff --git a/plugins/GSnull/GifTransfer.h b/plugins/GSnull/GifTransfer.h index 0e16a99d62..f9f7ba3f26 100644 --- a/plugins/GSnull/GifTransfer.h +++ b/plugins/GSnull/GifTransfer.h @@ -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, }; diff --git a/plugins/GSnull/Registers.h b/plugins/GSnull/Registers.h new file mode 100644 index 0000000000..fd77fbec25 --- /dev/null +++ b/plugins/GSnull/Registers.h @@ -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 + }; + + \ No newline at end of file diff --git a/plugins/LilyPad/Config.cpp b/plugins/LilyPad/Config.cpp index a5bb915bf2..2a8fe44f6b 100644 --- a/plugins/LilyPad/Config.cpp +++ b/plugins/LilyPad/Config.cpp @@ -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); diff --git a/plugins/LilyPad/HidDevice.cpp b/plugins/LilyPad/HidDevice.cpp new file mode 100644 index 0000000000..8a2d404c2e --- /dev/null +++ b/plugins/LilyPad/HidDevice.cpp @@ -0,0 +1,111 @@ +#include "Global.h" +#include "HidDevice.h" +#include + +// 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; + } +} diff --git a/plugins/LilyPad/HidDevice.h b/plugins/LilyPad/HidDevice.h new file mode 100644 index 0000000000..52f2565713 --- /dev/null +++ b/plugins/LilyPad/HidDevice.h @@ -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 diff --git a/plugins/LilyPad/InputManager.cpp b/plugins/LilyPad/InputManager.cpp index 1686838e0a..43b82668d5 100644 --- a/plugins/LilyPad/InputManager.cpp +++ b/plugins/LilyPad/InputManager.cpp @@ -379,12 +379,8 @@ Device *InputDeviceManager::GetActiveDevice(void *info, unsigned int *uid, int * for (j=0; jnumVirtualControls; 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; diff --git a/plugins/LilyPad/LilyPad_VC2005.vcproj b/plugins/LilyPad/LilyPad_VC2005.vcproj index 9bdaa75218..6d5c5809c3 100644 --- a/plugins/LilyPad/LilyPad_VC2005.vcproj +++ b/plugins/LilyPad/LilyPad_VC2005.vcproj @@ -608,6 +608,14 @@ RelativePath=".\DirectInput.h" > + + + + diff --git a/plugins/LilyPad/LilyPad_VC2008.vcproj b/plugins/LilyPad/LilyPad_VC2008.vcproj index 8e7255761f..c88205ade6 100644 --- a/plugins/LilyPad/LilyPad_VC2008.vcproj +++ b/plugins/LilyPad/LilyPad_VC2008.vcproj @@ -65,7 +65,7 @@ /> + + + +