From 915d0c6953cbc0dec42131367fe7708342a6606a Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Fri, 28 Aug 2009 14:57:51 +0000 Subject: [PATCH 01/14] More CDVD and cdvdiso bugfixes: cd-rom images should work now (ie, the old school non-DVD sort!), and improved the error and async read handling (possibly affects people running games from dvdrom) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1697 96395faa-99c1-11dd-bbfe-3dabce05a288 --- common/include/PS2Edefs.h | 15 ++++++++++++++- pcsx2/CDVD/CDVD.cpp | 17 +++++++++-------- pcsx2/CDVD/CdRom.cpp | 11 +++++++---- pcsx2/CDVD/IsoFileFormats.cpp | 9 +++++++-- pcsx2/CDVD/IsoFileFormats.h | 14 +++++++------- pcsx2/Plugins.cpp | 12 +++--------- 6 files changed, 47 insertions(+), 31 deletions(-) diff --git a/common/include/PS2Edefs.h b/common/include/PS2Edefs.h index 70cc460169..aa42ef0c32 100644 --- a/common/include/PS2Edefs.h +++ b/common/include/PS2Edefs.h @@ -617,8 +617,22 @@ typedef s32 (CALLBACK* _CDVDinit)(); typedef s32 (CALLBACK* _CDVDopen)(const char* pTitleFilename); typedef void (CALLBACK* _CDVDclose)(); typedef void (CALLBACK* _CDVDshutdown)(); + +// Initiates an asynchronous track read operation. +// Returns -1 on error (invalid track) +// Returns 0 on success. typedef s32 (CALLBACK* _CDVDreadTrack)(u32 lsn, int mode); + +// *OBSOLETE* returns a pointer to the buffer, or NULL if data hasn't finished +// loading yet. typedef u8* (CALLBACK* _CDVDgetBuffer)(); + +// Copies loaded data to the target buffer. +// Returns -2 if the asynchronous read is still pending. +// Returns 0 on success. +// This function is not allowed to return -1 (reserved for use by readTrack) +typedef s32 (CALLBACK* _CDVDgetBuffer2)(u8* buffer); + typedef s32 (CALLBACK* _CDVDreadSubQ)(u32 lsn, cdvdSubQ* subq); typedef s32 (CALLBACK* _CDVDgetTN)(cdvdTN *Buffer); typedef s32 (CALLBACK* _CDVDgetTD)(u8 Track, cdvdTD *Buffer); @@ -628,7 +642,6 @@ typedef s32 (CALLBACK* _CDVDgetTrayStatus)(); typedef s32 (CALLBACK* _CDVDctrlTrayOpen)(); typedef s32 (CALLBACK* _CDVDctrlTrayClose)(); typedef s32 (CALLBACK* _CDVDreadSector)(u8* buffer, u32 lsn, int mode); -typedef s32 (CALLBACK* _CDVDgetBuffer2)(u8* buffer); typedef s32 (CALLBACK* _CDVDgetDualInfo)(s32* dualType, u32* _layer1start); typedef void (CALLBACK* _CDVDconfigure)(); diff --git a/pcsx2/CDVD/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp index 419f0a84ce..dff2701f3e 100644 --- a/pcsx2/CDVD/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -714,11 +714,9 @@ __forceinline void cdvdReadInterrupt() } else { - if (cdvd.RErr == 0) - { - cdr.RErr = DoCDVDgetBuffer(cdr.Transfer); - } - else if (cdr.RErr == -1) + // Read Error -1 is only returned by readTrack, so handle it first here. + // If readTrack failed it means we don't have any valid data to fetch. + if (cdvd.RErr == -1) { cdvd.RetryCntP++; Console::Error("CDVD READ ERROR, sector=%d", params cdvd.Sector); @@ -730,10 +728,13 @@ __forceinline void cdvdReadInterrupt() return; } } - else if(cdr.RErr == -2) + + cdvd.RErr = DoCDVDgetBuffer(cdr.Transfer); + + if(cdvd.RErr == -2) { // not finished yet ... give it a bit more time - CDVDREAD_INT(cdvd.ReadTime); + CDVDREAD_INT(cdvd.ReadTime/4); return; } cdvd.Reading = false; @@ -764,7 +765,7 @@ __forceinline void cdvdReadInterrupt() cdvd.RetryCntP = 0; cdvd.Reading = 1; - cdr.RErr = DoCDVDreadTrack(cdvd.Sector, cdvd.ReadMode); + cdvd.RErr = DoCDVDreadTrack(cdvd.Sector, cdvd.ReadMode); CDVDREAD_INT(cdvd.ReadTime); return; diff --git a/pcsx2/CDVD/CdRom.cpp b/pcsx2/CDVD/CdRom.cpp index d5c742b3ae..7cecf04277 100644 --- a/pcsx2/CDVD/CdRom.cpp +++ b/pcsx2/CDVD/CdRom.cpp @@ -497,19 +497,22 @@ void cdrReadInterrupt() { cdr.StatP|= 0x22; cdr.Result[0] = cdr.StatP; - Console::Status("Reading From CDR"); - cdr.RErr = DoCDVDgetBuffer(cdr.Transfer); + // Read Error -1 is only returned by readTrack, so handle it first here. + // If readTrack failed it means we don't have any valid data to fetch. if (cdr.RErr == -1) { CDR_LOG(" err\n"); - memzero_ptr<2340>(cdr.Transfer); + memzero_obj(cdr.Transfer); cdr.Stat = DiskError; cdr.Result[0]|= 0x01; ReadTrack(); CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); return; } - else if(cdr.RErr == -2) + + cdr.RErr = DoCDVDgetBuffer(cdr.Transfer); + + if(cdr.RErr == -2) { // async mode is not finished yet ... give it a bit more time CDREAD_INT(cdReadTime / 4); diff --git a/pcsx2/CDVD/IsoFileFormats.cpp b/pcsx2/CDVD/IsoFileFormats.cpp index abfb9277e1..fb0f8a4d67 100644 --- a/pcsx2/CDVD/IsoFileFormats.cpp +++ b/pcsx2/CDVD/IsoFileFormats.cpp @@ -362,8 +362,13 @@ int isoReadBlock(isoFile *iso, u8 *dst, int lsn) if (iso->type == ISOTYPE_CD) { - LSNtoMSF(dst + 12, lsn); - dst[15] = 2; + // This is weird voodoo mess that does some kind of time adjustment on the + // block headers of CD-Rom images. hackfixed it to work with 24 byte block + // offsets... no idea if it'll work with others. + DevAssert( iso->blockofs == 24, "Undocumented CD-Rom checkpoint." ); + + LSNtoMSF(dst - iso->blockofs + 12, lsn); + dst[15-iso->blockofs] = 2; } return 0; diff --git a/pcsx2/CDVD/IsoFileFormats.h b/pcsx2/CDVD/IsoFileFormats.h index f7e6f95af2..0645e7d36f 100644 --- a/pcsx2/CDVD/IsoFileFormats.h +++ b/pcsx2/CDVD/IsoFileFormats.h @@ -33,10 +33,10 @@ enum isoType enum isoFlags { - ISOFLAGS_Z = 0x0001, + ISOFLAGS_Z = 0x0001, ISOFLAGS_Z2 = 0x0002, ISOFLAGS_BLOCKDUMP = 0x0004, - ISOFLAGS_MULTI = 0x0008, + ISOFLAGS_MULTI = 0x0008, ISOFLAGS_BZ2 = 0x0010 }; @@ -46,17 +46,17 @@ enum isoFlags //#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ //#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ -typedef struct +struct _multih { u32 slsn; u32 elsn; void *handle; -} _multih; +}; -typedef struct +struct isoFile { char filename[256]; - u32 type; + isoType type; u32 flags; u32 offset; u32 blockofs; @@ -70,7 +70,7 @@ typedef struct _multih multih[8]; int buflsn; u8 *buffer; -} isoFile; +}; isoFile *isoOpen(const char *filename); diff --git a/pcsx2/Plugins.cpp b/pcsx2/Plugins.cpp index 534a3e8f28..a523321f07 100644 --- a/pcsx2/Plugins.cpp +++ b/pcsx2/Plugins.cpp @@ -488,18 +488,12 @@ static void CALLBACK CDVD_newDiskCB(void (*callback)()) {} extern int lastReadSize; static s32 CALLBACK CDVD_getBuffer2(u8* buffer) { - int ret; - // TEMP: until I fix all the plugins to use this function style u8* pb = CDVD->getBuffer(); - if(pb != NULL) - { - memcpy(buffer,pb,lastReadSize); - ret = 0; - } - else ret = -2; + if(pb == NULL) return -2; - return ret; + memcpy_fast( buffer, pb, lastReadSize ); + return 0; } static s32 CALLBACK CDVD_readSector(u8* buffer, u32 lsn, int mode) From a159d82f8b2c66d99c9974583d6f71b341f70267 Mon Sep 17 00:00:00 2001 From: arcum42 Date: Fri, 28 Aug 2009 16:12:05 +0000 Subject: [PATCH 02/14] A quick fix to prevent creating dumps with the built in iso code from crashing. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1698 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/CDVD/CDVD.h | 2 +- pcsx2/CDVD/CDVDaccess.cpp | 2 +- pcsx2/CDVD/CDVDisoReader.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pcsx2/CDVD/CDVD.h b/pcsx2/CDVD/CDVD.h index 7af6a707a5..9771adfdf0 100644 --- a/pcsx2/CDVD/CDVD.h +++ b/pcsx2/CDVD/CDVD.h @@ -21,7 +21,7 @@ #include "IopCommon.h" #include "CDVD/CDVDaccess.h" -extern char isoFileName[]; +//extern char isoFileName[]; #define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ #define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ diff --git a/pcsx2/CDVD/CDVDaccess.cpp b/pcsx2/CDVD/CDVDaccess.cpp index 8bd9c0e57f..528fc2aad6 100644 --- a/pcsx2/CDVD/CDVDaccess.cpp +++ b/pcsx2/CDVD/CDVDaccess.cpp @@ -532,5 +532,5 @@ CDVD_API CDVDapi_NoDisc = NODISCgetBuffer2, NODISCgetDualInfo, - NULL + NODISCgetUniqueFilename }; diff --git a/pcsx2/CDVD/CDVDisoReader.cpp b/pcsx2/CDVD/CDVDisoReader.cpp index 5f2a0ba37c..273d7691e2 100644 --- a/pcsx2/CDVD/CDVDisoReader.cpp +++ b/pcsx2/CDVD/CDVDisoReader.cpp @@ -415,5 +415,5 @@ CDVD_API CDVDapi_Iso = ISOgetBuffer2, ISOgetDualInfo, - NULL + ISOgetUniqueFilename }; From 8f6ce7751cfa073b6dd0cc089ae25494c4f67f8a Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Fri, 28 Aug 2009 16:30:57 +0000 Subject: [PATCH 03/14] It fixes the compilation error in Windows, or it gets the hose again. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1699 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/CDVD/CDVDaccess.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcsx2/CDVD/CDVDaccess.cpp b/pcsx2/CDVD/CDVDaccess.cpp index 528fc2aad6..33024d0654 100644 --- a/pcsx2/CDVD/CDVDaccess.cpp +++ b/pcsx2/CDVD/CDVDaccess.cpp @@ -505,7 +505,7 @@ s32 CALLBACK NODISCgetDualInfo(s32* dualType, u32* _layer1start) return -1; } -const char* NODISCgetUniqueFilename() +string NODISCgetUniqueFilename() { DevAssert( false, "NODISC is an invalid CDVD object for block dumping.. >_<" ); return "epicfail"; From 8393f828dd73384fbaac6800aa0ad7bb61c0902c Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Fri, 28 Aug 2009 19:45:37 +0000 Subject: [PATCH 04/14] Fix a typo causing *.dump files not to appear in the "Run ISO" file browser. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1700 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/windows/WinMain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcsx2/windows/WinMain.cpp b/pcsx2/windows/WinMain.cpp index 682e7f6721..6eba335452 100644 --- a/pcsx2/windows/WinMain.cpp +++ b/pcsx2/windows/WinMain.cpp @@ -461,7 +461,7 @@ BOOL Open_Iso_File_Proc( std::string& outstr ) char szFileName[ g_MaxPath ]; char szFileTitle[ g_MaxPath ]; char * filter = - "All Supported (.iso .mdf .nrg .bin .img .dump)\0*.iso;*.mdf;*.nrg;*.bin;*.img,*.dump\0" + "All Supported (.iso .mdf .nrg .bin .img .dump)\0*.iso;*.mdf;*.nrg;*.bin;*.img;*.dump\0" "Disc Images (.iso .mdf .nrg .bin .img)\0*.iso;*.mdf;*.nrg;*.bin;*.img\0" "Blockdumps (.dump)\0*.dump\0" "All Files (*.*)\0*.*\0"; From b4b292d2194d3765ec468a6d32be70fcdc907268 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Fri, 28 Aug 2009 21:23:32 +0000 Subject: [PATCH 05/14] More CDVD fixes. I *think* this revision might provide some noticeable speedups when running games directly from cd drives. Also built-in CDVD blockdumps work now (DVD images only, legacy CdRom games still don't blockdump right unless you use the cdvdiso plugin). git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1701 96395faa-99c1-11dd-bbfe-3dabce05a288 --- common/include/PS2Edefs.h | 2 +- pcsx2/CDVD/CDVD.cpp | 45 ++++++++++++++--------- pcsx2/CDVD/CDVDaccess.cpp | 46 ++++++++++++------------ pcsx2/CDVD/CDVDisoReader.cpp | 17 +++++++-- pcsx2/CDVD/CdRom.cpp | 23 ++++++------ pcsx2/CDVD/IsoFileFormats.cpp | 67 +++++++++++++++++++---------------- pcsx2/CDVD/IsoFileFormats.h | 23 ++++++------ pcsx2/CDVD/IsoFileTools.cpp | 2 +- pcsx2/Plugins.cpp | 4 ++- 9 files changed, 130 insertions(+), 99 deletions(-) diff --git a/common/include/PS2Edefs.h b/common/include/PS2Edefs.h index aa42ef0c32..024cb82a4a 100644 --- a/common/include/PS2Edefs.h +++ b/common/include/PS2Edefs.h @@ -629,8 +629,8 @@ typedef u8* (CALLBACK* _CDVDgetBuffer)(); // Copies loaded data to the target buffer. // Returns -2 if the asynchronous read is still pending. +// Returns -1 if the asyncronous read failed. // Returns 0 on success. -// This function is not allowed to return -1 (reserved for use by readTrack) typedef s32 (CALLBACK* _CDVDgetBuffer2)(u8* buffer); typedef s32 (CALLBACK* _CDVDreadSubQ)(u32 lsn, cdvdSubQ* subq); diff --git a/pcsx2/CDVD/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp index dff2701f3e..5cf28db064 100644 --- a/pcsx2/CDVD/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -714,36 +714,49 @@ __forceinline void cdvdReadInterrupt() } else { - // Read Error -1 is only returned by readTrack, so handle it first here. - // If readTrack failed it means we don't have any valid data to fetch. - if (cdvd.RErr == -1) + if( cdvd.RErr == 0 ) { - cdvd.RetryCntP++; - Console::Error("CDVD READ ERROR, sector=%d", params cdvd.Sector); - - if (cdvd.RetryCntP <= cdvd.RetryCnt) + while( (cdvd.RErr = DoCDVDgetBuffer(cdr.Transfer)), cdvd.RErr == -2 ) { - cdvd.RErr = DoCDVDreadTrack(cdvd.Sector, cdvd.ReadMode); - CDVDREAD_INT(cdvd.ReadTime); - return; + // not finished yet ... block on the read until it finishes. + Threading::Sleep( 0 ); + Threading::SpinWait(); } } - cdvd.RErr = DoCDVDgetBuffer(cdr.Transfer); - - if(cdvd.RErr == -2) + if (cdvd.RErr == -1) { - // not finished yet ... give it a bit more time - CDVDREAD_INT(cdvd.ReadTime/4); + cdvd.RetryCntP++; + + if (cdvd.RetryCntP <= cdvd.RetryCnt) + { + CDVD_LOG( "CDVD read err, retrying... (attempt %d of %d)", cdvd.RetryCntP, cdvd.RetryCnt ); + cdvd.RErr = DoCDVDreadTrack(cdvd.Sector, cdvd.ReadMode); + CDVDREAD_INT(cdvd.ReadTime); + } + else + Console::Error("CDVD READ ERROR, sector = 0x%08x", params cdvd.Sector); + return; } + cdvd.Reading = false; + + // Any other value besides 0 should be considered invalid here (wtf is that wacky + // plugin trying to do?) + jASSUME( cdvd.RErr == 0 ); } if (cdvdReadSector() == -1) { + // This means that the BCR/DMA hasn't finished yet, and rather than fire off the + // sector-finished notice too early (which might overwrite game data) we delay a + // bit and try to read the sector again later. + // An arbitrary delay of some number of cycles probably makes more sense here, + // but for now it's based on the cdvd.ReadTime value. -- air + assert((int)cdvd.ReadTime > 0 ); - CDVDREAD_INT(cdvd.ReadTime); + CDVDREAD_INT(cdvd.ReadTime/4); return; } diff --git a/pcsx2/CDVD/CDVDaccess.cpp b/pcsx2/CDVD/CDVDaccess.cpp index 33024d0654..d140ee5a0d 100644 --- a/pcsx2/CDVD/CDVDaccess.cpp +++ b/pcsx2/CDVD/CDVDaccess.cpp @@ -44,6 +44,7 @@ static int diskTypeCached = -1; // used to bridge the gap between the old getBuffer api and the new getBuffer2 api. int lastReadSize; +int lastLSN; // needed for block dumping // Records last read block length for block dumping static int plsn = 0; @@ -56,11 +57,9 @@ static void CheckNullCDVD() DevAssert( CDVD != NULL, "Invalid CDVD object state (null pointer exception)" ); } -///////////////////////////////////////////////// -// +////////////////////////////////////////////////////////////////////////////////////////// // Disk Type detection stuff (from cdvdGigaherz) // - int CheckDiskTypeFS(int baseType) { int f; @@ -118,7 +117,7 @@ static int FindDiskType(int mType) } else if (mType < 0) { - static u8 bleh[2352]; + static u8 bleh[CD_FRAMESIZE_RAW]; cdvdTD td; CDVD->getTD(0,&td); @@ -322,26 +321,25 @@ s32 DoCDVDopen(const char* pTitleFilename) cdvdTD td; CDVD->getTD(0, &td); - int blockofs = 0, blocksize = 0, blocks = td.lsn; - - switch(cdtype) + blockDumpFile = isoCreate(Path::Combine( Path::GetWorkingDirectory(), fname ).c_str(), ISOFLAGS_BLOCKDUMP_V3); + if (blockDumpFile) { - case CDVD_TYPE_PS2DVD: - case CDVD_TYPE_DVDV: - case CDVD_TYPE_DETCTDVDS: - case CDVD_TYPE_DETCTDVDD: - blockofs = 24; - blocksize = 2048; - break; - - default: - blockofs = 0; - blocksize= 2352; - break; - } + int blockofs = 0, blocksize = CD_FRAMESIZE_RAW, blocks = td.lsn; - blockDumpFile = isoCreate(fname.c_str(), ISOFLAGS_BLOCKDUMP); - if (blockDumpFile) isoSetFormat(blockDumpFile, blockofs, blocksize, blocks); + // hack: Because of limitations of the current cdvd design, we can't query the blocksize + // of the underlying media. So lets make a best guess: + + switch(cdtype) + { + case CDVD_TYPE_PS2DVD: + case CDVD_TYPE_DVDV: + case CDVD_TYPE_DETCTDVDS: + case CDVD_TYPE_DETCTDVDD: + blocksize = 2048; + break; + } + isoSetFormat(blockDumpFile, blockofs, blocksize, blocks); + } } else { @@ -396,7 +394,7 @@ s32 DoCDVDreadTrack(u32 lsn, int mode) } //DevCon::Notice("CDVD readTrack(lsn=%d,mode=%d)",params lsn, lastReadSize); - + lastLSN = lsn; return CDVD->readTrack(lsn,mode); } @@ -407,7 +405,7 @@ s32 DoCDVDgetBuffer(u8* buffer) if (ret == 0 && blockDumpFile != NULL) { - isoWriteBlock(blockDumpFile, buffer, lastReadSize); + isoWriteBlock(blockDumpFile, buffer, lastLSN); } return ret; diff --git a/pcsx2/CDVD/CDVDisoReader.cpp b/pcsx2/CDVD/CDVDisoReader.cpp index 273d7691e2..0b19a2033c 100644 --- a/pcsx2/CDVD/CDVDisoReader.cpp +++ b/pcsx2/CDVD/CDVDisoReader.cpp @@ -295,9 +295,10 @@ s32 CALLBACK ISOreadSector(u8* tempbuffer, u32 lsn, int mode) return 0; } - isoReadBlock(iso, cdbuffer + iso->blockofs, lsn); + isoReadBlock(iso, cdbuffer, lsn); pbuffer = cdbuffer; + switch (mode) { case CDVD_MODE_2352: @@ -317,6 +318,11 @@ s32 CALLBACK ISOreadSector(u8* tempbuffer, u32 lsn, int mode) break; } + // version 3 blockdumps have no pbuffer header, so lets reset back to the + // original pointer. :) + if( iso->flags & ISOFLAGS_BLOCKDUMP_V3 ) + pbuffer = cdbuffer; + memcpy_fast(tempbuffer,pbuffer,psize); return 0; @@ -329,9 +335,9 @@ s32 CALLBACK ISOreadTrack(u32 lsn, int mode) if (_lsn < 0) lsn = iso->blocks + _lsn; if (lsn > iso->blocks) return -1; - isoReadBlock(iso, cdbuffer + iso->blockofs, lsn); - + isoReadBlock(iso, cdbuffer, lsn); pbuffer = cdbuffer; + switch (mode) { case CDVD_MODE_2352: @@ -351,6 +357,11 @@ s32 CALLBACK ISOreadTrack(u32 lsn, int mode) break; } + // version 3 blockdumps have no pbuffer header, so lets reset back to the + // original pointer. :) + if( iso->flags & ISOFLAGS_BLOCKDUMP_V3 ) + pbuffer = cdbuffer; + return 0; } diff --git a/pcsx2/CDVD/CdRom.cpp b/pcsx2/CDVD/CdRom.cpp index 7cecf04277..aec69a4c63 100644 --- a/pcsx2/CDVD/CdRom.cpp +++ b/pcsx2/CDVD/CdRom.cpp @@ -497,28 +497,27 @@ void cdrReadInterrupt() { cdr.StatP|= 0x22; cdr.Result[0] = cdr.StatP; - // Read Error -1 is only returned by readTrack, so handle it first here. - // If readTrack failed it means we don't have any valid data to fetch. + if( cdr.RErr == 0 ) + { + while( (cdr.RErr = DoCDVDgetBuffer(cdr.Transfer)), cdr.RErr == -2 ) + { + // not finished yet ... block on the read until it finishes. + Threading::Sleep( 0 ); + Threading::SpinWait(); + } + } + if (cdr.RErr == -1) { CDR_LOG(" err\n"); memzero_obj(cdr.Transfer); cdr.Stat = DiskError; - cdr.Result[0]|= 0x01; + cdr.Result[0] |= 0x01; ReadTrack(); CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); return; } - cdr.RErr = DoCDVDgetBuffer(cdr.Transfer); - - if(cdr.RErr == -2) - { - // async mode is not finished yet ... give it a bit more time - CDREAD_INT(cdReadTime / 4); - return; - } - cdr.Stat = DataReady; CDR_LOG(" %x:%x:%x", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); diff --git a/pcsx2/CDVD/IsoFileFormats.cpp b/pcsx2/CDVD/IsoFileFormats.cpp index fb0f8a4d67..80a29f6221 100644 --- a/pcsx2/CDVD/IsoFileFormats.cpp +++ b/pcsx2/CDVD/IsoFileFormats.cpp @@ -29,12 +29,12 @@ int detect(isoFile *iso) { u8 buf[2448]; - struct cdVolDesc *volDesc; + cdVolDesc *volDesc; - if (isoReadBlock(iso, buf + iso->blockofs, 16) == -1) return -1; - - volDesc = (struct cdVolDesc *)(buf + 24); + if (isoReadBlock(iso, buf, 16) == -1) return -1; + volDesc = (cdVolDesc *) (( iso->flags & ISOFLAGS_BLOCKDUMP_V3 ) ? buf : (buf + 24)); + if (strncmp((char*)volDesc->volID, "CD001", 5)) return 0; if (volDesc->rootToc.tocSize == 2048) @@ -87,7 +87,16 @@ int isoDetect(isoFile *iso) // based on florin's CDVDbin detection code :) if (strncmp(buf, "BDV2", 4) == 0) { - iso->flags = ISOFLAGS_BLOCKDUMP; + iso->flags = ISOFLAGS_BLOCKDUMP_V2; + _readfile(iso->handle, &iso->blocksize, 4); + _readfile(iso->handle, &iso->blocks, 4); + _readfile(iso->handle, &iso->blockofs, 4); + _isoReadDtable(iso); + return (detect(iso) == 1) ? 0 : -1; + } + else if (strncmp(buf, "BDV3", 4) == 0) + { + iso->flags = ISOFLAGS_BLOCKDUMP_V3; _readfile(iso->handle, &iso->blocksize, 4); _readfile(iso->handle, &iso->blocks, 4); _readfile(iso->handle, &iso->blockofs, 4); @@ -111,7 +120,7 @@ int isoDetect(isoFile *iso) // based on florin's CDVDbin detection code :) if (tryIsoType(iso, 2448, -8, 0)) return 0; // RAWQ 2448 iso->offset = 0; - iso->blocksize = 2352; + iso->blocksize = CD_FRAMESIZE_RAW; iso->blockofs = 0; iso->type = ISOTYPE_AUDIO; return 0; @@ -232,13 +241,19 @@ int isoSetFormat(isoFile *iso, int blockofs, int blocksize, int blocks) Console::WriteLn("blocksize = %d", params iso->blocksize); Console::WriteLn("blocks = %d", params iso->blocks); - if (iso->flags & ISOFLAGS_BLOCKDUMP) + if (iso->flags & ISOFLAGS_BLOCKDUMP_V2) { if (_writefile(iso->handle, "BDV2", 4) < 4) return -1; if (_writefile(iso->handle, &blocksize, 4) < 4) return -1; if (_writefile(iso->handle, &blocks, 4) < 4) return -1; if (_writefile(iso->handle, &blockofs, 4) < 4) return -1; } + else if (iso->flags & ISOFLAGS_BLOCKDUMP_V3) + { + if (_writefile(iso->handle, "BDV3", 4) < 4) return -1; + if (_writefile(iso->handle, &blocksize, 4) < 4) return -1; + if (_writefile(iso->handle, &blocks, 4) < 4) return -1; + } return 0; } @@ -275,7 +290,7 @@ int _isoReadBlock(isoFile *iso, u8 *dst, int lsn) memset(dst, 0, iso->blockofs); _seekfile(iso->handle, ofs, SEEK_SET); - ret = _readfile(iso->handle, dst, iso->blocksize); + ret = _readfile(iso->handle, dst + iso->blockofs, iso->blocksize); if (ret < iso->blocksize) { @@ -293,13 +308,13 @@ int _isoReadBlockD(isoFile *iso, u8 *dst, int lsn) // Console::WriteLn("_isoReadBlockD %d, blocksize=%d, blockofs=%d\n", params lsn, iso->blocksize, iso->blockofs); memset(dst, 0, iso->blockofs); - for (int i = 0; i < iso->dtablesize;i++) + for (int i = 0; i < iso->dtablesize; i++) { if (iso->dtable[i] != lsn) continue; _seekfile(iso->handle, 16 + i * (iso->blocksize + 4) + 4, SEEK_SET); - ret = _readfile(iso->handle, dst, iso->blocksize); - + ret = _readfile(iso->handle, dst + iso->blockofs, iso->blocksize); + if (ret < iso->blocksize) return -1; return 0; @@ -330,7 +345,7 @@ int _isoReadBlockM(isoFile *iso, u8 *dst, int lsn) memset(dst, 0, iso->blockofs); _seekfile(iso->multih[i].handle, ofs, SEEK_SET); - ret = _readfile(iso->multih[i].handle, dst, iso->blocksize); + ret = _readfile(iso->multih[i].handle, dst + iso->blockofs, iso->blocksize); if (ret < iso->blocksize) { @@ -351,7 +366,9 @@ int isoReadBlock(isoFile *iso, u8 *dst, int lsn) return -1; } - if (iso->flags & ISOFLAGS_BLOCKDUMP) + if (iso->flags & ISOFLAGS_BLOCKDUMP_V2) + ret = _isoReadBlockD(iso, dst, lsn); + else if( iso->flags & ISOFLAGS_BLOCKDUMP_V3 ) ret = _isoReadBlockD(iso, dst, lsn); else if (iso->flags & ISOFLAGS_MULTI) ret = _isoReadBlockM(iso, dst, lsn); @@ -362,13 +379,8 @@ int isoReadBlock(isoFile *iso, u8 *dst, int lsn) if (iso->type == ISOTYPE_CD) { - // This is weird voodoo mess that does some kind of time adjustment on the - // block headers of CD-Rom images. hackfixed it to work with 24 byte block - // offsets... no idea if it'll work with others. - DevAssert( iso->blockofs == 24, "Undocumented CD-Rom checkpoint." ); - - LSNtoMSF(dst - iso->blockofs + 12, lsn); - dst[15-iso->blockofs] = 2; + LSNtoMSF(dst + 12, lsn); + dst[15] = 2; } return 0; @@ -381,7 +393,7 @@ int _isoWriteBlock(isoFile *iso, u8 *src, int lsn) u64 ofs = (u64)lsn * iso->blocksize + iso->offset; _seekfile(iso->handle, ofs, SEEK_SET); - ret = _writefile(iso->handle, src, iso->blocksize); + ret = _writefile(iso->handle, src + iso->blockofs, iso->blocksize); if (ret < iso->blocksize) return -1; return 0; @@ -395,7 +407,7 @@ int _isoWriteBlockD(isoFile *iso, u8 *src, int lsn) ret = _writefile(iso->handle, &lsn, 4); if (ret < 4) return -1; - ret = _writefile(iso->handle, src, iso->blocksize); + ret = _writefile(iso->handle, src + iso->blockofs, iso->blocksize); // Console::WriteLn("_isoWriteBlock %d", params ret); @@ -406,15 +418,10 @@ int _isoWriteBlockD(isoFile *iso, u8 *src, int lsn) int isoWriteBlock(isoFile *iso, u8 *src, int lsn) { - int ret; - - if (iso->flags & ISOFLAGS_BLOCKDUMP) - ret = _isoWriteBlockD(iso, src, lsn); + if (iso->flags & ISOFLAGS_BLOCKDUMP_V3) + return _isoWriteBlockD(iso, src, lsn); else - ret = _isoWriteBlock(iso, src, lsn); - - if (ret == -1) return -1; - return 0; + return _isoWriteBlock(iso, src, lsn); } void isoClose(isoFile *iso) diff --git a/pcsx2/CDVD/IsoFileFormats.h b/pcsx2/CDVD/IsoFileFormats.h index 0645e7d36f..d57be8bbae 100644 --- a/pcsx2/CDVD/IsoFileFormats.h +++ b/pcsx2/CDVD/IsoFileFormats.h @@ -35,13 +35,14 @@ enum isoFlags { ISOFLAGS_Z = 0x0001, ISOFLAGS_Z2 = 0x0002, - ISOFLAGS_BLOCKDUMP = 0x0004, + ISOFLAGS_BLOCKDUMP_V2 = 0x0004, ISOFLAGS_MULTI = 0x0008, - ISOFLAGS_BZ2 = 0x0010 + ISOFLAGS_BZ2 = 0x0010, + ISOFLAGS_BLOCKDUMP_V3 = 0x0020 }; -#define CD_FRAMESIZE_RAW 2352 -#define DATA_SIZE (CD_FRAMESIZE_RAW-12) +static const int CD_FRAMESIZE_RAW = 2352; +static const int CD_DATA_SIZE = CD_FRAMESIZE_RAW - 12; //#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ //#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ @@ -73,12 +74,12 @@ struct isoFile }; -isoFile *isoOpen(const char *filename); -isoFile *isoCreate(const char *filename, int mode); -int isoSetFormat(isoFile *iso, int blockofs, int blocksize, int blocks); -int isoDetect(isoFile *iso); -int isoReadBlock(isoFile *iso, u8 *dst, int lsn); -int isoWriteBlock(isoFile *iso, u8 *src, int lsn); -void isoClose(isoFile *iso); +extern isoFile *isoOpen(const char *filename); +extern isoFile *isoCreate(const char *filename, int mode); +extern int isoSetFormat(isoFile *iso, int blockofs, int blocksize, int blocks); +extern int isoDetect(isoFile *iso); +extern int isoReadBlock(isoFile *iso, u8 *dst, int lsn); +extern int isoWriteBlock(isoFile *iso, u8 *src, int lsn); +extern void isoClose(isoFile *iso); #endif /* __LIBISO_H__ */ diff --git a/pcsx2/CDVD/IsoFileTools.cpp b/pcsx2/CDVD/IsoFileTools.cpp index c69f18b71b..f7f253e644 100644 --- a/pcsx2/CDVD/IsoFileTools.cpp +++ b/pcsx2/CDVD/IsoFileTools.cpp @@ -38,7 +38,7 @@ void *_openfile(const char *filename, int flags) handle = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); } - return handle == INVALID_HANDLE_VALUE ? NULL : handle; + return (handle == INVALID_HANDLE_VALUE) ? NULL : handle; } u64 _tellfile(void *handle) diff --git a/pcsx2/Plugins.cpp b/pcsx2/Plugins.cpp index a523321f07..ecfc55367b 100644 --- a/pcsx2/Plugins.cpp +++ b/pcsx2/Plugins.cpp @@ -485,7 +485,7 @@ static void CALLBACK CDVD_about() {} static s32 CALLBACK CDVD_test() { return 0; } static void CALLBACK CDVD_newDiskCB(void (*callback)()) {} -extern int lastReadSize; +extern int lastReadSize, lastLSN; static s32 CALLBACK CDVD_getBuffer2(u8* buffer) { // TEMP: until I fix all the plugins to use this function style @@ -517,6 +517,8 @@ static s32 CALLBACK CDVD_readSector(u8* buffer, u32 lsn, int mode) lastReadSize = 2048; break; } + + lastLSN = lsn; return CDVD->getBuffer2(buffer); } From c2eb41f637f6b32428e9108c23e01cc38937194c Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Fri, 28 Aug 2009 21:24:37 +0000 Subject: [PATCH 06/14] More Macro VU work git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1702 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/x86/microVU_Macro.inl | 327 ++++++++++++++++++------------------ 1 file changed, 161 insertions(+), 166 deletions(-) diff --git a/pcsx2/x86/microVU_Macro.inl b/pcsx2/x86/microVU_Macro.inl index 962507f95a..ee8f33bcfc 100644 --- a/pcsx2/x86/microVU_Macro.inl +++ b/pcsx2/x86/microVU_Macro.inl @@ -336,10 +336,167 @@ static void recQMTC2(s32 info) using namespace R5900::Dynarec; -void printCOP2(const char* text) { - Console::Status(text); +void setupMacroOp(int mode, const char* opName) { + DevCon::Status(opName); + 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(); + if (mode & 1) { // Q-Reg will be Read + SSE_MOVSS_M32_to_XMM(xmmPQ, (uptr)µVU0.regs->VI[REG_Q].UL); + } } +void endMacroOp(int mode) { + if (mode & 2) { // Q-Reg was Written To + SSE_MOVSS_XMM_to_M32((uptr)µVU0.regs->VI[REG_Q].UL, xmmPQ); + } + microVU0.regAlloc->flushAll(); +} + +#define REC_COP2_mVU0(f, opName, mode) \ + void recV##f(s32 info) { \ + setupMacroOp(mode, opName); \ + mVU_##f(µVU0, 1); \ + endMacroOp(mode); \ + } + +//------------------------------------------------------------------ +// Macro VU - Redirect Upper Instructions +//------------------------------------------------------------------ + +REC_COP2_mVU0(ABS, "ABS", 0); +REC_COP2_mVU0(ITOF0, "ITOF0", 0); +REC_COP2_mVU0(ITOF4, "ITOF4", 0); +REC_COP2_mVU0(ITOF12, "ITOF12", 0); +REC_COP2_mVU0(ITOF15, "ITOF15", 0); +REC_COP2_mVU0(FTOI0, "FTOI0", 0); +REC_COP2_mVU0(FTOI4, "FTOI4", 0); +REC_COP2_mVU0(FTOI12, "FTOI12", 0); +REC_COP2_mVU0(FTOI15, "FTOI15", 0); +REC_COP2_mVU0(ADD, "ADD", 0); +REC_COP2_mVU0(ADDi, "ADDi", 0); +REC_COP2_mVU0(ADDq, "ADDq", 1); +REC_COP2_mVU0(ADDx, "ADDx", 0); +REC_COP2_mVU0(ADDy, "ADDy", 0); +REC_COP2_mVU0(ADDz, "ADDz", 0); +REC_COP2_mVU0(ADDw, "ADDw", 0); +REC_COP2_mVU0(ADDA, "ADDA", 0); +REC_COP2_mVU0(ADDAi, "ADDAi", 0); +REC_COP2_mVU0(ADDAq, "ADDAq", 1); +REC_COP2_mVU0(ADDAx, "ADDAx", 0); +REC_COP2_mVU0(ADDAy, "ADDAy", 0); +REC_COP2_mVU0(ADDAz, "ADDAz", 0); +REC_COP2_mVU0(ADDAw, "ADDAw", 0); +REC_COP2_mVU0(SUB, "SUB", 0); +REC_COP2_mVU0(SUBi, "SUBi", 0); +REC_COP2_mVU0(SUBq, "SUBq", 1); +REC_COP2_mVU0(SUBx, "SUBx", 0); +REC_COP2_mVU0(SUBy, "SUBy", 0); +REC_COP2_mVU0(SUBz, "SUBz", 0); +REC_COP2_mVU0(SUBw, "SUBw", 0); +REC_COP2_mVU0(SUBA, "SUBA", 0); +REC_COP2_mVU0(SUBAi, "SUBAi", 0); +REC_COP2_mVU0(SUBAq, "SUBAq", 1); +REC_COP2_mVU0(SUBAx, "SUBAx", 0); +REC_COP2_mVU0(SUBAy, "SUBAy", 0); +REC_COP2_mVU0(SUBAz, "SUBAz", 0); +REC_COP2_mVU0(SUBAw, "SUBAw", 0); +REC_COP2_mVU0(MUL, "MUL", 0); +REC_COP2_mVU0(MULi, "MULi", 0); +REC_COP2_mVU0(MULq, "MULq", 1); +REC_COP2_mVU0(MULx, "MULx", 0); +REC_COP2_mVU0(MULy, "MULy", 0); +REC_COP2_mVU0(MULz, "MULz", 0); +REC_COP2_mVU0(MULw, "MULw", 0); +REC_COP2_mVU0(MULA, "MULA", 0); +REC_COP2_mVU0(MULAi, "MULAi", 0); +REC_COP2_mVU0(MULAq, "MULAq", 1); +REC_COP2_mVU0(MULAx, "MULAx", 0); +REC_COP2_mVU0(MULAy, "MULAy", 0); +REC_COP2_mVU0(MULAz, "MULAz", 0); +REC_COP2_mVU0(MULAw, "MULAw", 0); +REC_COP2_mVU0(MAX, "MAX", 0); +REC_COP2_mVU0(MAXi, "MAXi", 0); +REC_COP2_mVU0(MAXx, "MAXx", 0); +REC_COP2_mVU0(MAXy, "MAXy", 0); +REC_COP2_mVU0(MAXz, "MAXz", 0); +REC_COP2_mVU0(MAXw, "MAXw", 0); +REC_COP2_mVU0(MINI, "MINI", 0); +REC_COP2_mVU0(MINIi, "MINIi", 0); +REC_COP2_mVU0(MINIx, "MINIx", 0); +REC_COP2_mVU0(MINIy, "MINIy", 0); +REC_COP2_mVU0(MINIz, "MINIz", 0); +REC_COP2_mVU0(MINIw, "MINIw", 0); +REC_COP2_mVU0(MADD, "MADD", 0); +REC_COP2_mVU0(MADDi, "MADDi", 0); +REC_COP2_mVU0(MADDq, "MADDq", 1); +REC_COP2_mVU0(MADDx, "MADDx", 0); +REC_COP2_mVU0(MADDy, "MADDy", 0); +REC_COP2_mVU0(MADDz, "MADDz", 0); +REC_COP2_mVU0(MADDw, "MADDw", 0); +REC_COP2_mVU0(MADDA, "MADDA", 0); +REC_COP2_mVU0(MADDAi, "MADDAi", 0); +REC_COP2_mVU0(MADDAq, "MADDAq", 1); +REC_COP2_mVU0(MADDAx, "MADDAx", 0); +REC_COP2_mVU0(MADDAy, "MADDAy", 0); +REC_COP2_mVU0(MADDAz, "MADDAz", 0); +REC_COP2_mVU0(MADDAw, "MADDAw", 0); +REC_COP2_mVU0(MSUB, "MSUB", 0); +REC_COP2_mVU0(MSUBi, "MSUBi", 0); +REC_COP2_mVU0(MSUBq, "MSUBq", 1); +REC_COP2_mVU0(MSUBx, "MSUBx", 0); +REC_COP2_mVU0(MSUBy, "MSUBy", 0); +REC_COP2_mVU0(MSUBz, "MSUBz", 0); +REC_COP2_mVU0(MSUBw, "MSUBw", 0); +REC_COP2_mVU0(MSUBA, "MSUBA", 0); +REC_COP2_mVU0(MSUBAi, "MSUBAi", 0); +REC_COP2_mVU0(MSUBAq, "MSUBAq", 1); +REC_COP2_mVU0(MSUBAx, "MSUBAx", 0); +REC_COP2_mVU0(MSUBAy, "MSUBAy", 0); +REC_COP2_mVU0(MSUBAz, "MSUBAz", 0); +REC_COP2_mVU0(MSUBAw, "MSUBAw", 0); +REC_COP2_mVU0(OPMULA, "OPMULA", 0); +REC_COP2_mVU0(OPMSUB, "OPMSUB", 0); +REC_COP2_VU0 (CLIP); + +//------------------------------------------------------------------ +// Macro VU - Redirect Lower Instructions +//------------------------------------------------------------------ + +REC_COP2_mVU0(DIV, "DIV", 2); +REC_COP2_mVU0(SQRT, "SQRT", 2); +REC_COP2_mVU0(RSQRT, "RSQRT", 2); +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_mVU0(MOVE, "MOVE", 0); +REC_COP2_VU0 (MFIR); +REC_COP2_VU0 (MTIR); +REC_COP2_mVU0(MR32, "MR32", 0); +REC_COP2_VU0 (RINIT); +REC_COP2_VU0 (RGET); +REC_COP2_VU0 (RNEXT); +REC_COP2_VU0 (RXOR); + +//------------------------------------------------------------------ +// Macro VU - Misc... +//------------------------------------------------------------------ + +void recVNOP (s32 info) {} +void recVWAITQ(s32 info) {} +INTERPRETATE_COP2_FUNC(CALLMS); +INTERPRETATE_COP2_FUNC(CALLMSR); + //------------------------------------------------------------------ // Macro VU - Branches //------------------------------------------------------------------ @@ -347,7 +504,6 @@ void printCOP2(const char* text) { static void _setupBranchTest() { _eeFlushAllUnused(); TEST32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, 0x100); - printCOP2("_setupBranchTest()"); } void recBC2F(s32 info) { @@ -370,171 +526,10 @@ void recBC2TL(s32 info) { 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 +// Macro VU - Tables //------------------------------------------------------------------ -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); @@ -599,7 +594,7 @@ 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 +// 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, From 6ab6749a53326afbeb5201dd808b68d5dfe89ab5 Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Fri, 28 Aug 2009 22:50:55 +0000 Subject: [PATCH 07/14] microVU: Removed the use of an offset-register for referencing VI regs. It didn't make any noticeable difference speedwise, and removing it will make mVU macro code simpler. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1703 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/x86/microVU_Alloc.inl | 9 ++++----- pcsx2/x86/microVU_Branch.inl | 2 +- pcsx2/x86/microVU_Compile.inl | 1 - pcsx2/x86/microVU_Execute.inl | 2 -- pcsx2/x86/microVU_Flags.inl | 5 ++--- pcsx2/x86/microVU_Lower.inl | 19 +++++++++---------- pcsx2/x86/microVU_Misc.h | 4 +--- pcsx2/x86/microVU_Misc.inl | 1 - 8 files changed, 17 insertions(+), 26 deletions(-) diff --git a/pcsx2/x86/microVU_Alloc.inl b/pcsx2/x86/microVU_Alloc.inl index d794fc0082..1db752045c 100644 --- a/pcsx2/x86/microVU_Alloc.inl +++ b/pcsx2/x86/microVU_Alloc.inl @@ -100,17 +100,16 @@ microVUt(void) mVUallocCFLAGb(mV, int reg, int fInstance) { microVUt(void) mVUallocVIa(mV, int GPRreg, int _reg_) { if (!_reg_) { XOR32RtoR(GPRreg, GPRreg); } - else { MOVZX32Rm16toR(GPRreg, gprR, (_reg_ - 9) * 16); } + else { MOVZX32M16toR(GPRreg, (uptr)&mVU->regs->VI[_reg_].UL); } } microVUt(void) mVUallocVIb(mV, int GPRreg, int _reg_) { if (mVUlow.backupVI) { // Backs up reg to memory (used when VI is modified b4 a branch) - MOVZX32M16toR(gprR, (uptr)&mVU->regs->VI[_reg_].UL); - MOV32RtoM((uptr)&mVU->VIbackup, gprR); - MOV32ItoR(gprR, Roffset); + MOVZX32M16toR(gprT3, (uptr)&mVU->regs->VI[_reg_].UL); + MOV32RtoM((uptr)&mVU->VIbackup, gprT3); } if (_reg_ == 0) { return; } - else if (_reg_ < 16) { MOV16RtoRm(gprR, GPRreg, (_reg_ - 9) * 16); } + else if (_reg_ < 16) { MOV16RtoM((uptr)&mVU->regs->VI[_reg_].UL, GPRreg); } } //------------------------------------------------------------------ diff --git a/pcsx2/x86/microVU_Branch.inl b/pcsx2/x86/microVU_Branch.inl index 3e574abd64..054446c567 100644 --- a/pcsx2/x86/microVU_Branch.inl +++ b/pcsx2/x86/microVU_Branch.inl @@ -104,7 +104,7 @@ void normJumpCompile(mV, microFlagCycles& mFC, bool isEvilJump) { if (isEvilJump) MOV32MtoR(gprT2, (uptr)&mVU->evilBranch); else MOV32MtoR(gprT2, (uptr)&mVU->branch); - MOV32ItoR(gprR, (u32)&mVUpBlock->pStateEnd); + MOV32ItoR(gprT3, (u32)&mVUpBlock->pStateEnd); if (!mVU->index) xCALL(mVUcompileJIT<0>); //(u32 startPC, uptr pState) else xCALL(mVUcompileJIT<1>); diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index cec2b5b6e4..88dcc1b255 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -295,7 +295,6 @@ microVUt(void) mVUtestCycles(mV) { 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 76c0e4fb5d..1e4c105820 100644 --- a/pcsx2/x86/microVU_Execute.inl +++ b/pcsx2/x86/microVU_Execute.inl @@ -40,9 +40,7 @@ void mVUdispatcherA(mV) { SSE_LDMXCSR((uptr)&g_sseVUMXCSR); // Load Regs - MOV32ItoR(gprR, Roffset); // Load VI Reg Offset MOV32MtoR(gprF0, (uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL); - MOV32RtoR(gprF1, gprF0); SHR32ItoR(gprF1, 3); AND32ItoR(gprF1, 0x18); diff --git a/pcsx2/x86/microVU_Flags.inl b/pcsx2/x86/microVU_Flags.inl index dd9ccfcb68..1401761c9e 100644 --- a/pcsx2/x86/microVU_Flags.inl +++ b/pcsx2/x86/microVU_Flags.inl @@ -197,12 +197,11 @@ microVUt(void) mVUsetupFlags(mV, microFlagCycles& mFC) { else { MOV32RtoR(gprT1, getFlagReg1(bStatus[0])); MOV32RtoR(gprT2, getFlagReg1(bStatus[1])); - MOV32RtoR(gprR, getFlagReg1(bStatus[2])); + MOV32RtoR(gprT3, getFlagReg1(bStatus[2])); MOV32RtoR(gprF3, getFlagReg1(bStatus[3])); MOV32RtoR(gprF0, gprT1); MOV32RtoR(gprF1, gprT2); - MOV32RtoR(gprF2, gprR); - MOV32ItoR(gprR, Roffset); // Restore gprR + MOV32RtoR(gprF2, gprT3); } } diff --git a/pcsx2/x86/microVU_Lower.inl b/pcsx2/x86/microVU_Lower.inl index cf51547bf5..1cbf0e0250 100644 --- a/pcsx2/x86/microVU_Lower.inl +++ b/pcsx2/x86/microVU_Lower.inl @@ -1030,23 +1030,22 @@ mVUop(mVU_RNEXT) { pass1 { mVUanalyzeR2(mVU, _Ft_, 0); } pass2 { // algorithm from www.project-fao.org - MOV32MtoR(gprR, Rmem); - MOV32RtoR(gprT1, gprR); + MOV32MtoR(gprT3, Rmem); + MOV32RtoR(gprT1, gprT3); SHR32ItoR(gprT1, 4); AND32ItoR(gprT1, 1); - MOV32RtoR(gprT2, gprR); + MOV32RtoR(gprT2, gprT3); SHR32ItoR(gprT2, 22); AND32ItoR(gprT2, 1); - SHL32ItoR(gprR, 1); + SHL32ItoR(gprT3, 1); XOR32RtoR(gprT1, gprT2); - XOR32RtoR(gprR, gprT1); - AND32ItoR(gprR, 0x007fffff); - OR32ItoR (gprR, 0x3f800000); - MOV32RtoM(Rmem, gprR); - mVU_RGET_(mVU, gprR); - MOV32ItoR(gprR, Roffset); // Restore gprR + XOR32RtoR(gprT3, gprT1); + AND32ItoR(gprT3, 0x007fffff); + OR32ItoR (gprT3, 0x3f800000); + MOV32RtoM(Rmem, gprT3); + mVU_RGET_(mVU, gprT3); } pass3 { mVUlog("RNEXT.%s vf%02d, R", _XYZW_String, _Ft_); } } diff --git a/pcsx2/x86/microVU_Misc.h b/pcsx2/x86/microVU_Misc.h index 1c203e10dc..e5fa9fadb3 100644 --- a/pcsx2/x86/microVU_Misc.h +++ b/pcsx2/x86/microVU_Misc.h @@ -128,7 +128,7 @@ declareAllVariables #define gprT1 0 // Temp Reg #define gprT2 1 // Temp Reg -#define gprR 2 // VI Reg Offset +#define gprT3 2 // Temp Reg #define gprF0 3 // Status Flag 0 #define gprESP 4 // Don't use? #define gprF1 5 // Status Flag 1 @@ -219,7 +219,6 @@ typedef u32 (__fastcall *mVUCall)(void*, void*); #define shufflePQ (((mVU->p) ? 0xb0 : 0xe0) | ((mVU->q) ? 0x01 : 0x04)) #define cmpOffset(x) ((u8*)&(((u8*)x)[mVUprogI.ranges.range[i][0]])) #define Rmem (uptr)&mVU->regs->VI[REG_R].UL -#define Roffset (uptr)&mVU->regs->VI[9].UL #define aWrap(x, m) ((x > m) ? 0 : x) #define shuffleSS(x) ((x==1)?(0x27):((x==2)?(0xc6):((x==4)?(0xe1):(0xe4)))) @@ -287,6 +286,5 @@ typedef u32 (__fastcall *mVUCall)(void*, void*); MOV32ItoR(gprT2, xPC); \ if (isEndPC) { CALLFunc((uptr)mVUprintPC2); } \ else { CALLFunc((uptr)mVUprintPC1); } \ - MOV32ItoR(gprR, Roffset); \ } \ } diff --git a/pcsx2/x86/microVU_Misc.inl b/pcsx2/x86/microVU_Misc.inl index 1e92a5dc44..5961ec14cb 100644 --- a/pcsx2/x86/microVU_Misc.inl +++ b/pcsx2/x86/microVU_Misc.inl @@ -317,7 +317,6 @@ microVUt(void) mVUbackupRegs(microVU* mVU) { // Restore Volatile Regs microVUt(void) mVUrestoreRegs(microVU* mVU) { SSE_MOVAPS_M128_to_XMM(xmmPQ, (uptr)&mVU->xmmPQb[0]); - MOV32ItoR(gprR, Roffset); // Restore gprR } //------------------------------------------------------------------ From 712a23b7d6742e35379f0969810f849e5651a670 Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Fri, 28 Aug 2009 23:36:03 +0000 Subject: [PATCH 08/14] mVU Macro: Implemented more instructions... git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1704 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/x86/microVU_Macro.inl | 50 +++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/pcsx2/x86/microVU_Macro.inl b/pcsx2/x86/microVU_Macro.inl index ee8f33bcfc..e95869c4fe 100644 --- a/pcsx2/x86/microVU_Macro.inl +++ b/pcsx2/x86/microVU_Macro.inl @@ -355,11 +355,17 @@ void endMacroOp(int mode) { microVU0.regAlloc->flushAll(); } -#define REC_COP2_mVU0(f, opName, mode) \ - void recV##f(s32 info) { \ - setupMacroOp(mode, opName); \ - mVU_##f(µVU0, 1); \ - endMacroOp(mode); \ +#define REC_COP2_mVU0(f, opName, mode) \ + void recV##f(s32 info) { \ + setupMacroOp(mode, opName); \ + if (mode & 4) { \ + mVU_##f(µVU0, 0); \ + if (!microVU0.prog.IRinfo.info[0].lOp.isNOP) { \ + mVU_##f(µVU0, 1); \ + } \ + } \ + else { mVU_##f(µVU0, 1); } \ + endMacroOp(mode); \ } //------------------------------------------------------------------ @@ -468,25 +474,25 @@ REC_COP2_VU0 (CLIP); REC_COP2_mVU0(DIV, "DIV", 2); REC_COP2_mVU0(SQRT, "SQRT", 2); REC_COP2_mVU0(RSQRT, "RSQRT", 2); -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_mVU0(IADD, "IADD", 4); +REC_COP2_mVU0(IADDI, "IADDI", 4); +REC_COP2_mVU0(IAND, "IAND", 4); +REC_COP2_mVU0(IOR, "IOR", 4); +REC_COP2_mVU0(ISUB, "ISUB", 4); +REC_COP2_mVU0(ILWR, "ILWR", 4); +REC_COP2_mVU0(ISWR, "ISWR", 0); +REC_COP2_mVU0(LQI, "LQI", 4); +REC_COP2_mVU0(LQD, "LQD", 4); +REC_COP2_mVU0(SQI, "SQI", 0); +REC_COP2_mVU0(SQD, "SQD", 0); +REC_COP2_mVU0(MFIR, "MFIR", 4); +REC_COP2_mVU0(MTIR, "MTIR", 4); REC_COP2_mVU0(MOVE, "MOVE", 0); -REC_COP2_VU0 (MFIR); -REC_COP2_VU0 (MTIR); REC_COP2_mVU0(MR32, "MR32", 0); -REC_COP2_VU0 (RINIT); -REC_COP2_VU0 (RGET); -REC_COP2_VU0 (RNEXT); -REC_COP2_VU0 (RXOR); +REC_COP2_mVU0(RINIT, "RINIT", 0); +REC_COP2_mVU0(RGET, "RGET", 4); +REC_COP2_mVU0(RNEXT, "RNEXT", 4); +REC_COP2_mVU0(RXOR, "RXOR", 0); //------------------------------------------------------------------ // Macro VU - Misc... From 2b57f2363408bee461f8896f1b7d258b076a4587 Mon Sep 17 00:00:00 2001 From: arcum42 Date: Sat, 29 Aug 2009 00:35:20 +0000 Subject: [PATCH 09/14] Changed the chcr stuff over to bitfields, and got various other bitfield stuff ready for later on. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1705 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/Dump.cpp | 2 +- pcsx2/Gif.cpp | 34 +++++------ pcsx2/Gif.h | 32 +++++----- pcsx2/Hw.cpp | 12 ++-- pcsx2/Hw.h | 150 +++++++++++++++++++++++++++++++++++++++++++++- pcsx2/IPU/IPU.cpp | 50 ++++++++-------- pcsx2/IPU/IPU.h | 48 --------------- pcsx2/SPR.cpp | 36 +++++------ pcsx2/Sif.cpp | 24 ++++---- pcsx2/Tags.h | 110 ++++++---------------------------- pcsx2/Vif.cpp | 18 +++--- pcsx2/Vif.h | 54 +++++++++++------ pcsx2/VifDma.cpp | 68 ++++++++++----------- 13 files changed, 342 insertions(+), 296 deletions(-) diff --git a/pcsx2/Dump.cpp b/pcsx2/Dump.cpp index 2e9453569f..6b3357f5f8 100644 --- a/pcsx2/Dump.cpp +++ b/pcsx2/Dump.cpp @@ -131,7 +131,7 @@ void iDumpRegisters(u32 startpc, u32 temp) for(i = 0; i < ArraySize(dmacs); ++i) { DMACh* p = (DMACh*)(PS2MEM_HW+dmacs[i]); - __Log("dma%d c%x m%x q%x t%x s%x", i, p->chcr, p->madr, p->qwc, p->tadr, p->sadr); + __Log("dma%d c%x m%x q%x t%x s%x", i, p->chcr._u32, p->madr, p->qwc, p->tadr, p->sadr); } __Log("dmac %x %x %x %x", psHu32(DMAC_CTRL), psHu32(DMAC_STAT), psHu32(DMAC_RBSR), psHu32(DMAC_RBOR)); __Log("intc %x %x", psHu32(INTC_STAT), psHu32(INTC_MASK)); diff --git a/pcsx2/Gif.cpp b/pcsx2/Gif.cpp index 9096c6d695..d57b478ae2 100644 --- a/pcsx2/Gif.cpp +++ b/pcsx2/Gif.cpp @@ -57,9 +57,9 @@ __forceinline void gsInterrupt() { GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle); - if (!(CHCR::STR(gif))) + if (!(gif->chcr.STR)) { - //Console::WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", params gif->chcr, gif->qwc, done); + //Console::WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", params gif->chcr._u32, gif->qwc, done); return; } @@ -86,7 +86,7 @@ __forceinline void gsInterrupt() gspath3done = 0; gscycles = 0; - CHCR::clearSTR(gif); + gif->chcr.STR = 0; vif1Regs->stat &= ~VIF1_STAT_VGW; psHu32(GIF_STAT) &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH | GIF_STAT_P3Q | GIF_STAT_FQC); @@ -160,7 +160,7 @@ static __forceinline void GIFchain() static __forceinline bool checkTieBit(u32* &ptag) { - if ((CHCR::TIE(gif)) && (Tag::IRQ(ptag))) //Check TIE bit of CHCR and IRQ bit of tag + if (gif->chcr.TIE && (Tag::IRQ(ptag))) //Check TIE bit of CHCR and IRQ bit of tag { GIF_LOG("dmaIrq Set"); gspath3done = 1; @@ -238,7 +238,7 @@ void GIFdma() { if (gif->qwc == 0) { - if ((CHCR::MOD(gif) == CHAIN_MODE) && CHCR::STR(gif)) + if ((gif->chcr.MOD == CHAIN_MODE) && gif->chcr.STR) { if (!ReadTag(ptag, id)) return; GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr); @@ -261,10 +261,10 @@ void GIFdma() } // Transfer Dn_QWC from Dn_MADR to GIF - if ((CHCR::MOD(gif) == NORMAL_MODE) || (gif->qwc > 0)) // Normal Mode + if ((gif->chcr.MOD == NORMAL_MODE) || (gif->qwc > 0)) // Normal Mode { - if (((psHu32(DMAC_CTRL) & 0xC0) == 0x80) && (CHCR::MOD(gif) == NORMAL_MODE)) + if (((psHu32(DMAC_CTRL) & 0xC0) == 0x80) && (gif->chcr.MOD == NORMAL_MODE)) { Console::WriteLn("DMA Stall Control on GIF normal"); } @@ -275,7 +275,7 @@ void GIFdma() return; } - if ((CHCR::MOD(gif) == CHAIN_MODE) && (gspath3done == 0)) // Chain Mode + if ((gif->chcr.MOD == CHAIN_MODE) && (gspath3done == 0)) // Chain Mode { if (!ReadTag(ptag, id)) return; GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr); @@ -326,7 +326,7 @@ void dmaGIF() { //We used to add wait time for the buffer to fill here, fixing some timing problems in path 3 masking //It takes the time of 24 QW for the BUS to become ready - The Punisher And Streetball - GIF_LOG("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gif->chcr, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1); + GIF_LOG("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gif->chcr._u32, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1); Path3progress = STOPPED_MODE; gspath3done = 0; // For some reason this doesn't clear? So when the system starts the thread, we will clear it :) @@ -341,7 +341,7 @@ void dmaGIF() return; } - if ((gif->qwc == 0) && ((CHCR::MOD(gif) != NORMAL_MODE))) + if ((gif->qwc == 0) && (gif->chcr.MOD != NORMAL_MODE)) { u32 *ptag; @@ -447,7 +447,7 @@ void mfifoGIFtransfer(int qwc) gifstate &= ~GIF_STATE_EMPTY; } - GIF_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr); + GIF_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr); if (gif->qwc == 0) { @@ -505,7 +505,7 @@ void mfifoGIFtransfer(int qwc) break; } - if ((CHCR::TIE(gif)) && (Tag::IRQ(ptag))) + if ((gif->chcr.TIE) && (Tag::IRQ(ptag))) { SPR_LOG("dmaIrq Set"); gifstate = GIF_STATE_DONE; @@ -525,7 +525,7 @@ void mfifoGIFtransfer(int qwc) if ((gif->qwc == 0) && (gifstate == GIF_STATE_DONE)) gifstate = GIF_STATE_STALL; CPU_INT(11,mfifocycles); - SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr); + SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr); } void gifMFIFOInterrupt() @@ -533,13 +533,13 @@ void gifMFIFOInterrupt() mfifocycles = 0; if (Path3progress == STOPPED_MODE) psHu32(GIF_STAT)&= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0 - if ((CHCR::STR(spr0)) && (spr0->qwc == 0)) + if ((spr0->chcr.STR) && (spr0->qwc == 0)) { - CHCR::clearSTR(spr0); + spr0->chcr.STR = 0; hwDmacIrq(DMAC_FROM_SPR); } - if (!(CHCR::STR(gif))) + if (!(gif->chcr.STR)) { Console::WriteLn("WTF GIFMFIFO"); cpuRegs.interrupt &= ~(1 << 11); @@ -583,7 +583,7 @@ void gifMFIFOInterrupt() 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); + gif->chcr.STR = 0; gifstate = GIF_STATE_READY; hwDmacIrq(DMAC_GIF); clearFIFOstuff(false); diff --git a/pcsx2/Gif.h b/pcsx2/Gif.h index 33c73f7fee..cbfc991797 100644 --- a/pcsx2/Gif.h +++ b/pcsx2/Gif.h @@ -46,9 +46,9 @@ union tGIF_CTRL u32 PSE : 1; u32 reserved2 : 28; }; - u32 value; + u32 _u32; - tGIF_CTRL( u32 val ) : value( val ) + tGIF_CTRL( u32 val ) : _u32( val ) { } }; @@ -62,9 +62,9 @@ union tGIF_MODE u32 IMT : 1; u32 reserved2 : 29; }; - u32 value; + u32 _u32; - tGIF_MODE( u32 val ) : value( val ) + tGIF_MODE( u32 val ) : _u32( val ) { } }; @@ -89,9 +89,9 @@ union tGIF_STAT u32 FQC : 5; u32 reserved3 : 3; }; - u32 value; + u32 _u32; - tGIF_STAT( u32 val ) : value( val ) + tGIF_STAT( u32 val ) : _u32( val ) { } }; @@ -104,9 +104,9 @@ union tGIF_TAG0 u32 EOP : 1; u32 TAG : 16; }; - u32 value; + u32 _u32; - tGIF_TAG0( u32 val ) : value( val ) + tGIF_TAG0( u32 val ) : _u32( val ) { } }; @@ -121,9 +121,9 @@ union tGIF_TAG1 u32 FLG : 2; u32 NREG : 4; }; - u32 value; + u32 _u32; - tGIF_TAG1( u32 val ) : value( val ) + tGIF_TAG1( u32 val ) : _u32( val ) { } }; @@ -139,9 +139,9 @@ union tGIF_CNT u32 reserved2 : 10; }; - u32 value; + u32 _u32; - tGIF_CNT( u32 val ) : value( val ) + tGIF_CNT( u32 val ) : _u32( val ) { } }; @@ -153,9 +153,9 @@ union tGIF_P3CNT u32 P3CNT : 15; u32 reserved1 : 17; }; - u32 value; + u32 _u32; - tGIF_P3CNT( u32 val ) : value( val ) + tGIF_P3CNT( u32 val ) : _u32( val ) { } }; @@ -168,9 +168,9 @@ union tGIF_P3TAG u32 EOP : 1; u32 reserved1 : 16; }; - u32 value; + u32 _u32; - tGIF_P3TAG( u32 val ) : value( val ) + tGIF_P3TAG( u32 val ) : _u32( val ) { } }; diff --git a/pcsx2/Hw.cpp b/pcsx2/Hw.cpp index 4ef9d27c8e..4bd619f84e 100644 --- a/pcsx2/Hw.cpp +++ b/pcsx2/Hw.cpp @@ -177,15 +177,15 @@ bool hwDmacSrcChainWithStack(DMACh *dma, int id) { dma->madr = dma->tadr + 16; //Set MADR to data following the tag - switch(CHCR::ASP(dma)) + switch(dma->chcr.ASP) { case 0: { //Check if ASR0 is empty dma->asr0 = dma->madr + (dma->qwc << 4); //If yes store Succeeding tag - dma->chcr = (dma->chcr & 0xffffffcf) | 0x10; //1 Address in call stack + dma->chcr._u32 = (dma->chcr._u32 & 0xffffffcf) | 0x10; //1 Address in call stack break; } case 1: { - dma->chcr = (dma->chcr & 0xffffffcf) | 0x20; //2 Addresses in call stack + dma->chcr._u32 = (dma->chcr._u32 & 0xffffffcf) | 0x20; //2 Addresses in call stack dma->asr1 = dma->madr + (dma->qwc << 4); //If no store Succeeding tag in ASR1 break; } @@ -200,17 +200,17 @@ bool hwDmacSrcChainWithStack(DMACh *dma, int id) { } case TAG_RET: // Ret - Transfer QWC following the tag, load next tag dma->madr = dma->tadr + 16; //Set MADR to data following the tag - switch(CHCR::ASP(dma)) + switch(dma->chcr.ASP) { case 2: { //If ASR1 is NOT equal to 0 (Contains address) - dma->chcr = (dma->chcr & 0xffffffcf) | 0x10; //1 Address left in call stack + dma->chcr._u32 = (dma->chcr._u32 & 0xffffffcf) | 0x10; //1 Address left in call stack dma->tadr = dma->asr1; //Read ASR1 as next tag dma->asr1 = 0; //Clear ASR1 break; } //If ASR1 is empty (No address held) case 1:{ //Check if ASR0 is NOT equal to 0 (Contains address) - dma->chcr = (dma->chcr & 0xffffffcf); //No addresses left in call stack + dma->chcr._u32 = (dma->chcr._u32 & 0xffffffcf); //No addresses left in call stack dma->tadr = dma->asr0; //Read ASR0 as next tag dma->asr0 = 0; //Clear ASR0 break; diff --git a/pcsx2/Hw.h b/pcsx2/Hw.h index 2607990118..9b2cb2940d 100644 --- a/pcsx2/Hw.h +++ b/pcsx2/Hw.h @@ -47,8 +47,23 @@ void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value); // --- DMA --- // +union tDMA_CHCR { + struct { + u32 DIR : 1; + u32 reserved1 : 1; + u32 MOD : 2; + u32 ASP : 2; + u32 TTE : 1; + u32 TIE : 1; + u32 STR : 1; + u32 reserved2 : 7; + u32 TAG : 16; + }; + u32 _u32; +}; + struct DMACh { - u32 chcr; + tDMA_CHCR chcr; u32 null0[3]; u32 madr; u32 null1[3]; @@ -418,6 +433,137 @@ enum DMAInter MEISintr = 0x40004000 }; +union tDMAC_CTRL { + struct { + u32 DMAE : 1; + u32 RELE : 1; + u32 MFD : 2; + u32 STS : 2; + u32 STD : 2; + u32 RCYC : 3; + u32 reserved1 : 21; + }; + u32 _u32; +}; + +union tDMAC_STAT { + struct { + u32 CIS0 : 1; + u32 CIS1 : 1; + u32 CIS2 : 1; + u32 CIS3 : 1; + u32 CIS4 : 1; + u32 CIS5 : 1; + u32 CIS6 : 1; + u32 CIS7 : 1; + u32 CIS8 : 1; + u32 CIS9 : 1; + u32 reserved1 : 3; + u32 SIS : 1; + u32 MEIS : 1; + u32 BEIS : 1; + u32 CIM0 : 1; + u32 CIM1 : 1; + u32 CIM2 : 1; + u32 CIM3 : 1; + u32 CIM4 : 1; + u32 CIM5 : 1; + u32 CIM6 : 1; + u32 CIM7 : 1; + u32 CIM8 : 1; + u32 CIM9 : 1; + u32 reserved2 : 3; + u32 SIM : 1; + u32 MEIM : 1; + u32 reserved3 : 1; + }; + u32 _u32; +}; + +union tDMAC_PCR { + struct { + u32 CPC0 : 1; + u32 CPC1 : 1; + u32 CPC2 : 1; + u32 CPC3 : 1; + u32 CPC4 : 1; + u32 CPC5 : 1; + u32 CPC6 : 1; + u32 CPC7 : 1; + u32 CPC8 : 1; + u32 CPC9 : 1; + u32 reserved1 : 6; + u32 CDE0 : 1; + u32 CDE1 : 1; + u32 CDE2 : 1; + u32 CDE3 : 1; + u32 CDE4 : 1; + u32 CDE5 : 1; + u32 CDE6 : 1; + u32 CDE7 : 1; + u32 CDE8 : 1; + u32 CDE9 : 1; + u32 reserved2 : 5; + u32 PCE : 1; + }; + u32 _u32; +}; + +union tDMAC_SQWC { + struct { + u32 SQWC : 8; + u32 reserved1 : 8; + u32 TQWC : 8; + u32 reserved2 : 8; + }; + u32 _u32; +}; + +union tDMAC_RBSR { + struct { + u32 RMSK : 31; + u32 reserved1 : 1; + }; + u32 _u32; +}; + +union tDMAC_RBOR { + struct { + u32 ADDR : 31; + u32 reserved1 : 1; + }; + u32 _u32; +}; + +union tDMAC_STADR { + struct { + u32 ADDR : 31; + u32 reserved1 : 1; + }; + u32 _u32; +}; + +struct DMACregisters +{ + // Note: not yet tested. + tDMAC_CTRL ctrl; + u32 padding[3]; + tDMAC_STAT stat; + u32 padding1[3]; + tDMAC_PCR pcr; + u32 padding2[3]; + + tDMAC_SQWC sqwc; + u32 padding3[3]; + tDMAC_RBSR rbsr; + u32 padding4[3]; + tDMAC_RBOR rbor; + u32 padding5[3]; + tDMAC_STADR stadr; +}; + +#define dmacRegs ((DMACregisters*)(PS2MEM_HW+0xE000)) + #ifdef PCSX2_VIRTUAL_MEM #define dmaGetAddrBase(addr) (((addr) & 0x80000000) ? (void*)&PS2MEM_SCRATCH[(addr) & 0x3ff0] : (void*)(PS2MEM_BASE+TRANSFORM_ADDR(addr))) @@ -485,7 +631,7 @@ static __forceinline u32 *_dmaGetAddr(DMACh *dma, u32 addr, u32 num) // DMA End psHu32(DMAC_STAT) |= 1<chcr &= ~0x100; + dma->chcr.STR = 0; } return ptr; diff --git a/pcsx2/IPU/IPU.cpp b/pcsx2/IPU/IPU.cpp index 852ea8c863..fa4ac59aee 100644 --- a/pcsx2/IPU/IPU.cpp +++ b/pcsx2/IPU/IPU.cpp @@ -811,7 +811,7 @@ void IPUCMD_WRITE(u32 val) case SCE_IPU_FDEC: IPU_LOG("IPU FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, FP %d, CHCR 0x%x, %x", - val & 0x3f, g_BP.IFC, (int)g_BP.BP, g_BP.FP, ipu1dma->chcr, cpuRegs.pc); + val & 0x3f, g_BP.IFC, (int)g_BP.BP, g_BP.FP, ipu1dma->chcr._u32, cpuRegs.pc); g_BP.BP += val & 0x3F; if (ipuFDEC(val)) return; ipuRegs->cmd.BUSY = 0x80000000; @@ -840,7 +840,7 @@ void IPUCMD_WRITE(u32 val) if (ipuCSC(ipuRegs->cmd.DATA)) { - if (ipu0dma->qwc > 0 && (CHCR::STR(ipu0dma))) IPU_INT0_FROM(); + if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM(); return; } break; @@ -855,7 +855,7 @@ void IPUCMD_WRITE(u32 val) if (ipuIDEC(val)) { // idec done, ipu0 done too - if (ipu0dma->qwc > 0 && (CHCR::STR(ipu0dma))) IPU_INT0_FROM(); + if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM(); return; } ipuRegs->topbusy = 0x80000000; @@ -867,7 +867,7 @@ void IPUCMD_WRITE(u32 val) case SCE_IPU_BDEC: if (ipuBDEC(val)) { - if (ipu0dma->qwc > 0 && (CHCR::STR(ipu0dma))) IPU_INT0_FROM(); + if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM(); if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) hwIntcIrq(INTC_IPU); return; } @@ -931,7 +931,7 @@ void IPUWorker() hwIntcIrq(INTC_IPU); return; } - if ((ipu0dma->qwc > 0) && (CHCR::STR(ipu0dma))) IPU_INT0_FROM(); + if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM(); break; case SCE_IPU_PACK: @@ -957,7 +957,7 @@ void IPUWorker() ipuCurCmd = 0xffffffff; // CHECK!: IPU0dma remains when IDEC is done, so we need to clear it - if ((ipu0dma->qwc > 0) && (CHCR::STR(ipu0dma))) IPU_INT0_FROM(); + if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM(); s_routine = NULL; break; @@ -974,7 +974,7 @@ void IPUWorker() ipuRegs->cmd.BUSY = 0; ipuCurCmd = 0xffffffff; - if ((ipu0dma->qwc > 0) && (CHCR::STR(ipu0dma))) IPU_INT0_FROM(); + if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM(); s_routine = NULL; if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) hwIntcIrq(INTC_IPU); return; @@ -1450,9 +1450,9 @@ static __forceinline bool ipuDmacSrcChain(DMACh *tag, u32 *ptag) static __forceinline void flushGIF() { - while(CHCR::STR(gif) && (vif1Regs->mskpath3 == 0)) + while(gif->chcr.STR && (vif1Regs->mskpath3 == 0)) { - GIF_LOG("Flushing gif chcr %x tadr %x madr %x qwc %x", gif->chcr, gif->tadr, gif->madr, gif->qwc); + GIF_LOG("Flushing gif chcr %x tadr %x madr %x qwc %x", gif->chcr._u32, gif->tadr, gif->madr, gif->qwc); gsInterrupt(); } } @@ -1463,9 +1463,9 @@ int IPU1dma() bool done = false; int ipu1cycles = 0, totalqwc = 0; - assert(!(CHCR::TTE(ipu1dma))); + assert(!ipu1dma->chcr.TTE); - if (!(CHCR::STR(ipu1dma)) || (cpuRegs.interrupt & (1 << DMAC_TO_IPU))) return 0; + if (!(ipu1dma->chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_TO_IPU))) return 0; assert(!(g_nDMATransfer & IPU_DMA_TIE1)); @@ -1478,7 +1478,7 @@ int IPU1dma() if (IPU1chain(totalqwc)) return totalqwc; //Check TIE bit of CHCR and IRQ bit of tag - if (CHCR::TIE(ipu1dma) && (g_nDMATransfer & IPU_DMA_DOTIE1)) + if (ipu1dma->chcr.TIE && (g_nDMATransfer & IPU_DMA_DOTIE1)) { Console::WriteLn("IPU1 TIE"); @@ -1488,7 +1488,7 @@ int IPU1dma() return totalqwc; } - if (CHCR::MOD(ipu1dma) == NORMAL_MODE) // If mode is normal mode. + if (ipu1dma->chcr.MOD == NORMAL_MODE) // If mode is normal mode. { IPU_INT_TO(totalqwc * BIAS); return totalqwc; @@ -1496,9 +1496,9 @@ int IPU1dma() else { // Chain mode. - u32 tag = ipu1dma->chcr; // upper bits describe current tag + u32 tag = ipu1dma->chcr._u32; // upper bits describe current tag - if (CHCR::TIE(ipu1dma) && Tag::IRQ(tag)) + if (ipu1dma->chcr.TIE && Tag::IRQ(tag)) { ptag = (u32*)dmaGetAddr(ipu1dma->tadr); @@ -1523,7 +1523,7 @@ int IPU1dma() } // Normal Mode & qwc is finished - if ((CHCR::MOD(ipu1dma) == NORMAL_MODE) && (ipu1dma->qwc == 0)) + if ((ipu1dma->chcr.MOD == NORMAL_MODE) && (ipu1dma->qwc == 0)) { //Console::WriteLn("ipu1 normal empty qwc?"); return totalqwc; @@ -1555,7 +1555,7 @@ int IPU1dma() ptag[1], ptag[0], ipu1dma->qwc, ipu1dma->madr, 8 - g_BP.IFC); - if (CHCR::TIE(ipu1dma) && Tag::IRQ(ptag)) + if (ipu1dma->chcr.TIE && Tag::IRQ(ptag)) g_nDMATransfer |= IPU_DMA_DOTIE1; else g_nDMATransfer &= ~IPU_DMA_DOTIE1; @@ -1672,15 +1672,15 @@ int IPU0dma() int readsize; void* pMem; - if ((!(CHCR::STR(ipu0dma)) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma->qwc == 0)) + if ((!(ipu0dma->chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma->qwc == 0)) return 0; - assert(!(CHCR::TTE(ipu0dma))); + assert(!(ipu0dma->chcr.TTE)); IPU_LOG("dmaIPU0 chcr = %lx, madr = %lx, qwc = %lx", - ipu0dma->chcr, ipu0dma->madr, ipu0dma->qwc); + ipu0dma->chcr._u32, ipu0dma->madr, ipu0dma->qwc); - assert((ipu0dma->chcr & 0xC) == 0); + assert((ipu0dma->chcr._u32 & 0xC) == 0); pMem = (u32*)dmaGetAddr(ipu0dma->madr); readsize = min(ipu0dma->qwc, (u16)ipuRegs->ctrl.OFC); FIFOfrom_read(pMem, readsize); @@ -1734,14 +1734,14 @@ void ipu0Interrupt() { // gif g_nDMATransfer &= ~IPU_DMA_GIFSTALL; - if (CHCR::STR(gif)) GIFdma(); + if (gif->chcr.STR) GIFdma(); } if (g_nDMATransfer & IPU_DMA_VIFSTALL) { // vif g_nDMATransfer &= ~IPU_DMA_VIFSTALL; - if (CHCR::STR(vif1ch)) dmaVIF1(); + if (vif1ch->chcr.STR) dmaVIF1(); } if (g_nDMATransfer & IPU_DMA_TIE0) @@ -1749,7 +1749,7 @@ void ipu0Interrupt() g_nDMATransfer &= ~IPU_DMA_TIE0; } - CHCR::clearSTR(ipu0dma); + ipu0dma->chcr.STR = 0; hwDmacIrq(DMAC_FROM_IPU); } @@ -1767,7 +1767,7 @@ IPU_FORCEINLINE void ipu1Interrupt() if (g_nDMATransfer & IPU_DMA_TIE1) g_nDMATransfer &= ~IPU_DMA_TIE1; else - CHCR::clearSTR(ipu1dma); + ipu1dma->chcr.STR = 0; hwDmacIrq(DMAC_TO_IPU); } diff --git a/pcsx2/IPU/IPU.h b/pcsx2/IPU/IPU.h index bfc9d3c2f1..5edc309f39 100644 --- a/pcsx2/IPU/IPU.h +++ b/pcsx2/IPU/IPU.h @@ -60,40 +60,6 @@ union tIPU_CMD { }; }; -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 // @@ -118,20 +84,6 @@ union tIPU_CTRL { u32 _u32; }; -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/SPR.cpp b/pcsx2/SPR.cpp index 10b0b14b6d..6e1a87d862 100644 --- a/pcsx2/SPR.cpp +++ b/pcsx2/SPR.cpp @@ -140,7 +140,7 @@ static __forceinline void _dmaSPR0() } // Transfer Dn_QWC from SPR to Dn_MADR - switch(CHCR::MOD(spr0)) + switch(spr0->chcr.MOD) { case NORMAL_MODE: { @@ -192,7 +192,7 @@ static __forceinline void _dmaSPR0() break; } SPR0chain(); - if (CHCR::TIE(spr0) && Tag::IRQ(ptag)) //Check TIE bit of CHCR and IRQ bit of tag + if (spr0->chcr.TIE && Tag::IRQ(ptag)) //Check TIE bit of CHCR and IRQ bit of tag { //Console::WriteLn("SPR0 TIE"); done = TRUE; @@ -229,23 +229,23 @@ void SPRFROMinterrupt() { if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("GIF MFIFO Write outside MFIFO area"); spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR)); - //Console::WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", params gif->chcr, gif->madr, gif->tadr); + //Console::WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", params gif->chcr._u32, gif->madr, gif->tadr); mfifoGIFtransfer(mfifotransferred); mfifotransferred = 0; - if (CHCR::STR(gif)) return; + if (gif->chcr.STR) return; } else if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) // VIF1 MFIFO { if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("VIF MFIFO Write outside MFIFO area"); spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR)); - //Console::WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", params vif1ch->chcr, vif1ch->madr, vif1ch->tadr); + //Console::WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", params vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr); mfifoVIF1transfer(mfifotransferred); mfifotransferred = 0; - if (CHCR::STR(vif1ch)) return; + if (vif1ch->chcr.STR) return; } } if (spr0finished == 0) return; - CHCR::clearSTR(spr0); + spr0->chcr.STR = 0; hwDmacIrq(DMAC_FROM_SPR); } @@ -253,9 +253,9 @@ void SPRFROMinterrupt() void dmaSPR0() // fromSPR { SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx", - spr0->chcr, spr0->madr, spr0->qwc, spr0->sadr); + spr0->chcr._u32, spr0->madr, spr0->qwc, spr0->sadr); - if ((CHCR::MOD(spr0) == CHAIN_MODE) && spr0->qwc == 0) + if ((spr0->chcr.MOD == CHAIN_MODE) && spr0->qwc == 0) { u32 *ptag; ptag = (u32*) & PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; //Set memory pointer to SADR @@ -324,7 +324,7 @@ void _SPR1interleave() void _dmaSPR1() // toSPR work function { - switch(CHCR::MOD(spr1)) + switch(spr1->chcr.MOD) { case NORMAL_MODE: { @@ -338,7 +338,7 @@ void _dmaSPR1() // toSPR work function { u32 *ptag; int id; - bool done = FALSE; + bool done = false; if (spr1->qwc > 0) { @@ -353,7 +353,7 @@ void _dmaSPR1() // toSPR work function if (!(Tag::Transfer("SPR1 Tag", spr1, ptag))) { - done = TRUE; + done = true; spr1finished = (done) ? 1: 0; } @@ -361,7 +361,7 @@ void _dmaSPR1() // toSPR work function spr1->madr = ptag[1]; //MADR = ADDR field // Transfer dma tag if tte is set - if (CHCR::TTE(spr1)) + if (spr1->chcr.TTE) { SPR_LOG("SPR TTE: %x_%x\n", ptag[3], ptag[2]); SPR1transfer(ptag, 4); //Transfer Tag @@ -373,12 +373,12 @@ void _dmaSPR1() // toSPR work function done = (hwDmacSrcChain(spr1, id) == 1); SPR1chain(); //Transfers the data set by the switch - if (CHCR::TIE(spr1) && Tag::IRQ(ptag)) //Check TIE bit of CHCR and IRQ bit of tag + if (spr1->chcr.TIE && Tag::IRQ(ptag)) //Check TIE bit of CHCR and IRQ bit of tag { SPR_LOG("dmaIrq Set"); //Console::WriteLn("SPR1 TIE"); - done = TRUE; + done = true; } spr1finished = done; @@ -403,10 +403,10 @@ void dmaSPR1() // toSPR SPR_LOG("dmaSPR1 chcr = 0x%x, madr = 0x%x, qwc = 0x%x\n" " tadr = 0x%x, sadr = 0x%x", - spr1->chcr, spr1->madr, spr1->qwc, + spr1->chcr._u32, spr1->madr, spr1->qwc, spr1->tadr, spr1->sadr); - if ((CHCR::MOD(spr1) == CHAIN_MODE) && (spr1->qwc == 0)) + if ((spr1->chcr.MOD == CHAIN_MODE) && (spr1->qwc == 0)) { u32 *ptag; ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR @@ -423,7 +423,7 @@ void SPRTOinterrupt() { _dmaSPR1(); if (spr1finished == 0) return; - CHCR::clearSTR(spr1); + spr1->chcr.STR = 0; hwDmacIrq(DMAC_TO_SPR); } diff --git a/pcsx2/Sif.cpp b/pcsx2/Sif.cpp index 21b91676e0..716636ab63 100644 --- a/pcsx2/Sif.cpp +++ b/pcsx2/Sif.cpp @@ -222,7 +222,7 @@ __forceinline void SIF0Dma() if (sif0dma->qwc == 0) { // Stop if TIE & the IRQ are set, or at the end. (I'll try to convert this to use the tags code later.) - if (((sif0dma->chcr & 0x80000080) == 0x80000080) || (sif0.end)) + if (((sif0dma->chcr._u32 & 0x80000080) == 0x80000080) || (sif0.end)) { if (sif0.end) SIF_LOG(" EE SIF end"); @@ -241,7 +241,7 @@ __forceinline void SIF0Dma() sif0dma->qwc = (u16)tag[0]; sif0dma->madr = tag[1]; - sif0dma->chcr = (sif0dma->chcr & 0xffff) | (tag[0] & 0xffff0000); + sif0dma->chcr._u32 = (sif0dma->chcr._u32 & 0xffff) | (tag[0] & 0xffff0000); SIF_LOG(" EE SIF dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)", sif0dma->madr, sif0dma->qwc, (tag[0] >> 28)&3, (tag[0] >> 31)&1, tag[1], tag[0]); @@ -274,7 +274,7 @@ __forceinline void SIF1Dma() if (sif1dma->qwc == 0) // If there's no more to transfer { - if ((CHCR::MOD(sif1dma) == NORMAL_MODE) || sif1.end) // If NORMAL mode or end of CHAIN then stop DMA + if ((sif1dma->chcr.MOD == NORMAL_MODE) || sif1.end) // If NORMAL mode or end of CHAIN then stop DMA { // Stop & signal interrupts on EE SIF_LOG("EE SIF1 End %x", sif1.end); @@ -294,10 +294,10 @@ __forceinline void SIF1Dma() //_dmaGetAddr(sif1dma, *ptag, sif1dma->tadr, 6); - sif1dma->chcr = (sif1dma->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); // Copy the tag + sif1dma->chcr._u32 = (sif1dma->chcr._u32 & 0xFFFF) | ((*ptag) & 0xFFFF0000); // Copy the tag sif1dma->qwc = (u16)ptag[0]; - if (CHCR::TTE(sif1dma)) + if (sif1dma->chcr.TTE) { Console::WriteLn("SIF1 TTE"); SIF1write(ptag + 2, 2); @@ -343,7 +343,7 @@ __forceinline void SIF1Dma() default: Console::WriteLn("Bad addr1 source chain"); } - if ((CHCR::TIE(sif1dma)) && (Tag::IRQ(ptag))) + if ((sif1dma->chcr.TIE) && (Tag::IRQ(ptag))) { Console::WriteLn("SIF1 TIE"); sif1.end = 1; @@ -435,19 +435,19 @@ __forceinline void sif1Interrupt() __forceinline void EEsif0Interrupt() { hwDmacIrq(DMAC_SIF0); - CHCR::clearSTR(sif0dma); + sif0dma->chcr.STR = 0; } __forceinline void EEsif1Interrupt() { hwDmacIrq(DMAC_SIF1); - CHCR::clearSTR(sif1dma); + sif1dma->chcr.STR = 0; } __forceinline void dmaSIF0() { SIF_LOG("EE: dmaSIF0 chcr = %lx, madr = %lx, qwc = %lx, tadr = %lx", - sif0dma->chcr, sif0dma->madr, sif0dma->qwc, sif0dma->tadr); + sif0dma->chcr._u32, sif0dma->madr, sif0dma->qwc, sif0dma->tadr); if (sif0.fifoReadPos != sif0.fifoWritePos) { @@ -470,7 +470,7 @@ __forceinline void dmaSIF0() __forceinline void dmaSIF1() { SIF_LOG("EE: dmaSIF1 chcr = %lx, madr = %lx, qwc = %lx, tadr = %lx", - sif1dma->chcr, sif1dma->madr, sif1dma->qwc, sif1dma->tadr); + sif1dma->chcr._u32, sif1dma->madr, sif1dma->qwc, sif1dma->tadr); if (sif1.fifoReadPos != sif1.fifoWritePos) { @@ -494,9 +494,9 @@ __forceinline void dmaSIF1() __forceinline void dmaSIF2() { SIF_LOG("dmaSIF2 chcr = %lx, madr = %lx, qwc = %lx", - sif2dma->chcr, sif2dma->madr, sif2dma->qwc); + sif2dma->chcr._u32, sif2dma->madr, sif2dma->qwc); - CHCR::clearSTR(sif2dma); + sif2dma->chcr.STR = 0; hwDmacIrq(DMAC_SIF2); Console::WriteLn("*PCSX2*: dmaSIF2"); } diff --git a/pcsx2/Tags.h b/pcsx2/Tags.h index fbb58bb333..d83f477ce9 100644 --- a/pcsx2/Tags.h +++ b/pcsx2/Tags.h @@ -107,7 +107,7 @@ namespace Tag static __forceinline void UpperTransfer(DMACh *tag, u32* ptag) { // Transfer upper part of tag to CHCR bits 31-15 - tag->chcr = (tag->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); + tag->chcr._u32 = (tag->chcr._u32 & 0xFFFF) | ((*ptag) & 0xFFFF0000); } static __forceinline void LowerTransfer(DMACh *tag, u32* ptag) @@ -193,100 +193,28 @@ namespace Tag } } -namespace CHCR +// Print information about a chcr tag. +static __forceinline void PrintCHCR(const char* s, DMACh *tag) { - // Query the flags in the channel control register. - static __forceinline bool STR(DMACh *tag) { return !!(tag->chcr & CHCR_STR); } - static __forceinline bool TIE(DMACh *tag) { return !!(tag->chcr & CHCR_TIE); } - static __forceinline bool TTE(DMACh *tag) { return !!(tag->chcr & CHCR_TTE); } - static __forceinline u8 DIR(DMACh *tag) { return (tag->chcr & CHCR_DIR); } - - static __forceinline TransferMode MOD(DMACh *tag) - { - return (TransferMode)((tag->chcr & CHCR_MOD) >> 2); - } - - static __forceinline u8 ASP(DMACh *tag) - { + u8 num_addr = tag->chcr.ASP; + u32 mode = tag->chcr.MOD; - return (TransferMode)((tag->chcr & CHCR_ASP) >> 4); - } - - // Clear the individual flags. - static __forceinline void clearSTR(DMACh *tag) { tag->chcr &= ~CHCR_STR; } - static __forceinline void clearTIE(DMACh *tag) { tag->chcr &= ~CHCR_TIE; } - static __forceinline void clearTTE(DMACh *tag) { tag->chcr &= ~CHCR_TTE; } - static __forceinline void clearDIR(DMACh *tag) { tag->chcr &= ~CHCR_DIR; } - - // Set them. - static __forceinline void setSTR(DMACh *tag) { tag->chcr |= CHCR_STR; } - static __forceinline void setTIE(DMACh *tag) { tag->chcr |= CHCR_TIE; } - static __forceinline void setTTE(DMACh *tag) { tag->chcr |= CHCR_TTE; } - static __forceinline void setDIR(DMACh *tag) { tag->chcr |= CHCR_DIR; } - - static __forceinline void setMOD(DMACh *tag, TransferMode mode) - { - if (mode & (1 << 0)) - tag->chcr |= CHCR_MOD1; - else - tag->chcr &= CHCR_MOD1; - - if (mode & (1 << 1)) - tag->chcr |= CHCR_MOD2; - else - tag->chcr &= CHCR_MOD2; - } - - static __forceinline void setASP(DMACh *tag, u8 num) - { - if (num & (1 << 0)) - tag->chcr |= CHCR_ASP1; - else - tag->chcr &= CHCR_ASP2; - - if (num & (1 << 1)) - tag->chcr |= CHCR_ASP1; - else - tag->chcr &= CHCR_ASP2; - } - - // Print information about a chcr tag. - static __forceinline void Print(const char* s, DMACh *tag) - { - u8 num_addr = ASP(tag); - TransferMode mode = MOD(tag); + Console::Write("%s chcr %s mem: ", params s, (tag->chcr.DIR) ? "from" : "to"); - Console::Write("%s chcr %s mem: ", params s, (DIR(tag)) ? "from" : "to"); + if (mode == NORMAL_MODE) + Console::Write(" normal mode; "); + else if (mode == CHAIN_MODE) + Console::Write(" chain mode; "); + else if (mode == INTERLEAVE_MODE) + Console::Write(" interleave mode; "); + else + Console::Write(" ?? mode; "); - if (mode == NORMAL_MODE) - Console::Write(" normal mode; "); - else if (mode == CHAIN_MODE) - Console::Write(" chain mode; "); - else if (mode == INTERLEAVE_MODE) - Console::Write(" interleave mode; "); - else - Console::Write(" ?? mode; "); - - if (num_addr != 0) Console::Write("ASP = %d;", params num_addr); - if (TTE(tag)) Console::Write("TTE;"); - if (TIE(tag)) Console::Write("TIE;"); - if (STR(tag)) Console::Write(" (DMA started)."); else Console::Write(" (DMA stopped)."); - Console::WriteLn(""); - } -} - -namespace QWC -{ - static __forceinline bool Empty(DMACh *tag) - { - return (tag->qwc == 0); - } - - - static __forceinline void Clear(DMACh *tag) - { - tag->qwc = 0; - } + if (num_addr != 0) Console::Write("ASP = %d;", params num_addr); + if (tag->chcr.TTE) Console::Write("TTE;"); + if (tag->chcr.TIE) Console::Write("TIE;"); + if (tag->chcr.STR) Console::Write(" (DMA started)."); else Console::Write(" (DMA stopped)."); + Console::WriteLn(""); } namespace D_CTRL diff --git a/pcsx2/Vif.cpp b/pcsx2/Vif.cpp index 9989358acb..7fd34bbc49 100644 --- a/pcsx2/Vif.cpp +++ b/pcsx2/Vif.cpp @@ -434,7 +434,7 @@ void mfifoVIF1transfer(int qwc) if (qwc > 0) { vifqwc += qwc; - SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch->chcr, vif1.vifstalled, vif1.done); + SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch->chcr._u32, vif1.vifstalled, vif1.done); if (vif1.inprogress & 0x10) { if (vif1ch->madr >= psHu32(DMAC_RBOR) && vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR))) @@ -453,7 +453,7 @@ void mfifoVIF1transfer(int qwc) { ptag = (u32*)dmaGetAddr(vif1ch->tadr); - if (CHCR::TTE(vif1ch)) + if (vif1ch->chcr.TTE) { if (vif1.stallontag) ret = VIF1transfer(ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset, 1); //Transfer Tag on Stall @@ -513,7 +513,7 @@ void mfifoVIF1transfer(int qwc) break; } - if ((CHCR::TIE(vif1ch)) && (Tag::IRQ(ptag))) + if ((vif1ch->chcr.TIE) && (Tag::IRQ(ptag))) { VIF_LOG("dmaIrq Set"); vif1.done = true; @@ -522,7 +522,7 @@ void mfifoVIF1transfer(int qwc) vif1.inprogress |= 1; - SPR_LOG("mfifoVIF1transfer end %x madr %x, tadr %x vifqwc %x", vif1ch->chcr, vif1ch->madr, vif1ch->tadr, vifqwc); + SPR_LOG("mfifoVIF1transfer end %x madr %x, tadr %x vifqwc %x", vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr, vifqwc); } void vifMFIFOInterrupt() @@ -533,7 +533,7 @@ void vifMFIFOInterrupt() if ((vif1Regs->stat & VIF1_STAT_VGW)) { - if (CHCR::STR(gif)) + if (gif->chcr.STR) { CPU_INT(10, 16); return; @@ -545,9 +545,9 @@ void vifMFIFOInterrupt() } - if ((CHCR::STR(spr0)) && (spr0->qwc == 0)) + if ((spr0->chcr.STR) && (spr0->qwc == 0)) { - CHCR::clearSTR(spr0); + spr0->chcr.STR = 0; hwDmacIrq(DMAC_FROM_SPR); } @@ -559,7 +559,7 @@ void vifMFIFOInterrupt() if (vif1Regs->stat & (VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS)) { vif1Regs->stat &= ~VIF1_STAT_FQC; // FQC=0 - CHCR::clearSTR(vif1ch); + vif1ch->chcr.STR = 0; return; } } @@ -606,7 +606,7 @@ void vifMFIFOInterrupt() vif1.done = 1; g_vifCycles = 0; - CHCR::clearSTR(vif1ch); + vif1ch->chcr.STR = 0; hwDmacIrq(DMAC_VIF1); VIF_LOG("vif mfifo dma end"); diff --git a/pcsx2/Vif.h b/pcsx2/Vif.h index 5e06ef38af..6f4d98d83d 100644 --- a/pcsx2/Vif.h +++ b/pcsx2/Vif.h @@ -29,32 +29,52 @@ struct vifCycle { // union tVIF_STAT { struct { - u32 VPS : 2; - u32 VEW : 1; - u32 VGW : 1; + u32 VPS : 2; // Vif(0/1) status. + u32 VEW : 1; // E-bit wait (1 - wait, 0 - don't wait) + u32 VGW : 1; // Status waiting for the end of gif transfer (Vif1 only) 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 MRK : 1; // Mark Detect + u32 DBF : 1; // Double Buffer Flag + u32 VSS : 1; // Stopped by STOP + u32 VFS : 1; // Stopped by ForceBreak + u32 VIS : 1; // Vif Interrupt Stall + u32 INT : 1; // Intereupt by the i bit. + u32 ER0 : 1; // DmaTag Mismatch error. + u32 ER1 : 1; // VifCode error u32 reserved2 : 9; - u32 FDR : 1; - u32 FQC : 5; + u32 FDR : 1; // VIF/FIFO transfer direction. (0 - memory -> Vif, 1 - Vif -> memory) + u32 FQC : 5; // Amount of data. Up to 8 qwords on Vif0, 16 on Vif1. + }; + u32 _u32; +}; + +union tVIF_FBRST { + struct { + u32 RST : 1; // Resets Vif(0/1) when written. + u32 FBK : 1; // Causes a Forcebreak to Vif((0/1) when 1 is written. (Stall) + u32 STP : 1; // Stops after the end of the Vifcode in progress when written. (Stall) + u32 STC : 1; // Cancels the Vif(0/1) stall and clears Vif Stats VSS, VFS, VIS, INT, ER0 & ER1. + u32 reserved : 28; + }; + u32 _u32; +}; + +union tVIF_ERR { + struct { + u32 MII : 1; // Masks Stat INT. + u32 ME0 : 1; // Masks Stat Err0. + u32 ME1 : 1; // Masks Stat Err1. + u32 reserved : 29; }; u32 _u32; }; -// r0-r3 and c0-c3 would be more managable as arrays. struct VIFregisters { u32 stat; u32 pad0[3]; u32 fbrst; u32 pad1[3]; - u32 err; + tVIF_ERR err; u32 pad2[3]; u32 mark; u32 pad3[3]; @@ -102,7 +122,7 @@ struct VIFregisters { u32 addr; }; -enum vif_errors +/*enum vif_errors { VIF_ERR_MII = 0x1, VIF_ERR_ME0 = 0x2, @@ -120,7 +140,7 @@ namespace VIF_ERR // If true, VifCode errors are masked. static __forceinline bool ME1(VIFregisters *tag) { return !!(tag->err & VIF_ERR_ME1); } -} +}*/ extern "C" { diff --git a/pcsx2/VifDma.cpp b/pcsx2/VifDma.cpp index 7740d2384d..a0cf051cca 100644 --- a/pcsx2/VifDma.cpp +++ b/pcsx2/VifDma.cpp @@ -1222,7 +1222,7 @@ static void Vif0CMDMPGTransfer() // MPG static void Vif0CMDNull() // invalid opcode { // if ME1, then force the vif to interrupt - if (!(VIF_ERR::ME1(vif0Regs))) //Ignore vifcode and tag mismatch error + if (!(vif0Regs->err.ME1)) //Ignore vifcode and tag mismatch error { Console::WriteLn("UNKNOWN VifCmd: %x", params vif0.cmd); vif0Regs->stat |= VIF0_STAT_ER1; @@ -1274,7 +1274,7 @@ int VIF0transfer(u32 *data, int size, int istag) if ((vif0.cmd & 0x7f) > 0x4A) { - if (!(VIF_ERR::ME1(vif0Regs))) //Ignore vifcode and tag mismatch error + if (!(vif0Regs->err.ME1)) //Ignore vifcode and tag mismatch error { Console::WriteLn("UNKNOWN VifCmd: %x", params vif0.cmd); vif0Regs->stat |= VIF0_STAT_ER1; @@ -1294,7 +1294,7 @@ int VIF0transfer(u32 *data, int size, int istag) { vif0.cmd &= 0x7f; - if (!(VIF_ERR::MII(vif0Regs))) //i bit on vifcode and not masked by VIF0_ERR + if (!(vif0Regs->err.MII)) //i bit on vifcode and not masked by VIF0_ERR { VIF_LOG("Interrupt on VIFcmd: %x (INTC_MASK = %x)", vif0.cmd, psHu32(INTC_MASK)); @@ -1385,7 +1385,7 @@ int _chainVIF0() vif0ptag[1], vif0ptag[0], vif0ch->qwc, id, vif0ch->madr, vif0ch->tadr); // Transfer dma tag if tte is set - if (CHCR::TTE(vif0ch)) + if (vif0ch->chcr.TTE) { if (vif0.vifstalled) ret = VIF0transfer(vif0ptag + (2 + vif0.irqoffset), 2 - vif0.irqoffset, 1); //Transfer Tag on stall @@ -1403,7 +1403,7 @@ int _chainVIF0() ret = _VIF0chain(); //Transfers the data set by the switch - if (CHCR::TIE(vif0ch) && Tag::IRQ(vif0ptag)) //Check TIE bit of CHCR and IRQ bit of tag + if (vif0ch->chcr.TIE && Tag::IRQ(vif0ptag)) //Check TIE bit of CHCR and IRQ bit of tag { VIF_LOG("dmaIrq Set\n"); @@ -1426,7 +1426,7 @@ void vif0Interrupt() if (vif0Regs->stat & (VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS)) { vif0Regs->stat &= ~VIF0_STAT_FQC; // FQC=0 - CHCR::clearSTR(vif0ch); + vif0ch->chcr.STR = 0; return; } @@ -1442,9 +1442,9 @@ void vif0Interrupt() } } - if (!CHCR::STR(vif0ch)) Console::WriteLn("Vif0 running when CHCR = %x", params vif0ch->chcr); + if (!vif0ch->chcr.STR) Console::WriteLn("Vif0 running when CHCR = %x", params vif0ch->chcr._u32); - if ((CHCR::MOD(vif0ch) == CHAIN_MODE) && (!vif0.done) && (!vif0.vifstalled)) + if ((vif0ch->chcr.STR == CHAIN_MODE) && (!vif0.done) && (!vif0.vifstalled)) { if (!(psHu32(DMAC_CTRL) & 0x1)) @@ -1465,7 +1465,7 @@ void vif0Interrupt() if (vif0ch->qwc > 0) Console::WriteLn("VIF0 Ending with QWC left"); if (vif0.cmd != 0) Console::WriteLn("vif0.cmd still set %x", params vif0.cmd); - CHCR::clearSTR(vif0ch); + vif0ch->chcr.STR = 0; hwDmacIrq(DMAC_VIF0); vif0Regs->stat &= ~VIF0_STAT_FQC; // FQC=0 } @@ -1510,14 +1510,14 @@ void dmaVIF0() { VIF_LOG("dmaVIF0 chcr = %lx, madr = %lx, qwc = %lx\n" " tadr = %lx, asr0 = %lx, asr1 = %lx\n", - vif0ch->chcr, vif0ch->madr, vif0ch->qwc, + vif0ch->chcr._u32, vif0ch->madr, vif0ch->qwc, vif0ch->tadr, vif0ch->asr0, vif0ch->asr1); g_vifCycles = 0; vif0Regs->stat |= 0x8000000; // FQC=8 - if (!(vif0ch->chcr & 0x4) || vif0ch->qwc > 0) // Normal Mode + if (!(vif0ch->chcr.MOD & 0x1) || vif0ch->qwc > 0) // Normal Mode { if (_VIF0chain() == -2) { @@ -1561,7 +1561,7 @@ void vif0Write32(u32 mem, u32 value) psHu64(VIF0_FIFO) = 0; psHu64(VIF0_FIFO + 8) = 0; // VIF0_FIFO + 8 vif0.done = true; - vif0Regs->err = 0; + vif0Regs->err._u32 = 0; vif0Regs->stat &= ~(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0 } @@ -1608,7 +1608,7 @@ void vif0Write32(u32 mem, u32 value) else _VIF0chain(); - CHCR::setSTR(vif0ch); + vif0ch->chcr.STR = 1; CPU_INT(0, g_vifCycles); // Gets the timing right - Flatout } } @@ -1620,7 +1620,7 @@ void vif0Write32(u32 mem, u32 value) VIF_LOG("VIF0_ERR write32 0x%8.8x", value); /* Set VIF0_ERR with 'value' */ - vif0Regs->err = value; + vif0Regs->err._u32 = value; break; case VIF0_R0: @@ -1862,7 +1862,7 @@ static int __fastcall Vif1TransDirectHL(u32 *data) if ((vif1.cmd & 0x7f) == 0x51) { - if (CHCR::STR(gif) && (!vif1Regs->mskpath3 && (Path3progress == IMAGE_MODE))) //PATH3 is in image mode, so wait for end of transfer + if (gif->chcr.STR && (!vif1Regs->mskpath3 && (Path3progress == IMAGE_MODE))) //PATH3 is in image mode, so wait for end of transfer { vif1Regs->stat |= VIF1_STAT_VGW; return 0; @@ -2068,7 +2068,7 @@ void Vif1MskPath3() // MSKPATH3 } static void Vif1CMDMskPath3() // MSKPATH3 { - if (CHCR::STR(vif1ch)) + if (vif1ch->chcr.STR) { schedulepath3msk = 0x10 | ((vif1Regs->code >> 15) & 0x1); vif1.vifstalled = true; @@ -2096,7 +2096,7 @@ static void Vif1CMDFlush() // FLUSH/E/A if ((vif1.cmd & 0x7f) == 0x13) { // Gif is already transferring so wait for it. - if (((Path3progress != STOPPED_MODE) || !vif1Regs->mskpath3) && CHCR::STR(gif)) + if (((Path3progress != STOPPED_MODE) || !vif1Regs->mskpath3) && gif->chcr.STR) { vif1Regs->stat |= VIF1_STAT_VGW; CPU_INT(2, 4); @@ -2157,7 +2157,7 @@ static void Vif1CMDNull() // invalid opcode { // if ME1, then force the vif to interrupt - if (!(VIF_ERR::ME1(vif1Regs))) //Ignore vifcode and tag mismatch error + if (!(vif1Regs->err.ME1)) //Ignore vifcode and tag mismatch error { Console::WriteLn("UNKNOWN VifCmd: %x\n", params vif1.cmd); vif1Regs->stat |= VIF1_STAT_ER1; @@ -2255,7 +2255,7 @@ int VIF1transfer(u32 *data, int size, int istag) if ((vif1.cmd & 0x7f) > 0x51) { - if (!(VIF_ERR::ME1(vif1Regs))) //Ignore vifcode and tag mismatch error + if (!(vif0Regs->err.ME1)) //Ignore vifcode and tag mismatch error { Console::WriteLn("UNKNOWN VifCmd: %x", params vif1.cmd); vif1Regs->stat |= VIF1_STAT_ER1; @@ -2273,7 +2273,7 @@ int VIF1transfer(u32 *data, int size, int istag) { vif1.cmd &= 0x7f; - if (!(VIF_ERR::MII(vif1Regs))) //i bit on vifcode and not masked by VIF1_ERR + if (!(vif1Regs->err.MII)) //i bit on vifcode and not masked by VIF1_ERR { VIF_LOG("Interrupt on VIFcmd: %x (INTC_MASK = %x)", vif1.cmd, psHu32(INTC_MASK)); @@ -2474,7 +2474,7 @@ __forceinline void vif1SetupTransfer() vif1.inprogress = 1; - if (CHCR::TTE(vif1ch)) + if (vif1ch->chcr.TTE) { if (vif1.vifstalled) @@ -2493,7 +2493,7 @@ __forceinline void vif1SetupTransfer() vif1.done |= hwDmacSrcChainWithStack(vif1ch, id); //Check TIE bit of CHCR and IRQ bit of tag - if ((CHCR::TIE(vif1ch)) && (Tag::IRQ(vif1ptag))) + if (vif1ch->chcr.TIE && (Tag::IRQ(vif1ptag))) { VIF_LOG("dmaIrq Set"); @@ -2514,7 +2514,7 @@ __forceinline void vif1Interrupt() if((vif1Regs->stat & VIF1_STAT_VGW)) { - if (CHCR::STR(gif)) + if (gif->chcr.STR) { CPU_INT(1, gif->qwc * BIAS); return; @@ -2523,7 +2523,7 @@ __forceinline void vif1Interrupt() } - if (!(CHCR::STR(vif1ch))) Console::WriteLn("Vif1 running when CHCR == %x", params vif1ch->chcr); + if (!(vif1ch->chcr.STR)) Console::WriteLn("Vif1 running when CHCR == %x", params vif1ch->chcr._u32); if (vif1.irq && vif1.tag.size == 0) { @@ -2535,7 +2535,7 @@ __forceinline void vif1Interrupt() 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); + vif1ch->chcr.STR = 0; return; } else if ((vif1ch->qwc > 0) || (vif1.irqoffset > 0)) @@ -2580,7 +2580,7 @@ __forceinline void vif1Interrupt() #endif vif1Regs->stat &= ~VIF1_STAT_VPS; //Vif goes idle as the stall happened between commands; - CHCR::clearSTR(vif1ch); + vif1ch->chcr.STR = 0; g_vifCycles = 0; hwDmacIrq(DMAC_VIF1); @@ -2588,7 +2588,7 @@ __forceinline void vif1Interrupt() //Games effected by setting, Fatal Frame, KH2, Shox, Crash N Burn, GT3/4 possibly //Im guessing due to the full gs fifo before the reverse? (Refraction) //Note also this is only the condition for reverse fifo mode, normal direction clears it as normal - if (!vif1Regs->mskpath3 || (CHCR::DIR(vif1ch))) vif1Regs->stat &= ~0x1F000000; // FQC=0 + if (!vif1Regs->mskpath3 || vif1ch->chcr.DIR) vif1Regs->stat &= ~0x1F000000; // FQC=0 } void dmaVIF1() @@ -2605,7 +2605,7 @@ void dmaVIF1() { //Console::WriteLn("VIFMFIFO\n"); // Test changed because the Final Fantasy 12 opening somehow has the tag in *Undefined* mode, which is not in the documentation that I saw. - if (CHCR::MOD(vif1ch) == NORMAL_MODE) Console::WriteLn("MFIFO mode is normal (which isn't normal here)! %x", params vif1ch->chcr); + if (vif1ch->chcr.MOD == NORMAL_MODE) Console::WriteLn("MFIFO mode is normal (which isn't normal here)! %x", params vif1ch->chcr); vifMFIFOInterrupt(); return; } @@ -2617,13 +2617,13 @@ void dmaVIF1() } #endif - if ((CHCR::MOD(vif1ch) == NORMAL_MODE) || vif1ch->qwc > 0) // Normal Mode + if ((vif1ch->chcr.MOD == NORMAL_MODE) || vif1ch->qwc > 0) // Normal Mode { if ((psHu32(DMAC_CTRL) & 0xC0) == 0x40) Console::WriteLn("DMA Stall Control on VIF1 normal"); - if ((CHCR::DIR(vif1ch))) // to Memory + if (vif1ch->chcr.DIR) // to Memory vif1.dmamode = VIF_NORMAL_TO_MEM_MODE; else vif1.dmamode = VIF_NORMAL_FROM_MEM_MODE; @@ -2672,10 +2672,10 @@ void vif1Write32(u32 mem, u32 value) { vif1Regs->mskpath3 = 0; psHu32(GIF_STAT) &= ~GIF_STAT_IMT; - if (CHCR::STR(gif)) CPU_INT(2, 4); + if (gif->chcr.STR) CPU_INT(2, 4); } - vif1Regs->err = 0; + vif1Regs->err._u32 = 0; vif1.inprogress = 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 } @@ -2731,7 +2731,7 @@ void vif1Write32(u32 mem, u32 value) // Gets the timing right - Flatout CPU_INT(1, vif1ch->qwc * BIAS); } - CHCR::setSTR(vif1ch); + vif1ch->chcr.STR = 1; } } } @@ -2741,7 +2741,7 @@ void vif1Write32(u32 mem, u32 value) VIF_LOG("VIF1_ERR write32 0x%8.8x", value); /* Set VIF1_ERR with 'value' */ - vif1Regs->err = value; + vif1Regs->err._u32 = value; break; case VIF1_STAT: // STAT From 4d7bfbb86e56968a10883ea3f3ced03b9814e772 Mon Sep 17 00:00:00 2001 From: arcum42 Date: Sat, 29 Aug 2009 00:37:34 +0000 Subject: [PATCH 10/14] Fixed typo. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1706 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/VifDma.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcsx2/VifDma.cpp b/pcsx2/VifDma.cpp index a0cf051cca..545017dcc8 100644 --- a/pcsx2/VifDma.cpp +++ b/pcsx2/VifDma.cpp @@ -1444,7 +1444,7 @@ void vif0Interrupt() if (!vif0ch->chcr.STR) Console::WriteLn("Vif0 running when CHCR = %x", params vif0ch->chcr._u32); - if ((vif0ch->chcr.STR == CHAIN_MODE) && (!vif0.done) && (!vif0.vifstalled)) + if ((vif0ch->chcr.MOD == CHAIN_MODE) && (!vif0.done) && (!vif0.vifstalled)) { if (!(psHu32(DMAC_CTRL) & 0x1)) From 2c1397e5595a0a87f91ac8fca20a1ac74eda2525 Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Sat, 29 Aug 2009 05:00:03 +0000 Subject: [PATCH 11/14] mVU Macro: Implemented more stuff and did a big cleanup. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1707 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/x86/microVU_Alloc.inl | 6 +- pcsx2/x86/microVU_Macro.inl | 624 +++++++++++------------------------- 2 files changed, 185 insertions(+), 445 deletions(-) diff --git a/pcsx2/x86/microVU_Alloc.inl b/pcsx2/x86/microVU_Alloc.inl index 1db752045c..bc4eb4f84f 100644 --- a/pcsx2/x86/microVU_Alloc.inl +++ b/pcsx2/x86/microVU_Alloc.inl @@ -87,11 +87,13 @@ microVUt(void) mVUallocMFLAGb(mV, int reg, int fInstance) { } microVUt(void) mVUallocCFLAGa(mV, int reg, int fInstance) { - MOV32MtoR(reg, (uptr)&mVU->clipFlag[fInstance]); + if (fInstance < 4) MOV32MtoR(reg, (uptr)&mVU->clipFlag[fInstance]); // microVU + else MOV32MtoR(reg, (uptr)&mVU->regs->VI[REG_CLIP_FLAG].UL); // macroVU } microVUt(void) mVUallocCFLAGb(mV, int reg, int fInstance) { - MOV32RtoM((uptr)&mVU->clipFlag[fInstance], reg); + if (fInstance < 4) MOV32RtoM((uptr)&mVU->clipFlag[fInstance], reg); // microVU + else MOV32RtoM((uptr)&mVU->regs->VI[REG_CLIP_FLAG].UL, reg); // macroVU } //------------------------------------------------------------------ diff --git a/pcsx2/x86/microVU_Macro.inl b/pcsx2/x86/microVU_Macro.inl index e95869c4fe..6ec4f9ac5f 100644 --- a/pcsx2/x86/microVU_Macro.inl +++ b/pcsx2/x86/microVU_Macro.inl @@ -25,319 +25,16 @@ 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 +// Macro VU - Helper Macros / Functions //------------------------------------------------------------------ using namespace R5900::Dynarec; +#define printCOP2 0&& +//#define printCOP2 DevCon::Status + void setupMacroOp(int mode, const char* opName) { - DevCon::Status(opName); + printCOP2(opName); microVU0.prog.IRinfo.curPC = 0; microVU0.code = cpuRegs.code; memset(µVU0.prog.IRinfo.info[0], 0, sizeof(microVU0.prog.IRinfo.info[0])); @@ -346,6 +43,10 @@ void setupMacroOp(int mode, const char* opName) { if (mode & 1) { // Q-Reg will be Read SSE_MOVSS_M32_to_XMM(xmmPQ, (uptr)µVU0.regs->VI[REG_Q].UL); } + if (mode & 8) { // Clip Instruction + microVU0.prog.IRinfo.info[0].cFlag.write = 0xff; + microVU0.prog.IRinfo.info[0].cFlag.lastWrite = 0xff; + } } void endMacroOp(int mode) { @@ -356,7 +57,7 @@ void endMacroOp(int mode) { } #define REC_COP2_mVU0(f, opName, mode) \ - void recV##f(s32 info) { \ + void recV##f() { \ setupMacroOp(mode, opName); \ if (mode & 4) { \ mVU_##f(µVU0, 0); \ @@ -368,6 +69,19 @@ void endMacroOp(int mode) { endMacroOp(mode); \ } +#define INTERPRETATE_COP2_FUNC(f) \ + void recV##f() { \ + MOV32ItoM((uptr)&cpuRegs.code, cpuRegs.code); \ + MOV32ItoM((uptr)&cpuRegs.pc, pc); \ + iFlushCall(FLUSH_EVERYTHING); \ + CALLFunc((uptr)V##f); \ + _freeX86regs(); \ + } + +//------------------------------------------------------------------ +// Macro VU - Instructions +//------------------------------------------------------------------ + //------------------------------------------------------------------ // Macro VU - Redirect Upper Instructions //------------------------------------------------------------------ @@ -465,7 +179,7 @@ REC_COP2_mVU0(MSUBAz, "MSUBAz", 0); REC_COP2_mVU0(MSUBAw, "MSUBAw", 0); REC_COP2_mVU0(OPMULA, "OPMULA", 0); REC_COP2_mVU0(OPMSUB, "OPMSUB", 0); -REC_COP2_VU0 (CLIP); +REC_COP2_mVU0(CLIP, "CLIP", 8); //------------------------------------------------------------------ // Macro VU - Redirect Lower Instructions @@ -498,8 +212,8 @@ REC_COP2_mVU0(RXOR, "RXOR", 0); // Macro VU - Misc... //------------------------------------------------------------------ -void recVNOP (s32 info) {} -void recVWAITQ(s32 info) {} +void recVNOP() {} +void recVWAITQ(){} INTERPRETATE_COP2_FUNC(CALLMS); INTERPRETATE_COP2_FUNC(CALLMSR); @@ -507,166 +221,190 @@ INTERPRETATE_COP2_FUNC(CALLMSR); // Macro VU - Branches //------------------------------------------------------------------ -static void _setupBranchTest() { +void _setupBranchTest(u32*(jmpType)(u32), bool isLikely) { + printCOP2("COP2 Branch"); _eeFlushAllUnused(); TEST32ItoM((uptr)&VU0.VI[REG_VPU_STAT].UL, 0x100); + recDoBranchImm(jmpType(0), isLikely); } -void recBC2F(s32 info) { - _setupBranchTest(); - recDoBranchImm(JNZ32(0)); +void recBC2F() { _setupBranchTest(JNZ32, false); } +void recBC2T() { _setupBranchTest(JZ32, false); } +void recBC2FL() { _setupBranchTest(JNZ32, true); } +void recBC2TL() { _setupBranchTest(JZ32, true); } + +//------------------------------------------------------------------ +// Macro VU - COP2 Transfer Instructions +//------------------------------------------------------------------ + +void COP2_Interlock(bool cond) { + if (cond) { + iFlushCall(FLUSH_NOCONST); + CALLFunc((uptr)_vu0WaitMicro); + } } -void recBC2T(s32 info) { - _setupBranchTest(); - recDoBranchImm(JZ32(0)); +void TEST_FBRST_RESET(uptr resetFunct, int vuIndex) { + TEST32ItoR(EAX, (vuIndex) ? 0x200 : 0x002); + j8Ptr[0] = JZ8(0); + CALLFunc(resetFunct); + MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]); + x86SetJ8(j8Ptr[0]); } -void recBC2FL(s32 info) { - _setupBranchTest(); - recDoBranchImm_Likely(JNZ32(0)); +static void recCFC2() { + + printCOP2("CFC2"); + COP2_Interlock(cpuRegs.code & 1); + if (!_Rt_) return; + iFlushCall(FLUSH_EVERYTHING); + + MOV32MtoR(EAX, (uptr)µVU0.regs->VI[_Rd_].UL); + MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], EAX); + + if( _Rd_ >= 16 ) { + CDQ(); // Sign Extend + MOV32RtoM ((uptr)&cpuRegs.GPR.r[_Rt_].UL[1], EDX); + } + else MOV32ItoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[1], 0); + + // FixMe: I think this is needed, but not sure how it works + _eeOnWriteReg(_Rt_, 1); } -void recBC2TL(s32 info) { - _setupBranchTest(); - recDoBranchImm_Likely(JZ32(0)); +static void recCTC2() { + + printCOP2("CTC2"); + COP2_Interlock(cpuRegs.code & 1); + if (!_Rd_) return; + iFlushCall(FLUSH_EVERYTHING); + + switch(_Rd_) { + case REG_MAC_FLAG: case REG_TPC: + case REG_VPU_STAT: break; // Read Only Regs + case REG_R: + MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]); + OR32ItoR (EAX, 0x3f800000); + MOV32RtoM((uptr)µVU0.regs->VI[REG_R].UL, EAX); + break; + case REG_CMSAR1: // REG_CMSAR1 + if (_Rt_) { + MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]); + PUSH32R(EAX); + } + else PUSH32I(0); + CALLFunc((uptr)vu1ExecMicro); // Execute VU1 Micro SubRoutine + ADD32ItoR(ESP, 4); + break; + case REG_FBRST: + if (!_Rt_) { + MOV32ItoM((uptr)µVU0.regs->VI[REG_FBRST].UL, 0); + return; + } + else MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]); + + TEST_FBRST_RESET((uptr)vu0ResetRegs, 0); + TEST_FBRST_RESET((uptr)vu1ResetRegs, 1); + + AND32ItoR(EAX, 0x0C0C); + MOV32RtoM((uptr)µVU0.regs->VI[REG_FBRST].UL, EAX); + break; + default: + _eeMoveGPRtoM((uptr)µVU0.regs->VI[_Rd_].UL, _Rt_); + break; + } +} + +static void recQMFC2() { + + printCOP2("QMFC2"); + COP2_Interlock(cpuRegs.code & 1); + if (!_Rt_) return; + iFlushCall(FLUSH_EVERYTHING); + + // FixMe: For some reason this line is needed or else games break: + _eeOnWriteReg(_Rt_, 0); + + SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)µVU0.regs->VF[_Rd_].UL[0]); + SSE_MOVAPS_XMM_to_M128((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], xmmT1); +} + +static void recQMTC2() { + + printCOP2("QMTC2"); + COP2_Interlock(cpuRegs.code & 1); + if (!_Rd_) return; + iFlushCall(FLUSH_EVERYTHING); + + SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]); + SSE_MOVAPS_XMM_to_M128((uptr)µVU0.regs->VF[_Rd_].UL[0], xmmT1); } //------------------------------------------------------------------ // Macro VU - Tables //------------------------------------------------------------------ -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 recCOP2(); +void recCOP2_BC2(); +void recCOP2_SPEC1(); +void recCOP2_SPEC2(); +void rec_C2UNK() { + Console::Error("Cop2 bad opcode: %x", params cpuRegs.code); } -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); } +// This is called by EE Recs to setup sVU info, this isn't needed for mVU Macro (cottonvibes) +void _vuRegsCOP22(VURegs* VU, _VURegsNum* 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 (*recCOP2t[32])() = { + 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_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, + recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, recCOP2_SPEC1, }; -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 (*recCOP2_BC2t[32])() = { + 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 (*recCOP2SPECIAL1t[64])() = { + 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_SPEC2, recCOP2_SPEC2, recCOP2_SPEC2, recCOP2_SPEC2, }; -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, +void (*recCOP2SPECIAL2t[128])() = { + 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); } +namespace OpcodeImpl { void recCOP2() { recCOP2t[_Rs_](); }}}} +void recCOP2_BC2 () { recCOP2_BC2t[_Rt_](); } +void recCOP2_SPEC1() { recCOP2SPECIAL1t[_Funct_](); } +void recCOP2_SPEC2() { recCOP2SPECIAL2t[(cpuRegs.code&3)|((cpuRegs.code>>4)&0x7c)](); } #endif // CHECK_MACROVU0 From fd480496c4dcbea4f013cc5aa341389021fe8315 Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Sat, 29 Aug 2009 20:11:38 +0000 Subject: [PATCH 12/14] mVU Macro: Some changes for a more correct interlocking behavior again VU0 micro programs. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1708 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/VU0.cpp | 38 +++++++++++++++++-------------------- pcsx2/x86/microVU_Macro.inl | 16 +++++++++------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/pcsx2/VU0.cpp b/pcsx2/VU0.cpp index 8659d12603..a896c540e1 100644 --- a/pcsx2/VU0.cpp +++ b/pcsx2/VU0.cpp @@ -66,35 +66,31 @@ void COP2_Unknown() } //**************************************************************************** -void _vu0WaitMicro() { - int startcycle; + +__forceinline void _vu0run(bool breakOnMbit) { - if ((VU0.VI[REG_VPU_STAT].UL & 0x1) == 0) { - return; - } + if (!(VU0.VI[REG_VPU_STAT].UL & 1)) return; - startcycle = VU0.cycle; + int startcycle = VU0.cycle; + VU0.flags &= ~VUFLAG_MFLAGSET; - VU0.flags|= VUFLAG_BREAKONMFLAG; - VU0.flags&= ~VUFLAG_MFLAGSET; - - 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! + do { + // knockout kings 2002 loops here with sVU + if (breakOnMbit && (VU0.cycle-startcycle > 0x1000)) { + Console::Notice("VU0 perma-stall, breaking execution..."); + break; // mVU will never get here (it handles mBit internally) + } + CpuVU0.ExecuteBlock(); + } while ((VU0.VI[REG_VPU_STAT].UL & 1) // E-bit Termination + && (!breakOnMbit || !(VU0.flags & VUFLAG_MFLAGSET))); // M-bit Break //NEW cpuRegs.cycle += (VU0.cycle-startcycle)*2; - VU0.flags&= ~VUFLAG_BREAKONMFLAG; } +void _vu0WaitMicro() { _vu0run(1); } // Runs VU0 Micro Until E-bit or M-Bit End +void _vu0FinishMicro() { _vu0run(0); } // Runs VU0 Micro Until E-Bit End + namespace R5900 { namespace Interpreter{ namespace OpcodeImpl diff --git a/pcsx2/x86/microVU_Macro.inl b/pcsx2/x86/microVU_Macro.inl index 6ec4f9ac5f..0e9bee6a4b 100644 --- a/pcsx2/x86/microVU_Macro.inl +++ b/pcsx2/x86/microVU_Macro.inl @@ -23,6 +23,7 @@ #include "R5900OpcodeTables.h" extern void _vu0WaitMicro(); +extern void _vu0FinishMicro(); //------------------------------------------------------------------ // Macro VU - Helper Macros / Functions @@ -237,10 +238,11 @@ void recBC2TL() { _setupBranchTest(JZ32, true); } // Macro VU - COP2 Transfer Instructions //------------------------------------------------------------------ -void COP2_Interlock(bool cond) { - if (cond) { +void COP2_Interlock(bool mBitSync) { + if (cpuRegs.code & 1) { iFlushCall(FLUSH_NOCONST); - CALLFunc((uptr)_vu0WaitMicro); + if (mBitSync) CALLFunc((uptr)_vu0WaitMicro); + else CALLFunc((uptr)_vu0FinishMicro); } } @@ -255,7 +257,7 @@ void TEST_FBRST_RESET(uptr resetFunct, int vuIndex) { static void recCFC2() { printCOP2("CFC2"); - COP2_Interlock(cpuRegs.code & 1); + COP2_Interlock(0); if (!_Rt_) return; iFlushCall(FLUSH_EVERYTHING); @@ -275,7 +277,7 @@ static void recCFC2() { static void recCTC2() { printCOP2("CTC2"); - COP2_Interlock(cpuRegs.code & 1); + COP2_Interlock(1); if (!_Rd_) return; iFlushCall(FLUSH_EVERYTHING); @@ -318,7 +320,7 @@ static void recCTC2() { static void recQMFC2() { printCOP2("QMFC2"); - COP2_Interlock(cpuRegs.code & 1); + COP2_Interlock(0); if (!_Rt_) return; iFlushCall(FLUSH_EVERYTHING); @@ -332,7 +334,7 @@ static void recQMFC2() { static void recQMTC2() { printCOP2("QMTC2"); - COP2_Interlock(cpuRegs.code & 1); + COP2_Interlock(1); if (!_Rd_) return; iFlushCall(FLUSH_EVERYTHING); From e879890d2a453b06eed247f099637e90d8c1d695 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Sat, 29 Aug 2009 20:45:19 +0000 Subject: [PATCH 13/14] Installer Improvements: * installer will automatically version itself to the svn checkout * default installation folder, filenames, and links all contain the revision number now. * Plugins are optionally included into the package (details in txt) * VC++ Redist detection: the Redist installer is only extracted/invoked if it's not already installed. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1709 96395faa-99c1-11dd-bbfe-3dabce05a288 --- nsis/nsis_instructions.txt | 53 ++++++-- nsis/pcsx2_installer_script.nsi | 205 +++++++++++++++++++++-------- nsis/templates/svnrev_cdvdiso.nsh | 1 + nsis/templates/svnrev_gsdx.nsh | 1 + nsis/templates/svnrev_lilypad.nsh | 1 + nsis/templates/svnrev_pcsx2.nsh | 3 + nsis/templates/svnrev_spu2x.nsh | 1 + nsis/templates/svnrev_zerogs.nsh | 1 + nsis/templates/svnrev_zerospu2.nsh | 1 + 9 files changed, 203 insertions(+), 64 deletions(-) create mode 100644 nsis/templates/svnrev_cdvdiso.nsh create mode 100644 nsis/templates/svnrev_gsdx.nsh create mode 100644 nsis/templates/svnrev_lilypad.nsh create mode 100644 nsis/templates/svnrev_pcsx2.nsh create mode 100644 nsis/templates/svnrev_spu2x.nsh create mode 100644 nsis/templates/svnrev_zerogs.nsh create mode 100644 nsis/templates/svnrev_zerospu2.nsh diff --git a/nsis/nsis_instructions.txt b/nsis/nsis_instructions.txt index a6f995be47..8555a26a6d 100644 --- a/nsis/nsis_instructions.txt +++ b/nsis/nsis_instructions.txt @@ -1,10 +1,45 @@ -Instruction for installations: +------------------------------------- + PCSX2 NSIS Installer Instructions +------------------------------------- -Install NSIS (tested with 2.45) -Install NSIS Script Advanced Uninstall Log NSIS Header (you can find it opn NSIS wiki) -Create a folder -Put the nsis script in said folder -Put vcredist_x86.exe in said folder -Put the pcsx2 folder in said folder (warning, leave only the files you want in the installer. All files from the pcsx2 folder will be added to the installer ) -Edit the NSIS script with a text editor, changing the installer name and putting the correct name for the menu item (2 times, both filename and link name) -Compile the NSIS script + * Install NSIS (tested with 2.45) + * Install NSIS Script: Advanced Uninstall Log (you can find it on NSIS wiki) + + * Download the latest Visual C++ Redistributable (currently 2008 SP1 as of this writing) and + save it to this nsis/ folder. + + * Load the PCSX2 Suite solution and rebuild all in the following targets: + * Release SSE2 + * Release SSSE3 (only needed if packaging plugins) + * Release SSE4 (only needed if packaging plugins) + * Devel (optional) + + You may selectively unload plugins you do not wish to package prior to running the NSIS + script. + + * Compile script, and Enjoy :) + + +-------------------------------------------- + Compilation Targets and Plugin Inclusion +-------------------------------------------- + +pcsx2-dev.exe is included into the installer as well *if* present (but is not required). +The Release mode (without -dev) is required, and the script errors if it's missing. + +To include non-NULL plugins into the installer you must specify /DINC_PLUGINS on the command +line when compiling the script. The installer will include plugins only if they are present. +If you do not build plugins, or remove some (or all) plugins before running the nsis script, +only PCSX2 and whatever remaining plugins will be packaged. + +GSdx SSE2, SSSE3, and SSE4 versions are all included into the installer *if* they are present. +You will need to follow the above instructions and compile all release targets to get all the +GSdx DLLs. + +-------------------------------------------- + TODO / Wish List!! +-------------------------------------------- + + * pcsx2-dev should probably be an optional section, conditionally scripted only if the + file is present at compilation time, and packaged. + \ No newline at end of file diff --git a/nsis/pcsx2_installer_script.nsi b/nsis/pcsx2_installer_script.nsi index fa4a69b775..9c4ad00f6e 100644 --- a/nsis/pcsx2_installer_script.nsi +++ b/nsis/pcsx2_installer_script.nsi @@ -1,30 +1,78 @@ -; Pcsx2 NSIS installer script +; PCSX2 NSIS installer script ; loosely based on a collection of examples and on information from the wikipedia -!define APP_NAME "Pcsx2 - A Playstation 2 Emulator" +; Application version, changed for each release to match the verision + +; ---------------------------------------- +; Determine the revision numbers of the various components + +!system 'SubWCRev.exe ..\pcsx2 templates\svnrev_pcsx2.nsh svnrev_pcsx2.nsh' + +!ifdef INC_PLUGINS + !system 'SubWCRev.exe ..\plugins\gsdx templates\svnrev_gsdx.nsh svnrev_gsdx.nsh' + !system 'SubWCRev.exe ..\plugins\spu2-x templates\svnrev_spu2x.nsh svnrev_spu2x.nsh' + !system 'SubWCRev.exe ..\plugins\cdvdiso templates\svnrev_cdvdiso.nsh svnrev_cdvdiso.nsh' + !system 'SubWCRev.exe ..\plugins\lilypad templates\svnrev_lilypad.nsh svnrev_lilypad.nsh' + !system 'SubWCRev.exe ..\plugins\zerogs\dx templates\svnrev_zerogs.nsh svnrev_zerogs.nsh' + !system 'SubWCRev.exe ..\plugins\zerospu2 templates\svnrev_zerospu2.nsh svnrev_zerospu2.nsh' +!endif + +!include "svnrev_pcsx2.nsh" + +!ifdef INC_PLUGINS + !include "svnrev_gsdx.nsh" + !include "svnrev_spu2x.nsh" + !include "svnrev_cdvdiso.nsh" + !include "svnrev_lilypad.nsh" + !include "svnrev_zerogs.nsh" + !include "svnrev_zerospu2.nsh" +!endif + +; ---------------------------------------- + +!define APP_NAME "PCSX2 Beta r${SVNREV}" + !define INSTDIR_REG_ROOT "HKLM" -!define INSTDIR_REG_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" +!define INSTDIR_REG_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\PCSX2-beta-r${SVNREV}" -;-------------------------------- -;Include Modern UI 2 and advanced log uninstaller. all credits to the respective authors - !include "MUI2.nsh" - !include "AdvUninstLog.nsh" +; ---------------------------------------- +; Include Modern UI 2 and advanced log uninstaller. -;-------------------------------- +!include "MUI2.nsh" +!include "AdvUninstLog.nsh" +; ------------------------------------- +; Test if Visual Studio Redistributables 2008 SP1 installed +; Returns -1 if there is no VC redistributables intstalled +; +Function CheckVCRedist + + Push $R0 + ClearErrors + ReadRegDword $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{9A25302D-30C0-39D9-BD6F-21E6EC160475}" "Version" + + ; if VS 2005+ redist SP1 not installed, install it + IfErrors 0 VSRedistInstalled + StrCpy $R0 "-1" + +VSRedistInstalled: + Exch $R0 + +FunctionEnd + +; ---------------------------------------- ; The name of the installer -Name "Pcsx2" +Name "PCSX2 Beta r${SVNREV}" -; The file to write. To change each release -OutFile "Pcsx2-beta-1474-setup.exe" +OutFile "pcsx2-beta-${SVNREV}-setup.exe" ; The default installation directory -InstallDir "$PROGRAMFILES\Pcsx2" +InstallDir "$PROGRAMFILES\pcsx2-r${SVNREV}" ; Registry key to check for directory (so if you install again, it will ; overwrite the old one automatically) -InstallDirRegKey HKLM "Software\Pcsx2" "Install_Dir" +InstallDirRegKey HKLM "Software\pcsx2" "Install_Dir" ; Request application privileges for Windows Vista RequestExecutionLevel admin @@ -42,50 +90,98 @@ RequestExecutionLevel admin !insertmacro MUI_UNPAGE_INSTFILES -;-------------------------------- - +; ---------------------------------------- ; Basic section (emulation proper) -Section "Pcsx2 (required)" +Section "PCSX2 Beta r${SVNREV} (required)" SectionIn RO - ; Set output path to the installation directory. - SetOutPath $INSTDIR - ; Put file there. It's catched by the uninstaller script + SetOutPath $INSTDIR !insertmacro UNINSTALL.LOG_OPEN_INSTALL - File /r "Pcsx2\" + + SetOutPath $INSTDIR + File /oname=pcsx2-r${SVNREV}.exe ..\bin\pcsx2.exe + File ..\bin\w32pthreads.dll + File ..\bin\gnu_gettext.dll + + File /nonfatal /oname=pcsx2-dev-r${SVNREV}.exe ..\bin\pcsx2-dev.exe + + SetOutPath $INSTDIR\Langs + File /r ..\bin\Langs\*.mo + + SetOutPath $INSTDIR\Patches + File /r ..\bin\Patches\*.pnach + + ; NULL plugins are required, and really there should be more but we don't have working + ; SPU2 or GS null plugins right now. + + File ..\bin\Plugins\USBnull.dll + File ..\bin\Plugins\DEV9null.dll + File ..\bin\Plugins\FWnull.dll + File ..\bin\Plugins\CDVDnull.dll + +!ifdef INC_PLUGINS + SetOutPath $INSTDIR\Plugins + File /nonfatal /oname=gsdx-sse2-r${SVNREV_GSDX}.dll ..\bin\Plugins\gsdx-sse2.dll + File /nonfatal /oname=gsdx-ssse3-r${SVNREV_GSDX}.dll ..\bin\Plugins\gsdx-ssse3.dll + File /nonfatal /oname=gsdx-sse4-r${SVNREV_GSDX}.dll ..\bin\Plugins\gsdx-sse4.dll + File /nonfatal /oname=spu2-x-r${SVNREV_SPU2X}.dll ..\bin\Plugins\spu2-x.dll + File /nonfatal /oname=cdvdiso-r${SVNREV_CDVDISO}.dll ..\bin\Plugins\cdvdiso.dll + File /nonfatal /oname=lilypad-r${SVNREV_LILYPAD}.dll ..\bin\Plugins\lilypad.dll + + File /nonfatal /oname=zerogs-r${SVNREV_ZEROGS}.dll ..\bin\Plugins\zerogs.dll + File /nonfatal /oname=zerospu2-r${SVNREV_ZEROSPU2}.dll ..\bin\Plugins\zerospu2.dll +!endif + + SetOutPath $INSTDIR !insertmacro UNINSTALL.LOG_CLOSE_INSTALL ; Write the installation path into the registry - WriteRegStr HKLM Software\Pcsx2 "Install_Dir" "$INSTDIR" + WriteRegStr HKLM Software\pcsx2 "Install_Dir" "$INSTDIR" ; Write the uninstall keys for Windows - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pcsx2" "DisplayName" "Pcsx2 - Playstation 2 Emulator" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pcsx2" "UninstallString" '"$INSTDIR\uninstall.exe"' - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pcsx2" "NoModify" 1 - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pcsx2" "NoRepair" 1 - WriteUninstaller "uninstall.exe" - + WriteRegStr HKLM "${INSTDIR_REG_KEY}" "DisplayName" "PCSX2 - Playstation 2 Emulator" + WriteRegStr HKLM "${INSTDIR_REG_KEY}" "UninstallString" '"$INSTDIR\uninstall-r${SVNREV}.exe"' + WriteRegDWORD HKLM "${INSTDIR_REG_KEY}" "NoModify" 1 + WriteRegDWORD HKLM "${INSTDIR_REG_KEY}" "NoRepair" 1 + WriteUninstaller "uninstall-r${SVNREV}.exe" + SectionEnd +; ---------------------------------------- +; MSVC Redistributable - required if the user des not already have it +; Note: if your NSIS generates an error here it means you need to download the latest +; visual studio redist package from microsoft. Any redist 2008/SP1 or newer will do. +Section "Microsoft Visual C++ 2008 SP1 Redist (required)" + + SectionIn RO + SetOutPath $TEMP + File "vcredist_x86.exe" + Call CheckVCRedist + StrCmp $R0 "-1" installRedist + DetailPrint "Visual C++ 2008 SP1 Redistributable already installed, skipping..." + Goto skipRedist + + installRedist: + ExecWait "$TEMP\vcredist_x86.exe" + +SkipRedist: +SectionEnd + +; ---------------------------------------- ; Optional sections (can be disabled by the user) Section "Start Menu Shortcuts" + SetOutPath $INSTDIR + ; Need to change name too, for each version - CreateDirectory "$SMPROGRAMS\Pcsx2" - CreateShortCut "$SMPROGRAMS\Pcsx2\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 - CreateShortCut "$SMPROGRAMS\Pcsx2\Pcsx2.lnk" "$INSTDIR\pcsx2-beta-1474.exe" "" "$INSTDIR\pcsx2-beta-1474.exe" 0 - -SectionEnd + CreateDirectory "$SMPROGRAMS\pcsx2" + CreateShortCut "$SMPROGRAMS\pcsx2\Uninstall-r${SVNREV}.lnk" "$INSTDIR\uninstall-r${SVNREV}.exe" "" "$INSTDIR\uninstall-r${SVNREV}.exe" 0 + CreateShortCut "$SMPROGRAMS\pcsx2\pcsx2-r${SVNREV}.lnk" "$INSTDIR\pcsx2-r${SVNREV}.exe" "" "$INSTDIR\pcsx2-r${SVNREV}.exe" 0 + CreateShortCut "$SMPROGRAMS\pcsx2\pcsx2-dev-r${SVNREV}.lnk" "$INSTDIR\pcsx2-dev-r${SVNREV}.exe" "" "$INSTDIR\pcsx2-dev-r${SVNREV}.exe" 0 "" "" \ + "PCSX2 Devel (has debugging and memory dumping)" -; Optional, but required if you don't already have it -Section "Microsoft Visual C++ 2008 SP1 Redist(Required)" - - SetOutPath $TEMP - File "vcredist_x86.exe" - ExecWait "$TEMP\vcredist_x86.exe" - SectionEnd ;-------------------------------- @@ -105,38 +201,36 @@ Function .onInstSuccess FunctionEnd -;-------------------------------- - - +; -------------------------------------- ; Uninstaller -Section "Un.Standard uninstallation (Leaves user created files untouched)" - +Section "Un.Safe uninstall (Removes only files installed by this installer)" + ; Remove registry keys - DeleteRegKey HKLM Software\Microsoft\Windows\CurrentVersion\Uninstall\Pcsx2 - DeleteRegKey HKLM Software\Pcsx2 + DeleteRegKey HKLM ${INSTDIR_REG_KEY} + DeleteRegKey HKLM Software\pcsx2 ; Remove shortcuts, if any - Delete "$SMPROGRAMS\Pcsx2\*.*" - RMDir "$SMPROGRAMS\Pcsx2" - + Delete "$SMPROGRAMS\pcsx2\*.*" + RMDir "$SMPROGRAMS\pcsx2" + !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR" DeleteRegKey ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" SectionEnd ; This option lets you COMPLETELY uninstall by deleting the main folder. Caution! :) -Section /o "Un.Complete Uninstall. WARNING, this will delete every file in the program folder" +Section /o "Un.Complete Uninstall. *Completely* removes all files and folders." - MessageBox MB_YESNO "You have chosen to remove ALL files in the installation folder. This will remove all your saves, screenshots, patches and bios as well. Do you want to proceed?" IDYES true IDNO false + MessageBox MB_YESNO "WANRING! You have chosen to remove ALL files in the installation folder, including all saves, screenshots, plugins, patches, and bios files. Do you want to proceed?" IDYES true IDNO false true: - Delete "$SMPROGRAMS\Pcsx2\*.*" - RMDir "$SMPROGRAMS\Pcsx2" + Delete "$SMPROGRAMS\pcsx2\*.*" + RMDir "$SMPROGRAMS\pcsx2" RMDir /r "$INSTDIR" DeleteRegKey ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" false: - + SectionEnd Function UN.onInit @@ -144,4 +238,5 @@ Function UN.onInit ;begin uninstall, could be added on top of uninstall section instead !insertmacro UNINSTALL.LOG_BEGIN_UNINSTALL -FunctionEnd \ No newline at end of file +FunctionEnd + diff --git a/nsis/templates/svnrev_cdvdiso.nsh b/nsis/templates/svnrev_cdvdiso.nsh new file mode 100644 index 0000000000..cf0d8ac873 --- /dev/null +++ b/nsis/templates/svnrev_cdvdiso.nsh @@ -0,0 +1 @@ +!define SVNREV_CDVDISO $WCREV$ \ No newline at end of file diff --git a/nsis/templates/svnrev_gsdx.nsh b/nsis/templates/svnrev_gsdx.nsh new file mode 100644 index 0000000000..f7e81143e3 --- /dev/null +++ b/nsis/templates/svnrev_gsdx.nsh @@ -0,0 +1 @@ +!define SVNREV_GSDX $WCREV$ diff --git a/nsis/templates/svnrev_lilypad.nsh b/nsis/templates/svnrev_lilypad.nsh new file mode 100644 index 0000000000..383e8131d2 --- /dev/null +++ b/nsis/templates/svnrev_lilypad.nsh @@ -0,0 +1 @@ +!define SVNREV_LILYPAD $WCREV$ \ No newline at end of file diff --git a/nsis/templates/svnrev_pcsx2.nsh b/nsis/templates/svnrev_pcsx2.nsh new file mode 100644 index 0000000000..d669b4624f --- /dev/null +++ b/nsis/templates/svnrev_pcsx2.nsh @@ -0,0 +1,3 @@ + +!define SVNREV $WCREV$ +!define SVN_MODS $WCMODS?1:0$ \ No newline at end of file diff --git a/nsis/templates/svnrev_spu2x.nsh b/nsis/templates/svnrev_spu2x.nsh new file mode 100644 index 0000000000..f24947e1d5 --- /dev/null +++ b/nsis/templates/svnrev_spu2x.nsh @@ -0,0 +1 @@ +!define SVNREV_SPU2X $WCREV$ \ No newline at end of file diff --git a/nsis/templates/svnrev_zerogs.nsh b/nsis/templates/svnrev_zerogs.nsh new file mode 100644 index 0000000000..4662beb378 --- /dev/null +++ b/nsis/templates/svnrev_zerogs.nsh @@ -0,0 +1 @@ +!define SVNREV_ZEROGS $WCREV$ \ No newline at end of file diff --git a/nsis/templates/svnrev_zerospu2.nsh b/nsis/templates/svnrev_zerospu2.nsh new file mode 100644 index 0000000000..2b35a869ae --- /dev/null +++ b/nsis/templates/svnrev_zerospu2.nsh @@ -0,0 +1 @@ +!define SVNREV_ZEROSPU2 $WCREV$ \ No newline at end of file From 7c7dfa2f5892a1907d07347bac1a5e59ba3c649f Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Sat, 29 Aug 2009 23:07:03 +0000 Subject: [PATCH 14/14] Finished mVU macro, and set it on by default. Basically this means whenever COP2 recs are used, its calling mVU instructions instead of sVU instructions. Note: Theres a very-minor incompatibility problem when using interpreters/sVU for VU0 with mVU Macro. But I'll fix it later (and it probably doesn't effect much). git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1710 96395faa-99c1-11dd-bbfe-3dabce05a288 --- common/include/Pcsx2Config.h | 2 +- pcsx2/x86/microVU_Alloc.inl | 26 +++++++++++++++++++++++- pcsx2/x86/microVU_Branch.inl | 5 +++++ pcsx2/x86/microVU_Execute.inl | 21 ++++++-------------- pcsx2/x86/microVU_Macro.inl | 37 +++++++++++++++++++++++++++++------ 5 files changed, 68 insertions(+), 23 deletions(-) diff --git a/common/include/Pcsx2Config.h b/common/include/Pcsx2Config.h index ce8b9b2c12..b1d69d4e4e 100644 --- a/common/include/Pcsx2Config.h +++ b/common/include/Pcsx2Config.h @@ -61,7 +61,7 @@ extern SessionOverrideFlags g_Session; #define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD) #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_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/x86/microVU_Alloc.inl b/pcsx2/x86/microVU_Alloc.inl index bc4eb4f84f..dd40b4b6f3 100644 --- a/pcsx2/x86/microVU_Alloc.inl +++ b/pcsx2/x86/microVU_Alloc.inl @@ -77,13 +77,37 @@ microVUt(void) mVUallocSFLAGc(int reg, int regT, int fInstance) { OR32RtoR(reg, regT); } +// Denormalizes Status Flag +microVUt(void) mVUallocSFLAGd(uptr memAddr, bool setAllflags) { + MOV32MtoR(gprF0, memAddr); + MOV32RtoR(gprF1, gprF0); + SHR32ItoR(gprF1, 3); + AND32ItoR(gprF1, 0x18); + + MOV32RtoR(gprF2, gprF0); + SHL32ItoR(gprF2, 11); + AND32ItoR(gprF2, 0x1800); + OR32RtoR (gprF1, gprF2); + + SHL32ItoR(gprF0, 14); + AND32ItoR(gprF0, 0x3cf0000); + OR32RtoR (gprF1, gprF0); + + if (setAllflags) { + MOV32RtoR(gprF0, gprF1); + MOV32RtoR(gprF2, gprF1); + MOV32RtoR(gprF3, gprF1); + } +} + microVUt(void) mVUallocMFLAGa(mV, int reg, int fInstance) { MOVZX32M16toR(reg, (uptr)&mVU->macFlag[fInstance]); } microVUt(void) mVUallocMFLAGb(mV, int reg, int fInstance) { //AND32ItoR(reg, 0xffff); - MOV32RtoM((uptr)&mVU->macFlag[fInstance], reg); + if (fInstance < 4) MOV32RtoM((uptr)&mVU->macFlag[fInstance], reg); // microVU + else MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, reg); // macroVU } microVUt(void) mVUallocCFLAGa(mV, int reg, int fInstance) { diff --git a/pcsx2/x86/microVU_Branch.inl b/pcsx2/x86/microVU_Branch.inl index 054446c567..7fe9c8c723 100644 --- a/pcsx2/x86/microVU_Branch.inl +++ b/pcsx2/x86/microVU_Branch.inl @@ -59,8 +59,13 @@ microVUt(void) mVUendProgram(mV, microFlagCycles* mFC, int isEbit) { } // Save Flag Instances +#ifdef CHECK_MACROVU0 + getFlagReg(fStatus, fStatus); + MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, fStatus); +#else mVUallocSFLAGc(gprT1, gprT2, fStatus); MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, gprT1); +#endif mVUallocMFLAGa(mVU, gprT1, fMac); mVUallocCFLAGa(mVU, gprT2, fClip); MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, gprT1); diff --git a/pcsx2/x86/microVU_Execute.inl b/pcsx2/x86/microVU_Execute.inl index 1e4c105820..ca29e10469 100644 --- a/pcsx2/x86/microVU_Execute.inl +++ b/pcsx2/x86/microVU_Execute.inl @@ -40,24 +40,15 @@ void mVUdispatcherA(mV) { SSE_LDMXCSR((uptr)&g_sseVUMXCSR); // Load Regs +#ifdef CHECK_MACROVU0 MOV32MtoR(gprF0, (uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL); MOV32RtoR(gprF1, gprF0); - SHR32ItoR(gprF1, 3); - AND32ItoR(gprF1, 0x18); - MOV32RtoR(gprF2, gprF0); - SHL32ItoR(gprF2, 11); - AND32ItoR(gprF2, 0x1800); - OR32RtoR (gprF1, gprF2); - - SHL32ItoR(gprF0, 14); - AND32ItoR(gprF0, 0x3cf0000); - OR32RtoR (gprF1, gprF0); - - MOV32RtoR(gprF0, gprF1); - MOV32RtoR(gprF2, gprF1); - MOV32RtoR(gprF3, gprF1); - + MOV32RtoR(gprF3, gprF0); +#else + mVUallocSFLAGd((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, 1); +#endif + SSE_MOVAPS_M128_to_XMM(xmmT1, (uptr)&mVU->regs->VI[REG_MAC_FLAG].UL); SSE_SHUFPS_XMM_to_XMM (xmmT1, xmmT1, 0); SSE_MOVAPS_XMM_to_M128((uptr)mVU->macFlag, xmmT1); diff --git a/pcsx2/x86/microVU_Macro.inl b/pcsx2/x86/microVU_Macro.inl index 0e9bee6a4b..f1073a902c 100644 --- a/pcsx2/x86/microVU_Macro.inl +++ b/pcsx2/x86/microVU_Macro.inl @@ -41,19 +41,31 @@ void setupMacroOp(int mode, const char* opName) { memset(µVU0.prog.IRinfo.info[0], 0, sizeof(microVU0.prog.IRinfo.info[0])); iFlushCall(FLUSH_EVERYTHING); microVU0.regAlloc->reset(); - if (mode & 1) { // Q-Reg will be Read + if (mode & 0x01) { // Q-Reg will be Read SSE_MOVSS_M32_to_XMM(xmmPQ, (uptr)µVU0.regs->VI[REG_Q].UL); } - if (mode & 8) { // Clip Instruction + if (mode & 0x08) { // Clip Instruction microVU0.prog.IRinfo.info[0].cFlag.write = 0xff; microVU0.prog.IRinfo.info[0].cFlag.lastWrite = 0xff; } + if (mode & 0x10) { // Update Status/Mac Flags + microVU0.prog.IRinfo.info[0].sFlag.doFlag = 1; + microVU0.prog.IRinfo.info[0].sFlag.doNonSticky = 1; + microVU0.prog.IRinfo.info[0].sFlag.write = 0; + microVU0.prog.IRinfo.info[0].sFlag.lastWrite = 0; + microVU0.prog.IRinfo.info[0].mFlag.doFlag = 1; + microVU0.prog.IRinfo.info[0].mFlag.write = 0xff; + MOV32MtoR(gprF0, (uptr)µVU0.regs->VI[REG_STATUS_FLAG].UL); + } } void endMacroOp(int mode) { - if (mode & 2) { // Q-Reg was Written To + if (mode & 0x02) { // Q-Reg was Written To SSE_MOVSS_XMM_to_M32((uptr)µVU0.regs->VI[REG_Q].UL, xmmPQ); } + if (mode & 0x10) { // Status/Mac Flags were Updated + MOV32RtoM((uptr)µVU0.regs->VI[REG_STATUS_FLAG].UL, gprF0); + } microVU0.regAlloc->flushAll(); } @@ -261,10 +273,16 @@ static void recCFC2() { if (!_Rt_) return; iFlushCall(FLUSH_EVERYTHING); - MOV32MtoR(EAX, (uptr)µVU0.regs->VI[_Rd_].UL); + if (_Rd_ == REG_STATUS_FLAG) { // Normalize Status Flag + MOV32MtoR(gprF0, (uptr)µVU0.regs->VI[REG_STATUS_FLAG].UL); + mVUallocSFLAGc(EAX, gprF0, 0); + } + else MOV32MtoR(EAX, (uptr)µVU0.regs->VI[_Rd_].UL); + + // FixMe: Should R-Reg have upper 9 bits 0? MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], EAX); - if( _Rd_ >= 16 ) { + if (_Rd_ >= 16) { CDQ(); // Sign Extend MOV32RtoM ((uptr)&cpuRegs.GPR.r[_Rt_].UL[1], EDX); } @@ -289,7 +307,14 @@ static void recCTC2() { OR32ItoR (EAX, 0x3f800000); MOV32RtoM((uptr)µVU0.regs->VI[REG_R].UL, EAX); break; - case REG_CMSAR1: // REG_CMSAR1 + case REG_STATUS_FLAG: + if (_Rt_) { // Denormalizes flag into gprF1 + mVUallocSFLAGd((uptr)&cpuRegs.GPR.r[_Rt_].UL[0], 0); + MOV32RtoM((uptr)µVU0.regs->VI[_Rd_].UL, gprF1); + } + else MOV32ItoM((uptr)µVU0.regs->VI[_Rd_].UL, 0); + break; + case REG_CMSAR1: if (_Rt_) { MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rt_].UL[0]); PUSH32R(EAX);