From c15da3a2097f1dfd8b8081b3c80ca413f2ee8738 Mon Sep 17 00:00:00 2001 From: gigaherz Date: Fri, 27 Jun 2008 14:45:25 +0000 Subject: [PATCH] Massive update of the GPL license headers. I don't know if I missed something, but I hope not. --- pcsx2/CDVD.c | 24 +- pcsx2/CDVD.h | 4 +- pcsx2/CDVDiso.c | 1689 ++--- pcsx2/CDVDiso.h | 17 + pcsx2/CDVDisodrv.c | 17 + pcsx2/CDVDisodrv.h | 17 + pcsx2/CDVDlib.h | 17 + pcsx2/COP0.c | 28 +- pcsx2/COP0.h | 4 +- pcsx2/Cache.c | 780 +-- pcsx2/Cache.h | 4 +- pcsx2/CdRom.c | 2184 +++---- pcsx2/CdRom.h | 4 +- pcsx2/Common.h | 4 +- pcsx2/Counters.c | 1436 ++--- pcsx2/Counters.h | 4 +- pcsx2/DebugTools/Debug.h | 4 +- pcsx2/DebugTools/DisASM.h | 4 +- pcsx2/DebugTools/DisR3000A.c | 14 +- pcsx2/DebugTools/DisR3000asm.c | 14 +- pcsx2/DebugTools/DisR5900.c | 14 +- pcsx2/DebugTools/DisR5900asm.c | 14 +- pcsx2/DebugTools/DisVU0Micro.c | 17 +- pcsx2/DebugTools/DisVU1Micro.c | 14 +- pcsx2/DebugTools/DisVUmicro.h | 4 +- pcsx2/DebugTools/DisVUops.h | 4 +- pcsx2/DebugTools/cpuopsDebug.c | 14 +- pcsx2/DebugTools/cpuopsDebug.h | 4 +- pcsx2/Decode_XA.c | 17 + pcsx2/Decode_XA.h | 17 + pcsx2/EEregs.h | 4 +- pcsx2/Elfheader.c | 14 +- pcsx2/Elfheader.h | 4 +- pcsx2/FPU.c | 14 +- pcsx2/FPU2.cpp | 17 + pcsx2/FiFo.c | 14 +- pcsx2/GS.cpp | 28 +- pcsx2/GS.h | 4 +- pcsx2/Hw.c | 14 +- pcsx2/Hw.h | 4 +- pcsx2/IPU/IPU.c | 14 +- pcsx2/IPU/IPU.h | 4 +- pcsx2/IPU/acoroutine.asm | 4 +- pcsx2/IPU/coroutine.c | 28 +- pcsx2/IPU/coroutine.h | 4 +- pcsx2/IPU/mpeg2lib/Idct.c | 2 +- pcsx2/IPU/mpeg2lib/Mpeg.c | 2 +- pcsx2/IPU/mpeg2lib/Mpeg.h | 2 +- pcsx2/IPU/mpeg2lib/Vlc.h | 2 +- pcsx2/IPU/yuv2rgb.c | 2 +- pcsx2/IPU/yuv2rgb.h | 2 +- pcsx2/InterTables.c | 14 +- pcsx2/InterTables.h | 4 +- pcsx2/Interpreter.c | 28 +- pcsx2/Linux/Config.c | 28 +- pcsx2/Linux/GtkGui.c | 17 + pcsx2/Linux/Linux.h | 4 +- pcsx2/Linux/LnxMain.c | 14 +- pcsx2/Linux/callbacks.h | 17 + pcsx2/Linux/interface.c | 17 + pcsx2/Linux/interface.h | 17 + pcsx2/Linux/support.c | 17 + pcsx2/Linux/support.h | 17 + pcsx2/MMI.c | 15 +- pcsx2/Mdec.c | 14 +- pcsx2/Mdec.h | 4 +- pcsx2/Memory.c | 14 +- pcsx2/Memory.h | 4 +- pcsx2/Misc.c | 28 +- pcsx2/Misc.h | 4 +- pcsx2/PS2Edefs.h | 17 + pcsx2/PS2Etypes.h | 17 + pcsx2/Patch.c | 14 +- pcsx2/Patch.h | 17 + pcsx2/Plugins.c | 14 +- pcsx2/Plugins.h | 4 +- pcsx2/PsxBios.c | 14 +- pcsx2/PsxBios.h | 4 +- pcsx2/PsxBios2.h | 4 +- pcsx2/PsxCommon.h | 4 +- pcsx2/PsxCounters.c | 1562 ++--- pcsx2/PsxCounters.h | 4 +- pcsx2/PsxDma.c | 542 +- pcsx2/PsxDma.h | 4 +- pcsx2/PsxHw.c | 14 +- pcsx2/PsxHw.h | 4 +- pcsx2/PsxInterpreter.c | 15 +- pcsx2/PsxMem.c | 28 +- pcsx2/PsxMem.h | 4 +- pcsx2/PsxSio2.c | 14 +- pcsx2/PsxSio2.h | 4 +- pcsx2/R3000A.c | 14 +- pcsx2/R3000A.h | 4 +- pcsx2/R5900.c | 28 +- pcsx2/R5900.h | 564 +- pcsx2/RDebug/deci2.c | 14 +- pcsx2/RDebug/deci2.h | 4 +- pcsx2/RDebug/deci2_dbgp.c | 14 +- pcsx2/RDebug/deci2_dbgp.h | 4 +- pcsx2/RDebug/deci2_dcmp.c | 14 +- pcsx2/RDebug/deci2_dcmp.h | 4 +- pcsx2/RDebug/deci2_drfp.c | 14 +- pcsx2/RDebug/deci2_drfp.h | 4 +- pcsx2/RDebug/deci2_iloadp.c | 14 +- pcsx2/RDebug/deci2_iloadp.h | 4 +- pcsx2/RDebug/deci2_netmp.c | 14 +- pcsx2/RDebug/deci2_netmp.h | 4 +- pcsx2/RDebug/deci2_ttyp.c | 14 +- pcsx2/RDebug/deci2_ttyp.h | 4 +- pcsx2/SPR.c | 808 +-- pcsx2/SPR.h | 4 +- pcsx2/Sif.c | 14 +- pcsx2/Sif.h | 4 +- pcsx2/Sifcmd.h | 4 +- pcsx2/Sio.c | 14 +- pcsx2/Sio.h | 4 +- pcsx2/Stats.c | 14 +- pcsx2/Stats.h | 4 +- pcsx2/System.h | 4 +- pcsx2/VU.h | 4 +- pcsx2/VU0.c | 14 +- pcsx2/VU0.h | 4 +- pcsx2/VU0micro.c | 15 +- pcsx2/VU1micro.c | 15 +- pcsx2/VUflags.c | 14 +- pcsx2/VUflags.h | 4 +- pcsx2/VUmicro.h | 4 +- pcsx2/VUops.c | 14 +- pcsx2/VUops.h | 4 +- pcsx2/Vif.c | 50 +- pcsx2/Vif.h | 4 +- pcsx2/VifDma.c | 5166 +++++++-------- pcsx2/VifDma.h | 4 +- pcsx2/cheatscpp.h | 17 + pcsx2/windows/AboutDlg.c | 14 +- pcsx2/windows/AboutDlg.h | 4 +- pcsx2/windows/ConfigDlg.c | 14 +- pcsx2/windows/CpuDlg.c | 14 +- pcsx2/windows/DebugMemory.c | 14 +- pcsx2/windows/Debugger.c | 15 +- pcsx2/windows/Debugger.h | 4 +- pcsx2/windows/Debugreg.c | 14 +- pcsx2/windows/McdsDlg.c | 14 +- pcsx2/windows/McdsDlg.cpp | 14 +- pcsx2/windows/McdsDlg.h | 4 +- pcsx2/windows/PatchBrowser.c | 15 +- pcsx2/windows/RDebugger.c | 15 +- pcsx2/windows/RDebugger.h | 4 +- pcsx2/windows/VCprojects/pcsx2_2005.vcproj | 18 +- pcsx2/windows/Win32.h | 4 +- pcsx2/windows/WinMain.c | 14 +- pcsx2/windows/cheats/browser.cpp | 17 + pcsx2/windows/cheats/cheats.cpp | 17 + pcsx2/windows/cheats/cheats.h | 17 + pcsx2/windows/ini.c | 15 +- pcsx2/windows/mingw/pcsx2_private.h | 17 + pcsx2/x86/aVif.asm | 4 +- pcsx2/x86/iCOP2.c | 15 +- pcsx2/x86/iCP0.c | 29 +- pcsx2/x86/iCP0.h | 4 +- pcsx2/x86/iCore.cpp | 17 + pcsx2/x86/iCore.h | 4 +- pcsx2/x86/iFPU.c | 15 +- pcsx2/x86/iFPU.h | 4 +- pcsx2/x86/iGS.cpp | 28 +- pcsx2/x86/iHw.c | 128 +- pcsx2/x86/iMMI.c | 14 +- pcsx2/x86/iMMI.h | 4 +- pcsx2/x86/iPsxHw.c | 29 +- pcsx2/x86/iPsxMem.c | 29 +- pcsx2/x86/iR3000A.cpp | 28 +- pcsx2/x86/iR3000A.h | 4 +- pcsx2/x86/iR3000Atables.cpp | 28 +- pcsx2/x86/iR5900.h | 4 +- pcsx2/x86/iR5900Arit.h | 4 +- pcsx2/x86/iR5900AritImm.h | 14 +- pcsx2/x86/iR5900Branch.h | 14 +- pcsx2/x86/iR5900Jump.h | 14 +- pcsx2/x86/iR5900LoadStore.h | 14 +- pcsx2/x86/iR5900Move.h | 14 +- pcsx2/x86/iR5900MultDiv.h | 14 +- pcsx2/x86/iR5900Shift.h | 14 +- pcsx2/x86/iVU0micro.c | 15 +- pcsx2/x86/iVU0micro.h | 14 +- pcsx2/x86/iVU1micro.c | 15 +- pcsx2/x86/iVU1micro.h | 14 +- pcsx2/x86/iVUmicro.c | 15 +- pcsx2/x86/iVUmicro.h | 14 +- pcsx2/x86/iVUops.h | 14 +- pcsx2/x86/iVUzerorec.cpp | 28 +- pcsx2/x86/iVUzerorec.h | 14 +- pcsx2/x86/iVif.cpp | 14 +- pcsx2/x86/ir5900tables.c | 14 +- pcsx2/x86/ix86-32/iCore-32.cpp | 17 + pcsx2/x86/ix86-32/iR5900-32.c | 6626 ++++++++++---------- pcsx2/x86/ix86-32/iR5900Arit.c | 28 +- pcsx2/x86/ix86-32/iR5900AritImm.c | 28 +- pcsx2/x86/ix86-32/iR5900Branch.c | 28 +- pcsx2/x86/ix86-32/iR5900Jump.c | 28 +- pcsx2/x86/ix86-32/iR5900LoadStore.c | 28 +- pcsx2/x86/ix86-32/iR5900Move.c | 14 +- pcsx2/x86/ix86-32/iR5900MultDiv.c | 29 +- pcsx2/x86/ix86-32/iR5900Shift.c | 29 +- pcsx2/x86/ix86-64/fast_routines-64.asm | 4 +- pcsx2/x86/ix86-64/iCore-64.cpp | 17 + pcsx2/x86/ix86-64/iR5900-64.c | 28 +- pcsx2/x86/ix86-64/iR5900Arit-64.c | 15 +- pcsx2/x86/ix86-64/iR5900AritImm-64.c | 15 +- pcsx2/x86/ix86-64/iR5900Branch-64.c | 15 +- pcsx2/x86/ix86-64/iR5900Jump-64.c | 15 +- pcsx2/x86/ix86-64/iR5900LoadStore-64.c | 15 +- pcsx2/x86/ix86-64/iR5900Move-64.c | 15 +- pcsx2/x86/ix86-64/iR5900MultDiv-64.c | 15 +- pcsx2/x86/ix86-64/iR5900Shift-64.c | 15 +- pcsx2/x86/ix86/ix86.c | 17 + pcsx2/x86/ix86/ix86.h | 17 + pcsx2/x86/ix86/ix86_3dnow.c | 17 + pcsx2/x86/ix86/ix86_cpudetect.c | 12 +- pcsx2/x86/ix86/ix86_fpu.c | 17 + pcsx2/x86/ix86/ix86_mmx.c | 17 + pcsx2/x86/ix86/ix86_sse.c | 17 + pcsx2/xmlpatchloader.cpp | 17 + 222 files changed, 12382 insertions(+), 11807 deletions(-) diff --git a/pcsx2/CDVD.c b/pcsx2/CDVD.c index 54b52f5..c02bac5 100644 --- a/pcsx2/CDVD.c +++ b/pcsx2/CDVD.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2007 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include @@ -1339,14 +1339,14 @@ void cdvdWrite07(u8 rt) { // BREAK } /* -Interrupts - -0x00 No interrupt -0x01 Data Ready -0x02 Command Complete -0x03 Acknowledge (reserved) -0x04 End of Data Detected -0x05 Error Detected +Interrupts + +0x00 No interrupt +0x01 Data Ready +0x02 Command Complete +0x03 Acknowledge (reserved) +0x04 End of Data Detected +0x05 Error Detected 0x06 Drive Not Ready */ diff --git a/pcsx2/CDVD.h b/pcsx2/CDVD.h index 5a1d9ac..0099c94 100644 --- a/pcsx2/CDVD.h +++ b/pcsx2/CDVD.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __CDVD_H__ diff --git a/pcsx2/CDVDiso.c b/pcsx2/CDVDiso.c index f2b96f1..68755b6 100644 --- a/pcsx2/CDVDiso.c +++ b/pcsx2/CDVDiso.c @@ -1,836 +1,853 @@ -/* - * Original code from libcdvd by Hiryu & Sjeep (C) 2002 - * Modified by Florin for PCSX2 emu - * Fixed CdRead by linuzappz - */ - -#include - -#include "CDVDiso.h" -#include "CDVDisodrv.h" - -struct dir_toc_data{ - unsigned int start_LBA; - unsigned int num_sectors; - unsigned int num_entries; - unsigned int current_entry; - unsigned int current_sector; - unsigned int current_sector_offset; - unsigned int inc_dirs; - unsigned char extension_list[128+1]; -}; - -//static u8 cdVolDescriptor[2048]; -static struct dir_toc_data getDirTocData; -static struct cdVolDesc CDVolDesc; - -void _splitpath2(const char *constpath, char *dir, char *fname){ - // 255 char max path-length is an ISO9660 restriction - // we must change this for Joliet or relaxed iso restriction support - static char pathcopy[1024+1]; - - char* slash; - - strncpy(pathcopy, constpath, 1024); - - slash = strrchr (pathcopy, '/'); - - // if the path doesn't contain a '/' then look for a '\' - if (!slash) - slash = strrchr (pathcopy, (int)'\\'); - - // if a slash was found - if (slash != NULL) - { - // null terminate the path - slash[0] = 0; - // and copy the path into 'dir' - strncpy(dir, pathcopy, 1024); - dir[255]=0; - - // copy the filename into 'fname' - strncpy(fname, slash+1, 128); - fname[128]=0; - } - else - { - dir[0] = 0; - - strncpy(fname, pathcopy, 128); - fname[128]=0; - } - -} - -// Used in findfile -int tolower(int c); -int strcasecmp(const char *s1, const char *s2){ - while (*s1 != '\0' && tolower(*s1) == tolower(*s2)) - { - s1++; - s2++; - } - - return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2); -} - -// Copy a TOC Entry from the CD native format to our tidier format -void TocEntryCopy(struct TocEntry* tocEntry, struct dirTocEntry* internalTocEntry){ - int i; - int filenamelen; - - tocEntry->fileSize = internalTocEntry->fileSize; - tocEntry->fileLBA = internalTocEntry->fileLBA; - tocEntry->fileProperties = internalTocEntry->fileProperties; - memcpy(tocEntry->date, internalTocEntry->dateStamp, 7); - - if (CDVolDesc.filesystemType == 2){ - // This is a Joliet Filesystem, so use Unicode to ISO string copy - - filenamelen = internalTocEntry->filenameLength/2; - - if (!(tocEntry->fileProperties & 0x02)){ - // strip the ;1 from the filename -// filenamelen -= 2;//(Florin) nah, do not strip ;1 - } - - for (i=0; i < filenamelen; i++) - tocEntry->filename[i] = internalTocEntry->filename[(i<<1)+1]; - - tocEntry->filename[filenamelen] = 0; - } - else{ - filenamelen = internalTocEntry->filenameLength; - - if (!(tocEntry->fileProperties & 0x02)){ - // strip the ;1 from the filename -// filenamelen -= 2;//(Florin) nah, do not strip ;1 - } - - // use normal string copy - strncpy(tocEntry->filename,internalTocEntry->filename,128); - tocEntry->filename[filenamelen] = 0; - } -} - -// Check if a TOC Entry matches our extension list -int TocEntryCompare(char* filename, char* extensions){ - static char ext_list[129]; - - char* token; - - char* ext_point; - - strncpy(ext_list,extensions,128); - ext_list[128]=0; - - token = strtok( ext_list, " ," ); - while( token != NULL ) - { - // if 'token' matches extension of 'filename' - // then return a match - ext_point = strrchr(filename,'.'); - - if (strnicmp(ext_point, token, strlen(token)) == 0) - return (TRUE); - - /* Get next token: */ - token = strtok( NULL, " ," ); - } - - // If not match found then return FALSE - return (FALSE); - -} - -#define CD_SECS 60 /* seconds per minute */ -#define CD_FRAMES 75 /* frames per second */ -#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */ - -int CdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode){ - u32 i; - u8* buff; - int rmode; - - switch (mode->datapattern) { - case CdSecS2048: - rmode = CDVD_MODE_2048; break; - case CdSecS2328: - rmode = CDVD_MODE_2328; break; - case CdSecS2340: - rmode = CDVD_MODE_2340; break; - default: - return 0; - } - - for (i=0; idatapattern){ - case CdSecS2048: - memcpy_fast((void*)((uptr)buf+2048*i), buff, 2048);break;//only data - case CdSecS2328: - memcpy_fast((void*)((uptr)buf+2328*i), buff, 2328);break;//without sync & head & sub - case CdSecS2340: - memcpy_fast((void*)((uptr)buf+2340*i), buff, 2340);break;//without sync - } - FreezeMMXRegs(0); - } - return 1; -} - -int DvdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode){ - u32 i; - u8* buff; - - for (i=lsn; i<(lsn+sectors); i++){ - if (CDVDreadTrack(i, CDVD_MODE_2048)==-1) - return 0; - buff = CDVDgetBuffer(); - if (buff==NULL) return 0; - -// switch (mode->datapattern){ -// case CdSecS2064: - ((u32*)buf)[0] = i + 0x30000; - FreezeMMXRegs(1); - memcpy_fast((u8*)buf+12, buff, 2048); - FreezeMMXRegs(0); - buf = (char*)buf + 2064; break; -// default: -// return 0; -// } - } - - return 1; -} - -/************************************************************** -* The functions below are not exported for normal file-system * -* operations, but are used by the file-system operations, and * -* may also be exported for use via RPC * -**************************************************************/ - -int CDVD_GetVolumeDescriptor(void){ - // Read until we find the last valid Volume Descriptor - int volDescSector; - - static struct cdVolDesc localVolDesc; - -#ifdef DEBUG - SysPrintf("CDVD_GetVolumeDescriptor called\n"); -#endif - - for (volDescSector = 16; volDescSector<20; volDescSector++) - { - CdRead(volDescSector,1,&localVolDesc,&cdReadMode); -// CdSync(0x00); - - // If this is still a volume Descriptor - if (strncmp(localVolDesc.volID, "CD001", 5) == 0) - { - if ((localVolDesc.filesystemType == 1) || - (localVolDesc.filesystemType == 2)) - { - FreezeMMXRegs(1); - memcpy_fast(&CDVolDesc, &localVolDesc, sizeof(struct cdVolDesc)); - FreezeMMXRegs(0); - } - } - else - break; - } - -#ifdef DEBUG - if (CDVolDesc.filesystemType == 1) - SysPrintf("CD FileSystem is ISO9660\n"); - else if (CDVolDesc.filesystemType == 2) - SysPrintf("CD FileSystem is Joliet\n"); - else SysPrintf("Could not detect CD FileSystem type\n"); -#endif -// CdStop(); - - return TRUE; -} - -int CDVD_findfile(char* fname, struct TocEntry* tocEntry){ - static char filename[128+1]; - static char pathname[1024+1]; - static char toc[2048]; - char* dirname; - - - static struct TocEntry localTocEntry; // used for internal checking only - - int found_dir; - - int num_dir_sectors; - int current_sector; - - int dir_lba; - - struct dirTocEntry* tocEntryPointer; - -#ifdef DEBUG - SysPrintf("CDVD_findfile called\n"); -#endif - - //make sure we have good cdReadMode - cdReadMode.trycount = 0; - cdReadMode.spindlctrl = CdSpinStm; - cdReadMode.datapattern = CdSecS2048; - - _splitpath2(fname, pathname, filename); - - // Find the TOC for a specific directory - if (CDVD_GetVolumeDescriptor() != TRUE){ -#ifdef RPC_LOG - RPC_LOG("Could not get CD Volume Descriptor\n"); -#endif - return -1; - } - - // Read the TOC of the root directory - if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){ -#ifdef RPC_LOG - RPC_LOG("Couldn't Read from CD !\n"); -#endif - return -1; - } - //CdSync(0x00); - - // point the tocEntryPointer at the first real toc entry - tocEntryPointer = (struct dirTocEntry*)toc; - - num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; //round up fix - current_sector = tocEntryPointer->fileLBA; - - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - - - localTocEntry.fileLBA = CDVolDesc.rootToc.tocLBA; - // while (there are more dir names in the path) - dirname = strtok( pathname, "\\/" ); - - while( dirname != NULL ) - { - found_dir = FALSE; -/* - while(tocEntryPointer->length > 0) - { - // while there are still more directory entries then search through - // for the one we want - - if (tocEntryPointer->fileProperties & 0x02) - { - // Copy the CD format TOC Entry to our format - TocEntryCopy(&localTocEntry, tocEntryPointer); - - // If this TOC Entry is a directory, - // then see if it has the right name - if (strcasecmp(dirname,localTocEntry.filename) == 0) - { - // if the name matches then we've found the directory - found_dir = TRUE; - break; - } - } - - // point to the next entry - (char*)tocEntryPointer += tocEntryPointer->length; - } -*/ - while(1) - { - if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048)) - { - num_dir_sectors--; - - if (num_dir_sectors > 0) - { - // If we've run out of entries, but arent on the last sector - // then load another sector - - current_sector++; - if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE) - { - SysPrintf("Couldn't Read from CD !\n"); - return -1; - } -// CdSync(0x00); - - tocEntryPointer = (struct dirTocEntry*)toc; - } - else - { - // Couldnt find the directory, and got to end of directory - return -1; - } - } - - - if (tocEntryPointer->fileProperties & 0x02) - { - TocEntryCopy(&localTocEntry, tocEntryPointer); - - // If this TOC Entry is a directory, - // then see if it has the right name - if (strcmp(dirname,localTocEntry.filename) == 0) - { - // if the name matches then we've found the directory - found_dir = TRUE; - break; - } - } - - // point to the next entry - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - } - - // If we havent found the directory name we wanted then fail - if (found_dir != TRUE) - { - SysPrintf("CDVD_findfile: could not find dir\n"); - return -1; - } - - // Get next directory name - dirname = strtok( NULL, "\\/" ); - - // Read the TOC of the found subdirectory - if (CdRead(localTocEntry.fileLBA,1,toc,&cdReadMode) != TRUE) - { - SysPrintf("Couldn't Read from CD !\n"); - return -1; - } -// CdSync(0x00); - - num_dir_sectors = (localTocEntry.fileSize+2047) >> 11; //round up fix - current_sector = localTocEntry.fileLBA; - - // and point the tocEntryPointer at the first real toc entry - tocEntryPointer = (struct dirTocEntry*)toc; - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - } - -#ifdef DEBUG - SysPrintf("CDVD_findfile: found dir, now looking for file\n"); -#endif - - tocEntryPointer = (struct dirTocEntry*)toc; - - num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; //round up fix - dir_lba = tocEntryPointer->fileLBA; - - tocEntryPointer = (struct dirTocEntry*)toc; - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - - while (num_dir_sectors > 0) - { - while(tocEntryPointer->length != 0) - { - // Copy the CD format TOC Entry to our format - TocEntryCopy(&localTocEntry, tocEntryPointer); - - if ((strnicmp(localTocEntry.filename, filename, strlen(filename)) == 0) || - ((filename[strlen(filename)-2] == ';') && - (localTocEntry.filename[strlen(localTocEntry.filename)-2] == ';') && - (strnicmp(localTocEntry.filename, filename, strlen(filename)-2) == 0))) - { - // if the filename matches then copy the toc Entry - tocEntry->fileLBA = localTocEntry.fileLBA; - tocEntry->fileProperties = localTocEntry.fileProperties; - tocEntry->fileSize = localTocEntry.fileSize; - - strcpy(tocEntry->filename, localTocEntry.filename); - memcpy(tocEntry->date, localTocEntry.date, 7); - -#ifdef DEBUG - SysPrintf("CDVD_findfile: found file\n"); -#endif - - return TRUE; - } - - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - } - - num_dir_sectors--; - - if (num_dir_sectors > 0) - { - dir_lba++; - - if (CdRead(dir_lba,1,toc,&cdReadMode) != TRUE){ - SysPrintf("Couldn't Read from CD !\n"); - return -1; - } -// CdSync(0x00); - - tocEntryPointer = (struct dirTocEntry*)toc; - } - } - -#ifdef DEBUG - SysPrintf("CDVD_findfile: could not find file\n"); -#endif - - return FALSE; -} - -// This is the RPC-ready function which takes the request to start the tocEntry retrieval -int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_dirs){ -// int dir_depth = 1; - static char toc[2048]; - char* dirname; - int found_dir; - int num_dir_sectors; - unsigned int toc_entry_num; - struct dirTocEntry* tocEntryPointer; - static struct TocEntry localTocEntry; - int current_sector; - - // store the extension list statically for the retrieve function - strncpy(getDirTocData.extension_list, extensions, 128); - getDirTocData.extension_list[128]=0; - - getDirTocData.inc_dirs = inc_dirs; - - // Find the TOC for a specific directory - if (CDVD_GetVolumeDescriptor() != TRUE){ -#ifdef RPC_LOG - RPC_LOG("[RPC:cdvd] Could not get CD Volume Descriptor\n"); -#endif - return -1; - } - -#ifdef RPC_LOG - RPC_LOG("[RPC:cdvd] Getting Directory Listing for: \"%s\"\n", pathname); -#endif - - // Read the TOC of the root directory - if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){ -#ifdef RPC_LOG - RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); -#endif - return -1; - } - //CdSync(0x00); - - // point the tocEntryPointer at the first real toc entry - tocEntryPointer = (struct dirTocEntry*)toc; - - num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; - current_sector = tocEntryPointer->fileLBA; - - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - - // use strtok to get the next dir name - - // if there isnt one, then assume we want the LBA - // for the current one, and exit the while loop - - // if there is another dir name then increment dir_depth - // and look through dir table entries until we find the right name - // if we dont find the right name - // before finding an entry at a higher level (lower num), then return nothing - - localTocEntry.fileLBA = CDVolDesc.rootToc.tocLBA; - - // while (there are more dir names in the path) - dirname = strtok( pathname, "\\/" ); - while( dirname != NULL ){ - found_dir = FALSE; - - while(1){ - if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048)) { - num_dir_sectors--; - - if (num_dir_sectors > 0){ - // If we've run out of entries, but arent on the last sector - // then load another sector - - current_sector++; - if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE){ -#ifdef RPC_LOG - RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); -#endif - return -1; - } - //CdSync(0x00); - - tocEntryPointer = (struct dirTocEntry*)toc; - } - else{ - // Couldnt find the directory, and got to end of directory - return -1; - } - } - - if (tocEntryPointer->fileProperties & 0x02){ - TocEntryCopy(&localTocEntry, tocEntryPointer); - - // If this TOC Entry is a directory, - // then see if it has the right name - if (strcmp(dirname,localTocEntry.filename) == 0){ - // if the name matches then we've found the directory - found_dir = TRUE; -#ifdef RPC_LOG - RPC_LOG("[RPC: ] Found directory %s in subdir at sector %d\n",dirname,current_sector); - RPC_LOG("[RPC: ] LBA of found subdirectory = %d\n",localTocEntry.fileLBA); -#endif - break; - } - } - - // point to the next entry - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - } - - // If we havent found the directory name we wanted then fail - if (found_dir != TRUE) - return -1; - - // Get next directory name - dirname = strtok( NULL, "\\/" ); - - // Read the TOC of the found subdirectory - if (CdRead(localTocEntry.fileLBA,1,toc,&cdReadMode) != TRUE){ -#ifdef RPC_LOG - RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); -#endif - return -1; - } - //CdSync(0x00); - - num_dir_sectors = (localTocEntry.fileSize+2047) >> 11; - current_sector = localTocEntry.fileLBA; - - // and point the tocEntryPointer at the first real toc entry - tocEntryPointer = (struct dirTocEntry*)toc; - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - } - - // We know how much data we need to read in from the DirTocHeader - // but we need to read in at least 1 sector before we can get this value - - // Now we need to COUNT the number of entries (dont do anything with info at this point) - // so set the tocEntryPointer to point to the first actual file entry - - // This is a bit of a waste of reads since we're not actually copying the data out yet, - // but we dont know how big this TOC might be, so we cant allocate a specific size - - tocEntryPointer = (struct dirTocEntry*)toc; - - // Need to STORE the start LBA and number of Sectors, for use by the retrieve func. - getDirTocData.start_LBA = localTocEntry.fileLBA; - getDirTocData.num_sectors = (tocEntryPointer->fileSize+2047) >> 11; - getDirTocData.num_entries = 0; - getDirTocData.current_entry = 0; - getDirTocData.current_sector = getDirTocData.start_LBA; - getDirTocData.current_sector_offset = 0; - - num_dir_sectors = getDirTocData.num_sectors; - - tocEntryPointer = (struct dirTocEntry*)toc; - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - - toc_entry_num=0; - - while(1){ - if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048)){ - // decrease the number of dirs remaining - num_dir_sectors--; - - if (num_dir_sectors > 0){ - // If we've run out of entries, but arent on the last sector - // then load another sector - getDirTocData.current_sector++; - - if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ -#ifdef RPC_LOG - RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); -#endif - return -1; - } - //CdSync(0x00); - - tocEntryPointer = (struct dirTocEntry*)toc; - -// continue; - } - else{ - getDirTocData.num_entries = toc_entry_num; - getDirTocData.current_sector = getDirTocData.start_LBA; - return (toc_entry_num); - } - } - - // We've found a file/dir in this directory - // now check if it matches our extension list (if there is one) - TocEntryCopy(&localTocEntry, tocEntryPointer); - - if (localTocEntry.fileProperties & 0x02){ - // If this is a subdir, then check if we want to include subdirs - if (getDirTocData.inc_dirs){ - toc_entry_num++; - } - } - else{ - if (strlen(getDirTocData.extension_list) > 0){ - if (TocEntryCompare(localTocEntry.filename, getDirTocData.extension_list) == TRUE){ - // increment the number of matching entries counter - toc_entry_num++; - } - } - else{ - toc_entry_num++; - } - } - - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - } - - - // THIS SHOULD BE UNREACHABLE - - // since we are trying to count ALL matching entries, rather than upto a limit - - - // STORE total number of TOC entries - getDirTocData.num_entries = toc_entry_num; - getDirTocData.current_sector = getDirTocData.start_LBA; - - - // we've reached the toc entry limit, so return how many we've done - return (toc_entry_num); - -} - -// This function can be called repeatedly after CDVD_GetDir_RPC_request to get the actual entries -// buffer (tocEntry) must be 18KB in size, and this will be filled with a maximum of 128 entries in one go -int CDVD_GetDir_RPC_get_entries(struct TocEntry tocEntry[], int req_entries){ - static char toc[2048]; - int toc_entry_num; - - struct dirTocEntry* tocEntryPointer; - - if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ -#ifdef RPC_LOG - RPC_LOG("[RPC:cdvd] Couldn't Read from CD !\n"); -#endif - return -1; - } - //CdSync(0x00); - - if (getDirTocData.current_entry == 0){ - // if this is the first read then make sure we point to the first real entry - tocEntryPointer = (struct dirTocEntry*)toc; - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); - - - getDirTocData.current_sector_offset = (char*)tocEntryPointer - toc; - } - else{ - tocEntryPointer = (struct dirTocEntry*)(toc + getDirTocData.current_sector_offset); - } - - if (req_entries > 128) - req_entries = 128; - - for (toc_entry_num=0; toc_entry_num < req_entries;){ - if ((tocEntryPointer->length == 0) || (getDirTocData.current_sector_offset >= 2048)){ - // decrease the number of dirs remaining - getDirTocData.num_sectors--; - - if (getDirTocData.num_sectors > 0){ - // If we've run out of entries, but arent on the last sector - // then load another sector - getDirTocData.current_sector++; - - if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ -#ifdef RPC_LOG - RPC_LOG("[RPC:cdvd] Couldn't Read from CD !\n"); -#endif - return -1; - } - //CdSync(0x00); - - getDirTocData.current_sector_offset = 0; - tocEntryPointer = (struct dirTocEntry*)(toc + getDirTocData.current_sector_offset); - -// continue; - } - else{ - return (toc_entry_num); - } - } - - // This must be incremented even if the filename doesnt match extension list - getDirTocData.current_entry++; - - // We've found a file in this directory - // now check if it matches our extension list (if there is one) - - // Copy the entry regardless, as it makes the comparison easier - // if it doesn't match then it will just be overwritten - TocEntryCopy(&tocEntry[toc_entry_num], tocEntryPointer); - - if (tocEntry[toc_entry_num].fileProperties & 0x02){ - // If this is a subdir, then check if we want to include subdirs - if (getDirTocData.inc_dirs) { - toc_entry_num++; - } - - getDirTocData.current_sector_offset += tocEntryPointer->length; - tocEntryPointer = (struct dirTocEntry*)(toc + getDirTocData.current_sector_offset); - } - else{ - if (strlen(getDirTocData.extension_list) > 0){ - if (TocEntryCompare(tocEntry[toc_entry_num].filename, getDirTocData.extension_list) == TRUE){ - // increment the number of matching entries counter - toc_entry_num++; - } - - getDirTocData.current_sector_offset += tocEntryPointer->length; - tocEntryPointer = (struct dirTocEntry*)(toc + getDirTocData.current_sector_offset); - - } - else{ - toc_entry_num++; - getDirTocData.current_sector_offset += tocEntryPointer->length; - tocEntryPointer = (struct dirTocEntry*)(toc + getDirTocData.current_sector_offset); - } - } -/* - if (strlen(getDirTocData.extension_list) > 0) - { - if (TocEntryCompare(tocEntry[toc_entry_num].filename, getDirTocData.extension_list) == TRUE) - { - - // increment this here, rather than in the main for loop - // since this should count the number of matching entries - toc_entry_num++; - } - - getDirTocData.current_sector_offset += tocEntryPointer->length; - (char*)tocEntryPointer = toc + getDirTocData.current_sector_offset; - } - else - { - toc_entry_num++; - getDirTocData.current_sector_offset += tocEntryPointer->length; - (char*)tocEntryPointer = toc + getDirTocData.current_sector_offset; - } -*/ - } - return (toc_entry_num); -} +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +/* + * Original code from libcdvd by Hiryu & Sjeep (C) 2002 + * Modified by Florin for PCSX2 emu + * Fixed CdRead by linuzappz + */ + +#include + +#include "CDVDiso.h" +#include "CDVDisodrv.h" + +struct dir_toc_data{ + unsigned int start_LBA; + unsigned int num_sectors; + unsigned int num_entries; + unsigned int current_entry; + unsigned int current_sector; + unsigned int current_sector_offset; + unsigned int inc_dirs; + unsigned char extension_list[128+1]; +}; + +//static u8 cdVolDescriptor[2048]; +static struct dir_toc_data getDirTocData; +static struct cdVolDesc CDVolDesc; + +void _splitpath2(const char *constpath, char *dir, char *fname){ + // 255 char max path-length is an ISO9660 restriction + // we must change this for Joliet or relaxed iso restriction support + static char pathcopy[1024+1]; + + char* slash; + + strncpy(pathcopy, constpath, 1024); + + slash = strrchr (pathcopy, '/'); + + // if the path doesn't contain a '/' then look for a '\' + if (!slash) + slash = strrchr (pathcopy, (int)'\\'); + + // if a slash was found + if (slash != NULL) + { + // null terminate the path + slash[0] = 0; + // and copy the path into 'dir' + strncpy(dir, pathcopy, 1024); + dir[255]=0; + + // copy the filename into 'fname' + strncpy(fname, slash+1, 128); + fname[128]=0; + } + else + { + dir[0] = 0; + + strncpy(fname, pathcopy, 128); + fname[128]=0; + } + +} + +// Used in findfile +int tolower(int c); +int strcasecmp(const char *s1, const char *s2){ + while (*s1 != '\0' && tolower(*s1) == tolower(*s2)) + { + s1++; + s2++; + } + + return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2); +} + +// Copy a TOC Entry from the CD native format to our tidier format +void TocEntryCopy(struct TocEntry* tocEntry, struct dirTocEntry* internalTocEntry){ + int i; + int filenamelen; + + tocEntry->fileSize = internalTocEntry->fileSize; + tocEntry->fileLBA = internalTocEntry->fileLBA; + tocEntry->fileProperties = internalTocEntry->fileProperties; + memcpy(tocEntry->date, internalTocEntry->dateStamp, 7); + + if (CDVolDesc.filesystemType == 2){ + // This is a Joliet Filesystem, so use Unicode to ISO string copy + + filenamelen = internalTocEntry->filenameLength/2; + + if (!(tocEntry->fileProperties & 0x02)){ + // strip the ;1 from the filename +// filenamelen -= 2;//(Florin) nah, do not strip ;1 + } + + for (i=0; i < filenamelen; i++) + tocEntry->filename[i] = internalTocEntry->filename[(i<<1)+1]; + + tocEntry->filename[filenamelen] = 0; + } + else{ + filenamelen = internalTocEntry->filenameLength; + + if (!(tocEntry->fileProperties & 0x02)){ + // strip the ;1 from the filename +// filenamelen -= 2;//(Florin) nah, do not strip ;1 + } + + // use normal string copy + strncpy(tocEntry->filename,internalTocEntry->filename,128); + tocEntry->filename[filenamelen] = 0; + } +} + +// Check if a TOC Entry matches our extension list +int TocEntryCompare(char* filename, char* extensions){ + static char ext_list[129]; + + char* token; + + char* ext_point; + + strncpy(ext_list,extensions,128); + ext_list[128]=0; + + token = strtok( ext_list, " ," ); + while( token != NULL ) + { + // if 'token' matches extension of 'filename' + // then return a match + ext_point = strrchr(filename,'.'); + + if (strnicmp(ext_point, token, strlen(token)) == 0) + return (TRUE); + + /* Get next token: */ + token = strtok( NULL, " ," ); + } + + // If not match found then return FALSE + return (FALSE); + +} + +#define CD_SECS 60 /* seconds per minute */ +#define CD_FRAMES 75 /* frames per second */ +#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */ + +int CdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode){ + u32 i; + u8* buff; + int rmode; + + switch (mode->datapattern) { + case CdSecS2048: + rmode = CDVD_MODE_2048; break; + case CdSecS2328: + rmode = CDVD_MODE_2328; break; + case CdSecS2340: + rmode = CDVD_MODE_2340; break; + default: + return 0; + } + + for (i=0; idatapattern){ + case CdSecS2048: + memcpy_fast((void*)((uptr)buf+2048*i), buff, 2048);break;//only data + case CdSecS2328: + memcpy_fast((void*)((uptr)buf+2328*i), buff, 2328);break;//without sync & head & sub + case CdSecS2340: + memcpy_fast((void*)((uptr)buf+2340*i), buff, 2340);break;//without sync + } + FreezeMMXRegs(0); + } + return 1; +} + +int DvdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode){ + u32 i; + u8* buff; + + for (i=lsn; i<(lsn+sectors); i++){ + if (CDVDreadTrack(i, CDVD_MODE_2048)==-1) + return 0; + buff = CDVDgetBuffer(); + if (buff==NULL) return 0; + +// switch (mode->datapattern){ +// case CdSecS2064: + ((u32*)buf)[0] = i + 0x30000; + FreezeMMXRegs(1); + memcpy_fast((u8*)buf+12, buff, 2048); + FreezeMMXRegs(0); + buf = (char*)buf + 2064; break; +// default: +// return 0; +// } + } + + return 1; +} + +/************************************************************** +* The functions below are not exported for normal file-system * +* operations, but are used by the file-system operations, and * +* may also be exported for use via RPC * +**************************************************************/ + +int CDVD_GetVolumeDescriptor(void){ + // Read until we find the last valid Volume Descriptor + int volDescSector; + + static struct cdVolDesc localVolDesc; + +#ifdef DEBUG + SysPrintf("CDVD_GetVolumeDescriptor called\n"); +#endif + + for (volDescSector = 16; volDescSector<20; volDescSector++) + { + CdRead(volDescSector,1,&localVolDesc,&cdReadMode); +// CdSync(0x00); + + // If this is still a volume Descriptor + if (strncmp(localVolDesc.volID, "CD001", 5) == 0) + { + if ((localVolDesc.filesystemType == 1) || + (localVolDesc.filesystemType == 2)) + { + FreezeMMXRegs(1); + memcpy_fast(&CDVolDesc, &localVolDesc, sizeof(struct cdVolDesc)); + FreezeMMXRegs(0); + } + } + else + break; + } + +#ifdef DEBUG + if (CDVolDesc.filesystemType == 1) + SysPrintf("CD FileSystem is ISO9660\n"); + else if (CDVolDesc.filesystemType == 2) + SysPrintf("CD FileSystem is Joliet\n"); + else SysPrintf("Could not detect CD FileSystem type\n"); +#endif +// CdStop(); + + return TRUE; +} + +int CDVD_findfile(char* fname, struct TocEntry* tocEntry){ + static char filename[128+1]; + static char pathname[1024+1]; + static char toc[2048]; + char* dirname; + + + static struct TocEntry localTocEntry; // used for internal checking only + + int found_dir; + + int num_dir_sectors; + int current_sector; + + int dir_lba; + + struct dirTocEntry* tocEntryPointer; + +#ifdef DEBUG + SysPrintf("CDVD_findfile called\n"); +#endif + + //make sure we have good cdReadMode + cdReadMode.trycount = 0; + cdReadMode.spindlctrl = CdSpinStm; + cdReadMode.datapattern = CdSecS2048; + + _splitpath2(fname, pathname, filename); + + // Find the TOC for a specific directory + if (CDVD_GetVolumeDescriptor() != TRUE){ +#ifdef RPC_LOG + RPC_LOG("Could not get CD Volume Descriptor\n"); +#endif + return -1; + } + + // Read the TOC of the root directory + if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){ +#ifdef RPC_LOG + RPC_LOG("Couldn't Read from CD !\n"); +#endif + return -1; + } + //CdSync(0x00); + + // point the tocEntryPointer at the first real toc entry + tocEntryPointer = (struct dirTocEntry*)toc; + + num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; //round up fix + current_sector = tocEntryPointer->fileLBA; + + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + + + localTocEntry.fileLBA = CDVolDesc.rootToc.tocLBA; + // while (there are more dir names in the path) + dirname = strtok( pathname, "\\/" ); + + while( dirname != NULL ) + { + found_dir = FALSE; +/* + while(tocEntryPointer->length > 0) + { + // while there are still more directory entries then search through + // for the one we want + + if (tocEntryPointer->fileProperties & 0x02) + { + // Copy the CD format TOC Entry to our format + TocEntryCopy(&localTocEntry, tocEntryPointer); + + // If this TOC Entry is a directory, + // then see if it has the right name + if (strcasecmp(dirname,localTocEntry.filename) == 0) + { + // if the name matches then we've found the directory + found_dir = TRUE; + break; + } + } + + // point to the next entry + (char*)tocEntryPointer += tocEntryPointer->length; + } +*/ + while(1) + { + if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048)) + { + num_dir_sectors--; + + if (num_dir_sectors > 0) + { + // If we've run out of entries, but arent on the last sector + // then load another sector + + current_sector++; + if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE) + { + SysPrintf("Couldn't Read from CD !\n"); + return -1; + } +// CdSync(0x00); + + tocEntryPointer = (struct dirTocEntry*)toc; + } + else + { + // Couldnt find the directory, and got to end of directory + return -1; + } + } + + + if (tocEntryPointer->fileProperties & 0x02) + { + TocEntryCopy(&localTocEntry, tocEntryPointer); + + // If this TOC Entry is a directory, + // then see if it has the right name + if (strcmp(dirname,localTocEntry.filename) == 0) + { + // if the name matches then we've found the directory + found_dir = TRUE; + break; + } + } + + // point to the next entry + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + } + + // If we havent found the directory name we wanted then fail + if (found_dir != TRUE) + { + SysPrintf("CDVD_findfile: could not find dir\n"); + return -1; + } + + // Get next directory name + dirname = strtok( NULL, "\\/" ); + + // Read the TOC of the found subdirectory + if (CdRead(localTocEntry.fileLBA,1,toc,&cdReadMode) != TRUE) + { + SysPrintf("Couldn't Read from CD !\n"); + return -1; + } +// CdSync(0x00); + + num_dir_sectors = (localTocEntry.fileSize+2047) >> 11; //round up fix + current_sector = localTocEntry.fileLBA; + + // and point the tocEntryPointer at the first real toc entry + tocEntryPointer = (struct dirTocEntry*)toc; + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + } + +#ifdef DEBUG + SysPrintf("CDVD_findfile: found dir, now looking for file\n"); +#endif + + tocEntryPointer = (struct dirTocEntry*)toc; + + num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; //round up fix + dir_lba = tocEntryPointer->fileLBA; + + tocEntryPointer = (struct dirTocEntry*)toc; + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + + while (num_dir_sectors > 0) + { + while(tocEntryPointer->length != 0) + { + // Copy the CD format TOC Entry to our format + TocEntryCopy(&localTocEntry, tocEntryPointer); + + if ((strnicmp(localTocEntry.filename, filename, strlen(filename)) == 0) || + ((filename[strlen(filename)-2] == ';') && + (localTocEntry.filename[strlen(localTocEntry.filename)-2] == ';') && + (strnicmp(localTocEntry.filename, filename, strlen(filename)-2) == 0))) + { + // if the filename matches then copy the toc Entry + tocEntry->fileLBA = localTocEntry.fileLBA; + tocEntry->fileProperties = localTocEntry.fileProperties; + tocEntry->fileSize = localTocEntry.fileSize; + + strcpy(tocEntry->filename, localTocEntry.filename); + memcpy(tocEntry->date, localTocEntry.date, 7); + +#ifdef DEBUG + SysPrintf("CDVD_findfile: found file\n"); +#endif + + return TRUE; + } + + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + } + + num_dir_sectors--; + + if (num_dir_sectors > 0) + { + dir_lba++; + + if (CdRead(dir_lba,1,toc,&cdReadMode) != TRUE){ + SysPrintf("Couldn't Read from CD !\n"); + return -1; + } +// CdSync(0x00); + + tocEntryPointer = (struct dirTocEntry*)toc; + } + } + +#ifdef DEBUG + SysPrintf("CDVD_findfile: could not find file\n"); +#endif + + return FALSE; +} + +// This is the RPC-ready function which takes the request to start the tocEntry retrieval +int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_dirs){ +// int dir_depth = 1; + static char toc[2048]; + char* dirname; + int found_dir; + int num_dir_sectors; + unsigned int toc_entry_num; + struct dirTocEntry* tocEntryPointer; + static struct TocEntry localTocEntry; + int current_sector; + + // store the extension list statically for the retrieve function + strncpy(getDirTocData.extension_list, extensions, 128); + getDirTocData.extension_list[128]=0; + + getDirTocData.inc_dirs = inc_dirs; + + // Find the TOC for a specific directory + if (CDVD_GetVolumeDescriptor() != TRUE){ +#ifdef RPC_LOG + RPC_LOG("[RPC:cdvd] Could not get CD Volume Descriptor\n"); +#endif + return -1; + } + +#ifdef RPC_LOG + RPC_LOG("[RPC:cdvd] Getting Directory Listing for: \"%s\"\n", pathname); +#endif + + // Read the TOC of the root directory + if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){ +#ifdef RPC_LOG + RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); +#endif + return -1; + } + //CdSync(0x00); + + // point the tocEntryPointer at the first real toc entry + tocEntryPointer = (struct dirTocEntry*)toc; + + num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; + current_sector = tocEntryPointer->fileLBA; + + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + + // use strtok to get the next dir name + + // if there isnt one, then assume we want the LBA + // for the current one, and exit the while loop + + // if there is another dir name then increment dir_depth + // and look through dir table entries until we find the right name + // if we dont find the right name + // before finding an entry at a higher level (lower num), then return nothing + + localTocEntry.fileLBA = CDVolDesc.rootToc.tocLBA; + + // while (there are more dir names in the path) + dirname = strtok( pathname, "\\/" ); + while( dirname != NULL ){ + found_dir = FALSE; + + while(1){ + if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048)) { + num_dir_sectors--; + + if (num_dir_sectors > 0){ + // If we've run out of entries, but arent on the last sector + // then load another sector + + current_sector++; + if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE){ +#ifdef RPC_LOG + RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); +#endif + return -1; + } + //CdSync(0x00); + + tocEntryPointer = (struct dirTocEntry*)toc; + } + else{ + // Couldnt find the directory, and got to end of directory + return -1; + } + } + + if (tocEntryPointer->fileProperties & 0x02){ + TocEntryCopy(&localTocEntry, tocEntryPointer); + + // If this TOC Entry is a directory, + // then see if it has the right name + if (strcmp(dirname,localTocEntry.filename) == 0){ + // if the name matches then we've found the directory + found_dir = TRUE; +#ifdef RPC_LOG + RPC_LOG("[RPC: ] Found directory %s in subdir at sector %d\n",dirname,current_sector); + RPC_LOG("[RPC: ] LBA of found subdirectory = %d\n",localTocEntry.fileLBA); +#endif + break; + } + } + + // point to the next entry + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + } + + // If we havent found the directory name we wanted then fail + if (found_dir != TRUE) + return -1; + + // Get next directory name + dirname = strtok( NULL, "\\/" ); + + // Read the TOC of the found subdirectory + if (CdRead(localTocEntry.fileLBA,1,toc,&cdReadMode) != TRUE){ +#ifdef RPC_LOG + RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); +#endif + return -1; + } + //CdSync(0x00); + + num_dir_sectors = (localTocEntry.fileSize+2047) >> 11; + current_sector = localTocEntry.fileLBA; + + // and point the tocEntryPointer at the first real toc entry + tocEntryPointer = (struct dirTocEntry*)toc; + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + } + + // We know how much data we need to read in from the DirTocHeader + // but we need to read in at least 1 sector before we can get this value + + // Now we need to COUNT the number of entries (dont do anything with info at this point) + // so set the tocEntryPointer to point to the first actual file entry + + // This is a bit of a waste of reads since we're not actually copying the data out yet, + // but we dont know how big this TOC might be, so we cant allocate a specific size + + tocEntryPointer = (struct dirTocEntry*)toc; + + // Need to STORE the start LBA and number of Sectors, for use by the retrieve func. + getDirTocData.start_LBA = localTocEntry.fileLBA; + getDirTocData.num_sectors = (tocEntryPointer->fileSize+2047) >> 11; + getDirTocData.num_entries = 0; + getDirTocData.current_entry = 0; + getDirTocData.current_sector = getDirTocData.start_LBA; + getDirTocData.current_sector_offset = 0; + + num_dir_sectors = getDirTocData.num_sectors; + + tocEntryPointer = (struct dirTocEntry*)toc; + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + + toc_entry_num=0; + + while(1){ + if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048)){ + // decrease the number of dirs remaining + num_dir_sectors--; + + if (num_dir_sectors > 0){ + // If we've run out of entries, but arent on the last sector + // then load another sector + getDirTocData.current_sector++; + + if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ +#ifdef RPC_LOG + RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); +#endif + return -1; + } + //CdSync(0x00); + + tocEntryPointer = (struct dirTocEntry*)toc; + +// continue; + } + else{ + getDirTocData.num_entries = toc_entry_num; + getDirTocData.current_sector = getDirTocData.start_LBA; + return (toc_entry_num); + } + } + + // We've found a file/dir in this directory + // now check if it matches our extension list (if there is one) + TocEntryCopy(&localTocEntry, tocEntryPointer); + + if (localTocEntry.fileProperties & 0x02){ + // If this is a subdir, then check if we want to include subdirs + if (getDirTocData.inc_dirs){ + toc_entry_num++; + } + } + else{ + if (strlen(getDirTocData.extension_list) > 0){ + if (TocEntryCompare(localTocEntry.filename, getDirTocData.extension_list) == TRUE){ + // increment the number of matching entries counter + toc_entry_num++; + } + } + else{ + toc_entry_num++; + } + } + + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + } + + + // THIS SHOULD BE UNREACHABLE - + // since we are trying to count ALL matching entries, rather than upto a limit + + + // STORE total number of TOC entries + getDirTocData.num_entries = toc_entry_num; + getDirTocData.current_sector = getDirTocData.start_LBA; + + + // we've reached the toc entry limit, so return how many we've done + return (toc_entry_num); + +} + +// This function can be called repeatedly after CDVD_GetDir_RPC_request to get the actual entries +// buffer (tocEntry) must be 18KB in size, and this will be filled with a maximum of 128 entries in one go +int CDVD_GetDir_RPC_get_entries(struct TocEntry tocEntry[], int req_entries){ + static char toc[2048]; + int toc_entry_num; + + struct dirTocEntry* tocEntryPointer; + + if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ +#ifdef RPC_LOG + RPC_LOG("[RPC:cdvd] Couldn't Read from CD !\n"); +#endif + return -1; + } + //CdSync(0x00); + + if (getDirTocData.current_entry == 0){ + // if this is the first read then make sure we point to the first real entry + tocEntryPointer = (struct dirTocEntry*)toc; + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + tocEntryPointer = (struct dirTocEntry*)((char*)tocEntryPointer + tocEntryPointer->length); + + + getDirTocData.current_sector_offset = (char*)tocEntryPointer - toc; + } + else{ + tocEntryPointer = (struct dirTocEntry*)(toc + getDirTocData.current_sector_offset); + } + + if (req_entries > 128) + req_entries = 128; + + for (toc_entry_num=0; toc_entry_num < req_entries;){ + if ((tocEntryPointer->length == 0) || (getDirTocData.current_sector_offset >= 2048)){ + // decrease the number of dirs remaining + getDirTocData.num_sectors--; + + if (getDirTocData.num_sectors > 0){ + // If we've run out of entries, but arent on the last sector + // then load another sector + getDirTocData.current_sector++; + + if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ +#ifdef RPC_LOG + RPC_LOG("[RPC:cdvd] Couldn't Read from CD !\n"); +#endif + return -1; + } + //CdSync(0x00); + + getDirTocData.current_sector_offset = 0; + tocEntryPointer = (struct dirTocEntry*)(toc + getDirTocData.current_sector_offset); + +// continue; + } + else{ + return (toc_entry_num); + } + } + + // This must be incremented even if the filename doesnt match extension list + getDirTocData.current_entry++; + + // We've found a file in this directory + // now check if it matches our extension list (if there is one) + + // Copy the entry regardless, as it makes the comparison easier + // if it doesn't match then it will just be overwritten + TocEntryCopy(&tocEntry[toc_entry_num], tocEntryPointer); + + if (tocEntry[toc_entry_num].fileProperties & 0x02){ + // If this is a subdir, then check if we want to include subdirs + if (getDirTocData.inc_dirs) { + toc_entry_num++; + } + + getDirTocData.current_sector_offset += tocEntryPointer->length; + tocEntryPointer = (struct dirTocEntry*)(toc + getDirTocData.current_sector_offset); + } + else{ + if (strlen(getDirTocData.extension_list) > 0){ + if (TocEntryCompare(tocEntry[toc_entry_num].filename, getDirTocData.extension_list) == TRUE){ + // increment the number of matching entries counter + toc_entry_num++; + } + + getDirTocData.current_sector_offset += tocEntryPointer->length; + tocEntryPointer = (struct dirTocEntry*)(toc + getDirTocData.current_sector_offset); + + } + else{ + toc_entry_num++; + getDirTocData.current_sector_offset += tocEntryPointer->length; + tocEntryPointer = (struct dirTocEntry*)(toc + getDirTocData.current_sector_offset); + } + } +/* + if (strlen(getDirTocData.extension_list) > 0) + { + if (TocEntryCompare(tocEntry[toc_entry_num].filename, getDirTocData.extension_list) == TRUE) + { + + // increment this here, rather than in the main for loop + // since this should count the number of matching entries + toc_entry_num++; + } + + getDirTocData.current_sector_offset += tocEntryPointer->length; + (char*)tocEntryPointer = toc + getDirTocData.current_sector_offset; + } + else + { + toc_entry_num++; + getDirTocData.current_sector_offset += tocEntryPointer->length; + (char*)tocEntryPointer = toc + getDirTocData.current_sector_offset; + } +*/ + } + return (toc_entry_num); +} diff --git a/pcsx2/CDVDiso.h b/pcsx2/CDVDiso.h index 43c7d36..83d43c9 100644 --- a/pcsx2/CDVDiso.h +++ b/pcsx2/CDVDiso.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* * Original code from libcdvd by Hiryu & Sjeep (C) 2002 * Modified by Florin for PCSX2 emu diff --git a/pcsx2/CDVDisodrv.c b/pcsx2/CDVDisodrv.c index c01879c..8985d60 100644 --- a/pcsx2/CDVDisodrv.c +++ b/pcsx2/CDVDisodrv.c @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* * Original code from libcdvd by Hiryu & Sjeep (C) 2002 * Modified by Florin for PCSX2 emu diff --git a/pcsx2/CDVDisodrv.h b/pcsx2/CDVDisodrv.h index dcf8545..9cf3a63 100644 --- a/pcsx2/CDVDisodrv.h +++ b/pcsx2/CDVDisodrv.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* * Original code from libcdvd by Hiryu & Sjeep (C) 2002 * Modified by Florin for PCSX2 emu diff --git a/pcsx2/CDVDlib.h b/pcsx2/CDVDlib.h index e027204..2a96abe 100644 --- a/pcsx2/CDVDlib.h +++ b/pcsx2/CDVDlib.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* * Original code from libcdvd by Hiryu & Sjeep (C) 2002 * Linux kernel headers diff --git a/pcsx2/COP0.c b/pcsx2/COP0.c index 585cf0b..85e4cae 100644 --- a/pcsx2/COP0.c +++ b/pcsx2/COP0.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/pcsx2/COP0.h b/pcsx2/COP0.h index 30ad063..f1c1cb8 100644 --- a/pcsx2/COP0.h +++ b/pcsx2/COP0.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __COP0_H__ diff --git a/pcsx2/Cache.c b/pcsx2/Cache.c index 5e03d7c..67a759e 100644 --- a/pcsx2/Cache.c +++ b/pcsx2/Cache.c @@ -1,391 +1,391 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include "Common.h" -#include "Cache.h" - -#ifndef PCSX2_VIRTUAL_MEM -_cacheS pCache[64]; -int getFreeCache(u32 mem, int mode, int * way) { - u8 * out; - u32 paddr; - u32 taddr[2]; - u8 * t; - int number; - int i = (mem >> 6) & 0x3F; - - paddr = memLUTR[mem >> 12]; - taddr[0] = memLUTW[pCache[i].tag[0]>>12]; - taddr[1] = memLUTW[pCache[i].tag[1]>>12]; - - if (taddr[0] == paddr && (pCache[i].tag[0] & 0x20)) - { - *way = 0; - return i; - }else if(taddr[1] == paddr && (pCache[i].tag[1] & 0x20)) - { - *way = 1; - return i; - } - - number = ((pCache[i].tag[0]>>4) & 1) ^ ((pCache[i].tag[1]>>4) & 1); - - if(pCache[i].tag[number] & 0x60) // Valid Dirty - { - t = (char *)(taddr[number]); - out = (u8*)(t + (mem & 0xFC0)); - ((u64*)out)[0] = ((u64*)pCache[i].data[number][0].b8._8)[0]; - ((u64*)out)[1] = ((u64*)pCache[i].data[number][0].b8._8)[1]; - ((u64*)out)[2] = ((u64*)pCache[i].data[number][1].b8._8)[0]; - ((u64*)out)[3] = ((u64*)pCache[i].data[number][1].b8._8)[1]; - ((u64*)out)[4] = ((u64*)pCache[i].data[number][2].b8._8)[0]; - ((u64*)out)[5] = ((u64*)pCache[i].data[number][2].b8._8)[1]; - ((u64*)out)[6] = ((u64*)pCache[i].data[number][3].b8._8)[0]; - ((u64*)out)[7] = ((u64*)pCache[i].data[number][3].b8._8)[1]; - } - - - - if(mode == 1) - { - pCache[i].tag[number] |= 0x40; // Set Dirty Bit if mode == write - } - - pCache[i].tag[number] &= ~(0xFFFFF000); - pCache[i].tag[number] |= ((mem>>12) & 0xFFFFF) << 12; - - - t = (u8 *)paddr; - out= (u8*)(t + (mem & 0xFC0)); - ((u64*)pCache[i].data[number][0].b8._8)[0] = ((u64*)out)[0]; - ((u64*)pCache[i].data[number][0].b8._8)[1] = ((u64*)out)[1]; - ((u64*)pCache[i].data[number][1].b8._8)[0] = ((u64*)out)[2]; - ((u64*)pCache[i].data[number][1].b8._8)[1] = ((u64*)out)[3]; - ((u64*)pCache[i].data[number][2].b8._8)[0] = ((u64*)out)[4]; - ((u64*)pCache[i].data[number][2].b8._8)[1] = ((u64*)out)[5]; - ((u64*)pCache[i].data[number][3].b8._8)[0] = ((u64*)out)[6]; - ((u64*)pCache[i].data[number][3].b8._8)[1] = ((u64*)out)[7]; - - if(pCache[i].tag[number] & 0x10) pCache[i].tag[number] &= ~(0x10); - else pCache[i].tag[number] |= 0x10; - - pCache[i].tag[number] |= 0x20; - *way = number; - return i; -} - -void writeCache8(u32 mem, u8 value) { - int i, number; - - i = getFreeCache(mem,1,&number); -// CACHE_LOG("writeCache8 %8.8x adding to %d, way %d, value %x\n", mem, i,number,value); - - pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)] = value; -} - -void writeCache16(u32 mem, u16 value) { - int i, number; - - i = getFreeCache(mem,1,&number); -// CACHE_LOG("writeCache16 %8.8x adding to %d, way %d, value %x\n", mem, i,number,value); - - *(u16*)(&pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)]) = value; -} - -void writeCache32(u32 mem, u32 value) { - int i, number; - - i = getFreeCache(mem,1,&number); -// CACHE_LOG("writeCache32 %8.8x adding to %d, way %d, value %x\n", mem, i,number,value); - *(u32*)(&pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)]) = value; -} - -void writeCache64(u32 mem, u64 value) { - int i, number; - - i = getFreeCache(mem,1,&number); -// CACHE_LOG("writeCache64 %8.8x adding to %d, way %d, value %x\n", mem, i,number,value); - *(u64*)(&pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)]) = value; -} - -void writeCache128(u32 mem, u64 *value) { - int i, number; - - i = getFreeCache(mem,1,&number); -// CACHE_LOG("writeCache128 %8.8x adding to %d\n", mem, i); - ((u64*)pCache[i].data[number][(mem>>4) & 0x3].b8._8)[0] = value[0]; - ((u64*)pCache[i].data[number][(mem>>4) & 0x3].b8._8)[1] = value[1]; -} - -u8 *readCache(u32 mem) { - int i, number; - - i = getFreeCache(mem,0,&number); -// CACHE_LOG("readCache %8.8x from %d, way %d\n", mem, i,number); - - return pCache[i].data[number][(mem>>4) & 0x3].b8._8; -} - -extern int Dcache; -void CACHE() { - u32 addr; - //if(Dcache == 0) return; - addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; - switch (_Rt_) { - case 0x1a: - { - int index = (addr >> 6) & 0x3F; - u32 paddr[2]; - int way; - u32 taddr = memLUTR[addr >> 12]; - paddr[0] = memLUTW[pCache[index].tag[0] >> 12]; - paddr[1] = memLUTW[pCache[index].tag[1] >> 12]; - - if(paddr[0] == taddr && (pCache[index].tag[0] & 0x20)) - { - way = 0; - } - else if(paddr[1] == taddr && (pCache[index].tag[1] & 0x20)) - { - way = 1; - } - else - { - return; - } - -#ifdef CACHE_LOG - CACHE_LOG("CACHE DHIN addr %x, index %d, way %d, Flags %x\n",addr,index,way,pCache[index].tag[way] & 0x78); -#endif - pCache[index].tag[way] &= ~(0x6F); - ((u64*)pCache[index].data[way][0].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][0].b8._8)[1] = 0; - ((u64*)pCache[index].data[way][1].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][1].b8._8)[1] = 0; - ((u64*)pCache[index].data[way][2].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][2].b8._8)[1] = 0; - ((u64*)pCache[index].data[way][3].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][3].b8._8)[1] = 0; - break; - } - case 0x18: - { - u8 * out; - int index = (addr >> 6) & 0x3F; - u32 paddr[2]; - int way; - u32 taddr = memLUTW[addr >> 12]; - paddr[0] = memLUTW[pCache[index].tag[0] >> 12]; - paddr[1] = memLUTW[pCache[index].tag[1] >> 12]; - - if(paddr[0] == taddr && (pCache[index].tag[0] & 0x20)) - { - way = 0; - } - else if(paddr[1] == taddr && (pCache[index].tag[1] & 0x20)) - { - way = 1; - } - else - { - return; - } - -#ifdef CACHE_LOG - CACHE_LOG("CACHE DHWBIN addr %x, index %d, way %d, Flags %x\n",addr,index,way,pCache[index].tag[way] & 0x78); -#endif - - if(pCache[index].tag[way] & 0x60) // Valid Dirty - { - char * t = (char *)(taddr);//paddr[way]); - out = (u8*)(t + (addr & 0xFC0)); - ((u64*)out)[0] = ((u64*)pCache[index].data[way][0].b8._8)[0]; - ((u64*)out)[1] = ((u64*)pCache[index].data[way][0].b8._8)[1]; - ((u64*)out)[2] = ((u64*)pCache[index].data[way][1].b8._8)[0]; - ((u64*)out)[3] = ((u64*)pCache[index].data[way][1].b8._8)[1]; - ((u64*)out)[4] = ((u64*)pCache[index].data[way][2].b8._8)[0]; - ((u64*)out)[5] = ((u64*)pCache[index].data[way][2].b8._8)[1]; - ((u64*)out)[6] = ((u64*)pCache[index].data[way][3].b8._8)[0]; - ((u64*)out)[7] = ((u64*)pCache[index].data[way][3].b8._8)[1]; - } - - pCache[index].tag[way] &= ~(0x6F); - ((u64*)pCache[index].data[way][0].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][0].b8._8)[1] = 0; - ((u64*)pCache[index].data[way][1].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][1].b8._8)[1] = 0; - ((u64*)pCache[index].data[way][2].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][2].b8._8)[1] = 0; - ((u64*)pCache[index].data[way][3].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][3].b8._8)[1] = 0; - - break; - } - case 0x1c: - { - u8 * out; - int index = (addr >> 6) & 0x3F; - u32 paddr[2]; - int way; - u32 taddr = memLUTW[addr >> 12]; - paddr[0] = memLUTW[pCache[index].tag[0] >> 12]; - paddr[1] = memLUTW[pCache[index].tag[1] >> 12]; - - if(paddr[0] == taddr && (pCache[index].tag[0] & 0x20)) - { - way = 0; - } - else if(paddr[1] == taddr && (pCache[index].tag[1] & 0x20)) - { - way = 1; - } - else - { - return; - } -#ifdef CACHE_LOG - CACHE_LOG("CACHE DHWOIN addr %x, index %d, way %d, Flags %x\n",addr,index,way,pCache[index].tag[way] & 0x78); -#endif - if(pCache[index].tag[way] & 0x60) // Valid Dirty - { - char * t = (char *)(taddr); - out = (u8*)(t + (addr & 0xFC0)); - ((u64*)out)[0] = ((u64*)pCache[index].data[way][0].b8._8)[0]; - ((u64*)out)[1] = ((u64*)pCache[index].data[way][0].b8._8)[1]; - ((u64*)out)[2] = ((u64*)pCache[index].data[way][1].b8._8)[0]; - ((u64*)out)[3] = ((u64*)pCache[index].data[way][1].b8._8)[1]; - ((u64*)out)[4] = ((u64*)pCache[index].data[way][2].b8._8)[0]; - ((u64*)out)[5] = ((u64*)pCache[index].data[way][2].b8._8)[1]; - ((u64*)out)[6] = ((u64*)pCache[index].data[way][3].b8._8)[0]; - ((u64*)out)[7] = ((u64*)pCache[index].data[way][3].b8._8)[1]; - } - - pCache[index].tag[way] &= ~(0x40); - break; - } - case 0x16: - { - int index = (addr >> 6) & 0x3F; - int way = addr & 0x1; -#ifdef CACHE_LOG - CACHE_LOG("CACHE DXIN addr %x, index %d, way %d, flag %x\n",addr,index,way,pCache[index].tag[way] & 0x78); -#endif - pCache[index].tag[way] &= ~(0x6F); - - ((u64*)pCache[index].data[way][0].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][0].b8._8)[1] = 0; - ((u64*)pCache[index].data[way][1].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][1].b8._8)[1] = 0; - ((u64*)pCache[index].data[way][2].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][2].b8._8)[1] = 0; - ((u64*)pCache[index].data[way][3].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][3].b8._8)[1] = 0; - break; - } - case 0x11: - { - int index = (addr >> 6) & 0x3F; - int way = addr & 0x1; - u8 * out = pCache[index].data[way][(addr>>4) & 0x3].b8._8; - cpuRegs.CP0.r[28] = *(u32 *)(out+(addr&0xf)); -#ifdef CACHE_LOG - CACHE_LOG("CACHE DXLDT addr %x, index %d, way %d, DATA %x\n",addr,index,way,cpuRegs.CP0.r[28]); -#endif - break; - } - case 0x10: - { - int index = (addr >> 6) & 0x3F; - int way = addr & 0x1; - - cpuRegs.CP0.r[28] = 0; - cpuRegs.CP0.r[28] = pCache[index].tag[way]; -#ifdef CACHE_LOG - CACHE_LOG("CACHE DXLTG addr %x, index %d, way %d, DATA %x\n",addr,index,way,cpuRegs.CP0.r[28]); -#endif - break; - } - case 0x13: - { - int index = (addr >> 6) & 0x3F; - int way = addr & 0x1; - u8 * out = pCache[index].data[way][(addr>>4) & 0x3].b8._8; - *(u32*)(&pCache[index].data[way][(addr>>4) & 0x3].b8._8[(addr&0xf)]) = cpuRegs.CP0.r[28]; -#ifdef CACHE_LOG - CACHE_LOG("CACHE DXSDT addr %x, index %d, way %d, DATA %x\n",addr,index,way,cpuRegs.CP0.r[28]); -#endif - break; - } - case 0x12: - { - int index = (addr >> 6) & 0x3F; - int way = addr & 0x1; - pCache[index].tag[way] = cpuRegs.CP0.r[28]; -#ifdef CACHE_LOG - CACHE_LOG("CACHE DXSTG addr %x, index %d, way %d, DATA %x\n",addr,index,way,cpuRegs.CP0.r[28] & 0x6F); -#endif - break; - } - case 0x14: - { - - u8 * out; - int index = (addr >> 6) & 0x3F; - int way = addr & 0x1; - -#ifdef CACHE_LOG - CACHE_LOG("CACHE DXWBIN addr %x, index %d, way %d, Flags %x\n",addr,index,way,pCache[index].tag[way] & 0x78); -#endif - if(pCache[index].tag[way] & 0x60) // Dirty - { - u32 paddr = memLUTW[pCache[index].tag[way] >> 12]; - char * t = (char *)(paddr); - out = (u8*)(t + (addr & 0xFC0)); - ((u64*)out)[0] = ((u64*)pCache[index].data[way][0].b8._8)[0]; - ((u64*)out)[1] = ((u64*)pCache[index].data[way][0].b8._8)[1]; - ((u64*)out)[2] = ((u64*)pCache[index].data[way][1].b8._8)[0]; - ((u64*)out)[3] = ((u64*)pCache[index].data[way][1].b8._8)[1]; - ((u64*)out)[4] = ((u64*)pCache[index].data[way][2].b8._8)[0]; - ((u64*)out)[5] = ((u64*)pCache[index].data[way][2].b8._8)[1]; - ((u64*)out)[6] = ((u64*)pCache[index].data[way][3].b8._8)[0]; - ((u64*)out)[7] = ((u64*)pCache[index].data[way][3].b8._8)[1]; - } - - pCache[index].tag[way] &= ~(0x6F); - ((u64*)pCache[index].data[way][0].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][0].b8._8)[1] = 0; - ((u64*)pCache[index].data[way][1].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][1].b8._8)[1] = 0; - ((u64*)pCache[index].data[way][2].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][2].b8._8)[1] = 0; - ((u64*)pCache[index].data[way][3].b8._8)[0] = 0; - ((u64*)pCache[index].data[way][3].b8._8)[1] = 0; - break; - } - } -} -#else - -void CACHE() { -} - +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include + +#include "Common.h" +#include "Cache.h" + +#ifndef PCSX2_VIRTUAL_MEM +_cacheS pCache[64]; +int getFreeCache(u32 mem, int mode, int * way) { + u8 * out; + u32 paddr; + u32 taddr[2]; + u8 * t; + int number; + int i = (mem >> 6) & 0x3F; + + paddr = memLUTR[mem >> 12]; + taddr[0] = memLUTW[pCache[i].tag[0]>>12]; + taddr[1] = memLUTW[pCache[i].tag[1]>>12]; + + if (taddr[0] == paddr && (pCache[i].tag[0] & 0x20)) + { + *way = 0; + return i; + }else if(taddr[1] == paddr && (pCache[i].tag[1] & 0x20)) + { + *way = 1; + return i; + } + + number = ((pCache[i].tag[0]>>4) & 1) ^ ((pCache[i].tag[1]>>4) & 1); + + if(pCache[i].tag[number] & 0x60) // Valid Dirty + { + t = (char *)(taddr[number]); + out = (u8*)(t + (mem & 0xFC0)); + ((u64*)out)[0] = ((u64*)pCache[i].data[number][0].b8._8)[0]; + ((u64*)out)[1] = ((u64*)pCache[i].data[number][0].b8._8)[1]; + ((u64*)out)[2] = ((u64*)pCache[i].data[number][1].b8._8)[0]; + ((u64*)out)[3] = ((u64*)pCache[i].data[number][1].b8._8)[1]; + ((u64*)out)[4] = ((u64*)pCache[i].data[number][2].b8._8)[0]; + ((u64*)out)[5] = ((u64*)pCache[i].data[number][2].b8._8)[1]; + ((u64*)out)[6] = ((u64*)pCache[i].data[number][3].b8._8)[0]; + ((u64*)out)[7] = ((u64*)pCache[i].data[number][3].b8._8)[1]; + } + + + + if(mode == 1) + { + pCache[i].tag[number] |= 0x40; // Set Dirty Bit if mode == write + } + + pCache[i].tag[number] &= ~(0xFFFFF000); + pCache[i].tag[number] |= ((mem>>12) & 0xFFFFF) << 12; + + + t = (u8 *)paddr; + out= (u8*)(t + (mem & 0xFC0)); + ((u64*)pCache[i].data[number][0].b8._8)[0] = ((u64*)out)[0]; + ((u64*)pCache[i].data[number][0].b8._8)[1] = ((u64*)out)[1]; + ((u64*)pCache[i].data[number][1].b8._8)[0] = ((u64*)out)[2]; + ((u64*)pCache[i].data[number][1].b8._8)[1] = ((u64*)out)[3]; + ((u64*)pCache[i].data[number][2].b8._8)[0] = ((u64*)out)[4]; + ((u64*)pCache[i].data[number][2].b8._8)[1] = ((u64*)out)[5]; + ((u64*)pCache[i].data[number][3].b8._8)[0] = ((u64*)out)[6]; + ((u64*)pCache[i].data[number][3].b8._8)[1] = ((u64*)out)[7]; + + if(pCache[i].tag[number] & 0x10) pCache[i].tag[number] &= ~(0x10); + else pCache[i].tag[number] |= 0x10; + + pCache[i].tag[number] |= 0x20; + *way = number; + return i; +} + +void writeCache8(u32 mem, u8 value) { + int i, number; + + i = getFreeCache(mem,1,&number); +// CACHE_LOG("writeCache8 %8.8x adding to %d, way %d, value %x\n", mem, i,number,value); + + pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)] = value; +} + +void writeCache16(u32 mem, u16 value) { + int i, number; + + i = getFreeCache(mem,1,&number); +// CACHE_LOG("writeCache16 %8.8x adding to %d, way %d, value %x\n", mem, i,number,value); + + *(u16*)(&pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)]) = value; +} + +void writeCache32(u32 mem, u32 value) { + int i, number; + + i = getFreeCache(mem,1,&number); +// CACHE_LOG("writeCache32 %8.8x adding to %d, way %d, value %x\n", mem, i,number,value); + *(u32*)(&pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)]) = value; +} + +void writeCache64(u32 mem, u64 value) { + int i, number; + + i = getFreeCache(mem,1,&number); +// CACHE_LOG("writeCache64 %8.8x adding to %d, way %d, value %x\n", mem, i,number,value); + *(u64*)(&pCache[i].data[number][(mem>>4) & 0x3].b8._8[(mem&0xf)]) = value; +} + +void writeCache128(u32 mem, u64 *value) { + int i, number; + + i = getFreeCache(mem,1,&number); +// CACHE_LOG("writeCache128 %8.8x adding to %d\n", mem, i); + ((u64*)pCache[i].data[number][(mem>>4) & 0x3].b8._8)[0] = value[0]; + ((u64*)pCache[i].data[number][(mem>>4) & 0x3].b8._8)[1] = value[1]; +} + +u8 *readCache(u32 mem) { + int i, number; + + i = getFreeCache(mem,0,&number); +// CACHE_LOG("readCache %8.8x from %d, way %d\n", mem, i,number); + + return pCache[i].data[number][(mem>>4) & 0x3].b8._8; +} + +extern int Dcache; +void CACHE() { + u32 addr; + //if(Dcache == 0) return; + addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; + switch (_Rt_) { + case 0x1a: + { + int index = (addr >> 6) & 0x3F; + u32 paddr[2]; + int way; + u32 taddr = memLUTR[addr >> 12]; + paddr[0] = memLUTW[pCache[index].tag[0] >> 12]; + paddr[1] = memLUTW[pCache[index].tag[1] >> 12]; + + if(paddr[0] == taddr && (pCache[index].tag[0] & 0x20)) + { + way = 0; + } + else if(paddr[1] == taddr && (pCache[index].tag[1] & 0x20)) + { + way = 1; + } + else + { + return; + } + +#ifdef CACHE_LOG + CACHE_LOG("CACHE DHIN addr %x, index %d, way %d, Flags %x\n",addr,index,way,pCache[index].tag[way] & 0x78); +#endif + pCache[index].tag[way] &= ~(0x6F); + ((u64*)pCache[index].data[way][0].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][0].b8._8)[1] = 0; + ((u64*)pCache[index].data[way][1].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][1].b8._8)[1] = 0; + ((u64*)pCache[index].data[way][2].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][2].b8._8)[1] = 0; + ((u64*)pCache[index].data[way][3].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][3].b8._8)[1] = 0; + break; + } + case 0x18: + { + u8 * out; + int index = (addr >> 6) & 0x3F; + u32 paddr[2]; + int way; + u32 taddr = memLUTW[addr >> 12]; + paddr[0] = memLUTW[pCache[index].tag[0] >> 12]; + paddr[1] = memLUTW[pCache[index].tag[1] >> 12]; + + if(paddr[0] == taddr && (pCache[index].tag[0] & 0x20)) + { + way = 0; + } + else if(paddr[1] == taddr && (pCache[index].tag[1] & 0x20)) + { + way = 1; + } + else + { + return; + } + +#ifdef CACHE_LOG + CACHE_LOG("CACHE DHWBIN addr %x, index %d, way %d, Flags %x\n",addr,index,way,pCache[index].tag[way] & 0x78); +#endif + + if(pCache[index].tag[way] & 0x60) // Valid Dirty + { + char * t = (char *)(taddr);//paddr[way]); + out = (u8*)(t + (addr & 0xFC0)); + ((u64*)out)[0] = ((u64*)pCache[index].data[way][0].b8._8)[0]; + ((u64*)out)[1] = ((u64*)pCache[index].data[way][0].b8._8)[1]; + ((u64*)out)[2] = ((u64*)pCache[index].data[way][1].b8._8)[0]; + ((u64*)out)[3] = ((u64*)pCache[index].data[way][1].b8._8)[1]; + ((u64*)out)[4] = ((u64*)pCache[index].data[way][2].b8._8)[0]; + ((u64*)out)[5] = ((u64*)pCache[index].data[way][2].b8._8)[1]; + ((u64*)out)[6] = ((u64*)pCache[index].data[way][3].b8._8)[0]; + ((u64*)out)[7] = ((u64*)pCache[index].data[way][3].b8._8)[1]; + } + + pCache[index].tag[way] &= ~(0x6F); + ((u64*)pCache[index].data[way][0].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][0].b8._8)[1] = 0; + ((u64*)pCache[index].data[way][1].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][1].b8._8)[1] = 0; + ((u64*)pCache[index].data[way][2].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][2].b8._8)[1] = 0; + ((u64*)pCache[index].data[way][3].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][3].b8._8)[1] = 0; + + break; + } + case 0x1c: + { + u8 * out; + int index = (addr >> 6) & 0x3F; + u32 paddr[2]; + int way; + u32 taddr = memLUTW[addr >> 12]; + paddr[0] = memLUTW[pCache[index].tag[0] >> 12]; + paddr[1] = memLUTW[pCache[index].tag[1] >> 12]; + + if(paddr[0] == taddr && (pCache[index].tag[0] & 0x20)) + { + way = 0; + } + else if(paddr[1] == taddr && (pCache[index].tag[1] & 0x20)) + { + way = 1; + } + else + { + return; + } +#ifdef CACHE_LOG + CACHE_LOG("CACHE DHWOIN addr %x, index %d, way %d, Flags %x\n",addr,index,way,pCache[index].tag[way] & 0x78); +#endif + if(pCache[index].tag[way] & 0x60) // Valid Dirty + { + char * t = (char *)(taddr); + out = (u8*)(t + (addr & 0xFC0)); + ((u64*)out)[0] = ((u64*)pCache[index].data[way][0].b8._8)[0]; + ((u64*)out)[1] = ((u64*)pCache[index].data[way][0].b8._8)[1]; + ((u64*)out)[2] = ((u64*)pCache[index].data[way][1].b8._8)[0]; + ((u64*)out)[3] = ((u64*)pCache[index].data[way][1].b8._8)[1]; + ((u64*)out)[4] = ((u64*)pCache[index].data[way][2].b8._8)[0]; + ((u64*)out)[5] = ((u64*)pCache[index].data[way][2].b8._8)[1]; + ((u64*)out)[6] = ((u64*)pCache[index].data[way][3].b8._8)[0]; + ((u64*)out)[7] = ((u64*)pCache[index].data[way][3].b8._8)[1]; + } + + pCache[index].tag[way] &= ~(0x40); + break; + } + case 0x16: + { + int index = (addr >> 6) & 0x3F; + int way = addr & 0x1; +#ifdef CACHE_LOG + CACHE_LOG("CACHE DXIN addr %x, index %d, way %d, flag %x\n",addr,index,way,pCache[index].tag[way] & 0x78); +#endif + pCache[index].tag[way] &= ~(0x6F); + + ((u64*)pCache[index].data[way][0].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][0].b8._8)[1] = 0; + ((u64*)pCache[index].data[way][1].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][1].b8._8)[1] = 0; + ((u64*)pCache[index].data[way][2].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][2].b8._8)[1] = 0; + ((u64*)pCache[index].data[way][3].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][3].b8._8)[1] = 0; + break; + } + case 0x11: + { + int index = (addr >> 6) & 0x3F; + int way = addr & 0x1; + u8 * out = pCache[index].data[way][(addr>>4) & 0x3].b8._8; + cpuRegs.CP0.r[28] = *(u32 *)(out+(addr&0xf)); +#ifdef CACHE_LOG + CACHE_LOG("CACHE DXLDT addr %x, index %d, way %d, DATA %x\n",addr,index,way,cpuRegs.CP0.r[28]); +#endif + break; + } + case 0x10: + { + int index = (addr >> 6) & 0x3F; + int way = addr & 0x1; + + cpuRegs.CP0.r[28] = 0; + cpuRegs.CP0.r[28] = pCache[index].tag[way]; +#ifdef CACHE_LOG + CACHE_LOG("CACHE DXLTG addr %x, index %d, way %d, DATA %x\n",addr,index,way,cpuRegs.CP0.r[28]); +#endif + break; + } + case 0x13: + { + int index = (addr >> 6) & 0x3F; + int way = addr & 0x1; + u8 * out = pCache[index].data[way][(addr>>4) & 0x3].b8._8; + *(u32*)(&pCache[index].data[way][(addr>>4) & 0x3].b8._8[(addr&0xf)]) = cpuRegs.CP0.r[28]; +#ifdef CACHE_LOG + CACHE_LOG("CACHE DXSDT addr %x, index %d, way %d, DATA %x\n",addr,index,way,cpuRegs.CP0.r[28]); +#endif + break; + } + case 0x12: + { + int index = (addr >> 6) & 0x3F; + int way = addr & 0x1; + pCache[index].tag[way] = cpuRegs.CP0.r[28]; +#ifdef CACHE_LOG + CACHE_LOG("CACHE DXSTG addr %x, index %d, way %d, DATA %x\n",addr,index,way,cpuRegs.CP0.r[28] & 0x6F); +#endif + break; + } + case 0x14: + { + + u8 * out; + int index = (addr >> 6) & 0x3F; + int way = addr & 0x1; + +#ifdef CACHE_LOG + CACHE_LOG("CACHE DXWBIN addr %x, index %d, way %d, Flags %x\n",addr,index,way,pCache[index].tag[way] & 0x78); +#endif + if(pCache[index].tag[way] & 0x60) // Dirty + { + u32 paddr = memLUTW[pCache[index].tag[way] >> 12]; + char * t = (char *)(paddr); + out = (u8*)(t + (addr & 0xFC0)); + ((u64*)out)[0] = ((u64*)pCache[index].data[way][0].b8._8)[0]; + ((u64*)out)[1] = ((u64*)pCache[index].data[way][0].b8._8)[1]; + ((u64*)out)[2] = ((u64*)pCache[index].data[way][1].b8._8)[0]; + ((u64*)out)[3] = ((u64*)pCache[index].data[way][1].b8._8)[1]; + ((u64*)out)[4] = ((u64*)pCache[index].data[way][2].b8._8)[0]; + ((u64*)out)[5] = ((u64*)pCache[index].data[way][2].b8._8)[1]; + ((u64*)out)[6] = ((u64*)pCache[index].data[way][3].b8._8)[0]; + ((u64*)out)[7] = ((u64*)pCache[index].data[way][3].b8._8)[1]; + } + + pCache[index].tag[way] &= ~(0x6F); + ((u64*)pCache[index].data[way][0].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][0].b8._8)[1] = 0; + ((u64*)pCache[index].data[way][1].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][1].b8._8)[1] = 0; + ((u64*)pCache[index].data[way][2].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][2].b8._8)[1] = 0; + ((u64*)pCache[index].data[way][3].b8._8)[0] = 0; + ((u64*)pCache[index].data[way][3].b8._8)[1] = 0; + break; + } + } +} +#else + +void CACHE() { +} + #endif \ No newline at end of file diff --git a/pcsx2/Cache.h b/pcsx2/Cache.h index 017b10d..903e2c0 100644 --- a/pcsx2/Cache.h +++ b/pcsx2/Cache.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __CACHE_H__ diff --git a/pcsx2/CdRom.c b/pcsx2/CdRom.c index 717d165..32b50e9 100644 --- a/pcsx2/CdRom.c +++ b/pcsx2/CdRom.c @@ -1,1092 +1,1092 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2007 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -//THIS ALL IS FOR THE CDROM REGISTERS HANDLING -#include "PsxCommon.h" - -#define CdlSync 0 -#define CdlNop 1 -#define CdlSetloc 2 -#define CdlPlay 3 -#define CdlForward 4 -#define CdlBackward 5 -#define CdlReadN 6 -#define CdlStandby 7 -#define CdlStop 8 -#define CdlPause 9 -#define CdlInit 10 -#define CdlMute 11 -#define CdlDemute 12 -#define CdlSetfilter 13 -#define CdlSetmode 14 -#define CdlGetmode 15 -#define CdlGetlocL 16 -#define CdlGetlocP 17 -#define Cdl18 18 -#define CdlGetTN 19 -#define CdlGetTD 20 -#define CdlSeekL 21 -#define CdlSeekP 22 -#define CdlTest 25 -#define CdlID 26 -#define CdlReadS 27 -#define CdlReset 28 -#define CdlReadToc 30 - -#define AUTOPAUSE 249 -#define READ_ACK 250 -#define READ 251 -#define REPPLAY_ACK 252 -#define REPPLAY 253 -#define ASYNC 254 -/* don't set 255, it's reserved */ - -char *CmdName[0x100]= { - "CdlSync", "CdlNop", "CdlSetloc", "CdlPlay", - "CdlForward", "CdlBackward", "CdlReadN", "CdlStandby", - "CdlStop", "CdlPause", "CdlInit", "CdlMute", - "CdlDemute", "CdlSetfilter", "CdlSetmode", "CdlGetmode", - "CdlGetlocL", "CdlGetlocP", "Cdl18", "CdlGetTN", - "CdlGetTD", "CdlSeekL", "CdlSeekP", NULL, - NULL, "CdlTest", "CdlID", "CdlReadS", - "CdlReset", NULL, "CDlReadToc", NULL -}; - -long LoadCdBios; -int cdOpenCase; - -u8 Test04[] = { 0 }; -u8 Test05[] = { 0 }; -u8 Test20[] = { 0x98, 0x06, 0x10, 0xC3 }; -u8 Test22[] = { 0x66, 0x6F, 0x72, 0x20, 0x45, 0x75, 0x72, 0x6F }; -u8 Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 }; - -// 1x = 75 sectors per second -// PSXCLK = 1 sec in the ps -// so (PSXCLK / 75) / BIAS = cdr read time (linuzappz) -//#define cdReadTime ((PSXCLK / 75) / BIAS) -unsigned long cdReadTime;// = ((PSXCLK / 75) / BIAS); - -#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ -#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ - -/*static struct CdrStat stat; -static struct SubQ *subq;*/ - -#define CDR_INT(eCycle) PSX_INT(17, eCycle) -#define CDREAD_INT(eCycle) PSX_INT(18, eCycle) - -#define StartReading(type) { \ - cdr.Reading = type; \ - cdr.FirstSector = 1; \ - cdr.Readed = 0xff; \ - AddIrqQueue(READ_ACK, 0x800); \ -} - -#define StopReading() { \ - if (cdr.Reading) { \ - cdr.Reading = 0; \ - psxRegs.interrupt&=~0x40000; \ - } \ -} - -#define StopCdda() { \ - if (cdr.Play) { \ -/* if (!Config.Cdda) CDR_stop();*/ \ - cdr.StatP&=~0x80; \ - cdr.Play = 0; \ - } \ -} - -#define SetResultSize(size) { \ - cdr.ResultP = 0; \ - cdr.ResultC = size; \ - cdr.ResultReady = 1; \ -} - -s32 MSFtoLSN(u8 *Time) { - u32 lsn; - - lsn = Time[2]; - lsn+=(Time[1] - 2) * 75; - lsn+= Time[0] * 75 * 60; - return lsn; -} - -void LSNtoMSF(u8 *Time, s32 lsn) { - lsn += 150; - Time[2] = lsn / 4500; // minuten - lsn = lsn - Time[2] * 4500; // minuten rest - Time[1] = lsn / 75; // sekunden - Time[0] = lsn - Time[1] * 75; // sekunden rest -} - -void ReadTrack() { - cdr.Prev[0] = itob(cdr.SetSector[0]); - cdr.Prev[1] = itob(cdr.SetSector[1]); - cdr.Prev[2] = itob(cdr.SetSector[2]); - -#ifdef CDR_LOG - CDR_LOG("KEY *** %x:%x:%x\n", cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]); -#endif - cdr.RErr = CDVDreadTrack(MSFtoLSN(cdr.SetSector), CDVD_MODE_2352); -} - -// cdr.Stat: -#define NoIntr 0 -#define DataReady 1 -#define Complete 2 -#define Acknowledge 3 -#define DataEnd 4 -#define DiskError 5 - -void AddIrqQueue(u8 irq, unsigned long ecycle) { - cdr.Irq = irq; - if (cdr.Stat) { - cdr.eCycle = ecycle; - } else { - CDR_INT(ecycle); - } -} - -void cdrInterrupt() { - cdvdTD trackInfo; - int i; - u8 Irq = cdr.Irq; - - if (cdr.Stat) { - CDR_INT(0x800); - return; - } - - cdr.Irq = 0xff; - cdr.Ctrl&=~0x80; - - switch (Irq) { - case CdlSync: - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - break; - - case CdlNop: - SetResultSize(1); - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; -/* i = stat.Status; - if (CDR_getStatus(&stat) != -1) { - if (stat.Type == 0xff) cdr.Stat = DiskError; - if (stat.Status & 0x10) { - cdr.Stat = DiskError; - cdr.Result[0]|= 0x11; - cdr.Result[0]&=~0x02; - } - else if (i & 0x10) { - cdr.StatP |= 0x2; - cdr.Result[0]|= 0x2; - CheckCdrom(); - } - }*/ - break; - - case CdlSetloc: - cdr.CmdProcess = 0; - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - break; - - case CdlPlay: - cdr.CmdProcess = 0; - SetResultSize(1); - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - cdr.StatP|= 0x82; -// if ((cdr.Mode & 0x5) == 0x5) AddIrqQueue(REPPLAY, cdReadTime); - break; - - case CdlForward: - cdr.CmdProcess = 0; - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Complete; - break; - - case CdlBackward: - cdr.CmdProcess = 0; - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Complete; - break; - - case CdlStandby: - cdr.CmdProcess = 0; - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Complete; - break; - - case CdlStop: - cdr.CmdProcess = 0; - SetResultSize(1); - cdr.StatP&=~0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Complete; -// cdr.Stat = Acknowledge; - break; - - case CdlPause: - SetResultSize(1); - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - AddIrqQueue(CdlPause + 0x20, 0x800); - break; - - case CdlPause + 0x20: - SetResultSize(1); - cdr.StatP&=~0x20; - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Complete; - break; - - case CdlInit: - SetResultSize(1); - cdr.StatP = 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; -// if (!cdr.Init) { - AddIrqQueue(CdlInit + 0x20, 0x800); -// } - break; - - case CdlInit + 0x20: - SetResultSize(1); - cdr.Result[0] = cdr.StatP; - cdr.Stat = Complete; - cdr.Init = 1; - break; - - case CdlMute: - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - break; - - case CdlDemute: - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - break; - - case CdlSetfilter: - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - break; - - case CdlSetmode: - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - break; - - case CdlGetmode: - SetResultSize(6); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Result[1] = cdr.Mode; - cdr.Result[2] = cdr.File; - cdr.Result[3] = cdr.Channel; - cdr.Result[4] = 0; - cdr.Result[5] = 0; - cdr.Stat = Acknowledge; - break; - - case CdlGetlocL: - SetResultSize(8); -// for (i=0; i<8; i++) cdr.Result[i] = itob(cdr.Transfer[i]); - for (i=0; i<8; i++) cdr.Result[i] = cdr.Transfer[i]; - cdr.Stat = Acknowledge; - break; - - case CdlGetlocP: - SetResultSize(8); -/* subq = (struct SubQ*) CDR_getBufferSub(); - if (subq != NULL) { - cdr.Result[0] = subq->TrackNumber; - cdr.Result[1] = subq->IndexNumber; - memcpy(cdr.Result+2, subq->TrackRelativeAddress, 3); - memcpy(cdr.Result+5, subq->AbsoluteAddress, 3); - } else { -*/ cdr.Result[0] = 1; - cdr.Result[1] = 1; - cdr.Result[2] = cdr.Prev[0]; - cdr.Result[3] = itob((btoi(cdr.Prev[1])) - 2); - cdr.Result[4] = cdr.Prev[2]; - cdr.Result[5] = cdr.Prev[0]; - cdr.Result[6] = cdr.Prev[1]; - cdr.Result[7] = cdr.Prev[2]; -// } - cdr.Stat = Acknowledge; - break; - - case CdlGetTN: - cdr.CmdProcess = 0; - SetResultSize(3); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - if (CDVDgetTN(&cdr.ResultTN) == -1) { - cdr.Stat = DiskError; - cdr.Result[0]|= 0x01; - } else { - cdr.Stat = Acknowledge; - cdr.Result[1] = itob(cdr.ResultTN.strack); - cdr.Result[2] = itob(cdr.ResultTN.etrack); - } - break; - - case CdlGetTD: - cdr.CmdProcess = 0; - cdr.Track = btoi(cdr.Param[0]); - SetResultSize(4); - cdr.StatP|= 0x2; - if (CDVDgetTD(cdr.Track, &trackInfo) == -1) { - cdr.Stat = DiskError; - cdr.Result[0]|= 0x01; - } else { - LSNtoMSF(cdr.ResultTD, trackInfo.lsn); - cdr.Stat = Acknowledge; - cdr.Result[0] = cdr.StatP; - cdr.Result[1] = itob(cdr.ResultTD[0]); - cdr.Result[2] = itob(cdr.ResultTD[1]); - cdr.Result[3] = itob(cdr.ResultTD[2]); - } - break; - - case CdlSeekL: - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - AddIrqQueue(CdlSeekL + 0x20, 0x800); - break; - - case CdlSeekL + 0x20: - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Complete; - break; - - case CdlSeekP: - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - AddIrqQueue(CdlSeekP + 0x20, 0x800); - break; - - case CdlSeekP + 0x20: - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Complete; - break; - - case CdlTest: - cdr.Stat = Acknowledge; - switch (cdr.Param[0]) { - case 0x20: // System Controller ROM Version - SetResultSize(4); - *(int*)cdr.Result = *(int*)Test20; - break; - case 0x22: - SetResultSize(8); - *(int*)cdr.Result = *(int*)Test22; - break; - case 0x23: case 0x24: - SetResultSize(8); - *(int*)cdr.Result = *(int*)Test23; - break; - } - break; - - case CdlID: - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - AddIrqQueue(CdlID + 0x20, 0x800); - break; - - case CdlID + 0x20: - SetResultSize(8); -// if (CDR_getStatus(&stat) == -1) { - cdr.Result[0] = 0x00; // 0x08 and cdr.Result[1]|0x10 : audio cd, enters cd player - cdr.Result[1] = 0x00; // 0x80 leads to the menu in the bios, else loads CD -/* } - else { - if (stat.Type == 2) { - cdr.Result[0] = 0x08; - cdr.Result[1] = 0x10; - } - else { - cdr.Result[0] = 0x00; - cdr.Result[1] = 0x00; - } - }*/ - if (!LoadCdBios) cdr.Result[1] |= 0x80; - - cdr.Result[2] = 0x00; - cdr.Result[3] = 0x00; - strncpy((char *)&cdr.Result[4], "PCSX", 4); - cdr.Stat = Complete; - break; - - case CdlReset: - SetResultSize(1); - cdr.StatP = 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - break; - - case CdlReadToc: - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - AddIrqQueue(CdlReadToc + 0x20, 0x800); - break; - - case CdlReadToc + 0x20: - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Complete; - break; - - case AUTOPAUSE: - cdr.OCUP = 0; -/* SetResultSize(1); - StopCdda(); - StopReading(); - cdr.OCUP = 0; - cdr.StatP&=~0x20; - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = DataEnd; -*/ AddIrqQueue(CdlPause, 0x400); - break; - - case READ_ACK: - if (!cdr.Reading) { - psxRegs.interrupt&= ~(1 << 17); - return; - } - - SetResultSize(1); - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Acknowledge; - - ReadTrack(); - - CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); - - break; - - case REPPLAY_ACK: - cdr.Stat = Acknowledge; - cdr.Result[0] = cdr.StatP; - SetResultSize(1); - AddIrqQueue(REPPLAY, cdReadTime); - break; - - case REPPLAY: - if ((cdr.Mode & 5) != 5) break; -/* if (CDR_getStatus(&stat) == -1) { - cdr.Result[0] = 0; - cdr.Result[1] = 0; - cdr.Result[2] = 0; - cdr.Result[3] = 0; - cdr.Result[4] = 0; - cdr.Result[5] = 0; - cdr.Result[6] = 0; - cdr.Result[7] = 0; - } else memcpy(cdr.Result, &stat.Track, 8); - cdr.Stat = 1; - SetResultSize(8); - AddIrqQueue(REPPLAY_ACK, cdReadTime); -*/ break; - - case 0xff: - psxRegs.interrupt&= ~(1 << 17); - return; - - default: - cdr.Stat = Complete; - break; - } - - if (cdr.Stat != NoIntr && cdr.Reg2 != 0x18) psxHu32(0x1070)|=0x4; - -#ifdef CDR_LOG - CDR_LOG("Cdr Interrupt %x\n", Irq); -#endif - psxRegs.interrupt&= ~(1 << 17); -} - -void cdrReadInterrupt() { - u8 *buf; - - if (!cdr.Reading) { - psxRegs.interrupt&= ~(1 << 18); - return; - } - - if (cdr.Stat) { - CDREAD_INT(0x800); - return; - } - -#ifdef CDR_LOG - CDR_LOG("KEY END"); -#endif - - cdr.OCUP = 1; - SetResultSize(1); - cdr.StatP|= 0x22; - cdr.Result[0] = cdr.StatP; - - SysMessage("Reading From CDR"); - buf = CDVDgetBuffer(); - if (buf == NULL) cdr.RErr = -1; - - if (cdr.RErr == -1) { -#ifdef CDR_LOG - fprintf(emuLog, " err\n"); -#endif - memset(cdr.Transfer, 0, 2340); - cdr.Stat = DiskError; - cdr.Result[0]|= 0x01; - ReadTrack(); - CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); - return; - } - FreezeMMXRegs(1); - memcpy_fast(cdr.Transfer, buf+12, 2340); - FreezeMMXRegs(0); - cdr.Stat = DataReady; - -#ifdef CDR_LOG - fprintf(emuLog, " %x:%x:%x\n", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); -#endif - -/* if ((cdr.Muted == 1) && (cdr.Mode & 0x40) && (!Config.Xa) && (cdr.FirstSector != -1)) { // CD-XA - if ((cdr.Transfer[4+2] & 0x4) && - ((cdr.Mode&0x8) ? (cdr.Transfer[4+1] == cdr.Channel) : 1) && - (cdr.Transfer[4+0] == cdr.File)) { - int ret = xa_decode_sector(&cdr.Xa, cdr.Transfer+4, cdr.FirstSector); - - if (!ret) { - SPU_playADPCMchannel(&cdr.Xa); - cdr.FirstSector = 0; - } - else cdr.FirstSector = -1; - } - }*/ - - cdr.SetSector[2]++; - if (cdr.SetSector[2] == 75) { - cdr.SetSector[2] = 0; - cdr.SetSector[1]++; - if (cdr.SetSector[1] == 60) { - cdr.SetSector[1] = 0; - cdr.SetSector[0]++; - } - } - - cdr.Readed = 0; - - if ((cdr.Transfer[4+2] & 0x80) && (cdr.Mode & 0x2)) { // EOF -#ifdef CDR_LOG - CDR_LOG("AutoPausing Read\n"); -#endif -// AddIrqQueue(AUTOPAUSE, 0x800); - AddIrqQueue(CdlPause, 0x800); - } - else { - ReadTrack(); - CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); - } - - psxHu32(0x1070)|=0x4; - return; -} - -/* -cdrRead0: - bit 0 - 0 REG1 command send / 1 REG1 data read - bit 1 - 0 data transfer finish / 1 data transfer ready/in progress - bit 2 - unknown - bit 3 - unknown - bit 4 - unknown - bit 5 - 1 result ready - bit 6 - 1 dma ready - bit 7 - 1 command being processed -*/ - -u8 cdrRead0(void) { - if (cdr.ResultReady) cdr.Ctrl|= 0x20; - else cdr.Ctrl&=~0x20; - - if (cdr.OCUP) cdr.Ctrl|= 0x40; - else cdr.Ctrl&=~0x40; - - // what means the 0x10 and the 0x08 bits? i only saw it used by the bios - cdr.Ctrl|=0x18; - -#ifdef CDR_LOG - CDR_LOG("CD0 Read: %x\n", cdr.Ctrl); -#endif - return psxHu8(0x1800) = cdr.Ctrl; -} - -/* -cdrWrite0: - 0 - to send a command / 1 - to get the result -*/ - -void cdrWrite0(u8 rt) { -#ifdef CDR_LOG - CDR_LOG("CD0 write: %x\n", rt); -#endif - cdr.Ctrl = rt | (cdr.Ctrl & ~0x3); - - if (rt == 0) { - cdr.ParamP = 0; - cdr.ParamC = 0; - cdr.ResultReady = 0; - } -} - -u8 cdrRead1(void) { - if (cdr.ResultReady && cdr.Ctrl & 0x1) { - psxHu8(0x1801) = cdr.Result[cdr.ResultP++]; - if (cdr.ResultP == cdr.ResultC) cdr.ResultReady = 0; - } else psxHu8(0x1801) = 0; -#ifdef CDR_LOG - CDR_LOG("CD1 Read: %x\n", psxHu8(0x1801)); -#endif - return psxHu8(0x1801); -} - -void cdrWrite1(u8 rt) { - int i; - -#ifdef CDR_LOG - CDR_LOG("CD1 write: %x (%s)\n", rt, CmdName[rt]); -#endif -// psxHu8(0x1801) = rt; - cdr.Cmd = rt; - cdr.OCUP = 0; - -#ifdef CDRCMD_DEBUG - SysPrintf("CD1 write: %x (%s)", rt, CmdName[rt]); - if (cdr.ParamC) { - SysPrintf(" Param[%d] = {", cdr.ParamC); - for (i=0;i cdr.ResultTN[1]) cdr.CurTrack = cdr.ResultTN[1]; - if (CDR_getTD((u8)(cdr.CurTrack), cdr.ResultTD) != -1) { - int tmp = cdr.ResultTD[2]; - cdr.ResultTD[2] = cdr.ResultTD[0]; - cdr.ResultTD[0] = tmp; - if (!Config.Cdda) CDR_play(cdr.ResultTD); - } - } - } - else if (!Config.Cdda) CDR_play(cdr.SetSector); -*/ cdr.Play = 1; - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlForward: - if (cdr.CurTrack < 0xaa) cdr.CurTrack++; - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlBackward: - if (cdr.CurTrack > 1) cdr.CurTrack--; - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlReadN: - cdr.Irq = 0; - StopReading(); - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - StartReading(1); - break; - - case CdlStandby: - StopCdda(); - StopReading(); - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlStop: - StopCdda(); - StopReading(); - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlPause: - StopCdda(); - StopReading(); - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x40000); - break; - - case CdlReset: - case CdlInit: - StopCdda(); - StopReading(); - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlMute: - cdr.Muted = 0; - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlDemute: - cdr.Muted = 1; - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlSetfilter: - cdr.File = cdr.Param[0]; - cdr.Channel = cdr.Param[1]; - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlSetmode: -#ifdef CDR_LOG - CDR_LOG("Setmode %x\n", cdr.Param[0]); -#endif - cdr.Mode = cdr.Param[0]; - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlGetmode: - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlGetlocL: - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlGetlocP: - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlGetTN: - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlGetTD: - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlSeekL: - ((unsigned long *)cdr.SetSectorSeek)[0] = ((unsigned long *)cdr.SetSector)[0]; - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlSeekP: - ((unsigned long *)cdr.SetSectorSeek)[0] = ((unsigned long *)cdr.SetSector)[0]; - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlTest: - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlID: - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlReadS: - cdr.Irq = 0; - StopReading(); - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - StartReading(2); - break; - - case CdlReadToc: - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - default: -#ifdef CDR_LOG - CDR_LOG("Unknown Cmd: %x\n", cdr.Cmd); -#endif - return; - } - if (cdr.Stat != NoIntr) psxHu32(0x1070)|=0x4; -} - -u8 cdrRead2(void) { - u8 ret; - - if (cdr.Readed == 0) { - ret = 0; - } else { - ret = *cdr.pTransfer++; - } - -#ifdef CDR_LOG - CDR_LOG("CD2 Read: %x\n", ret); -#endif - return ret; -} - -void cdrWrite2(u8 rt) { -#ifdef CDR_LOG - CDR_LOG("CD2 write: %x\n", rt); -#endif - if (cdr.Ctrl & 0x1) { - switch (rt) { - case 0x07: - cdr.ParamP = 0; - cdr.ParamC = 0; - cdr.ResultReady = 0; - cdr.Ctrl = 0; - break; - - default: - cdr.Reg2 = rt; - break; - } - } else if (!(cdr.Ctrl & 0x1) && cdr.ParamP < 8) { - cdr.Param[cdr.ParamP++] = rt; - cdr.ParamC++; - } -} - -u8 cdrRead3(void) { - if (cdr.Stat) { - if (cdr.Ctrl & 0x1) psxHu8(0x1803) = cdr.Stat | 0xE0; - else psxHu8(0x1803) = 0xff; - } else psxHu8(0x1803) = 0; -#ifdef CDR_LOG - CDR_LOG("CD3 Read: %x\n", psxHu8(0x1803)); -#endif - return psxHu8(0x1803); -} - -void cdrWrite3(u8 rt) { -#ifdef CDR_LOG - CDR_LOG("CD3 write: %x\n", rt); -#endif - if (rt == 0x07 && cdr.Ctrl & 0x1) { - cdr.Stat = 0; - - if (cdr.Irq == 0xff) { cdr.Irq = 0; return; } - if (cdr.Irq) { - CDR_INT(cdr.eCycle); - }/* else if (cdr.Reading) { - CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); - }*/ - return; - } - if (rt == 0x80 && !(cdr.Ctrl & 0x1) && cdr.Readed == 0) { - cdr.Readed = 1; - cdr.pTransfer = cdr.Transfer; - - switch (cdr.Mode&0x30) { - case 0x10: - case 0x00: cdr.pTransfer+=12; break; - default: break; - } - } -} - -void psxDma3(u32 madr, u32 bcr, u32 chcr) { - u32 cdsize; - -#ifdef CDR_LOG - CDR_LOG("*** DMA 3 *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); -#endif - - switch (chcr) { - case 0x11000000: - case 0x11400100: - if (cdr.Readed == 0) { -#ifdef CDR_LOG - CDR_LOG("*** DMA 3 *** NOT READY\n"); -#endif - return; - } - - cdsize = (bcr & 0xffff) * 4; - FreezeMMXRegs(1); - memcpy_fast((u8*)PSXM(madr), cdr.pTransfer, cdsize); - FreezeMMXRegs(0); - psxCpu->Clear(madr, cdsize/4); - cdr.pTransfer+=cdsize; - - break; - case 0x41000200: - //SysPrintf("unhandled cdrom dma3: madr: %x, bcr: %x, chcr %x\n", madr, bcr, chcr); - // size = 16 * 32 * 4 (one sector) -/* PSXMu8(madr+0) = 0x10; - PSXMu8(madr+1) = 0x00; - PSXMu8(madr+2) = 0x03; - PSXMu8(madr+3) = 0x00;*/ - return; - - default: -#ifdef CDR_LOG - CDR_LOG("Unknown cddma %lx\n", chcr); -#endif - break; - } - HW_DMA3_CHCR &= ~0x01000000; - psxDmaInterrupt(3); -} - -void cdrReset() { - memset(&cdr, 0, sizeof(cdr)); - cdr.CurTrack=1; - cdr.File=1; cdr.Channel=1; - cdReadTime = (PSXCLK / 1757) * BIAS; - //DVD is 4x (PSXCLK / 75) CD is 24x on the PS2, so that would mean CD = (PSXCLK / 450) - // 75/4 = 18.75 x 24 = 450 remember its faster than the PS1 ;) Refraction - - // with the timing set to 60 Gran Turismo works - // anybody knows why it doesn't with 75? - // 75 is the correct cdrom timing -// if (Config.CdTiming) -// cdReadTime = (PSXCLK / 60) / BIAS; - // this seems to be the most compatible - // let's leave like this until we know why - // 75 is buggy with some games -} - -int cdrFreeze(gzFile f, int Mode) { - int tmp; - - gzfreeze(&cdr, sizeof(cdr)); - - if (Mode == 1) tmp = (int)(cdr.pTransfer - cdr.Transfer); - gzfreeze(&tmp, 4); - if (Mode == 0) cdr.pTransfer = cdr.Transfer + tmp; - - return 0; -} - +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +//THIS ALL IS FOR THE CDROM REGISTERS HANDLING +#include "PsxCommon.h" + +#define CdlSync 0 +#define CdlNop 1 +#define CdlSetloc 2 +#define CdlPlay 3 +#define CdlForward 4 +#define CdlBackward 5 +#define CdlReadN 6 +#define CdlStandby 7 +#define CdlStop 8 +#define CdlPause 9 +#define CdlInit 10 +#define CdlMute 11 +#define CdlDemute 12 +#define CdlSetfilter 13 +#define CdlSetmode 14 +#define CdlGetmode 15 +#define CdlGetlocL 16 +#define CdlGetlocP 17 +#define Cdl18 18 +#define CdlGetTN 19 +#define CdlGetTD 20 +#define CdlSeekL 21 +#define CdlSeekP 22 +#define CdlTest 25 +#define CdlID 26 +#define CdlReadS 27 +#define CdlReset 28 +#define CdlReadToc 30 + +#define AUTOPAUSE 249 +#define READ_ACK 250 +#define READ 251 +#define REPPLAY_ACK 252 +#define REPPLAY 253 +#define ASYNC 254 +/* don't set 255, it's reserved */ + +char *CmdName[0x100]= { + "CdlSync", "CdlNop", "CdlSetloc", "CdlPlay", + "CdlForward", "CdlBackward", "CdlReadN", "CdlStandby", + "CdlStop", "CdlPause", "CdlInit", "CdlMute", + "CdlDemute", "CdlSetfilter", "CdlSetmode", "CdlGetmode", + "CdlGetlocL", "CdlGetlocP", "Cdl18", "CdlGetTN", + "CdlGetTD", "CdlSeekL", "CdlSeekP", NULL, + NULL, "CdlTest", "CdlID", "CdlReadS", + "CdlReset", NULL, "CDlReadToc", NULL +}; + +long LoadCdBios; +int cdOpenCase; + +u8 Test04[] = { 0 }; +u8 Test05[] = { 0 }; +u8 Test20[] = { 0x98, 0x06, 0x10, 0xC3 }; +u8 Test22[] = { 0x66, 0x6F, 0x72, 0x20, 0x45, 0x75, 0x72, 0x6F }; +u8 Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 }; + +// 1x = 75 sectors per second +// PSXCLK = 1 sec in the ps +// so (PSXCLK / 75) / BIAS = cdr read time (linuzappz) +//#define cdReadTime ((PSXCLK / 75) / BIAS) +unsigned long cdReadTime;// = ((PSXCLK / 75) / BIAS); + +#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ +#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ + +/*static struct CdrStat stat; +static struct SubQ *subq;*/ + +#define CDR_INT(eCycle) PSX_INT(17, eCycle) +#define CDREAD_INT(eCycle) PSX_INT(18, eCycle) + +#define StartReading(type) { \ + cdr.Reading = type; \ + cdr.FirstSector = 1; \ + cdr.Readed = 0xff; \ + AddIrqQueue(READ_ACK, 0x800); \ +} + +#define StopReading() { \ + if (cdr.Reading) { \ + cdr.Reading = 0; \ + psxRegs.interrupt&=~0x40000; \ + } \ +} + +#define StopCdda() { \ + if (cdr.Play) { \ +/* if (!Config.Cdda) CDR_stop();*/ \ + cdr.StatP&=~0x80; \ + cdr.Play = 0; \ + } \ +} + +#define SetResultSize(size) { \ + cdr.ResultP = 0; \ + cdr.ResultC = size; \ + cdr.ResultReady = 1; \ +} + +s32 MSFtoLSN(u8 *Time) { + u32 lsn; + + lsn = Time[2]; + lsn+=(Time[1] - 2) * 75; + lsn+= Time[0] * 75 * 60; + return lsn; +} + +void LSNtoMSF(u8 *Time, s32 lsn) { + lsn += 150; + Time[2] = lsn / 4500; // minuten + lsn = lsn - Time[2] * 4500; // minuten rest + Time[1] = lsn / 75; // sekunden + Time[0] = lsn - Time[1] * 75; // sekunden rest +} + +void ReadTrack() { + cdr.Prev[0] = itob(cdr.SetSector[0]); + cdr.Prev[1] = itob(cdr.SetSector[1]); + cdr.Prev[2] = itob(cdr.SetSector[2]); + +#ifdef CDR_LOG + CDR_LOG("KEY *** %x:%x:%x\n", cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]); +#endif + cdr.RErr = CDVDreadTrack(MSFtoLSN(cdr.SetSector), CDVD_MODE_2352); +} + +// cdr.Stat: +#define NoIntr 0 +#define DataReady 1 +#define Complete 2 +#define Acknowledge 3 +#define DataEnd 4 +#define DiskError 5 + +void AddIrqQueue(u8 irq, unsigned long ecycle) { + cdr.Irq = irq; + if (cdr.Stat) { + cdr.eCycle = ecycle; + } else { + CDR_INT(ecycle); + } +} + +void cdrInterrupt() { + cdvdTD trackInfo; + int i; + u8 Irq = cdr.Irq; + + if (cdr.Stat) { + CDR_INT(0x800); + return; + } + + cdr.Irq = 0xff; + cdr.Ctrl&=~0x80; + + switch (Irq) { + case CdlSync: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlNop: + SetResultSize(1); + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; +/* i = stat.Status; + if (CDR_getStatus(&stat) != -1) { + if (stat.Type == 0xff) cdr.Stat = DiskError; + if (stat.Status & 0x10) { + cdr.Stat = DiskError; + cdr.Result[0]|= 0x11; + cdr.Result[0]&=~0x02; + } + else if (i & 0x10) { + cdr.StatP |= 0x2; + cdr.Result[0]|= 0x2; + CheckCdrom(); + } + }*/ + break; + + case CdlSetloc: + cdr.CmdProcess = 0; + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlPlay: + cdr.CmdProcess = 0; + SetResultSize(1); + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + cdr.StatP|= 0x82; +// if ((cdr.Mode & 0x5) == 0x5) AddIrqQueue(REPPLAY, cdReadTime); + break; + + case CdlForward: + cdr.CmdProcess = 0; + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case CdlBackward: + cdr.CmdProcess = 0; + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case CdlStandby: + cdr.CmdProcess = 0; + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case CdlStop: + cdr.CmdProcess = 0; + SetResultSize(1); + cdr.StatP&=~0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; +// cdr.Stat = Acknowledge; + break; + + case CdlPause: + SetResultSize(1); + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + AddIrqQueue(CdlPause + 0x20, 0x800); + break; + + case CdlPause + 0x20: + SetResultSize(1); + cdr.StatP&=~0x20; + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case CdlInit: + SetResultSize(1); + cdr.StatP = 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; +// if (!cdr.Init) { + AddIrqQueue(CdlInit + 0x20, 0x800); +// } + break; + + case CdlInit + 0x20: + SetResultSize(1); + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + cdr.Init = 1; + break; + + case CdlMute: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlDemute: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlSetfilter: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlSetmode: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlGetmode: + SetResultSize(6); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Result[1] = cdr.Mode; + cdr.Result[2] = cdr.File; + cdr.Result[3] = cdr.Channel; + cdr.Result[4] = 0; + cdr.Result[5] = 0; + cdr.Stat = Acknowledge; + break; + + case CdlGetlocL: + SetResultSize(8); +// for (i=0; i<8; i++) cdr.Result[i] = itob(cdr.Transfer[i]); + for (i=0; i<8; i++) cdr.Result[i] = cdr.Transfer[i]; + cdr.Stat = Acknowledge; + break; + + case CdlGetlocP: + SetResultSize(8); +/* subq = (struct SubQ*) CDR_getBufferSub(); + if (subq != NULL) { + cdr.Result[0] = subq->TrackNumber; + cdr.Result[1] = subq->IndexNumber; + memcpy(cdr.Result+2, subq->TrackRelativeAddress, 3); + memcpy(cdr.Result+5, subq->AbsoluteAddress, 3); + } else { +*/ cdr.Result[0] = 1; + cdr.Result[1] = 1; + cdr.Result[2] = cdr.Prev[0]; + cdr.Result[3] = itob((btoi(cdr.Prev[1])) - 2); + cdr.Result[4] = cdr.Prev[2]; + cdr.Result[5] = cdr.Prev[0]; + cdr.Result[6] = cdr.Prev[1]; + cdr.Result[7] = cdr.Prev[2]; +// } + cdr.Stat = Acknowledge; + break; + + case CdlGetTN: + cdr.CmdProcess = 0; + SetResultSize(3); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + if (CDVDgetTN(&cdr.ResultTN) == -1) { + cdr.Stat = DiskError; + cdr.Result[0]|= 0x01; + } else { + cdr.Stat = Acknowledge; + cdr.Result[1] = itob(cdr.ResultTN.strack); + cdr.Result[2] = itob(cdr.ResultTN.etrack); + } + break; + + case CdlGetTD: + cdr.CmdProcess = 0; + cdr.Track = btoi(cdr.Param[0]); + SetResultSize(4); + cdr.StatP|= 0x2; + if (CDVDgetTD(cdr.Track, &trackInfo) == -1) { + cdr.Stat = DiskError; + cdr.Result[0]|= 0x01; + } else { + LSNtoMSF(cdr.ResultTD, trackInfo.lsn); + cdr.Stat = Acknowledge; + cdr.Result[0] = cdr.StatP; + cdr.Result[1] = itob(cdr.ResultTD[0]); + cdr.Result[2] = itob(cdr.ResultTD[1]); + cdr.Result[3] = itob(cdr.ResultTD[2]); + } + break; + + case CdlSeekL: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + AddIrqQueue(CdlSeekL + 0x20, 0x800); + break; + + case CdlSeekL + 0x20: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case CdlSeekP: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + AddIrqQueue(CdlSeekP + 0x20, 0x800); + break; + + case CdlSeekP + 0x20: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case CdlTest: + cdr.Stat = Acknowledge; + switch (cdr.Param[0]) { + case 0x20: // System Controller ROM Version + SetResultSize(4); + *(int*)cdr.Result = *(int*)Test20; + break; + case 0x22: + SetResultSize(8); + *(int*)cdr.Result = *(int*)Test22; + break; + case 0x23: case 0x24: + SetResultSize(8); + *(int*)cdr.Result = *(int*)Test23; + break; + } + break; + + case CdlID: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + AddIrqQueue(CdlID + 0x20, 0x800); + break; + + case CdlID + 0x20: + SetResultSize(8); +// if (CDR_getStatus(&stat) == -1) { + cdr.Result[0] = 0x00; // 0x08 and cdr.Result[1]|0x10 : audio cd, enters cd player + cdr.Result[1] = 0x00; // 0x80 leads to the menu in the bios, else loads CD +/* } + else { + if (stat.Type == 2) { + cdr.Result[0] = 0x08; + cdr.Result[1] = 0x10; + } + else { + cdr.Result[0] = 0x00; + cdr.Result[1] = 0x00; + } + }*/ + if (!LoadCdBios) cdr.Result[1] |= 0x80; + + cdr.Result[2] = 0x00; + cdr.Result[3] = 0x00; + strncpy((char *)&cdr.Result[4], "PCSX", 4); + cdr.Stat = Complete; + break; + + case CdlReset: + SetResultSize(1); + cdr.StatP = 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlReadToc: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + AddIrqQueue(CdlReadToc + 0x20, 0x800); + break; + + case CdlReadToc + 0x20: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case AUTOPAUSE: + cdr.OCUP = 0; +/* SetResultSize(1); + StopCdda(); + StopReading(); + cdr.OCUP = 0; + cdr.StatP&=~0x20; + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = DataEnd; +*/ AddIrqQueue(CdlPause, 0x400); + break; + + case READ_ACK: + if (!cdr.Reading) { + psxRegs.interrupt&= ~(1 << 17); + return; + } + + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + + ReadTrack(); + + CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); + + break; + + case REPPLAY_ACK: + cdr.Stat = Acknowledge; + cdr.Result[0] = cdr.StatP; + SetResultSize(1); + AddIrqQueue(REPPLAY, cdReadTime); + break; + + case REPPLAY: + if ((cdr.Mode & 5) != 5) break; +/* if (CDR_getStatus(&stat) == -1) { + cdr.Result[0] = 0; + cdr.Result[1] = 0; + cdr.Result[2] = 0; + cdr.Result[3] = 0; + cdr.Result[4] = 0; + cdr.Result[5] = 0; + cdr.Result[6] = 0; + cdr.Result[7] = 0; + } else memcpy(cdr.Result, &stat.Track, 8); + cdr.Stat = 1; + SetResultSize(8); + AddIrqQueue(REPPLAY_ACK, cdReadTime); +*/ break; + + case 0xff: + psxRegs.interrupt&= ~(1 << 17); + return; + + default: + cdr.Stat = Complete; + break; + } + + if (cdr.Stat != NoIntr && cdr.Reg2 != 0x18) psxHu32(0x1070)|=0x4; + +#ifdef CDR_LOG + CDR_LOG("Cdr Interrupt %x\n", Irq); +#endif + psxRegs.interrupt&= ~(1 << 17); +} + +void cdrReadInterrupt() { + u8 *buf; + + if (!cdr.Reading) { + psxRegs.interrupt&= ~(1 << 18); + return; + } + + if (cdr.Stat) { + CDREAD_INT(0x800); + return; + } + +#ifdef CDR_LOG + CDR_LOG("KEY END"); +#endif + + cdr.OCUP = 1; + SetResultSize(1); + cdr.StatP|= 0x22; + cdr.Result[0] = cdr.StatP; + + SysMessage("Reading From CDR"); + buf = CDVDgetBuffer(); + if (buf == NULL) cdr.RErr = -1; + + if (cdr.RErr == -1) { +#ifdef CDR_LOG + fprintf(emuLog, " err\n"); +#endif + memset(cdr.Transfer, 0, 2340); + cdr.Stat = DiskError; + cdr.Result[0]|= 0x01; + ReadTrack(); + CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); + return; + } + FreezeMMXRegs(1); + memcpy_fast(cdr.Transfer, buf+12, 2340); + FreezeMMXRegs(0); + cdr.Stat = DataReady; + +#ifdef CDR_LOG + fprintf(emuLog, " %x:%x:%x\n", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); +#endif + +/* if ((cdr.Muted == 1) && (cdr.Mode & 0x40) && (!Config.Xa) && (cdr.FirstSector != -1)) { // CD-XA + if ((cdr.Transfer[4+2] & 0x4) && + ((cdr.Mode&0x8) ? (cdr.Transfer[4+1] == cdr.Channel) : 1) && + (cdr.Transfer[4+0] == cdr.File)) { + int ret = xa_decode_sector(&cdr.Xa, cdr.Transfer+4, cdr.FirstSector); + + if (!ret) { + SPU_playADPCMchannel(&cdr.Xa); + cdr.FirstSector = 0; + } + else cdr.FirstSector = -1; + } + }*/ + + cdr.SetSector[2]++; + if (cdr.SetSector[2] == 75) { + cdr.SetSector[2] = 0; + cdr.SetSector[1]++; + if (cdr.SetSector[1] == 60) { + cdr.SetSector[1] = 0; + cdr.SetSector[0]++; + } + } + + cdr.Readed = 0; + + if ((cdr.Transfer[4+2] & 0x80) && (cdr.Mode & 0x2)) { // EOF +#ifdef CDR_LOG + CDR_LOG("AutoPausing Read\n"); +#endif +// AddIrqQueue(AUTOPAUSE, 0x800); + AddIrqQueue(CdlPause, 0x800); + } + else { + ReadTrack(); + CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); + } + + psxHu32(0x1070)|=0x4; + return; +} + +/* +cdrRead0: + bit 0 - 0 REG1 command send / 1 REG1 data read + bit 1 - 0 data transfer finish / 1 data transfer ready/in progress + bit 2 - unknown + bit 3 - unknown + bit 4 - unknown + bit 5 - 1 result ready + bit 6 - 1 dma ready + bit 7 - 1 command being processed +*/ + +u8 cdrRead0(void) { + if (cdr.ResultReady) cdr.Ctrl|= 0x20; + else cdr.Ctrl&=~0x20; + + if (cdr.OCUP) cdr.Ctrl|= 0x40; + else cdr.Ctrl&=~0x40; + + // what means the 0x10 and the 0x08 bits? i only saw it used by the bios + cdr.Ctrl|=0x18; + +#ifdef CDR_LOG + CDR_LOG("CD0 Read: %x\n", cdr.Ctrl); +#endif + return psxHu8(0x1800) = cdr.Ctrl; +} + +/* +cdrWrite0: + 0 - to send a command / 1 - to get the result +*/ + +void cdrWrite0(u8 rt) { +#ifdef CDR_LOG + CDR_LOG("CD0 write: %x\n", rt); +#endif + cdr.Ctrl = rt | (cdr.Ctrl & ~0x3); + + if (rt == 0) { + cdr.ParamP = 0; + cdr.ParamC = 0; + cdr.ResultReady = 0; + } +} + +u8 cdrRead1(void) { + if (cdr.ResultReady && cdr.Ctrl & 0x1) { + psxHu8(0x1801) = cdr.Result[cdr.ResultP++]; + if (cdr.ResultP == cdr.ResultC) cdr.ResultReady = 0; + } else psxHu8(0x1801) = 0; +#ifdef CDR_LOG + CDR_LOG("CD1 Read: %x\n", psxHu8(0x1801)); +#endif + return psxHu8(0x1801); +} + +void cdrWrite1(u8 rt) { + int i; + +#ifdef CDR_LOG + CDR_LOG("CD1 write: %x (%s)\n", rt, CmdName[rt]); +#endif +// psxHu8(0x1801) = rt; + cdr.Cmd = rt; + cdr.OCUP = 0; + +#ifdef CDRCMD_DEBUG + SysPrintf("CD1 write: %x (%s)", rt, CmdName[rt]); + if (cdr.ParamC) { + SysPrintf(" Param[%d] = {", cdr.ParamC); + for (i=0;i cdr.ResultTN[1]) cdr.CurTrack = cdr.ResultTN[1]; + if (CDR_getTD((u8)(cdr.CurTrack), cdr.ResultTD) != -1) { + int tmp = cdr.ResultTD[2]; + cdr.ResultTD[2] = cdr.ResultTD[0]; + cdr.ResultTD[0] = tmp; + if (!Config.Cdda) CDR_play(cdr.ResultTD); + } + } + } + else if (!Config.Cdda) CDR_play(cdr.SetSector); +*/ cdr.Play = 1; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlForward: + if (cdr.CurTrack < 0xaa) cdr.CurTrack++; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlBackward: + if (cdr.CurTrack > 1) cdr.CurTrack--; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlReadN: + cdr.Irq = 0; + StopReading(); + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + StartReading(1); + break; + + case CdlStandby: + StopCdda(); + StopReading(); + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlStop: + StopCdda(); + StopReading(); + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlPause: + StopCdda(); + StopReading(); + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x40000); + break; + + case CdlReset: + case CdlInit: + StopCdda(); + StopReading(); + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlMute: + cdr.Muted = 0; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlDemute: + cdr.Muted = 1; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlSetfilter: + cdr.File = cdr.Param[0]; + cdr.Channel = cdr.Param[1]; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlSetmode: +#ifdef CDR_LOG + CDR_LOG("Setmode %x\n", cdr.Param[0]); +#endif + cdr.Mode = cdr.Param[0]; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlGetmode: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlGetlocL: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlGetlocP: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlGetTN: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlGetTD: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlSeekL: + ((unsigned long *)cdr.SetSectorSeek)[0] = ((unsigned long *)cdr.SetSector)[0]; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlSeekP: + ((unsigned long *)cdr.SetSectorSeek)[0] = ((unsigned long *)cdr.SetSector)[0]; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlTest: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlID: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlReadS: + cdr.Irq = 0; + StopReading(); + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + StartReading(2); + break; + + case CdlReadToc: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + default: +#ifdef CDR_LOG + CDR_LOG("Unknown Cmd: %x\n", cdr.Cmd); +#endif + return; + } + if (cdr.Stat != NoIntr) psxHu32(0x1070)|=0x4; +} + +u8 cdrRead2(void) { + u8 ret; + + if (cdr.Readed == 0) { + ret = 0; + } else { + ret = *cdr.pTransfer++; + } + +#ifdef CDR_LOG + CDR_LOG("CD2 Read: %x\n", ret); +#endif + return ret; +} + +void cdrWrite2(u8 rt) { +#ifdef CDR_LOG + CDR_LOG("CD2 write: %x\n", rt); +#endif + if (cdr.Ctrl & 0x1) { + switch (rt) { + case 0x07: + cdr.ParamP = 0; + cdr.ParamC = 0; + cdr.ResultReady = 0; + cdr.Ctrl = 0; + break; + + default: + cdr.Reg2 = rt; + break; + } + } else if (!(cdr.Ctrl & 0x1) && cdr.ParamP < 8) { + cdr.Param[cdr.ParamP++] = rt; + cdr.ParamC++; + } +} + +u8 cdrRead3(void) { + if (cdr.Stat) { + if (cdr.Ctrl & 0x1) psxHu8(0x1803) = cdr.Stat | 0xE0; + else psxHu8(0x1803) = 0xff; + } else psxHu8(0x1803) = 0; +#ifdef CDR_LOG + CDR_LOG("CD3 Read: %x\n", psxHu8(0x1803)); +#endif + return psxHu8(0x1803); +} + +void cdrWrite3(u8 rt) { +#ifdef CDR_LOG + CDR_LOG("CD3 write: %x\n", rt); +#endif + if (rt == 0x07 && cdr.Ctrl & 0x1) { + cdr.Stat = 0; + + if (cdr.Irq == 0xff) { cdr.Irq = 0; return; } + if (cdr.Irq) { + CDR_INT(cdr.eCycle); + }/* else if (cdr.Reading) { + CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); + }*/ + return; + } + if (rt == 0x80 && !(cdr.Ctrl & 0x1) && cdr.Readed == 0) { + cdr.Readed = 1; + cdr.pTransfer = cdr.Transfer; + + switch (cdr.Mode&0x30) { + case 0x10: + case 0x00: cdr.pTransfer+=12; break; + default: break; + } + } +} + +void psxDma3(u32 madr, u32 bcr, u32 chcr) { + u32 cdsize; + +#ifdef CDR_LOG + CDR_LOG("*** DMA 3 *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + + switch (chcr) { + case 0x11000000: + case 0x11400100: + if (cdr.Readed == 0) { +#ifdef CDR_LOG + CDR_LOG("*** DMA 3 *** NOT READY\n"); +#endif + return; + } + + cdsize = (bcr & 0xffff) * 4; + FreezeMMXRegs(1); + memcpy_fast((u8*)PSXM(madr), cdr.pTransfer, cdsize); + FreezeMMXRegs(0); + psxCpu->Clear(madr, cdsize/4); + cdr.pTransfer+=cdsize; + + break; + case 0x41000200: + //SysPrintf("unhandled cdrom dma3: madr: %x, bcr: %x, chcr %x\n", madr, bcr, chcr); + // size = 16 * 32 * 4 (one sector) +/* PSXMu8(madr+0) = 0x10; + PSXMu8(madr+1) = 0x00; + PSXMu8(madr+2) = 0x03; + PSXMu8(madr+3) = 0x00;*/ + return; + + default: +#ifdef CDR_LOG + CDR_LOG("Unknown cddma %lx\n", chcr); +#endif + break; + } + HW_DMA3_CHCR &= ~0x01000000; + psxDmaInterrupt(3); +} + +void cdrReset() { + memset(&cdr, 0, sizeof(cdr)); + cdr.CurTrack=1; + cdr.File=1; cdr.Channel=1; + cdReadTime = (PSXCLK / 1757) * BIAS; + //DVD is 4x (PSXCLK / 75) CD is 24x on the PS2, so that would mean CD = (PSXCLK / 450) + // 75/4 = 18.75 x 24 = 450 remember its faster than the PS1 ;) Refraction + + // with the timing set to 60 Gran Turismo works + // anybody knows why it doesn't with 75? + // 75 is the correct cdrom timing +// if (Config.CdTiming) +// cdReadTime = (PSXCLK / 60) / BIAS; + // this seems to be the most compatible + // let's leave like this until we know why + // 75 is buggy with some games +} + +int cdrFreeze(gzFile f, int Mode) { + int tmp; + + gzfreeze(&cdr, sizeof(cdr)); + + if (Mode == 1) tmp = (int)(cdr.pTransfer - cdr.Transfer); + gzfreeze(&tmp, 4); + if (Mode == 0) cdr.pTransfer = cdr.Transfer + tmp; + + return 0; +} + diff --git a/pcsx2/CdRom.h b/pcsx2/CdRom.h index a3b1ef9..fe04f79 100644 --- a/pcsx2/CdRom.h +++ b/pcsx2/CdRom.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __CDROM_H__ diff --git a/pcsx2/Common.h b/pcsx2/Common.h index dad08a4..8f9095d 100644 --- a/pcsx2/Common.h +++ b/pcsx2/Common.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __COMMON_H__ diff --git a/pcsx2/Counters.c b/pcsx2/Counters.c index c77f316..910922d 100644 --- a/pcsx2/Counters.c +++ b/pcsx2/Counters.c @@ -1,277 +1,277 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include -#include -#include -#include "Common.h" -#include "PsxCommon.h" -#include "GS.h" - -u64 profile_starttick = 0; -u64 profile_totalticks = 0; - -int gates = 0; -extern u8 psxhblankgate; -int hblankend = 0; -Counter counters[6]; -u32 nextCounter, nextsCounter; -static void (*s_prevExecuteVU1Block)() = NULL; -LARGE_INTEGER lfreq; - -// its so it doesnt keep triggering an interrupt once its reached its target -// if it doesnt reset the counter it needs stopping -u32 eecntmask = 0; - -void rcntUpdTarget(int index) { - counters[index].sCycleT = cpuRegs.cycle; -} - -void rcntUpd(int index) { - counters[index].sCycle = cpuRegs.cycle; - rcntUpdTarget(index); -} - -void rcntReset(int index) { - counters[index].count = 0; - //counters[index].mode&= ~0x00400C00; - rcntUpd(index); -} - -void rcntSet() { - u32 c; - int i; - - nextCounter = 0xffffffff; - nextsCounter = cpuRegs.cycle; - - for (i = 0; i < 4; i++) { - if (!(counters[i].mode & 0x80) || (counters[i].mode & 0x3) == 0x3) continue; // Stopped - c = ((0x10000 - counters[i].count) * counters[i].rate) - (cpuRegs.cycle - counters[i].sCycleT); - if (c < nextCounter) { - nextCounter = c; - } - - // the + 10 is just in case of overflow - //if(!(counters[i].mode & 0x100) || counters[i].target > 0xffff) continue; - c = ((counters[i].target - counters[i].count) * counters[i].rate) - (cpuRegs.cycle - counters[i].sCycleT); - if (c < nextCounter) { - nextCounter = c; - } - - } - //Calculate HBlank - c = counters[4].CycleT - (cpuRegs.cycle - counters[4].sCycleT); - if (c < nextCounter) { - nextCounter = c; - } - //if(nextCounter > 0x1000) SysPrintf("Nextcounter %x HBlank %x VBlank %x\n", nextCounter, c, counters[5].CycleT - (cpuRegs.cycle - counters[5].sCycleT)); - //Calculate VBlank - c = counters[5].CycleT - (cpuRegs.cycle - counters[5].sCycleT); - if (c < nextCounter) { - nextCounter = c; - } - -} - -void rcntInit() { - int i; - - memset(counters, 0, sizeof(counters)); - - for (i=0; i<4; i++) { - counters[i].rate = 2; - counters[i].target = 0xffff; - } - counters[0].interrupt = 9; - counters[1].interrupt = 10; - counters[2].interrupt = 11; - counters[3].interrupt = 12; - - counters[4].mode = 0x3c0; // The VSync counter mode - counters[5].mode = 0x3c0; - - - - UpdateVSyncRate(); - /*hblankend = 0; - counters[5].mode &= ~0x10000; - counters[4].sCycleT = cpuRegs.cycle; - counters[4].CycleT = HBLANKCNT(1); - counters[4].count = 1; - counters[5].CycleT = VBLANKCNT(1); - counters[5].count = 1; - counters[5].sCycleT = cpuRegs.cycle;*/ - -#ifdef _WIN32 - QueryPerformanceFrequency(&lfreq); -#endif - - for (i=0; i<4; i++) rcntUpd(i); - rcntSet(); - - assert(Cpu != NULL && Cpu->ExecuteVU1Block != NULL ); - s_prevExecuteVU1Block = Cpu->ExecuteVU1Block; -} - -// debug code, used for stats -int g_nCounters[4]; -extern u32 s_lastvsync[2]; -static int iFrame = 0; - -#ifndef _WIN32 -#include -#endif - -u64 iTicks=0; - -u64 GetTickFrequency() -{ -#ifdef _WIN32 - return lfreq.QuadPart; -#else - return 1000000; -#endif -} - -u64 GetCPUTicks() -{ -#ifdef _WIN32 - LARGE_INTEGER count; - QueryPerformanceCounter(&count); - return count.QuadPart; -#else - struct timeval t; - gettimeofday(&t, NULL); - return (u64)t.tv_sec*1000000+t.tv_usec; -#endif -} - - -void UpdateVSyncRate() { - if (Config.PsxType & 1) { - SysPrintf("PAL\n"); - counters[4].Cycle = 227000; - /*if(Config.PsxType & 2)counters[5].rate = PS2VBLANK_PAL_INT; - else counters[5].rate = PS2VBLANK_PAL;*/ - - counters[5].Cycle = 720; - } else { - SysPrintf("NTSC\n"); - counters[4].Cycle = 227000; - /*if(Config.PsxType & 2)counters[5].rate = PS2VBLANK_NTSC_INT; - else counters[5].rate = PS2VBLANK_NTSC;*/ - - counters[5].Cycle = 720; - } - - hblankend = 0; - counters[5].mode &= ~0x10000; - counters[4].sCycleT = cpuRegs.cycle; - counters[4].CycleT = HBLANKCNT(1); - counters[4].count = 1; - counters[5].CycleT = VBLANKCNT(1); - counters[5].count = 1; - counters[5].sCycleT = cpuRegs.cycle; - - //rcntUpdTarget(4); - //counters[4].CycleT = counters[4].rate; - ///rcntUpdTarget(5); - /*counters[5].CycleT = counters[5].rate; - counters[5].Cycle = PS2VBLANKEND;*/ - - { - u32 vsyncs = (Config.PsxType&1) ? 50:60; - if(Config.CustomFps>0) vsyncs = Config.CustomFps; - iTicks = GetTickFrequency()/vsyncs; - SysPrintf("Framelimiter rate updated (UpdateVSyncRate): %d fps\n",vsyncs); - } - rcntSet(); -} - -u32 pauses=0; - -void FrameLimiter() -{ - static u64 iStart=0, iEnd=0, iExpectedEnd=0; - - if(iStart==0) iStart = GetCPUTicks(); - - iExpectedEnd = iStart + iTicks; - iEnd = GetCPUTicks(); - - if(iEnd>=iExpectedEnd) - { - u64 diff = iEnd-iExpectedEnd; - if((diff>>3)>iTicks) iExpectedEnd=iEnd; - } - else do { - Sleep(1); - pauses++; - iEnd = GetCPUTicks(); - } while(iEnd +#include +#include +#include "Common.h" +#include "PsxCommon.h" +#include "GS.h" + +u64 profile_starttick = 0; +u64 profile_totalticks = 0; + +int gates = 0; +extern u8 psxhblankgate; +int hblankend = 0; +Counter counters[6]; +u32 nextCounter, nextsCounter; +static void (*s_prevExecuteVU1Block)() = NULL; +LARGE_INTEGER lfreq; + +// its so it doesnt keep triggering an interrupt once its reached its target +// if it doesnt reset the counter it needs stopping +u32 eecntmask = 0; + +void rcntUpdTarget(int index) { + counters[index].sCycleT = cpuRegs.cycle; +} + +void rcntUpd(int index) { + counters[index].sCycle = cpuRegs.cycle; + rcntUpdTarget(index); +} + +void rcntReset(int index) { + counters[index].count = 0; + //counters[index].mode&= ~0x00400C00; + rcntUpd(index); +} + +void rcntSet() { + u32 c; + int i; + + nextCounter = 0xffffffff; + nextsCounter = cpuRegs.cycle; + + for (i = 0; i < 4; i++) { + if (!(counters[i].mode & 0x80) || (counters[i].mode & 0x3) == 0x3) continue; // Stopped + c = ((0x10000 - counters[i].count) * counters[i].rate) - (cpuRegs.cycle - counters[i].sCycleT); + if (c < nextCounter) { + nextCounter = c; + } + + // the + 10 is just in case of overflow + //if(!(counters[i].mode & 0x100) || counters[i].target > 0xffff) continue; + c = ((counters[i].target - counters[i].count) * counters[i].rate) - (cpuRegs.cycle - counters[i].sCycleT); + if (c < nextCounter) { + nextCounter = c; + } + + } + //Calculate HBlank + c = counters[4].CycleT - (cpuRegs.cycle - counters[4].sCycleT); + if (c < nextCounter) { + nextCounter = c; + } + //if(nextCounter > 0x1000) SysPrintf("Nextcounter %x HBlank %x VBlank %x\n", nextCounter, c, counters[5].CycleT - (cpuRegs.cycle - counters[5].sCycleT)); + //Calculate VBlank + c = counters[5].CycleT - (cpuRegs.cycle - counters[5].sCycleT); + if (c < nextCounter) { + nextCounter = c; + } + +} + +void rcntInit() { + int i; + + memset(counters, 0, sizeof(counters)); + + for (i=0; i<4; i++) { + counters[i].rate = 2; + counters[i].target = 0xffff; + } + counters[0].interrupt = 9; + counters[1].interrupt = 10; + counters[2].interrupt = 11; + counters[3].interrupt = 12; + + counters[4].mode = 0x3c0; // The VSync counter mode + counters[5].mode = 0x3c0; + + + + UpdateVSyncRate(); + /*hblankend = 0; + counters[5].mode &= ~0x10000; + counters[4].sCycleT = cpuRegs.cycle; + counters[4].CycleT = HBLANKCNT(1); + counters[4].count = 1; + counters[5].CycleT = VBLANKCNT(1); + counters[5].count = 1; + counters[5].sCycleT = cpuRegs.cycle;*/ + +#ifdef _WIN32 + QueryPerformanceFrequency(&lfreq); +#endif + + for (i=0; i<4; i++) rcntUpd(i); + rcntSet(); + + assert(Cpu != NULL && Cpu->ExecuteVU1Block != NULL ); + s_prevExecuteVU1Block = Cpu->ExecuteVU1Block; +} + +// debug code, used for stats +int g_nCounters[4]; +extern u32 s_lastvsync[2]; +static int iFrame = 0; + +#ifndef _WIN32 +#include +#endif + +u64 iTicks=0; + +u64 GetTickFrequency() +{ +#ifdef _WIN32 + return lfreq.QuadPart; +#else + return 1000000; +#endif +} + +u64 GetCPUTicks() +{ +#ifdef _WIN32 + LARGE_INTEGER count; + QueryPerformanceCounter(&count); + return count.QuadPart; +#else + struct timeval t; + gettimeofday(&t, NULL); + return (u64)t.tv_sec*1000000+t.tv_usec; +#endif +} + + +void UpdateVSyncRate() { + if (Config.PsxType & 1) { + SysPrintf("PAL\n"); + counters[4].Cycle = 227000; + /*if(Config.PsxType & 2)counters[5].rate = PS2VBLANK_PAL_INT; + else counters[5].rate = PS2VBLANK_PAL;*/ + + counters[5].Cycle = 720; + } else { + SysPrintf("NTSC\n"); + counters[4].Cycle = 227000; + /*if(Config.PsxType & 2)counters[5].rate = PS2VBLANK_NTSC_INT; + else counters[5].rate = PS2VBLANK_NTSC;*/ + + counters[5].Cycle = 720; + } + + hblankend = 0; + counters[5].mode &= ~0x10000; + counters[4].sCycleT = cpuRegs.cycle; + counters[4].CycleT = HBLANKCNT(1); + counters[4].count = 1; + counters[5].CycleT = VBLANKCNT(1); + counters[5].count = 1; + counters[5].sCycleT = cpuRegs.cycle; + + //rcntUpdTarget(4); + //counters[4].CycleT = counters[4].rate; + ///rcntUpdTarget(5); + /*counters[5].CycleT = counters[5].rate; + counters[5].Cycle = PS2VBLANKEND;*/ + + { + u32 vsyncs = (Config.PsxType&1) ? 50:60; + if(Config.CustomFps>0) vsyncs = Config.CustomFps; + iTicks = GetTickFrequency()/vsyncs; + SysPrintf("Framelimiter rate updated (UpdateVSyncRate): %d fps\n",vsyncs); + } + rcntSet(); +} + +u32 pauses=0; + +void FrameLimiter() +{ + static u64 iStart=0, iEnd=0, iExpectedEnd=0; + + if(iStart==0) iStart = GetCPUTicks(); + + iExpectedEnd = iStart + iTicks; + iEnd = GetCPUTicks(); + + if(iEnd>=iExpectedEnd) + { + u64 diff = iEnd-iExpectedEnd; + if((diff>>3)>iTicks) iExpectedEnd=iEnd; + } + else do { + Sleep(1); + pauses++; + iEnd = GetCPUTicks(); + } while(iEnd 0 ) { - if( iFrame > g_TestRun.frame ) { - // take a snapshot - if( g_TestRun.pimagename != NULL && GSmakeSnapshot2 != NULL ) { - if( g_TestRun.snapdone ) { - g_TestRun.curimage++; - g_TestRun.snapdone = 0; - g_TestRun.frame += 20; - if( g_TestRun.curimage >= g_TestRun.numimages ) { - // exit - SysClose(); - exit(0); - } - } - else { - // query for the image - GSmakeSnapshot2(g_TestRun.pimagename, &g_TestRun.snapdone, g_TestRun.jpgcapture); - } - } - else { - // exit - SysClose(); - exit(0); - } - } - } - - GSVSYNC(); - - if( g_SaveGSStream == 1 ) { - freezeData fP; - - g_SaveGSStream = 2; - gsFreeze(g_fGSSave, 1); - - if (GSfreeze(FREEZE_SIZE, &fP) == -1) { - gzclose(g_fGSSave); - g_SaveGSStream = 0; - } - else { - fP.data = (s8*)malloc(fP.size); - if (fP.data == NULL) { - gzclose(g_fGSSave); - g_SaveGSStream = 0; - } - else { - if (GSfreeze(FREEZE_SAVE, &fP) == -1) { - gzclose(g_fGSSave); - g_SaveGSStream = 0; - } - else { - gzwrite(g_fGSSave, &fP.size, sizeof(fP.size)); - if (fP.size) { - gzwrite(g_fGSSave, fP.data, fP.size); - free(fP.data); - } - } - } - } - } - else if( g_SaveGSStream == 2 ) { - - if( --g_nLeftGSFrames <= 0 ) { - gzclose(g_fGSSave); - g_fGSSave = NULL; - g_SaveGSStream = 0; - SysPrintf("Done saving GS stream\n"); - } - } -#endif - - - - - - //counters[5].mode&= ~0x10000; - //UpdateVSyncRate(); - - //SysPrintf("ctrs: %d %d %d %d\n", g_nCounters[0], g_nCounters[1], g_nCounters[2], g_nCounters[3]); - //SysPrintf("vif: %d\n", (((LARGE_INTEGER*)g_nCounters)->QuadPart * 1000000) / lfreq.QuadPart); - //memset(g_nCounters, 0, 16); - counters[5].mode|= 0x10000; - if ((CSRw & 0x8)) - GSCSRr|= 0x8; - - if (!(GSIMR&0x800) ) - gsIrq(); - - hwIntcIrq(2); - psxVSyncStart(); - - if(Config.Patch) applypatch(1); - if(gates)rcntStartGate(0x8); - -// __Log("%u %u 0\n", cpuRegs.cycle-s_lastvsync[1], timeGetTime()-s_lastvsync[0]); -// s_lastvsync[0] = timeGetTime(); -// s_lastvsync[1] = cpuRegs.cycle; - } -} - - -void rcntUpdate() -{ - int i; - u32 change = 0; - for (i=0; i<=3; i++) { - if(gates & (1< 0) SysPrintf("Change saved on %x = %x\n", i, change); - } - - if ((u32)(cpuRegs.cycle - counters[4].sCycleT) >= (u32)counters[4].CycleT && hblankend == 1){ - - - if ((CSRw & 0x4)) - GSCSRr |= 4; // signal - - - if (!(GSIMR&0x400) ) - gsIrq(); - - if(gates)rcntEndGate(0); - if(psxhblankgate)psxCheckEndGate(0); - hblankend = 0; - - counters[4].CycleT = HBLANKCNT(counters[4].count); - } else - if ((u32)(cpuRegs.cycle - counters[4].sCycleT) >= (u32)counters[4].CycleT) { - - if(counters[4].count >= counters[4].Cycle){ - //SysPrintf("%x of %x hblanks reorder in %x cycles cpuRegs.cycle = %x\n", counters[4].count, counters[4].Cycle, cpuRegs.cycle - counters[4].sCycleT, cpuRegs.cycle); - counters[4].sCycleT += HBLANKCNT(counters[4].Cycle); - counters[4].count -= counters[4].Cycle; - - } - //counters[4].sCycleT += HBLANKCNT(1); - counters[4].count++; - - counters[4].CycleT = HBLANKCNT(counters[4].count) - (HBLANKCNT(0.5)); - - rcntStartGate(0); - psxCheckStartGate(0); - hblankend = 1; - //if(cpuRegs.cycle > 0xffff0000 || cpuRegs.cycle < 0x1000 - //SysPrintf("%x hsync done in %x cycles cpuRegs.cycle = %x next will happen on %x\n", counters[4].count, counters[4].CycleT, cpuRegs.cycle, (u32)(counters[4].sCycleT + counters[4].CycleT)); - } - - if((counters[5].mode & 0x10000)){ - if ((cpuRegs.cycle - counters[5].sCycleT) >= counters[5].CycleT){ - //counters[5].sCycleT = cpuRegs.cycle; - counters[5].CycleT = VBLANKCNT(counters[5].count); - VSync(); - } - } else if ((cpuRegs.cycle - counters[5].sCycleT) >= counters[5].CycleT) { - if(counters[5].count >= counters[5].Cycle){ - //SysPrintf("reset %x of %x frames done in %x cycles cpuRegs.cycle = %x\n", counters[5].count, counters[5].Cycle, cpuRegs.cycle - counters[5].sCycleT, cpuRegs.cycle); - counters[5].sCycleT += VBLANKCNT(counters[5].Cycle); - counters[5].count -= counters[5].Cycle; - } - counters[5].count++; - //counters[5].sCycleT += VBLANKCNT(1); - counters[5].CycleT = VBLANKCNT(counters[5].count) - (VBLANKCNT(1)/2); - //SysPrintf("%x frames done in %x cycles cpuRegs.cycle = %x cycletdiff %x\n", counters[5].Cycle, counters[5].sCycleT, cpuRegs.cycle, (counters[5].CycleT - VBLANKCNT(1)) - (cpuRegs.cycle - counters[5].sCycleT)); - VSync(); - } - - for (i=0; i<=3; i++) { - if (!(counters[i].mode & 0x80)) continue; // Stopped - - if ((s64)(counters[i].target - counters[i].count) <= 0 /*&& (counters[i].target & 0xffff) > 0*/) { // Target interrupt - - if((counters[i].target > 0xffff)) { - //SysPrintf("EE Correcting target %x after reset on target\n", i); - counters[i].target &= 0xffff; - } - - if(counters[i].mode & 0x100 ) { -#ifdef EECNT_LOG - EECNT_LOG("EE counter %d target reached mode %x count %x target %x\n", i, counters[i].mode, counters[i].count, counters[i].target); -#endif - - counters[i].mode|= 0x0400; // Target flag - hwIntcIrq(counters[i].interrupt); - if (counters[i].mode & 0x40) { //The PS2 only resets if the interrupt is enabled - Tested on PS2 - - counters[i].count -= counters[i].target; // Reset on target - } - else counters[i].target += 0x10000000; - } else counters[i].target += 0x10000000; - - } - if (counters[i].count > 0xffff) { - - - if (counters[i].mode & 0x0200) { // Overflow interrupt -#ifdef EECNT_LOG - EECNT_LOG("EE counter %d overflow mode %x count %x target %x\n", i, counters[i].mode, counters[i].count, counters[i].target); -#endif - counters[i].mode|= 0x0800; // Overflow flag - hwIntcIrq(counters[i].interrupt); - //SysPrintf("counter[%d] overflow interrupt (%x)\n", i, cpuRegs.cycle); - } - counters[i].count -= 0x10000; - if(counters[i].target > 0xffff) { - //SysPrintf("EE %x Correcting target on overflow\n", i); - counters[i].target &= 0xffff; - } - } - - } - - - rcntSet(); - -} - - - -void rcntWcount(int index, u32 value) { - u32 change = 0; -#ifdef EECNT_LOG - EECNT_LOG("EE count write %d count %x with %x target %x eecycle %x\n", index, counters[index].count, value, counters[index].target, cpuRegs.eCycle); -#endif - counters[index].count = value & 0xffff; - if(counters[index].target > 0xffff) { - counters[index].target &= 0xffff; - //SysPrintf("EE Counter %x count write, target > 0xffff\n", index); - } - //rcntUpd(index); - if((counters[index].mode & 0x3) != 0x3){ - change = cpuRegs.cycle - counters[index].sCycleT; - change -= (change / counters[index].rate) * counters[index].rate; - counters[index].sCycleT = cpuRegs.cycle - change; - }/* else { - SysPrintf("EE Counter %x count write %x\n", index, value); - }*/ - rcntSet(); -} - -void rcntWmode(int index, u32 value) -{ - u32 change = 0; - - - if (value & 0xc00) { //Clear status flags, the ps2 only clears what is given in the value - counters[index].mode &= ~(value & 0xc00); - } - - if(counters[index].mode & 0x80){ - if((counters[index].mode & 0x3) != 0x3){ - change = cpuRegs.cycle - counters[index].sCycleT; - counters[index].count += (int)(change / counters[index].rate); - change -= (change / counters[index].rate) * counters[index].rate; - counters[index].sCycleT = cpuRegs.cycle - change; - } - //if(change != 0) SysPrintf("Weee\n"); - //counters[index].sCycleT = cpuRegs.cycle - ((cpuRegs.cycle - counters[index].sCycleT) % counters[index].rate); - if(!(value & 0x80)) SysPrintf("Stopping\n"); - } - else { - SysPrintf("Counter %d not running c%x s%x c%x\n", index, counters[index].count, counters[index].sCycleT, cpuRegs.cycle); - if(value & 0x80) SysPrintf("Starting %d, v%x\n", index, value); - counters[index].sCycleT = cpuRegs.cycle; - } - //if((value & 0x80) && !(counters[index].mode & 0x80)) rcntUpd(index); //Counter wasnt started, so set the start cycle - - counters[index].mode = (counters[index].mode & 0xc00) | (value & 0x3ff); - -#ifdef EECNT_LOG - EECNT_LOG("EE counter set %d mode %x count %x\n", index, counters[index].mode, rcntCycle(index)); -#endif - /*if((value & 0x3) && (counters[index].mode & 0x3) != 0x3){ - //SysPrintf("Syncing %d with HBLANK clock\n", index); - counters[index].CycleT = counters[4].CycleT; - }*/ - - switch (value & 0x3) { //Clock rate divisers *2, they use BUSCLK speed not PS2CLK - case 0: counters[index].rate = 2; break; - case 1: counters[index].rate = 32; break; - case 2: counters[index].rate = 512; break; - case 3: counters[index].rate = PS2HBLANK; break; - } - - if((counters[index].mode & 0xF) == 0x7) { - gates &= ~(1< 0xffff) && (counters[index].target & 0xffff) > rcntCycle(index)) { - //SysPrintf("EE Correcting target %x after mode write\n", index); - counters[index].target &= 0xffff; - }*/ - rcntSet(); - -} - -void rcntStartGate(int mode){ - int i; - - if(mode == 0){ - for(i = 0; i < 4; i++){ //Update counters using the hblank as the clock - if((counters[i].mode & 0x83) == 0x83) counters[i].count++; - } - } - - for(i=0; i <=3; i++){ //Gates for counters - if(!(gates & (1<> 4); - switch((counters[i].mode & 0x30) >> 4){ - case 0x0: //Count When Signal is low (off) - counters[i].count = rcntRcount(i); - rcntUpd(i); - counters[i].mode &= ~0x80; - break; - case 0x1: //Reset and start counting on Vsync start - counters[i].mode |= 0x80; - rcntReset(i); - counters[i].target &= 0xffff; - break; - case 0x2: //Reset and start counting on Vsync end - //Do Nothing - break; - case 0x3: //Reset and start counting on Vsync start and end - counters[i].mode |= 0x80; - rcntReset(i); - counters[i].target &= 0xffff; - break; - default: - SysPrintf("EE Start Counter %x Gate error\n", i); - break; - } - } -} -void rcntEndGate(int mode){ - int i; - - for(i=0; i <=3; i++){ //Gates for counters - if(!(gates & (1<> 4); - switch((counters[i].mode & 0x30) >> 4){ - case 0x0: //Count When Signal is low (off) - rcntUpd(i); - counters[i].mode |= 0x80; - break; - case 0x1: //Reset and start counting on Vsync start - //Do Nothing - break; - case 0x2: //Reset and start counting on Vsync end - counters[i].mode |= 0x80; - rcntReset(i); - counters[i].target &= 0xffff; - break; - case 0x3: //Reset and start counting on Vsync start and end - counters[i].mode |= 0x80; - rcntReset(i); - counters[i].target &= 0xffff; - break; - default: - SysPrintf("EE Start Counter %x Gate error\n", i); - break; - } - } -} -void rcntWtarget(int index, u32 value) { - -#ifdef EECNT_LOG - EECNT_LOG("EE target write %d target %x value %x\n", index, counters[index].target, value); -#endif - counters[index].target = value & 0xffff; - if(counters[index].target <= rcntCycle(index)/* && counters[index].target != 0*/) { - //SysPrintf("EE Saving target %d from early trigger, target = %x, count = %x\n", index, counters[index].target, rcntCycle(index)); - counters[index].target += 0x10000000; - } - rcntSet(); -} - -void rcntWhold(int index, u32 value) { -#ifdef EECNT_LOG - EECNT_LOG("EE hold write %d value %x\n", index, value); -#endif - counters[index].hold = value; -} - -u16 rcntRcount(int index) { - u16 ret; - - if ((counters[index].mode & 0x80)) { - ret = counters[index].count + (int)((cpuRegs.cycle - counters[index].sCycleT) / counters[index].rate); - }else{ - ret = counters[index].count; - } -#ifdef EECNT_LOG - EECNT_LOG("EE count read %d value %x\n", index, ret); -#endif - return (u16)ret; -} - -u32 rcntCycle(int index) { - - if ((counters[index].mode & 0x80)) { - return (u32)counters[index].count + (int)((cpuRegs.cycle - counters[index].sCycleT) / counters[index].rate); - }else{ - return (u32)counters[index].count; - } -} - -int rcntFreeze(gzFile f, int Mode) { - gzfreezel(counters); - gzfreeze(&nextCounter, sizeof(nextCounter)); - gzfreeze(&nextsCounter, sizeof(nextsCounter)); - - return 0; -} - + + + //SysPrintf("c: %x, %x\n", cpuRegs.cycle, *(u32*)&VU1.Micro[16]); + //if( (iFrame%20) == 0 ) SysPrintf("svu time: %d\n", SuperVUGetRecTimes(1) * 100000 / lfreq.QuadPart); +// if( (iFrame%10) == 0 ) { +// SysPrintf("vu0 time: %d\n", vu0time); +// vu0time = 0; +// } + + +#ifdef PCSX2_DEVBUILD + if( g_TestRun.enabled && g_TestRun.frame > 0 ) { + if( iFrame > g_TestRun.frame ) { + // take a snapshot + if( g_TestRun.pimagename != NULL && GSmakeSnapshot2 != NULL ) { + if( g_TestRun.snapdone ) { + g_TestRun.curimage++; + g_TestRun.snapdone = 0; + g_TestRun.frame += 20; + if( g_TestRun.curimage >= g_TestRun.numimages ) { + // exit + SysClose(); + exit(0); + } + } + else { + // query for the image + GSmakeSnapshot2(g_TestRun.pimagename, &g_TestRun.snapdone, g_TestRun.jpgcapture); + } + } + else { + // exit + SysClose(); + exit(0); + } + } + } + + GSVSYNC(); + + if( g_SaveGSStream == 1 ) { + freezeData fP; + + g_SaveGSStream = 2; + gsFreeze(g_fGSSave, 1); + + if (GSfreeze(FREEZE_SIZE, &fP) == -1) { + gzclose(g_fGSSave); + g_SaveGSStream = 0; + } + else { + fP.data = (s8*)malloc(fP.size); + if (fP.data == NULL) { + gzclose(g_fGSSave); + g_SaveGSStream = 0; + } + else { + if (GSfreeze(FREEZE_SAVE, &fP) == -1) { + gzclose(g_fGSSave); + g_SaveGSStream = 0; + } + else { + gzwrite(g_fGSSave, &fP.size, sizeof(fP.size)); + if (fP.size) { + gzwrite(g_fGSSave, fP.data, fP.size); + free(fP.data); + } + } + } + } + } + else if( g_SaveGSStream == 2 ) { + + if( --g_nLeftGSFrames <= 0 ) { + gzclose(g_fGSSave); + g_fGSSave = NULL; + g_SaveGSStream = 0; + SysPrintf("Done saving GS stream\n"); + } + } +#endif + + + + + + //counters[5].mode&= ~0x10000; + //UpdateVSyncRate(); + + //SysPrintf("ctrs: %d %d %d %d\n", g_nCounters[0], g_nCounters[1], g_nCounters[2], g_nCounters[3]); + //SysPrintf("vif: %d\n", (((LARGE_INTEGER*)g_nCounters)->QuadPart * 1000000) / lfreq.QuadPart); + //memset(g_nCounters, 0, 16); + counters[5].mode|= 0x10000; + if ((CSRw & 0x8)) + GSCSRr|= 0x8; + + if (!(GSIMR&0x800) ) + gsIrq(); + + hwIntcIrq(2); + psxVSyncStart(); + + if(Config.Patch) applypatch(1); + if(gates)rcntStartGate(0x8); + +// __Log("%u %u 0\n", cpuRegs.cycle-s_lastvsync[1], timeGetTime()-s_lastvsync[0]); +// s_lastvsync[0] = timeGetTime(); +// s_lastvsync[1] = cpuRegs.cycle; + } +} + + +void rcntUpdate() +{ + int i; + u32 change = 0; + for (i=0; i<=3; i++) { + if(gates & (1< 0) SysPrintf("Change saved on %x = %x\n", i, change); + } + + if ((u32)(cpuRegs.cycle - counters[4].sCycleT) >= (u32)counters[4].CycleT && hblankend == 1){ + + + if ((CSRw & 0x4)) + GSCSRr |= 4; // signal + + + if (!(GSIMR&0x400) ) + gsIrq(); + + if(gates)rcntEndGate(0); + if(psxhblankgate)psxCheckEndGate(0); + hblankend = 0; + + counters[4].CycleT = HBLANKCNT(counters[4].count); + } else + if ((u32)(cpuRegs.cycle - counters[4].sCycleT) >= (u32)counters[4].CycleT) { + + if(counters[4].count >= counters[4].Cycle){ + //SysPrintf("%x of %x hblanks reorder in %x cycles cpuRegs.cycle = %x\n", counters[4].count, counters[4].Cycle, cpuRegs.cycle - counters[4].sCycleT, cpuRegs.cycle); + counters[4].sCycleT += HBLANKCNT(counters[4].Cycle); + counters[4].count -= counters[4].Cycle; + + } + //counters[4].sCycleT += HBLANKCNT(1); + counters[4].count++; + + counters[4].CycleT = HBLANKCNT(counters[4].count) - (HBLANKCNT(0.5)); + + rcntStartGate(0); + psxCheckStartGate(0); + hblankend = 1; + //if(cpuRegs.cycle > 0xffff0000 || cpuRegs.cycle < 0x1000 + //SysPrintf("%x hsync done in %x cycles cpuRegs.cycle = %x next will happen on %x\n", counters[4].count, counters[4].CycleT, cpuRegs.cycle, (u32)(counters[4].sCycleT + counters[4].CycleT)); + } + + if((counters[5].mode & 0x10000)){ + if ((cpuRegs.cycle - counters[5].sCycleT) >= counters[5].CycleT){ + //counters[5].sCycleT = cpuRegs.cycle; + counters[5].CycleT = VBLANKCNT(counters[5].count); + VSync(); + } + } else if ((cpuRegs.cycle - counters[5].sCycleT) >= counters[5].CycleT) { + if(counters[5].count >= counters[5].Cycle){ + //SysPrintf("reset %x of %x frames done in %x cycles cpuRegs.cycle = %x\n", counters[5].count, counters[5].Cycle, cpuRegs.cycle - counters[5].sCycleT, cpuRegs.cycle); + counters[5].sCycleT += VBLANKCNT(counters[5].Cycle); + counters[5].count -= counters[5].Cycle; + } + counters[5].count++; + //counters[5].sCycleT += VBLANKCNT(1); + counters[5].CycleT = VBLANKCNT(counters[5].count) - (VBLANKCNT(1)/2); + //SysPrintf("%x frames done in %x cycles cpuRegs.cycle = %x cycletdiff %x\n", counters[5].Cycle, counters[5].sCycleT, cpuRegs.cycle, (counters[5].CycleT - VBLANKCNT(1)) - (cpuRegs.cycle - counters[5].sCycleT)); + VSync(); + } + + for (i=0; i<=3; i++) { + if (!(counters[i].mode & 0x80)) continue; // Stopped + + if ((s64)(counters[i].target - counters[i].count) <= 0 /*&& (counters[i].target & 0xffff) > 0*/) { // Target interrupt + + if((counters[i].target > 0xffff)) { + //SysPrintf("EE Correcting target %x after reset on target\n", i); + counters[i].target &= 0xffff; + } + + if(counters[i].mode & 0x100 ) { +#ifdef EECNT_LOG + EECNT_LOG("EE counter %d target reached mode %x count %x target %x\n", i, counters[i].mode, counters[i].count, counters[i].target); +#endif + + counters[i].mode|= 0x0400; // Target flag + hwIntcIrq(counters[i].interrupt); + if (counters[i].mode & 0x40) { //The PS2 only resets if the interrupt is enabled - Tested on PS2 + + counters[i].count -= counters[i].target; // Reset on target + } + else counters[i].target += 0x10000000; + } else counters[i].target += 0x10000000; + + } + if (counters[i].count > 0xffff) { + + + if (counters[i].mode & 0x0200) { // Overflow interrupt +#ifdef EECNT_LOG + EECNT_LOG("EE counter %d overflow mode %x count %x target %x\n", i, counters[i].mode, counters[i].count, counters[i].target); +#endif + counters[i].mode|= 0x0800; // Overflow flag + hwIntcIrq(counters[i].interrupt); + //SysPrintf("counter[%d] overflow interrupt (%x)\n", i, cpuRegs.cycle); + } + counters[i].count -= 0x10000; + if(counters[i].target > 0xffff) { + //SysPrintf("EE %x Correcting target on overflow\n", i); + counters[i].target &= 0xffff; + } + } + + } + + + rcntSet(); + +} + + + +void rcntWcount(int index, u32 value) { + u32 change = 0; +#ifdef EECNT_LOG + EECNT_LOG("EE count write %d count %x with %x target %x eecycle %x\n", index, counters[index].count, value, counters[index].target, cpuRegs.eCycle); +#endif + counters[index].count = value & 0xffff; + if(counters[index].target > 0xffff) { + counters[index].target &= 0xffff; + //SysPrintf("EE Counter %x count write, target > 0xffff\n", index); + } + //rcntUpd(index); + if((counters[index].mode & 0x3) != 0x3){ + change = cpuRegs.cycle - counters[index].sCycleT; + change -= (change / counters[index].rate) * counters[index].rate; + counters[index].sCycleT = cpuRegs.cycle - change; + }/* else { + SysPrintf("EE Counter %x count write %x\n", index, value); + }*/ + rcntSet(); +} + +void rcntWmode(int index, u32 value) +{ + u32 change = 0; + + + if (value & 0xc00) { //Clear status flags, the ps2 only clears what is given in the value + counters[index].mode &= ~(value & 0xc00); + } + + if(counters[index].mode & 0x80){ + if((counters[index].mode & 0x3) != 0x3){ + change = cpuRegs.cycle - counters[index].sCycleT; + counters[index].count += (int)(change / counters[index].rate); + change -= (change / counters[index].rate) * counters[index].rate; + counters[index].sCycleT = cpuRegs.cycle - change; + } + //if(change != 0) SysPrintf("Weee\n"); + //counters[index].sCycleT = cpuRegs.cycle - ((cpuRegs.cycle - counters[index].sCycleT) % counters[index].rate); + if(!(value & 0x80)) SysPrintf("Stopping\n"); + } + else { + SysPrintf("Counter %d not running c%x s%x c%x\n", index, counters[index].count, counters[index].sCycleT, cpuRegs.cycle); + if(value & 0x80) SysPrintf("Starting %d, v%x\n", index, value); + counters[index].sCycleT = cpuRegs.cycle; + } + //if((value & 0x80) && !(counters[index].mode & 0x80)) rcntUpd(index); //Counter wasnt started, so set the start cycle + + counters[index].mode = (counters[index].mode & 0xc00) | (value & 0x3ff); + +#ifdef EECNT_LOG + EECNT_LOG("EE counter set %d mode %x count %x\n", index, counters[index].mode, rcntCycle(index)); +#endif + /*if((value & 0x3) && (counters[index].mode & 0x3) != 0x3){ + //SysPrintf("Syncing %d with HBLANK clock\n", index); + counters[index].CycleT = counters[4].CycleT; + }*/ + + switch (value & 0x3) { //Clock rate divisers *2, they use BUSCLK speed not PS2CLK + case 0: counters[index].rate = 2; break; + case 1: counters[index].rate = 32; break; + case 2: counters[index].rate = 512; break; + case 3: counters[index].rate = PS2HBLANK; break; + } + + if((counters[index].mode & 0xF) == 0x7) { + gates &= ~(1< 0xffff) && (counters[index].target & 0xffff) > rcntCycle(index)) { + //SysPrintf("EE Correcting target %x after mode write\n", index); + counters[index].target &= 0xffff; + }*/ + rcntSet(); + +} + +void rcntStartGate(int mode){ + int i; + + if(mode == 0){ + for(i = 0; i < 4; i++){ //Update counters using the hblank as the clock + if((counters[i].mode & 0x83) == 0x83) counters[i].count++; + } + } + + for(i=0; i <=3; i++){ //Gates for counters + if(!(gates & (1<> 4); + switch((counters[i].mode & 0x30) >> 4){ + case 0x0: //Count When Signal is low (off) + counters[i].count = rcntRcount(i); + rcntUpd(i); + counters[i].mode &= ~0x80; + break; + case 0x1: //Reset and start counting on Vsync start + counters[i].mode |= 0x80; + rcntReset(i); + counters[i].target &= 0xffff; + break; + case 0x2: //Reset and start counting on Vsync end + //Do Nothing + break; + case 0x3: //Reset and start counting on Vsync start and end + counters[i].mode |= 0x80; + rcntReset(i); + counters[i].target &= 0xffff; + break; + default: + SysPrintf("EE Start Counter %x Gate error\n", i); + break; + } + } +} +void rcntEndGate(int mode){ + int i; + + for(i=0; i <=3; i++){ //Gates for counters + if(!(gates & (1<> 4); + switch((counters[i].mode & 0x30) >> 4){ + case 0x0: //Count When Signal is low (off) + rcntUpd(i); + counters[i].mode |= 0x80; + break; + case 0x1: //Reset and start counting on Vsync start + //Do Nothing + break; + case 0x2: //Reset and start counting on Vsync end + counters[i].mode |= 0x80; + rcntReset(i); + counters[i].target &= 0xffff; + break; + case 0x3: //Reset and start counting on Vsync start and end + counters[i].mode |= 0x80; + rcntReset(i); + counters[i].target &= 0xffff; + break; + default: + SysPrintf("EE Start Counter %x Gate error\n", i); + break; + } + } +} +void rcntWtarget(int index, u32 value) { + +#ifdef EECNT_LOG + EECNT_LOG("EE target write %d target %x value %x\n", index, counters[index].target, value); +#endif + counters[index].target = value & 0xffff; + if(counters[index].target <= rcntCycle(index)/* && counters[index].target != 0*/) { + //SysPrintf("EE Saving target %d from early trigger, target = %x, count = %x\n", index, counters[index].target, rcntCycle(index)); + counters[index].target += 0x10000000; + } + rcntSet(); +} + +void rcntWhold(int index, u32 value) { +#ifdef EECNT_LOG + EECNT_LOG("EE hold write %d value %x\n", index, value); +#endif + counters[index].hold = value; +} + +u16 rcntRcount(int index) { + u16 ret; + + if ((counters[index].mode & 0x80)) { + ret = counters[index].count + (int)((cpuRegs.cycle - counters[index].sCycleT) / counters[index].rate); + }else{ + ret = counters[index].count; + } +#ifdef EECNT_LOG + EECNT_LOG("EE count read %d value %x\n", index, ret); +#endif + return (u16)ret; +} + +u32 rcntCycle(int index) { + + if ((counters[index].mode & 0x80)) { + return (u32)counters[index].count + (int)((cpuRegs.cycle - counters[index].sCycleT) / counters[index].rate); + }else{ + return (u32)counters[index].count; + } +} + +int rcntFreeze(gzFile f, int Mode) { + gzfreezel(counters); + gzfreeze(&nextCounter, sizeof(nextCounter)); + gzfreeze(&nextsCounter, sizeof(nextsCounter)); + + return 0; +} + diff --git a/pcsx2/Counters.h b/pcsx2/Counters.h index 8db0188..2c4049e 100644 --- a/pcsx2/Counters.h +++ b/pcsx2/Counters.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __COUNTERS_H__ diff --git a/pcsx2/DebugTools/Debug.h b/pcsx2/DebugTools/Debug.h index 093adaa..1b149bc 100644 --- a/pcsx2/DebugTools/Debug.h +++ b/pcsx2/DebugTools/Debug.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ diff --git a/pcsx2/DebugTools/DisASM.h b/pcsx2/DebugTools/DisASM.h index ceb5917..d7cbcc0 100644 --- a/pcsx2/DebugTools/DisASM.h +++ b/pcsx2/DebugTools/DisASM.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/pcsx2/DebugTools/DisR3000A.c b/pcsx2/DebugTools/DisR3000A.c index d0dad71..d99829d 100644 --- a/pcsx2/DebugTools/DisR3000A.c +++ b/pcsx2/DebugTools/DisR3000A.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include "Debug.h" diff --git a/pcsx2/DebugTools/DisR3000asm.c b/pcsx2/DebugTools/DisR3000asm.c index 4afa2d1..4ffd964 100644 --- a/pcsx2/DebugTools/DisR3000asm.c +++ b/pcsx2/DebugTools/DisR3000asm.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/DebugTools/DisR5900.c b/pcsx2/DebugTools/DisR5900.c index 0c49caf..cecc6f8 100644 --- a/pcsx2/DebugTools/DisR5900.c +++ b/pcsx2/DebugTools/DisR5900.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/DebugTools/DisR5900asm.c b/pcsx2/DebugTools/DisR5900asm.c index e3261d4..7283895 100644 --- a/pcsx2/DebugTools/DisR5900asm.c +++ b/pcsx2/DebugTools/DisR5900asm.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/DebugTools/DisVU0Micro.c b/pcsx2/DebugTools/DisVU0Micro.c index f5d36dc..3fcbe1b 100644 --- a/pcsx2/DebugTools/DisVU0Micro.c +++ b/pcsx2/DebugTools/DisVU0Micro.c @@ -1,22 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +nclude #include #include diff --git a/pcsx2/DebugTools/DisVU1Micro.c b/pcsx2/DebugTools/DisVU1Micro.c index fec3f27..03ba850 100644 --- a/pcsx2/DebugTools/DisVU1Micro.c +++ b/pcsx2/DebugTools/DisVU1Micro.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/DebugTools/DisVUmicro.h b/pcsx2/DebugTools/DisVUmicro.h index e2c5b9e..15caffe 100644 --- a/pcsx2/DebugTools/DisVUmicro.h +++ b/pcsx2/DebugTools/DisVUmicro.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ diff --git a/pcsx2/DebugTools/DisVUops.h b/pcsx2/DebugTools/DisVUops.h index 40cf978..fb43a9d 100644 --- a/pcsx2/DebugTools/DisVUops.h +++ b/pcsx2/DebugTools/DisVUops.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ diff --git a/pcsx2/DebugTools/cpuopsDebug.c b/pcsx2/DebugTools/cpuopsDebug.c index 99d6baf..a19058b 100644 --- a/pcsx2/DebugTools/cpuopsDebug.c +++ b/pcsx2/DebugTools/cpuopsDebug.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include "Common.h" diff --git a/pcsx2/DebugTools/cpuopsDebug.h b/pcsx2/DebugTools/cpuopsDebug.h index 3422693..ff3cdb2 100644 --- a/pcsx2/DebugTools/cpuopsDebug.h +++ b/pcsx2/DebugTools/cpuopsDebug.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ void UpdateR5900op(); diff --git a/pcsx2/Decode_XA.c b/pcsx2/Decode_XA.c index 3bd53f4..f75d5ac 100644 --- a/pcsx2/Decode_XA.c +++ b/pcsx2/Decode_XA.c @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ //============================================ //=== Audio XA decoding //=== Kazzuya diff --git a/pcsx2/Decode_XA.h b/pcsx2/Decode_XA.h index d363fb4..40262f2 100644 --- a/pcsx2/Decode_XA.h +++ b/pcsx2/Decode_XA.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ //============================================ //=== Audio XA decoding //=== Kazzuya diff --git a/pcsx2/EEregs.h b/pcsx2/EEregs.h index a25b709..2af2517 100644 --- a/pcsx2/EEregs.h +++ b/pcsx2/EEregs.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __EEREGS_H__ diff --git a/pcsx2/Elfheader.c b/pcsx2/Elfheader.c index fd66f0c..5c08032 100644 --- a/pcsx2/Elfheader.c +++ b/pcsx2/Elfheader.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/Elfheader.h b/pcsx2/Elfheader.h index 2b35157..8f986bd 100644 --- a/pcsx2/Elfheader.h +++ b/pcsx2/Elfheader.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __ELF_H__ diff --git a/pcsx2/FPU.c b/pcsx2/FPU.c index dda1001..2ba749d 100644 --- a/pcsx2/FPU.c +++ b/pcsx2/FPU.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include "Common.h" diff --git a/pcsx2/FPU2.cpp b/pcsx2/FPU2.cpp index fbda9e9..e182329 100644 --- a/pcsx2/FPU2.cpp +++ b/pcsx2/FPU2.cpp @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include // sqrtf only defined in C++ diff --git a/pcsx2/FiFo.c b/pcsx2/FiFo.c index 0e6e6bf..8726073 100644 --- a/pcsx2/FiFo.c +++ b/pcsx2/FiFo.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/GS.cpp b/pcsx2/GS.cpp index 3b5e111..86f607c 100644 --- a/pcsx2/GS.cpp +++ b/pcsx2/GS.cpp @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ // rewritten by zerofrog to add multithreading/gs caching to GS and VU1 diff --git a/pcsx2/GS.h b/pcsx2/GS.h index 52534e7..9bdd5d5 100644 --- a/pcsx2/GS.h +++ b/pcsx2/GS.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __GS_H__ diff --git a/pcsx2/Hw.c b/pcsx2/Hw.c index 2d1e101..2df4c9f 100644 --- a/pcsx2/Hw.c +++ b/pcsx2/Hw.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include diff --git a/pcsx2/Hw.h b/pcsx2/Hw.h index ffb56fa..0a83c3d 100644 --- a/pcsx2/Hw.h +++ b/pcsx2/Hw.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __HW_H__ diff --git a/pcsx2/IPU/IPU.c b/pcsx2/IPU/IPU.c index 8ce8911..5dc349c 100644 --- a/pcsx2/IPU/IPU.c +++ b/pcsx2/IPU/IPU.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include "Common.h" #include "IPU.h" diff --git a/pcsx2/IPU/IPU.h b/pcsx2/IPU/IPU.h index 313b6c3..aff55a5 100644 --- a/pcsx2/IPU/IPU.h +++ b/pcsx2/IPU/IPU.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __IPU_H__ diff --git a/pcsx2/IPU/acoroutine.asm b/pcsx2/IPU/acoroutine.asm index 4214ed5..d81a5f1 100644 --- a/pcsx2/IPU/acoroutine.asm +++ b/pcsx2/IPU/acoroutine.asm @@ -1,5 +1,5 @@ ; Pcsx2 - Pc Ps2 Emulator -; Copyright (C) 2002-2007 Pcsx2 Team +; Copyright (C) 2002-2008 Pcsx2 Team ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software -; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ;; x86-64 coroutine fucntions extern g_pCurrentRoutine:ptr diff --git a/pcsx2/IPU/coroutine.c b/pcsx2/IPU/coroutine.c index f5253b7..3bdf105 100644 --- a/pcsx2/IPU/coroutine.c +++ b/pcsx2/IPU/coroutine.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/pcsx2/IPU/coroutine.h b/pcsx2/IPU/coroutine.h index 4197cbd..4d0f3e1 100644 --- a/pcsx2/IPU/coroutine.h +++ b/pcsx2/IPU/coroutine.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef PCSX2_COROUTINE_LIB diff --git a/pcsx2/IPU/mpeg2lib/Idct.c b/pcsx2/IPU/mpeg2lib/Idct.c index c6f3ce8..b8d9fff 100644 --- a/pcsx2/IPU/mpeg2lib/Idct.c +++ b/pcsx2/IPU/mpeg2lib/Idct.c @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ //#include diff --git a/pcsx2/IPU/mpeg2lib/Mpeg.c b/pcsx2/IPU/mpeg2lib/Mpeg.c index caea77f..64a485f 100644 --- a/pcsx2/IPU/mpeg2lib/Mpeg.c +++ b/pcsx2/IPU/mpeg2lib/Mpeg.c @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "Mpeg.h" diff --git a/pcsx2/IPU/mpeg2lib/Mpeg.h b/pcsx2/IPU/mpeg2lib/Mpeg.h index 551ea80..5c570fe 100644 --- a/pcsx2/IPU/mpeg2lib/Mpeg.h +++ b/pcsx2/IPU/mpeg2lib/Mpeg.h @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __MPEG_H__ diff --git a/pcsx2/IPU/mpeg2lib/Vlc.h b/pcsx2/IPU/mpeg2lib/Vlc.h index 7eacf64..503267b 100644 --- a/pcsx2/IPU/mpeg2lib/Vlc.h +++ b/pcsx2/IPU/mpeg2lib/Vlc.h @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __VLC_H__ diff --git a/pcsx2/IPU/yuv2rgb.c b/pcsx2/IPU/yuv2rgb.c index 17d6c0c..c7df6a9 100644 --- a/pcsx2/IPU/yuv2rgb.c +++ b/pcsx2/IPU/yuv2rgb.c @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/pcsx2/IPU/yuv2rgb.h b/pcsx2/IPU/yuv2rgb.h index d9d4d9c..d53c32f 100644 --- a/pcsx2/IPU/yuv2rgb.h +++ b/pcsx2/IPU/yuv2rgb.h @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef YUV2RGB_H diff --git a/pcsx2/InterTables.c b/pcsx2/InterTables.c index 5f79905..9c5ad0d 100644 --- a/pcsx2/InterTables.c +++ b/pcsx2/InterTables.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ //all tables for R5900 are define here.. diff --git a/pcsx2/InterTables.h b/pcsx2/InterTables.h index 5788826..e6f0ce6 100644 --- a/pcsx2/InterTables.h +++ b/pcsx2/InterTables.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef INTERTABLES_H #define INTERTABLES_H diff --git a/pcsx2/Interpreter.c b/pcsx2/Interpreter.c index 69b8905..d9c7405 100644 --- a/pcsx2/Interpreter.c +++ b/pcsx2/Interpreter.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/pcsx2/Linux/Config.c b/pcsx2/Linux/Config.c index 68bacec..05a5214 100644 --- a/pcsx2/Linux/Config.c +++ b/pcsx2/Linux/Config.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/pcsx2/Linux/GtkGui.c b/pcsx2/Linux/GtkGui.c index 973972f..c3f1764 100644 --- a/pcsx2/Linux/GtkGui.c +++ b/pcsx2/Linux/GtkGui.c @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include #include diff --git a/pcsx2/Linux/Linux.h b/pcsx2/Linux/Linux.h index cc966bb..816476c 100644 --- a/pcsx2/Linux/Linux.h +++ b/pcsx2/Linux/Linux.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __LINUX_H__ diff --git a/pcsx2/Linux/LnxMain.c b/pcsx2/Linux/LnxMain.c index 500649f..6f242a4 100644 --- a/pcsx2/Linux/LnxMain.c +++ b/pcsx2/Linux/LnxMain.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/Linux/callbacks.h b/pcsx2/Linux/callbacks.h index 4bec544..83aabc0 100644 --- a/pcsx2/Linux/callbacks.h +++ b/pcsx2/Linux/callbacks.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include diff --git a/pcsx2/Linux/interface.c b/pcsx2/Linux/interface.c index 2004b8d..84e1f67 100644 --- a/pcsx2/Linux/interface.c +++ b/pcsx2/Linux/interface.c @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* * DO NOT EDIT THIS FILE - it is generated by Glade. */ diff --git a/pcsx2/Linux/interface.h b/pcsx2/Linux/interface.h index 5ddcaf7..fad1ec7 100644 --- a/pcsx2/Linux/interface.h +++ b/pcsx2/Linux/interface.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* * DO NOT EDIT THIS FILE - it is generated by Glade. */ diff --git a/pcsx2/Linux/support.c b/pcsx2/Linux/support.c index 00aff29..a3c79b3 100644 --- a/pcsx2/Linux/support.c +++ b/pcsx2/Linux/support.c @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* * DO NOT EDIT THIS FILE - it is generated by Glade. */ diff --git a/pcsx2/Linux/support.h b/pcsx2/Linux/support.h index a32649e..9168053 100644 --- a/pcsx2/Linux/support.h +++ b/pcsx2/Linux/support.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* * DO NOT EDIT THIS FILE - it is generated by Glade. */ diff --git a/pcsx2/MMI.c b/pcsx2/MMI.c index 0f30d5e..16fcdbe 100644 --- a/pcsx2/MMI.c +++ b/pcsx2/MMI.c @@ -1,21 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include "Common.h" diff --git a/pcsx2/Mdec.c b/pcsx2/Mdec.c index babc7a9..85f133b 100644 --- a/pcsx2/Mdec.c +++ b/pcsx2/Mdec.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* This code was based on the FPSE v0.08 Mdec decoder*/ diff --git a/pcsx2/Mdec.h b/pcsx2/Mdec.h index 33690c9..bc01be8 100644 --- a/pcsx2/Mdec.h +++ b/pcsx2/Mdec.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __MDEC_H__ diff --git a/pcsx2/Memory.c b/pcsx2/Memory.c index a91d329..fc4c544 100644 --- a/pcsx2/Memory.c +++ b/pcsx2/Memory.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* diff --git a/pcsx2/Memory.h b/pcsx2/Memory.h index 199d14e..684d86d 100644 --- a/pcsx2/Memory.h +++ b/pcsx2/Memory.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ ////////// diff --git a/pcsx2/Misc.c b/pcsx2/Misc.c index b7c0cf8..2d4de0a 100644 --- a/pcsx2/Misc.c +++ b/pcsx2/Misc.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/pcsx2/Misc.h b/pcsx2/Misc.h index fda03ca..e0b6b22 100644 --- a/pcsx2/Misc.h +++ b/pcsx2/Misc.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2007 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __MISC_H__ diff --git a/pcsx2/PS2Edefs.h b/pcsx2/PS2Edefs.h index 32dd484..bea99e3 100644 --- a/pcsx2/PS2Edefs.h +++ b/pcsx2/PS2Edefs.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef __PS2EDEFS_H__ #define __PS2EDEFS_H__ diff --git a/pcsx2/PS2Etypes.h b/pcsx2/PS2Etypes.h index 101dba9..797d0f8 100644 --- a/pcsx2/PS2Etypes.h +++ b/pcsx2/PS2Etypes.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef __PS2ETYPES_H__ #define __PS2ETYPES_H__ diff --git a/pcsx2/Patch.c b/pcsx2/Patch.c index 3b72608..b0d19ca 100644 --- a/pcsx2/Patch.c +++ b/pcsx2/Patch.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ // // Includes diff --git a/pcsx2/Patch.h b/pcsx2/Patch.h index 63aef6d..fe724ab 100644 --- a/pcsx2/Patch.h +++ b/pcsx2/Patch.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef __PATCH_H__ #define __PATCH_H__ diff --git a/pcsx2/Plugins.c b/pcsx2/Plugins.c index b20768a..7836ac7 100644 --- a/pcsx2/Plugins.c +++ b/pcsx2/Plugins.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/Plugins.h b/pcsx2/Plugins.h index fb53b7f..cb62404 100644 --- a/pcsx2/Plugins.h +++ b/pcsx2/Plugins.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __PLUGINS_H__ diff --git a/pcsx2/PsxBios.c b/pcsx2/PsxBios.c index 2e1495e..24fecad 100644 --- a/pcsx2/PsxBios.c +++ b/pcsx2/PsxBios.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/PsxBios.h b/pcsx2/PsxBios.h index 1ac0fe7..43f533c 100644 --- a/pcsx2/PsxBios.h +++ b/pcsx2/PsxBios.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __PSXBIOS_H__ diff --git a/pcsx2/PsxBios2.h b/pcsx2/PsxBios2.h index a0c6640..52e995b 100644 --- a/pcsx2/PsxBios2.h +++ b/pcsx2/PsxBios2.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /***** sysmem imageInfo diff --git a/pcsx2/PsxCommon.h b/pcsx2/PsxCommon.h index 23e1c60..3153327 100644 --- a/pcsx2/PsxCommon.h +++ b/pcsx2/PsxCommon.h @@ -1,4 +1,4 @@ -/* Pcsx2 - Pc Ps2 Emulator * Copyright (C) 2002-2003 Pcsx2 Team +/* Pcsx2 - Pc Ps2 Emulator * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -12,7 +12,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __PSXCOMMON_H__ diff --git a/pcsx2/PsxCounters.c b/pcsx2/PsxCounters.c index 64ee9a5..2f62f9d 100644 --- a/pcsx2/PsxCounters.c +++ b/pcsx2/PsxCounters.c @@ -1,801 +1,801 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include "PsxCommon.h" - -psxCounter psxCounters[8]; -u32 psxNextCounter, psxNextsCounter; -static int cnts = 6; -u8 psxhblankgate = 0; -u8 psxvblankgate = 0; -u8 psxcntmask = 0; - -static void psxRcntUpd16(u32 index) { - psxCounters[index].sCycleT = psxRegs.cycle; -} - -static void psxRcntUpd32(u32 index) { - psxCounters[index].sCycleT = psxRegs.cycle; -} - -static void psxRcntReset16(u32 index) { - psxCounters[index].count = 0; - - psxCounters[index].mode&= ~0x18301C00; - psxRcntUpd16(index); -} - -static void psxRcntReset32(u32 index) { - psxCounters[index].count = 0; - - psxCounters[index].mode&= ~0x18301C00; - psxRcntUpd32(index); -} - -static void psxRcntSet() { - u64 c; - int i; - - psxNextCounter = 0xffffffff; - psxNextsCounter = psxRegs.cycle; - - for (i=0; i<3; i++) { - if(psxCounters[i].rate == PSXHBLANK) continue; - c = (u64)((0x10000 - psxCounters[i].count) * psxCounters[i].rate) - (psxRegs.cycle - psxCounters[i].sCycleT); - if (c < psxNextCounter) { - psxNextCounter = (u32)c; - } - //if((psxCounters[i].mode & 0x10) == 0 || psxCounters[i].target > 0xffff) continue; - c = (u64)((psxCounters[i].target - psxCounters[i].count) * psxCounters[i].rate) - (psxRegs.cycle - psxCounters[i].sCycleT); - if (c < psxNextCounter) { - psxNextCounter = (u32)c; - } - - } - for (i=3; i<6; i++) { - if(psxCounters[i].rate == PSXHBLANK) continue; - c = (u64)((0x100000000 - psxCounters[i].count) * psxCounters[i].rate) - (psxRegs.cycle - psxCounters[i].sCycleT); - if (c < psxNextCounter) { - psxNextCounter = (u32)c; - } - - //if((psxCounters[i].mode & 0x10) == 0 || psxCounters[i].target > 0xffffffff) continue; - c = (u64)((psxCounters[i].target - psxCounters[i].count) * psxCounters[i].rate) - (psxRegs.cycle - psxCounters[i].sCycleT); - if (c < psxNextCounter) { - psxNextCounter = (u32)c; - } - - } - - if(SPU2async) - { - c = (u32)(psxCounters[6].CycleT - (psxRegs.cycle - psxCounters[6].sCycleT)) ; - if (c < psxNextCounter) { - psxNextCounter = (u32)c; - } - } - if(USBasync) - { - c = (u32)(psxCounters[7].CycleT - (psxRegs.cycle - psxCounters[7].sCycleT)) ; - if (c < psxNextCounter) { - psxNextCounter = (u32)c; - } - } -} - - -void psxRcntInit() { - int i; - - memset(psxCounters, 0, sizeof(psxCounters)); - - for (i=0; i<3; i++) { - psxCounters[i].rate = 1; - psxCounters[i].mode|= 0x0400; - psxCounters[i].target = 0x0; - } - for (i=3; i<6; i++) { - psxCounters[i].rate = 1; - psxCounters[i].mode|= 0x0400; - psxCounters[i].target = 0x0; - } - - psxCounters[0].interrupt = 0x10; - psxCounters[1].interrupt = 0x20; - psxCounters[2].interrupt = 0x40; - - psxCounters[3].interrupt = 0x04000; - psxCounters[4].interrupt = 0x08000; - psxCounters[5].interrupt = 0x10000; - - if (SPU2async != NULL) { - - - psxCounters[6].rate = 1; - psxCounters[6].CycleT = ((Config.Hacks & 0x4) ? 768 : 9216); - psxCounters[6].mode = 0x8; - } - - if (USBasync != NULL) { - psxCounters[7].rate = 1; - psxCounters[7].CycleT = PSXCLK/1000; - psxCounters[7].mode = 0x8; - } - - for (i=0; i<3; i++) - psxCounters[i].sCycleT = psxRegs.cycle; - for (i=3; i<6; i++) - psxCounters[i].sCycleT = psxRegs.cycle; - for (i=6; i<8; i++) - psxCounters[i].sCycleT = psxRegs.cycle; - - psxRcntSet(); -} - -void psxVSyncStart() { - cdvdVsync(); - psxHu32(0x1070)|= 1; - if(psxvblankgate & 1) psxCheckStartGate(1); - if(psxvblankgate & (1 << 3)) psxCheckStartGate(3); -} - -void psxVSyncEnd() { - psxHu32(0x1070)|= 0x800; - if(psxvblankgate & 1) psxCheckEndGate(1); - if(psxvblankgate & (1 << 3)) psxCheckEndGate(3); -} -void psxCheckEndGate(int counter) { //Check Gate events when Vsync Ends - int i = counter; - //SysPrintf("End Gate %x\n", counter); - if(counter < 3){ //Gates for 16bit counters - if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate - - switch((psxCounters[i].mode & 0x6) >> 1) { - case 0x0: //GATE_ON_count - psxCounters[i].count += (u16)psxRcntRcount16(i); //Only counts when signal is on - break; - case 0x1: //GATE_ON_ClearStart - if(psxCounters[i].mode & 0x10000000)psxRcntUpd16(i); - psxCounters[i].mode &= ~0x10000000; - break; - case 0x2: //GATE_ON_Clear_OFF_Start - psxCounters[i].mode &= ~0x10000000; - psxRcntUpd16(i); - break; - case 0x3: //GATE_ON_Start - break; - default: - SysPrintf("PCSX2 Warning: 16bit IOP Counter Gate Not Set!\n"); - break; - } - } - - if(counter >= 3){ //Gates for 32bit counters - if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate - - switch((psxCounters[i].mode & 0x6) >> 1) { - case 0x0: //GATE_ON_count - psxCounters[i].count += (u32)psxRcntRcount32(i); //Only counts when signal is on - break; - case 0x1: //GATE_ON_ClearStart - if(psxCounters[i].mode & 0x10000000)psxRcntUpd32(i); - psxCounters[i].mode &= ~0x10000000; - break; - case 0x2: //GATE_ON_Clear_OFF_Start - psxCounters[i].mode &= ~0x10000000; - psxRcntUpd32(i); - break; - case 0x3: //GATE_ON_Start - break; - default: - SysPrintf("PCSX2 Warning: 32bit IOP Counter Gate Not Set!\n"); - break; - } - } -} -void psxCheckStartGate(int counter) { //Check Gate events when Vsync Starts - int i = counter; - + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include "PsxCommon.h" + +psxCounter psxCounters[8]; +u32 psxNextCounter, psxNextsCounter; +static int cnts = 6; +u8 psxhblankgate = 0; +u8 psxvblankgate = 0; +u8 psxcntmask = 0; + +static void psxRcntUpd16(u32 index) { + psxCounters[index].sCycleT = psxRegs.cycle; +} + +static void psxRcntUpd32(u32 index) { + psxCounters[index].sCycleT = psxRegs.cycle; +} + +static void psxRcntReset16(u32 index) { + psxCounters[index].count = 0; + + psxCounters[index].mode&= ~0x18301C00; + psxRcntUpd16(index); +} + +static void psxRcntReset32(u32 index) { + psxCounters[index].count = 0; + + psxCounters[index].mode&= ~0x18301C00; + psxRcntUpd32(index); +} + +static void psxRcntSet() { + u64 c; + int i; + + psxNextCounter = 0xffffffff; + psxNextsCounter = psxRegs.cycle; + + for (i=0; i<3; i++) { + if(psxCounters[i].rate == PSXHBLANK) continue; + c = (u64)((0x10000 - psxCounters[i].count) * psxCounters[i].rate) - (psxRegs.cycle - psxCounters[i].sCycleT); + if (c < psxNextCounter) { + psxNextCounter = (u32)c; + } + //if((psxCounters[i].mode & 0x10) == 0 || psxCounters[i].target > 0xffff) continue; + c = (u64)((psxCounters[i].target - psxCounters[i].count) * psxCounters[i].rate) - (psxRegs.cycle - psxCounters[i].sCycleT); + if (c < psxNextCounter) { + psxNextCounter = (u32)c; + } + + } + for (i=3; i<6; i++) { + if(psxCounters[i].rate == PSXHBLANK) continue; + c = (u64)((0x100000000 - psxCounters[i].count) * psxCounters[i].rate) - (psxRegs.cycle - psxCounters[i].sCycleT); + if (c < psxNextCounter) { + psxNextCounter = (u32)c; + } + + //if((psxCounters[i].mode & 0x10) == 0 || psxCounters[i].target > 0xffffffff) continue; + c = (u64)((psxCounters[i].target - psxCounters[i].count) * psxCounters[i].rate) - (psxRegs.cycle - psxCounters[i].sCycleT); + if (c < psxNextCounter) { + psxNextCounter = (u32)c; + } + + } + + if(SPU2async) + { + c = (u32)(psxCounters[6].CycleT - (psxRegs.cycle - psxCounters[6].sCycleT)) ; + if (c < psxNextCounter) { + psxNextCounter = (u32)c; + } + } + if(USBasync) + { + c = (u32)(psxCounters[7].CycleT - (psxRegs.cycle - psxCounters[7].sCycleT)) ; + if (c < psxNextCounter) { + psxNextCounter = (u32)c; + } + } +} + + +void psxRcntInit() { + int i; + + memset(psxCounters, 0, sizeof(psxCounters)); + + for (i=0; i<3; i++) { + psxCounters[i].rate = 1; + psxCounters[i].mode|= 0x0400; + psxCounters[i].target = 0x0; + } + for (i=3; i<6; i++) { + psxCounters[i].rate = 1; + psxCounters[i].mode|= 0x0400; + psxCounters[i].target = 0x0; + } + + psxCounters[0].interrupt = 0x10; + psxCounters[1].interrupt = 0x20; + psxCounters[2].interrupt = 0x40; + + psxCounters[3].interrupt = 0x04000; + psxCounters[4].interrupt = 0x08000; + psxCounters[5].interrupt = 0x10000; + + if (SPU2async != NULL) { + + + psxCounters[6].rate = 1; + psxCounters[6].CycleT = ((Config.Hacks & 0x4) ? 768 : 9216); + psxCounters[6].mode = 0x8; + } + + if (USBasync != NULL) { + psxCounters[7].rate = 1; + psxCounters[7].CycleT = PSXCLK/1000; + psxCounters[7].mode = 0x8; + } + + for (i=0; i<3; i++) + psxCounters[i].sCycleT = psxRegs.cycle; + for (i=3; i<6; i++) + psxCounters[i].sCycleT = psxRegs.cycle; + for (i=6; i<8; i++) + psxCounters[i].sCycleT = psxRegs.cycle; + + psxRcntSet(); +} + +void psxVSyncStart() { + cdvdVsync(); + psxHu32(0x1070)|= 1; + if(psxvblankgate & 1) psxCheckStartGate(1); + if(psxvblankgate & (1 << 3)) psxCheckStartGate(3); +} + +void psxVSyncEnd() { + psxHu32(0x1070)|= 0x800; + if(psxvblankgate & 1) psxCheckEndGate(1); + if(psxvblankgate & (1 << 3)) psxCheckEndGate(3); +} +void psxCheckEndGate(int counter) { //Check Gate events when Vsync Ends + int i = counter; + //SysPrintf("End Gate %x\n", counter); + if(counter < 3){ //Gates for 16bit counters + if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate + + switch((psxCounters[i].mode & 0x6) >> 1) { + case 0x0: //GATE_ON_count + psxCounters[i].count += (u16)psxRcntRcount16(i); //Only counts when signal is on + break; + case 0x1: //GATE_ON_ClearStart + if(psxCounters[i].mode & 0x10000000)psxRcntUpd16(i); + psxCounters[i].mode &= ~0x10000000; + break; + case 0x2: //GATE_ON_Clear_OFF_Start + psxCounters[i].mode &= ~0x10000000; + psxRcntUpd16(i); + break; + case 0x3: //GATE_ON_Start + break; + default: + SysPrintf("PCSX2 Warning: 16bit IOP Counter Gate Not Set!\n"); + break; + } + } + + if(counter >= 3){ //Gates for 32bit counters + if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate + + switch((psxCounters[i].mode & 0x6) >> 1) { + case 0x0: //GATE_ON_count + psxCounters[i].count += (u32)psxRcntRcount32(i); //Only counts when signal is on + break; + case 0x1: //GATE_ON_ClearStart + if(psxCounters[i].mode & 0x10000000)psxRcntUpd32(i); + psxCounters[i].mode &= ~0x10000000; + break; + case 0x2: //GATE_ON_Clear_OFF_Start + psxCounters[i].mode &= ~0x10000000; + psxRcntUpd32(i); + break; + case 0x3: //GATE_ON_Start + break; + default: + SysPrintf("PCSX2 Warning: 32bit IOP Counter Gate Not Set!\n"); + break; + } + } +} +void psxCheckStartGate(int counter) { //Check Gate events when Vsync Starts + int i = counter; + if(counter == 0){ if((psxCounters[1].mode & 0x101) == 0x100 || (psxCounters[1].mode & 0x10000101) == 0x101)psxCounters[1].count++; if((psxCounters[3].mode & 0x101) == 0x100 || (psxCounters[3].mode & 0x10000101) == 0x101)psxCounters[3].count++; - /*if(SPU2async) - { + /*if(SPU2async) + { SPU2async(psxRegs.cycle - psxCounters[6].sCycleT); //SysPrintf("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT); psxCounters[6].sCycleT = psxRegs.cycle; - }*/ - } - - if(counter < 3){ //Gates for 16bit counters - if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate - //SysPrintf("PSX Gate %x\n", i); - switch((psxCounters[i].mode & 0x6) >> 1) { - case 0x0: //GATE_ON_count - psxRcntUpd32(i); - psxCounters[i].mode |= 0x10000000; - break; - case 0x1: //GATE_ON_ClearStart - if(psxCounters[i].mode & 0x10000000)psxRcntUpd16(i); - psxCounters[i].mode &= ~0x10000000; - break; - case 0x2: //GATE_ON_Clear_OFF_Start - psxRcntReset32(i); - psxCounters[i].mode |= 0x10000000; - break; - case 0x3: //GATE_ON_Start - psxCounters[i].mode &= ~0x10000000; - break; - default: - SysPrintf("PCSX2 Warning: 16bit IOP Counter Gate Not Set!\n"); - break; - } - } - - if(counter >= 3){ //Gates for 32bit counters - if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate - //SysPrintf("PSX Gate %x\n", i); - switch((psxCounters[i].mode & 0x6) >> 1) { - case 0x0: //GATE_ON_count - psxRcntUpd32(i); - psxCounters[i].mode &= ~0x10000000; - break; - case 0x1: //GATE_ON_ClearStart - if(psxCounters[i].mode & 0x10000000)psxRcntUpd32(i); - psxCounters[i].mode &= ~0x10000000; - break; - case 0x2: //GATE_ON_Clear_OFF_Start - psxRcntReset32(i); - psxCounters[i].mode |= 0x10000000; - break; - case 0x3: //GATE_ON_Start - psxCounters[i].mode &= ~0x10000000; - break; - default: - SysPrintf("PCSX2 Warning: 32bit IOP Counter Gate Not Set!\n"); - break; - } - } -} - -void _testRcnt16target(int i) { - -#ifdef PSXCNT_LOG - PSXCNT_LOG("[%d] target %x >= %x (CycleT); count=%I64x, target=%I64x, mode=%I64x\n", i, (psxRegs.cycle - psxCounters[i].sCycleT), psxCounters[i].CycleT, psxCounters[i].count, psxCounters[i].target, psxCounters[i].mode); -#endif - - if(psxCounters[i].target > 0xffff) { - psxCounters[i].target &= 0xffff; - //SysPrintf("IOP 16 Correcting target target %x\n", psxCounters[i].target); - } - - if (psxCounters[i].mode & 0x10){ - if(psxCounters[i].mode & 0x80)psxCounters[i].mode&= ~0x0400; // Interrupt flag - psxCounters[i].mode|= 0x0800; // Target flag - } - - - - if (psxCounters[i].mode & 0x10) { // Target interrupt - psxHu32(0x1070)|= psxCounters[i].interrupt; - } - - if (psxCounters[i].mode & 0x08) { // Reset on target - psxCounters[i].count -= psxCounters[i].target; - if((psxCounters[i].mode & 0x40) == 0){ - SysPrintf("Counter %x repeat intr not set on zero ret, ignoring target\n", i); - psxCounters[i].target += 0x1000000000; - } - - } else psxCounters[i].target += 0x1000000000; - -} - -void _testRcnt16overflow(int i) { - -#ifdef PSXCNT_LOG - PSXCNT_LOG("[%d] overflow 0x%x >= 0x%x (Cycle); Rcount=0x%x, count=0x%x\n", i, (psxRegs.cycle - psxCounters[i].sCycle) / psxCounters[i].rate, psxCounters[i].Cycle, psxRcntRcount16(i), psxCounters[i].count); -#endif - - - if (psxCounters[i].mode & 0x0020) { // Overflow interrupt - psxHu32(0x1070)|= psxCounters[i].interrupt; - psxCounters[i].mode|= 0x1000; // Overflow flag - if(psxCounters[i].mode & 0x80){ - - psxCounters[i].mode&= ~0x0400; // Interrupt flag - } - //SysPrintf("Overflow 16\n"); - } - psxCounters[i].count -= 0x10000; - psxRcntUpd16(i); - if(psxCounters[i].target > 0xffff) { - if((psxCounters[i].mode & 0x50) <= 0x40 && (psxCounters[i].mode & 0x50) != 0) SysPrintf("Counter %x overflowing, no repeat interrupt mode = %x\n", i, psxCounters[i].mode); - psxCounters[i].target &= 0xffff; - //SysPrintf("IOP 16 Correcting target ovf %x\n", psxCounters[i].target); - } -} - -void _testRcnt32target(int i) { - -#ifdef PSXCNT_LOG - PSXCNT_LOG("[%d] target %x >= %x (CycleT); count=%I64x, target=%I64x, mode=%I64x\n", i, (psxRegs.cycle - psxCounters[i].sCycleT), psxCounters[i].CycleT, psxCounters[i].count, psxCounters[i].target, psxCounters[i].mode); -#endif - if(psxCounters[i].target > 0xffffffff) { - //SysPrintf("IOP 32 Correcting target on target reset\n"); - psxCounters[i].target &= 0xffffffff; - } - - -// newtarget[i] = 0; - - - if (psxCounters[i].mode & 0x10){ - if(psxCounters[i].mode & 0x80)psxCounters[i].mode&= ~0x0400; // Interrupt flag - psxCounters[i].mode|= 0x0800; // Target flag - } - - - if (psxCounters[i].mode & 0x10) { // Target interrupt - psxHu32(0x1070)|= psxCounters[i].interrupt; - - } - - if (psxCounters[i].mode & 0x08) { // Reset on target - psxCounters[i].count -= psxCounters[i].target; - if((psxCounters[i].mode & 0x40) == 0){ - SysPrintf("Counter %x repeat intr not set on zero ret, ignoring target\n", i); - psxCounters[i].target += 0x1000000000; - } - - } else psxCounters[i].target += 0x1000000000; - -} - -void _testRcnt32overflow(int i) { - -#ifdef PSXCNT_LOG - PSXCNT_LOG("[%d] overflow 0x%x >= 0x%x (Cycle); Rcount=0x%x, count=0x%x\n", i, (psxRegs.cycle - psxCounters[i].sCycle), psxCounters[i].Cycle, psxRcntRcount32(i), psxCounters[i].count); -#endif - //SysPrintf("Overflow 32\n"); - if (psxCounters[i].mode & 0x0020) { // Overflow interrupt - psxHu32(0x1070)|= psxCounters[i].interrupt; - psxCounters[i].mode|= 0x1000; // Overflow flag - if(psxCounters[i].mode & 0x80){ - - psxCounters[i].mode&= ~0x0400; // Interrupt flag - } - } - psxCounters[i].count -= 0x100000000; - if(psxCounters[i].target > 0xffffffff) { - //SysPrintf("IOP 32 Correcting target on overflow\n"); - if((psxCounters[i].mode & 0x50) <= 0x40 && (psxCounters[i].mode & 0x50) != 0) SysPrintf("Counter %x overflowing, no repeat interrupt mode = %x\n", i, psxCounters[i].mode); - psxCounters[i].target &= 0xffffffff; - } -} - - -void _testRcnt16(int i) { - - if (/*psxCounters[i].target > 0 &&*/ (s64)(psxCounters[i].target - psxCounters[i].count) <= 0){ - _testRcnt16target(i); - } - if (psxCounters[i].count > 0xffff) - _testRcnt16overflow(i); -} - -void _testRcnt32(int i) { - - if (/*psxCounters[i].target > 0 && */(s64)(psxCounters[i].target - psxCounters[i].count) <= 0){ - _testRcnt32target(i); - } - if (psxCounters[i].count > 0xffffffff) - _testRcnt32overflow(i); - - -} -extern int spu2interrupts[2]; -void psxRcntUpdate() { - int i; - u32 change = 0; - - for (i=0; i<=5; i++) { - if((psxCounters[i].mode & 0x1) != 0 || psxCounters[i].rate == PSXHBLANK){ - //SysPrintf("Stopped accidental update of psx counter %x when using a gate\hblank source\n", i); - continue; - } - - change = psxRegs.cycle - psxCounters[i].sCycleT; - psxCounters[i].count += change / psxCounters[i].rate; - if(psxCounters[i].rate != 1){ - change -= (change / psxCounters[i].rate) * psxCounters[i].rate; - psxCounters[i].sCycleT = psxRegs.cycle - change; - //if(change > 0) SysPrintf("PSX Change saved on %x = %x\n", i, change); - } else psxCounters[i].sCycleT = psxRegs.cycle; - } - - _testRcnt16(0); - _testRcnt16(1); - _testRcnt16(2); - _testRcnt32(3); - _testRcnt32(4); - _testRcnt32(5); - - - if(SPU2async) - { - if((psxRegs.cycle - psxCounters[6].sCycleT) >= psxCounters[6].CycleT){ + }*/ + } + + if(counter < 3){ //Gates for 16bit counters + if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate + //SysPrintf("PSX Gate %x\n", i); + switch((psxCounters[i].mode & 0x6) >> 1) { + case 0x0: //GATE_ON_count + psxRcntUpd32(i); + psxCounters[i].mode |= 0x10000000; + break; + case 0x1: //GATE_ON_ClearStart + if(psxCounters[i].mode & 0x10000000)psxRcntUpd16(i); + psxCounters[i].mode &= ~0x10000000; + break; + case 0x2: //GATE_ON_Clear_OFF_Start + psxRcntReset32(i); + psxCounters[i].mode |= 0x10000000; + break; + case 0x3: //GATE_ON_Start + psxCounters[i].mode &= ~0x10000000; + break; + default: + SysPrintf("PCSX2 Warning: 16bit IOP Counter Gate Not Set!\n"); + break; + } + } + + if(counter >= 3){ //Gates for 32bit counters + if((psxCounters[i].mode & 0x1) == 0) return; //Ignore Gate + //SysPrintf("PSX Gate %x\n", i); + switch((psxCounters[i].mode & 0x6) >> 1) { + case 0x0: //GATE_ON_count + psxRcntUpd32(i); + psxCounters[i].mode &= ~0x10000000; + break; + case 0x1: //GATE_ON_ClearStart + if(psxCounters[i].mode & 0x10000000)psxRcntUpd32(i); + psxCounters[i].mode &= ~0x10000000; + break; + case 0x2: //GATE_ON_Clear_OFF_Start + psxRcntReset32(i); + psxCounters[i].mode |= 0x10000000; + break; + case 0x3: //GATE_ON_Start + psxCounters[i].mode &= ~0x10000000; + break; + default: + SysPrintf("PCSX2 Warning: 32bit IOP Counter Gate Not Set!\n"); + break; + } + } +} + +void _testRcnt16target(int i) { + +#ifdef PSXCNT_LOG + PSXCNT_LOG("[%d] target %x >= %x (CycleT); count=%I64x, target=%I64x, mode=%I64x\n", i, (psxRegs.cycle - psxCounters[i].sCycleT), psxCounters[i].CycleT, psxCounters[i].count, psxCounters[i].target, psxCounters[i].mode); +#endif + + if(psxCounters[i].target > 0xffff) { + psxCounters[i].target &= 0xffff; + //SysPrintf("IOP 16 Correcting target target %x\n", psxCounters[i].target); + } + + if (psxCounters[i].mode & 0x10){ + if(psxCounters[i].mode & 0x80)psxCounters[i].mode&= ~0x0400; // Interrupt flag + psxCounters[i].mode|= 0x0800; // Target flag + } + + + + if (psxCounters[i].mode & 0x10) { // Target interrupt + psxHu32(0x1070)|= psxCounters[i].interrupt; + } + + if (psxCounters[i].mode & 0x08) { // Reset on target + psxCounters[i].count -= psxCounters[i].target; + if((psxCounters[i].mode & 0x40) == 0){ + SysPrintf("Counter %x repeat intr not set on zero ret, ignoring target\n", i); + psxCounters[i].target += 0x1000000000; + } + + } else psxCounters[i].target += 0x1000000000; + +} + +void _testRcnt16overflow(int i) { + +#ifdef PSXCNT_LOG + PSXCNT_LOG("[%d] overflow 0x%x >= 0x%x (Cycle); Rcount=0x%x, count=0x%x\n", i, (psxRegs.cycle - psxCounters[i].sCycle) / psxCounters[i].rate, psxCounters[i].Cycle, psxRcntRcount16(i), psxCounters[i].count); +#endif + + + if (psxCounters[i].mode & 0x0020) { // Overflow interrupt + psxHu32(0x1070)|= psxCounters[i].interrupt; + psxCounters[i].mode|= 0x1000; // Overflow flag + if(psxCounters[i].mode & 0x80){ + + psxCounters[i].mode&= ~0x0400; // Interrupt flag + } + //SysPrintf("Overflow 16\n"); + } + psxCounters[i].count -= 0x10000; + psxRcntUpd16(i); + if(psxCounters[i].target > 0xffff) { + if((psxCounters[i].mode & 0x50) <= 0x40 && (psxCounters[i].mode & 0x50) != 0) SysPrintf("Counter %x overflowing, no repeat interrupt mode = %x\n", i, psxCounters[i].mode); + psxCounters[i].target &= 0xffff; + //SysPrintf("IOP 16 Correcting target ovf %x\n", psxCounters[i].target); + } +} + +void _testRcnt32target(int i) { + +#ifdef PSXCNT_LOG + PSXCNT_LOG("[%d] target %x >= %x (CycleT); count=%I64x, target=%I64x, mode=%I64x\n", i, (psxRegs.cycle - psxCounters[i].sCycleT), psxCounters[i].CycleT, psxCounters[i].count, psxCounters[i].target, psxCounters[i].mode); +#endif + if(psxCounters[i].target > 0xffffffff) { + //SysPrintf("IOP 32 Correcting target on target reset\n"); + psxCounters[i].target &= 0xffffffff; + } + + +// newtarget[i] = 0; + + + if (psxCounters[i].mode & 0x10){ + if(psxCounters[i].mode & 0x80)psxCounters[i].mode&= ~0x0400; // Interrupt flag + psxCounters[i].mode|= 0x0800; // Target flag + } + + + if (psxCounters[i].mode & 0x10) { // Target interrupt + psxHu32(0x1070)|= psxCounters[i].interrupt; + + } + + if (psxCounters[i].mode & 0x08) { // Reset on target + psxCounters[i].count -= psxCounters[i].target; + if((psxCounters[i].mode & 0x40) == 0){ + SysPrintf("Counter %x repeat intr not set on zero ret, ignoring target\n", i); + psxCounters[i].target += 0x1000000000; + } + + } else psxCounters[i].target += 0x1000000000; + +} + +void _testRcnt32overflow(int i) { + +#ifdef PSXCNT_LOG + PSXCNT_LOG("[%d] overflow 0x%x >= 0x%x (Cycle); Rcount=0x%x, count=0x%x\n", i, (psxRegs.cycle - psxCounters[i].sCycle), psxCounters[i].Cycle, psxRcntRcount32(i), psxCounters[i].count); +#endif + //SysPrintf("Overflow 32\n"); + if (psxCounters[i].mode & 0x0020) { // Overflow interrupt + psxHu32(0x1070)|= psxCounters[i].interrupt; + psxCounters[i].mode|= 0x1000; // Overflow flag + if(psxCounters[i].mode & 0x80){ + + psxCounters[i].mode&= ~0x0400; // Interrupt flag + } + } + psxCounters[i].count -= 0x100000000; + if(psxCounters[i].target > 0xffffffff) { + //SysPrintf("IOP 32 Correcting target on overflow\n"); + if((psxCounters[i].mode & 0x50) <= 0x40 && (psxCounters[i].mode & 0x50) != 0) SysPrintf("Counter %x overflowing, no repeat interrupt mode = %x\n", i, psxCounters[i].mode); + psxCounters[i].target &= 0xffffffff; + } +} + + +void _testRcnt16(int i) { + + if (/*psxCounters[i].target > 0 &&*/ (s64)(psxCounters[i].target - psxCounters[i].count) <= 0){ + _testRcnt16target(i); + } + if (psxCounters[i].count > 0xffff) + _testRcnt16overflow(i); +} + +void _testRcnt32(int i) { + + if (/*psxCounters[i].target > 0 && */(s64)(psxCounters[i].target - psxCounters[i].count) <= 0){ + _testRcnt32target(i); + } + if (psxCounters[i].count > 0xffffffff) + _testRcnt32overflow(i); + + +} +extern int spu2interrupts[2]; +void psxRcntUpdate() { + int i; + u32 change = 0; + + for (i=0; i<=5; i++) { + if((psxCounters[i].mode & 0x1) != 0 || psxCounters[i].rate == PSXHBLANK){ + //SysPrintf("Stopped accidental update of psx counter %x when using a gate\hblank source\n", i); + continue; + } + + change = psxRegs.cycle - psxCounters[i].sCycleT; + psxCounters[i].count += change / psxCounters[i].rate; + if(psxCounters[i].rate != 1){ + change -= (change / psxCounters[i].rate) * psxCounters[i].rate; + psxCounters[i].sCycleT = psxRegs.cycle - change; + //if(change > 0) SysPrintf("PSX Change saved on %x = %x\n", i, change); + } else psxCounters[i].sCycleT = psxRegs.cycle; + } + + _testRcnt16(0); + _testRcnt16(1); + _testRcnt16(2); + _testRcnt32(3); + _testRcnt32(4); + _testRcnt32(5); + + + if(SPU2async) + { + if((psxRegs.cycle - psxCounters[6].sCycleT) >= psxCounters[6].CycleT){ SPU2async(psxRegs.cycle - psxCounters[6].sCycleT); //SysPrintf("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT); psxCounters[6].sCycleT = psxRegs.cycle; psxCounters[6].CycleT = ((Config.Hacks & 0x4) ? 768 : 9216); - } - } - - if(USBasync) - { - if ((psxRegs.cycle - psxCounters[7].sCycleT) >= psxCounters[7].CycleT) { - USBasync(psxRegs.cycle - psxCounters[7].sCycleT); - psxCounters[7].sCycleT = psxRegs.cycle; - } - } - - psxRcntSet(); -} - -void psxRcntWcount16(int index, u32 value) { - u32 change = 0; -#ifdef PSXCNT_LOG - PSXCNT_LOG("writeCcount[%d] = %x\n", index, value); -#endif - - change = psxRegs.cycle - psxCounters[index].sCycleT; - //psxCounters[i].count += change / psxCounters[i].rate; - if(psxCounters[index].rate != 1){ - change -= (change / psxCounters[index].rate) * psxCounters[index].rate; - psxCounters[index].sCycleT = psxRegs.cycle - change; - if(change > 0) SysPrintf("PSX Change count write 16 %x = %x\n", index, change); - } - psxCounters[index].count = value & 0xffff; - if(psxCounters[index].target > 0xffff) { - //SysPrintf("IOP 16 Correcting target on count write\n"); - psxCounters[index].target &= 0xffff; - } - if(psxCounters[index].rate == PSXHBLANK)SysPrintf("Whoops 16 IOP\n"); - psxRcntUpd16(index); - psxRcntSet(); -} - -void psxRcntWcount32(int index, u32 value) { - u32 change = 0; -#ifdef PSXCNT_LOG - PSXCNT_LOG("writeCcount[%d] = %x\n", index, value); -#endif - - change = psxRegs.cycle - psxCounters[index].sCycleT; - //psxCounters[i].count += change / psxCounters[i].rate; - if(psxCounters[index].rate != 1){ - change -= (change / psxCounters[index].rate) * psxCounters[index].rate; - psxCounters[index].sCycleT = psxRegs.cycle - change; - if(change > 0) SysPrintf("PSX Change count write 32 %x = %x\n", index, change); - } - psxCounters[index].count = value; - if(psxCounters[index].target > 0xffffffff) { - //SysPrintf("IOP 32 Correcting target\n"); - psxCounters[index].target &= 0xffffffff; - } - if(psxCounters[index].rate == PSXHBLANK)SysPrintf("Whoops 32 IOP\n"); - //psxRcntUpd32(index); - psxRcntSet(); -} - -void psxRcnt0Wmode(u32 value) { -#ifdef PSXCNT_LOG - PSXCNT_LOG("IOP writeCmode[0] = %lx\n", value); -#endif - - if (value & 0x1c00) { - SysPrintf("Counter 0 Value write %x\n", value & 0x1c00); - } - - psxCounters[0].mode = value; - psxCounters[0].mode|= 0x0400; - psxCounters[0].rate = 1; - - if(value & 0x100) { - //SysPrintf("Timer 0 Set to Pixel clock %x\n", value); - psxCounters[0].rate = PSXPIXEL; - }// else SysPrintf("Timer 0 Set to 1 %x\n", value); - - if(psxCounters[0].mode & 0x1){ - SysPrintf("Gate Check set on Counter 0 %x\n", value); - psxCounters[0].mode|= 0x1000000; - psxhblankgate |= 1; - }else - psxhblankgate &= ~1; - - psxCounters[0].count = 0; - psxRcntUpd16(0); - if(psxCounters[0].target > 0xffff) { - //SysPrintf("IOP 16 Correcting target 0 after mode write\n"); - psxCounters[0].target &= 0xffff; - } - psxRcntSet(); - //} -} - -void psxRcnt1Wmode(u32 value) { -#ifdef PSXCNT_LOG - PSXCNT_LOG("IOP writeCmode[1] = %lx\n", value); -#endif - - if (value & 0x1c00) { - SysPrintf("Counter 1 Value write %x\n", value & 0x1c00); - } - - psxCounters[1].mode = value; - psxCounters[1].mode|= 0x0400; - psxCounters[1].rate = 1; - - if(value & 0x100){ - //SysPrintf("Timer 1 Set to HBlank clock %x\n", value); - psxCounters[1].rate = PSXHBLANK; - }// else SysPrintf("Timer 1 Set to 1 clock %x\n", value); - - if(psxCounters[1].mode & 0x1){ - SysPrintf("Gate Check set on Counter 1 %x\n", value); - psxCounters[1].mode|= 0x1000000; - psxvblankgate |= 1<<1; - }else - psxvblankgate &= ~(1<<1); - - psxCounters[1].count = 0; - psxRcntUpd16(1); - if(psxCounters[1].target > 0xffff) { - //SysPrintf("IOP 16 Correcting target 1 after mode write\n"); - psxCounters[1].target &= 0xffff; - } - psxRcntSet(); - //} -} - -void psxRcnt2Wmode(u32 value) { -#ifdef PSXCNT_LOG - PSXCNT_LOG("IOP writeCmode[2] = %lx\n", value); -#endif - - if (value & 0x1c00) { - SysPrintf("Counter 2 Value write %x\n", value & 0x1c00); - } - - psxCounters[2].mode = value; - psxCounters[2].mode|= 0x0400; - - switch(value & 0x200){ - case 0x200: - //SysPrintf("Timer 2 Set to 8 %x\n", value); - psxCounters[2].rate = 8; - break; - case 0x000: - //SysPrintf("Timer 2 Set to 1 %x\n", value); - psxCounters[2].rate = 1; - break; - } - - if((psxCounters[2].mode & 0x7) == 0x7 || (psxCounters[2].mode & 0x7) == 0x1){ - //SysPrintf("Gate set on IOP C2, disabling\n"); - psxCounters[2].mode|= 0x1000000; - } - // Need to set a rate and target - psxCounters[2].count = 0; - psxRcntUpd16(2); - if(psxCounters[2].target > 0xffff) { - //SysPrintf("IOP 16 Correcting target 2 after mode write\n"); - psxCounters[2].target &= 0xffff; - } - psxRcntSet(); -} - -void psxRcnt3Wmode(u32 value) { -#ifdef PSXCNT_LOG - PSXCNT_LOG("IOP writeCmode[3] = %lx\n", value); -#endif - - if (value & 0x1c00) { - SysPrintf("Counter 3 Value write %x\n", value & 0x1c00); - } - - psxCounters[3].mode = value; - psxCounters[3].rate = 1; - psxCounters[3].mode|= 0x0400; - - if(value & 0x100){ - //SysPrintf("Timer 3 Set to HBLANK clock %x\n", value); - psxCounters[3].rate = PSXHBLANK; - }//else SysPrintf("Timer 3 Set to 1 %x\n", value); - - if(psxCounters[3].mode & 0x1){ - SysPrintf("Gate Check set on Counter 3\n"); - psxCounters[3].mode|= 0x1000000; - psxvblankgate |= 1<<3; - }else - psxvblankgate &= ~(1<<3); - - psxCounters[3].count = 0; - psxRcntUpd32(3); - if(psxCounters[3].target > 0xffffffff) { - //SysPrintf("IOP 32 Correcting target 3 after mode write\n"); - psxCounters[3].target &= 0xffffffff; - } - psxRcntSet(); - //} -} - -void psxRcnt4Wmode(u32 value) { -#ifdef PSXCNT_LOG - PSXCNT_LOG("IOP writeCmode[4] = %lx\n", value); -#endif - - if (value & 0x1c00) { - SysPrintf("Counter 4 Value write %x\n", value & 0x1c00); - } - - psxCounters[4].mode = value; - psxCounters[4].mode|= 0x0400; - - switch(value & 0x6000){ - case 0x0000: - //SysPrintf("Timer 4 Set to 1 %x\n", value); - psxCounters[4].rate = 1; - break; - case 0x2000: - SysPrintf("Timer 4 Set to 8 %x\n", value); - psxCounters[4].rate = 8; - break; - case 0x4000: - SysPrintf("Timer 4 Set to 16 %x\n", value); - psxCounters[4].rate = 16; - break; - case 0x6000: - SysPrintf("Timer 4 Set to 256 %x\n", value); - psxCounters[4].rate = 256; - break; - } - // Need to set a rate and target - if((psxCounters[4].mode & 0x7) == 0x7 || (psxCounters[4].mode & 0x7) == 0x1){ - SysPrintf("Gate set on IOP C4, disabling\n"); - psxCounters[4].mode|= 0x1000000; - } - psxCounters[4].count = 0; - psxRcntUpd32(4); - if(psxCounters[4].target > 0xffffffff) { - //SysPrintf("IOP 32 Correcting target 4 after mode write\n"); - psxCounters[4].target &= 0xffffffff; - } - psxRcntSet(); -} - -void psxRcnt5Wmode(u32 value) { -#ifdef PSXCNT_LOG - PSXCNT_LOG("IOP writeCmode[5] = %lx\n", value); -#endif - - if (value & 0x1c00) { - SysPrintf("Counter 5 Value write %x\n", value & 0x1c00); - } - - psxCounters[5].mode = value; - psxCounters[5].mode|= 0x0400; - - switch(value & 0x6000){ - case 0x0000: - //SysPrintf("Timer 5 Set to 1 %x\n", value); - psxCounters[5].rate = 1; - break; - case 0x2000: - SysPrintf("Timer 5 Set to 8 %x\n", value); - psxCounters[5].rate = 8; - break; - case 0x4000: - SysPrintf("Timer 5 Set to 16 %x\n", value); - psxCounters[5].rate = 16; - break; - case 0x6000: - SysPrintf("Timer 5 Set to 256 %x\n", value); - psxCounters[5].rate = 256; - break; - } - // Need to set a rate and target - if((psxCounters[5].mode & 0x7) == 0x7 || (psxCounters[5].mode & 0x7) == 0x1){ - SysPrintf("Gate set on IOP C5, disabling\n"); - psxCounters[5].mode|= 0x1000000; - } - psxCounters[5].count = 0; - psxRcntUpd32(5); - if(psxCounters[5].target > 0xffffffff) { - //SysPrintf("IOP 32 Correcting target 5 after mode write\n"); - psxCounters[5].target &= 0xffffffff; - } - psxRcntSet(); -} - -void psxRcntWtarget16(int index, u32 value) { -#ifdef PSXCNT_LOG - PSXCNT_LOG("writeCtarget16[%ld] = %lx\n", index, value); -#endif - psxCounters[index].target = value & 0xffff; - if(psxCounters[index].target <= psxRcntCycles(index)/* && psxCounters[index].target != 0*/) { - //SysPrintf("IOP 16 Saving %x target from early trigger target = %x, count = %I64x\n", index, psxCounters[index].target, psxRcntCycles(index)); - psxCounters[index].target += 0x1000000000; - } - - psxRcntSet(); -} - -void psxRcntWtarget32(int index, u32 value) { -#ifdef PSXCNT_LOG - PSXCNT_LOG("writeCtarget32[%ld] = %lx (count=%lx) ; sCycleT: %x CycleT: %x psxRegscycle %x\n", - index, value, psxCounters[index].count, psxCounters[index].sCycleT, psxCounters[index].CycleT, psxRegs.cycle); -#endif - - psxCounters[index].target = value; - if(psxCounters[index].target <= psxRcntCycles(index)/* && psxCounters[index].target != 0*/) { - //SysPrintf("IOP 32 Saving %x target from early trigger target = %x, count = %I64x\n", index, psxCounters[index].target, psxRcntCycles(index)); - psxCounters[index].target += 0x1000000000; - } - - psxRcntSet(); -} - -u16 psxRcntRcount16(int index) { - if(psxCounters[index].mode & 0x1000000) return (u16)psxCounters[index].count; - return (u16)(psxCounters[index].count + (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate)); -} - -u32 psxRcntRcount32(int index) { - if(psxCounters[index].mode & 0x1000000) return (u32)psxCounters[index].count; - return (u32)(psxCounters[index].count + (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate)); -} - -u64 psxRcntCycles(int index) { - if(psxCounters[index].mode & 0x1000000) return psxCounters[index].count; - return (u64)(psxCounters[index].count + (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate)); -} - -extern u32 dwCurSaveStateVer; -int psxRcntFreeze(gzFile f, int Mode) -{ - if( Mode == 0 && (dwCurSaveStateVer < 0x7a300010) ) { // reading - // struct used to be 32bit count and target - int i; - u32 val; - for(i = 0; i < ARRAYSIZE(psxCounters); ++i) { - gzfreeze(&val,4); psxCounters[i].count = val; - gzfreeze(&val,4); psxCounters[i].mode = val; - gzfreeze(&val,4); psxCounters[i].target = val; - gzfreeze((u8*)&psxCounters[i].rate, sizeof(psxCounters[i])-20); - } - } - else - gzfreezel(psxCounters); - - - return 0; -} + } + } + + if(USBasync) + { + if ((psxRegs.cycle - psxCounters[7].sCycleT) >= psxCounters[7].CycleT) { + USBasync(psxRegs.cycle - psxCounters[7].sCycleT); + psxCounters[7].sCycleT = psxRegs.cycle; + } + } + + psxRcntSet(); +} + +void psxRcntWcount16(int index, u32 value) { + u32 change = 0; +#ifdef PSXCNT_LOG + PSXCNT_LOG("writeCcount[%d] = %x\n", index, value); +#endif + + change = psxRegs.cycle - psxCounters[index].sCycleT; + //psxCounters[i].count += change / psxCounters[i].rate; + if(psxCounters[index].rate != 1){ + change -= (change / psxCounters[index].rate) * psxCounters[index].rate; + psxCounters[index].sCycleT = psxRegs.cycle - change; + if(change > 0) SysPrintf("PSX Change count write 16 %x = %x\n", index, change); + } + psxCounters[index].count = value & 0xffff; + if(psxCounters[index].target > 0xffff) { + //SysPrintf("IOP 16 Correcting target on count write\n"); + psxCounters[index].target &= 0xffff; + } + if(psxCounters[index].rate == PSXHBLANK)SysPrintf("Whoops 16 IOP\n"); + psxRcntUpd16(index); + psxRcntSet(); +} + +void psxRcntWcount32(int index, u32 value) { + u32 change = 0; +#ifdef PSXCNT_LOG + PSXCNT_LOG("writeCcount[%d] = %x\n", index, value); +#endif + + change = psxRegs.cycle - psxCounters[index].sCycleT; + //psxCounters[i].count += change / psxCounters[i].rate; + if(psxCounters[index].rate != 1){ + change -= (change / psxCounters[index].rate) * psxCounters[index].rate; + psxCounters[index].sCycleT = psxRegs.cycle - change; + if(change > 0) SysPrintf("PSX Change count write 32 %x = %x\n", index, change); + } + psxCounters[index].count = value; + if(psxCounters[index].target > 0xffffffff) { + //SysPrintf("IOP 32 Correcting target\n"); + psxCounters[index].target &= 0xffffffff; + } + if(psxCounters[index].rate == PSXHBLANK)SysPrintf("Whoops 32 IOP\n"); + //psxRcntUpd32(index); + psxRcntSet(); +} + +void psxRcnt0Wmode(u32 value) { +#ifdef PSXCNT_LOG + PSXCNT_LOG("IOP writeCmode[0] = %lx\n", value); +#endif + + if (value & 0x1c00) { + SysPrintf("Counter 0 Value write %x\n", value & 0x1c00); + } + + psxCounters[0].mode = value; + psxCounters[0].mode|= 0x0400; + psxCounters[0].rate = 1; + + if(value & 0x100) { + //SysPrintf("Timer 0 Set to Pixel clock %x\n", value); + psxCounters[0].rate = PSXPIXEL; + }// else SysPrintf("Timer 0 Set to 1 %x\n", value); + + if(psxCounters[0].mode & 0x1){ + SysPrintf("Gate Check set on Counter 0 %x\n", value); + psxCounters[0].mode|= 0x1000000; + psxhblankgate |= 1; + }else + psxhblankgate &= ~1; + + psxCounters[0].count = 0; + psxRcntUpd16(0); + if(psxCounters[0].target > 0xffff) { + //SysPrintf("IOP 16 Correcting target 0 after mode write\n"); + psxCounters[0].target &= 0xffff; + } + psxRcntSet(); + //} +} + +void psxRcnt1Wmode(u32 value) { +#ifdef PSXCNT_LOG + PSXCNT_LOG("IOP writeCmode[1] = %lx\n", value); +#endif + + if (value & 0x1c00) { + SysPrintf("Counter 1 Value write %x\n", value & 0x1c00); + } + + psxCounters[1].mode = value; + psxCounters[1].mode|= 0x0400; + psxCounters[1].rate = 1; + + if(value & 0x100){ + //SysPrintf("Timer 1 Set to HBlank clock %x\n", value); + psxCounters[1].rate = PSXHBLANK; + }// else SysPrintf("Timer 1 Set to 1 clock %x\n", value); + + if(psxCounters[1].mode & 0x1){ + SysPrintf("Gate Check set on Counter 1 %x\n", value); + psxCounters[1].mode|= 0x1000000; + psxvblankgate |= 1<<1; + }else + psxvblankgate &= ~(1<<1); + + psxCounters[1].count = 0; + psxRcntUpd16(1); + if(psxCounters[1].target > 0xffff) { + //SysPrintf("IOP 16 Correcting target 1 after mode write\n"); + psxCounters[1].target &= 0xffff; + } + psxRcntSet(); + //} +} + +void psxRcnt2Wmode(u32 value) { +#ifdef PSXCNT_LOG + PSXCNT_LOG("IOP writeCmode[2] = %lx\n", value); +#endif + + if (value & 0x1c00) { + SysPrintf("Counter 2 Value write %x\n", value & 0x1c00); + } + + psxCounters[2].mode = value; + psxCounters[2].mode|= 0x0400; + + switch(value & 0x200){ + case 0x200: + //SysPrintf("Timer 2 Set to 8 %x\n", value); + psxCounters[2].rate = 8; + break; + case 0x000: + //SysPrintf("Timer 2 Set to 1 %x\n", value); + psxCounters[2].rate = 1; + break; + } + + if((psxCounters[2].mode & 0x7) == 0x7 || (psxCounters[2].mode & 0x7) == 0x1){ + //SysPrintf("Gate set on IOP C2, disabling\n"); + psxCounters[2].mode|= 0x1000000; + } + // Need to set a rate and target + psxCounters[2].count = 0; + psxRcntUpd16(2); + if(psxCounters[2].target > 0xffff) { + //SysPrintf("IOP 16 Correcting target 2 after mode write\n"); + psxCounters[2].target &= 0xffff; + } + psxRcntSet(); +} + +void psxRcnt3Wmode(u32 value) { +#ifdef PSXCNT_LOG + PSXCNT_LOG("IOP writeCmode[3] = %lx\n", value); +#endif + + if (value & 0x1c00) { + SysPrintf("Counter 3 Value write %x\n", value & 0x1c00); + } + + psxCounters[3].mode = value; + psxCounters[3].rate = 1; + psxCounters[3].mode|= 0x0400; + + if(value & 0x100){ + //SysPrintf("Timer 3 Set to HBLANK clock %x\n", value); + psxCounters[3].rate = PSXHBLANK; + }//else SysPrintf("Timer 3 Set to 1 %x\n", value); + + if(psxCounters[3].mode & 0x1){ + SysPrintf("Gate Check set on Counter 3\n"); + psxCounters[3].mode|= 0x1000000; + psxvblankgate |= 1<<3; + }else + psxvblankgate &= ~(1<<3); + + psxCounters[3].count = 0; + psxRcntUpd32(3); + if(psxCounters[3].target > 0xffffffff) { + //SysPrintf("IOP 32 Correcting target 3 after mode write\n"); + psxCounters[3].target &= 0xffffffff; + } + psxRcntSet(); + //} +} + +void psxRcnt4Wmode(u32 value) { +#ifdef PSXCNT_LOG + PSXCNT_LOG("IOP writeCmode[4] = %lx\n", value); +#endif + + if (value & 0x1c00) { + SysPrintf("Counter 4 Value write %x\n", value & 0x1c00); + } + + psxCounters[4].mode = value; + psxCounters[4].mode|= 0x0400; + + switch(value & 0x6000){ + case 0x0000: + //SysPrintf("Timer 4 Set to 1 %x\n", value); + psxCounters[4].rate = 1; + break; + case 0x2000: + SysPrintf("Timer 4 Set to 8 %x\n", value); + psxCounters[4].rate = 8; + break; + case 0x4000: + SysPrintf("Timer 4 Set to 16 %x\n", value); + psxCounters[4].rate = 16; + break; + case 0x6000: + SysPrintf("Timer 4 Set to 256 %x\n", value); + psxCounters[4].rate = 256; + break; + } + // Need to set a rate and target + if((psxCounters[4].mode & 0x7) == 0x7 || (psxCounters[4].mode & 0x7) == 0x1){ + SysPrintf("Gate set on IOP C4, disabling\n"); + psxCounters[4].mode|= 0x1000000; + } + psxCounters[4].count = 0; + psxRcntUpd32(4); + if(psxCounters[4].target > 0xffffffff) { + //SysPrintf("IOP 32 Correcting target 4 after mode write\n"); + psxCounters[4].target &= 0xffffffff; + } + psxRcntSet(); +} + +void psxRcnt5Wmode(u32 value) { +#ifdef PSXCNT_LOG + PSXCNT_LOG("IOP writeCmode[5] = %lx\n", value); +#endif + + if (value & 0x1c00) { + SysPrintf("Counter 5 Value write %x\n", value & 0x1c00); + } + + psxCounters[5].mode = value; + psxCounters[5].mode|= 0x0400; + + switch(value & 0x6000){ + case 0x0000: + //SysPrintf("Timer 5 Set to 1 %x\n", value); + psxCounters[5].rate = 1; + break; + case 0x2000: + SysPrintf("Timer 5 Set to 8 %x\n", value); + psxCounters[5].rate = 8; + break; + case 0x4000: + SysPrintf("Timer 5 Set to 16 %x\n", value); + psxCounters[5].rate = 16; + break; + case 0x6000: + SysPrintf("Timer 5 Set to 256 %x\n", value); + psxCounters[5].rate = 256; + break; + } + // Need to set a rate and target + if((psxCounters[5].mode & 0x7) == 0x7 || (psxCounters[5].mode & 0x7) == 0x1){ + SysPrintf("Gate set on IOP C5, disabling\n"); + psxCounters[5].mode|= 0x1000000; + } + psxCounters[5].count = 0; + psxRcntUpd32(5); + if(psxCounters[5].target > 0xffffffff) { + //SysPrintf("IOP 32 Correcting target 5 after mode write\n"); + psxCounters[5].target &= 0xffffffff; + } + psxRcntSet(); +} + +void psxRcntWtarget16(int index, u32 value) { +#ifdef PSXCNT_LOG + PSXCNT_LOG("writeCtarget16[%ld] = %lx\n", index, value); +#endif + psxCounters[index].target = value & 0xffff; + if(psxCounters[index].target <= psxRcntCycles(index)/* && psxCounters[index].target != 0*/) { + //SysPrintf("IOP 16 Saving %x target from early trigger target = %x, count = %I64x\n", index, psxCounters[index].target, psxRcntCycles(index)); + psxCounters[index].target += 0x1000000000; + } + + psxRcntSet(); +} + +void psxRcntWtarget32(int index, u32 value) { +#ifdef PSXCNT_LOG + PSXCNT_LOG("writeCtarget32[%ld] = %lx (count=%lx) ; sCycleT: %x CycleT: %x psxRegscycle %x\n", + index, value, psxCounters[index].count, psxCounters[index].sCycleT, psxCounters[index].CycleT, psxRegs.cycle); +#endif + + psxCounters[index].target = value; + if(psxCounters[index].target <= psxRcntCycles(index)/* && psxCounters[index].target != 0*/) { + //SysPrintf("IOP 32 Saving %x target from early trigger target = %x, count = %I64x\n", index, psxCounters[index].target, psxRcntCycles(index)); + psxCounters[index].target += 0x1000000000; + } + + psxRcntSet(); +} + +u16 psxRcntRcount16(int index) { + if(psxCounters[index].mode & 0x1000000) return (u16)psxCounters[index].count; + return (u16)(psxCounters[index].count + (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate)); +} + +u32 psxRcntRcount32(int index) { + if(psxCounters[index].mode & 0x1000000) return (u32)psxCounters[index].count; + return (u32)(psxCounters[index].count + (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate)); +} + +u64 psxRcntCycles(int index) { + if(psxCounters[index].mode & 0x1000000) return psxCounters[index].count; + return (u64)(psxCounters[index].count + (u32)((psxRegs.cycle - psxCounters[index].sCycleT) / psxCounters[index].rate)); +} + +extern u32 dwCurSaveStateVer; +int psxRcntFreeze(gzFile f, int Mode) +{ + if( Mode == 0 && (dwCurSaveStateVer < 0x7a300010) ) { // reading + // struct used to be 32bit count and target + int i; + u32 val; + for(i = 0; i < ARRAYSIZE(psxCounters); ++i) { + gzfreeze(&val,4); psxCounters[i].count = val; + gzfreeze(&val,4); psxCounters[i].mode = val; + gzfreeze(&val,4); psxCounters[i].target = val; + gzfreeze((u8*)&psxCounters[i].rate, sizeof(psxCounters[i])-20); + } + } + else + gzfreezel(psxCounters); + + + return 0; +} diff --git a/pcsx2/PsxCounters.h b/pcsx2/PsxCounters.h index ab25d35..c0a1e2f 100644 --- a/pcsx2/PsxCounters.h +++ b/pcsx2/PsxCounters.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __PSXCOUNTERS_H__ diff --git a/pcsx2/PsxDma.c b/pcsx2/PsxDma.c index 6ff1b54..5b0d696 100644 --- a/pcsx2/PsxDma.c +++ b/pcsx2/PsxDma.c @@ -1,289 +1,289 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2004 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include "PsxCommon.h" - -// Dma0/1 in Mdec.c -// Dma3 in CdRom.c -// Dma8 in PsxSpd.c -// Dma11/12 in PsxSio2.c -//static int spudmaenable[2]; -int spu2interrupts[2]; -int iopsifbusy[2] = { 0, 0 }; -void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU - int size; - - /*if(chcr & 0x400) SysPrintf("SPU 2 DMA 4 linked list chain mode! chcr = %x madr = %x bcr = %x\n", chcr, madr, bcr); - if(chcr & 0x40000000) SysPrintf("SPU 2 DMA 4 Unusual bit set on 'to' direction chcr = %x madr = %x bcr = %x\n", chcr, madr, bcr); - if((chcr & 0x1) == 0) SysPrintf("SPU 2 DMA 4 loading from spu2 memory chcr = %x madr = %x bcr = %x\n", chcr, madr, bcr); -*/ - - if(SPU2async) - { - //if((psxRegs.cycle - psxCounters[6].sCycleT) >= psxCounters[6].CycleT){ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "PsxCommon.h" + +// Dma0/1 in Mdec.c +// Dma3 in CdRom.c +// Dma8 in PsxSpd.c +// Dma11/12 in PsxSio2.c +//static int spudmaenable[2]; +int spu2interrupts[2]; +int iopsifbusy[2] = { 0, 0 }; +void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU + int size; + + /*if(chcr & 0x400) SysPrintf("SPU 2 DMA 4 linked list chain mode! chcr = %x madr = %x bcr = %x\n", chcr, madr, bcr); + if(chcr & 0x40000000) SysPrintf("SPU 2 DMA 4 Unusual bit set on 'to' direction chcr = %x madr = %x bcr = %x\n", chcr, madr, bcr); + if((chcr & 0x1) == 0) SysPrintf("SPU 2 DMA 4 loading from spu2 memory chcr = %x madr = %x bcr = %x\n", chcr, madr, bcr); +*/ + + if(SPU2async) + { + //if((psxRegs.cycle - psxCounters[6].sCycleT) >= psxCounters[6].CycleT){ SPU2async(psxRegs.cycle - psxCounters[6].sCycleT); //SysPrintf("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT); psxCounters[6].sCycleT = psxRegs.cycle; psxCounters[6].CycleT = ((bcr >> 16) * (bcr & 0xFFFF)) * 3; - //} - psxNextCounter -= (psxRegs.cycle-psxNextsCounter); - psxNextsCounter = psxRegs.cycle; - if(psxCounters[6].CycleT < psxNextCounter) psxNextCounter = psxCounters[6].CycleT; - - } - - switch (chcr) { - case 0x01000201: //cpu to spu transfer -#ifdef PSXDMA_LOG - PSXDMA_LOG("*** DMA 4 - SPU mem2spu *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); -#endif - //SysPrintf("DMA4 write blocks %x, size per block %x\n", (bcr >> 16), (bcr & 0xFFFF)); - size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer - SPU2writeDMA4Mem((u16 *)PSXM(madr), size*2); - break; - case 0x01000200: //spu to cpu transfer -#ifdef PSXDMA_LOG - PSXDMA_LOG("*** DMA 4 - SPU spu2mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); -#endif - //SysPrintf("DMA4 read blocks %x, size per block %x\n", (bcr >> 16), (bcr & 0xFFFF)); - size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer - SPU2readDMA4Mem((u16 *)PSXM(madr), size*2); - psxCpu->Clear(HW_DMA4_MADR, size); - break; - - default: - SysPrintf("*** DMA 4 - SPU unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); - break; - } - - //spudmaenable[0] = size; -} - -int psxDma4Interrupt() { - HW_DMA4_CHCR &= ~0x01000000; - psxDmaInterrupt(4); - psxHu32(0x1070)|= 1<<9; - return 1; -} - -void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU - HW_DMA2_CHCR &= ~0x01000000; - psxDmaInterrupt(2); -} - -void psxDma6(u32 madr, u32 bcr, u32 chcr) { - u32 *mem = (u32 *)PSXM(madr); - -#ifdef PSXDMA_LOG - PSXDMA_LOG("*** DMA 6 - OT *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); -#endif - - if (chcr == 0x11000002) { - while (bcr--) { - *mem-- = (madr - 4) & 0xffffff; - madr -= 4; - } - mem++; *mem = 0xffffff; - } else { - // Unknown option -#ifdef PSXDMA_LOG - PSXDMA_LOG("*** DMA 6 - OT unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); -#endif - } - HW_DMA6_CHCR &= ~0x01000000; - psxDmaInterrupt(6); -} - -void psxDma7(u32 madr, u32 bcr, u32 chcr) { - int size; - - if(SPU2async) - { - //if((psxRegs.cycle - psxCounters[6].sCycleT) >= psxCounters[6].CycleT){ + //} + psxNextCounter -= (psxRegs.cycle-psxNextsCounter); + psxNextsCounter = psxRegs.cycle; + if(psxCounters[6].CycleT < psxNextCounter) psxNextCounter = psxCounters[6].CycleT; + + } + + switch (chcr) { + case 0x01000201: //cpu to spu transfer +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 4 - SPU mem2spu *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + //SysPrintf("DMA4 write blocks %x, size per block %x\n", (bcr >> 16), (bcr & 0xFFFF)); + size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer + SPU2writeDMA4Mem((u16 *)PSXM(madr), size*2); + break; + case 0x01000200: //spu to cpu transfer +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 4 - SPU spu2mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + //SysPrintf("DMA4 read blocks %x, size per block %x\n", (bcr >> 16), (bcr & 0xFFFF)); + size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer + SPU2readDMA4Mem((u16 *)PSXM(madr), size*2); + psxCpu->Clear(HW_DMA4_MADR, size); + break; + + default: + SysPrintf("*** DMA 4 - SPU unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); + break; + } + + //spudmaenable[0] = size; +} + +int psxDma4Interrupt() { + HW_DMA4_CHCR &= ~0x01000000; + psxDmaInterrupt(4); + psxHu32(0x1070)|= 1<<9; + return 1; +} + +void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU + HW_DMA2_CHCR &= ~0x01000000; + psxDmaInterrupt(2); +} + +void psxDma6(u32 madr, u32 bcr, u32 chcr) { + u32 *mem = (u32 *)PSXM(madr); + +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 6 - OT *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + + if (chcr == 0x11000002) { + while (bcr--) { + *mem-- = (madr - 4) & 0xffffff; + madr -= 4; + } + mem++; *mem = 0xffffff; + } else { + // Unknown option +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 6 - OT unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + } + HW_DMA6_CHCR &= ~0x01000000; + psxDmaInterrupt(6); +} + +void psxDma7(u32 madr, u32 bcr, u32 chcr) { + int size; + + if(SPU2async) + { + //if((psxRegs.cycle - psxCounters[6].sCycleT) >= psxCounters[6].CycleT){ SPU2async(psxRegs.cycle - psxCounters[6].sCycleT); //SysPrintf("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT); psxCounters[6].sCycleT = psxRegs.cycle; psxCounters[6].CycleT = ((bcr >> 16) * (bcr & 0xFFFF)) * 3; - //} - psxNextCounter -= (psxRegs.cycle-psxNextsCounter); - psxNextsCounter = psxRegs.cycle; - if(psxCounters[6].CycleT < psxNextCounter) psxNextCounter = psxCounters[6].CycleT; - - } - - - switch (chcr) { - case 0x01000201: //cpu to spu2 transfer -#ifdef PSXDMA_LOG - PSXDMA_LOG("*** DMA 7 - SPU2 mem2spu *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); -#endif - //SysPrintf("DMA7 write blocks %x, size per block %x\n", (bcr >> 16), (bcr & 0xFFFF)); - size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer - - SPU2writeDMA7Mem((u16 *)PSXM(madr), size*2); - break; - case 0x01000200: //spu2 to cpu transfer -#ifdef PSXDMA_LOG - PSXDMA_LOG("*** DMA 7 - SPU2 spu2mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); -#endif - //SysPrintf("DMA4 read blocks %x, size per block %x\n", (bcr >> 16), (bcr & 0xFFFF)); - size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer - - SPU2readDMA7Mem((u16 *)PSXM(madr), size*2); - psxCpu->Clear(HW_DMA7_MADR, size); - break; - default: - SysPrintf("*** DMA 7 - SPU unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); - break; - } - -} - -int psxDma7Interrupt() { - - HW_DMA7_CHCR &= ~0x01000000; - psxDmaInterrupt2(0); - return 1; - -} -extern int eesifbusy[2]; -void psxDma9(u32 madr, u32 bcr, u32 chcr) { - - DMACh *dma = (DMACh*)&PS2MEM_HW[0xc000]; - -#ifdef SIF_LOG - SIF_LOG("IOP: dmaSIF0 chcr = %lx, madr = %lx, bcr = %lx, tadr = %lx\n", chcr, madr, bcr, HW_DMA9_TADR); -#endif - - iopsifbusy[0] = 1; - psHu32(0x1000F240) |= 0x2000; - if (eesifbusy[0] == 1 && iopsifbusy[0] == 1) { - SIF0Dma(); - psHu32(0x1000F240) &= ~0x20; - psHu32(0x1000F240) &= ~0x2000; - } -} - -void psxDma10(u32 madr, u32 bcr, u32 chcr) { - DMACh *dma = (DMACh*)&PS2MEM_HW[0xc400]; - -#ifdef SIF_LOG - SIF_LOG("IOP: dmaSIF1 chcr = %lx, madr = %lx, bcr = %lx\n", chcr, madr, bcr); -#endif - - iopsifbusy[1] = 1; - psHu32(0x1000F240) |= 0x4000; - if (eesifbusy[1] == 1 && iopsifbusy[1] == 1) { - SIF1Dma(); - psHu32(0x1000F240) &= ~0x40; - psHu32(0x1000F240) &= ~0x100; - psHu32(0x1000F240) &= ~0x4000; - } -} - -void psxDma8(u32 madr, u32 bcr, u32 chcr) { - int size; - - switch (chcr & 0x01000201) { - case 0x01000201: //cpu to dev9 transfer -#ifdef PSXDMA_LOG - PSXDMA_LOG("*** DMA 8 - DEV9 mem2dev9 *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); -#endif - size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer - - DEV9writeDMA8Mem((u32*)PSXM(madr), size*8); - break; - case 0x01000200: //dev9 to cpu transfer -#ifdef PSXDMA_LOG - PSXDMA_LOG("*** DMA 8 - DEV9 dev9mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); -#endif - size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer - - DEV9readDMA8Mem((u32*)PSXM(madr), size*8); - break; -#ifdef PSXDMA_LOG - default: - PSXDMA_LOG("*** DMA 8 - DEV9 unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); - break; -#endif - } - HW_DMA8_CHCR &= ~0x01000000; - psxDmaInterrupt2(1); -} - -void dev9Interrupt() { - if (dev9Handler == NULL) goto irq; - if (dev9Handler() != 1) { - psxRegs.interrupt&= ~(1 << 20); - return; - } -irq: - psxHu32(0x1070)|= 1<<13; - //SBUS - hwIntcIrq(INTC_SBUS); - psxRegs.interrupt&= ~(1 << 20); -} - -void dev9Irq(int cycles) { - PSX_INT(20, cycles); -} - -void usbInterrupt() { - if (usbHandler == NULL) goto irq; - if (usbHandler() != 1) { - psxRegs.interrupt&= ~(1 << 21); - return; - } -irq: - psxHu32(0x1070)|= 1<<22; - //SBUS - hwIntcIrq(INTC_SBUS); - psxRegs.interrupt&= ~(1 << 21); -} - -void usbIrq(int cycles) { - PSX_INT(21, cycles); -} - -void fwIrq() { - psxHu32(0x1070)|= 1<<24; - //SBUS - hwIntcIrq(INTC_SBUS); -} - -void spu2DMA4Irq() { - SPU2interruptDMA4(); - //HW_DMA4_BCR = 0; - HW_DMA4_CHCR &= ~0x01000000; - psxDmaInterrupt(4); -} - -void spu2DMA7Irq() { - SPU2interruptDMA7(); - //HW_DMA7_BCR = 0; - HW_DMA7_CHCR &= ~0x01000000; - psxDmaInterrupt2(0); -} - -void spu2Irq() { - psxHu32(0x1070)|= 1<<9; - //SBUS - hwIntcIrq(INTC_SBUS); -} + //} + psxNextCounter -= (psxRegs.cycle-psxNextsCounter); + psxNextsCounter = psxRegs.cycle; + if(psxCounters[6].CycleT < psxNextCounter) psxNextCounter = psxCounters[6].CycleT; + + } + + + switch (chcr) { + case 0x01000201: //cpu to spu2 transfer +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 7 - SPU2 mem2spu *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + //SysPrintf("DMA7 write blocks %x, size per block %x\n", (bcr >> 16), (bcr & 0xFFFF)); + size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer + + SPU2writeDMA7Mem((u16 *)PSXM(madr), size*2); + break; + case 0x01000200: //spu2 to cpu transfer +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 7 - SPU2 spu2mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + //SysPrintf("DMA4 read blocks %x, size per block %x\n", (bcr >> 16), (bcr & 0xFFFF)); + size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer + + SPU2readDMA7Mem((u16 *)PSXM(madr), size*2); + psxCpu->Clear(HW_DMA7_MADR, size); + break; + default: + SysPrintf("*** DMA 7 - SPU unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); + break; + } + +} + +int psxDma7Interrupt() { + + HW_DMA7_CHCR &= ~0x01000000; + psxDmaInterrupt2(0); + return 1; + +} +extern int eesifbusy[2]; +void psxDma9(u32 madr, u32 bcr, u32 chcr) { + + DMACh *dma = (DMACh*)&PS2MEM_HW[0xc000]; + +#ifdef SIF_LOG + SIF_LOG("IOP: dmaSIF0 chcr = %lx, madr = %lx, bcr = %lx, tadr = %lx\n", chcr, madr, bcr, HW_DMA9_TADR); +#endif + + iopsifbusy[0] = 1; + psHu32(0x1000F240) |= 0x2000; + if (eesifbusy[0] == 1 && iopsifbusy[0] == 1) { + SIF0Dma(); + psHu32(0x1000F240) &= ~0x20; + psHu32(0x1000F240) &= ~0x2000; + } +} + +void psxDma10(u32 madr, u32 bcr, u32 chcr) { + DMACh *dma = (DMACh*)&PS2MEM_HW[0xc400]; + +#ifdef SIF_LOG + SIF_LOG("IOP: dmaSIF1 chcr = %lx, madr = %lx, bcr = %lx\n", chcr, madr, bcr); +#endif + + iopsifbusy[1] = 1; + psHu32(0x1000F240) |= 0x4000; + if (eesifbusy[1] == 1 && iopsifbusy[1] == 1) { + SIF1Dma(); + psHu32(0x1000F240) &= ~0x40; + psHu32(0x1000F240) &= ~0x100; + psHu32(0x1000F240) &= ~0x4000; + } +} + +void psxDma8(u32 madr, u32 bcr, u32 chcr) { + int size; + + switch (chcr & 0x01000201) { + case 0x01000201: //cpu to dev9 transfer +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 8 - DEV9 mem2dev9 *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer + + DEV9writeDMA8Mem((u32*)PSXM(madr), size*8); + break; + case 0x01000200: //dev9 to cpu transfer +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 8 - DEV9 dev9mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer + + DEV9readDMA8Mem((u32*)PSXM(madr), size*8); + break; +#ifdef PSXDMA_LOG + default: + PSXDMA_LOG("*** DMA 8 - DEV9 unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); + break; +#endif + } + HW_DMA8_CHCR &= ~0x01000000; + psxDmaInterrupt2(1); +} + +void dev9Interrupt() { + if (dev9Handler == NULL) goto irq; + if (dev9Handler() != 1) { + psxRegs.interrupt&= ~(1 << 20); + return; + } +irq: + psxHu32(0x1070)|= 1<<13; + //SBUS + hwIntcIrq(INTC_SBUS); + psxRegs.interrupt&= ~(1 << 20); +} + +void dev9Irq(int cycles) { + PSX_INT(20, cycles); +} + +void usbInterrupt() { + if (usbHandler == NULL) goto irq; + if (usbHandler() != 1) { + psxRegs.interrupt&= ~(1 << 21); + return; + } +irq: + psxHu32(0x1070)|= 1<<22; + //SBUS + hwIntcIrq(INTC_SBUS); + psxRegs.interrupt&= ~(1 << 21); +} + +void usbIrq(int cycles) { + PSX_INT(21, cycles); +} + +void fwIrq() { + psxHu32(0x1070)|= 1<<24; + //SBUS + hwIntcIrq(INTC_SBUS); +} + +void spu2DMA4Irq() { + SPU2interruptDMA4(); + //HW_DMA4_BCR = 0; + HW_DMA4_CHCR &= ~0x01000000; + psxDmaInterrupt(4); +} + +void spu2DMA7Irq() { + SPU2interruptDMA7(); + //HW_DMA7_BCR = 0; + HW_DMA7_CHCR &= ~0x01000000; + psxDmaInterrupt2(0); +} + +void spu2Irq() { + psxHu32(0x1070)|= 1<<9; + //SBUS + hwIntcIrq(INTC_SBUS); +} diff --git a/pcsx2/PsxDma.h b/pcsx2/PsxDma.h index 4713a7a..702519f 100644 --- a/pcsx2/PsxDma.h +++ b/pcsx2/PsxDma.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __PSXDMA_H__ diff --git a/pcsx2/PsxHw.c b/pcsx2/PsxHw.c index 235d9b3..d1c9166 100644 --- a/pcsx2/PsxHw.c +++ b/pcsx2/PsxHw.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/PsxHw.h b/pcsx2/PsxHw.h index c0f4b64..cb689ed 100644 --- a/pcsx2/PsxHw.h +++ b/pcsx2/PsxHw.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __PSXHW_H__ diff --git a/pcsx2/PsxInterpreter.c b/pcsx2/PsxInterpreter.c index 955a4e7..f44200d 100644 --- a/pcsx2/PsxInterpreter.c +++ b/pcsx2/PsxInterpreter.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + #include #include diff --git a/pcsx2/PsxMem.c b/pcsx2/PsxMem.c index 3ad797a..62b151c 100644 --- a/pcsx2/PsxMem.c +++ b/pcsx2/PsxMem.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/pcsx2/PsxMem.h b/pcsx2/PsxMem.h index daf1018..762f4b3 100644 --- a/pcsx2/PsxMem.h +++ b/pcsx2/PsxMem.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __PSXMEMORY_H__ diff --git a/pcsx2/PsxSio2.c b/pcsx2/PsxSio2.c index a0bec68..72a013d 100644 --- a/pcsx2/PsxSio2.c +++ b/pcsx2/PsxSio2.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/PsxSio2.h b/pcsx2/PsxSio2.h index ad27925..6e64de1 100644 --- a/pcsx2/PsxSio2.h +++ b/pcsx2/PsxSio2.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __PSXSIO2_H__ diff --git a/pcsx2/R3000A.c b/pcsx2/R3000A.c index 836bd1e..4614f53 100644 --- a/pcsx2/R3000A.c +++ b/pcsx2/R3000A.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/R3000A.h b/pcsx2/R3000A.h index fd41813..cc56d3b 100644 --- a/pcsx2/R3000A.h +++ b/pcsx2/R3000A.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __R3000A_H__ diff --git a/pcsx2/R5900.c b/pcsx2/R5900.c index 9500521..c27a825 100644 --- a/pcsx2/R5900.c +++ b/pcsx2/R5900.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/pcsx2/R5900.h b/pcsx2/R5900.h index 648d5d7..db6efcc 100644 --- a/pcsx2/R5900.h +++ b/pcsx2/R5900.h @@ -1,282 +1,282 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __R5900_H__ -#define __R5900_H__ - -#include - -typedef struct { - int (*Init)(); - void (*Reset)(); - void (*Step)(); - void (*Execute)(); /* executes up to a break */ - void (*ExecuteBlock)(); /* executes up to a jump */ - void (*ExecuteVU0Block)(); /* executes up to a jump */ - void (*ExecuteVU1Block)(); /* executes up to a jump */ - void (*EnableVU0micro)(int enable); - void (*EnableVU1micro)(int enable); - void (*Clear)(u32 Addr, u32 Size); - void (*ClearVU0)(u32 Addr, u32 Size); - void (*ClearVU1)(u32 Addr, u32 Size); - void (*Shutdown)(); -} R5900cpu; - -extern R5900cpu *Cpu; -extern R5900cpu intCpu; -extern R5900cpu recCpu; -extern u32 bExecBIOS; - -typedef union { // Declare union type GPR register - u64 UD[2]; //128 bits - s64 SD[2]; - u32 UL[4]; - s32 SL[4]; - u16 US[8]; - s16 SS[8]; - u8 UC[16]; - s8 SC[16]; -} GPR_reg; - -typedef union { - struct { - GPR_reg r0, at, v0, v1, a0, a1, a2, a3, - t0, t1, t2, t3, t4, t5, t6, t7, - s0, s1, s2, s3, s4, s5, s6, s7, - t8, t9, k0, k1, gp, sp, s8, ra; - } n; - GPR_reg r[32]; -} GPRregs; - -typedef union { - struct { - u32 pccr, pcr0, pcr1, pad; - } n; - u32 r[4]; -} PERFregs; - -typedef union { - struct { - u32 Index, Random, EntryLo0, EntryLo1, - Context, PageMask, Wired, Reserved0, - BadVAddr, Count, EntryHi, Compare; - union { - struct { - int IE:1; - int EXL:1; - int ERL:1; - int KSU:2; - int unused0:3; - int IM:8; - int EIE:1; - int _EDI:1; - int CH:1; - int unused1:3; - int BEV:1; - int DEV:1; - int unused2:2; - int FR:1; - int unused3:1; - int CU:4; - } b; - u32 val; - } Status; - u32 Cause, EPC, PRid, - Config, LLAddr, WatchLO, WatchHI, - XContext, Reserved1, Reserved2, Debug, - DEPC, PerfCnt, ErrCtl, CacheErr, - TagLo, TagHi, ErrorEPC, DESAVE; - } n; - u32 r[32]; -} CP0regs; - -typedef struct { - GPRregs GPR; // GPR regs - // NOTE: don't change order since recompiler uses it - GPR_reg HI; - GPR_reg LO; // hi & log 128bit wide - CP0regs CP0; // is COP0 32bit? - u32 sa; // shift amount (32bit), needs to be 16 byte aligned - u32 constzero; // always 0, for MFSA - u32 pc; // Program counter, when changing offset in struct, check iR5900-X.S to make sure offset is correct - u32 code; // The instruction - PERFregs PERF; - u32 eCycle[32]; - u32 sCycle[32]; // for internal counters - u32 cycle; // calculate cpucycles.. - u32 interrupt; - int branch; - int opmode; // operating mode - u32 tempcycles; -} cpuRegisters; - -extern int EEsCycle; -extern u32 EEoCycle, IOPoCycle; -extern PCSX2_ALIGNED16_DECL(cpuRegisters cpuRegs); - -// used for optimization -typedef union { - u64 UD[1]; //64 bits - s64 SD[1]; - u32 UL[2]; - s32 SL[3]; - u16 US[4]; - s16 SS[4]; - u8 UC[8]; - s8 SC[8]; -} GPR_reg64; - -#define GPR_IS_CONST1(reg) ((reg)<32 && (g_cpuHasConstReg&(1<<(reg)))) -#define GPR_IS_CONST2(reg1, reg2) ((g_cpuHasConstReg&(1<<(reg1)))&&(g_cpuHasConstReg&(1<<(reg2)))) -#define GPR_SET_CONST(reg) { \ - if( (reg) < 32 ) { \ - g_cpuHasConstReg |= (1<<(reg)); \ - g_cpuFlushedConstReg &= ~(1<<(reg)); \ - } \ -} - -#define GPR_DEL_CONST(reg) { \ - if( (reg) < 32 ) g_cpuHasConstReg &= ~(1<<(reg)); \ -} - -extern PCSX2_ALIGNED16_DECL(GPR_reg64 g_cpuConstRegs[32]); -extern u32 g_cpuHasConstReg, g_cpuFlushedConstReg; - -typedef union { - float f; - u32 UL; -} FPRreg; - -typedef struct { - FPRreg fpr[32]; // 32bit floating point registers - u32 fprc[32]; // 32bit floating point control registers - FPRreg ACC; // 32 bit accumulator -} fpuRegisters; - -extern PCSX2_ALIGNED16_DECL(fpuRegisters fpuRegs); - - -typedef struct { - u32 PageMask,EntryHi; - u32 EntryLo0,EntryLo1; - u32 Mask, nMask; - u32 G; - u32 ASID; - u32 VPN2; - u32 PFN0; - u32 PFN1; -} tlbs; - -extern PCSX2_ALIGNED16_DECL(tlbs tlb[48]); - -#ifndef _PC_ - -#define _i64(x) (s64)x -#define _u64(x) (u64)x - -#define _i32(x) (s32)x -#define _u32(x) (u32)x - -#define _i16(x) (s16)x -#define _u16(x) (u16)x - -#define _i8(x) (s8)x -#define _u8(x) (u8)x - -/**** R3000A Instruction Macros ****/ -#define _PC_ cpuRegs.pc // The next PC to be executed - -#define _Funct_ ((cpuRegs.code ) & 0x3F) // The funct part of the instruction register -#define _Rd_ ((cpuRegs.code >> 11) & 0x1F) // The rd part of the instruction register -#define _Rt_ ((cpuRegs.code >> 16) & 0x1F) // The rt part of the instruction register -#define _Rs_ ((cpuRegs.code >> 21) & 0x1F) // The rs part of the instruction register -#define _Sa_ ((cpuRegs.code >> 6) & 0x1F) // The sa part of the instruction register -#define _Im_ ((u16)cpuRegs.code) // The immediate part of the instruction register -#define _Target_ (cpuRegs.code & 0x03ffffff) // The target part of the instruction register - -#define _Imm_ ((s16)cpuRegs.code) // sign-extended immediate -#define _ImmU_ (cpuRegs.code&0xffff) // zero-extended immediate - - -//#define _JumpTarget_ ((_Target_ * 4) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction -//#define _BranchTarget_ ((s16)_Im_ * 4 + _PC_) // Calculates the target during a branch instruction - -#define _JumpTarget_ ((_Target_ << 2) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction -#define _BranchTarget_ (((s32)(s16)_Im_ * 4) + _PC_) // Calculates the target during a branch instruction - -#define _SetLink(x) cpuRegs.GPR.r[x].UD[0] = _PC_ + 4; // Sets the return address in the link register - -#endif - -int cpuInit(); -void cpuReset(); -void cpuShutdown(); -void cpuException(u32 code, u32 bd); -void cpuTlbMissR(u32 addr, u32 bd); -void cpuTlbMissW(u32 addr, u32 bd); -void IntcpuBranchTest(); -void cpuBranchTest(); -void cpuTestHwInts(); -void cpuTestINTCInts(); -void cpuTestDMACInts(); -void cpuTestTIMRInts(); -void _cpuTestInterrupts(); -void cpuExecuteBios(); -void cpuRestartCPU(); - -u32 VirtualToPhysicalR(u32 addr); -u32 VirtualToPhysicalW(u32 addr); - -void intDoBranch(u32 target); -void intSetBranch(); -void intExecuteVU0Block(); -void intExecuteVU1Block(); - -void JumpCheckSym(u32 addr, u32 pc); -void JumpCheckSymRet(u32 addr); - -extern u32 g_EEFreezeRegs; - -//exception code -#define EXC_CODE(x) ((x)<<2) - -#define EXC_CODE_Int EXC_CODE(0) -#define EXC_CODE_Mod EXC_CODE(1) /* TLB Modification exception */ -#define EXC_CODE_TLBL EXC_CODE(2) /* TLB Miss exception (load or instruction fetch) */ -#define EXC_CODE_TLBS EXC_CODE(3) /* TLB Miss exception (store) */ -#define EXC_CODE_AdEL EXC_CODE(4) -#define EXC_CODE_AdES EXC_CODE(5) -#define EXC_CODE_IBE EXC_CODE(6) -#define EXC_CODE_DBE EXC_CODE(7) -#define EXC_CODE_Sys EXC_CODE(8) -#define EXC_CODE_Bp EXC_CODE(9) -#define EXC_CODE_Ri EXC_CODE(10) -#define EXC_CODE_CpU EXC_CODE(11) -#define EXC_CODE_Ov EXC_CODE(12) -#define EXC_CODE_Tr EXC_CODE(13) -#define EXC_CODE_FPE EXC_CODE(15) -#define EXC_CODE_WATCH EXC_CODE(23) -#define EXC_CODE__MASK 0x0000007c -#define EXC_CODE__SHIFT 2 - -#define EXC_TLB_STORE 1 -#define EXC_TLB_LOAD 0 - +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __R5900_H__ +#define __R5900_H__ + +#include + +typedef struct { + int (*Init)(); + void (*Reset)(); + void (*Step)(); + void (*Execute)(); /* executes up to a break */ + void (*ExecuteBlock)(); /* executes up to a jump */ + void (*ExecuteVU0Block)(); /* executes up to a jump */ + void (*ExecuteVU1Block)(); /* executes up to a jump */ + void (*EnableVU0micro)(int enable); + void (*EnableVU1micro)(int enable); + void (*Clear)(u32 Addr, u32 Size); + void (*ClearVU0)(u32 Addr, u32 Size); + void (*ClearVU1)(u32 Addr, u32 Size); + void (*Shutdown)(); +} R5900cpu; + +extern R5900cpu *Cpu; +extern R5900cpu intCpu; +extern R5900cpu recCpu; +extern u32 bExecBIOS; + +typedef union { // Declare union type GPR register + u64 UD[2]; //128 bits + s64 SD[2]; + u32 UL[4]; + s32 SL[4]; + u16 US[8]; + s16 SS[8]; + u8 UC[16]; + s8 SC[16]; +} GPR_reg; + +typedef union { + struct { + GPR_reg r0, at, v0, v1, a0, a1, a2, a3, + t0, t1, t2, t3, t4, t5, t6, t7, + s0, s1, s2, s3, s4, s5, s6, s7, + t8, t9, k0, k1, gp, sp, s8, ra; + } n; + GPR_reg r[32]; +} GPRregs; + +typedef union { + struct { + u32 pccr, pcr0, pcr1, pad; + } n; + u32 r[4]; +} PERFregs; + +typedef union { + struct { + u32 Index, Random, EntryLo0, EntryLo1, + Context, PageMask, Wired, Reserved0, + BadVAddr, Count, EntryHi, Compare; + union { + struct { + int IE:1; + int EXL:1; + int ERL:1; + int KSU:2; + int unused0:3; + int IM:8; + int EIE:1; + int _EDI:1; + int CH:1; + int unused1:3; + int BEV:1; + int DEV:1; + int unused2:2; + int FR:1; + int unused3:1; + int CU:4; + } b; + u32 val; + } Status; + u32 Cause, EPC, PRid, + Config, LLAddr, WatchLO, WatchHI, + XContext, Reserved1, Reserved2, Debug, + DEPC, PerfCnt, ErrCtl, CacheErr, + TagLo, TagHi, ErrorEPC, DESAVE; + } n; + u32 r[32]; +} CP0regs; + +typedef struct { + GPRregs GPR; // GPR regs + // NOTE: don't change order since recompiler uses it + GPR_reg HI; + GPR_reg LO; // hi & log 128bit wide + CP0regs CP0; // is COP0 32bit? + u32 sa; // shift amount (32bit), needs to be 16 byte aligned + u32 constzero; // always 0, for MFSA + u32 pc; // Program counter, when changing offset in struct, check iR5900-X.S to make sure offset is correct + u32 code; // The instruction + PERFregs PERF; + u32 eCycle[32]; + u32 sCycle[32]; // for internal counters + u32 cycle; // calculate cpucycles.. + u32 interrupt; + int branch; + int opmode; // operating mode + u32 tempcycles; +} cpuRegisters; + +extern int EEsCycle; +extern u32 EEoCycle, IOPoCycle; +extern PCSX2_ALIGNED16_DECL(cpuRegisters cpuRegs); + +// used for optimization +typedef union { + u64 UD[1]; //64 bits + s64 SD[1]; + u32 UL[2]; + s32 SL[3]; + u16 US[4]; + s16 SS[4]; + u8 UC[8]; + s8 SC[8]; +} GPR_reg64; + +#define GPR_IS_CONST1(reg) ((reg)<32 && (g_cpuHasConstReg&(1<<(reg)))) +#define GPR_IS_CONST2(reg1, reg2) ((g_cpuHasConstReg&(1<<(reg1)))&&(g_cpuHasConstReg&(1<<(reg2)))) +#define GPR_SET_CONST(reg) { \ + if( (reg) < 32 ) { \ + g_cpuHasConstReg |= (1<<(reg)); \ + g_cpuFlushedConstReg &= ~(1<<(reg)); \ + } \ +} + +#define GPR_DEL_CONST(reg) { \ + if( (reg) < 32 ) g_cpuHasConstReg &= ~(1<<(reg)); \ +} + +extern PCSX2_ALIGNED16_DECL(GPR_reg64 g_cpuConstRegs[32]); +extern u32 g_cpuHasConstReg, g_cpuFlushedConstReg; + +typedef union { + float f; + u32 UL; +} FPRreg; + +typedef struct { + FPRreg fpr[32]; // 32bit floating point registers + u32 fprc[32]; // 32bit floating point control registers + FPRreg ACC; // 32 bit accumulator +} fpuRegisters; + +extern PCSX2_ALIGNED16_DECL(fpuRegisters fpuRegs); + + +typedef struct { + u32 PageMask,EntryHi; + u32 EntryLo0,EntryLo1; + u32 Mask, nMask; + u32 G; + u32 ASID; + u32 VPN2; + u32 PFN0; + u32 PFN1; +} tlbs; + +extern PCSX2_ALIGNED16_DECL(tlbs tlb[48]); + +#ifndef _PC_ + +#define _i64(x) (s64)x +#define _u64(x) (u64)x + +#define _i32(x) (s32)x +#define _u32(x) (u32)x + +#define _i16(x) (s16)x +#define _u16(x) (u16)x + +#define _i8(x) (s8)x +#define _u8(x) (u8)x + +/**** R3000A Instruction Macros ****/ +#define _PC_ cpuRegs.pc // The next PC to be executed + +#define _Funct_ ((cpuRegs.code ) & 0x3F) // The funct part of the instruction register +#define _Rd_ ((cpuRegs.code >> 11) & 0x1F) // The rd part of the instruction register +#define _Rt_ ((cpuRegs.code >> 16) & 0x1F) // The rt part of the instruction register +#define _Rs_ ((cpuRegs.code >> 21) & 0x1F) // The rs part of the instruction register +#define _Sa_ ((cpuRegs.code >> 6) & 0x1F) // The sa part of the instruction register +#define _Im_ ((u16)cpuRegs.code) // The immediate part of the instruction register +#define _Target_ (cpuRegs.code & 0x03ffffff) // The target part of the instruction register + +#define _Imm_ ((s16)cpuRegs.code) // sign-extended immediate +#define _ImmU_ (cpuRegs.code&0xffff) // zero-extended immediate + + +//#define _JumpTarget_ ((_Target_ * 4) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction +//#define _BranchTarget_ ((s16)_Im_ * 4 + _PC_) // Calculates the target during a branch instruction + +#define _JumpTarget_ ((_Target_ << 2) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction +#define _BranchTarget_ (((s32)(s16)_Im_ * 4) + _PC_) // Calculates the target during a branch instruction + +#define _SetLink(x) cpuRegs.GPR.r[x].UD[0] = _PC_ + 4; // Sets the return address in the link register + +#endif + +int cpuInit(); +void cpuReset(); +void cpuShutdown(); +void cpuException(u32 code, u32 bd); +void cpuTlbMissR(u32 addr, u32 bd); +void cpuTlbMissW(u32 addr, u32 bd); +void IntcpuBranchTest(); +void cpuBranchTest(); +void cpuTestHwInts(); +void cpuTestINTCInts(); +void cpuTestDMACInts(); +void cpuTestTIMRInts(); +void _cpuTestInterrupts(); +void cpuExecuteBios(); +void cpuRestartCPU(); + +u32 VirtualToPhysicalR(u32 addr); +u32 VirtualToPhysicalW(u32 addr); + +void intDoBranch(u32 target); +void intSetBranch(); +void intExecuteVU0Block(); +void intExecuteVU1Block(); + +void JumpCheckSym(u32 addr, u32 pc); +void JumpCheckSymRet(u32 addr); + +extern u32 g_EEFreezeRegs; + +//exception code +#define EXC_CODE(x) ((x)<<2) + +#define EXC_CODE_Int EXC_CODE(0) +#define EXC_CODE_Mod EXC_CODE(1) /* TLB Modification exception */ +#define EXC_CODE_TLBL EXC_CODE(2) /* TLB Miss exception (load or instruction fetch) */ +#define EXC_CODE_TLBS EXC_CODE(3) /* TLB Miss exception (store) */ +#define EXC_CODE_AdEL EXC_CODE(4) +#define EXC_CODE_AdES EXC_CODE(5) +#define EXC_CODE_IBE EXC_CODE(6) +#define EXC_CODE_DBE EXC_CODE(7) +#define EXC_CODE_Sys EXC_CODE(8) +#define EXC_CODE_Bp EXC_CODE(9) +#define EXC_CODE_Ri EXC_CODE(10) +#define EXC_CODE_CpU EXC_CODE(11) +#define EXC_CODE_Ov EXC_CODE(12) +#define EXC_CODE_Tr EXC_CODE(13) +#define EXC_CODE_FPE EXC_CODE(15) +#define EXC_CODE_WATCH EXC_CODE(23) +#define EXC_CODE__MASK 0x0000007c +#define EXC_CODE__SHIFT 2 + +#define EXC_TLB_STORE 1 +#define EXC_TLB_LOAD 0 + //#define EE_PROFILING //EE Profiling enable #ifdef EE_PROFILING //EE Profiling code @@ -299,6 +299,6 @@ extern u64 profile_totalticks; #define END_EE_PROFILE() #define CLEAR_EE_PROFILE() -#endif - -#endif /* __R5900_H__ */ +#endif + +#endif /* __R5900_H__ */ diff --git a/pcsx2/RDebug/deci2.c b/pcsx2/RDebug/deci2.c index 49add6e..2f6c88c 100644 --- a/pcsx2/RDebug/deci2.c +++ b/pcsx2/RDebug/deci2.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include "Common.h" #include "deci2.h" diff --git a/pcsx2/RDebug/deci2.h b/pcsx2/RDebug/deci2.h index a26f49e..d2033b6 100644 --- a/pcsx2/RDebug/deci2.h +++ b/pcsx2/RDebug/deci2.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __DECI2_H__ diff --git a/pcsx2/RDebug/deci2_dbgp.c b/pcsx2/RDebug/deci2_dbgp.c index 879f573..597d526 100644 --- a/pcsx2/RDebug/deci2_dbgp.c +++ b/pcsx2/RDebug/deci2_dbgp.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include "Common.h" #include "PsxCommon.h" diff --git a/pcsx2/RDebug/deci2_dbgp.h b/pcsx2/RDebug/deci2_dbgp.h index ab28c21..7d5db0b 100644 --- a/pcsx2/RDebug/deci2_dbgp.h +++ b/pcsx2/RDebug/deci2_dbgp.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __DECI2DBGP_H__ diff --git a/pcsx2/RDebug/deci2_dcmp.c b/pcsx2/RDebug/deci2_dcmp.c index 9348040..b623b1a 100644 --- a/pcsx2/RDebug/deci2_dcmp.c +++ b/pcsx2/RDebug/deci2_dcmp.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include "Common.h" #include "deci2.h" diff --git a/pcsx2/RDebug/deci2_dcmp.h b/pcsx2/RDebug/deci2_dcmp.h index 18e2c80..aed478b 100644 --- a/pcsx2/RDebug/deci2_dcmp.h +++ b/pcsx2/RDebug/deci2_dcmp.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __DECI2DCMP_H__ diff --git a/pcsx2/RDebug/deci2_drfp.c b/pcsx2/RDebug/deci2_drfp.c index 64b2670..7a6e0c3 100644 --- a/pcsx2/RDebug/deci2_drfp.c +++ b/pcsx2/RDebug/deci2_drfp.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include "Common.h" #include "deci2.h" diff --git a/pcsx2/RDebug/deci2_drfp.h b/pcsx2/RDebug/deci2_drfp.h index eb90970..78c78eb 100644 --- a/pcsx2/RDebug/deci2_drfp.h +++ b/pcsx2/RDebug/deci2_drfp.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __DECI2DRFP_H__ diff --git a/pcsx2/RDebug/deci2_iloadp.c b/pcsx2/RDebug/deci2_iloadp.c index d761e8b..708d6b9 100644 --- a/pcsx2/RDebug/deci2_iloadp.c +++ b/pcsx2/RDebug/deci2_iloadp.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include "Common.h" #include "PsxCommon.h" diff --git a/pcsx2/RDebug/deci2_iloadp.h b/pcsx2/RDebug/deci2_iloadp.h index a55b046..4c16f42 100644 --- a/pcsx2/RDebug/deci2_iloadp.h +++ b/pcsx2/RDebug/deci2_iloadp.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __DECI2ILOADP_H__ diff --git a/pcsx2/RDebug/deci2_netmp.c b/pcsx2/RDebug/deci2_netmp.c index 472dfc5..ce540fa 100644 --- a/pcsx2/RDebug/deci2_netmp.c +++ b/pcsx2/RDebug/deci2_netmp.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include "Common.h" #include "deci2.h" diff --git a/pcsx2/RDebug/deci2_netmp.h b/pcsx2/RDebug/deci2_netmp.h index 760224d..31fec77 100644 --- a/pcsx2/RDebug/deci2_netmp.h +++ b/pcsx2/RDebug/deci2_netmp.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __DECI2NETMP_H__ diff --git a/pcsx2/RDebug/deci2_ttyp.c b/pcsx2/RDebug/deci2_ttyp.c index ce66e2f..94be7a5 100644 --- a/pcsx2/RDebug/deci2_ttyp.c +++ b/pcsx2/RDebug/deci2_ttyp.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include "Common.h" #include "deci2.h" diff --git a/pcsx2/RDebug/deci2_ttyp.h b/pcsx2/RDebug/deci2_ttyp.h index 8d27146..4edf573 100644 --- a/pcsx2/RDebug/deci2_ttyp.h +++ b/pcsx2/RDebug/deci2_ttyp.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __DECI2TTYP_H__ diff --git a/pcsx2/SPR.c b/pcsx2/SPR.c index 7c90374..4f7d271 100644 --- a/pcsx2/SPR.c +++ b/pcsx2/SPR.c @@ -1,416 +1,416 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include "Common.h" -#include "SPR.h" -#include "iR5900.h" - -#define spr0 ((DMACh*)&PS2MEM_HW[0xD000]) -#define spr1 ((DMACh*)&PS2MEM_HW[0xD400]) - -void sprInit() { -} - -//__inline static void SPR0transfer(u32 *data, int size) { -///* while (size > 0) { -//#ifdef SPR_LOG -// SPR_LOG("SPR1transfer: %x\n", *data); -//#endif -// data++; size--; -// }*/ -// size <<= 2; -// if ((psHu32(DMAC_CTRL) & 0xC) == 0xC || // GIF MFIFO -// (psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO -// hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], size); -// } else { -// u32 * p = (u32*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; -// //WriteCodeSSE2(p,data,size >> 4); -// memcpy_fast((u8*)data, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], size); -// } -// spr0->sadr+= size; -//} - -static void TestClearVUs(u32 madr, u32 size) -{ - if( madr >= 0x11000000 ) { - if( madr < 0x11004000 ) { -#ifdef _DEBUG - SysPrintf("scratch pad clearing vu0\n"); -#endif - Cpu->ClearVU0(madr&0xfff, size); - } - else if( madr >= 0x11008000 && madr < 0x1100c000 ) { -#ifdef _DEBUG - SysPrintf("scratch pad clearing vu1\n"); -#endif - Cpu->ClearVU1(madr&0x3fff, size); - } - } -} - -int _SPR0chain() { - u32 *pMem; - - if (spr0->qwc == 0) return 0; - pMem = (u32*)dmaGetAddr(spr0->madr); - if (pMem == NULL) return -1; - - //SPR0transfer(pMem, qwc << 2); - - if ((psHu32(DMAC_CTRL) & 0xC) >= 0x8) { // 0x8 VIF1 MFIFO, 0xC GIF MFIFO - if((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) SysPrintf("SPR MFIFO Write outside MFIFO area\n"); - hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); - spr0->madr += spr0->qwc << 4; - spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR)); - } else { - memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); - Cpu->Clear(spr0->madr, spr0->qwc<<2); - // clear VU mem also! - TestClearVUs(spr0->madr, spr0->qwc << 2); - - spr0->madr += spr0->qwc << 4; - } - spr0->sadr += spr0->qwc << 4; - - - return (spr0->qwc) * BIAS; // bus is 1/2 the ee speed -} - -#define SPR0chain() \ - cycles += _SPR0chain(); \ - spr0->qwc = 0; - - -void _SPR0interleave() { - int qwc = spr0->qwc; - int sqwc = psHu32(DMAC_SQWC) & 0xff; - int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff; - int cycles = 0; - u32 *pMem; - if(tqwc == 0) tqwc = qwc; - //SysPrintf("dmaSPR0 interleave\n"); -#ifdef SPR_LOG - SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx\n", - spr0->qwc, tqwc, sqwc, spr0->madr, spr0->sadr); -#endif - while (qwc > 0) { - spr0->qwc = min(tqwc, qwc); qwc-= spr0->qwc; - pMem = (u32*)dmaGetAddr(spr0->madr); - if ((psHu32(DMAC_CTRL) & 0xC) == 0xC || // GIF MFIFO - (psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO - hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc<<4); - } else { - Cpu->Clear(spr0->madr, spr0->qwc<<2); - // clear VU mem also! - TestClearVUs(spr0->madr, spr0->qwc<<2); - memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc<<4); - } - cycles += tqwc * BIAS; - spr0->sadr+= spr0->qwc * 16; - spr0->madr+= (sqwc+spr0->qwc)*16; //qwc-= sqwc; - } - - spr0->qwc = 0; - INT(8, cycles); -} - -void _dmaSPR0() { - - - if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) { // STS == fromSPR - SysPrintf("SPR0 stall %d\n", (psHu32(DMAC_CTRL)>>6)&3); - } - - - - // Transfer Dn_QWC from SPR to Dn_MADR - - - - if ((spr0->chcr & 0xc) == 0x0) { // Normal Mode - int cycles = 0; - SPR0chain(); - INT(8, cycles); - - return; - } else if ((spr0->chcr & 0xc) == 0x4) { - int cycles = 0; - u32 *ptag; - int id; - int done = 0; - - if(spr0->qwc > 0){ - SPR0chain(); - INT(8, cycles); - - return; - } - // Destination Chain Mode - - while (done == 0) { // Loop while Dn_CHCR.STR is 1 - ptag = (u32*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; - spr0->sadr+= 16; - - // Transfer dma tag if tte is set -// if (spr0->chcr & 0x40) SPR0transfer(ptag, 4); - - spr0->chcr = ( spr0->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - - id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag - spr0->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag - spr0->madr = ptag[1]; //MADR = ADDR field - -#ifdef SPR_LOG - SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx\n", - ptag[1], ptag[0], spr0->qwc, id, spr0->madr); -#endif - if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) { // STS == fromSPR - SysPrintf("SPR stall control\n"); - } - - switch (id) { - case 0: // CNTS - Transfer QWC following the tag (Stall Control) - if ((psHu32(DMAC_CTRL) & 0x30) == 0x20 ) psHu32(DMAC_STADR) = spr0->madr + (spr0->qwc * 16); //Copy MADR to DMAC_STADR stall addr register - break; - - case 1: // CNT - Transfer QWC following the tag. - break; - - case 7: // End - Transfer QWC following the tag - done = 1; //End Transfer - break; - } - SPR0chain(); - if (spr0->chcr & 0x80 && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag - //SysPrintf("SPR0 TIE\n"); - done = 1; - spr0->qwc = 0; - break; - } - - -/* if (spr0->chcr & 0x80 && ptag[0] >> 31) { -#ifdef SPR_LOG - SPR_LOG("dmaIrq Set\n"); -#endif - spr0->chcr&= ~0x100; - hwDmacIrq(8); - return; - }*/ - } - INT(8, cycles); - } else { // Interleave Mode - _SPR0interleave(); - } - - - -} - -void SPRFROMinterrupt() -{ - spr0->chcr&= ~0x100; - hwDmacIrq(8); - cpuRegs.interrupt &= ~(1 << 8); -} - -extern void mfifoGIFtransfer(int); -#define gif ((DMACh*)&PS2MEM_HW[0xA000]) -void dmaSPR0() { // fromSPR - int qwc = spr0->qwc; - FreezeMMXRegs(1); -#ifdef SPR_LOG - SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx\n", - spr0->chcr, spr0->madr, spr0->qwc, spr0->sadr); -#endif - - _dmaSPR0(); - FreezeMMXRegs(0); - if ((psHu32(DMAC_CTRL) & 0xC) == 0xC) { // GIF MFIFO - if((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) SysPrintf("GIF MFIFO Write outside MFIFO area\n"); - spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR)); - //SysPrintf("mfifoGIFtransfer %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr); - mfifoGIFtransfer(qwc); - } else - if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO - if((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) SysPrintf("VIF MFIFO Write outside MFIFO area\n"); - spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR)); - //SysPrintf("mfifoVIF1transfer %x madr %x, tadr %x\n", vif1ch->chcr, vif1ch->madr, vif1ch->tadr); - //vifqwc+= qwc; - mfifoVIF1transfer(qwc); - } - -} - -__inline static void SPR1transfer(u32 *data, int size) { -/* { - int i; - for (i=0; isadr+i*4) & 0x3fff, data[i] ); -#endif - } - }*/ - //Cpu->Clear(spr1->sadr, size); // why? - memcpy_fast(&PS2MEM_SCRATCH[spr1->sadr & 0x3fff], (u8*)data, size << 2); - - spr1->sadr+= size << 2; -} - -int _SPR1chain() { - u32 *pMem; - - if (spr1->qwc == 0) return 0; - - pMem = (u32*)dmaGetAddr(spr1->madr); - if (pMem == NULL) return -1; - - SPR1transfer(pMem, spr1->qwc << 2); - spr1->madr+= spr1->qwc << 4; - - return (spr1->qwc) * BIAS; -} - -#define SPR1chain() \ - cycles += _SPR1chain(); \ - spr1->qwc = 0; - - -void _SPR1interleave() { - int qwc = spr1->qwc; - int sqwc = psHu32(DMAC_SQWC) & 0xff; - int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff; - int cycles = 0; - u32 *pMem; - if(tqwc == 0) tqwc = qwc; - -#ifdef SPR_LOG - SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx\n", - spr1->qwc, tqwc, sqwc, spr1->madr, spr1->sadr); -#endif - while (qwc > 0) { - spr1->qwc = min(tqwc, qwc); qwc-= spr1->qwc; - pMem = (u32*)dmaGetAddr(spr1->madr); - memcpy_fast(&PS2MEM_SCRATCH[spr1->sadr & 0x3fff], (u8*)pMem, spr1->qwc <<4); - spr1->sadr += spr1->qwc * 16; - cycles += spr1->qwc * BIAS; - spr1->madr+= (sqwc + spr1->qwc) * 16; //qwc-= sqwc; - } - - spr1->qwc = 0; - INT(9, cycles); - -} - -void dmaSPR1() { // toSPR - - - FreezeMMXRegs(1); -#ifdef SPR_LOG - SPR_LOG("dmaSPR1 chcr = 0x%x, madr = 0x%x, qwc = 0x%x\n" - " tadr = 0x%x, sadr = 0x%x\n", - spr1->chcr, spr1->madr, spr1->qwc, - spr1->tadr, spr1->sadr); -#endif - - - - - if ((spr1->chcr & 0xc) == 0) { // Normal Mode - int cycles = 0; - //if(spr1->qwc == 0 && (spr1->chcr & 0xc) == 1) spr1->qwc = 0xffff; - // Transfer Dn_QWC from Dn_MADR to SPR1 - SPR1chain(); + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include "Common.h" +#include "SPR.h" +#include "iR5900.h" + +#define spr0 ((DMACh*)&PS2MEM_HW[0xD000]) +#define spr1 ((DMACh*)&PS2MEM_HW[0xD400]) + +void sprInit() { +} + +//__inline static void SPR0transfer(u32 *data, int size) { +///* while (size > 0) { +//#ifdef SPR_LOG +// SPR_LOG("SPR1transfer: %x\n", *data); +//#endif +// data++; size--; +// }*/ +// size <<= 2; +// if ((psHu32(DMAC_CTRL) & 0xC) == 0xC || // GIF MFIFO +// (psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO +// hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], size); +// } else { +// u32 * p = (u32*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; +// //WriteCodeSSE2(p,data,size >> 4); +// memcpy_fast((u8*)data, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], size); +// } +// spr0->sadr+= size; +//} + +static void TestClearVUs(u32 madr, u32 size) +{ + if( madr >= 0x11000000 ) { + if( madr < 0x11004000 ) { +#ifdef _DEBUG + SysPrintf("scratch pad clearing vu0\n"); +#endif + Cpu->ClearVU0(madr&0xfff, size); + } + else if( madr >= 0x11008000 && madr < 0x1100c000 ) { +#ifdef _DEBUG + SysPrintf("scratch pad clearing vu1\n"); +#endif + Cpu->ClearVU1(madr&0x3fff, size); + } + } +} + +int _SPR0chain() { + u32 *pMem; + + if (spr0->qwc == 0) return 0; + pMem = (u32*)dmaGetAddr(spr0->madr); + if (pMem == NULL) return -1; + + //SPR0transfer(pMem, qwc << 2); + + if ((psHu32(DMAC_CTRL) & 0xC) >= 0x8) { // 0x8 VIF1 MFIFO, 0xC GIF MFIFO + if((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) SysPrintf("SPR MFIFO Write outside MFIFO area\n"); + hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); + spr0->madr += spr0->qwc << 4; + spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR)); + } else { + memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); + Cpu->Clear(spr0->madr, spr0->qwc<<2); + // clear VU mem also! + TestClearVUs(spr0->madr, spr0->qwc << 2); + + spr0->madr += spr0->qwc << 4; + } + spr0->sadr += spr0->qwc << 4; + + + return (spr0->qwc) * BIAS; // bus is 1/2 the ee speed +} + +#define SPR0chain() \ + cycles += _SPR0chain(); \ + spr0->qwc = 0; + + +void _SPR0interleave() { + int qwc = spr0->qwc; + int sqwc = psHu32(DMAC_SQWC) & 0xff; + int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff; + int cycles = 0; + u32 *pMem; + if(tqwc == 0) tqwc = qwc; + //SysPrintf("dmaSPR0 interleave\n"); +#ifdef SPR_LOG + SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx\n", + spr0->qwc, tqwc, sqwc, spr0->madr, spr0->sadr); +#endif + while (qwc > 0) { + spr0->qwc = min(tqwc, qwc); qwc-= spr0->qwc; + pMem = (u32*)dmaGetAddr(spr0->madr); + if ((psHu32(DMAC_CTRL) & 0xC) == 0xC || // GIF MFIFO + (psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO + hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc<<4); + } else { + Cpu->Clear(spr0->madr, spr0->qwc<<2); + // clear VU mem also! + TestClearVUs(spr0->madr, spr0->qwc<<2); + memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc<<4); + } + cycles += tqwc * BIAS; + spr0->sadr+= spr0->qwc * 16; + spr0->madr+= (sqwc+spr0->qwc)*16; //qwc-= sqwc; + } + + spr0->qwc = 0; + INT(8, cycles); +} + +void _dmaSPR0() { + + + if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) { // STS == fromSPR + SysPrintf("SPR0 stall %d\n", (psHu32(DMAC_CTRL)>>6)&3); + } + + + + // Transfer Dn_QWC from SPR to Dn_MADR + + + + if ((spr0->chcr & 0xc) == 0x0) { // Normal Mode + int cycles = 0; + SPR0chain(); + INT(8, cycles); + + return; + } else if ((spr0->chcr & 0xc) == 0x4) { + int cycles = 0; + u32 *ptag; + int id; + int done = 0; + + if(spr0->qwc > 0){ + SPR0chain(); + INT(8, cycles); + + return; + } + // Destination Chain Mode + + while (done == 0) { // Loop while Dn_CHCR.STR is 1 + ptag = (u32*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; + spr0->sadr+= 16; + + // Transfer dma tag if tte is set +// if (spr0->chcr & 0x40) SPR0transfer(ptag, 4); + + spr0->chcr = ( spr0->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 + + id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag + spr0->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag + spr0->madr = ptag[1]; //MADR = ADDR field + +#ifdef SPR_LOG + SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx\n", + ptag[1], ptag[0], spr0->qwc, id, spr0->madr); +#endif + if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) { // STS == fromSPR + SysPrintf("SPR stall control\n"); + } + + switch (id) { + case 0: // CNTS - Transfer QWC following the tag (Stall Control) + if ((psHu32(DMAC_CTRL) & 0x30) == 0x20 ) psHu32(DMAC_STADR) = spr0->madr + (spr0->qwc * 16); //Copy MADR to DMAC_STADR stall addr register + break; + + case 1: // CNT - Transfer QWC following the tag. + break; + + case 7: // End - Transfer QWC following the tag + done = 1; //End Transfer + break; + } + SPR0chain(); + if (spr0->chcr & 0x80 && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag + //SysPrintf("SPR0 TIE\n"); + done = 1; + spr0->qwc = 0; + break; + } + + +/* if (spr0->chcr & 0x80 && ptag[0] >> 31) { +#ifdef SPR_LOG + SPR_LOG("dmaIrq Set\n"); +#endif + spr0->chcr&= ~0x100; + hwDmacIrq(8); + return; + }*/ + } + INT(8, cycles); + } else { // Interleave Mode + _SPR0interleave(); + } + + + +} + +void SPRFROMinterrupt() +{ + spr0->chcr&= ~0x100; + hwDmacIrq(8); + cpuRegs.interrupt &= ~(1 << 8); +} + +extern void mfifoGIFtransfer(int); +#define gif ((DMACh*)&PS2MEM_HW[0xA000]) +void dmaSPR0() { // fromSPR + int qwc = spr0->qwc; + FreezeMMXRegs(1); +#ifdef SPR_LOG + SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx\n", + spr0->chcr, spr0->madr, spr0->qwc, spr0->sadr); +#endif + + _dmaSPR0(); + FreezeMMXRegs(0); + if ((psHu32(DMAC_CTRL) & 0xC) == 0xC) { // GIF MFIFO + if((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) SysPrintf("GIF MFIFO Write outside MFIFO area\n"); + spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR)); + //SysPrintf("mfifoGIFtransfer %x madr %x, tadr %x\n", gif->chcr, gif->madr, gif->tadr); + mfifoGIFtransfer(qwc); + } else + if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) { // VIF1 MFIFO + if((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) SysPrintf("VIF MFIFO Write outside MFIFO area\n"); + spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR)); + //SysPrintf("mfifoVIF1transfer %x madr %x, tadr %x\n", vif1ch->chcr, vif1ch->madr, vif1ch->tadr); + //vifqwc+= qwc; + mfifoVIF1transfer(qwc); + } + +} + +__inline static void SPR1transfer(u32 *data, int size) { +/* { + int i; + for (i=0; isadr+i*4) & 0x3fff, data[i] ); +#endif + } + }*/ + //Cpu->Clear(spr1->sadr, size); // why? + memcpy_fast(&PS2MEM_SCRATCH[spr1->sadr & 0x3fff], (u8*)data, size << 2); + + spr1->sadr+= size << 2; +} + +int _SPR1chain() { + u32 *pMem; + + if (spr1->qwc == 0) return 0; + + pMem = (u32*)dmaGetAddr(spr1->madr); + if (pMem == NULL) return -1; + + SPR1transfer(pMem, spr1->qwc << 2); + spr1->madr+= spr1->qwc << 4; + + return (spr1->qwc) * BIAS; +} + +#define SPR1chain() \ + cycles += _SPR1chain(); \ + spr1->qwc = 0; + + +void _SPR1interleave() { + int qwc = spr1->qwc; + int sqwc = psHu32(DMAC_SQWC) & 0xff; + int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff; + int cycles = 0; + u32 *pMem; + if(tqwc == 0) tqwc = qwc; + +#ifdef SPR_LOG + SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx\n", + spr1->qwc, tqwc, sqwc, spr1->madr, spr1->sadr); +#endif + while (qwc > 0) { + spr1->qwc = min(tqwc, qwc); qwc-= spr1->qwc; + pMem = (u32*)dmaGetAddr(spr1->madr); + memcpy_fast(&PS2MEM_SCRATCH[spr1->sadr & 0x3fff], (u8*)pMem, spr1->qwc <<4); + spr1->sadr += spr1->qwc * 16; + cycles += spr1->qwc * BIAS; + spr1->madr+= (sqwc + spr1->qwc) * 16; //qwc-= sqwc; + } + + spr1->qwc = 0; + INT(9, cycles); + +} + +void dmaSPR1() { // toSPR + + + FreezeMMXRegs(1); +#ifdef SPR_LOG + SPR_LOG("dmaSPR1 chcr = 0x%x, madr = 0x%x, qwc = 0x%x\n" + " tadr = 0x%x, sadr = 0x%x\n", + spr1->chcr, spr1->madr, spr1->qwc, + spr1->tadr, spr1->sadr); +#endif + + + + + if ((spr1->chcr & 0xc) == 0) { // Normal Mode + int cycles = 0; + //if(spr1->qwc == 0 && (spr1->chcr & 0xc) == 1) spr1->qwc = 0xffff; + // Transfer Dn_QWC from Dn_MADR to SPR1 + SPR1chain(); INT(9, cycles); - FreezeMMXRegs(0); - return; - } else if ((spr1->chcr & 0xc) == 0x4){ - int cycles = 0; - u32 *ptag; - int id, done=0; - - - if(spr1->qwc > 0){ - //if(spr1->qwc == 0 && (spr1->chcr & 0xc) == 1) spr1->qwc = 0xffff; - // Transfer Dn_QWC from Dn_MADR to SPR1 - SPR1chain(); + FreezeMMXRegs(0); + return; + } else if ((spr1->chcr & 0xc) == 0x4){ + int cycles = 0; + u32 *ptag; + int id, done=0; + + + if(spr1->qwc > 0){ + //if(spr1->qwc == 0 && (spr1->chcr & 0xc) == 1) spr1->qwc = 0xffff; + // Transfer Dn_QWC from Dn_MADR to SPR1 + SPR1chain(); INT(9, cycles); - FreezeMMXRegs(0); - return; - } - // Chain Mode - - while (done == 0) { // Loop while Dn_CHCR.STR is 1 - ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR - if (ptag == NULL) { //Is ptag empty? - SysPrintf("SPR1 Tag BUSERR\n"); - spr1->chcr = ( spr1->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register - done = 1; - break; - } - spr1->chcr = ( spr1->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - - id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag - spr1->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag - spr1->madr = ptag[1]; //MADR = ADDR field - - // Transfer dma tag if tte is set - if (spr1->chcr & 0x40) { -#ifdef SPR_LOG - SPR_LOG("SPR TTE: %x_%x\n", ptag[3], ptag[2]); -#endif - SPR1transfer(ptag, 4); //Transfer Tag - - } - - - -#ifdef SPR_LOG - SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx\n", - ptag[1], ptag[0], spr1->qwc, id, spr1->madr); -#endif - - done = hwDmacSrcChain(spr1, id); - SPR1chain(); //Transfers the data set by the switch - - if (spr1->chcr & 0x80 && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag -#ifdef SPR_LOG - SPR_LOG("dmaIrq Set\n"); -#endif - //SysPrintf("SPR1 TIE\n"); - spr1->qwc = 0; - break; - } - } - INT(9, cycles); - } else { // Interleave Mode - _SPR1interleave(); - } - FreezeMMXRegs(0); - -} - -void SPRTOinterrupt() -{ - spr1->chcr &= ~0x100; - hwDmacIrq(9); - cpuRegs.interrupt &= ~(1 << 9); -} - + FreezeMMXRegs(0); + return; + } + // Chain Mode + + while (done == 0) { // Loop while Dn_CHCR.STR is 1 + ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR + if (ptag == NULL) { //Is ptag empty? + SysPrintf("SPR1 Tag BUSERR\n"); + spr1->chcr = ( spr1->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 + psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register + done = 1; + break; + } + spr1->chcr = ( spr1->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 + + id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag + spr1->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag + spr1->madr = ptag[1]; //MADR = ADDR field + + // Transfer dma tag if tte is set + if (spr1->chcr & 0x40) { +#ifdef SPR_LOG + SPR_LOG("SPR TTE: %x_%x\n", ptag[3], ptag[2]); +#endif + SPR1transfer(ptag, 4); //Transfer Tag + + } + + + +#ifdef SPR_LOG + SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx\n", + ptag[1], ptag[0], spr1->qwc, id, spr1->madr); +#endif + + done = hwDmacSrcChain(spr1, id); + SPR1chain(); //Transfers the data set by the switch + + if (spr1->chcr & 0x80 && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag +#ifdef SPR_LOG + SPR_LOG("dmaIrq Set\n"); +#endif + //SysPrintf("SPR1 TIE\n"); + spr1->qwc = 0; + break; + } + } + INT(9, cycles); + } else { // Interleave Mode + _SPR1interleave(); + } + FreezeMMXRegs(0); + +} + +void SPRTOinterrupt() +{ + spr1->chcr &= ~0x100; + hwDmacIrq(9); + cpuRegs.interrupt &= ~(1 << 9); +} + diff --git a/pcsx2/SPR.h b/pcsx2/SPR.h index ef3c4fe..e263231 100644 --- a/pcsx2/SPR.h +++ b/pcsx2/SPR.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __SPR_H__ diff --git a/pcsx2/Sif.c b/pcsx2/Sif.c index fc31613..6aa7b65 100644 --- a/pcsx2/Sif.c +++ b/pcsx2/Sif.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2004 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/Sif.h b/pcsx2/Sif.h index 18dc86b..782a786 100644 --- a/pcsx2/Sif.h +++ b/pcsx2/Sif.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2004 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __SIF_H__ diff --git a/pcsx2/Sifcmd.h b/pcsx2/Sifcmd.h index b953fed..8734ab2 100644 --- a/pcsx2/Sifcmd.h +++ b/pcsx2/Sifcmd.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __SIFCMD_H__ diff --git a/pcsx2/Sio.c b/pcsx2/Sio.c index 61b3924..e589964 100644 --- a/pcsx2/Sio.c +++ b/pcsx2/Sio.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/Sio.h b/pcsx2/Sio.h index e0e8281..ad2ee1f 100644 --- a/pcsx2/Sio.h +++ b/pcsx2/Sio.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ diff --git a/pcsx2/Stats.c b/pcsx2/Stats.c index 27b7da3..d01065e 100644 --- a/pcsx2/Stats.c +++ b/pcsx2/Stats.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/Stats.h b/pcsx2/Stats.h index a914e6b..428859b 100644 --- a/pcsx2/Stats.h +++ b/pcsx2/Stats.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __STATS_H__ diff --git a/pcsx2/System.h b/pcsx2/System.h index ace4b61..42a5018 100644 --- a/pcsx2/System.h +++ b/pcsx2/System.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __SYSTEM_H__ diff --git a/pcsx2/VU.h b/pcsx2/VU.h index 825a421..5629963 100644 --- a/pcsx2/VU.h +++ b/pcsx2/VU.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __VU_H__ diff --git a/pcsx2/VU0.c b/pcsx2/VU0.c index ad82bfc..75ef0a6 100644 --- a/pcsx2/VU0.c +++ b/pcsx2/VU0.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* TODO -Fix the flags Proper as they aren't handle now.. diff --git a/pcsx2/VU0.h b/pcsx2/VU0.h index b7c0b38..b9e3115 100644 --- a/pcsx2/VU0.h +++ b/pcsx2/VU0.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __VU0_H__ diff --git a/pcsx2/VU0micro.c b/pcsx2/VU0micro.c index 459597c..8f65eba 100644 --- a/pcsx2/VU0micro.c +++ b/pcsx2/VU0micro.c @@ -1,21 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/VU1micro.c b/pcsx2/VU1micro.c index 935b606..d522a87 100644 --- a/pcsx2/VU1micro.c +++ b/pcsx2/VU1micro.c @@ -1,21 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/VUflags.c b/pcsx2/VUflags.c index 5050f46..8cd51f8 100644 --- a/pcsx2/VUflags.c +++ b/pcsx2/VUflags.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/VUflags.h b/pcsx2/VUflags.h index 37338a5..2b4ff3d 100644 --- a/pcsx2/VUflags.h +++ b/pcsx2/VUflags.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __VUFLAGS_H__ diff --git a/pcsx2/VUmicro.h b/pcsx2/VUmicro.h index 1f56703..0920a61 100644 --- a/pcsx2/VUmicro.h +++ b/pcsx2/VUmicro.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __VUMICRO_H__ diff --git a/pcsx2/VUops.c b/pcsx2/VUops.c index 431c6c7..dfd126e 100644 --- a/pcsx2/VUops.c +++ b/pcsx2/VUops.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #define PLUGINtypedefs // for GSgifTransfer1 diff --git a/pcsx2/VUops.h b/pcsx2/VUops.h index 0b4a0f9..e8650a1 100644 --- a/pcsx2/VUops.h +++ b/pcsx2/VUops.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __VU1OPS_H__ diff --git a/pcsx2/Vif.c b/pcsx2/Vif.c index a471495..2a4acbe 100644 --- a/pcsx2/Vif.c +++ b/pcsx2/Vif.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include @@ -609,17 +609,17 @@ void mfifoVIF1transfer(int qwc) { void vifMFIFOInterrupt() { - if(vif1.irq && vif1.tag.size == 0) { - vif1Regs->stat|= VIF1_STAT_INT; - hwIntcIrq(5); - --vif1.irq; - if(vif1Regs->stat & (VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS)) - { - vif1Regs->stat&= ~0x1F000000; // FQC=0 - vif1ch->chcr &= ~0x100; - cpuRegs.interrupt &= ~(1 << 10); - return; - } + if(vif1.irq && vif1.tag.size == 0) { + vif1Regs->stat|= VIF1_STAT_INT; + hwIntcIrq(5); + --vif1.irq; + if(vif1Regs->stat & (VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS)) + { + vif1Regs->stat&= ~0x1F000000; // FQC=0 + vif1ch->chcr &= ~0x100; + cpuRegs.interrupt &= ~(1 << 10); + return; + } } if(vif1.done != 1) { diff --git a/pcsx2/Vif.h b/pcsx2/Vif.h index 5e36ec7..8dedc0c 100644 --- a/pcsx2/Vif.h +++ b/pcsx2/Vif.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __VIF_H__ diff --git a/pcsx2/VifDma.c b/pcsx2/VifDma.c index 086f0b8..1642ab2 100644 --- a/pcsx2/VifDma.c +++ b/pcsx2/VifDma.c @@ -1,2594 +1,2594 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include "Common.h" -#include "Vif.h" -#include "VUmicro.h" -#include "GS.h" - -#include "VifDma.h" - -#include - -#define gif ((DMACh*)&PS2MEM_HW[0xA000]) - -// Extern variables -extern VIFregisters *_vifRegs; -extern vifStruct *_vif; -extern u32* _vifMaskRegs; -extern PCSX2_ALIGNED16_DECL(u32 g_vifRow0[4]); -extern PCSX2_ALIGNED16_DECL(u32 g_vifCol0[4]); -extern PCSX2_ALIGNED16_DECL(u32 g_vifRow1[4]); -extern PCSX2_ALIGNED16_DECL(u32 g_vifCol1[4]); -extern u32* _vifRow, *_vifCol; - -vifStruct vif0, vif1; - -PCSX2_ALIGNED16(u32 g_vif1Masks[64]); -PCSX2_ALIGNED16(u32 g_vif0Masks[64]); -u32 g_vif1HasMask3[4] = {0}, g_vif0HasMask3[4] = {0}; - -// Generic constants -static const unsigned int VIF0intc = 4; -static const unsigned int VIF1intc = 5; -static const unsigned int VIF0dmanum = 0; -static const unsigned int VIF1dmanum = 1; - -#if defined(_WIN32) && !defined(WIN32_PTHREADS) -extern HANDLE g_hGsEvent; -#else -extern pthread_cond_t g_condGsEvent; -#endif - -int g_vifCycles = 0; -int path3hack = 0; - -#ifndef __x86_64__ -extern void * memcpy_fast(void *dest, const void *src, size_t n); -#endif - -typedef void (*UNPACKFUNCTYPE)( u32 *dest, u32 *data, int size ); -typedef int (*UNPACKPARTFUNCTYPESSE)( u32 *dest, u32 *data, int size ); -void (*Vif1CMDTLB[82])(); -void (*Vif0CMDTLB[75])(); -int (*Vif1TransTLB[128])(u32 *data); -int (*Vif0TransTLB[128])(u32 *data); - -typedef struct { - UNPACKFUNCTYPE funcU; - UNPACKFUNCTYPE funcS; - - int bsize; // currently unused - int dsize; // byte size of one channel - int gsize; // size of data in bytes used for each write cycle - int qsize; // used for unpack parts, num of vectors that - // will be decompressed from data for 1 cycle -} VIFUnpackFuncTable; - -/* block size; data size; group size; qword size; */ -#define _UNPACK_TABLE32(name, bsize, dsize, gsize, qsize) \ - { UNPACK_##name, UNPACK_##name, \ - bsize, dsize, gsize, qsize }, - -#define _UNPACK_TABLE(name, bsize, dsize, gsize, qsize) \ - { UNPACK_##name##u, UNPACK_##name##s, \ - bsize, dsize, gsize, qsize }, - -// Main table for function unpacking -static const VIFUnpackFuncTable VIFfuncTable[16] = { - _UNPACK_TABLE32(S_32, 1, 4, 4, 4) // 0x0 - S-32 - _UNPACK_TABLE(S_16, 2, 2, 2, 4) // 0x1 - S-16 - _UNPACK_TABLE(S_8, 4, 1, 1, 4) // 0x2 - S-8 - { NULL, NULL, 0, 0, 0, 0 }, // 0x3 - - _UNPACK_TABLE32(V2_32, 24, 4, 8, 2) // 0x4 - V2-32 - _UNPACK_TABLE(V2_16, 12, 2, 4, 2) // 0x5 - V2-16 - _UNPACK_TABLE(V2_8, 6, 1, 2, 2) // 0x6 - V2-8 - { NULL, NULL, 0, 0, 0, 0 }, // 0x7 - - _UNPACK_TABLE32(V3_32, 36, 4, 12, 3) // 0x8 - V3-32 - _UNPACK_TABLE(V3_16, 18, 2, 6, 3) // 0x9 - V3-16 - _UNPACK_TABLE(V3_8, 9, 1, 3, 3) // 0xA - V3-8 - { NULL, NULL, 0, 0, 0, 0 }, // 0xB - - _UNPACK_TABLE32(V4_32, 48, 4, 16, 4) // 0xC - V4-32 - _UNPACK_TABLE(V4_16, 24, 2, 8, 4) // 0xD - V4-16 - _UNPACK_TABLE(V4_8, 12, 1, 4, 4) // 0xE - V4-8 - _UNPACK_TABLE32(V4_5, 6, 2, 2, 4) // 0xF - V4-5 -}; - - -#if !defined(PCSX2_NORECBUILD) - -typedef struct { - // regular 0, 1, 2; mask 0, 1, 2 - UNPACKPARTFUNCTYPESSE funcU[9], funcS[9]; -} VIFSSEUnpackTable; - -#define DECL_UNPACK_TABLE_SSE(name, sign) \ -extern int UNPACK_SkippingWrite_##name##_##sign##_Regular_0(u32* dest, u32* data, int dmasize); \ -extern int UNPACK_SkippingWrite_##name##_##sign##_Regular_1(u32* dest, u32* data, int dmasize); \ -extern int UNPACK_SkippingWrite_##name##_##sign##_Regular_2(u32* dest, u32* data, int dmasize); \ -extern int UNPACK_SkippingWrite_##name##_##sign##_Mask_0(u32* dest, u32* data, int dmasize); \ -extern int UNPACK_SkippingWrite_##name##_##sign##_Mask_1(u32* dest, u32* data, int dmasize); \ -extern int UNPACK_SkippingWrite_##name##_##sign##_Mask_2(u32* dest, u32* data, int dmasize); \ -extern int UNPACK_SkippingWrite_##name##_##sign##_WriteMask_0(u32* dest, u32* data, int dmasize); \ -extern int UNPACK_SkippingWrite_##name##_##sign##_WriteMask_1(u32* dest, u32* data, int dmasize); \ -extern int UNPACK_SkippingWrite_##name##_##sign##_WriteMask_2(u32* dest, u32* data, int dmasize); \ - -#define _UNPACK_TABLE_SSE(name, sign) \ - UNPACK_SkippingWrite_##name##_##sign##_Regular_0, \ - UNPACK_SkippingWrite_##name##_##sign##_Regular_1, \ - UNPACK_SkippingWrite_##name##_##sign##_Regular_2, \ - UNPACK_SkippingWrite_##name##_##sign##_Mask_0, \ - UNPACK_SkippingWrite_##name##_##sign##_Mask_1, \ - UNPACK_SkippingWrite_##name##_##sign##_Mask_2, \ - UNPACK_SkippingWrite_##name##_##sign##_WriteMask_0, \ - UNPACK_SkippingWrite_##name##_##sign##_WriteMask_1, \ - UNPACK_SkippingWrite_##name##_##sign##_WriteMask_2 \ - -#define _UNPACK_TABLE_SSE_NULL \ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL - -// Main table for function unpacking -DECL_UNPACK_TABLE_SSE(S_32, u); -DECL_UNPACK_TABLE_SSE(S_16, u); -DECL_UNPACK_TABLE_SSE(S_8, u); -DECL_UNPACK_TABLE_SSE(S_16, s); -DECL_UNPACK_TABLE_SSE(S_8, s); - -DECL_UNPACK_TABLE_SSE(V2_32, u); -DECL_UNPACK_TABLE_SSE(V2_16, u); -DECL_UNPACK_TABLE_SSE(V2_8, u); -DECL_UNPACK_TABLE_SSE(V2_16, s); -DECL_UNPACK_TABLE_SSE(V2_8, s); - -DECL_UNPACK_TABLE_SSE(V3_32, u); -DECL_UNPACK_TABLE_SSE(V3_16, u); -DECL_UNPACK_TABLE_SSE(V3_8, u); -DECL_UNPACK_TABLE_SSE(V3_16, s); -DECL_UNPACK_TABLE_SSE(V3_8, s); - -DECL_UNPACK_TABLE_SSE(V4_32, u); -DECL_UNPACK_TABLE_SSE(V4_16, u); -DECL_UNPACK_TABLE_SSE(V4_8, u); -DECL_UNPACK_TABLE_SSE(V4_16, s); -DECL_UNPACK_TABLE_SSE(V4_8, s); -DECL_UNPACK_TABLE_SSE(V4_5, u); - -static const VIFSSEUnpackTable VIFfuncTableSSE[16] = { - { _UNPACK_TABLE_SSE(S_32, u), _UNPACK_TABLE_SSE(S_32, u) }, - { _UNPACK_TABLE_SSE(S_16, u), _UNPACK_TABLE_SSE(S_16, s) }, - { _UNPACK_TABLE_SSE(S_8, u), _UNPACK_TABLE_SSE(S_8, s) }, - { _UNPACK_TABLE_SSE_NULL, _UNPACK_TABLE_SSE_NULL }, - - { _UNPACK_TABLE_SSE(V2_32, u), _UNPACK_TABLE_SSE(V2_32, u) }, - { _UNPACK_TABLE_SSE(V2_16, u), _UNPACK_TABLE_SSE(V2_16, s) }, - { _UNPACK_TABLE_SSE(V2_8, u), _UNPACK_TABLE_SSE(V2_8, s) }, - { _UNPACK_TABLE_SSE_NULL, _UNPACK_TABLE_SSE_NULL }, - - { _UNPACK_TABLE_SSE(V3_32, u), _UNPACK_TABLE_SSE(V3_32, u) }, - { _UNPACK_TABLE_SSE(V3_16, u), _UNPACK_TABLE_SSE(V3_16, s) }, - { _UNPACK_TABLE_SSE(V3_8, u), _UNPACK_TABLE_SSE(V3_8, s) }, - { _UNPACK_TABLE_SSE_NULL, _UNPACK_TABLE_SSE_NULL }, - - { _UNPACK_TABLE_SSE(V4_32, u), _UNPACK_TABLE_SSE(V4_32, u) }, - { _UNPACK_TABLE_SSE(V4_16, u), _UNPACK_TABLE_SSE(V4_16, s) }, - { _UNPACK_TABLE_SSE(V4_8, u), _UNPACK_TABLE_SSE(V4_8, s) }, - { _UNPACK_TABLE_SSE(V4_5, u), _UNPACK_TABLE_SSE(V4_5, u) }, -}; - -#endif - - -__forceinline void vif0FLUSH() { - int _cycles; - _cycles = VU0.cycle; - - //FreezeXMMRegs(1); - vu0Finish(); - //FreezeXMMRegs(0); - g_vifCycles+= (VU0.cycle - _cycles)*BIAS; -} - -__forceinline void vif1FLUSH() { - int _cycles; - _cycles = VU1.cycle; - - if( VU0.VI[REG_VPU_STAT].UL & 0x100 ) { - //FreezeXMMRegs(1); - do { - Cpu->ExecuteVU1Block(); - } while(VU0.VI[REG_VPU_STAT].UL & 0x100); - -// FreezeXMMRegs(0); + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "Common.h" +#include "Vif.h" +#include "VUmicro.h" +#include "GS.h" + +#include "VifDma.h" + +#include + +#define gif ((DMACh*)&PS2MEM_HW[0xA000]) + +// Extern variables +extern VIFregisters *_vifRegs; +extern vifStruct *_vif; +extern u32* _vifMaskRegs; +extern PCSX2_ALIGNED16_DECL(u32 g_vifRow0[4]); +extern PCSX2_ALIGNED16_DECL(u32 g_vifCol0[4]); +extern PCSX2_ALIGNED16_DECL(u32 g_vifRow1[4]); +extern PCSX2_ALIGNED16_DECL(u32 g_vifCol1[4]); +extern u32* _vifRow, *_vifCol; + +vifStruct vif0, vif1; + +PCSX2_ALIGNED16(u32 g_vif1Masks[64]); +PCSX2_ALIGNED16(u32 g_vif0Masks[64]); +u32 g_vif1HasMask3[4] = {0}, g_vif0HasMask3[4] = {0}; + +// Generic constants +static const unsigned int VIF0intc = 4; +static const unsigned int VIF1intc = 5; +static const unsigned int VIF0dmanum = 0; +static const unsigned int VIF1dmanum = 1; + +#if defined(_WIN32) && !defined(WIN32_PTHREADS) +extern HANDLE g_hGsEvent; +#else +extern pthread_cond_t g_condGsEvent; +#endif + +int g_vifCycles = 0; +int path3hack = 0; + +#ifndef __x86_64__ +extern void * memcpy_fast(void *dest, const void *src, size_t n); +#endif + +typedef void (*UNPACKFUNCTYPE)( u32 *dest, u32 *data, int size ); +typedef int (*UNPACKPARTFUNCTYPESSE)( u32 *dest, u32 *data, int size ); +void (*Vif1CMDTLB[82])(); +void (*Vif0CMDTLB[75])(); +int (*Vif1TransTLB[128])(u32 *data); +int (*Vif0TransTLB[128])(u32 *data); + +typedef struct { + UNPACKFUNCTYPE funcU; + UNPACKFUNCTYPE funcS; + + int bsize; // currently unused + int dsize; // byte size of one channel + int gsize; // size of data in bytes used for each write cycle + int qsize; // used for unpack parts, num of vectors that + // will be decompressed from data for 1 cycle +} VIFUnpackFuncTable; + +/* block size; data size; group size; qword size; */ +#define _UNPACK_TABLE32(name, bsize, dsize, gsize, qsize) \ + { UNPACK_##name, UNPACK_##name, \ + bsize, dsize, gsize, qsize }, + +#define _UNPACK_TABLE(name, bsize, dsize, gsize, qsize) \ + { UNPACK_##name##u, UNPACK_##name##s, \ + bsize, dsize, gsize, qsize }, + +// Main table for function unpacking +static const VIFUnpackFuncTable VIFfuncTable[16] = { + _UNPACK_TABLE32(S_32, 1, 4, 4, 4) // 0x0 - S-32 + _UNPACK_TABLE(S_16, 2, 2, 2, 4) // 0x1 - S-16 + _UNPACK_TABLE(S_8, 4, 1, 1, 4) // 0x2 - S-8 + { NULL, NULL, 0, 0, 0, 0 }, // 0x3 + + _UNPACK_TABLE32(V2_32, 24, 4, 8, 2) // 0x4 - V2-32 + _UNPACK_TABLE(V2_16, 12, 2, 4, 2) // 0x5 - V2-16 + _UNPACK_TABLE(V2_8, 6, 1, 2, 2) // 0x6 - V2-8 + { NULL, NULL, 0, 0, 0, 0 }, // 0x7 + + _UNPACK_TABLE32(V3_32, 36, 4, 12, 3) // 0x8 - V3-32 + _UNPACK_TABLE(V3_16, 18, 2, 6, 3) // 0x9 - V3-16 + _UNPACK_TABLE(V3_8, 9, 1, 3, 3) // 0xA - V3-8 + { NULL, NULL, 0, 0, 0, 0 }, // 0xB + + _UNPACK_TABLE32(V4_32, 48, 4, 16, 4) // 0xC - V4-32 + _UNPACK_TABLE(V4_16, 24, 2, 8, 4) // 0xD - V4-16 + _UNPACK_TABLE(V4_8, 12, 1, 4, 4) // 0xE - V4-8 + _UNPACK_TABLE32(V4_5, 6, 2, 2, 4) // 0xF - V4-5 +}; + + +#if !defined(PCSX2_NORECBUILD) + +typedef struct { + // regular 0, 1, 2; mask 0, 1, 2 + UNPACKPARTFUNCTYPESSE funcU[9], funcS[9]; +} VIFSSEUnpackTable; + +#define DECL_UNPACK_TABLE_SSE(name, sign) \ +extern int UNPACK_SkippingWrite_##name##_##sign##_Regular_0(u32* dest, u32* data, int dmasize); \ +extern int UNPACK_SkippingWrite_##name##_##sign##_Regular_1(u32* dest, u32* data, int dmasize); \ +extern int UNPACK_SkippingWrite_##name##_##sign##_Regular_2(u32* dest, u32* data, int dmasize); \ +extern int UNPACK_SkippingWrite_##name##_##sign##_Mask_0(u32* dest, u32* data, int dmasize); \ +extern int UNPACK_SkippingWrite_##name##_##sign##_Mask_1(u32* dest, u32* data, int dmasize); \ +extern int UNPACK_SkippingWrite_##name##_##sign##_Mask_2(u32* dest, u32* data, int dmasize); \ +extern int UNPACK_SkippingWrite_##name##_##sign##_WriteMask_0(u32* dest, u32* data, int dmasize); \ +extern int UNPACK_SkippingWrite_##name##_##sign##_WriteMask_1(u32* dest, u32* data, int dmasize); \ +extern int UNPACK_SkippingWrite_##name##_##sign##_WriteMask_2(u32* dest, u32* data, int dmasize); \ + +#define _UNPACK_TABLE_SSE(name, sign) \ + UNPACK_SkippingWrite_##name##_##sign##_Regular_0, \ + UNPACK_SkippingWrite_##name##_##sign##_Regular_1, \ + UNPACK_SkippingWrite_##name##_##sign##_Regular_2, \ + UNPACK_SkippingWrite_##name##_##sign##_Mask_0, \ + UNPACK_SkippingWrite_##name##_##sign##_Mask_1, \ + UNPACK_SkippingWrite_##name##_##sign##_Mask_2, \ + UNPACK_SkippingWrite_##name##_##sign##_WriteMask_0, \ + UNPACK_SkippingWrite_##name##_##sign##_WriteMask_1, \ + UNPACK_SkippingWrite_##name##_##sign##_WriteMask_2 \ + +#define _UNPACK_TABLE_SSE_NULL \ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + +// Main table for function unpacking +DECL_UNPACK_TABLE_SSE(S_32, u); +DECL_UNPACK_TABLE_SSE(S_16, u); +DECL_UNPACK_TABLE_SSE(S_8, u); +DECL_UNPACK_TABLE_SSE(S_16, s); +DECL_UNPACK_TABLE_SSE(S_8, s); + +DECL_UNPACK_TABLE_SSE(V2_32, u); +DECL_UNPACK_TABLE_SSE(V2_16, u); +DECL_UNPACK_TABLE_SSE(V2_8, u); +DECL_UNPACK_TABLE_SSE(V2_16, s); +DECL_UNPACK_TABLE_SSE(V2_8, s); + +DECL_UNPACK_TABLE_SSE(V3_32, u); +DECL_UNPACK_TABLE_SSE(V3_16, u); +DECL_UNPACK_TABLE_SSE(V3_8, u); +DECL_UNPACK_TABLE_SSE(V3_16, s); +DECL_UNPACK_TABLE_SSE(V3_8, s); + +DECL_UNPACK_TABLE_SSE(V4_32, u); +DECL_UNPACK_TABLE_SSE(V4_16, u); +DECL_UNPACK_TABLE_SSE(V4_8, u); +DECL_UNPACK_TABLE_SSE(V4_16, s); +DECL_UNPACK_TABLE_SSE(V4_8, s); +DECL_UNPACK_TABLE_SSE(V4_5, u); + +static const VIFSSEUnpackTable VIFfuncTableSSE[16] = { + { _UNPACK_TABLE_SSE(S_32, u), _UNPACK_TABLE_SSE(S_32, u) }, + { _UNPACK_TABLE_SSE(S_16, u), _UNPACK_TABLE_SSE(S_16, s) }, + { _UNPACK_TABLE_SSE(S_8, u), _UNPACK_TABLE_SSE(S_8, s) }, + { _UNPACK_TABLE_SSE_NULL, _UNPACK_TABLE_SSE_NULL }, + + { _UNPACK_TABLE_SSE(V2_32, u), _UNPACK_TABLE_SSE(V2_32, u) }, + { _UNPACK_TABLE_SSE(V2_16, u), _UNPACK_TABLE_SSE(V2_16, s) }, + { _UNPACK_TABLE_SSE(V2_8, u), _UNPACK_TABLE_SSE(V2_8, s) }, + { _UNPACK_TABLE_SSE_NULL, _UNPACK_TABLE_SSE_NULL }, + + { _UNPACK_TABLE_SSE(V3_32, u), _UNPACK_TABLE_SSE(V3_32, u) }, + { _UNPACK_TABLE_SSE(V3_16, u), _UNPACK_TABLE_SSE(V3_16, s) }, + { _UNPACK_TABLE_SSE(V3_8, u), _UNPACK_TABLE_SSE(V3_8, s) }, + { _UNPACK_TABLE_SSE_NULL, _UNPACK_TABLE_SSE_NULL }, + + { _UNPACK_TABLE_SSE(V4_32, u), _UNPACK_TABLE_SSE(V4_32, u) }, + { _UNPACK_TABLE_SSE(V4_16, u), _UNPACK_TABLE_SSE(V4_16, s) }, + { _UNPACK_TABLE_SSE(V4_8, u), _UNPACK_TABLE_SSE(V4_8, s) }, + { _UNPACK_TABLE_SSE(V4_5, u), _UNPACK_TABLE_SSE(V4_5, u) }, +}; + +#endif + + +__forceinline void vif0FLUSH() { + int _cycles; + _cycles = VU0.cycle; + + //FreezeXMMRegs(1); + vu0Finish(); + //FreezeXMMRegs(0); + g_vifCycles+= (VU0.cycle - _cycles)*BIAS; +} + +__forceinline void vif1FLUSH() { + int _cycles; + _cycles = VU1.cycle; + + if( VU0.VI[REG_VPU_STAT].UL & 0x100 ) { + //FreezeXMMRegs(1); + do { + Cpu->ExecuteVU1Block(); + } while(VU0.VI[REG_VPU_STAT].UL & 0x100); + +// FreezeXMMRegs(0); // FreezeMMXRegs(0); - //FreezeXMMRegs(0); - g_vifCycles+= (VU1.cycle - _cycles)*BIAS; - } -} - -void vifDmaInit() { -} - -__inline static int _limit( int a, int max ) { - return ( a > max ? max : a ); -} - -void DummyExecuteVU1Block(void) -{ - VU0.VI[ REG_VPU_STAT ].UL &= ~0x100; - VU1.vifRegs->stat &= ~4; // also reset the bit (grandia 3 works) -} - -//#define VIFUNPACKDEBUG //enable unpack debugging output - -static void ProcessMemSkip(int size, unsigned int unpackType, const unsigned int VIFdmanum){ - const VIFUnpackFuncTable *unpack; - vifStruct *vif; - VIFregisters *vifRegs; - unpack = &VIFfuncTable[ unpackType ]; -// varLog |= 0x00000400; - - if (VIFdmanum == 0) - { - vif = &vif0; - vifRegs = vif0Regs; - } - else - { - vif = &vif1; - vifRegs = vif1Regs; - } - - switch(unpackType){ - case 0x0: - vif->tag.addr += size*4; -#ifdef VIFUNPACKDEBUG - SysPrintf("Processing S-32 skip, size = %d\n", size); -#endif - break; - case 0x1: - vif->tag.addr += size*8; -#ifdef VIFUNPACKDEBUG - SysPrintf("Processing S-16 skip, size = %d\n", size); -#endif - break; - case 0x2: - vif->tag.addr += size*16; -#ifdef VIFUNPACKDEBUG - SysPrintf("Processing S-8 skip, size = %d\n", size); -#endif - break; - case 0x4: - vif->tag.addr += size + ((size / unpack->gsize) * 8); -#ifdef VIFUNPACKDEBUG - SysPrintf("Processing V2-32 skip, size = %d\n", size); -#endif - break; - case 0x5: - vif->tag.addr += (size * 2) + ((size / unpack->gsize) * 8); -#ifdef VIFUNPACKDEBUG - SysPrintf("Processing V2-16 skip, size = %d\n", size); -#endif - break; - case 0x6: - vif->tag.addr += (size * 4) + ((size / unpack->gsize) * 8); -#ifdef VIFUNPACKDEBUG - SysPrintf("Processing V2-8 skip, size = %d\n", size); -#endif - break; - case 0x8: - vif->tag.addr += size + ((size / unpack->gsize) * 4); -#ifdef VIFUNPACKDEBUG - SysPrintf("Processing V3-32 skip, size = %d\n", size); -#endif - break; - case 0x9: - vif->tag.addr += (size * 2) + ((size / unpack->gsize) * 4); -#ifdef VIFUNPACKDEBUG - SysPrintf("Processing V3-16 skip, size = %d\n", size); -#endif - break; - case 0xA: - vif->tag.addr += (size * 4) + ((size / unpack->gsize) * 4); -#ifdef VIFUNPACKDEBUG - SysPrintf("Processing V3-8 skip, size = %d\n", size); -#endif - break; - case 0xC: - vif->tag.addr += size; -#ifdef VIFUNPACKDEBUG - SysPrintf("Processing V4-32 skip, size = %d, CL = %d, WL = %d\n", size, vif1Regs->cycle.cl, vif1Regs->cycle.wl); -#endif - break; - case 0xD: - vif->tag.addr += size * 2; -#ifdef VIFUNPACKDEBUG - SysPrintf("Processing V4-16 skip, size = %d\n", size); -#endif - break; - case 0xE: - vif->tag.addr += size * 4; -#ifdef VIFUNPACKDEBUG - SysPrintf("Processing V4-8 skip, size = %d\n", size); -#endif - break; - case 0xF: - vif->tag.addr += size * 8; -#ifdef VIFUNPACKDEBUG - SysPrintf("Processing V4-5 skip, size = %d\n", size); -#endif - break; - default: - SysPrintf("Invalid unpack type %x\n", unpackType); - break; - } - //if(vifRegs->offset == 0) { - //vif->tag.addr += (size / unpack->gsize) * ((vifRegs->cycle.cl - vifRegs->cycle.wl)*16); - //if(vifRegs->cycle.cl != vifRegs->cycle.wl)SysPrintf("Adjusting\n"); - //} - if((vif->tag.addr & 0xf) == unpack->gsize) { - //SysPrintf("Making up for lost bit Addr %x Gsize %x new addr %x\n", vif->tag.addr, unpack->gsize, vif->tag.addr + (16 - unpack->gsize)); - vif->tag.addr += 16 - unpack->gsize; - } -} - -#ifdef _MSC_VER -//#define __MMX__ -//#define __SSE__ -#include -#include -#endif - -//u32 unpacktotal = 0; - -static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdmanum) { - u32 *dest; - unsigned int unpackType; - UNPACKFUNCTYPE func; - const VIFUnpackFuncTable *ft; - vifStruct *vif; - VIFregisters *vifRegs; - VURegs * VU; - u8 *cdata = (u8*)data; - //u64 basetick = GetCPUTick(); -#ifdef _DEBUG - int memsize; -#endif - -#ifdef _MSC_VER - _mm_prefetch((char*)data, _MM_HINT_NTA); -#endif - - if (VIFdmanum == 0) { - VU = &VU0; - vif = &vif0; - vifRegs = vif0Regs; -#ifdef _DEBUG - memsize = 0x1000; -#endif - assert( v->addr < 0x1000 ); - //v->addr &= 0xfff; - } else { - - VU = &VU1; - vif = &vif1; - vifRegs = vif1Regs; -#ifdef _DEBUG - memsize = 0x4000; -#endif - assert( v->addr < 0x4000 ); - //v->addr &= 0x3fff; - - if( Cpu->ExecuteVU1Block == DummyExecuteVU1Block ) { - // don't process since the frame is dummy - vif->tag.addr += (size / (VIFfuncTable[ vif->cmd & 0xf ].gsize* vifRegs->cycle.wl)) * ((vifRegs->cycle.cl - vifRegs->cycle.wl)*16); - // unpacktotal += GetCPUTick()-basetick; - return; - } - } - - dest = (u32*)(VU->Mem + v->addr); - -#ifdef VIF_LOG - VIF_LOG("VIF%d UNPACK: Mode=%x, v->size=%d, size=%d, v->addr=%x\n", - VIFdmanum, v->cmd & 0xf, v->size, size, v->addr ); -#endif - -/* if (vifRegs->cycle.cl > vifRegs->cycle.wl) { - SysPrintf( "VIF%d UNPACK: Mode=%x, v->size=%d, size=%d, v->addr=%x\n", - VIFdmanum, v->cmd & 0xf, v->size, size, v->addr ); - }*/ -#ifdef _DEBUG - if (v->size != size) { -#ifdef VIF_LOG - VIF_LOG("*PCSX2*: warning v->size != size\n"); -#endif - } - if ((v->addr+size*4) > memsize) { - SysPrintf("*PCSX2*: fixme unpack overflow\n"); - SysPrintf( "VIF%d UNPACK: Mode=%x, v->size=%d, size=%d, v->addr=%x\n", - VIFdmanum, v->cmd & 0xf, v->size, size, v->addr ); - } -#endif - // The unpack type - unpackType = v->cmd & 0xf; - /*if (v->size != size) { - SysPrintf("*PCSX2*: v->size = %d, size = %d mode = %x\n", v->size, size, unpackType); - }*/ -#ifdef VIFUNPACKDEBUG - if (size == 0) { - SysPrintf("*PCSX2*: Unpack %x with size 0!! v->size = %d cl = %d, wl = %d, mode %d mask %x\n", v->cmd, v->size, vifRegs->cycle.cl, vifRegs->cycle.wl, vifRegs->mode, vifRegs->mask); - //return; - } -#endif - - - -#ifdef _MSC_VER - _mm_prefetch((char*)data+128, _MM_HINT_NTA); -#endif - _vifRegs = (VIFregisters*)vifRegs; - _vifMaskRegs = VIFdmanum ? g_vif1Masks : g_vif0Masks; - _vif = vif; - _vifRow = VIFdmanum ? g_vifRow1 : g_vifRow0; - ft = &VIFfuncTable[ unpackType ]; - func = _vif->usn ? ft->funcU : ft->funcS; - // Unpacking - //vif->wl = 0; vif->cl = 0; - - size<<= 2; -#ifdef _DEBUG - memsize = size; -#endif - if( _vifRegs->offset > 0) { - int destinc, unpacksize; -#ifdef VIFUNPACKDEBUG - SysPrintf("aligning packet size = %d offset %d addr %x\n", size, vifRegs->offset, vif->tag.addr); -#endif - // SSE doesn't handle such small data - if (v->size != (size>>2))ProcessMemSkip(size, unpackType, VIFdmanum); - - if(vifRegs->offset < (u32)ft->qsize){ - if((size/ft->dsize) < (ft->qsize - vifRegs->offset)){ - SysPrintf("wasnt enough left size/dsize = %x left to write %x\n", (size/ft->dsize), (ft->qsize - vifRegs->offset)); - } - unpacksize = min((size/ft->dsize), (ft->qsize - vifRegs->offset)); - } else { - unpacksize = 0; - SysPrintf("Unpack align offset = 0\n"); - } - destinc = (4 - ft->qsize) + unpacksize; - - func(dest, (u32*)cdata, unpacksize); - size -= unpacksize*ft->dsize; - cdata += unpacksize*ft->dsize; - - vifRegs->num--; - ++vif->cl; - if (vif->cl == vifRegs->cycle.wl) { - if(vifRegs->cycle.cl != vifRegs->cycle.wl){ - dest += ((vifRegs->cycle.cl - vifRegs->cycle.wl)<<2) + destinc; - //vif->tag.addr += (destinc<<2) + ((vifRegs->cycle.cl - vifRegs->cycle.wl)*16); - } else { - dest += destinc; - //vif->tag.addr += destinc << 2; - } - vif->cl = 0; - } - else { - dest += destinc; - //vif->tag.addr += destinc << 2; - } -#ifdef VIFUNPACKDEBUG - SysPrintf("aligning packet done size = %d offset %d addr %x\n", size, vifRegs->offset, vif->tag.addr); -#endif - //} - //skipmeminc += (((vifRegs->cycle.cl - vifRegs->cycle.wl)<<2)*4) * skipped; - } else if (v->size != (size>>2))ProcessMemSkip(size, unpackType, VIFdmanum); - - if (vifRegs->cycle.cl >= vifRegs->cycle.wl) { // skipping write - -#ifdef _DEBUG - static s_count=0; -#endif - //u32* olddest = dest; - - int incdest; - //ft = &VIFfuncTable[ unpackType ]; - if( vif->cl != 0 ) { - // continuation from last stream - - // func = vif->usn ? ft->funcU : ft->funcS; - incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl)<<2) + 4; - while (size >= ft->gsize && vifRegs->num > 0) { - func( dest, (u32*)cdata, ft->qsize); - cdata += ft->gsize; - size -= ft->gsize; - - vifRegs->num--; - ++vif->cl; - if (vif->cl == vifRegs->cycle.wl) { - dest += incdest; - vif->cl = 0; - break; - } - - dest += 4; - } - - // have to update - _vifRow[0] = _vifRegs->r0; - _vifRow[1] = _vifRegs->r1; - _vifRow[2] = _vifRegs->r2; - _vifRow[3] = _vifRegs->r3; - - } - -#if !defined(PCSX2_NORECBUILD) - - if( size >= ft->gsize && !(v->addr&0xf) && cpucaps.hasStreamingSIMD2Extensions) { - const UNPACKPARTFUNCTYPESSE* pfn; - int writemask; - //static LARGE_INTEGER lbase, lfinal; - //QueryPerformanceCounter(&lbase); - u32 oldcycle = -1; - //FreezeXMMRegs(1); - -// u16 tempdata[4] = { 0x8000, 0x7fff, 0x1010, 0xd0d0 }; -// vifRegs->cycle.cl = 4; -// vifRegs->cycle.wl = 1; -// SetNewMask(g_vif1Masks, g_vif1HasMask3, 0x3f, ~0x3f); -// memset(dest, 0xcd, 64*4); -// VIFfuncTableSSE[1].funcS[6](dest, (u32*)tempdata, 8); - -#ifdef _MSC_VER - -#ifdef __x86_64__ - _vifCol = VIFdmanum ? g_vifCol1 : g_vifCol0; -#else - if( VIFdmanum ) { - __asm movaps XMM_ROW, qword ptr [g_vifRow1] - __asm movaps XMM_COL, qword ptr [g_vifCol1] - } - else { - __asm movaps XMM_ROW, qword ptr [g_vifRow0] - __asm movaps XMM_COL, qword ptr [g_vifCol0] - } -#endif - -#else - if( VIFdmanum ) { - __asm__(".intel_syntax\n" - "movaps %%xmm6, qword ptr [%0]\n" - "movaps %%xmm7, qword ptr [%1]\n" - ".att_syntax\n" : :"r"(g_vifRow1), "r"(g_vifCol1) ); - } - else { - __asm__(".intel_syntax\n" - "movaps %%xmm6, qword ptr [%0]\n" - "movaps %%xmm7, qword ptr [%1]\n" - ".att_syntax\n" : : "r"(g_vifRow0), "r"(g_vifCol0) ); - } -#endif - - if( vifRegs->cycle.cl == 0 || vifRegs->cycle.wl == 0 || (vifRegs->cycle.cl == vifRegs->cycle.wl && !(vifRegs->code&0x10000000)) ) { - oldcycle = *(u32*)&vifRegs->cycle; - vifRegs->cycle.cl = vifRegs->cycle.wl = 1; - } - size = min(size, (int)vifRegs->num*ft->gsize); //size will always be the same or smaller - - pfn = vif->usn ? VIFfuncTableSSE[unpackType].funcU: VIFfuncTableSSE[unpackType].funcS; - writemask = VIFdmanum ? g_vif1HasMask3[min(vifRegs->cycle.wl,3)] : g_vif0HasMask3[min(vifRegs->cycle.wl,3)]; - writemask = pfn[(((vifRegs->code & 0x10000000)>>28)<mode](dest, (u32*)cdata, size); - - if( oldcycle != -1 ) *(u32*)&vifRegs->cycle = oldcycle; - - // if size is left over, update the src,dst pointers - if( writemask > 0 ) { - int left = (size-writemask)/ft->gsize; - cdata += left * ft->gsize; - dest = (u32*)((u8*)dest + ((left/vifRegs->cycle.wl)*vifRegs->cycle.cl + left%vifRegs->cycle.wl)*16); - vifRegs->num -= left; - // Add split transfer skipping - //vif->tag.addr += (size / (ft->gsize* vifRegs->cycle.wl)) * ((vifRegs->cycle.cl - vifRegs->cycle.wl)*16); - // check for left over write cycles (so can spill to next transfer) - _vif->cl = (size % (ft->gsize*vifRegs->cycle.wl)) / ft->gsize; - } - else { - vifRegs->num -= size/ft->gsize; - if(vifRegs->num > 0) _vif->cl = (size % (ft->gsize*vifRegs->cycle.wl)) / ft->gsize; - } - - size = writemask; - - _vifRegs->r0 = _vifRow[0]; - _vifRegs->r1 = _vifRow[1]; - _vifRegs->r2 = _vifRow[2]; - _vifRegs->r3 = _vifRow[3]; - //QueryPerformanceCounter(&lfinal); - //((LARGE_INTEGER*)g_nCounters)->QuadPart += lfinal.QuadPart - lbase.QuadPart; - } - else -#endif // !PCSX2_NORECBUILD - { - - if(unpackType == 0xC && vifRegs->cycle.cl == vifRegs->cycle.wl) { //No use when SSE is available - // v4-32 - if(vifRegs->mode == 0 && !(vifRegs->code & 0x10000000) && vif->usn == 0){ - vifRegs->num -= size>>4; - FreezeMMXRegs(1); - memcpy_fast((u8*)dest, cdata, size); - FreezeMMXRegs(0); - size = 0; - //unpacktotal += GetCPUTick()-basetick; - return; - } - } - // Assigning the normal upack function, the part type is assigned later - //func = vif->usn ? ft->funcU : ft->funcS; - - incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl)<<2) + 4; - - //SysPrintf("slow vif\n"); - //if(skipped > 0) skipped = 0; - // Add split transfer skipping - //vif->tag.addr += (size / (ft->gsize*vifRegs->cycle.wl)) * ((vifRegs->cycle.cl - vifRegs->cycle.wl)*16); - - while (size >= ft->gsize && vifRegs->num > 0) { - func( dest, (u32*)cdata, ft->qsize); - cdata += ft->gsize; - size -= ft->gsize; - - vifRegs->num--; - //SysPrintf("%d transferred, remaining %d, vifnum %d\n", ft->gsize, size, vifRegs->num); - ++vif->cl; - if (vif->cl == vifRegs->cycle.wl) { - dest += incdest; - vif->cl = 0; - } - else - { - dest += 4; - } - } - - // have to update - _vifRow[0] = _vifRegs->r0; - _vifRow[1] = _vifRegs->r1; - _vifRow[2] = _vifRegs->r2; - _vifRow[3] = _vifRegs->r3; - } - - // used for debugging vif -// { -// int i, j, k; -// u32* curdest = olddest; -// FILE* ftemp = fopen("temp.txt", s_count?"a+":"w"); -// fprintf(ftemp, "%x %x %x\n", s_count, size, vif->tag.addr); -// fprintf(ftemp, "%x %x %x\n", vifRegs->code>>24, vifRegs->mode, *(u32*)&vifRegs->cycle); -// fprintf(ftemp, "row: %x %x %x %x\n", _vifRow[0], _vifRow[1], _vifRow[2], _vifRow[3]); -// //fprintf(ftemp, "row2: %x %x %x %x\n", _vifRegs->r0, _vifRegs->r1, _vifRegs->r2, _vifRegs->r3); -// -// for(i = 0; i < memsize; ) { -// for(k = 0; k < vifRegs->cycle.wl; ++k) { -// for(j = 0; j <= ((vifRegs->code>>26)&3); ++j) { -// fprintf(ftemp, "%x ", curdest[4*k+j]); -// } -// } -// -// fprintf(ftemp, "\n"); -// curdest += 4*vifRegs->cycle.cl; -// i += (((vifRegs->code>>26)&3)+1)*ft->dsize*vifRegs->cycle.wl; -// } -// fclose(ftemp); -// } -// s_count++; - - if( size >= ft->dsize && vifRegs->num > 0) { - #ifdef VIF_LOG - VIF_LOG("warning, end with size = %d\n", size); - #endif - // SSE doesn't handle such small data - //ft = &VIFfuncTable[ unpackType ]; - //func = vif->usn ? ft->funcU : ft->funcS; - #ifdef VIFUNPACKDEBUG - SysPrintf("end with size %x dsize = %x unpacktype %x\n", size, ft->dsize, unpackType); - #endif - //while (size >= ft->dsize) { - /* unpack one qword */ - func(dest, (u32*)cdata, size / ft->dsize); - //cdata += ft->dsize; - //dest += 1; - size = 0; - //} - #ifdef VIFUNPACKDEBUG - SysPrintf("leftover done, size %d, vifnum %d, addr %x\n", size, vifRegs->num, vif->tag.addr); - #endif - } - - } - else { /* filling write */ -#ifdef VIF_LOG - VIF_LOG("*PCSX2*: filling write\n"); -#endif - //ft = &VIFfuncTable[ unpackType ]; - //func = vif->usn ? ft->funcU : ft->funcS; -#ifdef VIFUNPACKDEBUG - SysPrintf("filling write %d cl %d, wl %d mask %x mode %x unpacktype %x\n", vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl, vifRegs->mask, vifRegs->mode, unpackType); -#endif - while (size >= ft->gsize || vifRegs->num > 0) { - if (vif->cl == vifRegs->cycle.wl) { - vif->cl = 0; - } - // - if (vif->cl < vifRegs->cycle.cl) { /* unpack one qword */ - func( dest, (u32*)cdata, ft->qsize); - cdata += ft->gsize; - size -= ft->gsize; - vif->cl++; - vifRegs->num--; - if (vif->cl == vifRegs->cycle.wl) { - vif->cl = 0; - } - } - else - { - func( dest, (u32*)cdata, ft->qsize); - //cdata += ft->gsize; - //size -= ft->gsize; - vif->tag.addr += 16; - vifRegs->num--; - ++vif->cl; - - } - dest += 4; - //++vif->wl; - if(vifRegs->num == 0) break; - } - } - //unpacktotal += GetCPUTick()-basetick; - //if(vifRegs->num == 0 && size > 3) SysPrintf("Size = %x, Vifnum = 0!\n", size); -} - -static void vuExecMicro( u32 addr, const u32 VIFdmanum ) -{ - int _cycles; - VURegs * VU; - //void (*_vuExecMicro)(); - -// MessageBox(NULL, "3d doesn't work\n", "Query", MB_OK); -// return; - - if (VIFdmanum == 0) { - //_vuExecMicro = Cpu->ExecuteVU0Block; - VU = &VU0; - vif0FLUSH(); - } else { - //_vuExecMicro = Cpu->ExecuteVU1Block; - VU = &VU1; - vif1FLUSH(); - } - if(VU->vifRegs->itops > (VIFdmanum ? 0x3ffu : 0xffu)) - SysPrintf("VIF%d ITOP overrun! %x\n", VIFdmanum, VU->vifRegs->itops); - - VU->vifRegs->itop = VU->vifRegs->itops; - - if (VIFdmanum == 1) { - /* in case we're handling a VIF1 execMicro - set the top with the tops value */ - VU->vifRegs->top = VU->vifRegs->tops & 0x3ff; - - /* is DBF flag set in VIF_STAT? */ - if (VU->vifRegs->stat & 0x80) { - /* it is, so set tops with base + ofst - and clear stat DBF flag */ - VU->vifRegs->tops = VU->vifRegs->base; - VU->vifRegs->stat &= ~0x80; - } else { - /* it is not, so set tops with base - and set the stat DBF flag */ - VU->vifRegs->tops = VU->vifRegs->base + VU->vifRegs->ofst; - VU->vifRegs->stat |= 0x80; - } - } - //FreezeXMMRegs(1); - if (VIFdmanum == 0) { - _cycles = VU0.cycle; - vu0ExecMicro(addr); - // too much delay - //g_vifCycles+= (VU0.cycle - _cycles)*BIAS; - } else { - _cycles = VU1.cycle; - vu1ExecMicro(addr); - // too much delay - //g_vifCycles+= (VU1.cycle - _cycles)*BIAS; - } - //FreezeXMMRegs(0); -} - -u8 s_maskwrite[256]; -void vif0Init() -{ - - u32 i; - - for(i = 0; i < 256; ++i ) { - s_maskwrite[i] = ((i&3)==3)||((i&0xc)==0xc)||((i&0x30)==0x30)||((i&0xc0)==0xc0); - } - - SetNewMask(g_vif0Masks, g_vif0HasMask3, 0, 0xffffffff); -} - -__inline void vif0UNPACK(u32 *data) { - int vifNum; - int vl, vn; - int len; - - if(vif0Regs->cycle.wl == 0 && vif0Regs->cycle.wl < vif0Regs->cycle.cl){ - SysPrintf("Vif0 CL %d, WL %d\n", vif0Regs->cycle.cl, vif0Regs->cycle.wl); - vif0.cmd &= ~0x7f; - return; - } - - vif0FLUSH(); - - vl = (vif0.cmd ) & 0x3; - vn = (vif0.cmd >> 2) & 0x3; - vif0.tag.addr = (vif0Regs->code & 0x3ff) << 4; - vif0.usn = (vif0Regs->code >> 14) & 0x1; - vifNum = (vif0Regs->code >> 16) & 0xff; - if ( vifNum == 0 ) vifNum = 256; - vif0Regs->num = vifNum; - - if ( vif0Regs->cycle.wl <= vif0Regs->cycle.cl ) { - len = ((( 32 >> vl ) * ( vn + 1 )) * vifNum + 31) >> 5; - } else { - int n = vif0Regs->cycle.cl * (vifNum / vif0Regs->cycle.wl) + - _limit( vifNum % vif0Regs->cycle.wl, vif0Regs->cycle.cl ); - - len = ( ((( 32 >> vl ) * ( vn + 1 )) * n) + 31 ) >> 5; - } - //if((vif0.tag.addr + (vifNum * 16)) > 0x1000) SysPrintf("VIF0 Oops, Addr %x, NUM %x overlaps to %x\n", vif0.tag.addr, vifNum, (vif0.tag.addr + (vifNum * 16))); - vif0.wl = 0; vif0.cl = 0; - vif0.tag.cmd = vif0.cmd; - vif0.tag.addr &= 0xfff; - vif0.tag.size = len; - vif0Regs->offset = 0; -} - -__inline void _vif0mpgTransfer(u32 addr, u32 *data, int size) { -/* SysPrintf("_vif0mpgTransfer addr=%x; size=%x\n", addr, size); - { - FILE *f = fopen("vu1.raw", "wb"); - fwrite(data, 1, size*4, f); - fclose(f); - }*/ - if (memcmp(VU0.Micro + addr, data, size << 2)) { - FreezeMMXRegs(1); - memcpy_fast(VU0.Micro + addr, data, size << 2); - FreezeMMXRegs(0); - Cpu->ClearVU0(addr, size); - } -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Vif1 Data Transfer Commands -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static int Vif0TransNull(u32 *data){ // Shouldnt go here - SysPrintf("VIF0 Shouldnt go here CMD = %x\n", vif0Regs->code); - vif0.cmd = 0; - return 0; -} -static int Vif0TransSTMask(u32 *data){ // STMASK - SetNewMask(g_vif0Masks, g_vif0HasMask3, data[0], vif0Regs->mask); - vif0Regs->mask = data[0]; -#ifdef VIF_LOG - VIF_LOG("STMASK == %x\n", vif0Regs->mask); -#endif - vif0.tag.size = 0; - vif0.cmd = 0; - return 1; -} - -static int Vif0TransSTRow(u32 *data){ // STROW - int ret; - - u32* pmem = &vif0Regs->r0+(vif0.tag.addr<<2); - u32* pmem2 = g_vifRow0+vif0.tag.addr; - assert( vif0.tag.addr < 4 ); - ret = min(4-vif0.tag.addr, vif0.vifpacketsize); - assert( ret > 0 ); - switch(ret) { - case 4: pmem[12] = data[3]; pmem2[3] = data[3]; - case 3: pmem[8] = data[2]; pmem2[2] = data[2]; - case 2: pmem[4] = data[1]; pmem2[1] = data[1]; - case 1: pmem[0] = data[0]; pmem2[0] = data[0]; break; -#ifdef _MSC_VER - default: __assume(0); -#endif - } - vif0.tag.addr += ret; - vif0.tag.size -= ret; - if(vif0.tag.size == 0) vif0.cmd = 0; - - return ret; -} - -static int Vif0TransSTCol(u32 *data){ // STCOL - int ret; - - u32* pmem = &vif0Regs->c0+(vif0.tag.addr<<2); - u32* pmem2 = g_vifCol0+vif0.tag.addr; - ret = min(4-vif0.tag.addr, vif0.vifpacketsize); - switch(ret) { - case 4: pmem[12] = data[3]; pmem2[3] = data[3]; - case 3: pmem[8] = data[2]; pmem2[2] = data[2]; - case 2: pmem[4] = data[1]; pmem2[1] = data[1]; - case 1: pmem[0] = data[0]; pmem2[0] = data[0]; break; -#ifdef _MSC_VER - default: __assume(0); -#endif - } - vif0.tag.addr += ret; - vif0.tag.size -= ret; - if(vif0.tag.size == 0) vif0.cmd = 0; - return ret; -} - -static int Vif0TransMPG(u32 *data){ // MPG - if (vif0.vifpacketsize < vif0.tag.size) { - _vif0mpgTransfer(vif0.tag.addr, data, vif0.vifpacketsize); - vif0.tag.addr += vif0.vifpacketsize << 2; - vif0.tag.size -= vif0.vifpacketsize; - return vif0.vifpacketsize; - } else { - int ret; - _vif0mpgTransfer(vif0.tag.addr, data, vif0.tag.size); - ret = vif0.tag.size; - vif0.tag.size = 0; - vif0.cmd = 0; - return ret; - } -} - -static int Vif0TransUnpack(u32 *data){ // UNPACK - FreezeXMMRegs(1); - if (vif0.vifpacketsize < vif0.tag.size) { - /* size is less that the total size, transfer is - 'in pieces' */ - VIFunpack(data, &vif0.tag, vif0.vifpacketsize, VIF0dmanum); - // g_vifCycles+= size >> 1; - //vif0.tag.addr += size << 2; - vif0.tag.size -= vif0.vifpacketsize; - FreezeXMMRegs(0); - return vif0.vifpacketsize; - } else { - int ret; - /* we got all the data, transfer it fully */ - VIFunpack(data, &vif0.tag, vif0.tag.size, VIF0dmanum); - //g_vifCycles+= vif0.tag.size >> 1; - ret = vif0.tag.size; - vif0.tag.size = 0; - vif0.cmd = 0; - FreezeXMMRegs(0); - return ret; - } - -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Vif0 CMD Base Commands -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static void Vif0CMDNop(){ // NOP - vif0.cmd &= ~0x7f; -} - -static void Vif0CMDSTCycl(){ // STCYCL - vif0Regs->cycle.cl = (u8)vif0Regs->code; - vif0Regs->cycle.wl = (u8)(vif0Regs->code >> 8); - vif0.cmd &= ~0x7f; -} - -static void Vif0CMDITop(){ // ITOP - vif0Regs->itops = vif0Regs->code & 0x3ff; - vif0.cmd &= ~0x7f; -} - -static void Vif0CMDSTMod(){ // STMOD - vif0Regs->mode = vif0Regs->code & 0x3; - vif0.cmd &= ~0x7f; -} - -static void Vif0CMDMark(){ // MARK - vif0Regs->mark = (u16)vif0Regs->code; - vif0Regs->stat |= VIF0_STAT_MRK; - vif0.cmd &= ~0x7f; -} - -static void Vif0CMDFlushE(){ // FLUSHE - vif0FLUSH(); - vif0.cmd &= ~0x7f; -} - -static void Vif0CMDMSCALF(){ //MSCAL/F - vuExecMicro( (u16)(vif0Regs->code) << 3, VIF0dmanum ); - vif0.cmd &= ~0x7f; -} - -static void Vif0CMDMSCNT(){ // MSCNT - vuExecMicro( -1, VIF0dmanum ); - vif0.cmd &= ~0x7f; -} - -static void Vif0CMDSTMask(){ // STMASK - vif0.tag.size = 1; -} - -static void Vif0CMDSTRowCol(){// STROW / STCOL - vif0.tag.addr = 0; - vif0.tag.size = 4; -} - -static void Vif0CMDMPGTransfer(){ // MPG - int vifNum; - vif0FLUSH(); - vifNum = (u8)(vif0Regs->code >> 16); - if (vifNum == 0) vifNum = 256; - vif0.tag.addr = (u16)(vif0Regs->code) << 3; - vif0.tag.size = vifNum * 2; -} - -static void Vif0CMDNull(){ // invalid opcode - // if ME1, then force the vif to interrupt - if ((vif0Regs->err & 0x4) == 0) { //Ignore vifcode and tag mismatch error - SysPrintf( "UNKNOWN VifCmd: %x\n", vif0.cmd ); - vif0Regs->stat |= 1 << 13; - vif0.irq++; - } - vif0.cmd &= ~0x7f; -} - -int VIF0transfer(u32 *data, int size, int istag) { - int ret; - int transferred=vif0.vifstalled ? vif0.irqoffset : 0; // irqoffset necessary to add up the right qws, or else will spin (spiderman) - //vif0.irqoffset = 0; -#ifdef VIF_LOG - VIF_LOG( "VIF0transfer: size %x (vif0.cmd %x)\n", size, vif0.cmd ); -#endif - - vif0.stallontag = 0; - vif0.vifstalled = 0; - vif0.vifpacketsize = size; - - - while (vif0.vifpacketsize > 0) { - - if (vif0.cmd) { - //vif0Regs->stat |= VIF0_STAT_VPS_T; - ret = Vif0TransTLB[(vif0.cmd & 0x7f)](data); - data+= ret; vif0.vifpacketsize-= ret; - //vif0Regs->stat &= ~VIF0_STAT_VPS_T; - continue; - } - - vif0Regs->stat &= ~VIF0_STAT_VPS_W; - - if(vif0.tag.size != 0) SysPrintf("no vif0 cmd but tag size is left last cmd read %x\n", vif0Regs->code); - // if interrupt and new cmd is NOT MARK - if(vif0.irq) { - break; - } - - vif0.cmd = (data[0] >> 24); - vif0Regs->code = data[0]; - - - //vif0Regs->stat |= VIF0_STAT_VPS_D; - if ((vif0.cmd & 0x60) == 0x60) { - vif0UNPACK(data); - } else { -#ifdef VIF_LOG - VIF_LOG( "VIFtransfer: cmd %x, num %x, imm %x, size %x\n", vif0.cmd, (data[0] >> 16) & 0xff, data[0] & 0xffff, size ); -#endif - if((vif0.cmd & 0x7f) > 0x4A){ - if ((vif0Regs->err & 0x4) == 0) { //Ignore vifcode and tag mismatch error - SysPrintf( "UNKNOWN VifCmd: %x\n", vif0.cmd ); - vif0Regs->stat |= 1 << 13; - vif0.irq++; - } - vif0.cmd = 0; - } else Vif0CMDTLB[(vif0.cmd & 0x7f)](); - } - //vif0Regs->stat &= ~VIF0_STAT_VPS_D; - if(vif0.tag.size > 0) vif0Regs->stat |= VIF0_STAT_VPS_W; - ++data; - --vif0.vifpacketsize; - - if ((vif0.cmd & 0x80)) { //i bit on vifcode and not masked by VIF0_ERR - if(!(vif0Regs->err & 0x1)){ -#ifdef VIF_LOG - VIF_LOG( "Interrupt on VIFcmd: %x (INTC_MASK = %x)\n", vif0.cmd, psHu32(INTC_MASK) ); -#endif - - ++vif0.irq; - if(istag && vif0.tag.size <= vif0.vifpacketsize) vif0.stallontag = 1; - } - vif0.cmd &= 0x7f; - } - } - transferred += size - vif0.vifpacketsize; - g_vifCycles+= (transferred >> 2)*BIAS; /* guessing */ - // use tag.size because some game doesn't like .cmd - //if( !vif0.cmd ) - if( !vif0.tag.size ) - vif0Regs->stat &= ~VIF0_STAT_VPS_W; - - if (vif0.irq && vif0.tag.size == 0) { - vif0.vifstalled = 1; - - if(((vif0Regs->code >> 24) & 0x7f) != 0x7)vif0Regs->stat|= VIF0_STAT_VIS; - //else SysPrintf("VIF0 IRQ on MARK\n"); - // spiderman doesn't break on qw boundaries - vif0.irqoffset = transferred%4; // cannot lose the offset - - if( istag ) { - return -2; - } - - transferred = transferred >> 2; - vif0ch->madr+= (transferred << 4); - vif0ch->qwc-= transferred; - //SysPrintf("Stall on vif0, FromSPR = %x, Vif0MADR = %x Sif0MADR = %x STADR = %x\n", psHu32(0x1000d010), vif0ch->madr, psHu32(0x1000c010), psHu32(DMAC_STADR)); - return -2; - } - - if( !istag ) { - transferred = transferred >> 2; - vif0ch->madr+= (transferred << 4); - vif0ch->qwc-= transferred; - } - - return 0; -} - -int _VIF0chain() { - u32 *pMem; - u32 qwc = vif0ch->qwc; - u32 ret; - - if (vif0ch->qwc == 0 && vif0.vifstalled == 0) return 0; - - pMem = (u32*)dmaGetAddr(vif0ch->madr); - if (pMem == NULL) - return -1; - - if( vif0.vifstalled ) { - ret = VIF0transfer(pMem+vif0.irqoffset, vif0ch->qwc*4-vif0.irqoffset, 0); - } - else { - ret = VIF0transfer(pMem, vif0ch->qwc*4, 0); - } - /*vif0ch->madr+= (vif0ch->qwc << 4); - vif0ch->qwc-= qwc;*/ - - return ret; -} - - -int _chainVIF0() { - int id; - u32 *ptag; - //int done=0; - int ret; - - ptag = (u32*)dmaGetAddr(vif0ch->tadr); //Set memory pointer to TADR - if (ptag == NULL) { //Is ptag empty? - SysPrintf("Vif0 Tag BUSERR\n"); - vif0ch->chcr = ( vif0ch->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register - return -1; //Return -1 as an error has occurred - } - - id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag - vif0ch->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag - vif0ch->madr = ptag[1]; //MADR = ADDR field - g_vifCycles+=1; // Add 1 g_vifCycles from the QW read for the tag -#ifdef VIF_LOG - VIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n", - ptag[1], ptag[0], vif0ch->qwc, id, vif0ch->madr, vif0ch->tadr); -#endif - - vif0ch->chcr = ( vif0ch->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - // Transfer dma tag if tte is set - - if (vif0ch->chcr & 0x40) { - if(vif0.vifstalled == 1) ret = VIF0transfer(ptag+(2+vif0.irqoffset), 2-vif0.irqoffset, 1); //Transfer Tag on stall - else ret = VIF0transfer(ptag+2, 2, 1); //Transfer Tag - if (ret == -1) return -1; //There has been an error - if (ret == -2) { - //SysPrintf("VIF0 Stall on tag %x\n", vif0.irqoffset); - //vif0.vifstalled = 1; - return vif0.done; //IRQ set by VIFTransfer - } - } - - vif0.done |= hwDmacSrcChainWithStack(vif0ch, id); - -#ifdef VIF_LOG - VIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n", - ptag[1], ptag[0], vif0ch->qwc, id, vif0ch->madr, vif0ch->tadr); -#endif - - //done |= hwDmacSrcChainWithStack(vif0ch, id); - ret = _VIF0chain(); //Transfers the data set by the switch - if (ret == -1) { return -1; } //There's been an error - if (ret == -2) { //IRQ has been set by VifTransfer - //vif0.vifstalled = 1; - return vif0.done; - } - - //if(id == 7)vif0ch->tadr = vif0ch->madr; - - vif0.vifstalled = 0; - - if ((vif0ch->chcr & 0x80) && (ptag[0] >> 31)) { //Check TIE bit of CHCR and IRQ bit of tag -#ifdef VIF_LOG - VIF_LOG( "dmaIrq Set\n" ); -#endif - //SysPrintf("VIF0 TIE\n"); - //SysPrintf( "VIF0dmaIrq Set\n" ); - //vif0ch->qwc = 0; - //vif0Regs->stat|= VIF0_STAT_VIS; //Set the Tag Interrupt flag of VIF0_STAT - vif0.done = 1; - return vif0.done; //End Transfer - } - return vif0.done; //Return Done -} - -void vif0Interrupt() { - int ret; - g_vifCycles = 0; //Reset the cycle count, Wouldnt reset on stall if put lower down. -#ifdef VIF_LOG - VIF_LOG("vif0Interrupt: %8.8x\n", cpuRegs.cycle); -#endif - - //if(vif0.vifstalled == 1) { - if(vif0.irq && vif0.tag.size == 0) { - vif0Regs->stat|= VIF0_STAT_INT; - hwIntcIrq(VIF0intc); - --vif0.irq; - - if (vif0Regs->stat & (VIF0_STAT_VSS|VIF0_STAT_VIS|VIF0_STAT_VFS)) - { - vif0Regs->stat&= ~0xF000000; // FQC=0 - vif0ch->chcr &= ~0x100; - cpuRegs.interrupt &= ~1; - return; - } - if(vif0ch->qwc > 0 || vif0.irqoffset > 0){ - if(vif0.stallontag == 1) { - _chainVIF0(); - } - else _VIF0chain(); - INT(0, g_vifCycles); - return; - } - } - - //} - if((vif0ch->chcr & 0x100) == 0) { - SysPrintf("Vif0 running when CHCR = %x\n", vif0ch->chcr); - /*prevviftag = NULL; - prevvifcycles = 0; - vif1ch->chcr &= ~0x100; - hwDmacIrq(DMAC_VIF1); - hwIntcIrq(VIF1intc); - vif1Regs->stat&= ~0x1F000000; // FQC=0 - return 1;*/ - } - if (vif0ch->chcr & 0x4 && vif0.done == 0 && vif0.vifstalled == 0) { - - if( !(psHu32(DMAC_CTRL) & 0x1) ) { - SysPrintf("vif0 dma masked\n"); - return; - } - - if(vif0ch->qwc > 0) _VIF0chain(); - ret = _chainVIF0(); - INT(0, g_vifCycles); - return; - //if(ret!=2) - /*else*/ //return 1; - } - - - if(vif0ch->qwc > 0) SysPrintf("VIF0 Ending with QWC left\n"); - if(vif0.cmd != 0) SysPrintf("vif0.cmd still set %x\n", vif0.cmd); - vif0ch->chcr &= ~0x100; - hwDmacIrq(DMAC_VIF0); - vif0Regs->stat&= ~0xF000000; // FQC=0 - - cpuRegs.interrupt &= ~1; -} - -// Vif1 Data Transfer Table -int (*Vif0TransTLB[128])(u32 *data) = -{ - Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x7*/ - Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0xF*/ - Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x17*/ - Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x1F*/ - Vif0TransSTMask , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x27*/ - Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x2F*/ - Vif0TransSTRow , Vif0TransSTCol , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x37*/ - Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x3F*/ - Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x47*/ - Vif0TransNull , Vif0TransNull , Vif0TransMPG , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x4F*/ - Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x57*/ - Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x5F*/ - Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransNull , /*0x67*/ - Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , /*0x6F*/ - Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransNull , /*0x77*/ - Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransNull , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack /*0x7F*/ -}; - -// Vif1 CMD Table -void (*Vif0CMDTLB[75])() = -{ - Vif0CMDNop , Vif0CMDSTCycl , Vif0CMDNull , Vif0CMDNull , Vif0CMDITop , Vif0CMDSTMod , Vif0CMDNull, Vif0CMDMark , /*0x7*/ - Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0xF*/ - Vif0CMDFlushE , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull, Vif0CMDMSCALF, Vif0CMDMSCALF, Vif0CMDNull , Vif0CMDMSCNT, /*0x17*/ - Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0x1F*/ - Vif0CMDSTMask , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0x27*/ - Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0x2F*/ - Vif0CMDSTRowCol, Vif0CMDSTRowCol, Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0x37*/ - Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0x3F*/ - Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0x47*/ - Vif0CMDNull , Vif0CMDNull , Vif0CMDMPGTransfer -}; - -void dmaVIF0() { - -#ifdef VIF_LOG - VIF_LOG("dmaVIF0 chcr = %lx, madr = %lx, qwc = %lx\n" - " tadr = %lx, asr0 = %lx, asr1 = %lx\n", - vif0ch->chcr, vif0ch->madr, vif0ch->qwc, - vif0ch->tadr, vif0ch->asr0, vif0ch->asr1 ); -#endif - - /* Check if there is a pending irq */ - /*if (vif0.irq > 0) { - vif0.irq--; - hwIntcIrq(VIF0intc); - return; - }*/ -// if(vif0ch->qwc > 0) { -// _VIF0chain(); -// INT(0, g_vifCycles); -// } - g_vifCycles = 0; - - - vif0Regs->stat|= 0x8000000; // FQC=8 - - if (!(vif0ch->chcr & 0x4) || vif0ch->qwc > 0) { // Normal Mode - if(_VIF0chain() == -2) { - SysPrintf("Stall on normal %x\n", vif0Regs->stat); - //vif0.vifstalled = 1; - return; - } - vif0.done = 1; - INT(0, g_vifCycles); - return; - } - -/* if (_VIF0chain() != 0) { - INT(0, g_vifCycles); - return; - }*/ - // Chain Mode - vif0.done = 0; - INT(0, g_vifCycles); -} - - -void vif0Write32(u32 mem, u32 value) { - if (mem == 0x10003830) { // MARK -#ifdef VIF_LOG - VIF_LOG("VIF0_MARK write32 0x%8.8x\n", value); -#endif - /* Clear mark flag in VIF0_STAT and set mark with 'value' */ - vif0Regs->stat&= ~VIF0_STAT_MRK; - vif0Regs->mark = value; - } else - if (mem == 0x10003810) { // FBRST -#ifdef VIF_LOG - VIF_LOG("VIF0_FBRST write32 0x%8.8x\n", value); -#endif - if (value & 0x1) { - /* Reset VIF */ - //SysPrintf("Vif0 Reset %x\n", vif0Regs->stat); - memset(&vif0, 0, sizeof(vif0)); - vif0ch->qwc = 0; //? - psHu64(0x10004000) = 0; - psHu64(0x10004008) = 0; - vif0.done = 1; - vif0Regs->err = 0; - vif0Regs->stat&= ~(0xF000000|VIF0_STAT_INT|VIF0_STAT_VSS|VIF0_STAT_VIS|VIF0_STAT_VFS); // FQC=0 - } - if (value & 0x2) { - /* Force Break the VIF */ - /* I guess we should stop the VIF dma here - but not 100% sure (linuz) */ - vif0Regs->stat |= VIF0_STAT_VFS; - SysPrintf("vif0 force break\n"); - } - if (value & 0x4) { - /* Stop VIF */ - /* Not completly sure about this, can't remember what game - used this, but 'draining' the VIF helped it, instead of - just stoppin the VIF (linuz) */ - vif0Regs->stat |= VIF0_STAT_VSS; - //SysPrintf("Vif0 Stop\n"); - //dmaVIF0(); // Drain the VIF --- VIF Stops as not to outstrip dma source (refraction) - //FreezeXMMRegs(0); - } - if (value & 0x8) { - int cancel = 0; - - /* Cancel stall, first check if there is a stall to cancel, - and then clear VIF0_STAT VSS|VFS|VIS|INT|ER0|ER1 bits */ - if (vif0Regs->stat & (VIF0_STAT_VSS|VIF0_STAT_VIS|VIF0_STAT_VFS)) { - cancel = 1; - } - - vif0Regs->stat &= ~(VIF0_STAT_VSS | VIF0_STAT_VFS | VIF0_STAT_VIS | - VIF0_STAT_INT | VIF0_STAT_ER0 | VIF0_STAT_ER1); - if (cancel) { - //SysPrintf("VIF0 Stall Resume\n"); - if( vif0.vifstalled ) { - // loop necessary for spiderman - if(vif0.stallontag == 1){ - //SysPrintf("Sorting VIF0 Stall on tag\n"); - _chainVIF0(); - } else _VIF0chain(); - - vif0ch->chcr |= 0x100; - INT(0, g_vifCycles); // Gets the timing right - Flatout - } - } - } - } else - if (mem == 0x10003820) { // ERR -#ifdef VIF_LOG - VIF_LOG("VIF0_ERR write32 0x%8.8x\n", value); -#endif - /* Set VIF0_ERR with 'value' */ - vif0Regs->err = value; - } else{ - SysPrintf("Unknown Vif0 write to %x\n", mem); - if( mem >= 0x10003900 && mem < 0x10003980 ) { - - assert( (mem&0xf) == 0 ); - if( mem < 0x10003940 ) g_vifRow0[(mem>>4)&3] = value; - else g_vifCol0[(mem>>4)&3] = value; - } else psHu32(mem) = value; - } - - /* Other registers are read-only so do nothing for them */ -} - -void vif0Reset() { - /* Reset the whole VIF, meaning the internal pcsx2 vars - and all the registers */ - memset(&vif0, 0, sizeof(vif0)); - memset(vif0Regs, 0, sizeof(vif0Regs)); - SetNewMask(g_vif0Masks, g_vif0HasMask3, 0, 0xffffffff); - psHu64(0x10004000) = 0; - psHu64(0x10004008) = 0; - vif0.done = 1; - vif0Regs->stat&= ~0xF000000; // FQC=0 - //FreezeXMMRegs(0); - //FreezeMMXRegs(0); -} - -int vif0Freeze(gzFile f, int Mode) { - gzfreeze(&vif0, sizeof(vif0)); - if (Mode == 0) - SetNewMask(g_vif0Masks, g_vif0HasMask3, vif0Regs->mask, ~vif0Regs->mask); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -void vif1Init() { - SetNewMask(g_vif1Masks, g_vif1HasMask3, 0, 0xffffffff); -} - -__inline void vif1UNPACK(u32 *data) { - int vifNum; - int vl, vn; - //int len; - if(vif1Regs->cycle.wl == 0){ - if(vif1Regs->cycle.wl < vif1Regs->cycle.cl){ - SysPrintf("Vif1 CL %d, WL %d\n", vif1Regs->cycle.cl, vif1Regs->cycle.wl); - vif1.cmd &= ~0x7f; - return; -} - } - vif1FLUSH(); - - vl = (vif1.cmd ) & 0x3; - vn = (vif1.cmd >> 2) & 0x3; - - vif1.usn = (vif1Regs->code >> 14) & 0x1; - vifNum = (vif1Regs->code >> 16) & 0xff; - if ( vifNum == 0 ) vifNum = 256; - vif1Regs->num = vifNum; - - if ( vif1Regs->cycle.wl <= vif1Regs->cycle.cl ) { - vif1.tag.size = ((( 32 >> vl ) * ( vn + 1 )) * vifNum + 31) >> 5; - } else { - int n = vif1Regs->cycle.cl * (vifNum / vif1Regs->cycle.wl) + - _limit( vifNum % vif1Regs->cycle.wl, vif1Regs->cycle.cl ); - vif1.tag.size = ( ((( 32 >> vl ) * ( vn + 1 )) * n) + 31 ) >> 5; - } - if ( ( vif1Regs->code >> 15) & 0x1 ) { - vif1.tag.addr = (vif1Regs->code + vif1Regs->tops) & 0x3ff; - } else vif1.tag.addr = vif1Regs->code & 0x3ff; - - //vif1.wl = 0; - vif1.cl = 0; - vif1.tag.addr <<= 4; - //if((vif1.tag.addr + (vifNum * 16)) > 0x4000) SysPrintf("Oops, Addr %x, NUM %x overlaps to %x\n", vif1.tag.addr, vifNum, (vif1.tag.addr + (vifNum * 16))); - - vif1.tag.cmd = vif1.cmd; - // vif1Regs->offset = 0; -} - -__inline void _vif1mpgTransfer(u32 addr, u32 *data, int size) { -/* SysPrintf("_vif1mpgTransfer addr=%x; size=%x\n", addr, size); - { - FILE *f = fopen("vu1.raw", "wb"); - fwrite(data, 1, size*4, f); - fclose(f); - }*/ - assert( VU1.Micro > 0 ); - if (memcmp(VU1.Micro + addr, data, size << 2)) { - FreezeMMXRegs(1); - memcpy_fast(VU1.Micro + addr, data, size << 2); - FreezeMMXRegs(0); - Cpu->ClearVU1(addr, size); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Vif1 Data Transfer Commands -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static int Vif1TransNull(u32 *data){ // Shouldnt go here - SysPrintf("Shouldnt go here CMD = %x\n", vif1Regs->code); - vif1.cmd = 0; - return 0; -} -static int Vif1TransSTMask(u32 *data){ // STMASK - SetNewMask(g_vif1Masks, g_vif1HasMask3, data[0], vif1Regs->mask); - vif1Regs->mask = data[0]; -#ifdef VIF_LOG - VIF_LOG("STMASK == %x\n", vif1Regs->mask); -#endif - vif1.tag.size = 0; - vif1.cmd = 0; - return 1; -} - -static int Vif1TransSTRow(u32 *data){ - int ret; - - u32* pmem = &vif1Regs->r0+(vif1.tag.addr<<2); - u32* pmem2 = g_vifRow1+vif1.tag.addr; - assert( vif1.tag.addr < 4 ); - ret = min(4-vif1.tag.addr, vif1.vifpacketsize); - assert( ret > 0 ); - switch(ret) { - case 4: pmem[12] = data[3]; pmem2[3] = data[3]; - case 3: pmem[8] = data[2]; pmem2[2] = data[2]; - case 2: pmem[4] = data[1]; pmem2[1] = data[1]; - case 1: pmem[0] = data[0]; pmem2[0] = data[0]; break; -#ifdef _MSC_VER - default: __assume(0); -#endif - } - vif1.tag.addr += ret; - vif1.tag.size -= ret; - if(vif1.tag.size == 0) vif1.cmd = 0; - - return ret; -} - -static int Vif1TransSTCol(u32 *data){ - int ret; - - u32* pmem = &vif1Regs->c0+(vif1.tag.addr<<2); - u32* pmem2 = g_vifCol1+vif1.tag.addr; - ret = min(4-vif1.tag.addr, vif1.vifpacketsize); - switch(ret) { - case 4: pmem[12] = data[3]; pmem2[3] = data[3]; - case 3: pmem[8] = data[2]; pmem2[2] = data[2]; - case 2: pmem[4] = data[1]; pmem2[1] = data[1]; - case 1: pmem[0] = data[0]; pmem2[0] = data[0]; break; -#ifdef _MSC_VER - default: __assume(0); -#endif - } - vif1.tag.addr += ret; - vif1.tag.size -= ret; - if(vif1.tag.size == 0) vif1.cmd = 0; - return ret; -} - -static int Vif1TransMPG(u32 *data){ - if (vif1.vifpacketsize < vif1.tag.size) { - _vif1mpgTransfer(vif1.tag.addr, data, vif1.vifpacketsize); - vif1.tag.addr += vif1.vifpacketsize << 2; - vif1.tag.size -= vif1.vifpacketsize; - return vif1.vifpacketsize; - } else { - int ret; - _vif1mpgTransfer(vif1.tag.addr, data, vif1.tag.size); - ret = vif1.tag.size; - vif1.tag.size = 0; - vif1.cmd = 0; - return ret; - } -} -u32 splittransfer[4]; -u32 splitptr = 0; - -static int Vif1TransDirectHL(u32 *data){ - int ret = 0; - - - if(splitptr > 0){ //Leftover data from the last packet, filling the rest and sending to the GS - if(splitptr < 4 && vif1.vifpacketsize >= (4-splitptr)){ - - while(splitptr < 4){ - splittransfer[splitptr++] = (u32)data++; - ret++; - vif1.tag.size--; - } - } - //if(splitptr < 4) SysPrintf("Whoopsie\n"); - if( CHECK_MULTIGS ) { - u8* gsmem = GSRingBufCopy((u32*)splittransfer[0], 16, GS_RINGTYPE_P2); - if( gsmem != NULL ) { - FreezeMMXRegs(1); - memcpy_fast(gsmem, (u32*)splittransfer[0], 16); - GSRINGBUF_DONECOPY(gsmem, 16); - GSgifTransferDummy(1, (u32*)splittransfer[0], 1); - } - FreezeMMXRegs(0); - if( !CHECK_DUALCORE ) GS_SETEVENT(); - } - else { - FreezeXMMRegs(1); - FreezeMMXRegs(1); - GSGIFTRANSFER2((u32*)splittransfer[0], 1); - FreezeMMXRegs(0); - FreezeXMMRegs(0); - } - - if(vif1.tag.size == 0) vif1.cmd = 0; - splitptr = 0; - return ret; - } - if (vif1.vifpacketsize < vif1.tag.size) { - if(vif1.vifpacketsize < 4 && splitptr != 4) { //Not a full QW left in the buffer, saving left over data - ret = vif1.vifpacketsize; - while(ret > 0){ - splittransfer[splitptr++] = (u32)data++; - vif1.tag.size--; - ret--; - } - //if(vif1.tag.size < 0) SysPrintf("Help\n"); - return vif1.vifpacketsize; - } //else if(vif1.vifpacketsize%4 != 0) SysPrintf("Size left = %x, non-qw aligned amount == %x\n", vif1.vifpacketsize, vif1.vifpacketsize%4); - - vif1.tag.size-= vif1.vifpacketsize; - ret = vif1.vifpacketsize; - } else { - ret = vif1.tag.size; - vif1.tag.size = 0; - vif1.cmd = 0; - } - - - - if( CHECK_MULTIGS ) { - u8* gsmem = GSRingBufCopy(data, ret<<2, GS_RINGTYPE_P2); - - if( gsmem != NULL ) { - FreezeMMXRegs(1); - memcpy_fast(gsmem, data, ret<<2); - FreezeMMXRegs(0); - GSRINGBUF_DONECOPY(gsmem, ret<<2); - GSgifTransferDummy(1, data, ret>>2); - } - - if( !CHECK_DUALCORE ) GS_SETEVENT(); - } - else { - - FreezeXMMRegs(1); - FreezeMMXRegs(1); - GSGIFTRANSFER2(data, (ret >> 2)); - FreezeMMXRegs(0); - FreezeXMMRegs(0); - } - - - return ret; -} - - -static int Vif1TransUnpack(u32 *data){ - - FreezeXMMRegs(1); - - if (vif1.vifpacketsize < vif1.tag.size) { - /* size is less that the total size, transfer is - 'in pieces' */ - VIFunpack(data, &vif1.tag, vif1.vifpacketsize, VIF1dmanum); - // g_vifCycles+= size >> 1; - //vif1.tag.addr += size << 2; - vif1.tag.size -= vif1.vifpacketsize; - FreezeXMMRegs(0); - return vif1.vifpacketsize; - } else { - int ret; - /* we got all the data, transfer it fully */ - VIFunpack(data, &vif1.tag, vif1.tag.size, VIF1dmanum); - //g_vifCycles+= vif1.tag.size >> 1; - ret = vif1.tag.size; - vif1.tag.size = 0; - vif1.cmd = 0; - FreezeXMMRegs(0); - return ret; - } - -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Vif1 CMD Base Commands -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int transferred = 0; -int Path3transfer=0; -static void Vif1CMDNop(){ // NOP - vif1.cmd &= ~0x7f; -} -static void Vif1CMDSTCycl(){ // STCYCL - vif1Regs->cycle.cl = (u8)vif1Regs->code; - vif1Regs->cycle.wl = (u8)(vif1Regs->code >> 8); - vif1.cmd &= ~0x7f; -} -static void Vif1CMDOffset(){ // OFFSET - vif1Regs->ofst = vif1Regs->code & 0x3ff; - vif1Regs->stat &= ~0x80; - vif1Regs->tops = vif1Regs->base; - vif1.cmd &= ~0x7f; -} -static void Vif1CMDBase(){ // BASE - vif1Regs->base = vif1Regs->code & 0x3ff; - vif1.cmd &= ~0x7f; -} -static void Vif1CMDITop(){ // ITOP - vif1Regs->itops = vif1Regs->code & 0x3ff; - vif1.cmd &= ~0x7f; -} - -static void Vif1CMDSTMod(){ // STMOD - vif1Regs->mode = vif1Regs->code & 0x3; - vif1.cmd &= ~0x7f; -} - -static void Vif1CMDMskPath3(){ // MSKPATH3 - - vif1Regs->mskpath3 = (vif1Regs->code >> 15) & 0x1; - //SysPrintf("VIF MSKPATH3 %x\n", vif1Regs->mskpath3); -#ifdef GSPATH3FIX - - if ( (vif1Regs->code >> 15) & 0x1 ) { - while((gif->chcr & 0x100)){ //Can be done 2 different ways, depends on the game/company - if(path3hack == 0)if(Path3transfer == 0 && gif->qwc == 0) break; - - gsInterrupt(); - - if(path3hack == 1)if(gif->qwc == 0) break; //add games not working with it to elfheader.c to enable this instead - } - //while(gif->chcr & 0x100) gsInterrupt(); // Finish the transfer first - psHu32(GIF_STAT) |= 0x2; - } else { - if(gif->chcr & 0x100) INT(2, (transferred>>2) * BIAS); // Restart Path3 on its own, time it right! - psHu32(GIF_STAT) &= ~0x2; - } -#else - if ( vif1Regs->mskpath3 ) { - if(gif->qwc) _GIFchain(); // Finish the transfer first - psHu32(GIF_STAT) |= 0x2; - } else { - psHu32(GIF_STAT) &= ~0x2; - if(gif->qwc) _GIFchain(); // Finish the transfer first - } -#endif - vif1.cmd &= ~0x7f; -} - -static void Vif1CMDMark(){ // MARK - vif1Regs->mark = (u16)vif1Regs->code; - vif1Regs->stat |= VIF1_STAT_MRK; - vif1.cmd &= ~0x7f; -} -static void Vif1CMDFlush(){ // FLUSH/E/A - - vif1FLUSH(); - - if((vif1.cmd & 0x7f) == 0x13) { - //SysPrintf("FlushA\n"); - while((gif->chcr & 0x100)){ - if(Path3transfer == 0 && gif->qwc == 0) break; - gsInterrupt(); - } - } - - vif1.cmd &= ~0x7f; -} -static void Vif1CMDMSCALF(){ //MSCAL/F - vuExecMicro( (u16)(vif1Regs->code) << 3, VIF1dmanum ); - vif1.cmd &= ~0x7f; -} -static void Vif1CMDMSCNT(){ // MSCNT - vuExecMicro( -1, VIF1dmanum ); - vif1.cmd &= ~0x7f; -} -static void Vif1CMDSTMask(){ // STMASK - vif1.tag.size = 1; -} -static void Vif1CMDSTRowCol(){// STROW / STCOL - vif1.tag.addr = 0; - vif1.tag.size = 4; -} - -static void Vif1CMDMPGTransfer(){ // MPG - int vifNum; - vif1FLUSH(); - vifNum = (u8)(vif1Regs->code >> 16); - if (vifNum == 0) vifNum = 256; - vif1.tag.addr = (u16)(vif1Regs->code) << 3; - vif1.tag.size = vifNum * 2; -} -static void Vif1CMDDirectHL(){ // DIRECT/HL - int vifImm; - vifImm = (u16)vif1Regs->code; - if (vifImm == 0) { - vif1.tag.size = 65536 << 2; - } else { - vif1.tag.size = vifImm << 2; - } - while((gif->chcr & 0x100) && (vif1.cmd & 0x7f) == 0x51){ - gsInterrupt(); //DirectHL flushes the lot - //if((psHu32(GIF_STAT) & 0xE00) == 0) break; - } -} -static void Vif1CMDNull(){ // invalid opcode - // if ME1, then force the vif to interrupt - - if ((vif1Regs->err & 0x4) == 0) { //Ignore vifcode and tag mismatch error - SysPrintf( "UNKNOWN VifCmd: %x\n", vif1.cmd ); - vif1Regs->stat |= 1 << 13; - vif1.irq++; - } - vif1.cmd = 0; -} - -// Vif1 Data Transfer Table - -int (*Vif1TransTLB[128])(u32 *data) = -{ - Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x7*/ - Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0xF*/ - Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x17*/ - Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x1F*/ - Vif1TransSTMask , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x27*/ - Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x2F*/ - Vif1TransSTRow , Vif1TransSTCol , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x37*/ - Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x3F*/ - Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x47*/ - Vif1TransNull , Vif1TransNull , Vif1TransMPG , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x4F*/ - Vif1TransDirectHL, Vif1TransDirectHL, Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x57*/ - Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x5F*/ - Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransNull , /*0x67*/ - Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , /*0x6F*/ - Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransNull , /*0x77*/ - Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransNull , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack /*0x7F*/ -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Vif1 CMD Table -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void (*Vif1CMDTLB[82])() = -{ - Vif1CMDNop , Vif1CMDSTCycl , Vif1CMDOffset , Vif1CMDBase , Vif1CMDITop , Vif1CMDSTMod , Vif1CMDMskPath3, Vif1CMDMark , /*0x7*/ - Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0xF*/ - Vif1CMDFlush , Vif1CMDFlush , Vif1CMDNull , Vif1CMDFlush, Vif1CMDMSCALF, Vif1CMDMSCALF, Vif1CMDNull , Vif1CMDMSCNT, /*0x17*/ - Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x1F*/ - Vif1CMDSTMask , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x27*/ - Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x2F*/ - Vif1CMDSTRowCol, Vif1CMDSTRowCol, Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x37*/ - Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x3F*/ - Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x47*/ - Vif1CMDNull , Vif1CMDNull , Vif1CMDMPGTransfer, Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x4F*/ - Vif1CMDDirectHL, Vif1CMDDirectHL -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -int VIF1transfer(u32 *data, int size, int istag) { - int ret; - transferred=vif1.vifstalled ? vif1.irqoffset : 0; // irqoffset necessary to add up the right qws, or else will spin (spiderman) - -#ifdef VIF_LOG - VIF_LOG( "VIF1transfer: size %x (vif1.cmd %x)\n", size, vif1.cmd ); -#endif - - - vif1.irqoffset = 0; - vif1.vifstalled = 0; - vif1.stallontag = 0; - vif1.vifpacketsize = size; - - //vif1.irq = 0; - while (vif1.vifpacketsize > 0) { - - if (vif1.cmd) { - //vif1Regs->stat |= VIF1_STAT_VPS_T; - ret = Vif1TransTLB[vif1.cmd](data); - data+= ret; vif1.vifpacketsize-= ret; - //vif1Regs->stat &= ~VIF1_STAT_VPS_T; - continue; - } - - if(vif1.tag.size != 0) SysPrintf("no vif1 cmd but tag size is left last cmd read %x\n", vif1Regs->code); - //vif1Regs->stat &= ~VIF1_STAT_VPS_W; - - //if(vif1.tag.size > 0) SysPrintf("VIF1 Tag size %x when cmd == 0!\n", vif1.tag.size); - - - if(vif1.irq) break; - - vif1.cmd = (data[0] >> 24); - vif1Regs->code = data[0]; - - - //vif1Regs->stat |= VIF1_STAT_VPS_D; - if ((vif1.cmd & 0x60) == 0x60) { - vif1UNPACK(data); - } else { -#ifdef VIF_LOG - VIF_LOG( "VIFtransfer: cmd %x, num %x, imm %x, size %x\n", vif1.cmd, (data[0] >> 16) & 0xff, data[0] & 0xffff, vif1.vifpacketsize ); -#endif - //vif1CMD(data, size); - /*if((vif1.cmd & 0x7f) > 0x51){ - if ((vif1Regs->err & 0x4) == 0) { //Ignore vifcode and tag mismatch error - SysPrintf( "UNKNOWN VifCmd: %x\n", vif1.cmd ); - vif1Regs->stat |= 1 << 13; - vif1.irq++; - } - vif1.cmd = 0; - } else*/ Vif1CMDTLB[(vif1.cmd & 0x7f)](); - } - //vif1Regs->stat &= ~VIF1_STAT_VPS_D; - //if(vif1.tag.size > 0) vif1Regs->stat |= VIF1_STAT_VPS_W; - ++data; - --vif1.vifpacketsize; - - if ((vif1.cmd & 0x80)) { //i bit on vifcode and not masked by VIF1_ERR -#ifdef VIF_LOG - VIF_LOG( "Interrupt on VIFcmd: %x (INTC_MASK = %x)\n", vif1.cmd, psHu32(INTC_MASK) ); -#endif - /*if((psHu32(DMAC_CTRL) & 0xC) == 0x8){ - SysPrintf("VIF1 Stall on MFIFO, not implemented!\n"); - }*/ - - if(!(vif1Regs->err & 0x1)){ - ++vif1.irq; - if(istag && vif1.tag.size <= vif1.vifpacketsize) vif1.stallontag = 1; - } - vif1.cmd &= 0x7f; - } - } - //if(vif1.cmd != 0 && vif1.tag.size == 0) SysPrintf("cmd but no tag size is left %x\n", vif1.cmd); - //if(vif1.cmd == 0 && vif1.tag.size != 0) SysPrintf("no cmd but tag size is left last cmd read %x\n", vif1Regs->code); - transferred += size - vif1.vifpacketsize; - g_vifCycles+= (transferred>>2)*BIAS; /* guessing */ - // use tag.size because some game doesn't like .cmd - //if( !vif1.cmd ) - //if( !vif1.tag.size ) - // vif1Regs->stat &= ~VIF1_STAT_VPS_W; - - if (vif1.irq && vif1.tag.size == 0) { - vif1.vifstalled = 1; - if(((vif1Regs->code >> 24) & 0x7f) != 0x7)vif1Regs->stat|= VIF1_STAT_VIS; - //else SysPrintf("Stall on Vif1 MARK\n"); - // spiderman doesn't break on qw boundaries - vif1.irqoffset = transferred%4; // cannot lose the offset - - if( istag ) { - return -2; - } - - transferred = transferred >> 2; - vif1ch->madr+= (transferred << 4); - vif1ch->qwc-= transferred; - //SysPrintf("Stall on vif1, FromSPR = %x, Vif1MADR = %x Sif0MADR = %x STADR = %x\n", psHu32(0x1000d010), vif1ch->madr, psHu32(0x1000c010), psHu32(DMAC_STADR)); - return -2; - } - - - if( !istag ) { - /*if(transferred & 0x3) vif1.irqoffset = transferred%4; - else vif1.irqoffset = 0;*/ - - transferred = transferred >> 2; - vif1ch->madr+= (transferred << 4); - vif1ch->qwc-= transferred; - - //if(vif1ch->qwc > 0 && size != 0) vif1.vifstalled = 1; - - } - - - return 0; -} - -int _VIF1chain() { - u32 *pMem; - u32 qwc = vif1ch->qwc; - u32 ret; - - - if (vif1ch->qwc == 0 && vif1.vifstalled == 0) return 0; - - pMem = (u32*)dmaGetAddr(vif1ch->madr); - if (pMem == NULL) - return -1; - -#ifdef VIF_LOG - VIF_LOG("dmaChain size=%d, madr=%lx, tadr=%lx\n", - vif1ch->qwc, vif1ch->madr, vif1ch->tadr); -#endif - if( vif1.vifstalled ) { - ret = VIF1transfer(pMem+vif1.irqoffset, vif1ch->qwc*4-vif1.irqoffset, 0); - } - else { - ret = VIF1transfer(pMem, vif1ch->qwc*4, 0); - } - /*vif1ch->madr+= (vif1ch->qwc << 4); - vif1ch->qwc-= qwc;*/ - - return ret; -} - -static int prevvifcycles = 0; -static u32* prevviftag = NULL; -u32 *vifptag; -int _chainVIF1() { - int id; - //int done=0; - int ret; - //g_vifCycles = prevvifcycles; - - vifptag = (u32*)dmaGetAddr(vif1ch->tadr); //Set memory pointer to TADR - if (vifptag == NULL) { //Is ptag empty? - SysPrintf("Vif1 Tag BUSERR\n"); - vif1ch->chcr = ( vif1ch->chcr & 0xFFFF ) | ( (*vifptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register - return -1; //Return -1 as an error has occurred - } - - id = (vifptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag - vif1ch->qwc = (u16)vifptag[0]; //QWC set to lower 16bits of the tag - vif1ch->madr = vifptag[1]; //MADR = ADDR field - g_vifCycles+=1; // Add 1 g_vifCycles from the QW read for the tag - - vif1ch->chcr = ( vif1ch->chcr & 0xFFFF ) | ( (*vifptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 - // Transfer dma tag if tte is set - - - - - -#ifdef VIF_LOG - VIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n", - vifptag[1], vifptag[0], vif1ch->qwc, id, vif1ch->madr, vif1ch->tadr); -#endif - - - //} else - - - if (!vif1.done && (psHu32(DMAC_CTRL) & 0xC0) == 0x40 && id == 4) { // STD == VIF1 - //vif1.done |= hwDmacSrcChainWithStack(vif1ch, id); - // there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall - if( (vif1ch->madr + vif1ch->qwc * 16) >= psHu32(DMAC_STADR) ) { - // stalled - - //SysPrintf("Vif1 Stalling %x, %x, DMA_CTRL = %x\n",vif1ch->madr, psHu32(DMAC_STADR), psHu32(DMAC_CTRL)); - /*prevvifcycles = g_vifCycles; - prevviftag = vifptag;*/ - hwDmacIrq(13); - //vif1ch->tadr -= 16; - return 0; - } - } - //prevvifcycles = 0; - - if (vif1ch->chcr & 0x40) { - if(vif1.vifstalled == 1) ret = VIF1transfer(vifptag+(2+vif1.irqoffset), 2-vif1.irqoffset, 1); //Transfer Tag on stall - else ret = VIF1transfer(vifptag+2, 2, 1); //Transfer Tag - if (ret == -1) return -1; //There has been an error - if (ret == -2) { - //if(vif1.tag.size > 0)SysPrintf("VIF1 Stall on tag %x code %x\n", vif1.irqoffset, vif1Regs->code); - return 0; //IRQ set by VIFTransfer - } - } - //if((psHu32(DMAC_CTRL) & 0xC0) != 0x40 || id != 4) - vif1.done |= hwDmacSrcChainWithStack(vif1ch, id); - -#ifdef VIF_LOG - VIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n", - vifptag[1], vifptag[0], vif1ch->qwc, id, vif1ch->madr, vif1ch->tadr); -#endif - - //done |= hwDmacSrcChainWithStack(vif1ch, id); - ret = _VIF1chain(); //Transfers the data set by the switch - //if (ret == -1) { return -1; } //There's been an error - //if (ret == -2) { //IRQ has been set by VifTransfer - // return 0; - //} - - - if ((vif1ch->chcr & 0x80) && (vifptag[0] >> 31)) { //Check TIE bit of CHCR and IRQ bit of tag -#ifdef VIF_LOG - VIF_LOG( "dmaIrq Set\n" ); -#endif - //SysPrintf("VIF1 TIE\n"); - //SysPrintf( "VIF1dmaIrq Set\n" ); - //vif1ch->qwc = 0; - //vif1Regs->stat|= VIF1_STAT_VIS; //Set the Tag Interrupt flag of VIF1_STAT - vif1.done = 1; - return 0; //End Transfer - } - return vif1.done; //Return Done -} - -void vif1Interrupt() { - -#ifdef VIF_LOG - VIF_LOG("vif1Interrupt: %8.8x\n", cpuRegs.cycle); -#endif - - g_vifCycles = 0; - - //if(vif1.vifstalled == 1) { - if(vif1.irq && vif1.tag.size == 0) { - vif1Regs->stat|= VIF1_STAT_INT; - hwIntcIrq(VIF1intc); - --vif1.irq; - if(vif1Regs->stat & (VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS)) - { - vif1Regs->stat&= ~0x1F000000; // FQC=0 - // One game doesnt like vif stalling at end, cant remember what. Spiderman isnt keen on it tho - vif1ch->chcr &= ~0x100; - cpuRegs.interrupt &= ~(1 << 1); - return; - } - //return 0; - if(vif1ch->qwc > 0 || vif1.irqoffset > 0){ - if(vif1.stallontag == 1) { - _chainVIF1(); - } - else _VIF1chain(); - INT(1, g_vifCycles); - return; - } - } - - - //} - if((vif1ch->chcr & 0x100) == 0) { - SysPrintf("Vif1 running when CHCR == %x\n", vif1ch->chcr); - /*prevviftag = NULL; - prevvifcycles = 0; - vif1ch->chcr &= ~0x100; - hwDmacIrq(DMAC_VIF1); - hwIntcIrq(VIF1intc); - vif1Regs->stat&= ~0x1F000000; // FQC=0 - return 1;*/ - } - /*if(vif1ch->qwc > 0){ - _VIF1chain(); - INT(1, g_vifCycles); - return 0; - }*/ - if ((vif1ch->chcr & 0x104) == 0x104 && vif1.done == 0) { - - if( !(psHu32(DMAC_CTRL) & 0x1) ) { - SysPrintf("vif1 dma masked\n"); - return; - } - - _chainVIF1(); - INT(1, g_vifCycles); - - return; - } - if(vif1ch->qwc > 0) SysPrintf("VIF1 Ending with QWC left\n"); - if(vif1.cmd != 0) SysPrintf("vif1.cmd still set %x\n", vif1.cmd); - //SysPrintf("VIF Interrupt\n"); - //if((gif->chcr & 0x100) && vif1Regs->mskpath3) gsInterrupt(); - prevviftag = NULL; - prevvifcycles = 0; - - vif1ch->chcr &= ~0x100; - hwDmacIrq(DMAC_VIF1); - if(vif1Regs->mskpath3 == 0 || (vif1ch->chcr & 0x1) == 0x1)vif1Regs->stat&= ~0x1F000000; // FQC=0 - - cpuRegs.interrupt &= ~(1 << 1); -} - -extern void gsWaitGS(); -extern u32 g_MTGSVifStart, g_MTGSVifCount; -#define spr0 ((DMACh*)&PS2MEM_HW[0xD000]) -void dmaVIF1() -{ - -#ifdef VIF_LOG - VIF_LOG("dmaVIF1 chcr = %lx, madr = %lx, qwc = %lx\n" - " tadr = %lx, asr0 = %lx, asr1 = %lx\n", - vif1ch->chcr, vif1ch->madr, vif1ch->qwc, - vif1ch->tadr, vif1ch->asr0, vif1ch->asr1 ); -#endif - - /*if ((psHu32(DMAC_CTRL) & 0xC0)) { - SysPrintf("DMA Stall Control %x\n",(psHu32(DMAC_CTRL) & 0xC0)); - }*/ - /* Check if there is a pending irq */ - /*if (vif1.irq > 0) { - vif1.irq--; - hwIntcIrq(VIF1intc); - return; - }*/ -// if(vif1ch->qwc > 0) { -// _VIF1chain(); -// INT(1, g_vifCycles); -// } - vif1.done = 0; - g_vifCycles = 0; - - /*if( prevvifcycles != 0 ) { - int stallret = 0; - assert( prevviftag != NULL ); - - vifptag = prevviftag; - // transfer interrupted, so continue - //_VIF1chain(); - _chainVIF1(); - - if (vif1ch->chcr & 0x80 && vifptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag -#ifdef VIF_LOG - VIF_LOG("dmaIrq Set\n"); -#endif - vif1.done = 1; - INT(1, g_vifCycles); - return; - } - //vif1.done = 1; - INT(1, g_vifCycles); - return; - }*/ - - if (((psHu32(DMAC_CTRL) & 0xC) == 0x8)) { // VIF MFIFO - //SysPrintf("VIFMFIFO\n"); - if(!(vif1ch->chcr & 0x4)) SysPrintf("MFIFO mode != Chain! %x\n", vif1ch->chcr); - if(vif1ch->madr != spr0->madr)vifMFIFOInterrupt(); - return; - } - -#ifdef PCSX2_DEVBUILD - if ((psHu32(DMAC_CTRL) & 0xC0) == 0x40) { // STD == VIF1 - //SysPrintf("VIF Stall Control Source = %x, Drain = %x\n", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3); - //return; - } -#endif - - - vif1Regs->stat|= 0x10000000; // FQC=16 - - if (!(vif1ch->chcr & 0x4) || vif1ch->qwc > 0) { // Normal Mode - if ((psHu32(DMAC_CTRL) & 0xC0) == 0x40) { - SysPrintf("DMA Stall Control on VIF1 normal\n"); - } - if ((vif1ch->chcr & 0x1)) { // to Memory - if(_VIF1chain() == -2) { - SysPrintf("Stall on normal\n"); - vif1.vifstalled = 1; - return; - } - INT(1, g_vifCycles); - } else { // from Memory - - - - if( CHECK_MULTIGS ) { - u8* pTempMem, *pEndMem; - - u8* pMem = GSRingBufCopy(NULL, 0, GS_RINGTYPE_VIFFIFO); - *(u32*)(pMem-16) = GS_RINGTYPE_VIFFIFO|(vif1ch->qwc<<16); // hack - *(u32*)(pMem-12) = vif1ch->madr; - *(u32*)(pMem-8) = cpuRegs.cycle; - - // touch all the pages to make sure they are in memory - pTempMem = dmaGetAddr(vif1ch->madr); - pEndMem = (u8*)((uptr)(pTempMem + vif1ch->qwc*16 + 0xfff)&~0xfff); - pTempMem = (u8*)((uptr)pTempMem&~0xfff); - while(pTempMem < pEndMem ) { - pTempMem[0]++; - pTempMem[0]--; - pTempMem += 0x1000; - } - - GSRINGBUF_DONECOPY(pMem, 0); - - if( !CHECK_DUALCORE ) - GS_SETEVENT(); - - g_MTGSVifStart = cpuRegs.cycle; - g_MTGSVifCount = 4000000; // a little less than 1/60th of a second - - // wait is, the safest option - //gsWaitGS(); - //SysPrintf("waiting for gs\n"); - } - else { - - int size; - u64* pMem = (u64*)dmaGetAddr(vif1ch->madr); - if (pMem == NULL) { //Is ptag empty? - SysPrintf("Vif1 Tag BUSERR\n"); - psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register - vif1.done = 1; - vif1Regs->stat&= ~0x1f000000; - vif1ch->qwc = 0; - INT(1, g_vifCycles); - - return; //Return -1 as an error has occurred - } - FreezeXMMRegs(1); - if( GSreadFIFO2 == NULL ) { - for (size=vif1ch->qwc; size>0; --size) { - if (size > 1) GSreadFIFO((u64*)&PS2MEM_HW[0x5000]); - pMem[0] = psHu64(0x5000); - pMem[1] = psHu64(0x5008); pMem+= 2; - } - } - else { - GSreadFIFO2(pMem, vif1ch->qwc); - - // set incase read - psHu64(0x5000) = pMem[2*vif1ch->qwc-2]; - psHu64(0x5008) = pMem[2*vif1ch->qwc-1]; - } - FreezeXMMRegs(0); - - - if(vif1Regs->mskpath3 == 0)vif1Regs->stat&= ~0x1f000000; - g_vifCycles += vif1ch->qwc * 2; - vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes - vif1ch->qwc = 0; - INT(1, g_vifCycles); - } - - } - - vif1.done = 1; - return; - } - -/* if (_VIF1chain() != 0) { - INT(1, g_vifCycles); - return; - }*/ - - // Chain Mode - vif1.done = 0; - INT(1, g_vifCycles); -} - - -void vif1Write32(u32 mem, u32 value) { - if (mem == 0x10003c30) { // MARK -#ifdef VIF_LOG - VIF_LOG("VIF1_MARK write32 0x%8.8x\n", value); -#endif - /* Clear mark flag in VIF1_STAT and set mark with 'value' */ - vif1Regs->stat&= ~VIF1_STAT_MRK; - vif1Regs->mark = value; - } else - if (mem == 0x10003c10) { // FBRST -#ifdef VIF_LOG - VIF_LOG("VIF1_FBRST write32 0x%8.8x\n", value); -#endif - if (value & 0x1) { - /* Reset VIF */ - //SysPrintf("Vif1 Reset %x\n", vif1Regs->stat); - memset(&vif1, 0, sizeof(vif1)); - vif1ch->qwc = 0; //? - psHu64(0x10005000) = 0; - psHu64(0x10005008) = 0; - vif1.done = 1; - vif1Regs->err = 0; - vif1Regs->stat&= ~(0x1F800000|VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS); // FQC=0 - } - if (value & 0x2) { - /* Force Break the VIF */ - /* I guess we should stop the VIF dma here - but not 100% sure (linuz) */ - vif1Regs->stat |= VIF1_STAT_VFS; - cpuRegs.interrupt &= ~0x402; - vif1.vifstalled = 1; - SysPrintf("vif1 force break\n"); - } - if (value & 0x4) { - /* Stop VIF */ - /* Not completly sure about this, can't remember what game - used this, but 'draining' the VIF helped it, instead of - just stoppin the VIF (linuz) */ - vif1Regs->stat |= VIF1_STAT_VSS; - vif1.vifstalled = 1; - //SysPrintf("Vif1 Stop\n"); - //dmaVIF1(); // Drain the VIF --- VIF Stops as not to outstrip dma source (refraction) - //FreezeXMMRegs(0); - } - if (value & 0x8) { - int cancel = 0; - - /* Cancel stall, first check if there is a stall to cancel, - and then clear VIF1_STAT VSS|VFS|VIS|INT|ER0|ER1 bits */ - if (vif1Regs->stat & (VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS)) { - cancel = 1; - } - - vif1Regs->stat &= ~(VIF1_STAT_VSS | VIF1_STAT_VFS | VIF1_STAT_VIS | - VIF1_STAT_INT | VIF1_STAT_ER0 | VIF1_STAT_ER1); - if (cancel) { - //SysPrintf("VIF1 Stall Resume\n"); - if( vif1.vifstalled ) { - // loop necessary for spiderman - if((psHu32(DMAC_CTRL) & 0xC) == 0x8){ - //vif1.vifstalled = 0; - //SysPrintf("MFIFO Stall\n"); - INT(10, 0); - }else { - if(vif1.stallontag == 1){ - //SysPrintf("Sorting VIF Stall on tag\n"); - _chainVIF1(); - } else _VIF1chain(); - //vif1.vifstalled = 0' - INT(1, g_vifCycles); // Gets the timing right - Flatout - } - vif1ch->chcr |= 0x100; - } - } - } - } else - if (mem == 0x10003c20) { // ERR -#ifdef VIF_LOG - VIF_LOG("VIF1_ERR write32 0x%8.8x\n", value); -#endif - /* Set VIF1_ERR with 'value' */ - vif1Regs->err = value; - } else - if (mem == 0x10003c00) { // STAT -#ifdef VIF_LOG - VIF_LOG("VIF1_STAT write32 0x%8.8x\n", value); -#endif - -#ifdef PCSX2_DEVBUILD - /* Only FDR bit is writable, so mask the rest */ - if( (vif1Regs->stat & VIF1_STAT_FDR) ^ (value & VIF1_STAT_FDR) ) { - // different so can't be stalled - if (vif1Regs->stat & (VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS)) { - SysPrintf("changing dir when vif1 fifo stalled\n"); - } - } -#endif - - vif1Regs->stat = (vif1Regs->stat & ~VIF1_STAT_FDR) | (value & VIF1_STAT_FDR); - if (vif1Regs->stat & VIF1_STAT_FDR) { - vif1Regs->stat|= 0x01000000; - } else { - vif1ch->qwc = 0; - vif1.vifstalled = 0; - vif1.done = 1; - vif1Regs->stat&= ~0x1F000000; // FQC=0 - } - } - else - if (mem == 0x10003c50) { // MODE - vif1Regs->mode = value; - } - else { - SysPrintf("Unknown Vif1 write to %x\n", mem); - if( mem >= 0x10003d00 && mem < 0x10003d80 ) { - assert( (mem&0xf) == 0 ); - if( mem < 0x10003d40) g_vifRow1[(mem>>4)&3] = value; - else g_vifCol1[(mem>>4)&3] = value; - } else psHu32(mem) = value; - } - - /* Other registers are read-only so do nothing for them */ -} - -void vif1Reset() { - /* Reset the whole VIF, meaning the internal pcsx2 vars - and all the registers */ - memset(&vif1, 0, sizeof(vif1)); - memset(vif1Regs, 0, sizeof(vif1Regs)); - SetNewMask(g_vif1Masks, g_vif1HasMask3, 0, 0xffffffff); - psHu64(0x10005000) = 0; - psHu64(0x10005008) = 0; - vif1.done = 1; - vif1Regs->stat&= ~0x1F000000; // FQC=0 - /*FreezeXMMRegs(0); - FreezeMMXRegs(0);*/ -} - -int vif1Freeze(gzFile f, int Mode) { - gzfreeze(&vif1, sizeof(vif1)); - if (Mode == 0) - SetNewMask(g_vif1Masks, g_vif1HasMask3, vif1Regs->mask, ~vif1Regs->mask); - - return 0; -} + //FreezeXMMRegs(0); + g_vifCycles+= (VU1.cycle - _cycles)*BIAS; + } +} + +void vifDmaInit() { +} + +__inline static int _limit( int a, int max ) { + return ( a > max ? max : a ); +} + +void DummyExecuteVU1Block(void) +{ + VU0.VI[ REG_VPU_STAT ].UL &= ~0x100; + VU1.vifRegs->stat &= ~4; // also reset the bit (grandia 3 works) +} + +//#define VIFUNPACKDEBUG //enable unpack debugging output + +static void ProcessMemSkip(int size, unsigned int unpackType, const unsigned int VIFdmanum){ + const VIFUnpackFuncTable *unpack; + vifStruct *vif; + VIFregisters *vifRegs; + unpack = &VIFfuncTable[ unpackType ]; +// varLog |= 0x00000400; + + if (VIFdmanum == 0) + { + vif = &vif0; + vifRegs = vif0Regs; + } + else + { + vif = &vif1; + vifRegs = vif1Regs; + } + + switch(unpackType){ + case 0x0: + vif->tag.addr += size*4; +#ifdef VIFUNPACKDEBUG + SysPrintf("Processing S-32 skip, size = %d\n", size); +#endif + break; + case 0x1: + vif->tag.addr += size*8; +#ifdef VIFUNPACKDEBUG + SysPrintf("Processing S-16 skip, size = %d\n", size); +#endif + break; + case 0x2: + vif->tag.addr += size*16; +#ifdef VIFUNPACKDEBUG + SysPrintf("Processing S-8 skip, size = %d\n", size); +#endif + break; + case 0x4: + vif->tag.addr += size + ((size / unpack->gsize) * 8); +#ifdef VIFUNPACKDEBUG + SysPrintf("Processing V2-32 skip, size = %d\n", size); +#endif + break; + case 0x5: + vif->tag.addr += (size * 2) + ((size / unpack->gsize) * 8); +#ifdef VIFUNPACKDEBUG + SysPrintf("Processing V2-16 skip, size = %d\n", size); +#endif + break; + case 0x6: + vif->tag.addr += (size * 4) + ((size / unpack->gsize) * 8); +#ifdef VIFUNPACKDEBUG + SysPrintf("Processing V2-8 skip, size = %d\n", size); +#endif + break; + case 0x8: + vif->tag.addr += size + ((size / unpack->gsize) * 4); +#ifdef VIFUNPACKDEBUG + SysPrintf("Processing V3-32 skip, size = %d\n", size); +#endif + break; + case 0x9: + vif->tag.addr += (size * 2) + ((size / unpack->gsize) * 4); +#ifdef VIFUNPACKDEBUG + SysPrintf("Processing V3-16 skip, size = %d\n", size); +#endif + break; + case 0xA: + vif->tag.addr += (size * 4) + ((size / unpack->gsize) * 4); +#ifdef VIFUNPACKDEBUG + SysPrintf("Processing V3-8 skip, size = %d\n", size); +#endif + break; + case 0xC: + vif->tag.addr += size; +#ifdef VIFUNPACKDEBUG + SysPrintf("Processing V4-32 skip, size = %d, CL = %d, WL = %d\n", size, vif1Regs->cycle.cl, vif1Regs->cycle.wl); +#endif + break; + case 0xD: + vif->tag.addr += size * 2; +#ifdef VIFUNPACKDEBUG + SysPrintf("Processing V4-16 skip, size = %d\n", size); +#endif + break; + case 0xE: + vif->tag.addr += size * 4; +#ifdef VIFUNPACKDEBUG + SysPrintf("Processing V4-8 skip, size = %d\n", size); +#endif + break; + case 0xF: + vif->tag.addr += size * 8; +#ifdef VIFUNPACKDEBUG + SysPrintf("Processing V4-5 skip, size = %d\n", size); +#endif + break; + default: + SysPrintf("Invalid unpack type %x\n", unpackType); + break; + } + //if(vifRegs->offset == 0) { + //vif->tag.addr += (size / unpack->gsize) * ((vifRegs->cycle.cl - vifRegs->cycle.wl)*16); + //if(vifRegs->cycle.cl != vifRegs->cycle.wl)SysPrintf("Adjusting\n"); + //} + if((vif->tag.addr & 0xf) == unpack->gsize) { + //SysPrintf("Making up for lost bit Addr %x Gsize %x new addr %x\n", vif->tag.addr, unpack->gsize, vif->tag.addr + (16 - unpack->gsize)); + vif->tag.addr += 16 - unpack->gsize; + } +} + +#ifdef _MSC_VER +//#define __MMX__ +//#define __SSE__ +#include +#include +#endif + +//u32 unpacktotal = 0; + +static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdmanum) { + u32 *dest; + unsigned int unpackType; + UNPACKFUNCTYPE func; + const VIFUnpackFuncTable *ft; + vifStruct *vif; + VIFregisters *vifRegs; + VURegs * VU; + u8 *cdata = (u8*)data; + //u64 basetick = GetCPUTick(); +#ifdef _DEBUG + int memsize; +#endif + +#ifdef _MSC_VER + _mm_prefetch((char*)data, _MM_HINT_NTA); +#endif + + if (VIFdmanum == 0) { + VU = &VU0; + vif = &vif0; + vifRegs = vif0Regs; +#ifdef _DEBUG + memsize = 0x1000; +#endif + assert( v->addr < 0x1000 ); + //v->addr &= 0xfff; + } else { + + VU = &VU1; + vif = &vif1; + vifRegs = vif1Regs; +#ifdef _DEBUG + memsize = 0x4000; +#endif + assert( v->addr < 0x4000 ); + //v->addr &= 0x3fff; + + if( Cpu->ExecuteVU1Block == DummyExecuteVU1Block ) { + // don't process since the frame is dummy + vif->tag.addr += (size / (VIFfuncTable[ vif->cmd & 0xf ].gsize* vifRegs->cycle.wl)) * ((vifRegs->cycle.cl - vifRegs->cycle.wl)*16); + // unpacktotal += GetCPUTick()-basetick; + return; + } + } + + dest = (u32*)(VU->Mem + v->addr); + +#ifdef VIF_LOG + VIF_LOG("VIF%d UNPACK: Mode=%x, v->size=%d, size=%d, v->addr=%x\n", + VIFdmanum, v->cmd & 0xf, v->size, size, v->addr ); +#endif + +/* if (vifRegs->cycle.cl > vifRegs->cycle.wl) { + SysPrintf( "VIF%d UNPACK: Mode=%x, v->size=%d, size=%d, v->addr=%x\n", + VIFdmanum, v->cmd & 0xf, v->size, size, v->addr ); + }*/ +#ifdef _DEBUG + if (v->size != size) { +#ifdef VIF_LOG + VIF_LOG("*PCSX2*: warning v->size != size\n"); +#endif + } + if ((v->addr+size*4) > memsize) { + SysPrintf("*PCSX2*: fixme unpack overflow\n"); + SysPrintf( "VIF%d UNPACK: Mode=%x, v->size=%d, size=%d, v->addr=%x\n", + VIFdmanum, v->cmd & 0xf, v->size, size, v->addr ); + } +#endif + // The unpack type + unpackType = v->cmd & 0xf; + /*if (v->size != size) { + SysPrintf("*PCSX2*: v->size = %d, size = %d mode = %x\n", v->size, size, unpackType); + }*/ +#ifdef VIFUNPACKDEBUG + if (size == 0) { + SysPrintf("*PCSX2*: Unpack %x with size 0!! v->size = %d cl = %d, wl = %d, mode %d mask %x\n", v->cmd, v->size, vifRegs->cycle.cl, vifRegs->cycle.wl, vifRegs->mode, vifRegs->mask); + //return; + } +#endif + + + +#ifdef _MSC_VER + _mm_prefetch((char*)data+128, _MM_HINT_NTA); +#endif + _vifRegs = (VIFregisters*)vifRegs; + _vifMaskRegs = VIFdmanum ? g_vif1Masks : g_vif0Masks; + _vif = vif; + _vifRow = VIFdmanum ? g_vifRow1 : g_vifRow0; + ft = &VIFfuncTable[ unpackType ]; + func = _vif->usn ? ft->funcU : ft->funcS; + // Unpacking + //vif->wl = 0; vif->cl = 0; + + size<<= 2; +#ifdef _DEBUG + memsize = size; +#endif + if( _vifRegs->offset > 0) { + int destinc, unpacksize; +#ifdef VIFUNPACKDEBUG + SysPrintf("aligning packet size = %d offset %d addr %x\n", size, vifRegs->offset, vif->tag.addr); +#endif + // SSE doesn't handle such small data + if (v->size != (size>>2))ProcessMemSkip(size, unpackType, VIFdmanum); + + if(vifRegs->offset < (u32)ft->qsize){ + if((size/ft->dsize) < (ft->qsize - vifRegs->offset)){ + SysPrintf("wasnt enough left size/dsize = %x left to write %x\n", (size/ft->dsize), (ft->qsize - vifRegs->offset)); + } + unpacksize = min((size/ft->dsize), (ft->qsize - vifRegs->offset)); + } else { + unpacksize = 0; + SysPrintf("Unpack align offset = 0\n"); + } + destinc = (4 - ft->qsize) + unpacksize; + + func(dest, (u32*)cdata, unpacksize); + size -= unpacksize*ft->dsize; + cdata += unpacksize*ft->dsize; + + vifRegs->num--; + ++vif->cl; + if (vif->cl == vifRegs->cycle.wl) { + if(vifRegs->cycle.cl != vifRegs->cycle.wl){ + dest += ((vifRegs->cycle.cl - vifRegs->cycle.wl)<<2) + destinc; + //vif->tag.addr += (destinc<<2) + ((vifRegs->cycle.cl - vifRegs->cycle.wl)*16); + } else { + dest += destinc; + //vif->tag.addr += destinc << 2; + } + vif->cl = 0; + } + else { + dest += destinc; + //vif->tag.addr += destinc << 2; + } +#ifdef VIFUNPACKDEBUG + SysPrintf("aligning packet done size = %d offset %d addr %x\n", size, vifRegs->offset, vif->tag.addr); +#endif + //} + //skipmeminc += (((vifRegs->cycle.cl - vifRegs->cycle.wl)<<2)*4) * skipped; + } else if (v->size != (size>>2))ProcessMemSkip(size, unpackType, VIFdmanum); + + if (vifRegs->cycle.cl >= vifRegs->cycle.wl) { // skipping write + +#ifdef _DEBUG + static s_count=0; +#endif + //u32* olddest = dest; + + int incdest; + //ft = &VIFfuncTable[ unpackType ]; + if( vif->cl != 0 ) { + // continuation from last stream + + // func = vif->usn ? ft->funcU : ft->funcS; + incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl)<<2) + 4; + while (size >= ft->gsize && vifRegs->num > 0) { + func( dest, (u32*)cdata, ft->qsize); + cdata += ft->gsize; + size -= ft->gsize; + + vifRegs->num--; + ++vif->cl; + if (vif->cl == vifRegs->cycle.wl) { + dest += incdest; + vif->cl = 0; + break; + } + + dest += 4; + } + + // have to update + _vifRow[0] = _vifRegs->r0; + _vifRow[1] = _vifRegs->r1; + _vifRow[2] = _vifRegs->r2; + _vifRow[3] = _vifRegs->r3; + + } + +#if !defined(PCSX2_NORECBUILD) + + if( size >= ft->gsize && !(v->addr&0xf) && cpucaps.hasStreamingSIMD2Extensions) { + const UNPACKPARTFUNCTYPESSE* pfn; + int writemask; + //static LARGE_INTEGER lbase, lfinal; + //QueryPerformanceCounter(&lbase); + u32 oldcycle = -1; + //FreezeXMMRegs(1); + +// u16 tempdata[4] = { 0x8000, 0x7fff, 0x1010, 0xd0d0 }; +// vifRegs->cycle.cl = 4; +// vifRegs->cycle.wl = 1; +// SetNewMask(g_vif1Masks, g_vif1HasMask3, 0x3f, ~0x3f); +// memset(dest, 0xcd, 64*4); +// VIFfuncTableSSE[1].funcS[6](dest, (u32*)tempdata, 8); + +#ifdef _MSC_VER + +#ifdef __x86_64__ + _vifCol = VIFdmanum ? g_vifCol1 : g_vifCol0; +#else + if( VIFdmanum ) { + __asm movaps XMM_ROW, qword ptr [g_vifRow1] + __asm movaps XMM_COL, qword ptr [g_vifCol1] + } + else { + __asm movaps XMM_ROW, qword ptr [g_vifRow0] + __asm movaps XMM_COL, qword ptr [g_vifCol0] + } +#endif + +#else + if( VIFdmanum ) { + __asm__(".intel_syntax\n" + "movaps %%xmm6, qword ptr [%0]\n" + "movaps %%xmm7, qword ptr [%1]\n" + ".att_syntax\n" : :"r"(g_vifRow1), "r"(g_vifCol1) ); + } + else { + __asm__(".intel_syntax\n" + "movaps %%xmm6, qword ptr [%0]\n" + "movaps %%xmm7, qword ptr [%1]\n" + ".att_syntax\n" : : "r"(g_vifRow0), "r"(g_vifCol0) ); + } +#endif + + if( vifRegs->cycle.cl == 0 || vifRegs->cycle.wl == 0 || (vifRegs->cycle.cl == vifRegs->cycle.wl && !(vifRegs->code&0x10000000)) ) { + oldcycle = *(u32*)&vifRegs->cycle; + vifRegs->cycle.cl = vifRegs->cycle.wl = 1; + } + size = min(size, (int)vifRegs->num*ft->gsize); //size will always be the same or smaller + + pfn = vif->usn ? VIFfuncTableSSE[unpackType].funcU: VIFfuncTableSSE[unpackType].funcS; + writemask = VIFdmanum ? g_vif1HasMask3[min(vifRegs->cycle.wl,3)] : g_vif0HasMask3[min(vifRegs->cycle.wl,3)]; + writemask = pfn[(((vifRegs->code & 0x10000000)>>28)<mode](dest, (u32*)cdata, size); + + if( oldcycle != -1 ) *(u32*)&vifRegs->cycle = oldcycle; + + // if size is left over, update the src,dst pointers + if( writemask > 0 ) { + int left = (size-writemask)/ft->gsize; + cdata += left * ft->gsize; + dest = (u32*)((u8*)dest + ((left/vifRegs->cycle.wl)*vifRegs->cycle.cl + left%vifRegs->cycle.wl)*16); + vifRegs->num -= left; + // Add split transfer skipping + //vif->tag.addr += (size / (ft->gsize* vifRegs->cycle.wl)) * ((vifRegs->cycle.cl - vifRegs->cycle.wl)*16); + // check for left over write cycles (so can spill to next transfer) + _vif->cl = (size % (ft->gsize*vifRegs->cycle.wl)) / ft->gsize; + } + else { + vifRegs->num -= size/ft->gsize; + if(vifRegs->num > 0) _vif->cl = (size % (ft->gsize*vifRegs->cycle.wl)) / ft->gsize; + } + + size = writemask; + + _vifRegs->r0 = _vifRow[0]; + _vifRegs->r1 = _vifRow[1]; + _vifRegs->r2 = _vifRow[2]; + _vifRegs->r3 = _vifRow[3]; + //QueryPerformanceCounter(&lfinal); + //((LARGE_INTEGER*)g_nCounters)->QuadPart += lfinal.QuadPart - lbase.QuadPart; + } + else +#endif // !PCSX2_NORECBUILD + { + + if(unpackType == 0xC && vifRegs->cycle.cl == vifRegs->cycle.wl) { //No use when SSE is available + // v4-32 + if(vifRegs->mode == 0 && !(vifRegs->code & 0x10000000) && vif->usn == 0){ + vifRegs->num -= size>>4; + FreezeMMXRegs(1); + memcpy_fast((u8*)dest, cdata, size); + FreezeMMXRegs(0); + size = 0; + //unpacktotal += GetCPUTick()-basetick; + return; + } + } + // Assigning the normal upack function, the part type is assigned later + //func = vif->usn ? ft->funcU : ft->funcS; + + incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl)<<2) + 4; + + //SysPrintf("slow vif\n"); + //if(skipped > 0) skipped = 0; + // Add split transfer skipping + //vif->tag.addr += (size / (ft->gsize*vifRegs->cycle.wl)) * ((vifRegs->cycle.cl - vifRegs->cycle.wl)*16); + + while (size >= ft->gsize && vifRegs->num > 0) { + func( dest, (u32*)cdata, ft->qsize); + cdata += ft->gsize; + size -= ft->gsize; + + vifRegs->num--; + //SysPrintf("%d transferred, remaining %d, vifnum %d\n", ft->gsize, size, vifRegs->num); + ++vif->cl; + if (vif->cl == vifRegs->cycle.wl) { + dest += incdest; + vif->cl = 0; + } + else + { + dest += 4; + } + } + + // have to update + _vifRow[0] = _vifRegs->r0; + _vifRow[1] = _vifRegs->r1; + _vifRow[2] = _vifRegs->r2; + _vifRow[3] = _vifRegs->r3; + } + + // used for debugging vif +// { +// int i, j, k; +// u32* curdest = olddest; +// FILE* ftemp = fopen("temp.txt", s_count?"a+":"w"); +// fprintf(ftemp, "%x %x %x\n", s_count, size, vif->tag.addr); +// fprintf(ftemp, "%x %x %x\n", vifRegs->code>>24, vifRegs->mode, *(u32*)&vifRegs->cycle); +// fprintf(ftemp, "row: %x %x %x %x\n", _vifRow[0], _vifRow[1], _vifRow[2], _vifRow[3]); +// //fprintf(ftemp, "row2: %x %x %x %x\n", _vifRegs->r0, _vifRegs->r1, _vifRegs->r2, _vifRegs->r3); +// +// for(i = 0; i < memsize; ) { +// for(k = 0; k < vifRegs->cycle.wl; ++k) { +// for(j = 0; j <= ((vifRegs->code>>26)&3); ++j) { +// fprintf(ftemp, "%x ", curdest[4*k+j]); +// } +// } +// +// fprintf(ftemp, "\n"); +// curdest += 4*vifRegs->cycle.cl; +// i += (((vifRegs->code>>26)&3)+1)*ft->dsize*vifRegs->cycle.wl; +// } +// fclose(ftemp); +// } +// s_count++; + + if( size >= ft->dsize && vifRegs->num > 0) { + #ifdef VIF_LOG + VIF_LOG("warning, end with size = %d\n", size); + #endif + // SSE doesn't handle such small data + //ft = &VIFfuncTable[ unpackType ]; + //func = vif->usn ? ft->funcU : ft->funcS; + #ifdef VIFUNPACKDEBUG + SysPrintf("end with size %x dsize = %x unpacktype %x\n", size, ft->dsize, unpackType); + #endif + //while (size >= ft->dsize) { + /* unpack one qword */ + func(dest, (u32*)cdata, size / ft->dsize); + //cdata += ft->dsize; + //dest += 1; + size = 0; + //} + #ifdef VIFUNPACKDEBUG + SysPrintf("leftover done, size %d, vifnum %d, addr %x\n", size, vifRegs->num, vif->tag.addr); + #endif + } + + } + else { /* filling write */ +#ifdef VIF_LOG + VIF_LOG("*PCSX2*: filling write\n"); +#endif + //ft = &VIFfuncTable[ unpackType ]; + //func = vif->usn ? ft->funcU : ft->funcS; +#ifdef VIFUNPACKDEBUG + SysPrintf("filling write %d cl %d, wl %d mask %x mode %x unpacktype %x\n", vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl, vifRegs->mask, vifRegs->mode, unpackType); +#endif + while (size >= ft->gsize || vifRegs->num > 0) { + if (vif->cl == vifRegs->cycle.wl) { + vif->cl = 0; + } + // + if (vif->cl < vifRegs->cycle.cl) { /* unpack one qword */ + func( dest, (u32*)cdata, ft->qsize); + cdata += ft->gsize; + size -= ft->gsize; + vif->cl++; + vifRegs->num--; + if (vif->cl == vifRegs->cycle.wl) { + vif->cl = 0; + } + } + else + { + func( dest, (u32*)cdata, ft->qsize); + //cdata += ft->gsize; + //size -= ft->gsize; + vif->tag.addr += 16; + vifRegs->num--; + ++vif->cl; + + } + dest += 4; + //++vif->wl; + if(vifRegs->num == 0) break; + } + } + //unpacktotal += GetCPUTick()-basetick; + //if(vifRegs->num == 0 && size > 3) SysPrintf("Size = %x, Vifnum = 0!\n", size); +} + +static void vuExecMicro( u32 addr, const u32 VIFdmanum ) +{ + int _cycles; + VURegs * VU; + //void (*_vuExecMicro)(); + +// MessageBox(NULL, "3d doesn't work\n", "Query", MB_OK); +// return; + + if (VIFdmanum == 0) { + //_vuExecMicro = Cpu->ExecuteVU0Block; + VU = &VU0; + vif0FLUSH(); + } else { + //_vuExecMicro = Cpu->ExecuteVU1Block; + VU = &VU1; + vif1FLUSH(); + } + if(VU->vifRegs->itops > (VIFdmanum ? 0x3ffu : 0xffu)) + SysPrintf("VIF%d ITOP overrun! %x\n", VIFdmanum, VU->vifRegs->itops); + + VU->vifRegs->itop = VU->vifRegs->itops; + + if (VIFdmanum == 1) { + /* in case we're handling a VIF1 execMicro + set the top with the tops value */ + VU->vifRegs->top = VU->vifRegs->tops & 0x3ff; + + /* is DBF flag set in VIF_STAT? */ + if (VU->vifRegs->stat & 0x80) { + /* it is, so set tops with base + ofst + and clear stat DBF flag */ + VU->vifRegs->tops = VU->vifRegs->base; + VU->vifRegs->stat &= ~0x80; + } else { + /* it is not, so set tops with base + and set the stat DBF flag */ + VU->vifRegs->tops = VU->vifRegs->base + VU->vifRegs->ofst; + VU->vifRegs->stat |= 0x80; + } + } + //FreezeXMMRegs(1); + if (VIFdmanum == 0) { + _cycles = VU0.cycle; + vu0ExecMicro(addr); + // too much delay + //g_vifCycles+= (VU0.cycle - _cycles)*BIAS; + } else { + _cycles = VU1.cycle; + vu1ExecMicro(addr); + // too much delay + //g_vifCycles+= (VU1.cycle - _cycles)*BIAS; + } + //FreezeXMMRegs(0); +} + +u8 s_maskwrite[256]; +void vif0Init() +{ + + u32 i; + + for(i = 0; i < 256; ++i ) { + s_maskwrite[i] = ((i&3)==3)||((i&0xc)==0xc)||((i&0x30)==0x30)||((i&0xc0)==0xc0); + } + + SetNewMask(g_vif0Masks, g_vif0HasMask3, 0, 0xffffffff); +} + +__inline void vif0UNPACK(u32 *data) { + int vifNum; + int vl, vn; + int len; + + if(vif0Regs->cycle.wl == 0 && vif0Regs->cycle.wl < vif0Regs->cycle.cl){ + SysPrintf("Vif0 CL %d, WL %d\n", vif0Regs->cycle.cl, vif0Regs->cycle.wl); + vif0.cmd &= ~0x7f; + return; + } + + vif0FLUSH(); + + vl = (vif0.cmd ) & 0x3; + vn = (vif0.cmd >> 2) & 0x3; + vif0.tag.addr = (vif0Regs->code & 0x3ff) << 4; + vif0.usn = (vif0Regs->code >> 14) & 0x1; + vifNum = (vif0Regs->code >> 16) & 0xff; + if ( vifNum == 0 ) vifNum = 256; + vif0Regs->num = vifNum; + + if ( vif0Regs->cycle.wl <= vif0Regs->cycle.cl ) { + len = ((( 32 >> vl ) * ( vn + 1 )) * vifNum + 31) >> 5; + } else { + int n = vif0Regs->cycle.cl * (vifNum / vif0Regs->cycle.wl) + + _limit( vifNum % vif0Regs->cycle.wl, vif0Regs->cycle.cl ); + + len = ( ((( 32 >> vl ) * ( vn + 1 )) * n) + 31 ) >> 5; + } + //if((vif0.tag.addr + (vifNum * 16)) > 0x1000) SysPrintf("VIF0 Oops, Addr %x, NUM %x overlaps to %x\n", vif0.tag.addr, vifNum, (vif0.tag.addr + (vifNum * 16))); + vif0.wl = 0; vif0.cl = 0; + vif0.tag.cmd = vif0.cmd; + vif0.tag.addr &= 0xfff; + vif0.tag.size = len; + vif0Regs->offset = 0; +} + +__inline void _vif0mpgTransfer(u32 addr, u32 *data, int size) { +/* SysPrintf("_vif0mpgTransfer addr=%x; size=%x\n", addr, size); + { + FILE *f = fopen("vu1.raw", "wb"); + fwrite(data, 1, size*4, f); + fclose(f); + }*/ + if (memcmp(VU0.Micro + addr, data, size << 2)) { + FreezeMMXRegs(1); + memcpy_fast(VU0.Micro + addr, data, size << 2); + FreezeMMXRegs(0); + Cpu->ClearVU0(addr, size); + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Vif1 Data Transfer Commands +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static int Vif0TransNull(u32 *data){ // Shouldnt go here + SysPrintf("VIF0 Shouldnt go here CMD = %x\n", vif0Regs->code); + vif0.cmd = 0; + return 0; +} +static int Vif0TransSTMask(u32 *data){ // STMASK + SetNewMask(g_vif0Masks, g_vif0HasMask3, data[0], vif0Regs->mask); + vif0Regs->mask = data[0]; +#ifdef VIF_LOG + VIF_LOG("STMASK == %x\n", vif0Regs->mask); +#endif + vif0.tag.size = 0; + vif0.cmd = 0; + return 1; +} + +static int Vif0TransSTRow(u32 *data){ // STROW + int ret; + + u32* pmem = &vif0Regs->r0+(vif0.tag.addr<<2); + u32* pmem2 = g_vifRow0+vif0.tag.addr; + assert( vif0.tag.addr < 4 ); + ret = min(4-vif0.tag.addr, vif0.vifpacketsize); + assert( ret > 0 ); + switch(ret) { + case 4: pmem[12] = data[3]; pmem2[3] = data[3]; + case 3: pmem[8] = data[2]; pmem2[2] = data[2]; + case 2: pmem[4] = data[1]; pmem2[1] = data[1]; + case 1: pmem[0] = data[0]; pmem2[0] = data[0]; break; +#ifdef _MSC_VER + default: __assume(0); +#endif + } + vif0.tag.addr += ret; + vif0.tag.size -= ret; + if(vif0.tag.size == 0) vif0.cmd = 0; + + return ret; +} + +static int Vif0TransSTCol(u32 *data){ // STCOL + int ret; + + u32* pmem = &vif0Regs->c0+(vif0.tag.addr<<2); + u32* pmem2 = g_vifCol0+vif0.tag.addr; + ret = min(4-vif0.tag.addr, vif0.vifpacketsize); + switch(ret) { + case 4: pmem[12] = data[3]; pmem2[3] = data[3]; + case 3: pmem[8] = data[2]; pmem2[2] = data[2]; + case 2: pmem[4] = data[1]; pmem2[1] = data[1]; + case 1: pmem[0] = data[0]; pmem2[0] = data[0]; break; +#ifdef _MSC_VER + default: __assume(0); +#endif + } + vif0.tag.addr += ret; + vif0.tag.size -= ret; + if(vif0.tag.size == 0) vif0.cmd = 0; + return ret; +} + +static int Vif0TransMPG(u32 *data){ // MPG + if (vif0.vifpacketsize < vif0.tag.size) { + _vif0mpgTransfer(vif0.tag.addr, data, vif0.vifpacketsize); + vif0.tag.addr += vif0.vifpacketsize << 2; + vif0.tag.size -= vif0.vifpacketsize; + return vif0.vifpacketsize; + } else { + int ret; + _vif0mpgTransfer(vif0.tag.addr, data, vif0.tag.size); + ret = vif0.tag.size; + vif0.tag.size = 0; + vif0.cmd = 0; + return ret; + } +} + +static int Vif0TransUnpack(u32 *data){ // UNPACK + FreezeXMMRegs(1); + if (vif0.vifpacketsize < vif0.tag.size) { + /* size is less that the total size, transfer is + 'in pieces' */ + VIFunpack(data, &vif0.tag, vif0.vifpacketsize, VIF0dmanum); + // g_vifCycles+= size >> 1; + //vif0.tag.addr += size << 2; + vif0.tag.size -= vif0.vifpacketsize; + FreezeXMMRegs(0); + return vif0.vifpacketsize; + } else { + int ret; + /* we got all the data, transfer it fully */ + VIFunpack(data, &vif0.tag, vif0.tag.size, VIF0dmanum); + //g_vifCycles+= vif0.tag.size >> 1; + ret = vif0.tag.size; + vif0.tag.size = 0; + vif0.cmd = 0; + FreezeXMMRegs(0); + return ret; + } + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Vif0 CMD Base Commands +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static void Vif0CMDNop(){ // NOP + vif0.cmd &= ~0x7f; +} + +static void Vif0CMDSTCycl(){ // STCYCL + vif0Regs->cycle.cl = (u8)vif0Regs->code; + vif0Regs->cycle.wl = (u8)(vif0Regs->code >> 8); + vif0.cmd &= ~0x7f; +} + +static void Vif0CMDITop(){ // ITOP + vif0Regs->itops = vif0Regs->code & 0x3ff; + vif0.cmd &= ~0x7f; +} + +static void Vif0CMDSTMod(){ // STMOD + vif0Regs->mode = vif0Regs->code & 0x3; + vif0.cmd &= ~0x7f; +} + +static void Vif0CMDMark(){ // MARK + vif0Regs->mark = (u16)vif0Regs->code; + vif0Regs->stat |= VIF0_STAT_MRK; + vif0.cmd &= ~0x7f; +} + +static void Vif0CMDFlushE(){ // FLUSHE + vif0FLUSH(); + vif0.cmd &= ~0x7f; +} + +static void Vif0CMDMSCALF(){ //MSCAL/F + vuExecMicro( (u16)(vif0Regs->code) << 3, VIF0dmanum ); + vif0.cmd &= ~0x7f; +} + +static void Vif0CMDMSCNT(){ // MSCNT + vuExecMicro( -1, VIF0dmanum ); + vif0.cmd &= ~0x7f; +} + +static void Vif0CMDSTMask(){ // STMASK + vif0.tag.size = 1; +} + +static void Vif0CMDSTRowCol(){// STROW / STCOL + vif0.tag.addr = 0; + vif0.tag.size = 4; +} + +static void Vif0CMDMPGTransfer(){ // MPG + int vifNum; + vif0FLUSH(); + vifNum = (u8)(vif0Regs->code >> 16); + if (vifNum == 0) vifNum = 256; + vif0.tag.addr = (u16)(vif0Regs->code) << 3; + vif0.tag.size = vifNum * 2; +} + +static void Vif0CMDNull(){ // invalid opcode + // if ME1, then force the vif to interrupt + if ((vif0Regs->err & 0x4) == 0) { //Ignore vifcode and tag mismatch error + SysPrintf( "UNKNOWN VifCmd: %x\n", vif0.cmd ); + vif0Regs->stat |= 1 << 13; + vif0.irq++; + } + vif0.cmd &= ~0x7f; +} + +int VIF0transfer(u32 *data, int size, int istag) { + int ret; + int transferred=vif0.vifstalled ? vif0.irqoffset : 0; // irqoffset necessary to add up the right qws, or else will spin (spiderman) + //vif0.irqoffset = 0; +#ifdef VIF_LOG + VIF_LOG( "VIF0transfer: size %x (vif0.cmd %x)\n", size, vif0.cmd ); +#endif + + vif0.stallontag = 0; + vif0.vifstalled = 0; + vif0.vifpacketsize = size; + + + while (vif0.vifpacketsize > 0) { + + if (vif0.cmd) { + //vif0Regs->stat |= VIF0_STAT_VPS_T; + ret = Vif0TransTLB[(vif0.cmd & 0x7f)](data); + data+= ret; vif0.vifpacketsize-= ret; + //vif0Regs->stat &= ~VIF0_STAT_VPS_T; + continue; + } + + vif0Regs->stat &= ~VIF0_STAT_VPS_W; + + if(vif0.tag.size != 0) SysPrintf("no vif0 cmd but tag size is left last cmd read %x\n", vif0Regs->code); + // if interrupt and new cmd is NOT MARK + if(vif0.irq) { + break; + } + + vif0.cmd = (data[0] >> 24); + vif0Regs->code = data[0]; + + + //vif0Regs->stat |= VIF0_STAT_VPS_D; + if ((vif0.cmd & 0x60) == 0x60) { + vif0UNPACK(data); + } else { +#ifdef VIF_LOG + VIF_LOG( "VIFtransfer: cmd %x, num %x, imm %x, size %x\n", vif0.cmd, (data[0] >> 16) & 0xff, data[0] & 0xffff, size ); +#endif + if((vif0.cmd & 0x7f) > 0x4A){ + if ((vif0Regs->err & 0x4) == 0) { //Ignore vifcode and tag mismatch error + SysPrintf( "UNKNOWN VifCmd: %x\n", vif0.cmd ); + vif0Regs->stat |= 1 << 13; + vif0.irq++; + } + vif0.cmd = 0; + } else Vif0CMDTLB[(vif0.cmd & 0x7f)](); + } + //vif0Regs->stat &= ~VIF0_STAT_VPS_D; + if(vif0.tag.size > 0) vif0Regs->stat |= VIF0_STAT_VPS_W; + ++data; + --vif0.vifpacketsize; + + if ((vif0.cmd & 0x80)) { //i bit on vifcode and not masked by VIF0_ERR + if(!(vif0Regs->err & 0x1)){ +#ifdef VIF_LOG + VIF_LOG( "Interrupt on VIFcmd: %x (INTC_MASK = %x)\n", vif0.cmd, psHu32(INTC_MASK) ); +#endif + + ++vif0.irq; + if(istag && vif0.tag.size <= vif0.vifpacketsize) vif0.stallontag = 1; + } + vif0.cmd &= 0x7f; + } + } + transferred += size - vif0.vifpacketsize; + g_vifCycles+= (transferred >> 2)*BIAS; /* guessing */ + // use tag.size because some game doesn't like .cmd + //if( !vif0.cmd ) + if( !vif0.tag.size ) + vif0Regs->stat &= ~VIF0_STAT_VPS_W; + + if (vif0.irq && vif0.tag.size == 0) { + vif0.vifstalled = 1; + + if(((vif0Regs->code >> 24) & 0x7f) != 0x7)vif0Regs->stat|= VIF0_STAT_VIS; + //else SysPrintf("VIF0 IRQ on MARK\n"); + // spiderman doesn't break on qw boundaries + vif0.irqoffset = transferred%4; // cannot lose the offset + + if( istag ) { + return -2; + } + + transferred = transferred >> 2; + vif0ch->madr+= (transferred << 4); + vif0ch->qwc-= transferred; + //SysPrintf("Stall on vif0, FromSPR = %x, Vif0MADR = %x Sif0MADR = %x STADR = %x\n", psHu32(0x1000d010), vif0ch->madr, psHu32(0x1000c010), psHu32(DMAC_STADR)); + return -2; + } + + if( !istag ) { + transferred = transferred >> 2; + vif0ch->madr+= (transferred << 4); + vif0ch->qwc-= transferred; + } + + return 0; +} + +int _VIF0chain() { + u32 *pMem; + u32 qwc = vif0ch->qwc; + u32 ret; + + if (vif0ch->qwc == 0 && vif0.vifstalled == 0) return 0; + + pMem = (u32*)dmaGetAddr(vif0ch->madr); + if (pMem == NULL) + return -1; + + if( vif0.vifstalled ) { + ret = VIF0transfer(pMem+vif0.irqoffset, vif0ch->qwc*4-vif0.irqoffset, 0); + } + else { + ret = VIF0transfer(pMem, vif0ch->qwc*4, 0); + } + /*vif0ch->madr+= (vif0ch->qwc << 4); + vif0ch->qwc-= qwc;*/ + + return ret; +} + + +int _chainVIF0() { + int id; + u32 *ptag; + //int done=0; + int ret; + + ptag = (u32*)dmaGetAddr(vif0ch->tadr); //Set memory pointer to TADR + if (ptag == NULL) { //Is ptag empty? + SysPrintf("Vif0 Tag BUSERR\n"); + vif0ch->chcr = ( vif0ch->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 + psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register + return -1; //Return -1 as an error has occurred + } + + id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag + vif0ch->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag + vif0ch->madr = ptag[1]; //MADR = ADDR field + g_vifCycles+=1; // Add 1 g_vifCycles from the QW read for the tag +#ifdef VIF_LOG + VIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n", + ptag[1], ptag[0], vif0ch->qwc, id, vif0ch->madr, vif0ch->tadr); +#endif + + vif0ch->chcr = ( vif0ch->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 + // Transfer dma tag if tte is set + + if (vif0ch->chcr & 0x40) { + if(vif0.vifstalled == 1) ret = VIF0transfer(ptag+(2+vif0.irqoffset), 2-vif0.irqoffset, 1); //Transfer Tag on stall + else ret = VIF0transfer(ptag+2, 2, 1); //Transfer Tag + if (ret == -1) return -1; //There has been an error + if (ret == -2) { + //SysPrintf("VIF0 Stall on tag %x\n", vif0.irqoffset); + //vif0.vifstalled = 1; + return vif0.done; //IRQ set by VIFTransfer + } + } + + vif0.done |= hwDmacSrcChainWithStack(vif0ch, id); + +#ifdef VIF_LOG + VIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n", + ptag[1], ptag[0], vif0ch->qwc, id, vif0ch->madr, vif0ch->tadr); +#endif + + //done |= hwDmacSrcChainWithStack(vif0ch, id); + ret = _VIF0chain(); //Transfers the data set by the switch + if (ret == -1) { return -1; } //There's been an error + if (ret == -2) { //IRQ has been set by VifTransfer + //vif0.vifstalled = 1; + return vif0.done; + } + + //if(id == 7)vif0ch->tadr = vif0ch->madr; + + vif0.vifstalled = 0; + + if ((vif0ch->chcr & 0x80) && (ptag[0] >> 31)) { //Check TIE bit of CHCR and IRQ bit of tag +#ifdef VIF_LOG + VIF_LOG( "dmaIrq Set\n" ); +#endif + //SysPrintf("VIF0 TIE\n"); + //SysPrintf( "VIF0dmaIrq Set\n" ); + //vif0ch->qwc = 0; + //vif0Regs->stat|= VIF0_STAT_VIS; //Set the Tag Interrupt flag of VIF0_STAT + vif0.done = 1; + return vif0.done; //End Transfer + } + return vif0.done; //Return Done +} + +void vif0Interrupt() { + int ret; + g_vifCycles = 0; //Reset the cycle count, Wouldnt reset on stall if put lower down. +#ifdef VIF_LOG + VIF_LOG("vif0Interrupt: %8.8x\n", cpuRegs.cycle); +#endif + + //if(vif0.vifstalled == 1) { + if(vif0.irq && vif0.tag.size == 0) { + vif0Regs->stat|= VIF0_STAT_INT; + hwIntcIrq(VIF0intc); + --vif0.irq; + + if (vif0Regs->stat & (VIF0_STAT_VSS|VIF0_STAT_VIS|VIF0_STAT_VFS)) + { + vif0Regs->stat&= ~0xF000000; // FQC=0 + vif0ch->chcr &= ~0x100; + cpuRegs.interrupt &= ~1; + return; + } + if(vif0ch->qwc > 0 || vif0.irqoffset > 0){ + if(vif0.stallontag == 1) { + _chainVIF0(); + } + else _VIF0chain(); + INT(0, g_vifCycles); + return; + } + } + + //} + if((vif0ch->chcr & 0x100) == 0) { + SysPrintf("Vif0 running when CHCR = %x\n", vif0ch->chcr); + /*prevviftag = NULL; + prevvifcycles = 0; + vif1ch->chcr &= ~0x100; + hwDmacIrq(DMAC_VIF1); + hwIntcIrq(VIF1intc); + vif1Regs->stat&= ~0x1F000000; // FQC=0 + return 1;*/ + } + if (vif0ch->chcr & 0x4 && vif0.done == 0 && vif0.vifstalled == 0) { + + if( !(psHu32(DMAC_CTRL) & 0x1) ) { + SysPrintf("vif0 dma masked\n"); + return; + } + + if(vif0ch->qwc > 0) _VIF0chain(); + ret = _chainVIF0(); + INT(0, g_vifCycles); + return; + //if(ret!=2) + /*else*/ //return 1; + } + + + if(vif0ch->qwc > 0) SysPrintf("VIF0 Ending with QWC left\n"); + if(vif0.cmd != 0) SysPrintf("vif0.cmd still set %x\n", vif0.cmd); + vif0ch->chcr &= ~0x100; + hwDmacIrq(DMAC_VIF0); + vif0Regs->stat&= ~0xF000000; // FQC=0 + + cpuRegs.interrupt &= ~1; +} + +// Vif1 Data Transfer Table +int (*Vif0TransTLB[128])(u32 *data) = +{ + Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x7*/ + Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0xF*/ + Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x17*/ + Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x1F*/ + Vif0TransSTMask , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x27*/ + Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x2F*/ + Vif0TransSTRow , Vif0TransSTCol , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x37*/ + Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x3F*/ + Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x47*/ + Vif0TransNull , Vif0TransNull , Vif0TransMPG , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x4F*/ + Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x57*/ + Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , Vif0TransNull , /*0x5F*/ + Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransNull , /*0x67*/ + Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , /*0x6F*/ + Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransNull , /*0x77*/ + Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransNull , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack , Vif0TransUnpack /*0x7F*/ +}; + +// Vif1 CMD Table +void (*Vif0CMDTLB[75])() = +{ + Vif0CMDNop , Vif0CMDSTCycl , Vif0CMDNull , Vif0CMDNull , Vif0CMDITop , Vif0CMDSTMod , Vif0CMDNull, Vif0CMDMark , /*0x7*/ + Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0xF*/ + Vif0CMDFlushE , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull, Vif0CMDMSCALF, Vif0CMDMSCALF, Vif0CMDNull , Vif0CMDMSCNT, /*0x17*/ + Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0x1F*/ + Vif0CMDSTMask , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0x27*/ + Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0x2F*/ + Vif0CMDSTRowCol, Vif0CMDSTRowCol, Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0x37*/ + Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0x3F*/ + Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , Vif0CMDNull , /*0x47*/ + Vif0CMDNull , Vif0CMDNull , Vif0CMDMPGTransfer +}; + +void dmaVIF0() { + +#ifdef VIF_LOG + VIF_LOG("dmaVIF0 chcr = %lx, madr = %lx, qwc = %lx\n" + " tadr = %lx, asr0 = %lx, asr1 = %lx\n", + vif0ch->chcr, vif0ch->madr, vif0ch->qwc, + vif0ch->tadr, vif0ch->asr0, vif0ch->asr1 ); +#endif + + /* Check if there is a pending irq */ + /*if (vif0.irq > 0) { + vif0.irq--; + hwIntcIrq(VIF0intc); + return; + }*/ +// if(vif0ch->qwc > 0) { +// _VIF0chain(); +// INT(0, g_vifCycles); +// } + g_vifCycles = 0; + + + vif0Regs->stat|= 0x8000000; // FQC=8 + + if (!(vif0ch->chcr & 0x4) || vif0ch->qwc > 0) { // Normal Mode + if(_VIF0chain() == -2) { + SysPrintf("Stall on normal %x\n", vif0Regs->stat); + //vif0.vifstalled = 1; + return; + } + vif0.done = 1; + INT(0, g_vifCycles); + return; + } + +/* if (_VIF0chain() != 0) { + INT(0, g_vifCycles); + return; + }*/ + // Chain Mode + vif0.done = 0; + INT(0, g_vifCycles); +} + + +void vif0Write32(u32 mem, u32 value) { + if (mem == 0x10003830) { // MARK +#ifdef VIF_LOG + VIF_LOG("VIF0_MARK write32 0x%8.8x\n", value); +#endif + /* Clear mark flag in VIF0_STAT and set mark with 'value' */ + vif0Regs->stat&= ~VIF0_STAT_MRK; + vif0Regs->mark = value; + } else + if (mem == 0x10003810) { // FBRST +#ifdef VIF_LOG + VIF_LOG("VIF0_FBRST write32 0x%8.8x\n", value); +#endif + if (value & 0x1) { + /* Reset VIF */ + //SysPrintf("Vif0 Reset %x\n", vif0Regs->stat); + memset(&vif0, 0, sizeof(vif0)); + vif0ch->qwc = 0; //? + psHu64(0x10004000) = 0; + psHu64(0x10004008) = 0; + vif0.done = 1; + vif0Regs->err = 0; + vif0Regs->stat&= ~(0xF000000|VIF0_STAT_INT|VIF0_STAT_VSS|VIF0_STAT_VIS|VIF0_STAT_VFS); // FQC=0 + } + if (value & 0x2) { + /* Force Break the VIF */ + /* I guess we should stop the VIF dma here + but not 100% sure (linuz) */ + vif0Regs->stat |= VIF0_STAT_VFS; + SysPrintf("vif0 force break\n"); + } + if (value & 0x4) { + /* Stop VIF */ + /* Not completly sure about this, can't remember what game + used this, but 'draining' the VIF helped it, instead of + just stoppin the VIF (linuz) */ + vif0Regs->stat |= VIF0_STAT_VSS; + //SysPrintf("Vif0 Stop\n"); + //dmaVIF0(); // Drain the VIF --- VIF Stops as not to outstrip dma source (refraction) + //FreezeXMMRegs(0); + } + if (value & 0x8) { + int cancel = 0; + + /* Cancel stall, first check if there is a stall to cancel, + and then clear VIF0_STAT VSS|VFS|VIS|INT|ER0|ER1 bits */ + if (vif0Regs->stat & (VIF0_STAT_VSS|VIF0_STAT_VIS|VIF0_STAT_VFS)) { + cancel = 1; + } + + vif0Regs->stat &= ~(VIF0_STAT_VSS | VIF0_STAT_VFS | VIF0_STAT_VIS | + VIF0_STAT_INT | VIF0_STAT_ER0 | VIF0_STAT_ER1); + if (cancel) { + //SysPrintf("VIF0 Stall Resume\n"); + if( vif0.vifstalled ) { + // loop necessary for spiderman + if(vif0.stallontag == 1){ + //SysPrintf("Sorting VIF0 Stall on tag\n"); + _chainVIF0(); + } else _VIF0chain(); + + vif0ch->chcr |= 0x100; + INT(0, g_vifCycles); // Gets the timing right - Flatout + } + } + } + } else + if (mem == 0x10003820) { // ERR +#ifdef VIF_LOG + VIF_LOG("VIF0_ERR write32 0x%8.8x\n", value); +#endif + /* Set VIF0_ERR with 'value' */ + vif0Regs->err = value; + } else{ + SysPrintf("Unknown Vif0 write to %x\n", mem); + if( mem >= 0x10003900 && mem < 0x10003980 ) { + + assert( (mem&0xf) == 0 ); + if( mem < 0x10003940 ) g_vifRow0[(mem>>4)&3] = value; + else g_vifCol0[(mem>>4)&3] = value; + } else psHu32(mem) = value; + } + + /* Other registers are read-only so do nothing for them */ +} + +void vif0Reset() { + /* Reset the whole VIF, meaning the internal pcsx2 vars + and all the registers */ + memset(&vif0, 0, sizeof(vif0)); + memset(vif0Regs, 0, sizeof(vif0Regs)); + SetNewMask(g_vif0Masks, g_vif0HasMask3, 0, 0xffffffff); + psHu64(0x10004000) = 0; + psHu64(0x10004008) = 0; + vif0.done = 1; + vif0Regs->stat&= ~0xF000000; // FQC=0 + //FreezeXMMRegs(0); + //FreezeMMXRegs(0); +} + +int vif0Freeze(gzFile f, int Mode) { + gzfreeze(&vif0, sizeof(vif0)); + if (Mode == 0) + SetNewMask(g_vif0Masks, g_vif0HasMask3, vif0Regs->mask, ~vif0Regs->mask); + + return 0; +} + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + + +void vif1Init() { + SetNewMask(g_vif1Masks, g_vif1HasMask3, 0, 0xffffffff); +} + +__inline void vif1UNPACK(u32 *data) { + int vifNum; + int vl, vn; + //int len; + if(vif1Regs->cycle.wl == 0){ + if(vif1Regs->cycle.wl < vif1Regs->cycle.cl){ + SysPrintf("Vif1 CL %d, WL %d\n", vif1Regs->cycle.cl, vif1Regs->cycle.wl); + vif1.cmd &= ~0x7f; + return; +} + } + vif1FLUSH(); + + vl = (vif1.cmd ) & 0x3; + vn = (vif1.cmd >> 2) & 0x3; + + vif1.usn = (vif1Regs->code >> 14) & 0x1; + vifNum = (vif1Regs->code >> 16) & 0xff; + if ( vifNum == 0 ) vifNum = 256; + vif1Regs->num = vifNum; + + if ( vif1Regs->cycle.wl <= vif1Regs->cycle.cl ) { + vif1.tag.size = ((( 32 >> vl ) * ( vn + 1 )) * vifNum + 31) >> 5; + } else { + int n = vif1Regs->cycle.cl * (vifNum / vif1Regs->cycle.wl) + + _limit( vifNum % vif1Regs->cycle.wl, vif1Regs->cycle.cl ); + vif1.tag.size = ( ((( 32 >> vl ) * ( vn + 1 )) * n) + 31 ) >> 5; + } + if ( ( vif1Regs->code >> 15) & 0x1 ) { + vif1.tag.addr = (vif1Regs->code + vif1Regs->tops) & 0x3ff; + } else vif1.tag.addr = vif1Regs->code & 0x3ff; + + //vif1.wl = 0; + vif1.cl = 0; + vif1.tag.addr <<= 4; + //if((vif1.tag.addr + (vifNum * 16)) > 0x4000) SysPrintf("Oops, Addr %x, NUM %x overlaps to %x\n", vif1.tag.addr, vifNum, (vif1.tag.addr + (vifNum * 16))); + + vif1.tag.cmd = vif1.cmd; + // vif1Regs->offset = 0; +} + +__inline void _vif1mpgTransfer(u32 addr, u32 *data, int size) { +/* SysPrintf("_vif1mpgTransfer addr=%x; size=%x\n", addr, size); + { + FILE *f = fopen("vu1.raw", "wb"); + fwrite(data, 1, size*4, f); + fclose(f); + }*/ + assert( VU1.Micro > 0 ); + if (memcmp(VU1.Micro + addr, data, size << 2)) { + FreezeMMXRegs(1); + memcpy_fast(VU1.Micro + addr, data, size << 2); + FreezeMMXRegs(0); + Cpu->ClearVU1(addr, size); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Vif1 Data Transfer Commands +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static int Vif1TransNull(u32 *data){ // Shouldnt go here + SysPrintf("Shouldnt go here CMD = %x\n", vif1Regs->code); + vif1.cmd = 0; + return 0; +} +static int Vif1TransSTMask(u32 *data){ // STMASK + SetNewMask(g_vif1Masks, g_vif1HasMask3, data[0], vif1Regs->mask); + vif1Regs->mask = data[0]; +#ifdef VIF_LOG + VIF_LOG("STMASK == %x\n", vif1Regs->mask); +#endif + vif1.tag.size = 0; + vif1.cmd = 0; + return 1; +} + +static int Vif1TransSTRow(u32 *data){ + int ret; + + u32* pmem = &vif1Regs->r0+(vif1.tag.addr<<2); + u32* pmem2 = g_vifRow1+vif1.tag.addr; + assert( vif1.tag.addr < 4 ); + ret = min(4-vif1.tag.addr, vif1.vifpacketsize); + assert( ret > 0 ); + switch(ret) { + case 4: pmem[12] = data[3]; pmem2[3] = data[3]; + case 3: pmem[8] = data[2]; pmem2[2] = data[2]; + case 2: pmem[4] = data[1]; pmem2[1] = data[1]; + case 1: pmem[0] = data[0]; pmem2[0] = data[0]; break; +#ifdef _MSC_VER + default: __assume(0); +#endif + } + vif1.tag.addr += ret; + vif1.tag.size -= ret; + if(vif1.tag.size == 0) vif1.cmd = 0; + + return ret; +} + +static int Vif1TransSTCol(u32 *data){ + int ret; + + u32* pmem = &vif1Regs->c0+(vif1.tag.addr<<2); + u32* pmem2 = g_vifCol1+vif1.tag.addr; + ret = min(4-vif1.tag.addr, vif1.vifpacketsize); + switch(ret) { + case 4: pmem[12] = data[3]; pmem2[3] = data[3]; + case 3: pmem[8] = data[2]; pmem2[2] = data[2]; + case 2: pmem[4] = data[1]; pmem2[1] = data[1]; + case 1: pmem[0] = data[0]; pmem2[0] = data[0]; break; +#ifdef _MSC_VER + default: __assume(0); +#endif + } + vif1.tag.addr += ret; + vif1.tag.size -= ret; + if(vif1.tag.size == 0) vif1.cmd = 0; + return ret; +} + +static int Vif1TransMPG(u32 *data){ + if (vif1.vifpacketsize < vif1.tag.size) { + _vif1mpgTransfer(vif1.tag.addr, data, vif1.vifpacketsize); + vif1.tag.addr += vif1.vifpacketsize << 2; + vif1.tag.size -= vif1.vifpacketsize; + return vif1.vifpacketsize; + } else { + int ret; + _vif1mpgTransfer(vif1.tag.addr, data, vif1.tag.size); + ret = vif1.tag.size; + vif1.tag.size = 0; + vif1.cmd = 0; + return ret; + } +} +u32 splittransfer[4]; +u32 splitptr = 0; + +static int Vif1TransDirectHL(u32 *data){ + int ret = 0; + + + if(splitptr > 0){ //Leftover data from the last packet, filling the rest and sending to the GS + if(splitptr < 4 && vif1.vifpacketsize >= (4-splitptr)){ + + while(splitptr < 4){ + splittransfer[splitptr++] = (u32)data++; + ret++; + vif1.tag.size--; + } + } + //if(splitptr < 4) SysPrintf("Whoopsie\n"); + if( CHECK_MULTIGS ) { + u8* gsmem = GSRingBufCopy((u32*)splittransfer[0], 16, GS_RINGTYPE_P2); + if( gsmem != NULL ) { + FreezeMMXRegs(1); + memcpy_fast(gsmem, (u32*)splittransfer[0], 16); + GSRINGBUF_DONECOPY(gsmem, 16); + GSgifTransferDummy(1, (u32*)splittransfer[0], 1); + } + FreezeMMXRegs(0); + if( !CHECK_DUALCORE ) GS_SETEVENT(); + } + else { + FreezeXMMRegs(1); + FreezeMMXRegs(1); + GSGIFTRANSFER2((u32*)splittransfer[0], 1); + FreezeMMXRegs(0); + FreezeXMMRegs(0); + } + + if(vif1.tag.size == 0) vif1.cmd = 0; + splitptr = 0; + return ret; + } + if (vif1.vifpacketsize < vif1.tag.size) { + if(vif1.vifpacketsize < 4 && splitptr != 4) { //Not a full QW left in the buffer, saving left over data + ret = vif1.vifpacketsize; + while(ret > 0){ + splittransfer[splitptr++] = (u32)data++; + vif1.tag.size--; + ret--; + } + //if(vif1.tag.size < 0) SysPrintf("Help\n"); + return vif1.vifpacketsize; + } //else if(vif1.vifpacketsize%4 != 0) SysPrintf("Size left = %x, non-qw aligned amount == %x\n", vif1.vifpacketsize, vif1.vifpacketsize%4); + + vif1.tag.size-= vif1.vifpacketsize; + ret = vif1.vifpacketsize; + } else { + ret = vif1.tag.size; + vif1.tag.size = 0; + vif1.cmd = 0; + } + + + + if( CHECK_MULTIGS ) { + u8* gsmem = GSRingBufCopy(data, ret<<2, GS_RINGTYPE_P2); + + if( gsmem != NULL ) { + FreezeMMXRegs(1); + memcpy_fast(gsmem, data, ret<<2); + FreezeMMXRegs(0); + GSRINGBUF_DONECOPY(gsmem, ret<<2); + GSgifTransferDummy(1, data, ret>>2); + } + + if( !CHECK_DUALCORE ) GS_SETEVENT(); + } + else { + + FreezeXMMRegs(1); + FreezeMMXRegs(1); + GSGIFTRANSFER2(data, (ret >> 2)); + FreezeMMXRegs(0); + FreezeXMMRegs(0); + } + + + return ret; +} + + +static int Vif1TransUnpack(u32 *data){ + + FreezeXMMRegs(1); + + if (vif1.vifpacketsize < vif1.tag.size) { + /* size is less that the total size, transfer is + 'in pieces' */ + VIFunpack(data, &vif1.tag, vif1.vifpacketsize, VIF1dmanum); + // g_vifCycles+= size >> 1; + //vif1.tag.addr += size << 2; + vif1.tag.size -= vif1.vifpacketsize; + FreezeXMMRegs(0); + return vif1.vifpacketsize; + } else { + int ret; + /* we got all the data, transfer it fully */ + VIFunpack(data, &vif1.tag, vif1.tag.size, VIF1dmanum); + //g_vifCycles+= vif1.tag.size >> 1; + ret = vif1.tag.size; + vif1.tag.size = 0; + vif1.cmd = 0; + FreezeXMMRegs(0); + return ret; + } + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Vif1 CMD Base Commands +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +int transferred = 0; +int Path3transfer=0; +static void Vif1CMDNop(){ // NOP + vif1.cmd &= ~0x7f; +} +static void Vif1CMDSTCycl(){ // STCYCL + vif1Regs->cycle.cl = (u8)vif1Regs->code; + vif1Regs->cycle.wl = (u8)(vif1Regs->code >> 8); + vif1.cmd &= ~0x7f; +} +static void Vif1CMDOffset(){ // OFFSET + vif1Regs->ofst = vif1Regs->code & 0x3ff; + vif1Regs->stat &= ~0x80; + vif1Regs->tops = vif1Regs->base; + vif1.cmd &= ~0x7f; +} +static void Vif1CMDBase(){ // BASE + vif1Regs->base = vif1Regs->code & 0x3ff; + vif1.cmd &= ~0x7f; +} +static void Vif1CMDITop(){ // ITOP + vif1Regs->itops = vif1Regs->code & 0x3ff; + vif1.cmd &= ~0x7f; +} + +static void Vif1CMDSTMod(){ // STMOD + vif1Regs->mode = vif1Regs->code & 0x3; + vif1.cmd &= ~0x7f; +} + +static void Vif1CMDMskPath3(){ // MSKPATH3 + + vif1Regs->mskpath3 = (vif1Regs->code >> 15) & 0x1; + //SysPrintf("VIF MSKPATH3 %x\n", vif1Regs->mskpath3); +#ifdef GSPATH3FIX + + if ( (vif1Regs->code >> 15) & 0x1 ) { + while((gif->chcr & 0x100)){ //Can be done 2 different ways, depends on the game/company + if(path3hack == 0)if(Path3transfer == 0 && gif->qwc == 0) break; + + gsInterrupt(); + + if(path3hack == 1)if(gif->qwc == 0) break; //add games not working with it to elfheader.c to enable this instead + } + //while(gif->chcr & 0x100) gsInterrupt(); // Finish the transfer first + psHu32(GIF_STAT) |= 0x2; + } else { + if(gif->chcr & 0x100) INT(2, (transferred>>2) * BIAS); // Restart Path3 on its own, time it right! + psHu32(GIF_STAT) &= ~0x2; + } +#else + if ( vif1Regs->mskpath3 ) { + if(gif->qwc) _GIFchain(); // Finish the transfer first + psHu32(GIF_STAT) |= 0x2; + } else { + psHu32(GIF_STAT) &= ~0x2; + if(gif->qwc) _GIFchain(); // Finish the transfer first + } +#endif + vif1.cmd &= ~0x7f; +} + +static void Vif1CMDMark(){ // MARK + vif1Regs->mark = (u16)vif1Regs->code; + vif1Regs->stat |= VIF1_STAT_MRK; + vif1.cmd &= ~0x7f; +} +static void Vif1CMDFlush(){ // FLUSH/E/A + + vif1FLUSH(); + + if((vif1.cmd & 0x7f) == 0x13) { + //SysPrintf("FlushA\n"); + while((gif->chcr & 0x100)){ + if(Path3transfer == 0 && gif->qwc == 0) break; + gsInterrupt(); + } + } + + vif1.cmd &= ~0x7f; +} +static void Vif1CMDMSCALF(){ //MSCAL/F + vuExecMicro( (u16)(vif1Regs->code) << 3, VIF1dmanum ); + vif1.cmd &= ~0x7f; +} +static void Vif1CMDMSCNT(){ // MSCNT + vuExecMicro( -1, VIF1dmanum ); + vif1.cmd &= ~0x7f; +} +static void Vif1CMDSTMask(){ // STMASK + vif1.tag.size = 1; +} +static void Vif1CMDSTRowCol(){// STROW / STCOL + vif1.tag.addr = 0; + vif1.tag.size = 4; +} + +static void Vif1CMDMPGTransfer(){ // MPG + int vifNum; + vif1FLUSH(); + vifNum = (u8)(vif1Regs->code >> 16); + if (vifNum == 0) vifNum = 256; + vif1.tag.addr = (u16)(vif1Regs->code) << 3; + vif1.tag.size = vifNum * 2; +} +static void Vif1CMDDirectHL(){ // DIRECT/HL + int vifImm; + vifImm = (u16)vif1Regs->code; + if (vifImm == 0) { + vif1.tag.size = 65536 << 2; + } else { + vif1.tag.size = vifImm << 2; + } + while((gif->chcr & 0x100) && (vif1.cmd & 0x7f) == 0x51){ + gsInterrupt(); //DirectHL flushes the lot + //if((psHu32(GIF_STAT) & 0xE00) == 0) break; + } +} +static void Vif1CMDNull(){ // invalid opcode + // if ME1, then force the vif to interrupt + + if ((vif1Regs->err & 0x4) == 0) { //Ignore vifcode and tag mismatch error + SysPrintf( "UNKNOWN VifCmd: %x\n", vif1.cmd ); + vif1Regs->stat |= 1 << 13; + vif1.irq++; + } + vif1.cmd = 0; +} + +// Vif1 Data Transfer Table + +int (*Vif1TransTLB[128])(u32 *data) = +{ + Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x7*/ + Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0xF*/ + Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x17*/ + Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x1F*/ + Vif1TransSTMask , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x27*/ + Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x2F*/ + Vif1TransSTRow , Vif1TransSTCol , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x37*/ + Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x3F*/ + Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x47*/ + Vif1TransNull , Vif1TransNull , Vif1TransMPG , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x4F*/ + Vif1TransDirectHL, Vif1TransDirectHL, Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x57*/ + Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , Vif1TransNull , /*0x5F*/ + Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransNull , /*0x67*/ + Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , /*0x6F*/ + Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransNull , /*0x77*/ + Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransNull , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack , Vif1TransUnpack /*0x7F*/ +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Vif1 CMD Table +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void (*Vif1CMDTLB[82])() = +{ + Vif1CMDNop , Vif1CMDSTCycl , Vif1CMDOffset , Vif1CMDBase , Vif1CMDITop , Vif1CMDSTMod , Vif1CMDMskPath3, Vif1CMDMark , /*0x7*/ + Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0xF*/ + Vif1CMDFlush , Vif1CMDFlush , Vif1CMDNull , Vif1CMDFlush, Vif1CMDMSCALF, Vif1CMDMSCALF, Vif1CMDNull , Vif1CMDMSCNT, /*0x17*/ + Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x1F*/ + Vif1CMDSTMask , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x27*/ + Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x2F*/ + Vif1CMDSTRowCol, Vif1CMDSTRowCol, Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x37*/ + Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x3F*/ + Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x47*/ + Vif1CMDNull , Vif1CMDNull , Vif1CMDMPGTransfer, Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , Vif1CMDNull , /*0x4F*/ + Vif1CMDDirectHL, Vif1CMDDirectHL +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +int VIF1transfer(u32 *data, int size, int istag) { + int ret; + transferred=vif1.vifstalled ? vif1.irqoffset : 0; // irqoffset necessary to add up the right qws, or else will spin (spiderman) + +#ifdef VIF_LOG + VIF_LOG( "VIF1transfer: size %x (vif1.cmd %x)\n", size, vif1.cmd ); +#endif + + + vif1.irqoffset = 0; + vif1.vifstalled = 0; + vif1.stallontag = 0; + vif1.vifpacketsize = size; + + //vif1.irq = 0; + while (vif1.vifpacketsize > 0) { + + if (vif1.cmd) { + //vif1Regs->stat |= VIF1_STAT_VPS_T; + ret = Vif1TransTLB[vif1.cmd](data); + data+= ret; vif1.vifpacketsize-= ret; + //vif1Regs->stat &= ~VIF1_STAT_VPS_T; + continue; + } + + if(vif1.tag.size != 0) SysPrintf("no vif1 cmd but tag size is left last cmd read %x\n", vif1Regs->code); + //vif1Regs->stat &= ~VIF1_STAT_VPS_W; + + //if(vif1.tag.size > 0) SysPrintf("VIF1 Tag size %x when cmd == 0!\n", vif1.tag.size); + + + if(vif1.irq) break; + + vif1.cmd = (data[0] >> 24); + vif1Regs->code = data[0]; + + + //vif1Regs->stat |= VIF1_STAT_VPS_D; + if ((vif1.cmd & 0x60) == 0x60) { + vif1UNPACK(data); + } else { +#ifdef VIF_LOG + VIF_LOG( "VIFtransfer: cmd %x, num %x, imm %x, size %x\n", vif1.cmd, (data[0] >> 16) & 0xff, data[0] & 0xffff, vif1.vifpacketsize ); +#endif + //vif1CMD(data, size); + /*if((vif1.cmd & 0x7f) > 0x51){ + if ((vif1Regs->err & 0x4) == 0) { //Ignore vifcode and tag mismatch error + SysPrintf( "UNKNOWN VifCmd: %x\n", vif1.cmd ); + vif1Regs->stat |= 1 << 13; + vif1.irq++; + } + vif1.cmd = 0; + } else*/ Vif1CMDTLB[(vif1.cmd & 0x7f)](); + } + //vif1Regs->stat &= ~VIF1_STAT_VPS_D; + //if(vif1.tag.size > 0) vif1Regs->stat |= VIF1_STAT_VPS_W; + ++data; + --vif1.vifpacketsize; + + if ((vif1.cmd & 0x80)) { //i bit on vifcode and not masked by VIF1_ERR +#ifdef VIF_LOG + VIF_LOG( "Interrupt on VIFcmd: %x (INTC_MASK = %x)\n", vif1.cmd, psHu32(INTC_MASK) ); +#endif + /*if((psHu32(DMAC_CTRL) & 0xC) == 0x8){ + SysPrintf("VIF1 Stall on MFIFO, not implemented!\n"); + }*/ + + if(!(vif1Regs->err & 0x1)){ + ++vif1.irq; + if(istag && vif1.tag.size <= vif1.vifpacketsize) vif1.stallontag = 1; + } + vif1.cmd &= 0x7f; + } + } + //if(vif1.cmd != 0 && vif1.tag.size == 0) SysPrintf("cmd but no tag size is left %x\n", vif1.cmd); + //if(vif1.cmd == 0 && vif1.tag.size != 0) SysPrintf("no cmd but tag size is left last cmd read %x\n", vif1Regs->code); + transferred += size - vif1.vifpacketsize; + g_vifCycles+= (transferred>>2)*BIAS; /* guessing */ + // use tag.size because some game doesn't like .cmd + //if( !vif1.cmd ) + //if( !vif1.tag.size ) + // vif1Regs->stat &= ~VIF1_STAT_VPS_W; + + if (vif1.irq && vif1.tag.size == 0) { + vif1.vifstalled = 1; + if(((vif1Regs->code >> 24) & 0x7f) != 0x7)vif1Regs->stat|= VIF1_STAT_VIS; + //else SysPrintf("Stall on Vif1 MARK\n"); + // spiderman doesn't break on qw boundaries + vif1.irqoffset = transferred%4; // cannot lose the offset + + if( istag ) { + return -2; + } + + transferred = transferred >> 2; + vif1ch->madr+= (transferred << 4); + vif1ch->qwc-= transferred; + //SysPrintf("Stall on vif1, FromSPR = %x, Vif1MADR = %x Sif0MADR = %x STADR = %x\n", psHu32(0x1000d010), vif1ch->madr, psHu32(0x1000c010), psHu32(DMAC_STADR)); + return -2; + } + + + if( !istag ) { + /*if(transferred & 0x3) vif1.irqoffset = transferred%4; + else vif1.irqoffset = 0;*/ + + transferred = transferred >> 2; + vif1ch->madr+= (transferred << 4); + vif1ch->qwc-= transferred; + + //if(vif1ch->qwc > 0 && size != 0) vif1.vifstalled = 1; + + } + + + return 0; +} + +int _VIF1chain() { + u32 *pMem; + u32 qwc = vif1ch->qwc; + u32 ret; + + + if (vif1ch->qwc == 0 && vif1.vifstalled == 0) return 0; + + pMem = (u32*)dmaGetAddr(vif1ch->madr); + if (pMem == NULL) + return -1; + +#ifdef VIF_LOG + VIF_LOG("dmaChain size=%d, madr=%lx, tadr=%lx\n", + vif1ch->qwc, vif1ch->madr, vif1ch->tadr); +#endif + if( vif1.vifstalled ) { + ret = VIF1transfer(pMem+vif1.irqoffset, vif1ch->qwc*4-vif1.irqoffset, 0); + } + else { + ret = VIF1transfer(pMem, vif1ch->qwc*4, 0); + } + /*vif1ch->madr+= (vif1ch->qwc << 4); + vif1ch->qwc-= qwc;*/ + + return ret; +} + +static int prevvifcycles = 0; +static u32* prevviftag = NULL; +u32 *vifptag; +int _chainVIF1() { + int id; + //int done=0; + int ret; + //g_vifCycles = prevvifcycles; + + vifptag = (u32*)dmaGetAddr(vif1ch->tadr); //Set memory pointer to TADR + if (vifptag == NULL) { //Is ptag empty? + SysPrintf("Vif1 Tag BUSERR\n"); + vif1ch->chcr = ( vif1ch->chcr & 0xFFFF ) | ( (*vifptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 + psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register + return -1; //Return -1 as an error has occurred + } + + id = (vifptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag + vif1ch->qwc = (u16)vifptag[0]; //QWC set to lower 16bits of the tag + vif1ch->madr = vifptag[1]; //MADR = ADDR field + g_vifCycles+=1; // Add 1 g_vifCycles from the QW read for the tag + + vif1ch->chcr = ( vif1ch->chcr & 0xFFFF ) | ( (*vifptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 + // Transfer dma tag if tte is set + + + + + +#ifdef VIF_LOG + VIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n", + vifptag[1], vifptag[0], vif1ch->qwc, id, vif1ch->madr, vif1ch->tadr); +#endif + + + //} else + + + if (!vif1.done && (psHu32(DMAC_CTRL) & 0xC0) == 0x40 && id == 4) { // STD == VIF1 + //vif1.done |= hwDmacSrcChainWithStack(vif1ch, id); + // there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall + if( (vif1ch->madr + vif1ch->qwc * 16) >= psHu32(DMAC_STADR) ) { + // stalled + + //SysPrintf("Vif1 Stalling %x, %x, DMA_CTRL = %x\n",vif1ch->madr, psHu32(DMAC_STADR), psHu32(DMAC_CTRL)); + /*prevvifcycles = g_vifCycles; + prevviftag = vifptag;*/ + hwDmacIrq(13); + //vif1ch->tadr -= 16; + return 0; + } + } + //prevvifcycles = 0; + + if (vif1ch->chcr & 0x40) { + if(vif1.vifstalled == 1) ret = VIF1transfer(vifptag+(2+vif1.irqoffset), 2-vif1.irqoffset, 1); //Transfer Tag on stall + else ret = VIF1transfer(vifptag+2, 2, 1); //Transfer Tag + if (ret == -1) return -1; //There has been an error + if (ret == -2) { + //if(vif1.tag.size > 0)SysPrintf("VIF1 Stall on tag %x code %x\n", vif1.irqoffset, vif1Regs->code); + return 0; //IRQ set by VIFTransfer + } + } + //if((psHu32(DMAC_CTRL) & 0xC0) != 0x40 || id != 4) + vif1.done |= hwDmacSrcChainWithStack(vif1ch, id); + +#ifdef VIF_LOG + VIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n", + vifptag[1], vifptag[0], vif1ch->qwc, id, vif1ch->madr, vif1ch->tadr); +#endif + + //done |= hwDmacSrcChainWithStack(vif1ch, id); + ret = _VIF1chain(); //Transfers the data set by the switch + //if (ret == -1) { return -1; } //There's been an error + //if (ret == -2) { //IRQ has been set by VifTransfer + // return 0; + //} + + + if ((vif1ch->chcr & 0x80) && (vifptag[0] >> 31)) { //Check TIE bit of CHCR and IRQ bit of tag +#ifdef VIF_LOG + VIF_LOG( "dmaIrq Set\n" ); +#endif + //SysPrintf("VIF1 TIE\n"); + //SysPrintf( "VIF1dmaIrq Set\n" ); + //vif1ch->qwc = 0; + //vif1Regs->stat|= VIF1_STAT_VIS; //Set the Tag Interrupt flag of VIF1_STAT + vif1.done = 1; + return 0; //End Transfer + } + return vif1.done; //Return Done +} + +void vif1Interrupt() { + +#ifdef VIF_LOG + VIF_LOG("vif1Interrupt: %8.8x\n", cpuRegs.cycle); +#endif + + g_vifCycles = 0; + + //if(vif1.vifstalled == 1) { + if(vif1.irq && vif1.tag.size == 0) { + vif1Regs->stat|= VIF1_STAT_INT; + hwIntcIrq(VIF1intc); + --vif1.irq; + if(vif1Regs->stat & (VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS)) + { + vif1Regs->stat&= ~0x1F000000; // FQC=0 + // One game doesnt like vif stalling at end, cant remember what. Spiderman isnt keen on it tho + vif1ch->chcr &= ~0x100; + cpuRegs.interrupt &= ~(1 << 1); + return; + } + //return 0; + if(vif1ch->qwc > 0 || vif1.irqoffset > 0){ + if(vif1.stallontag == 1) { + _chainVIF1(); + } + else _VIF1chain(); + INT(1, g_vifCycles); + return; + } + } + + + //} + if((vif1ch->chcr & 0x100) == 0) { + SysPrintf("Vif1 running when CHCR == %x\n", vif1ch->chcr); + /*prevviftag = NULL; + prevvifcycles = 0; + vif1ch->chcr &= ~0x100; + hwDmacIrq(DMAC_VIF1); + hwIntcIrq(VIF1intc); + vif1Regs->stat&= ~0x1F000000; // FQC=0 + return 1;*/ + } + /*if(vif1ch->qwc > 0){ + _VIF1chain(); + INT(1, g_vifCycles); + return 0; + }*/ + if ((vif1ch->chcr & 0x104) == 0x104 && vif1.done == 0) { + + if( !(psHu32(DMAC_CTRL) & 0x1) ) { + SysPrintf("vif1 dma masked\n"); + return; + } + + _chainVIF1(); + INT(1, g_vifCycles); + + return; + } + if(vif1ch->qwc > 0) SysPrintf("VIF1 Ending with QWC left\n"); + if(vif1.cmd != 0) SysPrintf("vif1.cmd still set %x\n", vif1.cmd); + //SysPrintf("VIF Interrupt\n"); + //if((gif->chcr & 0x100) && vif1Regs->mskpath3) gsInterrupt(); + prevviftag = NULL; + prevvifcycles = 0; + + vif1ch->chcr &= ~0x100; + hwDmacIrq(DMAC_VIF1); + if(vif1Regs->mskpath3 == 0 || (vif1ch->chcr & 0x1) == 0x1)vif1Regs->stat&= ~0x1F000000; // FQC=0 + + cpuRegs.interrupt &= ~(1 << 1); +} + +extern void gsWaitGS(); +extern u32 g_MTGSVifStart, g_MTGSVifCount; +#define spr0 ((DMACh*)&PS2MEM_HW[0xD000]) +void dmaVIF1() +{ + +#ifdef VIF_LOG + VIF_LOG("dmaVIF1 chcr = %lx, madr = %lx, qwc = %lx\n" + " tadr = %lx, asr0 = %lx, asr1 = %lx\n", + vif1ch->chcr, vif1ch->madr, vif1ch->qwc, + vif1ch->tadr, vif1ch->asr0, vif1ch->asr1 ); +#endif + + /*if ((psHu32(DMAC_CTRL) & 0xC0)) { + SysPrintf("DMA Stall Control %x\n",(psHu32(DMAC_CTRL) & 0xC0)); + }*/ + /* Check if there is a pending irq */ + /*if (vif1.irq > 0) { + vif1.irq--; + hwIntcIrq(VIF1intc); + return; + }*/ +// if(vif1ch->qwc > 0) { +// _VIF1chain(); +// INT(1, g_vifCycles); +// } + vif1.done = 0; + g_vifCycles = 0; + + /*if( prevvifcycles != 0 ) { + int stallret = 0; + assert( prevviftag != NULL ); + + vifptag = prevviftag; + // transfer interrupted, so continue + //_VIF1chain(); + _chainVIF1(); + + if (vif1ch->chcr & 0x80 && vifptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag +#ifdef VIF_LOG + VIF_LOG("dmaIrq Set\n"); +#endif + vif1.done = 1; + INT(1, g_vifCycles); + return; + } + //vif1.done = 1; + INT(1, g_vifCycles); + return; + }*/ + + if (((psHu32(DMAC_CTRL) & 0xC) == 0x8)) { // VIF MFIFO + //SysPrintf("VIFMFIFO\n"); + if(!(vif1ch->chcr & 0x4)) SysPrintf("MFIFO mode != Chain! %x\n", vif1ch->chcr); + if(vif1ch->madr != spr0->madr)vifMFIFOInterrupt(); + return; + } + +#ifdef PCSX2_DEVBUILD + if ((psHu32(DMAC_CTRL) & 0xC0) == 0x40) { // STD == VIF1 + //SysPrintf("VIF Stall Control Source = %x, Drain = %x\n", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3); + //return; + } +#endif + + + vif1Regs->stat|= 0x10000000; // FQC=16 + + if (!(vif1ch->chcr & 0x4) || vif1ch->qwc > 0) { // Normal Mode + if ((psHu32(DMAC_CTRL) & 0xC0) == 0x40) { + SysPrintf("DMA Stall Control on VIF1 normal\n"); + } + if ((vif1ch->chcr & 0x1)) { // to Memory + if(_VIF1chain() == -2) { + SysPrintf("Stall on normal\n"); + vif1.vifstalled = 1; + return; + } + INT(1, g_vifCycles); + } else { // from Memory + + + + if( CHECK_MULTIGS ) { + u8* pTempMem, *pEndMem; + + u8* pMem = GSRingBufCopy(NULL, 0, GS_RINGTYPE_VIFFIFO); + *(u32*)(pMem-16) = GS_RINGTYPE_VIFFIFO|(vif1ch->qwc<<16); // hack + *(u32*)(pMem-12) = vif1ch->madr; + *(u32*)(pMem-8) = cpuRegs.cycle; + + // touch all the pages to make sure they are in memory + pTempMem = dmaGetAddr(vif1ch->madr); + pEndMem = (u8*)((uptr)(pTempMem + vif1ch->qwc*16 + 0xfff)&~0xfff); + pTempMem = (u8*)((uptr)pTempMem&~0xfff); + while(pTempMem < pEndMem ) { + pTempMem[0]++; + pTempMem[0]--; + pTempMem += 0x1000; + } + + GSRINGBUF_DONECOPY(pMem, 0); + + if( !CHECK_DUALCORE ) + GS_SETEVENT(); + + g_MTGSVifStart = cpuRegs.cycle; + g_MTGSVifCount = 4000000; // a little less than 1/60th of a second + + // wait is, the safest option + //gsWaitGS(); + //SysPrintf("waiting for gs\n"); + } + else { + + int size; + u64* pMem = (u64*)dmaGetAddr(vif1ch->madr); + if (pMem == NULL) { //Is ptag empty? + SysPrintf("Vif1 Tag BUSERR\n"); + psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register + vif1.done = 1; + vif1Regs->stat&= ~0x1f000000; + vif1ch->qwc = 0; + INT(1, g_vifCycles); + + return; //Return -1 as an error has occurred + } + FreezeXMMRegs(1); + if( GSreadFIFO2 == NULL ) { + for (size=vif1ch->qwc; size>0; --size) { + if (size > 1) GSreadFIFO((u64*)&PS2MEM_HW[0x5000]); + pMem[0] = psHu64(0x5000); + pMem[1] = psHu64(0x5008); pMem+= 2; + } + } + else { + GSreadFIFO2(pMem, vif1ch->qwc); + + // set incase read + psHu64(0x5000) = pMem[2*vif1ch->qwc-2]; + psHu64(0x5008) = pMem[2*vif1ch->qwc-1]; + } + FreezeXMMRegs(0); + + + if(vif1Regs->mskpath3 == 0)vif1Regs->stat&= ~0x1f000000; + g_vifCycles += vif1ch->qwc * 2; + vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes + vif1ch->qwc = 0; + INT(1, g_vifCycles); + } + + } + + vif1.done = 1; + return; + } + +/* if (_VIF1chain() != 0) { + INT(1, g_vifCycles); + return; + }*/ + + // Chain Mode + vif1.done = 0; + INT(1, g_vifCycles); +} + + +void vif1Write32(u32 mem, u32 value) { + if (mem == 0x10003c30) { // MARK +#ifdef VIF_LOG + VIF_LOG("VIF1_MARK write32 0x%8.8x\n", value); +#endif + /* Clear mark flag in VIF1_STAT and set mark with 'value' */ + vif1Regs->stat&= ~VIF1_STAT_MRK; + vif1Regs->mark = value; + } else + if (mem == 0x10003c10) { // FBRST +#ifdef VIF_LOG + VIF_LOG("VIF1_FBRST write32 0x%8.8x\n", value); +#endif + if (value & 0x1) { + /* Reset VIF */ + //SysPrintf("Vif1 Reset %x\n", vif1Regs->stat); + memset(&vif1, 0, sizeof(vif1)); + vif1ch->qwc = 0; //? + psHu64(0x10005000) = 0; + psHu64(0x10005008) = 0; + vif1.done = 1; + vif1Regs->err = 0; + vif1Regs->stat&= ~(0x1F800000|VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS); // FQC=0 + } + if (value & 0x2) { + /* Force Break the VIF */ + /* I guess we should stop the VIF dma here + but not 100% sure (linuz) */ + vif1Regs->stat |= VIF1_STAT_VFS; + cpuRegs.interrupt &= ~0x402; + vif1.vifstalled = 1; + SysPrintf("vif1 force break\n"); + } + if (value & 0x4) { + /* Stop VIF */ + /* Not completly sure about this, can't remember what game + used this, but 'draining' the VIF helped it, instead of + just stoppin the VIF (linuz) */ + vif1Regs->stat |= VIF1_STAT_VSS; + vif1.vifstalled = 1; + //SysPrintf("Vif1 Stop\n"); + //dmaVIF1(); // Drain the VIF --- VIF Stops as not to outstrip dma source (refraction) + //FreezeXMMRegs(0); + } + if (value & 0x8) { + int cancel = 0; + + /* Cancel stall, first check if there is a stall to cancel, + and then clear VIF1_STAT VSS|VFS|VIS|INT|ER0|ER1 bits */ + if (vif1Regs->stat & (VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS)) { + cancel = 1; + } + + vif1Regs->stat &= ~(VIF1_STAT_VSS | VIF1_STAT_VFS | VIF1_STAT_VIS | + VIF1_STAT_INT | VIF1_STAT_ER0 | VIF1_STAT_ER1); + if (cancel) { + //SysPrintf("VIF1 Stall Resume\n"); + if( vif1.vifstalled ) { + // loop necessary for spiderman + if((psHu32(DMAC_CTRL) & 0xC) == 0x8){ + //vif1.vifstalled = 0; + //SysPrintf("MFIFO Stall\n"); + INT(10, 0); + }else { + if(vif1.stallontag == 1){ + //SysPrintf("Sorting VIF Stall on tag\n"); + _chainVIF1(); + } else _VIF1chain(); + //vif1.vifstalled = 0' + INT(1, g_vifCycles); // Gets the timing right - Flatout + } + vif1ch->chcr |= 0x100; + } + } + } + } else + if (mem == 0x10003c20) { // ERR +#ifdef VIF_LOG + VIF_LOG("VIF1_ERR write32 0x%8.8x\n", value); +#endif + /* Set VIF1_ERR with 'value' */ + vif1Regs->err = value; + } else + if (mem == 0x10003c00) { // STAT +#ifdef VIF_LOG + VIF_LOG("VIF1_STAT write32 0x%8.8x\n", value); +#endif + +#ifdef PCSX2_DEVBUILD + /* Only FDR bit is writable, so mask the rest */ + if( (vif1Regs->stat & VIF1_STAT_FDR) ^ (value & VIF1_STAT_FDR) ) { + // different so can't be stalled + if (vif1Regs->stat & (VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS)) { + SysPrintf("changing dir when vif1 fifo stalled\n"); + } + } +#endif + + vif1Regs->stat = (vif1Regs->stat & ~VIF1_STAT_FDR) | (value & VIF1_STAT_FDR); + if (vif1Regs->stat & VIF1_STAT_FDR) { + vif1Regs->stat|= 0x01000000; + } else { + vif1ch->qwc = 0; + vif1.vifstalled = 0; + vif1.done = 1; + vif1Regs->stat&= ~0x1F000000; // FQC=0 + } + } + else + if (mem == 0x10003c50) { // MODE + vif1Regs->mode = value; + } + else { + SysPrintf("Unknown Vif1 write to %x\n", mem); + if( mem >= 0x10003d00 && mem < 0x10003d80 ) { + assert( (mem&0xf) == 0 ); + if( mem < 0x10003d40) g_vifRow1[(mem>>4)&3] = value; + else g_vifCol1[(mem>>4)&3] = value; + } else psHu32(mem) = value; + } + + /* Other registers are read-only so do nothing for them */ +} + +void vif1Reset() { + /* Reset the whole VIF, meaning the internal pcsx2 vars + and all the registers */ + memset(&vif1, 0, sizeof(vif1)); + memset(vif1Regs, 0, sizeof(vif1Regs)); + SetNewMask(g_vif1Masks, g_vif1HasMask3, 0, 0xffffffff); + psHu64(0x10005000) = 0; + psHu64(0x10005008) = 0; + vif1.done = 1; + vif1Regs->stat&= ~0x1F000000; // FQC=0 + /*FreezeXMMRegs(0); + FreezeMMXRegs(0);*/ +} + +int vif1Freeze(gzFile f, int Mode) { + gzfreeze(&vif1, sizeof(vif1)); + if (Mode == 0) + SetNewMask(g_vif1Masks, g_vif1HasMask3, vif1Regs->mask, ~vif1Regs->mask); + + return 0; +} diff --git a/pcsx2/VifDma.h b/pcsx2/VifDma.h index e5b31c0..a9f1936 100644 --- a/pcsx2/VifDma.h +++ b/pcsx2/VifDma.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __VIFDMA_H__ #define __VIFDMA_H__ diff --git a/pcsx2/cheatscpp.h b/pcsx2/cheatscpp.h index 0918189..3a8ac28 100644 --- a/pcsx2/cheatscpp.h +++ b/pcsx2/cheatscpp.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef CHEATSCPP_H_INCLUDED #define CHEATSCPP_H_INCLUDED diff --git a/pcsx2/windows/AboutDlg.c b/pcsx2/windows/AboutDlg.c index 56b9d48..8f72699 100644 --- a/pcsx2/windows/AboutDlg.c +++ b/pcsx2/windows/AboutDlg.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/windows/AboutDlg.h b/pcsx2/windows/AboutDlg.h index 1a209be..5807d5b 100644 --- a/pcsx2/windows/AboutDlg.h +++ b/pcsx2/windows/AboutDlg.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef _PCSX2_ABOUTDLG_H_ diff --git a/pcsx2/windows/ConfigDlg.c b/pcsx2/windows/ConfigDlg.c index b311cf7..8ea3fae 100644 --- a/pcsx2/windows/ConfigDlg.c +++ b/pcsx2/windows/ConfigDlg.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/windows/CpuDlg.c b/pcsx2/windows/CpuDlg.c index 32598fe..ea4b75d 100644 --- a/pcsx2/windows/CpuDlg.c +++ b/pcsx2/windows/CpuDlg.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2004 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/windows/DebugMemory.c b/pcsx2/windows/DebugMemory.c index f033bc7..a8c8975 100644 --- a/pcsx2/windows/DebugMemory.c +++ b/pcsx2/windows/DebugMemory.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include "Common.h" diff --git a/pcsx2/windows/Debugger.c b/pcsx2/windows/Debugger.c index e3d492b..ec14147 100644 --- a/pcsx2/windows/Debugger.c +++ b/pcsx2/windows/Debugger.c @@ -1,21 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/windows/Debugger.h b/pcsx2/windows/Debugger.h index d4e3d20..babd8a2 100644 --- a/pcsx2/windows/Debugger.h +++ b/pcsx2/windows/Debugger.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/pcsx2/windows/Debugreg.c b/pcsx2/windows/Debugreg.c index 3edc325..f73700c 100644 --- a/pcsx2/windows/Debugreg.c +++ b/pcsx2/windows/Debugreg.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #define WINVER 0x0500 #include diff --git a/pcsx2/windows/McdsDlg.c b/pcsx2/windows/McdsDlg.c index f425919..bb88b6f 100644 --- a/pcsx2/windows/McdsDlg.c +++ b/pcsx2/windows/McdsDlg.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2004 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/windows/McdsDlg.cpp b/pcsx2/windows/McdsDlg.cpp index e6361ad..d91dff8 100644 --- a/pcsx2/windows/McdsDlg.cpp +++ b/pcsx2/windows/McdsDlg.cpp @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2004 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include diff --git a/pcsx2/windows/McdsDlg.h b/pcsx2/windows/McdsDlg.h index c911430..756100a 100644 --- a/pcsx2/windows/McdsDlg.h +++ b/pcsx2/windows/McdsDlg.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2004 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __MCDSDLG_H__ diff --git a/pcsx2/windows/PatchBrowser.c b/pcsx2/windows/PatchBrowser.c index ec664c7..e2c9fd7 100644 --- a/pcsx2/windows/PatchBrowser.c +++ b/pcsx2/windows/PatchBrowser.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + /************************** * diff --git a/pcsx2/windows/RDebugger.c b/pcsx2/windows/RDebugger.c index 576cc57..2e091a0 100644 --- a/pcsx2/windows/RDebugger.c +++ b/pcsx2/windows/RDebugger.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + #include #include diff --git a/pcsx2/windows/RDebugger.h b/pcsx2/windows/RDebugger.h index eb7ae63..b61fe7c 100644 --- a/pcsx2/windows/RDebugger.h +++ b/pcsx2/windows/RDebugger.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/pcsx2/windows/VCprojects/pcsx2_2005.vcproj b/pcsx2/windows/VCprojects/pcsx2_2005.vcproj index a7e4bce..8459d73 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2005.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2005.vcproj @@ -5,7 +5,6 @@ Name="pcsx2" ProjectGUID="{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}" RootNamespace="pcsx2" - TargetFrameworkVersion="131072" > + + + + + #include #include diff --git a/pcsx2/windows/cheats/cheats.cpp b/pcsx2/windows/cheats/cheats.cpp index b913908..da03879 100644 --- a/pcsx2/windows/cheats/cheats.cpp +++ b/pcsx2/windows/cheats/cheats.cpp @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include #include diff --git a/pcsx2/windows/cheats/cheats.h b/pcsx2/windows/cheats/cheats.h index e4242da..80040f8 100644 --- a/pcsx2/windows/cheats/cheats.h +++ b/pcsx2/windows/cheats/cheats.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef CHEATS_H_INCLUDED #define CHEATS_H_INCLUDED diff --git a/pcsx2/windows/ini.c b/pcsx2/windows/ini.c index ae5a9b6..7c2430b 100644 --- a/pcsx2/windows/ini.c +++ b/pcsx2/windows/ini.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + /* 15-09-2004 : file rewriten for work with inis (shadow) */ diff --git a/pcsx2/windows/mingw/pcsx2_private.h b/pcsx2/windows/mingw/pcsx2_private.h index 38d3841..2e8cf9d 100644 --- a/pcsx2/windows/mingw/pcsx2_private.h +++ b/pcsx2/windows/mingw/pcsx2_private.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */ /* DO NOT EDIT ! */ diff --git a/pcsx2/x86/aVif.asm b/pcsx2/x86/aVif.asm index 01c873b..d23423d 100644 --- a/pcsx2/x86/aVif.asm +++ b/pcsx2/x86/aVif.asm @@ -1,5 +1,5 @@ ; Pcsx2 - Pc Ps2 Emulator -; Copyright (C) 2002-2007 Pcsx2 Team +; Copyright (C) 2002-2008 Pcsx2 Team ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software -; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ;; Fast VIF assembly routines for UNPACK zerofrog(@gmail.com) ;; NOTE: This file is used to build aVif_proc-[32/64].asm because ml has a very diff --git a/pcsx2/x86/iCOP2.c b/pcsx2/x86/iCOP2.c index cac6a9d..0ec5a9a 100644 --- a/pcsx2/x86/iCOP2.c +++ b/pcsx2/x86/iCOP2.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/iCP0.c b/pcsx2/x86/iCP0.c index 99a626d..c97a0a1 100644 --- a/pcsx2/x86/iCP0.c +++ b/pcsx2/x86/iCP0.c @@ -1,20 +1,21 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ + #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) #include "Common.h" diff --git a/pcsx2/x86/iCP0.h b/pcsx2/x86/iCP0.h index 5ee0203..b1b6a21 100644 --- a/pcsx2/x86/iCP0.h +++ b/pcsx2/x86/iCP0.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __ICP0_H__ diff --git a/pcsx2/x86/iCore.cpp b/pcsx2/x86/iCore.cpp index eb42076..2cf5843 100644 --- a/pcsx2/x86/iCore.cpp +++ b/pcsx2/x86/iCore.cpp @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/iCore.h b/pcsx2/x86/iCore.h index 9720fd6..0c0f194 100644 --- a/pcsx2/x86/iCore.h +++ b/pcsx2/x86/iCore.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ // NOTE: x86-64 recompiler doesn't support mmx diff --git a/pcsx2/x86/iFPU.c b/pcsx2/x86/iFPU.c index 37f9bd2..25f8d22 100644 --- a/pcsx2/x86/iFPU.c +++ b/pcsx2/x86/iFPU.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/iFPU.h b/pcsx2/x86/iFPU.h index 0d94bff..d9c85aa 100644 --- a/pcsx2/x86/iFPU.h +++ b/pcsx2/x86/iFPU.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __IFPU_H__ diff --git a/pcsx2/x86/iGS.cpp b/pcsx2/x86/iGS.cpp index df2c245..b67f6c5 100644 --- a/pcsx2/x86/iGS.cpp +++ b/pcsx2/x86/iGS.cpp @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2007 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ // stop compiling if NORECBUILD build (only for Visual Studio) diff --git a/pcsx2/x86/iHw.c b/pcsx2/x86/iHw.c index b3178e2..498ad1e 100644 --- a/pcsx2/x86/iHw.c +++ b/pcsx2/x86/iHw.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2007 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ // stop compiling if NORECBUILD build (only for Visual Studio) @@ -37,7 +37,7 @@ extern u32 *psHL; extern u64 *psHD; #endif -extern int rdram_devices; // put 8 for TOOL and 2 for PS2 and PSX +extern int rdram_devices; // put 8 for TOOL and 2 for PS2 and PSX extern int rdram_sdevid; extern char sio_buffer[1024]; extern int sio_count; @@ -261,23 +261,23 @@ void iMemRead32Check() int hwContRead32_f440() { - if ((psHu32(0xf430) >> 6) & 0xF) - return 0; - else - switch ((psHu32(0xf430)>>16) & 0xFFF){//MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 - case 0x21://INIT - { - int ret = 0x1F * (rdram_sdevid < rdram_devices); - rdram_sdevid += (rdram_sdevid < rdram_devices); - return ret; - } - case 0x23://CNFGA - return 0x0D0D; //PVER=3 | MVER=16 | DBL=1 | REFBIT=5 - case 0x24://CNFGB - //0x0110 for PSX SVER=0 | CORG=8(5x9x7) | SPT=1 | DEVTYP=0 | BYTE=0 - return 0x0090; //SVER=0 | CORG=4(5x9x6) | SPT=1 | DEVTYP=0 | BYTE=0 - case 0x40://DEVID - return psHu32(0xf430) & 0x1F; // =SDEV + if ((psHu32(0xf430) >> 6) & 0xF) + return 0; + else + switch ((psHu32(0xf430)>>16) & 0xFFF){//MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 + case 0x21://INIT + { + int ret = 0x1F * (rdram_sdevid < rdram_devices); + rdram_sdevid += (rdram_sdevid < rdram_devices); + return ret; + } + case 0x23://CNFGA + return 0x0D0D; //PVER=3 | MVER=16 | DBL=1 | REFBIT=5 + case 0x24://CNFGB + //0x0110 for PSX SVER=0 | CORG=8(5x9x7) | SPT=1 | DEVTYP=0 | BYTE=0 + return 0x0090; //SVER=0 | CORG=4(5x9x6) | SPT=1 | DEVTYP=0 | BYTE=0 + case 0x40://DEVID + return psHu32(0xf430) & 0x1F; // =SDEV } return 0; @@ -1033,38 +1033,38 @@ void hwConstWrite32(u32 mem, int mmreg) case 0x1000f410: break; - case 0x1000f430://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 - - //if ((((value >> 16) & 0xFFF) == 0x21) && (((value >> 6) & 0xF) == 1) && (((psHu32(0xf440) >> 7) & 1) == 0))//INIT & SRP=0 - // rdram_sdevid = 0 - _eeMoveMMREGtoR(EAX, mmreg); - MOV32RtoR(EDX, EAX); - MOV32RtoR(ECX, EAX); - SHR32ItoR(EAX, 6); - SHR32ItoR(EDX, 16); - AND32ItoR(EAX, 0xf); - AND32ItoR(EDX, 0xfff); - CMP32ItoR(EAX, 1); - j8Ptr[5] = JNE8(0); - CMP32ItoR(EDX, 0x21); - j8Ptr[6] = JNE8(0); - - TEST32ItoM((uptr)&psHu32(0xf440), 0x80); - j8Ptr[7] = JNZ8(0); - - // if SIO repeater is cleared, reset sdevid - MOV32ItoM((uptr)&rdram_sdevid, 0); - - //kill the busy bit - x86SetJ8(j8Ptr[5]); - x86SetJ8(j8Ptr[6]); - x86SetJ8(j8Ptr[7]); - AND32ItoR(ECX, ~0x80000000); - MOV32RtoM((uptr)&psHu32(0xf430), ECX); - break; - - case 0x1000f440://MCH_DRD: - _eeWriteConstMem32((uptr)&PS2MEM_HW[0xf440], mmreg); + case 0x1000f430://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 + + //if ((((value >> 16) & 0xFFF) == 0x21) && (((value >> 6) & 0xF) == 1) && (((psHu32(0xf440) >> 7) & 1) == 0))//INIT & SRP=0 + // rdram_sdevid = 0 + _eeMoveMMREGtoR(EAX, mmreg); + MOV32RtoR(EDX, EAX); + MOV32RtoR(ECX, EAX); + SHR32ItoR(EAX, 6); + SHR32ItoR(EDX, 16); + AND32ItoR(EAX, 0xf); + AND32ItoR(EDX, 0xfff); + CMP32ItoR(EAX, 1); + j8Ptr[5] = JNE8(0); + CMP32ItoR(EDX, 0x21); + j8Ptr[6] = JNE8(0); + + TEST32ItoM((uptr)&psHu32(0xf440), 0x80); + j8Ptr[7] = JNZ8(0); + + // if SIO repeater is cleared, reset sdevid + MOV32ItoM((uptr)&rdram_sdevid, 0); + + //kill the busy bit + x86SetJ8(j8Ptr[5]); + x86SetJ8(j8Ptr[6]); + x86SetJ8(j8Ptr[7]); + AND32ItoR(ECX, ~0x80000000); + MOV32RtoM((uptr)&psHu32(0xf430), ECX); + break; + + case 0x1000f440://MCH_DRD: + _eeWriteConstMem32((uptr)&PS2MEM_HW[0xf440], mmreg); break; case 0x1000f590: // DMAC_ENABLEW diff --git a/pcsx2/x86/iMMI.c b/pcsx2/x86/iMMI.c index 3c22e70..037ac28 100644 --- a/pcsx2/x86/iMMI.c +++ b/pcsx2/x86/iMMI.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /********************************************************* * cached MMI opcodes * diff --git a/pcsx2/x86/iMMI.h b/pcsx2/x86/iMMI.h index c69b6bc..dc8e7b3 100644 --- a/pcsx2/x86/iMMI.h +++ b/pcsx2/x86/iMMI.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /********************************************************* diff --git a/pcsx2/x86/iPsxHw.c b/pcsx2/x86/iPsxHw.c index b5ba423..eaa1344 100644 --- a/pcsx2/x86/iPsxHw.c +++ b/pcsx2/x86/iPsxHw.c @@ -1,20 +1,21 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/iPsxMem.c b/pcsx2/x86/iPsxMem.c index 5265e58..c4f4a45 100644 --- a/pcsx2/x86/iPsxMem.c +++ b/pcsx2/x86/iPsxMem.c @@ -1,20 +1,21 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/iR3000A.cpp b/pcsx2/x86/iR3000A.cpp index f6bc3e0..0ba776f 100644 --- a/pcsx2/x86/iR3000A.cpp +++ b/pcsx2/x86/iR3000A.cpp @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ // recompiler reworked to add dynamic linking Jan06 diff --git a/pcsx2/x86/iR3000A.h b/pcsx2/x86/iR3000A.h index 21befca..9cb8ef1 100644 --- a/pcsx2/x86/iR3000A.h +++ b/pcsx2/x86/iR3000A.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef _R3000A_SUPERREC_ #define _R3000A_SUPERREC_ diff --git a/pcsx2/x86/iR3000Atables.cpp b/pcsx2/x86/iR3000Atables.cpp index bbe437e..6697f50 100644 --- a/pcsx2/x86/iR3000Atables.cpp +++ b/pcsx2/x86/iR3000Atables.cpp @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ // stop compiling if NORECBUILD build (only for Visual Studio) diff --git a/pcsx2/x86/iR5900.h b/pcsx2/x86/iR5900.h index 2ed71fa..8e67d0d 100644 --- a/pcsx2/x86/iR5900.h +++ b/pcsx2/x86/iR5900.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __IR5900_H__ diff --git a/pcsx2/x86/iR5900Arit.h b/pcsx2/x86/iR5900Arit.h index 5fcd64d..e94b659 100644 --- a/pcsx2/x86/iR5900Arit.h +++ b/pcsx2/x86/iR5900Arit.h @@ -1,5 +1,5 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __IR5900ARIT_H__ diff --git a/pcsx2/x86/iR5900AritImm.h b/pcsx2/x86/iR5900AritImm.h index 4bd7a0c..b30fd0c 100644 --- a/pcsx2/x86/iR5900AritImm.h +++ b/pcsx2/x86/iR5900AritImm.h @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef __IR5900ARITIMM_H__ #define __IR5900ARITIMM_H__ diff --git a/pcsx2/x86/iR5900Branch.h b/pcsx2/x86/iR5900Branch.h index 3370b8a..5e77840 100644 --- a/pcsx2/x86/iR5900Branch.h +++ b/pcsx2/x86/iR5900Branch.h @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef __IR5900BRANCH_H__ #define __IR5900BRANCH_H__ diff --git a/pcsx2/x86/iR5900Jump.h b/pcsx2/x86/iR5900Jump.h index d35f87c..b613bee 100644 --- a/pcsx2/x86/iR5900Jump.h +++ b/pcsx2/x86/iR5900Jump.h @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef __IR5900JUMP_H__ #define __IR5900JUMP_H__ diff --git a/pcsx2/x86/iR5900LoadStore.h b/pcsx2/x86/iR5900LoadStore.h index 50e29e8..8dabe5d 100644 --- a/pcsx2/x86/iR5900LoadStore.h +++ b/pcsx2/x86/iR5900LoadStore.h @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef __IR5900LOADSTORE_H__ #define __IR5900LOADSTORE_H__ diff --git a/pcsx2/x86/iR5900Move.h b/pcsx2/x86/iR5900Move.h index ae501e3..0dc3728 100644 --- a/pcsx2/x86/iR5900Move.h +++ b/pcsx2/x86/iR5900Move.h @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef __IR5900MOVE_H__ #define __IR5900MOVE_H__ diff --git a/pcsx2/x86/iR5900MultDiv.h b/pcsx2/x86/iR5900MultDiv.h index 243fd5c..35b0df5 100644 --- a/pcsx2/x86/iR5900MultDiv.h +++ b/pcsx2/x86/iR5900MultDiv.h @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef __IR5900MULTDIV_H__ #define __IR5900MULTDIV_H__ diff --git a/pcsx2/x86/iR5900Shift.h b/pcsx2/x86/iR5900Shift.h index b7b3592..44b4eee 100644 --- a/pcsx2/x86/iR5900Shift.h +++ b/pcsx2/x86/iR5900Shift.h @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef __IR5900SHIFT_H__ #define __IR5900SHIFT_H__ diff --git a/pcsx2/x86/iVU0micro.c b/pcsx2/x86/iVU0micro.c index 24b969d..df94e5d 100644 --- a/pcsx2/x86/iVU0micro.c +++ b/pcsx2/x86/iVU0micro.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/iVU0micro.h b/pcsx2/x86/iVU0micro.h index 1b3c1c5..ef7faa4 100644 --- a/pcsx2/x86/iVU0micro.h +++ b/pcsx2/x86/iVU0micro.h @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef __IVU0MICRO_H__ #define __IVU0MICRO_H__ diff --git a/pcsx2/x86/iVU1micro.c b/pcsx2/x86/iVU1micro.c index 003d76b..1561032 100644 --- a/pcsx2/x86/iVU1micro.c +++ b/pcsx2/x86/iVU1micro.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/iVU1micro.h b/pcsx2/x86/iVU1micro.h index cd83b5c..9db687a 100644 --- a/pcsx2/x86/iVU1micro.h +++ b/pcsx2/x86/iVU1micro.h @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef __IVU1MICRO_H__ #define __IVU1MICRO_H__ diff --git a/pcsx2/x86/iVUmicro.c b/pcsx2/x86/iVUmicro.c index cd9312f..9eeccc1 100644 --- a/pcsx2/x86/iVUmicro.c +++ b/pcsx2/x86/iVUmicro.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/iVUmicro.h b/pcsx2/x86/iVUmicro.h index 2e38d50..526cc28 100644 --- a/pcsx2/x86/iVUmicro.h +++ b/pcsx2/x86/iVUmicro.h @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifndef __IVUMICRO_H__ #define __IVUMICRO_H__ diff --git a/pcsx2/x86/iVUops.h b/pcsx2/x86/iVUops.h index 736c4f9..2b4cc89 100644 --- a/pcsx2/x86/iVUops.h +++ b/pcsx2/x86/iVUops.h @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #ifdef _WIN32 #pragma warning(disable:4244) diff --git a/pcsx2/x86/iVUzerorec.cpp b/pcsx2/x86/iVUzerorec.cpp index 92b4157..e051e7d 100644 --- a/pcsx2/x86/iVUzerorec.cpp +++ b/pcsx2/x86/iVUzerorec.cpp @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ // Super VU recompiler - author: zerofrog(@gmail.com) diff --git a/pcsx2/x86/iVUzerorec.h b/pcsx2/x86/iVUzerorec.h index e6359e1..ba595a5 100644 --- a/pcsx2/x86/iVUzerorec.h +++ b/pcsx2/x86/iVUzerorec.h @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ // Super VU recompiler - author: zerofrog(@gmail.com) diff --git a/pcsx2/x86/iVif.cpp b/pcsx2/x86/iVif.cpp index ca6d5cd..99bfcd4 100644 --- a/pcsx2/x86/iVif.cpp +++ b/pcsx2/x86/iVif.cpp @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ir5900tables.c b/pcsx2/x86/ir5900tables.c index ef3ea93..375a990 100644 --- a/pcsx2/x86/ir5900tables.c +++ b/pcsx2/x86/ir5900tables.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ // Holds instruction tables for the r5900 recompiler diff --git a/pcsx2/x86/ix86-32/iCore-32.cpp b/pcsx2/x86/ix86-32/iCore-32.cpp index 77bd488..7bf2fd1 100644 --- a/pcsx2/x86/ix86-32/iCore-32.cpp +++ b/pcsx2/x86/ix86-32/iCore-32.cpp @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include #include diff --git a/pcsx2/x86/ix86-32/iR5900-32.c b/pcsx2/x86/ix86-32/iR5900-32.c index 239fc52..693cf21 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.c +++ b/pcsx2/x86/ix86-32/iR5900-32.c @@ -1,3323 +1,3323 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -// recompiler reworked to add dynamic linking zerofrog(@gmail.com) Jan06 -// Recompiled completely rewritten to add block level recompilation/reg-caching/ -// liveness analysis/constant propagation Apr06 (zerofrog@gmail.com) - -// stop compiling if NORECBUILD build (only for Visual Studio) -#if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) - -#include -#include -#include -#include - -#include "Common.h" -#include "Memory.h" -#include "InterTables.h" -#include "ix86/ix86.h" -#include "iR5900.h" -#include "iR5900AritImm.h" -#include "iR5900Arit.h" -#include "iR5900MultDiv.h" -#include "iR5900Shift.h" -#include "iR5900Branch.h" -#include "iR5900Jump.h" -#include "iR5900LoadStore.h" -#include "iR5900Move.h" -#include "iMMI.h" -#include "iFPU.h" -#include "iCP0.h" -#include "iVUmicro.h" -#include "iVU0micro.h" -#include "iVU1micro.h" -#include "VU.h" -#include "VUmicro.h" - -#include "iVUzerorec.h" - -#ifdef _WIN32 -#pragma warning(disable:4244) -#pragma warning(disable:4761) -#endif - -u32 maxrecmem = 0; -uptr *recLUT; - -#define X86 -#define RECSTACK_SIZE 0x00010000 - -#define EE_NUMBLOCKS (1<<15) - -static char *recMem = NULL; // the recompiled blocks will be here -static char* recStack = NULL; // stack mem -static BASEBLOCK *recRAM = NULL; // and the ptr to the blocks here -static BASEBLOCK *recROM = NULL; // and here -static BASEBLOCK *recROM1 = NULL; // also here -static BASEBLOCKEX *recBlocks = NULL; -static char *recPtr = NULL, *recStackPtr = NULL; -static EEINST* s_pInstCache = NULL; -static u32 s_nInstCacheSize = 0; - -u32 g_EEFreezeRegs = 0; // if set, should freeze the regs - -static BASEBLOCK* s_pCurBlock = NULL; -static BASEBLOCKEX* s_pCurBlockEx = NULL; -static BASEBLOCK* s_pDispatchBlock = NULL; -static u32 s_nEndBlock = 0; // what pc the current block ends -static u32 s_nHasDelay = 0; - -static u32 s_nNextBlock = 0; // next free block in recBlocks - -extern void (*recBSC[64])(); -extern void (*recBSC_co[64])(); -void rpropBSC(EEINST* prev, EEINST* pinst); - -// save states for branches -static u16 s_savex86FpuState, s_saveiCWstate; -static GPR_reg64 s_ConstGPRreg; -static u32 s_saveConstGPRreg = 0, s_saveHasConstReg = 0, s_saveFlushedConstReg = 0, s_saveRegHasLive1 = 0, s_saveRegHasSignExt = 0; -static EEINST* s_psaveInstInfo = NULL; - -u32 s_nBlockCycles = 0; // cycles of current block recompiling -static u32 s_savenBlockCycles = 0; - -void recCOP2RecompileInst(); -int recCOP2AnalyzeBlock(u32 startpc, u32 endpc); -void recCOP2EndBlock(void); - -#ifdef _DEBUG -u32 dumplog = 0; -#else -#define dumplog 0 -#endif - -u32 pc; // recompiler pc -int branch; // set for branch - -//#ifdef PCSX2_DEVBUILD -LARGE_INTEGER lbase = {0}, lfinal = {0}; -static u32 s_startcount = 0; -//#endif - -char *txt0 = "EAX = %x : ECX = %x : EDX = %x\n"; -char *txt0RC = "EAX = %x : EBX = %x : ECX = %x : EDX = %x : ESI = %x : EDI = %x\n"; -char *txt1 = "REG[%d] = %x_%x\n"; -char *txt2 = "M32 = %x\n"; - -void _cop2AnalyzeOp(EEINST* pinst, int dostalls); // reccop2.c -static void iBranchTest(u32 newpc, u32 cpuBranch); -void recRecompile( u32 startpc ); -void recCOP22( void ); - -BASEBLOCKEX* PC_GETBLOCKEX(BASEBLOCK* p) -{ -// BASEBLOCKEX* pex = *(BASEBLOCKEX**)(p+1); -// if( pex >= recBlocks && pex < recBlocks+EE_NUMBLOCKS ) -// return pex; - - // otherwise, use the sorted list - return GetBaseBlockEx(p->startpc, 0); -} - -//////////////////////////////////////////////////// -void iDumpBlock( int startpc, char * ptr ) -{ - FILE *f; - char filename[ 256 ]; - u32 i, j; - EEINST* pcur; - extern char *disRNameGPR[]; - u8 used[34]; - u8 fpuused[33]; - int numused, count, fpunumused; - - SysPrintf( "dump1 %x:%x, %x\n", startpc, pc, cpuRegs.cycle ); -#ifdef _WIN32 - CreateDirectory("dumps", NULL); - sprintf( filename, "dumps\\dump%.8X.txt", startpc); -#else - mkdir("dumps", 0755); - sprintf( filename, "dumps/dump%.8X.txt", startpc); -#endif - - fflush( stdout ); -// f = fopen( "dump1", "wb" ); -// fwrite( ptr, 1, (u32)x86Ptr - (u32)ptr, f ); -// fclose( f ); -// -// sprintf( command, "objdump -D --target=binary --architecture=i386 dump1 > %s", filename ); -// system( command ); - - f = fopen( filename, "w" ); - - if( disR5900GetSym(startpc) != NULL ) - fprintf(f, "%s\n", disR5900GetSym(startpc)); - for ( i = startpc; i < s_nEndBlock; i += 4 ) { - fprintf( f, "%s\n", disR5900Fasm( PSMu32( i ), i ) ); - } - - // write the instruction info - - fprintf(f, "\n\nlive0 - %x, live1 - %x, live2 - %x, lastuse - %x\nmmx - %x, xmm - %x, used - %x\n", - EEINST_LIVE0, EEINST_LIVE1, EEINST_LIVE2, EEINST_LASTUSE, EEINST_MMX, EEINST_XMM, EEINST_USED); - - memset(used, 0, sizeof(used)); - numused = 0; - for(i = 0; i < ARRAYSIZE(s_pInstCache->regs); ++i) { - if( s_pInstCache->regs[i] & EEINST_USED ) { - used[i] = 1; - numused++; - } - } - - memset(fpuused, 0, sizeof(fpuused)); - fpunumused = 0; - for(i = 0; i < ARRAYSIZE(s_pInstCache->fpuregs); ++i) { - if( s_pInstCache->fpuregs[i] & EEINST_USED ) { - fpuused[i] = 1; - fpunumused++; - } - } - - fprintf(f, " "); - for(i = 0; i < ARRAYSIZE(s_pInstCache->regs); ++i) { - if( used[i] ) fprintf(f, "%2d ", i); - } - for(i = 0; i < ARRAYSIZE(s_pInstCache->fpuregs); ++i) { - if( fpuused[i] ) fprintf(f, "%2d ", i); - } - fprintf(f, "\n"); - - fprintf(f, " "); - for(i = 0; i < ARRAYSIZE(s_pInstCache->regs); ++i) { - if( used[i] ) fprintf(f, "%s ", disRNameGPR[i]); - } - for(i = 0; i < ARRAYSIZE(s_pInstCache->fpuregs); ++i) { - if( fpuused[i] ) fprintf(f, "%s ", i<32?"FR":"FA"); - } - fprintf(f, "\n"); - - pcur = s_pInstCache+1; - for( i = 0; i < (s_nEndBlock-startpc)/4; ++i, ++pcur) { - fprintf(f, "%2d: %2.2x ", i+1, pcur->info); - - count = 1; - for(j = 0; j < ARRAYSIZE(s_pInstCache->regs); j++) { - if( used[j] ) { - fprintf(f, "%2.2x%s", pcur->regs[j], ((count%8)&&countfpuregs); j++) { - if( fpuused[j] ) { - fprintf(f, "%2.2x%s", pcur->fpuregs[j], ((count%8)&&count>26) { - case 26: // ldl - case 27: // ldr - case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: - case 55: // LD - case 30: // lq - return ((tempcode>>21)&0x1f)==((tempcode>>16)&0x1f); // rs==rt - } - return 0; -} - -u8 _eeIsLoadStoreCoIssue(u32 firstcode, u32 secondcode) -{ - switch(firstcode>>26) { - case 34: // lwl - return (secondcode>>26)==38; - case 38: // lwr - return (secondcode>>26)==34; - case 42: // swl - return (secondcode>>26)==46; - case 46: // swr - return (secondcode>>26)==42; - case 26: // ldl - return (secondcode>>26)==27; - case 27: // ldr - return (secondcode>>26)==26; - case 44: // sdl - return (secondcode>>26)==45; - case 45: // sdr - return (secondcode>>26)==44; - - case 32: case 33: case 35: case 36: case 37: case 39: - case 55: // LD - - // stores - case 40: case 41: case 43: - case 63: // sd - return (secondcode>>26)==(firstcode>>26); - - case 30: // lq - case 31: // sq - case 49: // lwc1 - case 57: // swc1 - case 54: // lqc2 - case 62: // sqc2 - return (secondcode>>26)==(firstcode>>26)&&cpucaps.hasStreamingSIMDExtensions; - } - return 0; -} - -u8 _eeIsLoadStoreCoX(u32 tempcode) -{ - switch( tempcode>>26 ) { - case 30: case 31: case 49: case 57: case 55: case 63: - return 1; - } - return 0; -} - -void _eeFlushAllUnused() -{ - int i; - for(i = 0; i < 34; ++i) { - if( pc < s_nEndBlock ) { - if( (g_pCurInstInfo[1].regs[i]&EEINST_USED) ) - continue; - } - else if( (g_pCurInstInfo[0].regs[i]&EEINST_USED) ) - continue; - - if( i < 32 && GPR_IS_CONST1(i) ) _flushConstReg(i); - else { - _deleteMMXreg(MMX_GPR+i, 1); - _deleteGPRtoXMMreg(i, 1); - } - } - - //TODO when used info is done for FPU and VU0 - for(i = 0; i < XMMREGS; ++i) { - if( xmmregs[i].inuse && xmmregs[i].type != XMMTYPE_GPRREG ) - _freeXMMreg(i); - } -} - -u32* _eeGetConstReg(int reg) -{ - assert( GPR_IS_CONST1( reg ) ); - - if( g_cpuFlushedConstReg & (1<regs[xmmregs[i].reg]&EEINST_USED) ) { - if( !_recIsRegWritten(g_pCurInstInfo+1, (s_nEndBlock-pc)/4, XMMTYPE_GPRREG, xmmregs[i].reg) ) { - _freeXMMreg(i); - xmmregs[i].inuse = 1; - return 1; - } - } - } - - return 0; -} - -int _flushMMXunused() -{ - int i; - for (i=0; iregs[mmxregs[i].reg-MMX_GPR]&EEINST_USED) ) { - if( !_recIsRegWritten(g_pCurInstInfo+1, (s_nEndBlock-pc)/4, XMMTYPE_GPRREG, mmxregs[i].reg-MMX_GPR) ) { - _freeMMXreg(i); - mmxregs[i].inuse = 1; - return 1; - } - } - } - - return 0; -} - -int _flushUnusedConstReg() -{ - int i; - for(i = 1; i < 32; ++i) { - if( (g_cpuHasConstReg & (1<regs[reg]&EEINST_LASTUSE) ) { - if( usemmx ) return _allocMMXreg(-1, MMX_GPR+reg, mode); - return _allocGPRtoXMMreg(-1, reg, mode); - } - - return -1; -} - -#define PROCESS_EE_SETMODES(mmreg) ((mmxregs[mmreg].mode&MODE_WRITE)?PROCESS_EE_MODEWRITES:0) -#define PROCESS_EE_SETMODET(mmreg) ((mmxregs[mmreg].mode&MODE_WRITE)?PROCESS_EE_MODEWRITET:0) - -// ignores XMMINFO_READS, XMMINFO_READT, and XMMINFO_READD_LO from xmminfo -// core of reg caching -void eeRecompileCode0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R5900FNPTR_INFO consttcode, R5900FNPTR_INFO noconstcode, int xmminfo) -{ - int mmreg1, mmreg2, mmreg3, mmtemp, moded; - - if ( ! _Rd_ && (xmminfo&XMMINFO_WRITED) ) return; - - if( xmminfo&XMMINFO_WRITED) { - CHECK_SAVE_REG(_Rd_); - _eeProcessHasLive(_Rd_, 0); - EEINST_RESETSIGNEXT(_Rd_); - } - - if( GPR_IS_CONST2(_Rs_, _Rt_) ) { - if( xmminfo & XMMINFO_WRITED ) { - _deleteMMXreg(MMX_GPR+_Rd_, 2); - _deleteGPRtoXMMreg(_Rd_, 2); - } - if( xmminfo&XMMINFO_WRITED ) GPR_SET_CONST(_Rd_); - constcode(); - return; - } - - moded = MODE_WRITE|((xmminfo&XMMINFO_READD)?MODE_READ:0); - - // test if should write mmx - if( g_pCurInstInfo->info & EEINST_MMX ) { - - if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) _addNeededMMXreg(MMX_GPR+MMX_LO); - if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) _addNeededMMXreg(MMX_GPR+MMX_HI); - _addNeededMMXreg(MMX_GPR+_Rs_); - _addNeededMMXreg(MMX_GPR+_Rt_); - - if( GPR_IS_CONST1(_Rs_) || GPR_IS_CONST1(_Rt_) ) { - int creg = GPR_IS_CONST1(_Rs_) ? _Rs_ : _Rt_; - int vreg = creg == _Rs_ ? _Rt_ : _Rs_; - -// if(g_pCurInstInfo->regs[vreg]&EEINST_MMX) { -// mmreg1 = _allocMMXreg(-1, MMX_GPR+vreg, MODE_READ); -// _addNeededMMXreg(MMX_GPR+vreg); -// } - mmreg1 = _allocCheckGPRtoMMX(g_pCurInstInfo, vreg, MODE_READ); - - if( mmreg1 >= 0 ) { - int info = PROCESS_EE_MMX; - - if( GPR_IS_CONST1(_Rs_) ) info |= PROCESS_EE_SETMODET(mmreg1); - else info |= PROCESS_EE_SETMODES(mmreg1); - - if( xmminfo & XMMINFO_WRITED ) { - _addNeededMMXreg(MMX_GPR+_Rd_); - mmreg3 = _checkMMXreg(MMX_GPR+_Rd_, moded); - - if( !(xmminfo&XMMINFO_READD) && mmreg3 < 0 && ((g_pCurInstInfo->regs[vreg] & EEINST_LASTUSE) || !EEINST_ISLIVE64(vreg)) ) { - if( EEINST_ISLIVE64(vreg) ) { - _freeMMXreg(mmreg1); - if( GPR_IS_CONST1(_Rs_) ) info &= ~PROCESS_EE_MODEWRITET; - else info &= ~PROCESS_EE_MODEWRITES; - } - _deleteGPRtoXMMreg(_Rd_, 2); - mmxregs[mmreg1].inuse = 1; - mmxregs[mmreg1].reg = _Rd_; - mmxregs[mmreg1].mode = moded; - mmreg3 = mmreg1; - } - else if( mmreg3 < 0 ) mmreg3 = _allocMMXreg(-1, MMX_GPR+_Rd_, moded); - - info |= PROCESS_EE_SET_D(mmreg3); - } - - if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { - mmtemp = eeProcessHILO(MMX_LO, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 1); - if( mmtemp >= 0 ) info |= PROCESS_EE_SET_LO(mmtemp); - } - if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { - mmtemp = eeProcessHILO(MMX_HI, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 1); - if( mmtemp >= 0 ) info |= PROCESS_EE_SET_HI(mmtemp); - } - - SetMMXstate(); - if( creg == _Rs_ ) constscode(info|PROCESS_EE_SET_T(mmreg1)); - else consttcode(info|PROCESS_EE_SET_S(mmreg1)); - _clearNeededMMXregs(); - if( xmminfo & XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); - return; - } - } - else { - // no const regs - mmreg1 = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rs_, MODE_READ); - mmreg2 = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rt_, MODE_READ); - - if( mmreg1 >= 0 || mmreg2 >= 0 ) { - int info = PROCESS_EE_MMX; - - // do it all in mmx - if( mmreg1 < 0 ) mmreg1 = _allocMMXreg(-1, MMX_GPR+_Rs_, MODE_READ); - if( mmreg2 < 0 ) mmreg2 = _allocMMXreg(-1, MMX_GPR+_Rt_, MODE_READ); - - info |= PROCESS_EE_SETMODES(mmreg1)|PROCESS_EE_SETMODET(mmreg2); - - // check for last used, if so don't alloc a new MMX reg - if( xmminfo & XMMINFO_WRITED ) { - _addNeededMMXreg(MMX_GPR+_Rd_); - mmreg3 = _checkMMXreg(MMX_GPR+_Rd_, moded); - - if( mmreg3 < 0 ) { - if( !(xmminfo&XMMINFO_READD) && ((g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVE64(_Rt_)) ) { - if( EEINST_ISLIVE64(_Rt_) ) { - _freeMMXreg(mmreg2); - info &= ~PROCESS_EE_MODEWRITET; - } - _deleteGPRtoXMMreg(_Rd_, 2); - mmxregs[mmreg2].inuse = 1; - mmxregs[mmreg2].reg = _Rd_; - mmxregs[mmreg2].mode = moded; - mmreg3 = mmreg2; - } - else if( !(xmminfo&XMMINFO_READD) && ((g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVE64(_Rs_)) ) { - if( EEINST_ISLIVE64(_Rs_) ) { - _freeMMXreg(mmreg1); - info &= ~PROCESS_EE_MODEWRITES; - } - _deleteGPRtoXMMreg(_Rd_, 2); - mmxregs[mmreg1].inuse = 1; - mmxregs[mmreg1].reg = _Rd_; - mmxregs[mmreg1].mode = moded; - mmreg3 = mmreg1; - } - else mmreg3 = _allocMMXreg(-1, MMX_GPR+_Rd_, moded); - } - - info |= PROCESS_EE_SET_D(mmreg3); - } - - if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { - mmtemp = eeProcessHILO(MMX_LO, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 1); - if( mmtemp >= 0 ) info |= PROCESS_EE_SET_LO(mmtemp); - } - if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { - mmtemp = eeProcessHILO(MMX_HI, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 1); - if( mmtemp >= 0 ) info |= PROCESS_EE_SET_HI(mmtemp); - } - - SetMMXstate(); - noconstcode(info|PROCESS_EE_SET_S(mmreg1)|PROCESS_EE_SET_T(mmreg2)); - _clearNeededMMXregs(); - if( xmminfo & XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); - return; - } - } - - _clearNeededMMXregs(); - } - - // test if should write xmm, mirror to mmx code - if( g_pCurInstInfo->info & EEINST_XMM ) { - - if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) _addNeededGPRtoXMMreg(XMMGPR_LO); - if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) _addNeededGPRtoXMMreg(XMMGPR_HI); - _addNeededGPRtoXMMreg(_Rs_); - _addNeededGPRtoXMMreg(_Rt_); - - if( GPR_IS_CONST1(_Rs_) || GPR_IS_CONST1(_Rt_) ) { - int creg = GPR_IS_CONST1(_Rs_) ? _Rs_ : _Rt_; - int vreg = creg == _Rs_ ? _Rt_ : _Rs_; - -// if(g_pCurInstInfo->regs[vreg]&EEINST_XMM) { -// mmreg1 = _allocGPRtoXMMreg(-1, vreg, MODE_READ); -// _addNeededGPRtoXMMreg(vreg); -// } - mmreg1 = _allocCheckGPRtoXMM(g_pCurInstInfo, vreg, MODE_READ); - - if( mmreg1 >= 0 ) { - int info = PROCESS_EE_XMM; - - if( GPR_IS_CONST1(_Rs_) ) info |= PROCESS_EE_SETMODET(mmreg1); - else info |= PROCESS_EE_SETMODES(mmreg1); - - if( xmminfo & XMMINFO_WRITED ) { - - _addNeededGPRtoXMMreg(_Rd_); - mmreg3 = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, MODE_WRITE); - - if( !(xmminfo&XMMINFO_READD) && mmreg3 < 0 && ((g_pCurInstInfo->regs[vreg] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(vreg)) ) { - _freeXMMreg(mmreg1); - if( GPR_IS_CONST1(_Rs_) ) info &= ~PROCESS_EE_MODEWRITET; - else info &= ~PROCESS_EE_MODEWRITES; - _deleteMMXreg(MMX_GPR+_Rd_, 2); - xmmregs[mmreg1].inuse = 1; - xmmregs[mmreg1].reg = _Rd_; - xmmregs[mmreg1].mode = moded; - mmreg3 = mmreg1; - } - else if( mmreg3 < 0 ) mmreg3 = _allocGPRtoXMMreg(-1, _Rd_, moded); - - info |= PROCESS_EE_SET_D(mmreg3); - } - - if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { - mmtemp = eeProcessHILO(XMMGPR_LO, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 0); - if( mmtemp >= 0 ) info |= PROCESS_EE_SET_LO(mmtemp); - } - if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { - mmtemp = eeProcessHILO(XMMGPR_HI, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 0); - if( mmtemp >= 0 ) info |= PROCESS_EE_SET_HI(mmtemp); - } - - if( creg == _Rs_ ) constscode(info|PROCESS_EE_SET_T(mmreg1)); - else consttcode(info|PROCESS_EE_SET_S(mmreg1)); - _clearNeededXMMregs(); - if( xmminfo & XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); - return; - } - } - else { - // no const regs - mmreg1 = _allocCheckGPRtoXMM(g_pCurInstInfo, _Rs_, MODE_READ); - mmreg2 = _allocCheckGPRtoXMM(g_pCurInstInfo, _Rt_, MODE_READ); - - if( mmreg1 >= 0 || mmreg2 >= 0 ) { - int info = PROCESS_EE_XMM; - - // do it all in xmm - if( mmreg1 < 0 ) mmreg1 = _allocGPRtoXMMreg(-1, _Rs_, MODE_READ); - if( mmreg2 < 0 ) mmreg2 = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ); - - info |= PROCESS_EE_SETMODES(mmreg1)|PROCESS_EE_SETMODET(mmreg2); - - if( xmminfo & XMMINFO_WRITED ) { - // check for last used, if so don't alloc a new XMM reg - _addNeededGPRtoXMMreg(_Rd_); - mmreg3 = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, moded); - - if( mmreg3 < 0 ) { - if( !(xmminfo&XMMINFO_READD) && ((g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rt_)) ) { - _freeXMMreg(mmreg2); - info &= ~PROCESS_EE_MODEWRITET; - _deleteMMXreg(MMX_GPR+_Rd_, 2); - xmmregs[mmreg2].inuse = 1; - xmmregs[mmreg2].reg = _Rd_; - xmmregs[mmreg2].mode = moded; - mmreg3 = mmreg2; - } - else if( !(xmminfo&XMMINFO_READD) && ((g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rs_)) ) { - _freeXMMreg(mmreg1); - info &= ~PROCESS_EE_MODEWRITES; - _deleteMMXreg(MMX_GPR+_Rd_, 2); - xmmregs[mmreg1].inuse = 1; - xmmregs[mmreg1].reg = _Rd_; - xmmregs[mmreg1].mode = moded; - mmreg3 = mmreg1; - } - else mmreg3 = _allocGPRtoXMMreg(-1, _Rd_, moded); - } - - info |= PROCESS_EE_SET_D(mmreg3); - } - - if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { - mmtemp = eeProcessHILO(XMMGPR_LO, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 0); - if( mmtemp >= 0 ) info |= PROCESS_EE_SET_LO(mmtemp); - } - if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { - mmtemp = eeProcessHILO(XMMGPR_HI, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 0); - if( mmtemp >= 0 ) info |= PROCESS_EE_SET_HI(mmtemp); - } - - noconstcode(info|PROCESS_EE_SET_S(mmreg1)|PROCESS_EE_SET_T(mmreg2)); - _clearNeededXMMregs(); - if( xmminfo & XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); - return; - } - } - - _clearNeededXMMregs(); - } - - // regular x86 - _deleteGPRtoXMMreg(_Rs_, 1); - _deleteGPRtoXMMreg(_Rt_, 1); - if( xmminfo&XMMINFO_WRITED ) - _deleteGPRtoXMMreg(_Rd_, (xmminfo&XMMINFO_READD)?0:2); - _deleteMMXreg(MMX_GPR+_Rs_, 1); - _deleteMMXreg(MMX_GPR+_Rt_, 1); - if( xmminfo&XMMINFO_WRITED ) - _deleteMMXreg(MMX_GPR+_Rd_, (xmminfo&XMMINFO_READD)?0:2); - - // don't delete, fn will take care of them -// if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { -// _deleteGPRtoXMMreg(XMMGPR_LO, (xmminfo&XMMINFO_READLO)?1:0); -// _deleteMMXreg(MMX_GPR+MMX_LO, (xmminfo&XMMINFO_READLO)?1:0); -// } -// if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { -// _deleteGPRtoXMMreg(XMMGPR_HI, (xmminfo&XMMINFO_READHI)?1:0); -// _deleteMMXreg(MMX_GPR+MMX_HI, (xmminfo&XMMINFO_READHI)?1:0); -// } - - if( GPR_IS_CONST1(_Rs_) ) { - constscode(0); - if( xmminfo&XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); - return; - } - - if( GPR_IS_CONST1(_Rt_) ) { - consttcode(0); - if( xmminfo&XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); - return; - } - - noconstcode(0); - if( xmminfo&XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); -} - -// rt = rs op imm16 -void eeRecompileCode1(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode) -{ - int mmreg1, mmreg2; - if ( ! _Rt_ ) return; - - CHECK_SAVE_REG(_Rt_); - _eeProcessHasLive(_Rt_, 0); - EEINST_RESETSIGNEXT(_Rt_); - - if( GPR_IS_CONST1(_Rs_) ) { - _deleteMMXreg(MMX_GPR+_Rt_, 2); - _deleteGPRtoXMMreg(_Rt_, 2); - GPR_SET_CONST(_Rt_); - constcode(); - return; - } - - // test if should write mmx - if( g_pCurInstInfo->info & EEINST_MMX ) { - - // no const regs - mmreg1 = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rs_, MODE_READ); - - if( mmreg1 >= 0 ) { - int info = PROCESS_EE_MMX|PROCESS_EE_SETMODES(mmreg1); - - // check for last used, if so don't alloc a new MMX reg - _addNeededMMXreg(MMX_GPR+_Rt_); - mmreg2 = _checkMMXreg(MMX_GPR+_Rt_, MODE_WRITE); - - if( mmreg2 < 0 ) { - if( (g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVE64(_Rs_) ) { - if( EEINST_ISLIVE64(_Rs_) ) { - _freeMMXreg(mmreg1); - info &= ~PROCESS_EE_MODEWRITES; - } - _deleteGPRtoXMMreg(_Rt_, 2); - mmxregs[mmreg1].inuse = 1; - mmxregs[mmreg1].reg = _Rt_; - mmxregs[mmreg1].mode = MODE_WRITE|MODE_READ; - mmreg2 = mmreg1; - } - else mmreg2 = _allocMMXreg(-1, MMX_GPR+_Rt_, MODE_WRITE); - } - - SetMMXstate(); - noconstcode(info|PROCESS_EE_SET_S(mmreg1)|PROCESS_EE_SET_T(mmreg2)); - _clearNeededMMXregs(); - GPR_DEL_CONST(_Rt_); - return; - } - - _clearNeededMMXregs(); - } - - // test if should write xmm, mirror to mmx code - if( g_pCurInstInfo->info & EEINST_XMM ) { - - // no const regs - mmreg1 = _allocCheckGPRtoXMM(g_pCurInstInfo, _Rs_, MODE_READ); - - if( mmreg1 >= 0 ) { - int info = PROCESS_EE_XMM|PROCESS_EE_SETMODES(mmreg1); - - // check for last used, if so don't alloc a new XMM reg - _addNeededGPRtoXMMreg(_Rt_); - mmreg2 = _checkXMMreg(XMMTYPE_GPRREG, _Rt_, MODE_WRITE); - - if( mmreg2 < 0 ) { - if( (g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rs_) ) { - _freeXMMreg(mmreg1); - info &= ~PROCESS_EE_MODEWRITES; - _deleteMMXreg(MMX_GPR+_Rt_, 2); - xmmregs[mmreg1].inuse = 1; - xmmregs[mmreg1].reg = _Rt_; - xmmregs[mmreg1].mode = MODE_WRITE|MODE_READ; - mmreg2 = mmreg1; - } - else mmreg2 = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE); - } - - noconstcode(info|PROCESS_EE_SET_S(mmreg1)|PROCESS_EE_SET_T(mmreg2)); - _clearNeededXMMregs(); - GPR_DEL_CONST(_Rt_); - return; - } - - _clearNeededXMMregs(); - } - - // regular x86 - _deleteGPRtoXMMreg(_Rs_, 1); - _deleteGPRtoXMMreg(_Rt_, 2); - _deleteMMXreg(MMX_GPR+_Rs_, 1); - _deleteMMXreg(MMX_GPR+_Rt_, 2); - - noconstcode(0); - GPR_DEL_CONST(_Rt_); -} - -// rd = rt op sa -void eeRecompileCode2(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode) -{ - int mmreg1, mmreg2; - if ( ! _Rd_ ) return; - - CHECK_SAVE_REG(_Rd_); - _eeProcessHasLive(_Rd_, 0); - EEINST_RESETSIGNEXT(_Rd_); - - if( GPR_IS_CONST1(_Rt_) ) { - _deleteMMXreg(MMX_GPR+_Rd_, 2); - _deleteGPRtoXMMreg(_Rd_, 2); - GPR_SET_CONST(_Rd_); - constcode(); - return; - } - - // test if should write mmx - if( g_pCurInstInfo->info & EEINST_MMX ) { - - // no const regs - mmreg1 = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rt_, MODE_READ); - - if( mmreg1 >= 0 ) { - int info = PROCESS_EE_MMX|PROCESS_EE_SETMODET(mmreg1); - - // check for last used, if so don't alloc a new MMX reg - _addNeededMMXreg(MMX_GPR+_Rd_); - mmreg2 = _checkMMXreg(MMX_GPR+_Rd_, MODE_WRITE); - - if( mmreg2 < 0 ) { - if( (g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVE64(_Rt_) ) { - if( EEINST_ISLIVE64(_Rt_) ) { - _freeMMXreg(mmreg1); - info &= ~PROCESS_EE_MODEWRITET; - } - _deleteGPRtoXMMreg(_Rd_, 2); - mmxregs[mmreg1].inuse = 1; - mmxregs[mmreg1].reg = _Rd_; - mmxregs[mmreg1].mode = MODE_WRITE|MODE_READ; - mmreg2 = mmreg1; - } - else mmreg2 = _allocMMXreg(-1, MMX_GPR+_Rd_, MODE_WRITE); - } - - SetMMXstate(); - noconstcode(info|PROCESS_EE_SET_T(mmreg1)|PROCESS_EE_SET_D(mmreg2)); - _clearNeededMMXregs(); - GPR_DEL_CONST(_Rd_); - return; - } - - _clearNeededMMXregs(); - } - - // test if should write xmm, mirror to mmx code - if( g_pCurInstInfo->info & EEINST_XMM ) { - - // no const regs - mmreg1 = _allocCheckGPRtoXMM(g_pCurInstInfo, _Rt_, MODE_READ); - - if( mmreg1 >= 0 ) { - int info = PROCESS_EE_XMM|PROCESS_EE_SETMODET(mmreg1); - - // check for last used, if so don't alloc a new XMM reg - _addNeededGPRtoXMMreg(_Rd_); - mmreg2 = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, MODE_WRITE); - - if( mmreg2 < 0 ) { - if( (g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVE64(_Rt_) ) { - _freeXMMreg(mmreg1); - info &= ~PROCESS_EE_MODEWRITET; - _deleteMMXreg(MMX_GPR+_Rd_, 2); - xmmregs[mmreg1].inuse = 1; - xmmregs[mmreg1].reg = _Rd_; - xmmregs[mmreg1].mode = MODE_WRITE|MODE_READ; - mmreg2 = mmreg1; - } - else mmreg2 = _allocGPRtoXMMreg(-1, _Rd_, MODE_WRITE); - } - - noconstcode(info|PROCESS_EE_SET_T(mmreg1)|PROCESS_EE_SET_D(mmreg2)); - _clearNeededXMMregs(); - GPR_DEL_CONST(_Rd_); - return; - } - - _clearNeededXMMregs(); - } - - // regular x86 - _deleteGPRtoXMMreg(_Rt_, 1); - _deleteGPRtoXMMreg(_Rd_, 2); - _deleteMMXreg(MMX_GPR+_Rt_, 1); - _deleteMMXreg(MMX_GPR+_Rd_, 2); - - noconstcode(0); - GPR_DEL_CONST(_Rd_); -} - -// rt op rs -void eeRecompileCode3(R5900FNPTR constcode, R5900FNPTR_INFO multicode) -{ - assert(0); - // for now, don't support xmm - _deleteEEreg(_Rs_, 1); - _deleteEEreg(_Rt_, 1); - - if( GPR_IS_CONST2(_Rs_, _Rt_) ) { - constcode(); - return; - } - - if( GPR_IS_CONST1(_Rs_) ) { - //multicode(PROCESS_EE_CONSTT); - return; - } - - if( GPR_IS_CONST1(_Rt_) ) { - //multicode(PROCESS_EE_CONSTT); - return; - } - - multicode(0); -} - -// Simple Code Templates // - -// rd = rs op rt -void eeRecompileCodeConst0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R5900FNPTR_INFO consttcode, R5900FNPTR_INFO noconstcode) -{ - if ( ! _Rd_ ) return; - - // for now, don't support xmm - CHECK_SAVE_REG(_Rd_); - - _deleteGPRtoXMMreg(_Rs_, 1); - _deleteGPRtoXMMreg(_Rt_, 1); - _deleteGPRtoXMMreg(_Rd_, 0); - _deleteMMXreg(MMX_GPR+_Rs_, 1); - _deleteMMXreg(MMX_GPR+_Rt_, 1); - _deleteMMXreg(MMX_GPR+_Rd_, 0); - - if( GPR_IS_CONST2(_Rs_, _Rt_) ) { - GPR_SET_CONST(_Rd_); - constcode(); - return; - } - - if( GPR_IS_CONST1(_Rs_) ) { - constscode(0); - GPR_DEL_CONST(_Rd_); - return; - } - - if( GPR_IS_CONST1(_Rt_) ) { - consttcode(0); - GPR_DEL_CONST(_Rd_); - return; - } - - noconstcode(0); - GPR_DEL_CONST(_Rd_); -} - -// rt = rs op imm16 -void eeRecompileCodeConst1(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode) -{ - if ( ! _Rt_ ) - return; - - // for now, don't support xmm - CHECK_SAVE_REG(_Rt_); - - _deleteGPRtoXMMreg(_Rs_, 1); - _deleteGPRtoXMMreg(_Rt_, 0); - - if( GPR_IS_CONST1(_Rs_) ) { - GPR_SET_CONST(_Rt_); - constcode(); - return; - } - - noconstcode(0); - GPR_DEL_CONST(_Rt_); -} - -// rd = rt op sa -void eeRecompileCodeConst2(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode) -{ - if ( ! _Rd_ ) return; - - // for now, don't support xmm - CHECK_SAVE_REG(_Rd_); - - _deleteGPRtoXMMreg(_Rt_, 1); - _deleteGPRtoXMMreg(_Rd_, 0); - - if( GPR_IS_CONST1(_Rt_) ) { - GPR_SET_CONST(_Rd_); - constcode(); - return; - } - - noconstcode(0); - GPR_DEL_CONST(_Rd_); -} - -// rd = rt MULT rs (SPECIAL) -void eeRecompileCodeConstSPECIAL(R5900FNPTR constcode, R5900FNPTR_INFO multicode, int MULT) -{ - assert(0); - // for now, don't support xmm - if( MULT ) { - CHECK_SAVE_REG(_Rd_); - _deleteGPRtoXMMreg(_Rd_, 0); - } - - _deleteGPRtoXMMreg(_Rs_, 1); - _deleteGPRtoXMMreg(_Rt_, 1); - - if( GPR_IS_CONST2(_Rs_, _Rt_) ) { - if( MULT && _Rd_ ) GPR_SET_CONST(_Rd_); - constcode(); - return; - } - - if( GPR_IS_CONST1(_Rs_) ) { - //multicode(PROCESS_EE_CONSTS); - if( MULT && _Rd_ ) GPR_DEL_CONST(_Rd_); - return; - } - - if( GPR_IS_CONST1(_Rt_) ) { - //multicode(PROCESS_EE_CONSTT); - if( MULT && _Rd_ ) GPR_DEL_CONST(_Rd_); - return; - } - - multicode(0); - if( MULT && _Rd_ ) GPR_DEL_CONST(_Rd_); -} - -// EE XMM allocation code -int eeRecompileCodeXMM(int xmminfo) -{ - int info = PROCESS_EE_XMM; - - // save state - if( xmminfo & XMMINFO_WRITED ) { - CHECK_SAVE_REG(_Rd_); - _eeProcessHasLive(_Rd_, 0); - EEINST_RESETSIGNEXT(_Rd_); - } - - // flush consts - if( xmminfo & XMMINFO_READT ) { - if( GPR_IS_CONST1( _Rt_ ) && !(g_cpuFlushedConstReg&(1<<_Rt_)) ) { - MOV32ItoM((int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], g_cpuConstRegs[_Rt_].UL[0]); - MOV32ItoM((int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], g_cpuConstRegs[_Rt_].UL[1]); - g_cpuFlushedConstReg |= (1<<_Rt_); - } - } - if( xmminfo & XMMINFO_READS) { - if( GPR_IS_CONST1( _Rs_ ) && !(g_cpuFlushedConstReg&(1<<_Rs_)) ) { - MOV32ItoM((int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ], g_cpuConstRegs[_Rs_].UL[0]); - MOV32ItoM((int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ], g_cpuConstRegs[_Rs_].UL[1]); - g_cpuFlushedConstReg |= (1<<_Rs_); - } - } - - if( xmminfo & XMMINFO_WRITED ) { - GPR_DEL_CONST(_Rd_); - } - - // add needed - if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { - _addNeededGPRtoXMMreg(XMMGPR_LO); - } - if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { - _addNeededGPRtoXMMreg(XMMGPR_HI); - } - if( xmminfo & XMMINFO_READS) _addNeededGPRtoXMMreg(_Rs_); - if( xmminfo & XMMINFO_READT) _addNeededGPRtoXMMreg(_Rt_); - if( xmminfo & XMMINFO_WRITED ) _addNeededGPRtoXMMreg(_Rd_); - - // allocate - if( xmminfo & XMMINFO_READS) { - int reg = _allocGPRtoXMMreg(-1, _Rs_, MODE_READ); - info |= PROCESS_EE_SET_S(reg)|PROCESS_EE_SETMODES(reg); - } - if( xmminfo & XMMINFO_READT) { - int reg = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ); - info |= PROCESS_EE_SET_T(reg)|PROCESS_EE_SETMODET(reg); - } - - if( xmminfo & XMMINFO_WRITED ) { - int readd = MODE_WRITE|((xmminfo&XMMINFO_READD)?((xmminfo&XMMINFO_READD_LO)?(MODE_READ|MODE_READHALF):MODE_READ):0); - - int regd = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, readd); - - if( regd < 0 ) { - if( !(xmminfo&XMMINFO_READD) && (xmminfo & XMMINFO_READT) && (_Rt_ == 0 || (g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rt_)) ) { - _freeXMMreg(EEREC_T); - _deleteMMXreg(MMX_GPR+_Rd_, 2); - xmmregs[EEREC_T].inuse = 1; - xmmregs[EEREC_T].reg = _Rd_; - xmmregs[EEREC_T].mode = readd; - regd = EEREC_T; - } - else if( !(xmminfo&XMMINFO_READD) && (xmminfo & XMMINFO_READS) && (_Rs_ == 0 || (g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rs_)) ) { - _freeXMMreg(EEREC_S); - _deleteMMXreg(MMX_GPR+_Rd_, 2); - xmmregs[EEREC_S].inuse = 1; - xmmregs[EEREC_S].reg = _Rd_; - xmmregs[EEREC_S].mode = readd; - regd = EEREC_S; - } - else regd = _allocGPRtoXMMreg(-1, _Rd_, readd); - } - - info |= PROCESS_EE_SET_D(regd); - } - if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { - info |= PROCESS_EE_SET_LO(_allocGPRtoXMMreg(-1, XMMGPR_LO, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0))); - info |= PROCESS_EE_LO; - } - if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { - info |= PROCESS_EE_SET_HI(_allocGPRtoXMMreg(-1, XMMGPR_HI, ((xmminfo&XMMINFO_READHI)?MODE_READ:0)|((xmminfo&XMMINFO_WRITEHI)?MODE_WRITE:0))); - info |= PROCESS_EE_HI; - } - return info; -} - -// EE COP1(FPU) XMM allocation code -#define _Ft_ _Rt_ -#define _Fs_ _Rd_ -#define _Fd_ _Sa_ - -#define PROCESS_EE_SETMODES_XMM(mmreg) ((xmmregs[mmreg].mode&MODE_WRITE)?PROCESS_EE_MODEWRITES:0) -#define PROCESS_EE_SETMODET_XMM(mmreg) ((xmmregs[mmreg].mode&MODE_WRITE)?PROCESS_EE_MODEWRITET:0) - -// rd = rs op rt -void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR_INFO fpucode, int xmminfo) -{ - int mmregs=-1, mmregt=-1, mmregd=-1, mmregacc=-1; - - if( EE_FPU_REGCACHING && cpucaps.hasStreamingSIMDExtensions ) { - int info = PROCESS_EE_XMM; - - if( xmminfo & XMMINFO_READS ) _addNeededFPtoXMMreg(_Fs_); - if( xmminfo & XMMINFO_READT ) _addNeededFPtoXMMreg(_Ft_); - if( xmminfo & (XMMINFO_WRITED|XMMINFO_READD) ) _addNeededFPtoXMMreg(_Fd_); - if( xmminfo & (XMMINFO_WRITEACC|XMMINFO_READACC) ) _addNeededFPACCtoXMMreg(); - - if( xmminfo & XMMINFO_READT ) { - if( g_pCurInstInfo->fpuregs[_Ft_] & EEINST_LASTUSE ) mmregt = _checkXMMreg(XMMTYPE_FPREG, _Ft_, MODE_READ); - else mmregt = _allocFPtoXMMreg(-1, _Ft_, MODE_READ); - } - - if( xmminfo & XMMINFO_READS ) { - if( (!(xmminfo&XMMINFO_READT)||mmregt>=0) && (g_pCurInstInfo->fpuregs[_Fs_] & EEINST_LASTUSE) ) - mmregs = _checkXMMreg(XMMTYPE_FPREG, _Fs_, MODE_READ); - else mmregs = _allocFPtoXMMreg(-1, _Fs_, MODE_READ); - } - - if( mmregs >= 0 ) info |= PROCESS_EE_SETMODES_XMM(mmregs); - if( mmregt >= 0 ) info |= PROCESS_EE_SETMODET_XMM(mmregt); - - if( xmminfo & XMMINFO_READD ) { - assert( xmminfo & XMMINFO_WRITED ); - mmregd = _allocFPtoXMMreg(-1, _Fd_, MODE_READ); - } - - if( xmminfo & XMMINFO_READACC ) { - if( !(xmminfo&XMMINFO_WRITEACC) && (g_pCurInstInfo->fpuregs[_Ft_] & EEINST_LASTUSE) ) - mmregacc = _checkXMMreg(XMMTYPE_FPACC, 0, MODE_READ); - else mmregacc = _allocFPACCtoXMMreg(-1, MODE_READ); - } - - if( xmminfo & XMMINFO_WRITEACC ) { - - // check for last used, if so don't alloc a new XMM reg - int readacc = MODE_WRITE|((xmminfo&XMMINFO_READACC)?MODE_READ:0); - - mmregacc = _checkXMMreg(XMMTYPE_FPACC, 0, readacc); - - if( mmregacc < 0 ) { - if( (xmminfo&XMMINFO_READT) && mmregt >= 0 && (FPUINST_LASTUSE(_Ft_) || !FPUINST_ISLIVE(_Ft_)) ) { - if( FPUINST_ISLIVE(_Ft_) ) { - _freeXMMreg(mmregt); - info &= ~PROCESS_EE_MODEWRITET; - } - _deleteMMXreg(MMX_FPU+XMMFPU_ACC, 2); - xmmregs[mmregt].inuse = 1; - xmmregs[mmregt].reg = 0; - xmmregs[mmregt].mode = readacc; - xmmregs[mmregt].type = XMMTYPE_FPACC; - mmregacc = mmregt; - } - else if( (xmminfo&XMMINFO_READS) && mmregs >= 0 && (FPUINST_LASTUSE(_Fs_) || !FPUINST_ISLIVE(_Fs_)) ) { - if( FPUINST_ISLIVE(_Fs_) ) { - _freeXMMreg(mmregs); - info &= ~PROCESS_EE_MODEWRITES; - } - _deleteMMXreg(MMX_FPU+XMMFPU_ACC, 2); - xmmregs[mmregs].inuse = 1; - xmmregs[mmregs].reg = 0; - xmmregs[mmregs].mode = readacc; - xmmregs[mmregs].type = XMMTYPE_FPACC; - mmregacc = mmregs; - } - else mmregacc = _allocFPACCtoXMMreg(-1, readacc); - } - - xmmregs[mmregacc].mode |= MODE_WRITE; - } - else if( xmminfo & XMMINFO_WRITED ) { - // check for last used, if so don't alloc a new XMM reg - int readd = MODE_WRITE|((xmminfo&XMMINFO_READD)?MODE_READ:0); - if( xmminfo&XMMINFO_READD ) mmregd = _allocFPtoXMMreg(-1, _Fd_, readd); - else mmregd = _checkXMMreg(XMMTYPE_FPREG, _Fd_, readd); - - if( mmregd < 0 ) { - if( (xmminfo&XMMINFO_READT) && mmregt >= 0 && (FPUINST_LASTUSE(_Ft_) || !FPUINST_ISLIVE(_Ft_)) ) { - if( FPUINST_ISLIVE(_Ft_) ) { - _freeXMMreg(mmregt); - info &= ~PROCESS_EE_MODEWRITET; - } - _deleteMMXreg(MMX_FPU+_Fd_, 2); - xmmregs[mmregt].inuse = 1; - xmmregs[mmregt].reg = _Fd_; - xmmregs[mmregt].mode = readd; - mmregd = mmregt; - } - else if( (xmminfo&XMMINFO_READS) && mmregs >= 0 && (FPUINST_LASTUSE(_Fs_) || !FPUINST_ISLIVE(_Fs_)) ) { - if( FPUINST_ISLIVE(_Fs_) ) { - _freeXMMreg(mmregs); - info &= ~PROCESS_EE_MODEWRITES; - } - _deleteMMXreg(MMX_FPU+_Fd_, 2); - xmmregs[mmregs].inuse = 1; - xmmregs[mmregs].reg = _Fd_; - xmmregs[mmregs].mode = readd; - mmregd = mmregs; - } - else if( (xmminfo&XMMINFO_READACC) && mmregacc >= 0 && (FPUINST_LASTUSE(XMMFPU_ACC) || !FPUINST_ISLIVE(XMMFPU_ACC)) ) { - if( FPUINST_ISLIVE(XMMFPU_ACC) ) - _freeXMMreg(mmregacc); - _deleteMMXreg(MMX_FPU+_Fd_, 2); - xmmregs[mmregacc].inuse = 1; - xmmregs[mmregacc].reg = _Fd_; - xmmregs[mmregacc].mode = readd; - xmmregs[mmregacc].type = XMMTYPE_FPREG; - mmregd = mmregacc; - } - else mmregd = _allocFPtoXMMreg(-1, _Fd_, readd); - } - } - - assert( mmregs >= 0 || mmregt >= 0 || mmregd >= 0 || mmregacc >= 0 ); - - if( xmminfo & XMMINFO_WRITED ) { - assert( mmregd >= 0 ); - info |= PROCESS_EE_SET_D(mmregd); - } - if( xmminfo & (XMMINFO_WRITEACC|XMMINFO_READACC) ) { - if( mmregacc >= 0 ) info |= PROCESS_EE_SET_ACC(mmregacc)|PROCESS_EE_ACC; - else assert( !(xmminfo&XMMINFO_WRITEACC)); - } - - if( xmminfo & XMMINFO_READS ) { - if( mmregs >= 0 ) info |= PROCESS_EE_SET_S(mmregs)|PROCESS_EE_S; - } - if( xmminfo & XMMINFO_READT ) { - if( mmregt >= 0 ) info |= PROCESS_EE_SET_T(mmregt)|PROCESS_EE_T; - } - - // at least one must be in xmm - if( (xmminfo & (XMMINFO_READS|XMMINFO_READT)) == (XMMINFO_READS|XMMINFO_READT) ) { - assert( mmregs >= 0 || mmregt >= 0 ); - } - - xmmcode(info); - _clearNeededXMMregs(); - return; - } - - if( xmminfo & XMMINFO_READS ) _deleteFPtoXMMreg(_Fs_, 0); - if( xmminfo & XMMINFO_READT ) _deleteFPtoXMMreg(_Ft_, 0); - if( xmminfo & (XMMINFO_READD|XMMINFO_WRITED) ) _deleteFPtoXMMreg(_Fd_, 0); - if( xmminfo & (XMMINFO_READACC|XMMINFO_WRITEACC) ) _deleteFPtoXMMreg(XMMFPU_ACC, 0); - fpucode(0); -} - -#undef _Ft_ -#undef _Fs_ -#undef _Fd_ - -//////////////////////////////////////////////////// -extern u8 g_MACFlagTransform[256]; // for vus - -u32 g_sseMXCSR = 0x9fc0; // disable all exception, round to 0, flush to 0 -u32 g_sseVUMXCSR = 0xff80; - -void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR) -{ - // SSE STATE // - // WARNING: do not touch unless you know what you are doing - - if( cpucaps.hasStreamingSIMDExtensions ) { - g_sseMXCSR = sseMXCSR; - g_sseVUMXCSR = sseVUMXCSR; - // do NOT set Denormals-Are-Zero flag (charlie and chocfac messes up) - // Update 11/05/08 - Doesnt seem to effect it anymore, for the speed boost, its on :p - //g_sseMXCSR = 0x9f80; // changing the rounding mode to 0x2000 (near) kills grandia III! - // changing the rounding mode to 0x0000 or 0x4000 totally kills gitaroo - // so... grandia III wins (you can change individual games with the 'roundmode' patch command) - -#ifdef _MSC_VER - __asm ldmxcsr g_sseMXCSR; // set the new sse control -#else - __asm__("ldmxcsr %0" : : "m"(g_sseMXCSR) ); -#endif - //g_sseVUMXCSR = g_sseMXCSR|0x6000; - } -} - -#define REC_CACHEMEM 0x01000000 - -int recInit( void ) -{ - int i; - const u8 macarr[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }; - - recLUT = (uptr*) _aligned_malloc( 0x010000 * sizeof(uptr), 16 ); - memset( recLUT, 0, 0x010000 * sizeof(uptr) ); - - // can't have upper 4 bits nonzero! - recMem = (char*)SysMmap(0x0d000000, REC_CACHEMEM); - - // 32 alignment necessary - recRAM = (BASEBLOCK*) _aligned_malloc( sizeof(BASEBLOCK)/4*0x02000000 , 4*sizeof(BASEBLOCK)); - recROM = (BASEBLOCK*) _aligned_malloc( sizeof(BASEBLOCK)/4*0x00400000 , 4*sizeof(BASEBLOCK)); - recROM1= (BASEBLOCK*) _aligned_malloc( sizeof(BASEBLOCK)/4*0x00040000 , 4*sizeof(BASEBLOCK)); - recBlocks = (BASEBLOCKEX*) _aligned_malloc( sizeof(BASEBLOCKEX)*EE_NUMBLOCKS, 16); - recStack = (char*)malloc( RECSTACK_SIZE ); - - s_nInstCacheSize = 128; - s_pInstCache = (EEINST*)malloc( sizeof(EEINST) * s_nInstCacheSize ); - - if ( recBlocks == NULL || recRAM == NULL || recROM == NULL || recROM1 == NULL || recMem == NULL || recLUT == NULL ) { - SysMessage( _( "Error allocating memory" ) ); - return -1; - } - - for ( i = 0x0000; i < 0x0200; i++ ) - { - recLUT[ i + 0x0000 ] = (uptr)&recRAM[ i << 14 ]; - recLUT[ i + 0x2000 ] = (uptr)&recRAM[ i << 14 ]; - recLUT[ i + 0x3000 ] = (uptr)&recRAM[ i << 14 ]; - } - - for ( i = 0x0000; i < 0x0040; i++ ) - { - recLUT[ i + 0x1fc0 ] = (uptr)&recROM[ i << 14 ]; - recLUT[ i + 0x9fc0 ] = (uptr)&recROM[ i << 14 ]; - recLUT[ i + 0xbfc0 ] = (uptr)&recROM[ i << 14 ]; - } - - for ( i = 0x0000; i < 0x0004; i++ ) - { - recLUT[ i + 0x1e00 ] = (uptr)&recROM1[ i << 14 ]; - recLUT[ i + 0x9e00 ] = (uptr)&recROM1[ i << 14 ]; - recLUT[ i + 0xbe00 ] = (uptr)&recROM1[ i << 14 ]; - } - - memcpy( recLUT + 0x8000, recLUT, 0x2000 * sizeof(uptr) ); - memcpy( recLUT + 0xa000, recLUT, 0x2000 * sizeof(uptr) ); - - memset(recMem, 0xcd, REC_CACHEMEM); - memset(recStack, 0, RECSTACK_SIZE); - - // SSE3 detection, manually create the code - x86SetPtr(recMem); - SSE3_MOVSLDUP_XMM_to_XMM(XMM0, XMM0); - RET(); - - cpudetectSSE3(recMem); - - x86SetPtr(recMem); - SSE4_DPPS_XMM_to_XMM(XMM0, XMM0, 0); - RET(); - - cpudetectSSE4(recMem); - - SysPrintf( "x86Init: \n" ); - SysPrintf( "\tCPU vender name = %s\n", cpuinfo.x86ID ); - SysPrintf( "\tFamilyID = %x\n", cpuinfo.x86StepID ); - SysPrintf( "\tx86Family = %s\n", cpuinfo.x86Fam ); - SysPrintf( "\tCPU speed = %d.%03d Ghz\n", cpuinfo.cpuspeed / 1000, cpuinfo.cpuspeed%1000); - SysPrintf( "\tx86PType = %s\n", cpuinfo.x86Type ); - SysPrintf( "\tx86Flags = %8.8x %8.8x\n", cpuinfo.x86Flags, cpuinfo.x86Flags2 ); - SysPrintf( "\tx86EFlags = %8.8x\n", cpuinfo.x86EFlags ); - SysPrintf( "Features: \n" ); - SysPrintf( "\t%sDetected MMX\n", cpucaps.hasMultimediaExtensions ? "" : "Not " ); - SysPrintf( "\t%sDetected SSE\n", cpucaps.hasStreamingSIMDExtensions ? "" : "Not " ); - SysPrintf( "\t%sDetected SSE2\n", cpucaps.hasStreamingSIMD2Extensions ? "" : "Not " ); - SysPrintf( "\t%sDetected SSE3\n", cpucaps.hasStreamingSIMD3Extensions ? "" : "Not " ); - SysPrintf( "\t%sDetected SSE4.1\n", cpucaps.hasStreamingSIMD4Extensions ? "" : "Not " ); - - if ( cpuinfo.x86ID[0] == 'A' ) //AMD cpu - { - SysPrintf( " Extented AMD Features: \n" ); - SysPrintf( "\t%sDetected MMX2\n", cpucaps.hasMultimediaExtensionsExt ? "" : "Not " ); - SysPrintf( "\t%sDetected 3DNOW\n", cpucaps.has3DNOWInstructionExtensions ? "" : "Not " ); - SysPrintf( "\t%sDetected 3DNOW2\n", cpucaps.has3DNOWInstructionExtensionsExt ? "" : "Not " ); - } - if ( !( cpucaps.hasMultimediaExtensions ) ) - { - SysMessage( _( "Processor doesn't supports MMX, can't run recompiler without that" ) ); - return -1; - } - - x86FpuState = FPU_STATE; - - SuperVUInit(-1); - - for(i = 0; i < 256; ++i) { - g_MACFlagTransform[i] = macarr[i>>4]|(macarr[i&15]<<4); - } - - SetCPUState(g_sseMXCSR, g_sseVUMXCSR); - - return 0; -} - -//////////////////////////////////////////////////// -void recReset( void ) { -#ifdef PCSX2_DEVBUILD - SysPrintf("EE Recompiler data reset\n"); -#endif - - s_nNextBlock = 0; - maxrecmem = 0; - memset( recRAM, 0, sizeof(BASEBLOCK)/4*0x02000000 ); - memset( recROM, 0, sizeof(BASEBLOCK)/4*0x00400000 ); - memset( recROM1, 0, sizeof(BASEBLOCK)/4*0x00040000 ); - memset( recBlocks, 0, sizeof(BASEBLOCKEX)*EE_NUMBLOCKS ); - if( s_pInstCache ) memset( s_pInstCache, 0, sizeof(EEINST)*s_nInstCacheSize ); - ResetBaseBlockEx(0); - -#ifdef _MSC_VER - __asm emms; -#else - __asm__("emms"); -#endif - -#ifdef _DEBUG - // don't clear since save states won't work - //memset(recMem, 0xcd, REC_CACHEMEM); -#endif - - recPtr = recMem; - recStackPtr = recStack; - x86FpuState = FPU_STATE; - iCWstate = 0; - - branch = 0; -} - -void recShutdown( void ) -{ - if ( recMem == NULL ) { - return; - } - - _aligned_free( recLUT ); - SysMunmap((uptr)recMem, REC_CACHEMEM); recMem = NULL; - _aligned_free( recRAM ); recRAM = NULL; - _aligned_free( recROM ); recROM = NULL; - _aligned_free( recROM1 ); recROM1 = NULL; - _aligned_free( recBlocks ); recBlocks = NULL; - free( s_pInstCache ); s_pInstCache = NULL; s_nInstCacheSize = 0; - - SuperVUDestroy(-1); - - x86Shutdown( ); -} - -void recEnableVU0micro(int enable) { -} - -void recEnableVU1micro(int enable) { -} - -#pragma warning(disable:4731) // frame pointer register 'ebp' modified by inline assembly code -static u32 s_uSaveESP = 0, s_uSaveEBP; - -static void execute( void ) -{ -#ifdef _DEBUG - u8* fnptr; - u32 oldesi; -#else - R5900FNPTR pfn; -#endif - BASEBLOCK* pblock = PC_GETBLOCK(cpuRegs.pc); - - if ( !pblock->pFnptr || pblock->startpc != cpuRegs.pc ) { - recRecompile(cpuRegs.pc); - } - - assert( pblock->pFnptr != 0 ); - g_EEFreezeRegs = 1; - - // skip the POPs -#ifdef _DEBUG - fnptr = (u8*)pblock->pFnptr; - -#ifdef _MSC_VER - __asm { - // save data - mov oldesi, esi - mov s_uSaveESP, esp - sub s_uSaveESP, 8 - mov s_uSaveEBP, ebp - push ebp - - call fnptr // jump into function - // restore data - pop ebp - mov esi, oldesi - } -#else - - __asm__("movl %%esi, %0\n" - "movl %%esp, %1\n" - "sub $8, %1\n" - "push %%ebp\n" - "call *%2\n" - "pop %%ebp\n" - "movl %0, %%esi\n" : "=m"(oldesi), "=m"(s_uSaveESP) : "c"(fnptr) ); -#endif // _MSC_VER - -#else - -#ifdef _MSC_VER - pfn = ((R5900FNPTR)pblock->pFnptr); - // use call instead of pfn() - __asm call pfn; -#else - ((R5900FNPTR)pblock->pFnptr)(); -#endif - -#endif - - g_EEFreezeRegs = 0; -} - -void recStep( void ) { -} - -void recExecute( void ) { - //SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); - //SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);//ABOVE_NORMAL_PRIORITY_CLASS); - //SetThreadAffinityMask(GetCurrentThread(), 0); - if( Config.Options & PCSX2_EEREC ) Config.Options |= PCSX2_COP2REC; - - for (;;) - execute(); -} - -void recExecuteBlock( void ) { - execute(); -} - -//////////////////////////////////////////////////// -extern u32 g_nextBranchCycle; - -u32 g_lastpc = 0; -u32 g_EEDispatchTemp; -u32 s_pCurBlock_ltime; - -#ifdef _MSC_VER - -// jumped to when invalid pc address -__declspec(naked,noreturn) void Dispatcher() -{ - // EDX contains the jump addr to modify - __asm push edx - - // calc PC_GETBLOCK - s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc); - - __asm { - mov eax, s_pDispatchBlock - - // check if startpc == cpuRegs.pc - mov ecx, cpuRegs.pc - //and ecx, 0x5fffffff // remove higher bits - cmp ecx, dword ptr [eax+BLOCKTYPE_STARTPC] - je CheckPtr - - // recompile - push cpuRegs.pc // pc - call recRecompile - add esp, 4 // pop old param - mov eax, s_pDispatchBlock -CheckPtr: - mov eax, dword ptr [eax] - } - -#ifdef _DEBUG - __asm mov g_EEDispatchTemp, eax - assert( g_EEDispatchTemp ); -#endif - -// __asm { -// test eax, 0x40000000 // BLOCKTYPE_NEEDCLEAR -// jz Done -// // move new pc -// and eax, 0x0fffffff -// mov ecx, cpuRegs.pc -// mov dword ptr [eax+1], ecx -// } - __asm { - and eax, 0x0fffffff - mov edx, eax - pop ecx // x86Ptr to mod - sub edx, ecx - sub edx, 4 - mov dword ptr [ecx], edx - - jmp eax - } -} - -__declspec(naked,noreturn) void DispatcherClear() -{ - // EDX contains the current pc - __asm mov cpuRegs.pc, edx - __asm push edx - - // calc PC_GETBLOCK - s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc); - - if( s_pDispatchBlock->startpc == cpuRegs.pc ) { - assert( s_pDispatchBlock->pFnptr != 0 ); - - // already modded the code, jump to the new place - __asm { - pop edx - add esp, 4 // ignore stack - mov eax, s_pDispatchBlock - mov eax, dword ptr [eax] - and eax, 0x0fffffff - jmp eax - } - } - - __asm { - call recRecompile - add esp, 4 // pop old param - mov eax, s_pDispatchBlock - mov eax, dword ptr [eax] - - pop ecx // old fnptr - - and eax, 0x0fffffff - mov byte ptr [ecx], 0xe9 // jmp32 - mov edx, eax - sub edx, ecx - sub edx, 5 - mov dword ptr [ecx+1], edx - - jmp eax - } -} - -// called when jumping to variable pc address -__declspec(naked,noreturn) void DispatcherReg() -{ - __asm { - //s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc); - mov edx, cpuRegs.pc - mov ecx, edx - } - - __asm { - shr edx, 14 - and edx, 0xfffffffc - add edx, recLUT - mov edx, dword ptr [edx] - - mov eax, ecx - and eax, 0xfffc - // edx += 2*eax - shl eax, 1 - add edx, eax - - // check if startpc == cpuRegs.pc - mov eax, ecx - //and eax, 0x5fffffff // remove higher bits - cmp eax, dword ptr [edx+BLOCKTYPE_STARTPC] - jne recomp - - mov eax, dword ptr [edx] - } - -#ifdef _DEBUG - __asm mov g_EEDispatchTemp, eax - assert( g_EEDispatchTemp ); -#endif - - __asm { - and eax, 0x0fffffff - jmp eax // fnptr - -recomp: - sub esp, 8 - mov dword ptr [esp+4], edx - mov dword ptr [esp], ecx - call recRecompile - mov edx, dword ptr [esp+4] - add esp, 8 - - mov eax, dword ptr [edx] - and eax, 0x0fffffff - jmp eax // fnptr - } -} - -#ifdef PCSX2_DEVBUILD -__declspec(naked) void _StartPerfCounter() -{ - __asm { - push eax - push ebx - push ecx - - rdtsc - mov dword ptr [offset lbase], eax - mov dword ptr [offset lbase + 4], edx - - pop ecx - pop ebx - pop eax - ret - } -} - -__declspec(naked) void _StopPerfCounter() -{ - __asm { - push eax - push ebx - push ecx - - rdtsc - - sub eax, dword ptr [offset lbase] - sbb edx, dword ptr [offset lbase + 4] - mov ecx, s_pCurBlock_ltime - add eax, dword ptr [ecx] - adc edx, dword ptr [ecx + 4] - mov dword ptr [ecx], eax - mov dword ptr [ecx + 4], edx - pop ecx - pop ebx - pop eax - ret - } -} - -#endif // PCSX2_DEVBUILD - -#else // _MSC_VER - -extern void Dispatcher(); -extern void DispatcherClear(); -extern void DispatcherReg(); -extern void _StartPerfCounter(); -extern void _StopPerfCounter(); - -#endif - -#ifdef PCSX2_DEVBUILD -void StartPerfCounter() -{ -#ifdef PCSX2_DEVBUILD - if( s_startcount ) { - CALLFunc((u32)_StartPerfCounter); - } -#endif -} - -void StopPerfCounter() -{ -#ifdef PCSX2_DEVBUILD - if( s_startcount ) { - MOV32ItoM((u32)&s_pCurBlock_ltime, (u32)&s_pCurBlockEx->ltime); - CALLFunc((u32)_StopPerfCounter); - } -#endif -} -#endif - -//////////////////////////////////////////////////// -void recClear64(BASEBLOCK* p) -{ - int left = 4 - ((u32)p % 16)/sizeof(BASEBLOCK); - recClearMem(p); - - if( left > 1 && *(u32*)(p+1) ) recClearMem(p+1); -} - -void recClear128(BASEBLOCK* p) -{ - int left = 4 - ((u32)p % 32)/sizeof(BASEBLOCK); - recClearMem(p); - - if( left > 1 && *(u32*)(p+1) ) recClearMem(p+1); - if( left > 2 && *(u32*)(p+2) ) recClearMem(p+2); - if( left > 3 && *(u32*)(p+3) ) recClearMem(p+3); -} - -void recClear( u32 Addr, u32 Size ) -{ - u32 i; - for(i = 0; i < Size; ++i, Addr+=4) { - REC_CLEARM(Addr); - } -} - -#define EE_MIN_BLOCK_BYTES 15 - -void recClearMem(BASEBLOCK* p) -{ - BASEBLOCKEX* pexblock; - BASEBLOCK* pstart; - int lastdelay; - - // necessary since recompiler doesn't call femms/emms -#ifdef _MSC_VER - if (cpucaps.has3DNOWInstructionExtensions) __asm femms; - else __asm emms; -#else - if( cpucaps.has3DNOWInstructionExtensions )__asm__("femms"); - else __asm__("emms"); -#endif - - assert( p != NULL ); - - if( p->uType & BLOCKTYPE_DELAYSLOT ) { - recClearMem(p-1); - if( p->pFnptr == 0 ) - return; - } - - assert( p->pFnptr != 0 ); - assert( p->startpc ); - - x86Ptr = (s8*)p->pFnptr; - - // there is a small problem: mem can be ored with 0xa<<28 or 0x8<<28, and don't know which - MOV32ItoR(EDX, p->startpc); - PUSH32I((u32)x86Ptr); // will be replaced by JMP32 - JMP32((u32)DispatcherClear - ( (u32)x86Ptr + 5 )); - assert( x86Ptr == (s8*)p->pFnptr + EE_MIN_BLOCK_BYTES ); - - pstart = PC_GETBLOCK(p->startpc); - pexblock = PC_GETBLOCKEX(pstart); - assert( pexblock->startpc == pstart->startpc ); - - if( pexblock->startpc != pstart->startpc ) { - // some bug with ffx after beating a big snake in sewers - RemoveBaseBlockEx(pexblock, 0); - pexblock->size = 0; - pexblock->startpc = 0; - return; - } - -// if( pexblock->pOldFnptr ) { -// // have to mod oldfnptr too -// x86Ptr = pexblock->pOldFnptr; -// -// MOV32ItoR(EDX, p->startpc); -// JMP32((u32)DispatcherClear - ( (u32)x86Ptr + 5 )); -// } -// else -// pexblock->pOldFnptr = (u8*)p->pFnptr; - - // don't delete if last is delay - lastdelay = pexblock->size; - if( pstart[pexblock->size-1].uType & BLOCKTYPE_DELAYSLOT ) { - assert( pstart[pexblock->size-1].pFnptr != pstart->pFnptr ); - if( pstart[pexblock->size-1].pFnptr != 0 ) { - pstart[pexblock->size-1].uType = 0; - --lastdelay; - } - } - - memset(pstart, 0, lastdelay*sizeof(BASEBLOCK)); - - RemoveBaseBlockEx(pexblock, 0); - pexblock->size = 0; - pexblock->startpc = 0; -} - -// check for end of bios -void CheckForBIOSEnd() -{ - MOV32MtoR(EAX, (int)&cpuRegs.pc); - - CMP32ItoR(EAX, 0x00200008); - j8Ptr[0] = JE8(0); - - CMP32ItoR(EAX, 0x00100008); - j8Ptr[1] = JE8(0); - - // return - j8Ptr[2] = JMP8(0); - - x86SetJ8( j8Ptr[0] ); - x86SetJ8( j8Ptr[1] ); - - // bios end - RET2(); - - x86SetJ8( j8Ptr[2] ); -} - -static int *s_pCode; - -void SetBranchReg( u32 reg ) -{ - branch = 1; - - if( reg != 0xffffffff ) { -// if( GPR_IS_CONST1(reg) ) -// MOV32ItoM( (u32)&cpuRegs.pc, g_cpuConstRegs[reg].UL[0] ); -// else { -// int mmreg; -// -// if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, reg, MODE_READ)) >= 0 ) { -// SSE_MOVSS_XMM_to_M32((u32)&cpuRegs.pc, mmreg); -// } -// else if( (mmreg = _checkMMXreg(MMX_GPR+reg, MODE_READ)) >= 0 ) { -// MOVDMMXtoM((u32)&cpuRegs.pc, mmreg); -// SetMMXstate(); -// } -// else { -// MOV32MtoR(EAX, (int)&cpuRegs.GPR.r[ reg ].UL[ 0 ] ); -// MOV32RtoM((u32)&cpuRegs.pc, EAX); -// } -// } - _allocX86reg(ESI, X86TYPE_PCWRITEBACK, 0, MODE_WRITE); - _eeMoveGPRtoR(ESI, reg); - - recompileNextInstruction(1); - - if( x86regs[ESI].inuse ) { - assert( x86regs[ESI].type == X86TYPE_PCWRITEBACK ); - MOV32RtoM((int)&cpuRegs.pc, ESI); - x86regs[ESI].inuse = 0; - } - else { - MOV32MtoR(EAX, (u32)&g_recWriteback); - MOV32RtoM((int)&cpuRegs.pc, EAX); - } - } - -// CMP32ItoM((u32)&cpuRegs.pc, 0); -// j8Ptr[5] = JNE8(0); -// CALLFunc((u32)tempfn); -// x86SetJ8( j8Ptr[5] ); - - iFlushCall(FLUSH_EVERYTHING); - - iBranchTest(0xffffffff, 1); - if( bExecBIOS ) CheckForBIOSEnd(); - - JMP32((u32)DispatcherReg - ( (u32)x86Ptr + 5 )); -} - -void SetBranchImm( u32 imm ) -{ - u32* ptr; - branch = 1; - - assert( imm ); - - // end the current block - MOV32ItoM( (u32)&cpuRegs.pc, imm ); - iFlushCall(FLUSH_EVERYTHING); - - iBranchTest(imm, imm <= pc); - if( bExecBIOS ) CheckForBIOSEnd(); - - MOV32ItoR(EDX, 0); - ptr = (u32*)(x86Ptr-4); - *ptr = (u32)JMP32((u32)Dispatcher - ( (u32)x86Ptr + 5 )); -} - -void SaveBranchState() -{ - s_savex86FpuState = x86FpuState; - s_saveiCWstate = iCWstate; - s_savenBlockCycles = s_nBlockCycles; - s_saveConstGPRreg = 0xffffffff; // indicate searching - s_saveHasConstReg = g_cpuHasConstReg; - s_saveFlushedConstReg = g_cpuFlushedConstReg; - s_psaveInstInfo = g_pCurInstInfo; - s_saveRegHasLive1 = g_cpuRegHasLive1; - s_saveRegHasSignExt = g_cpuRegHasSignExt; - - // save all mmx regs - memcpy(s_saveMMXregs, mmxregs, sizeof(mmxregs)); - memcpy(s_saveXMMregs, xmmregs, sizeof(xmmregs)); -} - -void LoadBranchState() -{ - x86FpuState = s_savex86FpuState; - iCWstate = s_saveiCWstate; - s_nBlockCycles = s_savenBlockCycles; - - if( s_saveConstGPRreg != 0xffffffff ) { - assert( s_saveConstGPRreg > 0 ); - - // make sure right GPR was saved - assert( g_cpuHasConstReg == s_saveHasConstReg || (g_cpuHasConstReg ^ s_saveHasConstReg) == (1<visited, 1 ); - } -#endif - -#ifdef _DEBUG - //CALLFunc((u32)testfpu); -#endif - - if( !USE_FAST_BRANCHES || cpuBranch ) { - MOV32MtoR(ECX, (int)&cpuRegs.cycle); - ADD32ItoR(ECX, s_nBlockCycles*EECYCLE_MULT); // NOTE: mulitply cycles here, 6/5 ratio stops pal ffx from randomly crashing, but crashes jakI - MOV32RtoM((int)&cpuRegs.cycle, ECX); // update cycles - } - else { - ADD32ItoM((int)&cpuRegs.cycle, s_nBlockCycles*EECYCLE_MULT); - return; - } - - SUB32MtoR(ECX, (int)&g_nextBranchCycle); - - // check if should branch - j8Ptr[0] = JS8( 0 ); - - // has to be in the middle of Save/LoadBranchState - CALLFunc( (int)cpuBranchTest ); - - if( newpc != 0xffffffff ) { - CMP32ItoM((int)&cpuRegs.pc, newpc); - JNE32((u32)DispatcherReg - ( (u32)x86Ptr + 6 )); - } - - x86SetJ8( j8Ptr[0] ); -} - - -//////////////////////////////////////////////////// -#ifndef CP2_RECOMPILE - -REC_SYS(COP2); - -#else - -void recCOP2( void ) -{ -#ifdef CPU_LOG - CPU_LOG( "Recompiling COP2:%s\n", disR5900Fasm( cpuRegs.code, cpuRegs.pc ) ); -#endif - - if ( !cpucaps.hasStreamingSIMDExtensions ) { - MOV32ItoM( (u32)&cpuRegs.code, cpuRegs.code ); - MOV32ItoM( (u32)&cpuRegs.pc, pc ); - iFlushCall(FLUSH_EVERYTHING); - g_cpuHasConstReg = 1; // reset all since COP2 can change regs - CALLFunc( (u32)COP2 ); - - CMP32ItoM((int)&cpuRegs.pc, pc); - j8Ptr[0] = JE8(0); - ADD32ItoM((u32)&cpuRegs.cycle, s_nBlockCycles); - JMP32((u32)DispatcherReg - ( (u32)x86Ptr + 5 )); - x86SetJ8(j8Ptr[0]); - } - else - { - recCOP22( ); - } -} - -#endif - -//////////////////////////////////////////////////// -void recSYSCALL( void ) { - MOV32ItoM( (u32)&cpuRegs.code, cpuRegs.code ); - MOV32ItoM( (u32)&cpuRegs.pc, pc ); - iFlushCall(FLUSH_NODESTROY); - CALLFunc( (u32)SYSCALL ); - - CMP32ItoM((int)&cpuRegs.pc, pc); - j8Ptr[0] = JE8(0); - ADD32ItoM((u32)&cpuRegs.cycle, s_nBlockCycles); - JMP32((u32)DispatcherReg - ( (u32)x86Ptr + 5 )); - x86SetJ8(j8Ptr[0]); - //branch = 2; -} - -//////////////////////////////////////////////////// -void recBREAK( void ) { - MOV32ItoM( (u32)&cpuRegs.code, cpuRegs.code ); - MOV32ItoM( (u32)&cpuRegs.pc, pc ); - iFlushCall(FLUSH_EVERYTHING); - CALLFunc( (u32)BREAK ); - - CMP32ItoM((int)&cpuRegs.pc, pc); - j8Ptr[0] = JE8(0); - ADD32ItoM((u32)&cpuRegs.cycle, s_nBlockCycles); - RET(); - x86SetJ8(j8Ptr[0]); - //branch = 2; -} - -//////////////////////////////////////////////////// -//static void recCACHE( void ) { -// MOV32ItoM( (u32)&cpuRegs.code, cpuRegs.code ); -// MOV32ItoM( (u32)&cpuRegs.pc, pc ); -// iFlushCall(FLUSH_EVERYTHING); -// CALLFunc( (u32)CACHE ); -// //branch = 2; -// -// CMP32ItoM((int)&cpuRegs.pc, pc); -// j8Ptr[0] = JE8(0); -// RET(); -// x86SetJ8(j8Ptr[0]); -//} - - -void recPREF( void ) -{ -} - -void recSYNC( void ) -{ -} - -void recMFSA( void ) -{ - int mmreg; - if (!_Rd_) return; - - mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, MODE_WRITE); - if( mmreg >= 0 ) { - SSE_MOVLPS_M64_to_XMM(mmreg, (u32)&cpuRegs.sa); - } - else if( (mmreg = _checkMMXreg(MMX_GPR+_Rd_, MODE_WRITE)) >= 0 ) { - MOVDMtoMMX(mmreg, (u32)&cpuRegs.sa); - SetMMXstate(); - } - else { - MOV32MtoR(EAX, (u32)&cpuRegs.sa); - _deleteEEreg(_Rd_, 0); - MOV32RtoM((u32)&cpuRegs.GPR.r[_Rd_].UL[0], EAX); - MOV32ItoM((u32)&cpuRegs.GPR.r[_Rd_].UL[1], 0); - } -} - -void recMTSA( void ) -{ - if( GPR_IS_CONST1(_Rs_) ) { - MOV32ItoM((u32)&cpuRegs.sa, g_cpuConstRegs[_Rs_].UL[0] ); - } - else { - int mmreg; - - if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) { - SSE_MOVSS_XMM_to_M32((u32)&cpuRegs.sa, mmreg); - } - else if( (mmreg = _checkMMXreg(MMX_GPR+_Rs_, MODE_READ)) >= 0 ) { - MOVDMMXtoM((u32)&cpuRegs.sa, mmreg); - SetMMXstate(); - } - else { - MOV32MtoR(EAX, (u32)&cpuRegs.GPR.r[_Rs_].UL[0]); - MOV32RtoM((u32)&cpuRegs.sa, EAX); - } - } -} - -void recMTSAB( void ) -{ - if( GPR_IS_CONST1(_Rs_) ) { - MOV32ItoM((u32)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF)) << 3); - } - else { - _eeMoveGPRtoR(EAX, _Rs_); - AND32ItoR(EAX, 0xF); - XOR32ItoR(EAX, _Imm_&0xf); - SHL32ItoR(EAX, 3); - MOV32RtoM((u32)&cpuRegs.sa, EAX); - } -} - -void recMTSAH( void ) -{ - if( GPR_IS_CONST1(_Rs_) ) { - MOV32ItoM((u32)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 4); - } - else { - _eeMoveGPRtoR(EAX, _Rs_); - AND32ItoR(EAX, 0x7); - XOR32ItoR(EAX, _Imm_&0x7); - SHL32ItoR(EAX, 4); - MOV32RtoM((u32)&cpuRegs.sa, EAX); - } -} - -static void checkcodefn() -{ - int pctemp; - -#ifdef _MSC_VER - __asm mov pctemp, eax; -#else - __asm__("movl %%eax, %0" : "=m"(pctemp) ); -#endif - - SysPrintf("code changed! %x\n", pctemp); - assert(0); -} - -void checkpchanged(u32 startpc) -{ - assert(0); -} - -//#ifdef _DEBUG -//#define CHECK_XMMCHANGED() CALLFunc((u32)checkxmmchanged); -//#else -//#define CHECK_XMMCHANGED() -//#endif -// -//static void checkxmmchanged() -//{ -// assert( !g_globalMMXSaved ); -// assert( !g_globalXMMSaved ); -//} - -u32 recompileCodeSafe(u32 temppc) -{ - BASEBLOCK* pblock = PC_GETBLOCK(temppc); - - if( pblock->pFnptr != 0 && pblock->startpc != s_pCurBlock->startpc ) { - if( pc == pblock->startpc ) - return 0; - } - - return 1; -} - -void recompileNextInstruction(int delayslot) -{ - static u8 s_bFlushReg = 1; - int i, count; - - BASEBLOCK* pblock = PC_GETBLOCK(pc); - - // need *ppblock != s_pCurBlock because of branches - if( pblock->pFnptr != 0 && pblock->startpc != s_pCurBlock->startpc ) { - - if( !delayslot && pc == pblock->startpc ) { - // code already in place, so jump to it and exit recomp - assert( PC_GETBLOCKEX(pblock)->startpc == pblock->startpc ); - - iFlushCall(FLUSH_EVERYTHING); - MOV32ItoM((u32)&cpuRegs.pc, pc); - -// if( pexblock->pOldFnptr ) { -// // code already in place, so jump to it and exit recomp -// JMP32((u32)pexblock->pOldFnptr - ((u32)x86Ptr + 5)); -// branch = 3; -// return; -// } - - JMP32((u32)pblock->pFnptr - ((u32)x86Ptr + 5)); - branch = 3; - return; - } - else { - - if( !(delayslot && pblock->startpc == pc) ) { - s8* oldX86 = x86Ptr; - //__Log("clear block %x\n", pblock->startpc); - recClearMem(pblock); - x86Ptr = oldX86; - if( delayslot ) - SysPrintf("delay slot %x\n", pc); - } - } - } - - if( delayslot ) - pblock->uType = BLOCKTYPE_DELAYSLOT; - - s_pCode = (int *)PSM( pc ); - assert(s_pCode); - -#ifdef _DEBUG - MOV32ItoR(EAX, pc); -#endif - - cpuRegs.code = *(int *)s_pCode; - s_nBlockCycles++; - pc += 4; - -//#ifdef _DEBUG -// CMP32ItoM((u32)s_pCode, cpuRegs.code); -// j8Ptr[0] = JE8(0); -// MOV32ItoR(EAX, pc); -// CALLFunc((u32)checkcodefn); -// x86SetJ8( j8Ptr[ 0 ] ); -// -// if( !delayslot ) { -// CMP32ItoM((u32)&cpuRegs.pc, s_pCurBlockEx->startpc); -// j8Ptr[0] = JB8(0); -// CMP32ItoM((u32)&cpuRegs.pc, pc); -// j8Ptr[1] = JA8(0); -// j8Ptr[2] = JMP8(0); -// x86SetJ8( j8Ptr[ 0 ] ); -// x86SetJ8( j8Ptr[ 1 ] ); -// PUSH32I(s_pCurBlockEx->startpc); -// CALLFunc((u32)checkpchanged); -// ADD32ItoR(ESP, 4); -// x86SetJ8( j8Ptr[ 2 ] ); -// } -//#endif - - g_pCurInstInfo++; - - // reorder register priorities -// for(i = 0; i < X86REGS; ++i) { -// if( x86regs[i].inuse ) { -// if( count > 0 ) mmxregs[i].counter = 1000-count; -// else mmxregs[i].counter = 0; -// } -// } - - for(i = 0; i < MMXREGS; ++i) { - if( mmxregs[i].inuse ) { - assert( MMX_ISGPR(mmxregs[i].reg) ); - count = _recIsRegWritten(g_pCurInstInfo, (s_nEndBlock-pc)/4 + 1, XMMTYPE_GPRREG, mmxregs[i].reg-MMX_GPR); - if( count > 0 ) mmxregs[i].counter = 1000-count; - else mmxregs[i].counter = 0; - } - } - - for(i = 0; i < XMMREGS; ++i) { - if( xmmregs[i].inuse ) { - count = _recIsRegWritten(g_pCurInstInfo, (s_nEndBlock-pc)/4 + 1, xmmregs[i].type, xmmregs[i].reg); - if( count > 0 ) xmmregs[i].counter = 1000-count; - else xmmregs[i].counter = 0; - } - } - - // peephole optimizations - if( g_pCurInstInfo->info & EEINSTINFO_COREC ) { - -#ifdef PCSX2_VIRTUAL_MEM - if( g_pCurInstInfo->numpeeps > 1 ) { - switch(cpuRegs.code>>26) { - case 30: recLQ_coX(g_pCurInstInfo->numpeeps); break; - case 31: recSQ_coX(g_pCurInstInfo->numpeeps); break; - case 49: recLWC1_coX(g_pCurInstInfo->numpeeps); break; - case 57: recSWC1_coX(g_pCurInstInfo->numpeeps); break; - case 55: recLD_coX(g_pCurInstInfo->numpeeps); break; - case 63: recSD_coX(g_pCurInstInfo->numpeeps); break; - default: - assert(0); - } - - pc += g_pCurInstInfo->numpeeps*4; - s_nBlockCycles += g_pCurInstInfo->numpeeps; - g_pCurInstInfo += g_pCurInstInfo->numpeeps; - } - else { - recBSC_co[cpuRegs.code>>26](); - pc += 4; - s_nBlockCycles++; - g_pCurInstInfo++; - } -#else - assert(0); -#endif - } - else { - assert( !(g_pCurInstInfo->info & EEINSTINFO_NOREC) ); - - // if this instruction is a jump or a branch, exit right away - if( delayslot ) { - switch(cpuRegs.code>>26) { - case 1: - switch(_Rt_) { - case 0: case 1: case 2: case 3: case 0x10: case 0x11: case 0x12: case 0x13: - SysPrintf("branch %x in delay slot!\n", cpuRegs.code); - _clearNeededX86regs(); - _clearNeededMMXregs(); - _clearNeededXMMregs(); - return; - } - break; - - case 2: case 3: case 4: case 5: case 6: case 7: case 0x14: case 0x15: case 0x16: case 0x17: - SysPrintf("branch %x in delay slot!\n", cpuRegs.code); - _clearNeededX86regs(); - _clearNeededMMXregs(); - _clearNeededXMMregs(); - return; - } - } - recBSC[ cpuRegs.code >> 26 ](); - } - - if( !delayslot ) { - if( s_bFlushReg ) { - //if( !_flushUnusedConstReg() ) { - int flushed = 0; - if( _getNumMMXwrite() > 3 ) flushed = _flushMMXunused(); - if( !flushed && _getNumXMMwrite() > 2 ) _flushXMMunused(); - s_bFlushReg = !flushed; -// } -// else s_bFlushReg = 0; - } - else s_bFlushReg = 1; - } - else s_bFlushReg = 1; - - //CHECK_XMMCHANGED(); - _clearNeededX86regs(); - _clearNeededMMXregs(); - _clearNeededXMMregs(); - -// _freeXMMregs(); -// _freeMMXregs(); -// _flushCachedRegs(); -// g_cpuHasConstReg = 1; -} - -//__declspec(naked) void iDummyBlock() -//{ -//// g_lastpc = cpuRegs.pc; -//// -//// do { -//// cpuRegs.cycle = g_nextBranchCycle; -//// cpuBranchTest(); -//// } while(g_lastpc == cpuRegs.pc); -//// -//// __asm jmp DispatcherReg -// __asm { -//RepDummy: -// add cpuRegs.cycle, 9 -// call cpuBranchTest -// cmp cpuRegs.pc, 0x81fc0 -// je RepDummy -// jmp DispatcherReg -// } -//} - -//////////////////////////////////////////////////// -#include "R3000A.h" -#include "PsxCounters.h" -#include "PsxMem.h" -extern tIPU_BP g_BP; - -extern u32 psxdump; -extern u32 psxNextCounter, psxNextsCounter; -extern void iDumpPsxRegisters(u32 startpc, u32 temp); -extern Counter counters[6]; -extern int rdram_devices; // put 8 for TOOL and 2 for PS2 and PSX -extern int rdram_sdevid; - -void iDumpRegisters(u32 startpc, u32 temp) -{ - int i; - char* pstr = temp ? "t" : ""; - const u32 dmacs[] = {0x8000, 0x9000, 0xa000, 0xb000, 0xb400, 0xc000, 0xc400, 0xc800, 0xd000, 0xd400 }; - extern char *disRNameGPR[]; - char* psymb; - - psymb = disR5900GetSym(startpc); - - if( psymb != NULL ) - __Log("%sreg(%s): %x %x c:%x\n", pstr, psymb, startpc, cpuRegs.interrupt, cpuRegs.cycle); - else - __Log("%sreg: %x %x c:%x\n", pstr, startpc, cpuRegs.interrupt, cpuRegs.cycle); - for(i = 1; i < 32; ++i) __Log("%s: %x_%x_%x_%x\n", disRNameGPR[i], cpuRegs.GPR.r[i].UL[3], cpuRegs.GPR.r[i].UL[2], cpuRegs.GPR.r[i].UL[1], cpuRegs.GPR.r[i].UL[0]); - //for(i = 0; i < 32; i+=4) __Log("cp%d: %x_%x_%x_%x\n", i, cpuRegs.CP0.r[i], cpuRegs.CP0.r[i+1], cpuRegs.CP0.r[i+2], cpuRegs.CP0.r[i+3]); - //for(i = 0; i < 32; ++i) __Log("%sf%d: %f %x\n", pstr, i, fpuRegs.fpr[i].f, fpuRegs.fprc[i]); - //for(i = 1; i < 32; ++i) __Log("%svf%d: %f %f %f %f, vi: %x\n", pstr, i, VU0.VF[i].F[3], VU0.VF[i].F[2], VU0.VF[i].F[1], VU0.VF[i].F[0], VU0.VI[i].UL); - for(i = 0; i < 32; ++i) __Log("%sf%d: %x %x\n", pstr, i, fpuRegs.fpr[i].UL, fpuRegs.fprc[i]); - for(i = 1; i < 32; ++i) __Log("%svf%d: %x %x %x %x, vi: %x\n", pstr, i, VU0.VF[i].UL[3], VU0.VF[i].UL[2], VU0.VF[i].UL[1], VU0.VF[i].UL[0], VU0.VI[i].UL); - __Log("%svfACC: %x %x %x %x\n", pstr, VU0.ACC.UL[3], VU0.ACC.UL[2], VU0.ACC.UL[1], VU0.ACC.UL[0]); - __Log("%sLO: %x_%x_%x_%x, HI: %x_%x_%x_%x\n", pstr, cpuRegs.LO.UL[3], cpuRegs.LO.UL[2], cpuRegs.LO.UL[1], cpuRegs.LO.UL[0], - cpuRegs.HI.UL[3], cpuRegs.HI.UL[2], cpuRegs.HI.UL[1], cpuRegs.HI.UL[0]); - __Log("%sCycle: %x %x, Count: %x\n", pstr, cpuRegs.cycle, g_nextBranchCycle, cpuRegs.CP0.n.Count); - iDumpPsxRegisters(psxRegs.pc, temp); - - __Log("f410,30,40: %x %x %x, %d %d\n", psHu32(0xf410), psHu32(0xf430), psHu32(0xf440), rdram_sdevid, rdram_devices); - __Log("cyc11: %x %x; vu0: %x, vu1: %x\n", cpuRegs.sCycle[1], cpuRegs.eCycle[1], VU0.cycle, VU1.cycle); - - __Log("%scounters: %x %x; psx: %x %x\n", pstr, nextsCounter, nextCounter, psxNextsCounter, psxNextCounter); - for(i = 0; i < 4; ++i) { - __Log("eetimer%d: count: %x mode: %x target: %x %x; %x %x; %x %x %x %x\n", i, - counters[i].count, counters[i].mode, counters[i].target, counters[i].hold, counters[i].rate, - counters[i].interrupt, counters[i].Cycle, counters[i].sCycle, counters[i].CycleT, counters[i].sCycleT); - } - __Log("VIF0_STAT = %x, VIF1_STAT = %x\n", psHu32(0x3800), psHu32(0x3C00)); - __Log("ipu %x %x %x %x; bp: %x %x %x %x\n", psHu32(0x2000), psHu32(0x2010), psHu32(0x2020), psHu32(0x2030), g_BP.BP, g_BP.bufferhasnew, g_BP.FP, g_BP.IFC); - __Log("gif: %x %x %x\n", psHu32(0x3000), psHu32(0x3010), psHu32(0x3020)); - 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\n", i, p->chcr, p->madr, p->qwc, p->tadr, p->sadr); - } - __Log("dmac %x %x %x %x\n", psHu32(DMAC_CTRL), psHu32(DMAC_STAT), psHu32(DMAC_RBSR), psHu32(DMAC_RBOR)); - __Log("intc %x %x\n", psHu32(INTC_STAT), psHu32(INTC_MASK)); - __Log("sif: %x %x %x %x %x\n", psHu32(0xf200), psHu32(0xf220), psHu32(0xf230), psHu32(0xf240), psHu32(0xf260)); -} - -extern u32 psxdump; - -static void printfn() -{ - static int lastrec = 0; - static int curcount = 0, count2 = 0; - const int skip = 0; - static int i; - - assert( !g_globalMMXSaved ); - assert( !g_globalXMMSaved ); - - if( (dumplog&2) && g_lastpc != 0x81fc0 ) {//&& lastrec != g_lastpc ) { - curcount++; - - if( curcount > skip ) { - iDumpRegisters(g_lastpc, 1); - curcount = 0; - } - - lastrec = g_lastpc; - } -} - -u32 s_recblocks[] = {0}; - -void badespfn() { - assert(0); - SysPrintf("Bad esp!\n"); -} - -#define OPTIMIZE_COP2 0//CHECK_VU0REC - -void recRecompile( u32 startpc ) -{ - u32 i = 0; - u32 branchTo; - u32 willbranch3 = 0; - u32* ptr; - u32 usecop2; - -#ifdef _DEBUG - //dumplog |= 4; - if( dumplog & 4 ) - iDumpRegisters(startpc, 0); -#endif - - assert( startpc ); - - // if recPtr reached the mem limit reset whole mem - if ( ( (uptr)recPtr - (uptr)recMem ) >= REC_CACHEMEM-0x40000 || dumplog == 0xffffffff) { - recReset(); - } - if ( ( (uptr)recStackPtr - (uptr)recStack ) >= RECSTACK_SIZE-0x100 ) { -#ifdef _DEBUG - SysPrintf("stack reset\n"); -#endif - recReset(); - } - - s_pCurBlock = PC_GETBLOCK(startpc); - - if( s_pCurBlock->pFnptr ) { - // clear if already taken - assert( s_pCurBlock->startpc < startpc ); - recClearMem(s_pCurBlock); - } - - if( s_pCurBlock->startpc == startpc ) { - s_pCurBlockEx = PC_GETBLOCKEX(s_pCurBlock); - assert( s_pCurBlockEx->startpc == startpc ); - } - else { - s_pCurBlockEx = NULL; - for(i = 0; i < EE_NUMBLOCKS; ++i) { - if( recBlocks[(i+s_nNextBlock)%EE_NUMBLOCKS].size == 0 ) { - s_pCurBlockEx = recBlocks+(i+s_nNextBlock)%EE_NUMBLOCKS; - s_nNextBlock = (i+s_nNextBlock+1)%EE_NUMBLOCKS; - break; - } - } - - if( s_pCurBlockEx == NULL ) { - //SysPrintf("ee reset (blocks)\n"); - recReset(); - s_nNextBlock = 0; - s_pCurBlockEx = recBlocks; - } - - s_pCurBlockEx->startpc = startpc; - } - - x86SetPtr( recPtr ); - x86Align(16); - recPtr = x86Ptr; - s_pCurBlock->pFnptr = (u32)x86Ptr; - s_pCurBlock->startpc = startpc; - - // slower -// if( startpc == 0x81fc0 ) { -// -// MOV32MtoR(ECX, (u32)&g_nextBranchCycle); -// MOV32RtoM((u32)&cpuRegs.cycle, ECX); -// //ADD32ItoR(ECX, 9); -// //ADD32ItoM((u32)&cpuRegs.cycle, 512); -// CALLFunc((u32)cpuBranchTest); -// CMP32ItoM((u32)&cpuRegs.pc, 0x81fc0); -// JE8(s_pCurBlock->pFnptr - (u32)(x86Ptr+2) ); -// JMP32((u32)DispatcherReg - (u32)(x86Ptr+5)); -// -// pc = startpc + 9*4; -// assert( (pc-startpc)>>2 <= 0xffff ); -// s_pCurBlockEx->size = (pc-startpc)>>2; -// -// for(i = 1; i < (u32)s_pCurBlockEx->size-1; ++i) { -// s_pCurBlock[i].pFnptr = s_pCurBlock->pFnptr; -// s_pCurBlock[i].startpc = s_pCurBlock->startpc; -// } -// -// // don't overwrite if delay slot -// if( i < (u32)s_pCurBlockEx->size && !(s_pCurBlock[i].uType & BLOCKTYPE_DELAYSLOT) ) { -// s_pCurBlock[i].pFnptr = s_pCurBlock->pFnptr; -// s_pCurBlock[i].startpc = s_pCurBlock->startpc; -// } -// -// // set the block ptr -// AddBaseBlockEx(s_pCurBlockEx, 0); -// -// if( !(pc&0x10000000) ) -// maxrecmem = max( (pc&~0xa0000000), maxrecmem ); -// -// recPtr = x86Ptr; -// return; -// } - - branch = 0; - - // reset recomp state variables - s_nBlockCycles = 0; - pc = startpc; - x86FpuState = FPU_STATE; - iCWstate = 0; - s_saveConstGPRreg = 0; - g_cpuHasConstReg = g_cpuFlushedConstReg = 1; - g_cpuPrevRegHasLive1 = g_cpuRegHasLive1 = 0xffffffff; - g_cpuPrevRegHasSignExt = g_cpuRegHasSignExt = 0; - _recClearWritebacks(); - assert( g_cpuConstRegs[0].UD[0] == 0 ); - - _initX86regs(); - _initXMMregs(); - _initMMXregs(); - -#ifdef _DEBUG - // for debugging purposes - MOV32ItoM((u32)&g_lastpc, pc); - CALLFunc((u32)printfn); - -// CMP32MtoR(EBP, (u32)&s_uSaveEBP); -// j8Ptr[0] = JE8(0); -// CALLFunc((u32)badespfn); -// x86SetJ8(j8Ptr[0]); -#endif - - // go until the next branch - i = startpc; - s_nEndBlock = 0xffffffff; - s_nHasDelay = 0; - - while(1) { - BASEBLOCK* pblock = PC_GETBLOCK(i); - if( pblock->pFnptr != 0 && pblock->startpc != s_pCurBlock->startpc ) { - - if( i == pblock->startpc ) { - // branch = 3 - willbranch3 = 1; - s_nEndBlock = i; - break; - } - } - - cpuRegs.code = *(int *)PSM(i); - - switch(cpuRegs.code >> 26) { - case 0: // special - - if( _Funct_ == 8 || _Funct_ == 9 ) { // JR, JALR - s_nEndBlock = i + 8; - s_nHasDelay = 1; - goto StartRecomp; - } - - break; - case 1: // regimm - - if( _Rt_ < 4 || (_Rt_ >= 16 && _Rt_ < 20) ) { - // branches - if( _Rt_ == 2 && _Rt_ == 3 && _Rt_ == 18 && _Rt_ == 19 ) s_nHasDelay = 1; - else s_nHasDelay = 2; - - branchTo = _Imm_ * 4 + i + 4; - if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo; - else s_nEndBlock = i+8; - - goto StartRecomp; - } - - break; - - case 2: // J - case 3: // JAL - s_nHasDelay = 1; - s_nEndBlock = i + 8; - goto StartRecomp; - - // branches - case 4: case 5: case 6: case 7: - case 20: case 21: case 22: case 23: - - if( (cpuRegs.code >> 26) >= 20 ) s_nHasDelay = 1; - else s_nHasDelay = 2; - - branchTo = _Imm_ * 4 + i + 4; - if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo; - else s_nEndBlock = i+8; - - goto StartRecomp; - - case 16: // cp0 - if( _Rs_ == 16 ) { - if( _Funct_ == 24 ) { // eret - s_nEndBlock = i+4; - goto StartRecomp; - } - } - - break; - case 17: // cp1 - case 18: // cp2 - if( _Rs_ == 8 ) { - // BC1F, BC1T, BC1FL, BC1TL - // BC2F, BC2T, BC2FL, BC2TL - if( _Rt_ >= 2 ) s_nHasDelay = 1; - else s_nHasDelay = 2; - - branchTo = _Imm_ * 4 + i + 4; - if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo; - else s_nEndBlock = i+8; - - goto StartRecomp; - } - break; - } - - i += 4; - } - -StartRecomp: - - // rec info // - { - EEINST* pcur; - - if( s_nInstCacheSize < (s_nEndBlock-startpc)/4+1 ) { - free(s_pInstCache); - s_nInstCacheSize = (s_nEndBlock-startpc)/4+10; - s_pInstCache = (EEINST*)malloc(sizeof(EEINST)*s_nInstCacheSize); - assert( s_pInstCache != NULL ); - } - - pcur = s_pInstCache + (s_nEndBlock-startpc)/4; - _recClearInst(pcur); - pcur->info = 0; - - for(i = s_nEndBlock; i > startpc; i -= 4 ) { - cpuRegs.code = *(int *)PSM(i-4); - pcur[-1] = pcur[0]; - rpropBSC(pcur-1, pcur); - pcur--; - } - } - - // analyze instructions // - { - usecop2 = 0; - g_pCurInstInfo = s_pInstCache; - - for(i = startpc; i < s_nEndBlock; i += 4) { - g_pCurInstInfo++; - cpuRegs.code = *(u32*)PSM(i); - - // cop2 // - if( g_pCurInstInfo->info & EEINSTINFO_COP2 ) { - - if( !usecop2 ) { - // init - if( OPTIMIZE_COP2 ) { - memset(VU0.fmac,0,sizeof(VU0.fmac)); - memset(&VU0.fdiv,0,sizeof(VU0.fdiv)); - memset(&VU0.efu,0,sizeof(VU0.efu)); - } - vucycle = 0; - usecop2 = 1; - } - - VU0.code = cpuRegs.code; - _cop2AnalyzeOp(g_pCurInstInfo, OPTIMIZE_COP2); - continue; - } - - if( usecop2 ) vucycle++; - - // peephole optimizations // -#ifdef PCSX2_VIRTUAL_MEM - if( i < s_nEndBlock-4 && recompileCodeSafe(i) ) { - u32 curcode = cpuRegs.code; - u32 nextcode = *(u32*)PSM(i+4); - if( _eeIsLoadStoreCoIssue(curcode, nextcode) && recBSC_co[curcode>>26] != NULL ) { - - // rs has to be the same, and cannot be just written - if( ((curcode >> 21) & 0x1F) == ((nextcode >> 21) & 0x1F) && !_eeLoadWritesRs(curcode) ) { - - if( _eeIsLoadStoreCoX(curcode) && ((nextcode>>16)&0x1f) != ((curcode>>21)&0x1f) ) { - // see how many stores there are - u32 j; - // use xmmregs since only supporting lwc1,lq,swc1,sq - for(j = i+8; j < s_nEndBlock && j < i+4*XMMREGS; j += 4 ) { - u32 nncode = *(u32*)PSM(j); - if( (nncode>>26) != (curcode>>26) || ((curcode>>21)&0x1f) != ((nncode>>21)&0x1f) || - _eeLoadWritesRs(nncode)) - break; - } - - if( j > i+8 ) { - u32 num = (j-i)>>2; // number of stores that can coissue - assert( num <= XMMREGS ); - - g_pCurInstInfo[0].numpeeps = num-1; - g_pCurInstInfo[0].info |= EEINSTINFO_COREC; - - while(i < j-4) { - g_pCurInstInfo++; - g_pCurInstInfo[0].info |= EEINSTINFO_NOREC; - i += 4; - } - - continue; - } - - // fall through - } - - // unaligned loadstores - - // if LWL, check if LWR and that offsets are +3 away - switch(curcode >> 26) { - case 0x22: // LWL - if( (nextcode>>26) != 0x26 || ((s16)nextcode)+3 != (s16)curcode ) - continue; - break; - case 0x26: // LWR - if( (nextcode>>26) != 0x22 || ((s16)nextcode) != (s16)curcode+3 ) - continue; - break; - - case 0x2a: // SWL - if( (nextcode>>26) != 0x2e || ((s16)nextcode)+3 != (s16)curcode ) - continue; - break; - case 0x2e: // SWR - if( (nextcode>>26) != 0x2a || ((s16)nextcode) != (s16)curcode+3 ) - continue; - break; - - case 0x1a: // LDL - if( (nextcode>>26) != 0x1b || ((s16)nextcode)+7 != (s16)curcode ) - continue; - break; - case 0x1b: // LWR - if( (nextcode>>26) != 0x1aa || ((s16)nextcode) != (s16)curcode+7 ) - continue; - break; - - case 0x2c: // SWL - if( (nextcode>>26) != 0x2d || ((s16)nextcode)+7 != (s16)curcode ) - continue; - break; - case 0x2d: // SWR - if( (nextcode>>26) != 0x2c || ((s16)nextcode) != (s16)curcode+7 ) - continue; - break; - } - - // good enough - g_pCurInstInfo[0].info |= EEINSTINFO_COREC; - g_pCurInstInfo[0].numpeeps = 1; - g_pCurInstInfo[1].info |= EEINSTINFO_NOREC; - g_pCurInstInfo++; - i += 4; - continue; - } - } - } -#endif // end peephole - } - - if( usecop2 ) { - // add necessary mac writebacks - g_pCurInstInfo = s_pInstCache; - - for(i = startpc; i < s_nEndBlock-4; i += 4) { - g_pCurInstInfo++; - - if( g_pCurInstInfo->info & EEINSTINFO_COP2 ) { - } - } - } - } - - // perf counters // -#ifdef PCSX2_DEVBUILD - s_startcount = 0; -// if( pc+32 < s_nEndBlock ) { -// // only blocks with more than 8 insts -// //PUSH32I((u32)&lbase); -// //CALLFunc((u32)QueryPerformanceCounter); -// lbase.QuadPart = GetCPUTick(); -// s_startcount = 1; -// } -#endif - -#ifdef _DEBUG - // dump code - for(i = 0; i < ARRAYSIZE(s_recblocks); ++i) { - if( startpc == s_recblocks[i] ) { - iDumpBlock(startpc, recPtr); - } - } - - if( (dumplog & 1) ) //|| usecop2 ) - iDumpBlock(startpc, recPtr); -#endif - - // finally recompile // - g_pCurInstInfo = s_pInstCache; - while (!branch && pc < s_nEndBlock) { - recompileNextInstruction(0); - } - -#ifdef _DEBUG - if( (dumplog & 1) ) - iDumpBlock(startpc, recPtr); -#endif - - assert( (pc-startpc)>>2 <= 0xffff ); - s_pCurBlockEx->size = (pc-startpc)>>2; - - for(i = 1; i < (u32)s_pCurBlockEx->size-1; ++i) { - s_pCurBlock[i].pFnptr = s_pCurBlock->pFnptr; - s_pCurBlock[i].startpc = s_pCurBlock->startpc; - } - - // don't overwrite if delay slot - if( i < (u32)s_pCurBlockEx->size && !(s_pCurBlock[i].uType & BLOCKTYPE_DELAYSLOT) ) { - s_pCurBlock[i].pFnptr = s_pCurBlock->pFnptr; - s_pCurBlock[i].startpc = s_pCurBlock->startpc; - } - - // set the block ptr - AddBaseBlockEx(s_pCurBlockEx, 0); -// if( p[1].startpc == p[0].startpc + 4 ) { -// assert( p[1].pFnptr != 0 ); -// // already fn in place, so add to list -// AddBaseBlockEx(s_pCurBlockEx, 0); -// } -// else -// *(BASEBLOCKEX**)(p+1) = pex; -// } - - //PC_SETBLOCKEX(s_pCurBlock, s_pCurBlockEx); - - if( !(pc&0x10000000) ) - maxrecmem = max( (pc&~0xa0000000), maxrecmem ); - - if( branch == 2 ) { - iFlushCall(FLUSH_EVERYTHING); - - iBranchTest(0xffffffff, 1); - if( bExecBIOS ) CheckForBIOSEnd(); - - JMP32((u32)DispatcherReg - ( (u32)x86Ptr + 5 )); - } - else { - assert( branch != 3 ); - if( branch ) assert( !willbranch3 ); - else ADD32ItoM((int)&cpuRegs.cycle, s_nBlockCycles*EECYCLE_MULT); - - if( willbranch3 ) { - BASEBLOCK* pblock = PC_GETBLOCK(s_nEndBlock); - assert( pc == s_nEndBlock ); - iFlushCall(FLUSH_EVERYTHING); - MOV32ItoM((u32)&cpuRegs.pc, pc); - JMP32((u32)pblock->pFnptr - ((u32)x86Ptr + 5)); - branch = 3; - } - else if( !branch ) { - // didn't branch, but had to stop - MOV32ItoM( (u32)&cpuRegs.pc, pc ); - - iFlushCall(FLUSH_EVERYTHING); - - ptr = JMP32(0); - } - } - - assert( x86Ptr >= (s8*)s_pCurBlock->pFnptr + EE_MIN_BLOCK_BYTES ); - assert( x86Ptr < recMem+REC_CACHEMEM ); - assert( recStackPtr < recStack+RECSTACK_SIZE ); - assert( x86FpuState == 0 ); - - recPtr = x86Ptr; - - assert( (g_cpuHasConstReg&g_cpuFlushedConstReg) == g_cpuHasConstReg ); - - if( !branch ) { - BASEBLOCK* pcurblock = s_pCurBlock; - u32 nEndBlock = s_nEndBlock; - s_pCurBlock = PC_GETBLOCK(pc); - assert( ptr != NULL ); - - if( s_pCurBlock->startpc != pc ) - recRecompile(pc); - - if( pcurblock->startpc == startpc ) { - assert( pcurblock->pFnptr ); - assert( s_pCurBlock->startpc == nEndBlock ); - *ptr = s_pCurBlock->pFnptr - ( (u32)ptr + 4 ); - } - else { - recRecompile(startpc); - assert( pcurblock->pFnptr != 0 ); - } - } -} - -R5900cpu recCpu = { - recInit, - recReset, - recStep, - recExecute, - recExecuteBlock, - recExecuteVU0Block, - recExecuteVU1Block, - recEnableVU0micro, - recEnableVU1micro, - recClear, - recClearVU0, - recClearVU1, - recShutdown -}; - -#endif // PCSX2_NORECBUILD + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +// recompiler reworked to add dynamic linking zerofrog(@gmail.com) Jan06 +// Recompiled completely rewritten to add block level recompilation/reg-caching/ +// liveness analysis/constant propagation Apr06 (zerofrog@gmail.com) + +// stop compiling if NORECBUILD build (only for Visual Studio) +#if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) + +#include +#include +#include +#include + +#include "Common.h" +#include "Memory.h" +#include "InterTables.h" +#include "ix86/ix86.h" +#include "iR5900.h" +#include "iR5900AritImm.h" +#include "iR5900Arit.h" +#include "iR5900MultDiv.h" +#include "iR5900Shift.h" +#include "iR5900Branch.h" +#include "iR5900Jump.h" +#include "iR5900LoadStore.h" +#include "iR5900Move.h" +#include "iMMI.h" +#include "iFPU.h" +#include "iCP0.h" +#include "iVUmicro.h" +#include "iVU0micro.h" +#include "iVU1micro.h" +#include "VU.h" +#include "VUmicro.h" + +#include "iVUzerorec.h" + +#ifdef _WIN32 +#pragma warning(disable:4244) +#pragma warning(disable:4761) +#endif + +u32 maxrecmem = 0; +uptr *recLUT; + +#define X86 +#define RECSTACK_SIZE 0x00010000 + +#define EE_NUMBLOCKS (1<<15) + +static char *recMem = NULL; // the recompiled blocks will be here +static char* recStack = NULL; // stack mem +static BASEBLOCK *recRAM = NULL; // and the ptr to the blocks here +static BASEBLOCK *recROM = NULL; // and here +static BASEBLOCK *recROM1 = NULL; // also here +static BASEBLOCKEX *recBlocks = NULL; +static char *recPtr = NULL, *recStackPtr = NULL; +static EEINST* s_pInstCache = NULL; +static u32 s_nInstCacheSize = 0; + +u32 g_EEFreezeRegs = 0; // if set, should freeze the regs + +static BASEBLOCK* s_pCurBlock = NULL; +static BASEBLOCKEX* s_pCurBlockEx = NULL; +static BASEBLOCK* s_pDispatchBlock = NULL; +static u32 s_nEndBlock = 0; // what pc the current block ends +static u32 s_nHasDelay = 0; + +static u32 s_nNextBlock = 0; // next free block in recBlocks + +extern void (*recBSC[64])(); +extern void (*recBSC_co[64])(); +void rpropBSC(EEINST* prev, EEINST* pinst); + +// save states for branches +static u16 s_savex86FpuState, s_saveiCWstate; +static GPR_reg64 s_ConstGPRreg; +static u32 s_saveConstGPRreg = 0, s_saveHasConstReg = 0, s_saveFlushedConstReg = 0, s_saveRegHasLive1 = 0, s_saveRegHasSignExt = 0; +static EEINST* s_psaveInstInfo = NULL; + +u32 s_nBlockCycles = 0; // cycles of current block recompiling +static u32 s_savenBlockCycles = 0; + +void recCOP2RecompileInst(); +int recCOP2AnalyzeBlock(u32 startpc, u32 endpc); +void recCOP2EndBlock(void); + +#ifdef _DEBUG +u32 dumplog = 0; +#else +#define dumplog 0 +#endif + +u32 pc; // recompiler pc +int branch; // set for branch + +//#ifdef PCSX2_DEVBUILD +LARGE_INTEGER lbase = {0}, lfinal = {0}; +static u32 s_startcount = 0; +//#endif + +char *txt0 = "EAX = %x : ECX = %x : EDX = %x\n"; +char *txt0RC = "EAX = %x : EBX = %x : ECX = %x : EDX = %x : ESI = %x : EDI = %x\n"; +char *txt1 = "REG[%d] = %x_%x\n"; +char *txt2 = "M32 = %x\n"; + +void _cop2AnalyzeOp(EEINST* pinst, int dostalls); // reccop2.c +static void iBranchTest(u32 newpc, u32 cpuBranch); +void recRecompile( u32 startpc ); +void recCOP22( void ); + +BASEBLOCKEX* PC_GETBLOCKEX(BASEBLOCK* p) +{ +// BASEBLOCKEX* pex = *(BASEBLOCKEX**)(p+1); +// if( pex >= recBlocks && pex < recBlocks+EE_NUMBLOCKS ) +// return pex; + + // otherwise, use the sorted list + return GetBaseBlockEx(p->startpc, 0); +} + +//////////////////////////////////////////////////// +void iDumpBlock( int startpc, char * ptr ) +{ + FILE *f; + char filename[ 256 ]; + u32 i, j; + EEINST* pcur; + extern char *disRNameGPR[]; + u8 used[34]; + u8 fpuused[33]; + int numused, count, fpunumused; + + SysPrintf( "dump1 %x:%x, %x\n", startpc, pc, cpuRegs.cycle ); +#ifdef _WIN32 + CreateDirectory("dumps", NULL); + sprintf( filename, "dumps\\dump%.8X.txt", startpc); +#else + mkdir("dumps", 0755); + sprintf( filename, "dumps/dump%.8X.txt", startpc); +#endif + + fflush( stdout ); +// f = fopen( "dump1", "wb" ); +// fwrite( ptr, 1, (u32)x86Ptr - (u32)ptr, f ); +// fclose( f ); +// +// sprintf( command, "objdump -D --target=binary --architecture=i386 dump1 > %s", filename ); +// system( command ); + + f = fopen( filename, "w" ); + + if( disR5900GetSym(startpc) != NULL ) + fprintf(f, "%s\n", disR5900GetSym(startpc)); + for ( i = startpc; i < s_nEndBlock; i += 4 ) { + fprintf( f, "%s\n", disR5900Fasm( PSMu32( i ), i ) ); + } + + // write the instruction info + + fprintf(f, "\n\nlive0 - %x, live1 - %x, live2 - %x, lastuse - %x\nmmx - %x, xmm - %x, used - %x\n", + EEINST_LIVE0, EEINST_LIVE1, EEINST_LIVE2, EEINST_LASTUSE, EEINST_MMX, EEINST_XMM, EEINST_USED); + + memset(used, 0, sizeof(used)); + numused = 0; + for(i = 0; i < ARRAYSIZE(s_pInstCache->regs); ++i) { + if( s_pInstCache->regs[i] & EEINST_USED ) { + used[i] = 1; + numused++; + } + } + + memset(fpuused, 0, sizeof(fpuused)); + fpunumused = 0; + for(i = 0; i < ARRAYSIZE(s_pInstCache->fpuregs); ++i) { + if( s_pInstCache->fpuregs[i] & EEINST_USED ) { + fpuused[i] = 1; + fpunumused++; + } + } + + fprintf(f, " "); + for(i = 0; i < ARRAYSIZE(s_pInstCache->regs); ++i) { + if( used[i] ) fprintf(f, "%2d ", i); + } + for(i = 0; i < ARRAYSIZE(s_pInstCache->fpuregs); ++i) { + if( fpuused[i] ) fprintf(f, "%2d ", i); + } + fprintf(f, "\n"); + + fprintf(f, " "); + for(i = 0; i < ARRAYSIZE(s_pInstCache->regs); ++i) { + if( used[i] ) fprintf(f, "%s ", disRNameGPR[i]); + } + for(i = 0; i < ARRAYSIZE(s_pInstCache->fpuregs); ++i) { + if( fpuused[i] ) fprintf(f, "%s ", i<32?"FR":"FA"); + } + fprintf(f, "\n"); + + pcur = s_pInstCache+1; + for( i = 0; i < (s_nEndBlock-startpc)/4; ++i, ++pcur) { + fprintf(f, "%2d: %2.2x ", i+1, pcur->info); + + count = 1; + for(j = 0; j < ARRAYSIZE(s_pInstCache->regs); j++) { + if( used[j] ) { + fprintf(f, "%2.2x%s", pcur->regs[j], ((count%8)&&countfpuregs); j++) { + if( fpuused[j] ) { + fprintf(f, "%2.2x%s", pcur->fpuregs[j], ((count%8)&&count>26) { + case 26: // ldl + case 27: // ldr + case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: + case 55: // LD + case 30: // lq + return ((tempcode>>21)&0x1f)==((tempcode>>16)&0x1f); // rs==rt + } + return 0; +} + +u8 _eeIsLoadStoreCoIssue(u32 firstcode, u32 secondcode) +{ + switch(firstcode>>26) { + case 34: // lwl + return (secondcode>>26)==38; + case 38: // lwr + return (secondcode>>26)==34; + case 42: // swl + return (secondcode>>26)==46; + case 46: // swr + return (secondcode>>26)==42; + case 26: // ldl + return (secondcode>>26)==27; + case 27: // ldr + return (secondcode>>26)==26; + case 44: // sdl + return (secondcode>>26)==45; + case 45: // sdr + return (secondcode>>26)==44; + + case 32: case 33: case 35: case 36: case 37: case 39: + case 55: // LD + + // stores + case 40: case 41: case 43: + case 63: // sd + return (secondcode>>26)==(firstcode>>26); + + case 30: // lq + case 31: // sq + case 49: // lwc1 + case 57: // swc1 + case 54: // lqc2 + case 62: // sqc2 + return (secondcode>>26)==(firstcode>>26)&&cpucaps.hasStreamingSIMDExtensions; + } + return 0; +} + +u8 _eeIsLoadStoreCoX(u32 tempcode) +{ + switch( tempcode>>26 ) { + case 30: case 31: case 49: case 57: case 55: case 63: + return 1; + } + return 0; +} + +void _eeFlushAllUnused() +{ + int i; + for(i = 0; i < 34; ++i) { + if( pc < s_nEndBlock ) { + if( (g_pCurInstInfo[1].regs[i]&EEINST_USED) ) + continue; + } + else if( (g_pCurInstInfo[0].regs[i]&EEINST_USED) ) + continue; + + if( i < 32 && GPR_IS_CONST1(i) ) _flushConstReg(i); + else { + _deleteMMXreg(MMX_GPR+i, 1); + _deleteGPRtoXMMreg(i, 1); + } + } + + //TODO when used info is done for FPU and VU0 + for(i = 0; i < XMMREGS; ++i) { + if( xmmregs[i].inuse && xmmregs[i].type != XMMTYPE_GPRREG ) + _freeXMMreg(i); + } +} + +u32* _eeGetConstReg(int reg) +{ + assert( GPR_IS_CONST1( reg ) ); + + if( g_cpuFlushedConstReg & (1<regs[xmmregs[i].reg]&EEINST_USED) ) { + if( !_recIsRegWritten(g_pCurInstInfo+1, (s_nEndBlock-pc)/4, XMMTYPE_GPRREG, xmmregs[i].reg) ) { + _freeXMMreg(i); + xmmregs[i].inuse = 1; + return 1; + } + } + } + + return 0; +} + +int _flushMMXunused() +{ + int i; + for (i=0; iregs[mmxregs[i].reg-MMX_GPR]&EEINST_USED) ) { + if( !_recIsRegWritten(g_pCurInstInfo+1, (s_nEndBlock-pc)/4, XMMTYPE_GPRREG, mmxregs[i].reg-MMX_GPR) ) { + _freeMMXreg(i); + mmxregs[i].inuse = 1; + return 1; + } + } + } + + return 0; +} + +int _flushUnusedConstReg() +{ + int i; + for(i = 1; i < 32; ++i) { + if( (g_cpuHasConstReg & (1<regs[reg]&EEINST_LASTUSE) ) { + if( usemmx ) return _allocMMXreg(-1, MMX_GPR+reg, mode); + return _allocGPRtoXMMreg(-1, reg, mode); + } + + return -1; +} + +#define PROCESS_EE_SETMODES(mmreg) ((mmxregs[mmreg].mode&MODE_WRITE)?PROCESS_EE_MODEWRITES:0) +#define PROCESS_EE_SETMODET(mmreg) ((mmxregs[mmreg].mode&MODE_WRITE)?PROCESS_EE_MODEWRITET:0) + +// ignores XMMINFO_READS, XMMINFO_READT, and XMMINFO_READD_LO from xmminfo +// core of reg caching +void eeRecompileCode0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R5900FNPTR_INFO consttcode, R5900FNPTR_INFO noconstcode, int xmminfo) +{ + int mmreg1, mmreg2, mmreg3, mmtemp, moded; + + if ( ! _Rd_ && (xmminfo&XMMINFO_WRITED) ) return; + + if( xmminfo&XMMINFO_WRITED) { + CHECK_SAVE_REG(_Rd_); + _eeProcessHasLive(_Rd_, 0); + EEINST_RESETSIGNEXT(_Rd_); + } + + if( GPR_IS_CONST2(_Rs_, _Rt_) ) { + if( xmminfo & XMMINFO_WRITED ) { + _deleteMMXreg(MMX_GPR+_Rd_, 2); + _deleteGPRtoXMMreg(_Rd_, 2); + } + if( xmminfo&XMMINFO_WRITED ) GPR_SET_CONST(_Rd_); + constcode(); + return; + } + + moded = MODE_WRITE|((xmminfo&XMMINFO_READD)?MODE_READ:0); + + // test if should write mmx + if( g_pCurInstInfo->info & EEINST_MMX ) { + + if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) _addNeededMMXreg(MMX_GPR+MMX_LO); + if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) _addNeededMMXreg(MMX_GPR+MMX_HI); + _addNeededMMXreg(MMX_GPR+_Rs_); + _addNeededMMXreg(MMX_GPR+_Rt_); + + if( GPR_IS_CONST1(_Rs_) || GPR_IS_CONST1(_Rt_) ) { + int creg = GPR_IS_CONST1(_Rs_) ? _Rs_ : _Rt_; + int vreg = creg == _Rs_ ? _Rt_ : _Rs_; + +// if(g_pCurInstInfo->regs[vreg]&EEINST_MMX) { +// mmreg1 = _allocMMXreg(-1, MMX_GPR+vreg, MODE_READ); +// _addNeededMMXreg(MMX_GPR+vreg); +// } + mmreg1 = _allocCheckGPRtoMMX(g_pCurInstInfo, vreg, MODE_READ); + + if( mmreg1 >= 0 ) { + int info = PROCESS_EE_MMX; + + if( GPR_IS_CONST1(_Rs_) ) info |= PROCESS_EE_SETMODET(mmreg1); + else info |= PROCESS_EE_SETMODES(mmreg1); + + if( xmminfo & XMMINFO_WRITED ) { + _addNeededMMXreg(MMX_GPR+_Rd_); + mmreg3 = _checkMMXreg(MMX_GPR+_Rd_, moded); + + if( !(xmminfo&XMMINFO_READD) && mmreg3 < 0 && ((g_pCurInstInfo->regs[vreg] & EEINST_LASTUSE) || !EEINST_ISLIVE64(vreg)) ) { + if( EEINST_ISLIVE64(vreg) ) { + _freeMMXreg(mmreg1); + if( GPR_IS_CONST1(_Rs_) ) info &= ~PROCESS_EE_MODEWRITET; + else info &= ~PROCESS_EE_MODEWRITES; + } + _deleteGPRtoXMMreg(_Rd_, 2); + mmxregs[mmreg1].inuse = 1; + mmxregs[mmreg1].reg = _Rd_; + mmxregs[mmreg1].mode = moded; + mmreg3 = mmreg1; + } + else if( mmreg3 < 0 ) mmreg3 = _allocMMXreg(-1, MMX_GPR+_Rd_, moded); + + info |= PROCESS_EE_SET_D(mmreg3); + } + + if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { + mmtemp = eeProcessHILO(MMX_LO, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 1); + if( mmtemp >= 0 ) info |= PROCESS_EE_SET_LO(mmtemp); + } + if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { + mmtemp = eeProcessHILO(MMX_HI, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 1); + if( mmtemp >= 0 ) info |= PROCESS_EE_SET_HI(mmtemp); + } + + SetMMXstate(); + if( creg == _Rs_ ) constscode(info|PROCESS_EE_SET_T(mmreg1)); + else consttcode(info|PROCESS_EE_SET_S(mmreg1)); + _clearNeededMMXregs(); + if( xmminfo & XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); + return; + } + } + else { + // no const regs + mmreg1 = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rs_, MODE_READ); + mmreg2 = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rt_, MODE_READ); + + if( mmreg1 >= 0 || mmreg2 >= 0 ) { + int info = PROCESS_EE_MMX; + + // do it all in mmx + if( mmreg1 < 0 ) mmreg1 = _allocMMXreg(-1, MMX_GPR+_Rs_, MODE_READ); + if( mmreg2 < 0 ) mmreg2 = _allocMMXreg(-1, MMX_GPR+_Rt_, MODE_READ); + + info |= PROCESS_EE_SETMODES(mmreg1)|PROCESS_EE_SETMODET(mmreg2); + + // check for last used, if so don't alloc a new MMX reg + if( xmminfo & XMMINFO_WRITED ) { + _addNeededMMXreg(MMX_GPR+_Rd_); + mmreg3 = _checkMMXreg(MMX_GPR+_Rd_, moded); + + if( mmreg3 < 0 ) { + if( !(xmminfo&XMMINFO_READD) && ((g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVE64(_Rt_)) ) { + if( EEINST_ISLIVE64(_Rt_) ) { + _freeMMXreg(mmreg2); + info &= ~PROCESS_EE_MODEWRITET; + } + _deleteGPRtoXMMreg(_Rd_, 2); + mmxregs[mmreg2].inuse = 1; + mmxregs[mmreg2].reg = _Rd_; + mmxregs[mmreg2].mode = moded; + mmreg3 = mmreg2; + } + else if( !(xmminfo&XMMINFO_READD) && ((g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVE64(_Rs_)) ) { + if( EEINST_ISLIVE64(_Rs_) ) { + _freeMMXreg(mmreg1); + info &= ~PROCESS_EE_MODEWRITES; + } + _deleteGPRtoXMMreg(_Rd_, 2); + mmxregs[mmreg1].inuse = 1; + mmxregs[mmreg1].reg = _Rd_; + mmxregs[mmreg1].mode = moded; + mmreg3 = mmreg1; + } + else mmreg3 = _allocMMXreg(-1, MMX_GPR+_Rd_, moded); + } + + info |= PROCESS_EE_SET_D(mmreg3); + } + + if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { + mmtemp = eeProcessHILO(MMX_LO, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 1); + if( mmtemp >= 0 ) info |= PROCESS_EE_SET_LO(mmtemp); + } + if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { + mmtemp = eeProcessHILO(MMX_HI, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 1); + if( mmtemp >= 0 ) info |= PROCESS_EE_SET_HI(mmtemp); + } + + SetMMXstate(); + noconstcode(info|PROCESS_EE_SET_S(mmreg1)|PROCESS_EE_SET_T(mmreg2)); + _clearNeededMMXregs(); + if( xmminfo & XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); + return; + } + } + + _clearNeededMMXregs(); + } + + // test if should write xmm, mirror to mmx code + if( g_pCurInstInfo->info & EEINST_XMM ) { + + if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) _addNeededGPRtoXMMreg(XMMGPR_LO); + if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) _addNeededGPRtoXMMreg(XMMGPR_HI); + _addNeededGPRtoXMMreg(_Rs_); + _addNeededGPRtoXMMreg(_Rt_); + + if( GPR_IS_CONST1(_Rs_) || GPR_IS_CONST1(_Rt_) ) { + int creg = GPR_IS_CONST1(_Rs_) ? _Rs_ : _Rt_; + int vreg = creg == _Rs_ ? _Rt_ : _Rs_; + +// if(g_pCurInstInfo->regs[vreg]&EEINST_XMM) { +// mmreg1 = _allocGPRtoXMMreg(-1, vreg, MODE_READ); +// _addNeededGPRtoXMMreg(vreg); +// } + mmreg1 = _allocCheckGPRtoXMM(g_pCurInstInfo, vreg, MODE_READ); + + if( mmreg1 >= 0 ) { + int info = PROCESS_EE_XMM; + + if( GPR_IS_CONST1(_Rs_) ) info |= PROCESS_EE_SETMODET(mmreg1); + else info |= PROCESS_EE_SETMODES(mmreg1); + + if( xmminfo & XMMINFO_WRITED ) { + + _addNeededGPRtoXMMreg(_Rd_); + mmreg3 = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, MODE_WRITE); + + if( !(xmminfo&XMMINFO_READD) && mmreg3 < 0 && ((g_pCurInstInfo->regs[vreg] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(vreg)) ) { + _freeXMMreg(mmreg1); + if( GPR_IS_CONST1(_Rs_) ) info &= ~PROCESS_EE_MODEWRITET; + else info &= ~PROCESS_EE_MODEWRITES; + _deleteMMXreg(MMX_GPR+_Rd_, 2); + xmmregs[mmreg1].inuse = 1; + xmmregs[mmreg1].reg = _Rd_; + xmmregs[mmreg1].mode = moded; + mmreg3 = mmreg1; + } + else if( mmreg3 < 0 ) mmreg3 = _allocGPRtoXMMreg(-1, _Rd_, moded); + + info |= PROCESS_EE_SET_D(mmreg3); + } + + if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { + mmtemp = eeProcessHILO(XMMGPR_LO, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 0); + if( mmtemp >= 0 ) info |= PROCESS_EE_SET_LO(mmtemp); + } + if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { + mmtemp = eeProcessHILO(XMMGPR_HI, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 0); + if( mmtemp >= 0 ) info |= PROCESS_EE_SET_HI(mmtemp); + } + + if( creg == _Rs_ ) constscode(info|PROCESS_EE_SET_T(mmreg1)); + else consttcode(info|PROCESS_EE_SET_S(mmreg1)); + _clearNeededXMMregs(); + if( xmminfo & XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); + return; + } + } + else { + // no const regs + mmreg1 = _allocCheckGPRtoXMM(g_pCurInstInfo, _Rs_, MODE_READ); + mmreg2 = _allocCheckGPRtoXMM(g_pCurInstInfo, _Rt_, MODE_READ); + + if( mmreg1 >= 0 || mmreg2 >= 0 ) { + int info = PROCESS_EE_XMM; + + // do it all in xmm + if( mmreg1 < 0 ) mmreg1 = _allocGPRtoXMMreg(-1, _Rs_, MODE_READ); + if( mmreg2 < 0 ) mmreg2 = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ); + + info |= PROCESS_EE_SETMODES(mmreg1)|PROCESS_EE_SETMODET(mmreg2); + + if( xmminfo & XMMINFO_WRITED ) { + // check for last used, if so don't alloc a new XMM reg + _addNeededGPRtoXMMreg(_Rd_); + mmreg3 = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, moded); + + if( mmreg3 < 0 ) { + if( !(xmminfo&XMMINFO_READD) && ((g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rt_)) ) { + _freeXMMreg(mmreg2); + info &= ~PROCESS_EE_MODEWRITET; + _deleteMMXreg(MMX_GPR+_Rd_, 2); + xmmregs[mmreg2].inuse = 1; + xmmregs[mmreg2].reg = _Rd_; + xmmregs[mmreg2].mode = moded; + mmreg3 = mmreg2; + } + else if( !(xmminfo&XMMINFO_READD) && ((g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rs_)) ) { + _freeXMMreg(mmreg1); + info &= ~PROCESS_EE_MODEWRITES; + _deleteMMXreg(MMX_GPR+_Rd_, 2); + xmmregs[mmreg1].inuse = 1; + xmmregs[mmreg1].reg = _Rd_; + xmmregs[mmreg1].mode = moded; + mmreg3 = mmreg1; + } + else mmreg3 = _allocGPRtoXMMreg(-1, _Rd_, moded); + } + + info |= PROCESS_EE_SET_D(mmreg3); + } + + if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { + mmtemp = eeProcessHILO(XMMGPR_LO, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 0); + if( mmtemp >= 0 ) info |= PROCESS_EE_SET_LO(mmtemp); + } + if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { + mmtemp = eeProcessHILO(XMMGPR_HI, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0), 0); + if( mmtemp >= 0 ) info |= PROCESS_EE_SET_HI(mmtemp); + } + + noconstcode(info|PROCESS_EE_SET_S(mmreg1)|PROCESS_EE_SET_T(mmreg2)); + _clearNeededXMMregs(); + if( xmminfo & XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); + return; + } + } + + _clearNeededXMMregs(); + } + + // regular x86 + _deleteGPRtoXMMreg(_Rs_, 1); + _deleteGPRtoXMMreg(_Rt_, 1); + if( xmminfo&XMMINFO_WRITED ) + _deleteGPRtoXMMreg(_Rd_, (xmminfo&XMMINFO_READD)?0:2); + _deleteMMXreg(MMX_GPR+_Rs_, 1); + _deleteMMXreg(MMX_GPR+_Rt_, 1); + if( xmminfo&XMMINFO_WRITED ) + _deleteMMXreg(MMX_GPR+_Rd_, (xmminfo&XMMINFO_READD)?0:2); + + // don't delete, fn will take care of them +// if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { +// _deleteGPRtoXMMreg(XMMGPR_LO, (xmminfo&XMMINFO_READLO)?1:0); +// _deleteMMXreg(MMX_GPR+MMX_LO, (xmminfo&XMMINFO_READLO)?1:0); +// } +// if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { +// _deleteGPRtoXMMreg(XMMGPR_HI, (xmminfo&XMMINFO_READHI)?1:0); +// _deleteMMXreg(MMX_GPR+MMX_HI, (xmminfo&XMMINFO_READHI)?1:0); +// } + + if( GPR_IS_CONST1(_Rs_) ) { + constscode(0); + if( xmminfo&XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); + return; + } + + if( GPR_IS_CONST1(_Rt_) ) { + consttcode(0); + if( xmminfo&XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); + return; + } + + noconstcode(0); + if( xmminfo&XMMINFO_WRITED ) GPR_DEL_CONST(_Rd_); +} + +// rt = rs op imm16 +void eeRecompileCode1(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode) +{ + int mmreg1, mmreg2; + if ( ! _Rt_ ) return; + + CHECK_SAVE_REG(_Rt_); + _eeProcessHasLive(_Rt_, 0); + EEINST_RESETSIGNEXT(_Rt_); + + if( GPR_IS_CONST1(_Rs_) ) { + _deleteMMXreg(MMX_GPR+_Rt_, 2); + _deleteGPRtoXMMreg(_Rt_, 2); + GPR_SET_CONST(_Rt_); + constcode(); + return; + } + + // test if should write mmx + if( g_pCurInstInfo->info & EEINST_MMX ) { + + // no const regs + mmreg1 = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rs_, MODE_READ); + + if( mmreg1 >= 0 ) { + int info = PROCESS_EE_MMX|PROCESS_EE_SETMODES(mmreg1); + + // check for last used, if so don't alloc a new MMX reg + _addNeededMMXreg(MMX_GPR+_Rt_); + mmreg2 = _checkMMXreg(MMX_GPR+_Rt_, MODE_WRITE); + + if( mmreg2 < 0 ) { + if( (g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVE64(_Rs_) ) { + if( EEINST_ISLIVE64(_Rs_) ) { + _freeMMXreg(mmreg1); + info &= ~PROCESS_EE_MODEWRITES; + } + _deleteGPRtoXMMreg(_Rt_, 2); + mmxregs[mmreg1].inuse = 1; + mmxregs[mmreg1].reg = _Rt_; + mmxregs[mmreg1].mode = MODE_WRITE|MODE_READ; + mmreg2 = mmreg1; + } + else mmreg2 = _allocMMXreg(-1, MMX_GPR+_Rt_, MODE_WRITE); + } + + SetMMXstate(); + noconstcode(info|PROCESS_EE_SET_S(mmreg1)|PROCESS_EE_SET_T(mmreg2)); + _clearNeededMMXregs(); + GPR_DEL_CONST(_Rt_); + return; + } + + _clearNeededMMXregs(); + } + + // test if should write xmm, mirror to mmx code + if( g_pCurInstInfo->info & EEINST_XMM ) { + + // no const regs + mmreg1 = _allocCheckGPRtoXMM(g_pCurInstInfo, _Rs_, MODE_READ); + + if( mmreg1 >= 0 ) { + int info = PROCESS_EE_XMM|PROCESS_EE_SETMODES(mmreg1); + + // check for last used, if so don't alloc a new XMM reg + _addNeededGPRtoXMMreg(_Rt_); + mmreg2 = _checkXMMreg(XMMTYPE_GPRREG, _Rt_, MODE_WRITE); + + if( mmreg2 < 0 ) { + if( (g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rs_) ) { + _freeXMMreg(mmreg1); + info &= ~PROCESS_EE_MODEWRITES; + _deleteMMXreg(MMX_GPR+_Rt_, 2); + xmmregs[mmreg1].inuse = 1; + xmmregs[mmreg1].reg = _Rt_; + xmmregs[mmreg1].mode = MODE_WRITE|MODE_READ; + mmreg2 = mmreg1; + } + else mmreg2 = _allocGPRtoXMMreg(-1, _Rt_, MODE_WRITE); + } + + noconstcode(info|PROCESS_EE_SET_S(mmreg1)|PROCESS_EE_SET_T(mmreg2)); + _clearNeededXMMregs(); + GPR_DEL_CONST(_Rt_); + return; + } + + _clearNeededXMMregs(); + } + + // regular x86 + _deleteGPRtoXMMreg(_Rs_, 1); + _deleteGPRtoXMMreg(_Rt_, 2); + _deleteMMXreg(MMX_GPR+_Rs_, 1); + _deleteMMXreg(MMX_GPR+_Rt_, 2); + + noconstcode(0); + GPR_DEL_CONST(_Rt_); +} + +// rd = rt op sa +void eeRecompileCode2(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode) +{ + int mmreg1, mmreg2; + if ( ! _Rd_ ) return; + + CHECK_SAVE_REG(_Rd_); + _eeProcessHasLive(_Rd_, 0); + EEINST_RESETSIGNEXT(_Rd_); + + if( GPR_IS_CONST1(_Rt_) ) { + _deleteMMXreg(MMX_GPR+_Rd_, 2); + _deleteGPRtoXMMreg(_Rd_, 2); + GPR_SET_CONST(_Rd_); + constcode(); + return; + } + + // test if should write mmx + if( g_pCurInstInfo->info & EEINST_MMX ) { + + // no const regs + mmreg1 = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rt_, MODE_READ); + + if( mmreg1 >= 0 ) { + int info = PROCESS_EE_MMX|PROCESS_EE_SETMODET(mmreg1); + + // check for last used, if so don't alloc a new MMX reg + _addNeededMMXreg(MMX_GPR+_Rd_); + mmreg2 = _checkMMXreg(MMX_GPR+_Rd_, MODE_WRITE); + + if( mmreg2 < 0 ) { + if( (g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVE64(_Rt_) ) { + if( EEINST_ISLIVE64(_Rt_) ) { + _freeMMXreg(mmreg1); + info &= ~PROCESS_EE_MODEWRITET; + } + _deleteGPRtoXMMreg(_Rd_, 2); + mmxregs[mmreg1].inuse = 1; + mmxregs[mmreg1].reg = _Rd_; + mmxregs[mmreg1].mode = MODE_WRITE|MODE_READ; + mmreg2 = mmreg1; + } + else mmreg2 = _allocMMXreg(-1, MMX_GPR+_Rd_, MODE_WRITE); + } + + SetMMXstate(); + noconstcode(info|PROCESS_EE_SET_T(mmreg1)|PROCESS_EE_SET_D(mmreg2)); + _clearNeededMMXregs(); + GPR_DEL_CONST(_Rd_); + return; + } + + _clearNeededMMXregs(); + } + + // test if should write xmm, mirror to mmx code + if( g_pCurInstInfo->info & EEINST_XMM ) { + + // no const regs + mmreg1 = _allocCheckGPRtoXMM(g_pCurInstInfo, _Rt_, MODE_READ); + + if( mmreg1 >= 0 ) { + int info = PROCESS_EE_XMM|PROCESS_EE_SETMODET(mmreg1); + + // check for last used, if so don't alloc a new XMM reg + _addNeededGPRtoXMMreg(_Rd_); + mmreg2 = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, MODE_WRITE); + + if( mmreg2 < 0 ) { + if( (g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVE64(_Rt_) ) { + _freeXMMreg(mmreg1); + info &= ~PROCESS_EE_MODEWRITET; + _deleteMMXreg(MMX_GPR+_Rd_, 2); + xmmregs[mmreg1].inuse = 1; + xmmregs[mmreg1].reg = _Rd_; + xmmregs[mmreg1].mode = MODE_WRITE|MODE_READ; + mmreg2 = mmreg1; + } + else mmreg2 = _allocGPRtoXMMreg(-1, _Rd_, MODE_WRITE); + } + + noconstcode(info|PROCESS_EE_SET_T(mmreg1)|PROCESS_EE_SET_D(mmreg2)); + _clearNeededXMMregs(); + GPR_DEL_CONST(_Rd_); + return; + } + + _clearNeededXMMregs(); + } + + // regular x86 + _deleteGPRtoXMMreg(_Rt_, 1); + _deleteGPRtoXMMreg(_Rd_, 2); + _deleteMMXreg(MMX_GPR+_Rt_, 1); + _deleteMMXreg(MMX_GPR+_Rd_, 2); + + noconstcode(0); + GPR_DEL_CONST(_Rd_); +} + +// rt op rs +void eeRecompileCode3(R5900FNPTR constcode, R5900FNPTR_INFO multicode) +{ + assert(0); + // for now, don't support xmm + _deleteEEreg(_Rs_, 1); + _deleteEEreg(_Rt_, 1); + + if( GPR_IS_CONST2(_Rs_, _Rt_) ) { + constcode(); + return; + } + + if( GPR_IS_CONST1(_Rs_) ) { + //multicode(PROCESS_EE_CONSTT); + return; + } + + if( GPR_IS_CONST1(_Rt_) ) { + //multicode(PROCESS_EE_CONSTT); + return; + } + + multicode(0); +} + +// Simple Code Templates // + +// rd = rs op rt +void eeRecompileCodeConst0(R5900FNPTR constcode, R5900FNPTR_INFO constscode, R5900FNPTR_INFO consttcode, R5900FNPTR_INFO noconstcode) +{ + if ( ! _Rd_ ) return; + + // for now, don't support xmm + CHECK_SAVE_REG(_Rd_); + + _deleteGPRtoXMMreg(_Rs_, 1); + _deleteGPRtoXMMreg(_Rt_, 1); + _deleteGPRtoXMMreg(_Rd_, 0); + _deleteMMXreg(MMX_GPR+_Rs_, 1); + _deleteMMXreg(MMX_GPR+_Rt_, 1); + _deleteMMXreg(MMX_GPR+_Rd_, 0); + + if( GPR_IS_CONST2(_Rs_, _Rt_) ) { + GPR_SET_CONST(_Rd_); + constcode(); + return; + } + + if( GPR_IS_CONST1(_Rs_) ) { + constscode(0); + GPR_DEL_CONST(_Rd_); + return; + } + + if( GPR_IS_CONST1(_Rt_) ) { + consttcode(0); + GPR_DEL_CONST(_Rd_); + return; + } + + noconstcode(0); + GPR_DEL_CONST(_Rd_); +} + +// rt = rs op imm16 +void eeRecompileCodeConst1(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode) +{ + if ( ! _Rt_ ) + return; + + // for now, don't support xmm + CHECK_SAVE_REG(_Rt_); + + _deleteGPRtoXMMreg(_Rs_, 1); + _deleteGPRtoXMMreg(_Rt_, 0); + + if( GPR_IS_CONST1(_Rs_) ) { + GPR_SET_CONST(_Rt_); + constcode(); + return; + } + + noconstcode(0); + GPR_DEL_CONST(_Rt_); +} + +// rd = rt op sa +void eeRecompileCodeConst2(R5900FNPTR constcode, R5900FNPTR_INFO noconstcode) +{ + if ( ! _Rd_ ) return; + + // for now, don't support xmm + CHECK_SAVE_REG(_Rd_); + + _deleteGPRtoXMMreg(_Rt_, 1); + _deleteGPRtoXMMreg(_Rd_, 0); + + if( GPR_IS_CONST1(_Rt_) ) { + GPR_SET_CONST(_Rd_); + constcode(); + return; + } + + noconstcode(0); + GPR_DEL_CONST(_Rd_); +} + +// rd = rt MULT rs (SPECIAL) +void eeRecompileCodeConstSPECIAL(R5900FNPTR constcode, R5900FNPTR_INFO multicode, int MULT) +{ + assert(0); + // for now, don't support xmm + if( MULT ) { + CHECK_SAVE_REG(_Rd_); + _deleteGPRtoXMMreg(_Rd_, 0); + } + + _deleteGPRtoXMMreg(_Rs_, 1); + _deleteGPRtoXMMreg(_Rt_, 1); + + if( GPR_IS_CONST2(_Rs_, _Rt_) ) { + if( MULT && _Rd_ ) GPR_SET_CONST(_Rd_); + constcode(); + return; + } + + if( GPR_IS_CONST1(_Rs_) ) { + //multicode(PROCESS_EE_CONSTS); + if( MULT && _Rd_ ) GPR_DEL_CONST(_Rd_); + return; + } + + if( GPR_IS_CONST1(_Rt_) ) { + //multicode(PROCESS_EE_CONSTT); + if( MULT && _Rd_ ) GPR_DEL_CONST(_Rd_); + return; + } + + multicode(0); + if( MULT && _Rd_ ) GPR_DEL_CONST(_Rd_); +} + +// EE XMM allocation code +int eeRecompileCodeXMM(int xmminfo) +{ + int info = PROCESS_EE_XMM; + + // save state + if( xmminfo & XMMINFO_WRITED ) { + CHECK_SAVE_REG(_Rd_); + _eeProcessHasLive(_Rd_, 0); + EEINST_RESETSIGNEXT(_Rd_); + } + + // flush consts + if( xmminfo & XMMINFO_READT ) { + if( GPR_IS_CONST1( _Rt_ ) && !(g_cpuFlushedConstReg&(1<<_Rt_)) ) { + MOV32ItoM((int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], g_cpuConstRegs[_Rt_].UL[0]); + MOV32ItoM((int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], g_cpuConstRegs[_Rt_].UL[1]); + g_cpuFlushedConstReg |= (1<<_Rt_); + } + } + if( xmminfo & XMMINFO_READS) { + if( GPR_IS_CONST1( _Rs_ ) && !(g_cpuFlushedConstReg&(1<<_Rs_)) ) { + MOV32ItoM((int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ], g_cpuConstRegs[_Rs_].UL[0]); + MOV32ItoM((int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ], g_cpuConstRegs[_Rs_].UL[1]); + g_cpuFlushedConstReg |= (1<<_Rs_); + } + } + + if( xmminfo & XMMINFO_WRITED ) { + GPR_DEL_CONST(_Rd_); + } + + // add needed + if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { + _addNeededGPRtoXMMreg(XMMGPR_LO); + } + if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { + _addNeededGPRtoXMMreg(XMMGPR_HI); + } + if( xmminfo & XMMINFO_READS) _addNeededGPRtoXMMreg(_Rs_); + if( xmminfo & XMMINFO_READT) _addNeededGPRtoXMMreg(_Rt_); + if( xmminfo & XMMINFO_WRITED ) _addNeededGPRtoXMMreg(_Rd_); + + // allocate + if( xmminfo & XMMINFO_READS) { + int reg = _allocGPRtoXMMreg(-1, _Rs_, MODE_READ); + info |= PROCESS_EE_SET_S(reg)|PROCESS_EE_SETMODES(reg); + } + if( xmminfo & XMMINFO_READT) { + int reg = _allocGPRtoXMMreg(-1, _Rt_, MODE_READ); + info |= PROCESS_EE_SET_T(reg)|PROCESS_EE_SETMODET(reg); + } + + if( xmminfo & XMMINFO_WRITED ) { + int readd = MODE_WRITE|((xmminfo&XMMINFO_READD)?((xmminfo&XMMINFO_READD_LO)?(MODE_READ|MODE_READHALF):MODE_READ):0); + + int regd = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, readd); + + if( regd < 0 ) { + if( !(xmminfo&XMMINFO_READD) && (xmminfo & XMMINFO_READT) && (_Rt_ == 0 || (g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rt_)) ) { + _freeXMMreg(EEREC_T); + _deleteMMXreg(MMX_GPR+_Rd_, 2); + xmmregs[EEREC_T].inuse = 1; + xmmregs[EEREC_T].reg = _Rd_; + xmmregs[EEREC_T].mode = readd; + regd = EEREC_T; + } + else if( !(xmminfo&XMMINFO_READD) && (xmminfo & XMMINFO_READS) && (_Rs_ == 0 || (g_pCurInstInfo->regs[_Rs_] & EEINST_LASTUSE) || !EEINST_ISLIVEXMM(_Rs_)) ) { + _freeXMMreg(EEREC_S); + _deleteMMXreg(MMX_GPR+_Rd_, 2); + xmmregs[EEREC_S].inuse = 1; + xmmregs[EEREC_S].reg = _Rd_; + xmmregs[EEREC_S].mode = readd; + regd = EEREC_S; + } + else regd = _allocGPRtoXMMreg(-1, _Rd_, readd); + } + + info |= PROCESS_EE_SET_D(regd); + } + if( xmminfo & (XMMINFO_READLO|XMMINFO_WRITELO) ) { + info |= PROCESS_EE_SET_LO(_allocGPRtoXMMreg(-1, XMMGPR_LO, ((xmminfo&XMMINFO_READLO)?MODE_READ:0)|((xmminfo&XMMINFO_WRITELO)?MODE_WRITE:0))); + info |= PROCESS_EE_LO; + } + if( xmminfo & (XMMINFO_READHI|XMMINFO_WRITEHI) ) { + info |= PROCESS_EE_SET_HI(_allocGPRtoXMMreg(-1, XMMGPR_HI, ((xmminfo&XMMINFO_READHI)?MODE_READ:0)|((xmminfo&XMMINFO_WRITEHI)?MODE_WRITE:0))); + info |= PROCESS_EE_HI; + } + return info; +} + +// EE COP1(FPU) XMM allocation code +#define _Ft_ _Rt_ +#define _Fs_ _Rd_ +#define _Fd_ _Sa_ + +#define PROCESS_EE_SETMODES_XMM(mmreg) ((xmmregs[mmreg].mode&MODE_WRITE)?PROCESS_EE_MODEWRITES:0) +#define PROCESS_EE_SETMODET_XMM(mmreg) ((xmmregs[mmreg].mode&MODE_WRITE)?PROCESS_EE_MODEWRITET:0) + +// rd = rs op rt +void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR_INFO fpucode, int xmminfo) +{ + int mmregs=-1, mmregt=-1, mmregd=-1, mmregacc=-1; + + if( EE_FPU_REGCACHING && cpucaps.hasStreamingSIMDExtensions ) { + int info = PROCESS_EE_XMM; + + if( xmminfo & XMMINFO_READS ) _addNeededFPtoXMMreg(_Fs_); + if( xmminfo & XMMINFO_READT ) _addNeededFPtoXMMreg(_Ft_); + if( xmminfo & (XMMINFO_WRITED|XMMINFO_READD) ) _addNeededFPtoXMMreg(_Fd_); + if( xmminfo & (XMMINFO_WRITEACC|XMMINFO_READACC) ) _addNeededFPACCtoXMMreg(); + + if( xmminfo & XMMINFO_READT ) { + if( g_pCurInstInfo->fpuregs[_Ft_] & EEINST_LASTUSE ) mmregt = _checkXMMreg(XMMTYPE_FPREG, _Ft_, MODE_READ); + else mmregt = _allocFPtoXMMreg(-1, _Ft_, MODE_READ); + } + + if( xmminfo & XMMINFO_READS ) { + if( (!(xmminfo&XMMINFO_READT)||mmregt>=0) && (g_pCurInstInfo->fpuregs[_Fs_] & EEINST_LASTUSE) ) + mmregs = _checkXMMreg(XMMTYPE_FPREG, _Fs_, MODE_READ); + else mmregs = _allocFPtoXMMreg(-1, _Fs_, MODE_READ); + } + + if( mmregs >= 0 ) info |= PROCESS_EE_SETMODES_XMM(mmregs); + if( mmregt >= 0 ) info |= PROCESS_EE_SETMODET_XMM(mmregt); + + if( xmminfo & XMMINFO_READD ) { + assert( xmminfo & XMMINFO_WRITED ); + mmregd = _allocFPtoXMMreg(-1, _Fd_, MODE_READ); + } + + if( xmminfo & XMMINFO_READACC ) { + if( !(xmminfo&XMMINFO_WRITEACC) && (g_pCurInstInfo->fpuregs[_Ft_] & EEINST_LASTUSE) ) + mmregacc = _checkXMMreg(XMMTYPE_FPACC, 0, MODE_READ); + else mmregacc = _allocFPACCtoXMMreg(-1, MODE_READ); + } + + if( xmminfo & XMMINFO_WRITEACC ) { + + // check for last used, if so don't alloc a new XMM reg + int readacc = MODE_WRITE|((xmminfo&XMMINFO_READACC)?MODE_READ:0); + + mmregacc = _checkXMMreg(XMMTYPE_FPACC, 0, readacc); + + if( mmregacc < 0 ) { + if( (xmminfo&XMMINFO_READT) && mmregt >= 0 && (FPUINST_LASTUSE(_Ft_) || !FPUINST_ISLIVE(_Ft_)) ) { + if( FPUINST_ISLIVE(_Ft_) ) { + _freeXMMreg(mmregt); + info &= ~PROCESS_EE_MODEWRITET; + } + _deleteMMXreg(MMX_FPU+XMMFPU_ACC, 2); + xmmregs[mmregt].inuse = 1; + xmmregs[mmregt].reg = 0; + xmmregs[mmregt].mode = readacc; + xmmregs[mmregt].type = XMMTYPE_FPACC; + mmregacc = mmregt; + } + else if( (xmminfo&XMMINFO_READS) && mmregs >= 0 && (FPUINST_LASTUSE(_Fs_) || !FPUINST_ISLIVE(_Fs_)) ) { + if( FPUINST_ISLIVE(_Fs_) ) { + _freeXMMreg(mmregs); + info &= ~PROCESS_EE_MODEWRITES; + } + _deleteMMXreg(MMX_FPU+XMMFPU_ACC, 2); + xmmregs[mmregs].inuse = 1; + xmmregs[mmregs].reg = 0; + xmmregs[mmregs].mode = readacc; + xmmregs[mmregs].type = XMMTYPE_FPACC; + mmregacc = mmregs; + } + else mmregacc = _allocFPACCtoXMMreg(-1, readacc); + } + + xmmregs[mmregacc].mode |= MODE_WRITE; + } + else if( xmminfo & XMMINFO_WRITED ) { + // check for last used, if so don't alloc a new XMM reg + int readd = MODE_WRITE|((xmminfo&XMMINFO_READD)?MODE_READ:0); + if( xmminfo&XMMINFO_READD ) mmregd = _allocFPtoXMMreg(-1, _Fd_, readd); + else mmregd = _checkXMMreg(XMMTYPE_FPREG, _Fd_, readd); + + if( mmregd < 0 ) { + if( (xmminfo&XMMINFO_READT) && mmregt >= 0 && (FPUINST_LASTUSE(_Ft_) || !FPUINST_ISLIVE(_Ft_)) ) { + if( FPUINST_ISLIVE(_Ft_) ) { + _freeXMMreg(mmregt); + info &= ~PROCESS_EE_MODEWRITET; + } + _deleteMMXreg(MMX_FPU+_Fd_, 2); + xmmregs[mmregt].inuse = 1; + xmmregs[mmregt].reg = _Fd_; + xmmregs[mmregt].mode = readd; + mmregd = mmregt; + } + else if( (xmminfo&XMMINFO_READS) && mmregs >= 0 && (FPUINST_LASTUSE(_Fs_) || !FPUINST_ISLIVE(_Fs_)) ) { + if( FPUINST_ISLIVE(_Fs_) ) { + _freeXMMreg(mmregs); + info &= ~PROCESS_EE_MODEWRITES; + } + _deleteMMXreg(MMX_FPU+_Fd_, 2); + xmmregs[mmregs].inuse = 1; + xmmregs[mmregs].reg = _Fd_; + xmmregs[mmregs].mode = readd; + mmregd = mmregs; + } + else if( (xmminfo&XMMINFO_READACC) && mmregacc >= 0 && (FPUINST_LASTUSE(XMMFPU_ACC) || !FPUINST_ISLIVE(XMMFPU_ACC)) ) { + if( FPUINST_ISLIVE(XMMFPU_ACC) ) + _freeXMMreg(mmregacc); + _deleteMMXreg(MMX_FPU+_Fd_, 2); + xmmregs[mmregacc].inuse = 1; + xmmregs[mmregacc].reg = _Fd_; + xmmregs[mmregacc].mode = readd; + xmmregs[mmregacc].type = XMMTYPE_FPREG; + mmregd = mmregacc; + } + else mmregd = _allocFPtoXMMreg(-1, _Fd_, readd); + } + } + + assert( mmregs >= 0 || mmregt >= 0 || mmregd >= 0 || mmregacc >= 0 ); + + if( xmminfo & XMMINFO_WRITED ) { + assert( mmregd >= 0 ); + info |= PROCESS_EE_SET_D(mmregd); + } + if( xmminfo & (XMMINFO_WRITEACC|XMMINFO_READACC) ) { + if( mmregacc >= 0 ) info |= PROCESS_EE_SET_ACC(mmregacc)|PROCESS_EE_ACC; + else assert( !(xmminfo&XMMINFO_WRITEACC)); + } + + if( xmminfo & XMMINFO_READS ) { + if( mmregs >= 0 ) info |= PROCESS_EE_SET_S(mmregs)|PROCESS_EE_S; + } + if( xmminfo & XMMINFO_READT ) { + if( mmregt >= 0 ) info |= PROCESS_EE_SET_T(mmregt)|PROCESS_EE_T; + } + + // at least one must be in xmm + if( (xmminfo & (XMMINFO_READS|XMMINFO_READT)) == (XMMINFO_READS|XMMINFO_READT) ) { + assert( mmregs >= 0 || mmregt >= 0 ); + } + + xmmcode(info); + _clearNeededXMMregs(); + return; + } + + if( xmminfo & XMMINFO_READS ) _deleteFPtoXMMreg(_Fs_, 0); + if( xmminfo & XMMINFO_READT ) _deleteFPtoXMMreg(_Ft_, 0); + if( xmminfo & (XMMINFO_READD|XMMINFO_WRITED) ) _deleteFPtoXMMreg(_Fd_, 0); + if( xmminfo & (XMMINFO_READACC|XMMINFO_WRITEACC) ) _deleteFPtoXMMreg(XMMFPU_ACC, 0); + fpucode(0); +} + +#undef _Ft_ +#undef _Fs_ +#undef _Fd_ + +//////////////////////////////////////////////////// +extern u8 g_MACFlagTransform[256]; // for vus + +u32 g_sseMXCSR = 0x9fc0; // disable all exception, round to 0, flush to 0 +u32 g_sseVUMXCSR = 0xffc0; + +void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR) +{ + // SSE STATE // + // WARNING: do not touch unless you know what you are doing + + if( cpucaps.hasStreamingSIMDExtensions ) { + g_sseMXCSR = sseMXCSR; + g_sseVUMXCSR = sseVUMXCSR; + // do NOT set Denormals-Are-Zero flag (charlie and chocfac messes up) + // Update 11/05/08 - Doesnt seem to effect it anymore, for the speed boost, its on :p + //g_sseMXCSR = 0x9f80; // changing the rounding mode to 0x2000 (near) kills grandia III! + // changing the rounding mode to 0x0000 or 0x4000 totally kills gitaroo + // so... grandia III wins (you can change individual games with the 'roundmode' patch command) + +#ifdef _MSC_VER + __asm ldmxcsr g_sseMXCSR; // set the new sse control +#else + __asm__("ldmxcsr %0" : : "m"(g_sseMXCSR) ); +#endif + //g_sseVUMXCSR = g_sseMXCSR|0x6000; + } +} + +#define REC_CACHEMEM 0x01000000 + +int recInit( void ) +{ + int i; + const u8 macarr[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }; + + recLUT = (uptr*) _aligned_malloc( 0x010000 * sizeof(uptr), 16 ); + memset( recLUT, 0, 0x010000 * sizeof(uptr) ); + + // can't have upper 4 bits nonzero! + recMem = (char*)SysMmap(0x0d000000, REC_CACHEMEM); + + // 32 alignment necessary + recRAM = (BASEBLOCK*) _aligned_malloc( sizeof(BASEBLOCK)/4*0x02000000 , 4*sizeof(BASEBLOCK)); + recROM = (BASEBLOCK*) _aligned_malloc( sizeof(BASEBLOCK)/4*0x00400000 , 4*sizeof(BASEBLOCK)); + recROM1= (BASEBLOCK*) _aligned_malloc( sizeof(BASEBLOCK)/4*0x00040000 , 4*sizeof(BASEBLOCK)); + recBlocks = (BASEBLOCKEX*) _aligned_malloc( sizeof(BASEBLOCKEX)*EE_NUMBLOCKS, 16); + recStack = (char*)malloc( RECSTACK_SIZE ); + + s_nInstCacheSize = 128; + s_pInstCache = (EEINST*)malloc( sizeof(EEINST) * s_nInstCacheSize ); + + if ( recBlocks == NULL || recRAM == NULL || recROM == NULL || recROM1 == NULL || recMem == NULL || recLUT == NULL ) { + SysMessage( _( "Error allocating memory" ) ); + return -1; + } + + for ( i = 0x0000; i < 0x0200; i++ ) + { + recLUT[ i + 0x0000 ] = (uptr)&recRAM[ i << 14 ]; + recLUT[ i + 0x2000 ] = (uptr)&recRAM[ i << 14 ]; + recLUT[ i + 0x3000 ] = (uptr)&recRAM[ i << 14 ]; + } + + for ( i = 0x0000; i < 0x0040; i++ ) + { + recLUT[ i + 0x1fc0 ] = (uptr)&recROM[ i << 14 ]; + recLUT[ i + 0x9fc0 ] = (uptr)&recROM[ i << 14 ]; + recLUT[ i + 0xbfc0 ] = (uptr)&recROM[ i << 14 ]; + } + + for ( i = 0x0000; i < 0x0004; i++ ) + { + recLUT[ i + 0x1e00 ] = (uptr)&recROM1[ i << 14 ]; + recLUT[ i + 0x9e00 ] = (uptr)&recROM1[ i << 14 ]; + recLUT[ i + 0xbe00 ] = (uptr)&recROM1[ i << 14 ]; + } + + memcpy( recLUT + 0x8000, recLUT, 0x2000 * sizeof(uptr) ); + memcpy( recLUT + 0xa000, recLUT, 0x2000 * sizeof(uptr) ); + + memset(recMem, 0xcd, REC_CACHEMEM); + memset(recStack, 0, RECSTACK_SIZE); + + // SSE3 detection, manually create the code + x86SetPtr(recMem); + SSE3_MOVSLDUP_XMM_to_XMM(XMM0, XMM0); + RET(); + + cpudetectSSE3(recMem); + + x86SetPtr(recMem); + SSE4_DPPS_XMM_to_XMM(XMM0, XMM0, 0); + RET(); + + cpudetectSSE4(recMem); + + SysPrintf( "x86Init: \n" ); + SysPrintf( "\tCPU vender name = %s\n", cpuinfo.x86ID ); + SysPrintf( "\tFamilyID = %x\n", cpuinfo.x86StepID ); + SysPrintf( "\tx86Family = %s\n", cpuinfo.x86Fam ); + SysPrintf( "\tCPU speed = %d.%03d Ghz\n", cpuinfo.cpuspeed / 1000, cpuinfo.cpuspeed%1000); + SysPrintf( "\tx86PType = %s\n", cpuinfo.x86Type ); + SysPrintf( "\tx86Flags = %8.8x %8.8x\n", cpuinfo.x86Flags, cpuinfo.x86Flags2 ); + SysPrintf( "\tx86EFlags = %8.8x\n", cpuinfo.x86EFlags ); + SysPrintf( "Features: \n" ); + SysPrintf( "\t%sDetected MMX\n", cpucaps.hasMultimediaExtensions ? "" : "Not " ); + SysPrintf( "\t%sDetected SSE\n", cpucaps.hasStreamingSIMDExtensions ? "" : "Not " ); + SysPrintf( "\t%sDetected SSE2\n", cpucaps.hasStreamingSIMD2Extensions ? "" : "Not " ); + SysPrintf( "\t%sDetected SSE3\n", cpucaps.hasStreamingSIMD3Extensions ? "" : "Not " ); + SysPrintf( "\t%sDetected SSE4.1\n", cpucaps.hasStreamingSIMD4Extensions ? "" : "Not " ); + + if ( cpuinfo.x86ID[0] == 'A' ) //AMD cpu + { + SysPrintf( " Extented AMD Features: \n" ); + SysPrintf( "\t%sDetected MMX2\n", cpucaps.hasMultimediaExtensionsExt ? "" : "Not " ); + SysPrintf( "\t%sDetected 3DNOW\n", cpucaps.has3DNOWInstructionExtensions ? "" : "Not " ); + SysPrintf( "\t%sDetected 3DNOW2\n", cpucaps.has3DNOWInstructionExtensionsExt ? "" : "Not " ); + } + if ( !( cpucaps.hasMultimediaExtensions ) ) + { + SysMessage( _( "Processor doesn't supports MMX, can't run recompiler without that" ) ); + return -1; + } + + x86FpuState = FPU_STATE; + + SuperVUInit(-1); + + for(i = 0; i < 256; ++i) { + g_MACFlagTransform[i] = macarr[i>>4]|(macarr[i&15]<<4); + } + + SetCPUState(g_sseMXCSR, g_sseVUMXCSR); + + return 0; +} + +//////////////////////////////////////////////////// +void recReset( void ) { +#ifdef PCSX2_DEVBUILD + SysPrintf("EE Recompiler data reset\n"); +#endif + + s_nNextBlock = 0; + maxrecmem = 0; + memset( recRAM, 0, sizeof(BASEBLOCK)/4*0x02000000 ); + memset( recROM, 0, sizeof(BASEBLOCK)/4*0x00400000 ); + memset( recROM1, 0, sizeof(BASEBLOCK)/4*0x00040000 ); + memset( recBlocks, 0, sizeof(BASEBLOCKEX)*EE_NUMBLOCKS ); + if( s_pInstCache ) memset( s_pInstCache, 0, sizeof(EEINST)*s_nInstCacheSize ); + ResetBaseBlockEx(0); + +#ifdef _MSC_VER + __asm emms; +#else + __asm__("emms"); +#endif + +#ifdef _DEBUG + // don't clear since save states won't work + //memset(recMem, 0xcd, REC_CACHEMEM); +#endif + + recPtr = recMem; + recStackPtr = recStack; + x86FpuState = FPU_STATE; + iCWstate = 0; + + branch = 0; +} + +void recShutdown( void ) +{ + if ( recMem == NULL ) { + return; + } + + _aligned_free( recLUT ); + SysMunmap((uptr)recMem, REC_CACHEMEM); recMem = NULL; + _aligned_free( recRAM ); recRAM = NULL; + _aligned_free( recROM ); recROM = NULL; + _aligned_free( recROM1 ); recROM1 = NULL; + _aligned_free( recBlocks ); recBlocks = NULL; + free( s_pInstCache ); s_pInstCache = NULL; s_nInstCacheSize = 0; + + SuperVUDestroy(-1); + + x86Shutdown( ); +} + +void recEnableVU0micro(int enable) { +} + +void recEnableVU1micro(int enable) { +} + +#pragma warning(disable:4731) // frame pointer register 'ebp' modified by inline assembly code +static u32 s_uSaveESP = 0, s_uSaveEBP; + +static void execute( void ) +{ +#ifdef _DEBUG + u8* fnptr; + u32 oldesi; +#else + R5900FNPTR pfn; +#endif + BASEBLOCK* pblock = PC_GETBLOCK(cpuRegs.pc); + + if ( !pblock->pFnptr || pblock->startpc != cpuRegs.pc ) { + recRecompile(cpuRegs.pc); + } + + assert( pblock->pFnptr != 0 ); + g_EEFreezeRegs = 1; + + // skip the POPs +#ifdef _DEBUG + fnptr = (u8*)pblock->pFnptr; + +#ifdef _MSC_VER + __asm { + // save data + mov oldesi, esi + mov s_uSaveESP, esp + sub s_uSaveESP, 8 + mov s_uSaveEBP, ebp + push ebp + + call fnptr // jump into function + // restore data + pop ebp + mov esi, oldesi + } +#else + + __asm__("movl %%esi, %0\n" + "movl %%esp, %1\n" + "sub $8, %1\n" + "push %%ebp\n" + "call *%2\n" + "pop %%ebp\n" + "movl %0, %%esi\n" : "=m"(oldesi), "=m"(s_uSaveESP) : "c"(fnptr) ); +#endif // _MSC_VER + +#else + +#ifdef _MSC_VER + pfn = ((R5900FNPTR)pblock->pFnptr); + // use call instead of pfn() + __asm call pfn; +#else + ((R5900FNPTR)pblock->pFnptr)(); +#endif + +#endif + + g_EEFreezeRegs = 0; +} + +void recStep( void ) { +} + +void recExecute( void ) { + //SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); + //SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);//ABOVE_NORMAL_PRIORITY_CLASS); + //SetThreadAffinityMask(GetCurrentThread(), 0); + if( Config.Options & PCSX2_EEREC ) Config.Options |= PCSX2_COP2REC; + + for (;;) + execute(); +} + +void recExecuteBlock( void ) { + execute(); +} + +//////////////////////////////////////////////////// +extern u32 g_nextBranchCycle; + +u32 g_lastpc = 0; +u32 g_EEDispatchTemp; +u32 s_pCurBlock_ltime; + +#ifdef _MSC_VER + +// jumped to when invalid pc address +__declspec(naked,noreturn) void Dispatcher() +{ + // EDX contains the jump addr to modify + __asm push edx + + // calc PC_GETBLOCK + s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc); + + __asm { + mov eax, s_pDispatchBlock + + // check if startpc == cpuRegs.pc + mov ecx, cpuRegs.pc + //and ecx, 0x5fffffff // remove higher bits + cmp ecx, dword ptr [eax+BLOCKTYPE_STARTPC] + je CheckPtr + + // recompile + push cpuRegs.pc // pc + call recRecompile + add esp, 4 // pop old param + mov eax, s_pDispatchBlock +CheckPtr: + mov eax, dword ptr [eax] + } + +#ifdef _DEBUG + __asm mov g_EEDispatchTemp, eax + assert( g_EEDispatchTemp ); +#endif + +// __asm { +// test eax, 0x40000000 // BLOCKTYPE_NEEDCLEAR +// jz Done +// // move new pc +// and eax, 0x0fffffff +// mov ecx, cpuRegs.pc +// mov dword ptr [eax+1], ecx +// } + __asm { + and eax, 0x0fffffff + mov edx, eax + pop ecx // x86Ptr to mod + sub edx, ecx + sub edx, 4 + mov dword ptr [ecx], edx + + jmp eax + } +} + +__declspec(naked,noreturn) void DispatcherClear() +{ + // EDX contains the current pc + __asm mov cpuRegs.pc, edx + __asm push edx + + // calc PC_GETBLOCK + s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc); + + if( s_pDispatchBlock->startpc == cpuRegs.pc ) { + assert( s_pDispatchBlock->pFnptr != 0 ); + + // already modded the code, jump to the new place + __asm { + pop edx + add esp, 4 // ignore stack + mov eax, s_pDispatchBlock + mov eax, dword ptr [eax] + and eax, 0x0fffffff + jmp eax + } + } + + __asm { + call recRecompile + add esp, 4 // pop old param + mov eax, s_pDispatchBlock + mov eax, dword ptr [eax] + + pop ecx // old fnptr + + and eax, 0x0fffffff + mov byte ptr [ecx], 0xe9 // jmp32 + mov edx, eax + sub edx, ecx + sub edx, 5 + mov dword ptr [ecx+1], edx + + jmp eax + } +} + +// called when jumping to variable pc address +__declspec(naked,noreturn) void DispatcherReg() +{ + __asm { + //s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc); + mov edx, cpuRegs.pc + mov ecx, edx + } + + __asm { + shr edx, 14 + and edx, 0xfffffffc + add edx, recLUT + mov edx, dword ptr [edx] + + mov eax, ecx + and eax, 0xfffc + // edx += 2*eax + shl eax, 1 + add edx, eax + + // check if startpc == cpuRegs.pc + mov eax, ecx + //and eax, 0x5fffffff // remove higher bits + cmp eax, dword ptr [edx+BLOCKTYPE_STARTPC] + jne recomp + + mov eax, dword ptr [edx] + } + +#ifdef _DEBUG + __asm mov g_EEDispatchTemp, eax + assert( g_EEDispatchTemp ); +#endif + + __asm { + and eax, 0x0fffffff + jmp eax // fnptr + +recomp: + sub esp, 8 + mov dword ptr [esp+4], edx + mov dword ptr [esp], ecx + call recRecompile + mov edx, dword ptr [esp+4] + add esp, 8 + + mov eax, dword ptr [edx] + and eax, 0x0fffffff + jmp eax // fnptr + } +} + +#ifdef PCSX2_DEVBUILD +__declspec(naked) void _StartPerfCounter() +{ + __asm { + push eax + push ebx + push ecx + + rdtsc + mov dword ptr [offset lbase], eax + mov dword ptr [offset lbase + 4], edx + + pop ecx + pop ebx + pop eax + ret + } +} + +__declspec(naked) void _StopPerfCounter() +{ + __asm { + push eax + push ebx + push ecx + + rdtsc + + sub eax, dword ptr [offset lbase] + sbb edx, dword ptr [offset lbase + 4] + mov ecx, s_pCurBlock_ltime + add eax, dword ptr [ecx] + adc edx, dword ptr [ecx + 4] + mov dword ptr [ecx], eax + mov dword ptr [ecx + 4], edx + pop ecx + pop ebx + pop eax + ret + } +} + +#endif // PCSX2_DEVBUILD + +#else // _MSC_VER + +extern void Dispatcher(); +extern void DispatcherClear(); +extern void DispatcherReg(); +extern void _StartPerfCounter(); +extern void _StopPerfCounter(); + +#endif + +#ifdef PCSX2_DEVBUILD +void StartPerfCounter() +{ +#ifdef PCSX2_DEVBUILD + if( s_startcount ) { + CALLFunc((u32)_StartPerfCounter); + } +#endif +} + +void StopPerfCounter() +{ +#ifdef PCSX2_DEVBUILD + if( s_startcount ) { + MOV32ItoM((u32)&s_pCurBlock_ltime, (u32)&s_pCurBlockEx->ltime); + CALLFunc((u32)_StopPerfCounter); + } +#endif +} +#endif + +//////////////////////////////////////////////////// +void recClear64(BASEBLOCK* p) +{ + int left = 4 - ((u32)p % 16)/sizeof(BASEBLOCK); + recClearMem(p); + + if( left > 1 && *(u32*)(p+1) ) recClearMem(p+1); +} + +void recClear128(BASEBLOCK* p) +{ + int left = 4 - ((u32)p % 32)/sizeof(BASEBLOCK); + recClearMem(p); + + if( left > 1 && *(u32*)(p+1) ) recClearMem(p+1); + if( left > 2 && *(u32*)(p+2) ) recClearMem(p+2); + if( left > 3 && *(u32*)(p+3) ) recClearMem(p+3); +} + +void recClear( u32 Addr, u32 Size ) +{ + u32 i; + for(i = 0; i < Size; ++i, Addr+=4) { + REC_CLEARM(Addr); + } +} + +#define EE_MIN_BLOCK_BYTES 15 + +void recClearMem(BASEBLOCK* p) +{ + BASEBLOCKEX* pexblock; + BASEBLOCK* pstart; + int lastdelay; + + // necessary since recompiler doesn't call femms/emms +#ifdef _MSC_VER + if (cpucaps.has3DNOWInstructionExtensions) __asm femms; + else __asm emms; +#else + if( cpucaps.has3DNOWInstructionExtensions )__asm__("femms"); + else __asm__("emms"); +#endif + + assert( p != NULL ); + + if( p->uType & BLOCKTYPE_DELAYSLOT ) { + recClearMem(p-1); + if( p->pFnptr == 0 ) + return; + } + + assert( p->pFnptr != 0 ); + assert( p->startpc ); + + x86Ptr = (s8*)p->pFnptr; + + // there is a small problem: mem can be ored with 0xa<<28 or 0x8<<28, and don't know which + MOV32ItoR(EDX, p->startpc); + PUSH32I((u32)x86Ptr); // will be replaced by JMP32 + JMP32((u32)DispatcherClear - ( (u32)x86Ptr + 5 )); + assert( x86Ptr == (s8*)p->pFnptr + EE_MIN_BLOCK_BYTES ); + + pstart = PC_GETBLOCK(p->startpc); + pexblock = PC_GETBLOCKEX(pstart); + assert( pexblock->startpc == pstart->startpc ); + + if( pexblock->startpc != pstart->startpc ) { + // some bug with ffx after beating a big snake in sewers + RemoveBaseBlockEx(pexblock, 0); + pexblock->size = 0; + pexblock->startpc = 0; + return; + } + +// if( pexblock->pOldFnptr ) { +// // have to mod oldfnptr too +// x86Ptr = pexblock->pOldFnptr; +// +// MOV32ItoR(EDX, p->startpc); +// JMP32((u32)DispatcherClear - ( (u32)x86Ptr + 5 )); +// } +// else +// pexblock->pOldFnptr = (u8*)p->pFnptr; + + // don't delete if last is delay + lastdelay = pexblock->size; + if( pstart[pexblock->size-1].uType & BLOCKTYPE_DELAYSLOT ) { + assert( pstart[pexblock->size-1].pFnptr != pstart->pFnptr ); + if( pstart[pexblock->size-1].pFnptr != 0 ) { + pstart[pexblock->size-1].uType = 0; + --lastdelay; + } + } + + memset(pstart, 0, lastdelay*sizeof(BASEBLOCK)); + + RemoveBaseBlockEx(pexblock, 0); + pexblock->size = 0; + pexblock->startpc = 0; +} + +// check for end of bios +void CheckForBIOSEnd() +{ + MOV32MtoR(EAX, (int)&cpuRegs.pc); + + CMP32ItoR(EAX, 0x00200008); + j8Ptr[0] = JE8(0); + + CMP32ItoR(EAX, 0x00100008); + j8Ptr[1] = JE8(0); + + // return + j8Ptr[2] = JMP8(0); + + x86SetJ8( j8Ptr[0] ); + x86SetJ8( j8Ptr[1] ); + + // bios end + RET2(); + + x86SetJ8( j8Ptr[2] ); +} + +static int *s_pCode; + +void SetBranchReg( u32 reg ) +{ + branch = 1; + + if( reg != 0xffffffff ) { +// if( GPR_IS_CONST1(reg) ) +// MOV32ItoM( (u32)&cpuRegs.pc, g_cpuConstRegs[reg].UL[0] ); +// else { +// int mmreg; +// +// if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, reg, MODE_READ)) >= 0 ) { +// SSE_MOVSS_XMM_to_M32((u32)&cpuRegs.pc, mmreg); +// } +// else if( (mmreg = _checkMMXreg(MMX_GPR+reg, MODE_READ)) >= 0 ) { +// MOVDMMXtoM((u32)&cpuRegs.pc, mmreg); +// SetMMXstate(); +// } +// else { +// MOV32MtoR(EAX, (int)&cpuRegs.GPR.r[ reg ].UL[ 0 ] ); +// MOV32RtoM((u32)&cpuRegs.pc, EAX); +// } +// } + _allocX86reg(ESI, X86TYPE_PCWRITEBACK, 0, MODE_WRITE); + _eeMoveGPRtoR(ESI, reg); + + recompileNextInstruction(1); + + if( x86regs[ESI].inuse ) { + assert( x86regs[ESI].type == X86TYPE_PCWRITEBACK ); + MOV32RtoM((int)&cpuRegs.pc, ESI); + x86regs[ESI].inuse = 0; + } + else { + MOV32MtoR(EAX, (u32)&g_recWriteback); + MOV32RtoM((int)&cpuRegs.pc, EAX); + } + } + +// CMP32ItoM((u32)&cpuRegs.pc, 0); +// j8Ptr[5] = JNE8(0); +// CALLFunc((u32)tempfn); +// x86SetJ8( j8Ptr[5] ); + + iFlushCall(FLUSH_EVERYTHING); + + iBranchTest(0xffffffff, 1); + if( bExecBIOS ) CheckForBIOSEnd(); + + JMP32((u32)DispatcherReg - ( (u32)x86Ptr + 5 )); +} + +void SetBranchImm( u32 imm ) +{ + u32* ptr; + branch = 1; + + assert( imm ); + + // end the current block + MOV32ItoM( (u32)&cpuRegs.pc, imm ); + iFlushCall(FLUSH_EVERYTHING); + + iBranchTest(imm, imm <= pc); + if( bExecBIOS ) CheckForBIOSEnd(); + + MOV32ItoR(EDX, 0); + ptr = (u32*)(x86Ptr-4); + *ptr = (u32)JMP32((u32)Dispatcher - ( (u32)x86Ptr + 5 )); +} + +void SaveBranchState() +{ + s_savex86FpuState = x86FpuState; + s_saveiCWstate = iCWstate; + s_savenBlockCycles = s_nBlockCycles; + s_saveConstGPRreg = 0xffffffff; // indicate searching + s_saveHasConstReg = g_cpuHasConstReg; + s_saveFlushedConstReg = g_cpuFlushedConstReg; + s_psaveInstInfo = g_pCurInstInfo; + s_saveRegHasLive1 = g_cpuRegHasLive1; + s_saveRegHasSignExt = g_cpuRegHasSignExt; + + // save all mmx regs + memcpy(s_saveMMXregs, mmxregs, sizeof(mmxregs)); + memcpy(s_saveXMMregs, xmmregs, sizeof(xmmregs)); +} + +void LoadBranchState() +{ + x86FpuState = s_savex86FpuState; + iCWstate = s_saveiCWstate; + s_nBlockCycles = s_savenBlockCycles; + + if( s_saveConstGPRreg != 0xffffffff ) { + assert( s_saveConstGPRreg > 0 ); + + // make sure right GPR was saved + assert( g_cpuHasConstReg == s_saveHasConstReg || (g_cpuHasConstReg ^ s_saveHasConstReg) == (1<visited, 1 ); + } +#endif + +#ifdef _DEBUG + //CALLFunc((u32)testfpu); +#endif + + if( !USE_FAST_BRANCHES || cpuBranch ) { + MOV32MtoR(ECX, (int)&cpuRegs.cycle); + ADD32ItoR(ECX, s_nBlockCycles*EECYCLE_MULT); // NOTE: mulitply cycles here, 6/5 ratio stops pal ffx from randomly crashing, but crashes jakI + MOV32RtoM((int)&cpuRegs.cycle, ECX); // update cycles + } + else { + ADD32ItoM((int)&cpuRegs.cycle, s_nBlockCycles*EECYCLE_MULT); + return; + } + + SUB32MtoR(ECX, (int)&g_nextBranchCycle); + + // check if should branch + j8Ptr[0] = JS8( 0 ); + + // has to be in the middle of Save/LoadBranchState + CALLFunc( (int)cpuBranchTest ); + + if( newpc != 0xffffffff ) { + CMP32ItoM((int)&cpuRegs.pc, newpc); + JNE32((u32)DispatcherReg - ( (u32)x86Ptr + 6 )); + } + + x86SetJ8( j8Ptr[0] ); +} + + +//////////////////////////////////////////////////// +#ifndef CP2_RECOMPILE + +REC_SYS(COP2); + +#else + +void recCOP2( void ) +{ +#ifdef CPU_LOG + CPU_LOG( "Recompiling COP2:%s\n", disR5900Fasm( cpuRegs.code, cpuRegs.pc ) ); +#endif + + if ( !cpucaps.hasStreamingSIMDExtensions ) { + MOV32ItoM( (u32)&cpuRegs.code, cpuRegs.code ); + MOV32ItoM( (u32)&cpuRegs.pc, pc ); + iFlushCall(FLUSH_EVERYTHING); + g_cpuHasConstReg = 1; // reset all since COP2 can change regs + CALLFunc( (u32)COP2 ); + + CMP32ItoM((int)&cpuRegs.pc, pc); + j8Ptr[0] = JE8(0); + ADD32ItoM((u32)&cpuRegs.cycle, s_nBlockCycles); + JMP32((u32)DispatcherReg - ( (u32)x86Ptr + 5 )); + x86SetJ8(j8Ptr[0]); + } + else + { + recCOP22( ); + } +} + +#endif + +//////////////////////////////////////////////////// +void recSYSCALL( void ) { + MOV32ItoM( (u32)&cpuRegs.code, cpuRegs.code ); + MOV32ItoM( (u32)&cpuRegs.pc, pc ); + iFlushCall(FLUSH_NODESTROY); + CALLFunc( (u32)SYSCALL ); + + CMP32ItoM((int)&cpuRegs.pc, pc); + j8Ptr[0] = JE8(0); + ADD32ItoM((u32)&cpuRegs.cycle, s_nBlockCycles); + JMP32((u32)DispatcherReg - ( (u32)x86Ptr + 5 )); + x86SetJ8(j8Ptr[0]); + //branch = 2; +} + +//////////////////////////////////////////////////// +void recBREAK( void ) { + MOV32ItoM( (u32)&cpuRegs.code, cpuRegs.code ); + MOV32ItoM( (u32)&cpuRegs.pc, pc ); + iFlushCall(FLUSH_EVERYTHING); + CALLFunc( (u32)BREAK ); + + CMP32ItoM((int)&cpuRegs.pc, pc); + j8Ptr[0] = JE8(0); + ADD32ItoM((u32)&cpuRegs.cycle, s_nBlockCycles); + RET(); + x86SetJ8(j8Ptr[0]); + //branch = 2; +} + +//////////////////////////////////////////////////// +//static void recCACHE( void ) { +// MOV32ItoM( (u32)&cpuRegs.code, cpuRegs.code ); +// MOV32ItoM( (u32)&cpuRegs.pc, pc ); +// iFlushCall(FLUSH_EVERYTHING); +// CALLFunc( (u32)CACHE ); +// //branch = 2; +// +// CMP32ItoM((int)&cpuRegs.pc, pc); +// j8Ptr[0] = JE8(0); +// RET(); +// x86SetJ8(j8Ptr[0]); +//} + + +void recPREF( void ) +{ +} + +void recSYNC( void ) +{ +} + +void recMFSA( void ) +{ + int mmreg; + if (!_Rd_) return; + + mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, MODE_WRITE); + if( mmreg >= 0 ) { + SSE_MOVLPS_M64_to_XMM(mmreg, (u32)&cpuRegs.sa); + } + else if( (mmreg = _checkMMXreg(MMX_GPR+_Rd_, MODE_WRITE)) >= 0 ) { + MOVDMtoMMX(mmreg, (u32)&cpuRegs.sa); + SetMMXstate(); + } + else { + MOV32MtoR(EAX, (u32)&cpuRegs.sa); + _deleteEEreg(_Rd_, 0); + MOV32RtoM((u32)&cpuRegs.GPR.r[_Rd_].UL[0], EAX); + MOV32ItoM((u32)&cpuRegs.GPR.r[_Rd_].UL[1], 0); + } +} + +void recMTSA( void ) +{ + if( GPR_IS_CONST1(_Rs_) ) { + MOV32ItoM((u32)&cpuRegs.sa, g_cpuConstRegs[_Rs_].UL[0] ); + } + else { + int mmreg; + + if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) { + SSE_MOVSS_XMM_to_M32((u32)&cpuRegs.sa, mmreg); + } + else if( (mmreg = _checkMMXreg(MMX_GPR+_Rs_, MODE_READ)) >= 0 ) { + MOVDMMXtoM((u32)&cpuRegs.sa, mmreg); + SetMMXstate(); + } + else { + MOV32MtoR(EAX, (u32)&cpuRegs.GPR.r[_Rs_].UL[0]); + MOV32RtoM((u32)&cpuRegs.sa, EAX); + } + } +} + +void recMTSAB( void ) +{ + if( GPR_IS_CONST1(_Rs_) ) { + MOV32ItoM((u32)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF)) << 3); + } + else { + _eeMoveGPRtoR(EAX, _Rs_); + AND32ItoR(EAX, 0xF); + XOR32ItoR(EAX, _Imm_&0xf); + SHL32ItoR(EAX, 3); + MOV32RtoM((u32)&cpuRegs.sa, EAX); + } +} + +void recMTSAH( void ) +{ + if( GPR_IS_CONST1(_Rs_) ) { + MOV32ItoM((u32)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 4); + } + else { + _eeMoveGPRtoR(EAX, _Rs_); + AND32ItoR(EAX, 0x7); + XOR32ItoR(EAX, _Imm_&0x7); + SHL32ItoR(EAX, 4); + MOV32RtoM((u32)&cpuRegs.sa, EAX); + } +} + +static void checkcodefn() +{ + int pctemp; + +#ifdef _MSC_VER + __asm mov pctemp, eax; +#else + __asm__("movl %%eax, %0" : "=m"(pctemp) ); +#endif + + SysPrintf("code changed! %x\n", pctemp); + assert(0); +} + +void checkpchanged(u32 startpc) +{ + assert(0); +} + +//#ifdef _DEBUG +//#define CHECK_XMMCHANGED() CALLFunc((u32)checkxmmchanged); +//#else +//#define CHECK_XMMCHANGED() +//#endif +// +//static void checkxmmchanged() +//{ +// assert( !g_globalMMXSaved ); +// assert( !g_globalXMMSaved ); +//} + +u32 recompileCodeSafe(u32 temppc) +{ + BASEBLOCK* pblock = PC_GETBLOCK(temppc); + + if( pblock->pFnptr != 0 && pblock->startpc != s_pCurBlock->startpc ) { + if( pc == pblock->startpc ) + return 0; + } + + return 1; +} + +void recompileNextInstruction(int delayslot) +{ + static u8 s_bFlushReg = 1; + int i, count; + + BASEBLOCK* pblock = PC_GETBLOCK(pc); + + // need *ppblock != s_pCurBlock because of branches + if( pblock->pFnptr != 0 && pblock->startpc != s_pCurBlock->startpc ) { + + if( !delayslot && pc == pblock->startpc ) { + // code already in place, so jump to it and exit recomp + assert( PC_GETBLOCKEX(pblock)->startpc == pblock->startpc ); + + iFlushCall(FLUSH_EVERYTHING); + MOV32ItoM((u32)&cpuRegs.pc, pc); + +// if( pexblock->pOldFnptr ) { +// // code already in place, so jump to it and exit recomp +// JMP32((u32)pexblock->pOldFnptr - ((u32)x86Ptr + 5)); +// branch = 3; +// return; +// } + + JMP32((u32)pblock->pFnptr - ((u32)x86Ptr + 5)); + branch = 3; + return; + } + else { + + if( !(delayslot && pblock->startpc == pc) ) { + s8* oldX86 = x86Ptr; + //__Log("clear block %x\n", pblock->startpc); + recClearMem(pblock); + x86Ptr = oldX86; + if( delayslot ) + SysPrintf("delay slot %x\n", pc); + } + } + } + + if( delayslot ) + pblock->uType = BLOCKTYPE_DELAYSLOT; + + s_pCode = (int *)PSM( pc ); + assert(s_pCode); + +#ifdef _DEBUG + MOV32ItoR(EAX, pc); +#endif + + cpuRegs.code = *(int *)s_pCode; + s_nBlockCycles++; + pc += 4; + +//#ifdef _DEBUG +// CMP32ItoM((u32)s_pCode, cpuRegs.code); +// j8Ptr[0] = JE8(0); +// MOV32ItoR(EAX, pc); +// CALLFunc((u32)checkcodefn); +// x86SetJ8( j8Ptr[ 0 ] ); +// +// if( !delayslot ) { +// CMP32ItoM((u32)&cpuRegs.pc, s_pCurBlockEx->startpc); +// j8Ptr[0] = JB8(0); +// CMP32ItoM((u32)&cpuRegs.pc, pc); +// j8Ptr[1] = JA8(0); +// j8Ptr[2] = JMP8(0); +// x86SetJ8( j8Ptr[ 0 ] ); +// x86SetJ8( j8Ptr[ 1 ] ); +// PUSH32I(s_pCurBlockEx->startpc); +// CALLFunc((u32)checkpchanged); +// ADD32ItoR(ESP, 4); +// x86SetJ8( j8Ptr[ 2 ] ); +// } +//#endif + + g_pCurInstInfo++; + + // reorder register priorities +// for(i = 0; i < X86REGS; ++i) { +// if( x86regs[i].inuse ) { +// if( count > 0 ) mmxregs[i].counter = 1000-count; +// else mmxregs[i].counter = 0; +// } +// } + + for(i = 0; i < MMXREGS; ++i) { + if( mmxregs[i].inuse ) { + assert( MMX_ISGPR(mmxregs[i].reg) ); + count = _recIsRegWritten(g_pCurInstInfo, (s_nEndBlock-pc)/4 + 1, XMMTYPE_GPRREG, mmxregs[i].reg-MMX_GPR); + if( count > 0 ) mmxregs[i].counter = 1000-count; + else mmxregs[i].counter = 0; + } + } + + for(i = 0; i < XMMREGS; ++i) { + if( xmmregs[i].inuse ) { + count = _recIsRegWritten(g_pCurInstInfo, (s_nEndBlock-pc)/4 + 1, xmmregs[i].type, xmmregs[i].reg); + if( count > 0 ) xmmregs[i].counter = 1000-count; + else xmmregs[i].counter = 0; + } + } + + // peephole optimizations + if( g_pCurInstInfo->info & EEINSTINFO_COREC ) { + +#ifdef PCSX2_VIRTUAL_MEM + if( g_pCurInstInfo->numpeeps > 1 ) { + switch(cpuRegs.code>>26) { + case 30: recLQ_coX(g_pCurInstInfo->numpeeps); break; + case 31: recSQ_coX(g_pCurInstInfo->numpeeps); break; + case 49: recLWC1_coX(g_pCurInstInfo->numpeeps); break; + case 57: recSWC1_coX(g_pCurInstInfo->numpeeps); break; + case 55: recLD_coX(g_pCurInstInfo->numpeeps); break; + case 63: recSD_coX(g_pCurInstInfo->numpeeps); break; + default: + assert(0); + } + + pc += g_pCurInstInfo->numpeeps*4; + s_nBlockCycles += g_pCurInstInfo->numpeeps; + g_pCurInstInfo += g_pCurInstInfo->numpeeps; + } + else { + recBSC_co[cpuRegs.code>>26](); + pc += 4; + s_nBlockCycles++; + g_pCurInstInfo++; + } +#else + assert(0); +#endif + } + else { + assert( !(g_pCurInstInfo->info & EEINSTINFO_NOREC) ); + + // if this instruction is a jump or a branch, exit right away + if( delayslot ) { + switch(cpuRegs.code>>26) { + case 1: + switch(_Rt_) { + case 0: case 1: case 2: case 3: case 0x10: case 0x11: case 0x12: case 0x13: + SysPrintf("branch %x in delay slot!\n", cpuRegs.code); + _clearNeededX86regs(); + _clearNeededMMXregs(); + _clearNeededXMMregs(); + return; + } + break; + + case 2: case 3: case 4: case 5: case 6: case 7: case 0x14: case 0x15: case 0x16: case 0x17: + SysPrintf("branch %x in delay slot!\n", cpuRegs.code); + _clearNeededX86regs(); + _clearNeededMMXregs(); + _clearNeededXMMregs(); + return; + } + } + recBSC[ cpuRegs.code >> 26 ](); + } + + if( !delayslot ) { + if( s_bFlushReg ) { + //if( !_flushUnusedConstReg() ) { + int flushed = 0; + if( _getNumMMXwrite() > 3 ) flushed = _flushMMXunused(); + if( !flushed && _getNumXMMwrite() > 2 ) _flushXMMunused(); + s_bFlushReg = !flushed; +// } +// else s_bFlushReg = 0; + } + else s_bFlushReg = 1; + } + else s_bFlushReg = 1; + + //CHECK_XMMCHANGED(); + _clearNeededX86regs(); + _clearNeededMMXregs(); + _clearNeededXMMregs(); + +// _freeXMMregs(); +// _freeMMXregs(); +// _flushCachedRegs(); +// g_cpuHasConstReg = 1; +} + +//__declspec(naked) void iDummyBlock() +//{ +//// g_lastpc = cpuRegs.pc; +//// +//// do { +//// cpuRegs.cycle = g_nextBranchCycle; +//// cpuBranchTest(); +//// } while(g_lastpc == cpuRegs.pc); +//// +//// __asm jmp DispatcherReg +// __asm { +//RepDummy: +// add cpuRegs.cycle, 9 +// call cpuBranchTest +// cmp cpuRegs.pc, 0x81fc0 +// je RepDummy +// jmp DispatcherReg +// } +//} + +//////////////////////////////////////////////////// +#include "R3000A.h" +#include "PsxCounters.h" +#include "PsxMem.h" +extern tIPU_BP g_BP; + +extern u32 psxdump; +extern u32 psxNextCounter, psxNextsCounter; +extern void iDumpPsxRegisters(u32 startpc, u32 temp); +extern Counter counters[6]; +extern int rdram_devices; // put 8 for TOOL and 2 for PS2 and PSX +extern int rdram_sdevid; + +void iDumpRegisters(u32 startpc, u32 temp) +{ + int i; + char* pstr = temp ? "t" : ""; + const u32 dmacs[] = {0x8000, 0x9000, 0xa000, 0xb000, 0xb400, 0xc000, 0xc400, 0xc800, 0xd000, 0xd400 }; + extern char *disRNameGPR[]; + char* psymb; + + psymb = disR5900GetSym(startpc); + + if( psymb != NULL ) + __Log("%sreg(%s): %x %x c:%x\n", pstr, psymb, startpc, cpuRegs.interrupt, cpuRegs.cycle); + else + __Log("%sreg: %x %x c:%x\n", pstr, startpc, cpuRegs.interrupt, cpuRegs.cycle); + for(i = 1; i < 32; ++i) __Log("%s: %x_%x_%x_%x\n", disRNameGPR[i], cpuRegs.GPR.r[i].UL[3], cpuRegs.GPR.r[i].UL[2], cpuRegs.GPR.r[i].UL[1], cpuRegs.GPR.r[i].UL[0]); + //for(i = 0; i < 32; i+=4) __Log("cp%d: %x_%x_%x_%x\n", i, cpuRegs.CP0.r[i], cpuRegs.CP0.r[i+1], cpuRegs.CP0.r[i+2], cpuRegs.CP0.r[i+3]); + //for(i = 0; i < 32; ++i) __Log("%sf%d: %f %x\n", pstr, i, fpuRegs.fpr[i].f, fpuRegs.fprc[i]); + //for(i = 1; i < 32; ++i) __Log("%svf%d: %f %f %f %f, vi: %x\n", pstr, i, VU0.VF[i].F[3], VU0.VF[i].F[2], VU0.VF[i].F[1], VU0.VF[i].F[0], VU0.VI[i].UL); + for(i = 0; i < 32; ++i) __Log("%sf%d: %x %x\n", pstr, i, fpuRegs.fpr[i].UL, fpuRegs.fprc[i]); + for(i = 1; i < 32; ++i) __Log("%svf%d: %x %x %x %x, vi: %x\n", pstr, i, VU0.VF[i].UL[3], VU0.VF[i].UL[2], VU0.VF[i].UL[1], VU0.VF[i].UL[0], VU0.VI[i].UL); + __Log("%svfACC: %x %x %x %x\n", pstr, VU0.ACC.UL[3], VU0.ACC.UL[2], VU0.ACC.UL[1], VU0.ACC.UL[0]); + __Log("%sLO: %x_%x_%x_%x, HI: %x_%x_%x_%x\n", pstr, cpuRegs.LO.UL[3], cpuRegs.LO.UL[2], cpuRegs.LO.UL[1], cpuRegs.LO.UL[0], + cpuRegs.HI.UL[3], cpuRegs.HI.UL[2], cpuRegs.HI.UL[1], cpuRegs.HI.UL[0]); + __Log("%sCycle: %x %x, Count: %x\n", pstr, cpuRegs.cycle, g_nextBranchCycle, cpuRegs.CP0.n.Count); + iDumpPsxRegisters(psxRegs.pc, temp); + + __Log("f410,30,40: %x %x %x, %d %d\n", psHu32(0xf410), psHu32(0xf430), psHu32(0xf440), rdram_sdevid, rdram_devices); + __Log("cyc11: %x %x; vu0: %x, vu1: %x\n", cpuRegs.sCycle[1], cpuRegs.eCycle[1], VU0.cycle, VU1.cycle); + + __Log("%scounters: %x %x; psx: %x %x\n", pstr, nextsCounter, nextCounter, psxNextsCounter, psxNextCounter); + for(i = 0; i < 4; ++i) { + __Log("eetimer%d: count: %x mode: %x target: %x %x; %x %x; %x %x %x %x\n", i, + counters[i].count, counters[i].mode, counters[i].target, counters[i].hold, counters[i].rate, + counters[i].interrupt, counters[i].Cycle, counters[i].sCycle, counters[i].CycleT, counters[i].sCycleT); + } + __Log("VIF0_STAT = %x, VIF1_STAT = %x\n", psHu32(0x3800), psHu32(0x3C00)); + __Log("ipu %x %x %x %x; bp: %x %x %x %x\n", psHu32(0x2000), psHu32(0x2010), psHu32(0x2020), psHu32(0x2030), g_BP.BP, g_BP.bufferhasnew, g_BP.FP, g_BP.IFC); + __Log("gif: %x %x %x\n", psHu32(0x3000), psHu32(0x3010), psHu32(0x3020)); + 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\n", i, p->chcr, p->madr, p->qwc, p->tadr, p->sadr); + } + __Log("dmac %x %x %x %x\n", psHu32(DMAC_CTRL), psHu32(DMAC_STAT), psHu32(DMAC_RBSR), psHu32(DMAC_RBOR)); + __Log("intc %x %x\n", psHu32(INTC_STAT), psHu32(INTC_MASK)); + __Log("sif: %x %x %x %x %x\n", psHu32(0xf200), psHu32(0xf220), psHu32(0xf230), psHu32(0xf240), psHu32(0xf260)); +} + +extern u32 psxdump; + +static void printfn() +{ + static int lastrec = 0; + static int curcount = 0, count2 = 0; + const int skip = 0; + static int i; + + assert( !g_globalMMXSaved ); + assert( !g_globalXMMSaved ); + + if( (dumplog&2) && g_lastpc != 0x81fc0 ) {//&& lastrec != g_lastpc ) { + curcount++; + + if( curcount > skip ) { + iDumpRegisters(g_lastpc, 1); + curcount = 0; + } + + lastrec = g_lastpc; + } +} + +u32 s_recblocks[] = {0}; + +void badespfn() { + assert(0); + SysPrintf("Bad esp!\n"); +} + +#define OPTIMIZE_COP2 0//CHECK_VU0REC + +void recRecompile( u32 startpc ) +{ + u32 i = 0; + u32 branchTo; + u32 willbranch3 = 0; + u32* ptr; + u32 usecop2; + +#ifdef _DEBUG + //dumplog |= 4; + if( dumplog & 4 ) + iDumpRegisters(startpc, 0); +#endif + + assert( startpc ); + + // if recPtr reached the mem limit reset whole mem + if ( ( (uptr)recPtr - (uptr)recMem ) >= REC_CACHEMEM-0x40000 || dumplog == 0xffffffff) { + recReset(); + } + if ( ( (uptr)recStackPtr - (uptr)recStack ) >= RECSTACK_SIZE-0x100 ) { +#ifdef _DEBUG + SysPrintf("stack reset\n"); +#endif + recReset(); + } + + s_pCurBlock = PC_GETBLOCK(startpc); + + if( s_pCurBlock->pFnptr ) { + // clear if already taken + assert( s_pCurBlock->startpc < startpc ); + recClearMem(s_pCurBlock); + } + + if( s_pCurBlock->startpc == startpc ) { + s_pCurBlockEx = PC_GETBLOCKEX(s_pCurBlock); + assert( s_pCurBlockEx->startpc == startpc ); + } + else { + s_pCurBlockEx = NULL; + for(i = 0; i < EE_NUMBLOCKS; ++i) { + if( recBlocks[(i+s_nNextBlock)%EE_NUMBLOCKS].size == 0 ) { + s_pCurBlockEx = recBlocks+(i+s_nNextBlock)%EE_NUMBLOCKS; + s_nNextBlock = (i+s_nNextBlock+1)%EE_NUMBLOCKS; + break; + } + } + + if( s_pCurBlockEx == NULL ) { + //SysPrintf("ee reset (blocks)\n"); + recReset(); + s_nNextBlock = 0; + s_pCurBlockEx = recBlocks; + } + + s_pCurBlockEx->startpc = startpc; + } + + x86SetPtr( recPtr ); + x86Align(16); + recPtr = x86Ptr; + s_pCurBlock->pFnptr = (u32)x86Ptr; + s_pCurBlock->startpc = startpc; + + // slower +// if( startpc == 0x81fc0 ) { +// +// MOV32MtoR(ECX, (u32)&g_nextBranchCycle); +// MOV32RtoM((u32)&cpuRegs.cycle, ECX); +// //ADD32ItoR(ECX, 9); +// //ADD32ItoM((u32)&cpuRegs.cycle, 512); +// CALLFunc((u32)cpuBranchTest); +// CMP32ItoM((u32)&cpuRegs.pc, 0x81fc0); +// JE8(s_pCurBlock->pFnptr - (u32)(x86Ptr+2) ); +// JMP32((u32)DispatcherReg - (u32)(x86Ptr+5)); +// +// pc = startpc + 9*4; +// assert( (pc-startpc)>>2 <= 0xffff ); +// s_pCurBlockEx->size = (pc-startpc)>>2; +// +// for(i = 1; i < (u32)s_pCurBlockEx->size-1; ++i) { +// s_pCurBlock[i].pFnptr = s_pCurBlock->pFnptr; +// s_pCurBlock[i].startpc = s_pCurBlock->startpc; +// } +// +// // don't overwrite if delay slot +// if( i < (u32)s_pCurBlockEx->size && !(s_pCurBlock[i].uType & BLOCKTYPE_DELAYSLOT) ) { +// s_pCurBlock[i].pFnptr = s_pCurBlock->pFnptr; +// s_pCurBlock[i].startpc = s_pCurBlock->startpc; +// } +// +// // set the block ptr +// AddBaseBlockEx(s_pCurBlockEx, 0); +// +// if( !(pc&0x10000000) ) +// maxrecmem = max( (pc&~0xa0000000), maxrecmem ); +// +// recPtr = x86Ptr; +// return; +// } + + branch = 0; + + // reset recomp state variables + s_nBlockCycles = 0; + pc = startpc; + x86FpuState = FPU_STATE; + iCWstate = 0; + s_saveConstGPRreg = 0; + g_cpuHasConstReg = g_cpuFlushedConstReg = 1; + g_cpuPrevRegHasLive1 = g_cpuRegHasLive1 = 0xffffffff; + g_cpuPrevRegHasSignExt = g_cpuRegHasSignExt = 0; + _recClearWritebacks(); + assert( g_cpuConstRegs[0].UD[0] == 0 ); + + _initX86regs(); + _initXMMregs(); + _initMMXregs(); + +#ifdef _DEBUG + // for debugging purposes + MOV32ItoM((u32)&g_lastpc, pc); + CALLFunc((u32)printfn); + +// CMP32MtoR(EBP, (u32)&s_uSaveEBP); +// j8Ptr[0] = JE8(0); +// CALLFunc((u32)badespfn); +// x86SetJ8(j8Ptr[0]); +#endif + + // go until the next branch + i = startpc; + s_nEndBlock = 0xffffffff; + s_nHasDelay = 0; + + while(1) { + BASEBLOCK* pblock = PC_GETBLOCK(i); + if( pblock->pFnptr != 0 && pblock->startpc != s_pCurBlock->startpc ) { + + if( i == pblock->startpc ) { + // branch = 3 + willbranch3 = 1; + s_nEndBlock = i; + break; + } + } + + cpuRegs.code = *(int *)PSM(i); + + switch(cpuRegs.code >> 26) { + case 0: // special + + if( _Funct_ == 8 || _Funct_ == 9 ) { // JR, JALR + s_nEndBlock = i + 8; + s_nHasDelay = 1; + goto StartRecomp; + } + + break; + case 1: // regimm + + if( _Rt_ < 4 || (_Rt_ >= 16 && _Rt_ < 20) ) { + // branches + if( _Rt_ == 2 && _Rt_ == 3 && _Rt_ == 18 && _Rt_ == 19 ) s_nHasDelay = 1; + else s_nHasDelay = 2; + + branchTo = _Imm_ * 4 + i + 4; + if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo; + else s_nEndBlock = i+8; + + goto StartRecomp; + } + + break; + + case 2: // J + case 3: // JAL + s_nHasDelay = 1; + s_nEndBlock = i + 8; + goto StartRecomp; + + // branches + case 4: case 5: case 6: case 7: + case 20: case 21: case 22: case 23: + + if( (cpuRegs.code >> 26) >= 20 ) s_nHasDelay = 1; + else s_nHasDelay = 2; + + branchTo = _Imm_ * 4 + i + 4; + if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo; + else s_nEndBlock = i+8; + + goto StartRecomp; + + case 16: // cp0 + if( _Rs_ == 16 ) { + if( _Funct_ == 24 ) { // eret + s_nEndBlock = i+4; + goto StartRecomp; + } + } + + break; + case 17: // cp1 + case 18: // cp2 + if( _Rs_ == 8 ) { + // BC1F, BC1T, BC1FL, BC1TL + // BC2F, BC2T, BC2FL, BC2TL + if( _Rt_ >= 2 ) s_nHasDelay = 1; + else s_nHasDelay = 2; + + branchTo = _Imm_ * 4 + i + 4; + if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo; + else s_nEndBlock = i+8; + + goto StartRecomp; + } + break; + } + + i += 4; + } + +StartRecomp: + + // rec info // + { + EEINST* pcur; + + if( s_nInstCacheSize < (s_nEndBlock-startpc)/4+1 ) { + free(s_pInstCache); + s_nInstCacheSize = (s_nEndBlock-startpc)/4+10; + s_pInstCache = (EEINST*)malloc(sizeof(EEINST)*s_nInstCacheSize); + assert( s_pInstCache != NULL ); + } + + pcur = s_pInstCache + (s_nEndBlock-startpc)/4; + _recClearInst(pcur); + pcur->info = 0; + + for(i = s_nEndBlock; i > startpc; i -= 4 ) { + cpuRegs.code = *(int *)PSM(i-4); + pcur[-1] = pcur[0]; + rpropBSC(pcur-1, pcur); + pcur--; + } + } + + // analyze instructions // + { + usecop2 = 0; + g_pCurInstInfo = s_pInstCache; + + for(i = startpc; i < s_nEndBlock; i += 4) { + g_pCurInstInfo++; + cpuRegs.code = *(u32*)PSM(i); + + // cop2 // + if( g_pCurInstInfo->info & EEINSTINFO_COP2 ) { + + if( !usecop2 ) { + // init + if( OPTIMIZE_COP2 ) { + memset(VU0.fmac,0,sizeof(VU0.fmac)); + memset(&VU0.fdiv,0,sizeof(VU0.fdiv)); + memset(&VU0.efu,0,sizeof(VU0.efu)); + } + vucycle = 0; + usecop2 = 1; + } + + VU0.code = cpuRegs.code; + _cop2AnalyzeOp(g_pCurInstInfo, OPTIMIZE_COP2); + continue; + } + + if( usecop2 ) vucycle++; + + // peephole optimizations // +#ifdef PCSX2_VIRTUAL_MEM + if( i < s_nEndBlock-4 && recompileCodeSafe(i) ) { + u32 curcode = cpuRegs.code; + u32 nextcode = *(u32*)PSM(i+4); + if( _eeIsLoadStoreCoIssue(curcode, nextcode) && recBSC_co[curcode>>26] != NULL ) { + + // rs has to be the same, and cannot be just written + if( ((curcode >> 21) & 0x1F) == ((nextcode >> 21) & 0x1F) && !_eeLoadWritesRs(curcode) ) { + + if( _eeIsLoadStoreCoX(curcode) && ((nextcode>>16)&0x1f) != ((curcode>>21)&0x1f) ) { + // see how many stores there are + u32 j; + // use xmmregs since only supporting lwc1,lq,swc1,sq + for(j = i+8; j < s_nEndBlock && j < i+4*XMMREGS; j += 4 ) { + u32 nncode = *(u32*)PSM(j); + if( (nncode>>26) != (curcode>>26) || ((curcode>>21)&0x1f) != ((nncode>>21)&0x1f) || + _eeLoadWritesRs(nncode)) + break; + } + + if( j > i+8 ) { + u32 num = (j-i)>>2; // number of stores that can coissue + assert( num <= XMMREGS ); + + g_pCurInstInfo[0].numpeeps = num-1; + g_pCurInstInfo[0].info |= EEINSTINFO_COREC; + + while(i < j-4) { + g_pCurInstInfo++; + g_pCurInstInfo[0].info |= EEINSTINFO_NOREC; + i += 4; + } + + continue; + } + + // fall through + } + + // unaligned loadstores + + // if LWL, check if LWR and that offsets are +3 away + switch(curcode >> 26) { + case 0x22: // LWL + if( (nextcode>>26) != 0x26 || ((s16)nextcode)+3 != (s16)curcode ) + continue; + break; + case 0x26: // LWR + if( (nextcode>>26) != 0x22 || ((s16)nextcode) != (s16)curcode+3 ) + continue; + break; + + case 0x2a: // SWL + if( (nextcode>>26) != 0x2e || ((s16)nextcode)+3 != (s16)curcode ) + continue; + break; + case 0x2e: // SWR + if( (nextcode>>26) != 0x2a || ((s16)nextcode) != (s16)curcode+3 ) + continue; + break; + + case 0x1a: // LDL + if( (nextcode>>26) != 0x1b || ((s16)nextcode)+7 != (s16)curcode ) + continue; + break; + case 0x1b: // LWR + if( (nextcode>>26) != 0x1aa || ((s16)nextcode) != (s16)curcode+7 ) + continue; + break; + + case 0x2c: // SWL + if( (nextcode>>26) != 0x2d || ((s16)nextcode)+7 != (s16)curcode ) + continue; + break; + case 0x2d: // SWR + if( (nextcode>>26) != 0x2c || ((s16)nextcode) != (s16)curcode+7 ) + continue; + break; + } + + // good enough + g_pCurInstInfo[0].info |= EEINSTINFO_COREC; + g_pCurInstInfo[0].numpeeps = 1; + g_pCurInstInfo[1].info |= EEINSTINFO_NOREC; + g_pCurInstInfo++; + i += 4; + continue; + } + } + } +#endif // end peephole + } + + if( usecop2 ) { + // add necessary mac writebacks + g_pCurInstInfo = s_pInstCache; + + for(i = startpc; i < s_nEndBlock-4; i += 4) { + g_pCurInstInfo++; + + if( g_pCurInstInfo->info & EEINSTINFO_COP2 ) { + } + } + } + } + + // perf counters // +#ifdef PCSX2_DEVBUILD + s_startcount = 0; +// if( pc+32 < s_nEndBlock ) { +// // only blocks with more than 8 insts +// //PUSH32I((u32)&lbase); +// //CALLFunc((u32)QueryPerformanceCounter); +// lbase.QuadPart = GetCPUTick(); +// s_startcount = 1; +// } +#endif + +#ifdef _DEBUG + // dump code + for(i = 0; i < ARRAYSIZE(s_recblocks); ++i) { + if( startpc == s_recblocks[i] ) { + iDumpBlock(startpc, recPtr); + } + } + + if( (dumplog & 1) ) //|| usecop2 ) + iDumpBlock(startpc, recPtr); +#endif + + // finally recompile // + g_pCurInstInfo = s_pInstCache; + while (!branch && pc < s_nEndBlock) { + recompileNextInstruction(0); + } + +#ifdef _DEBUG + if( (dumplog & 1) ) + iDumpBlock(startpc, recPtr); +#endif + + assert( (pc-startpc)>>2 <= 0xffff ); + s_pCurBlockEx->size = (pc-startpc)>>2; + + for(i = 1; i < (u32)s_pCurBlockEx->size-1; ++i) { + s_pCurBlock[i].pFnptr = s_pCurBlock->pFnptr; + s_pCurBlock[i].startpc = s_pCurBlock->startpc; + } + + // don't overwrite if delay slot + if( i < (u32)s_pCurBlockEx->size && !(s_pCurBlock[i].uType & BLOCKTYPE_DELAYSLOT) ) { + s_pCurBlock[i].pFnptr = s_pCurBlock->pFnptr; + s_pCurBlock[i].startpc = s_pCurBlock->startpc; + } + + // set the block ptr + AddBaseBlockEx(s_pCurBlockEx, 0); +// if( p[1].startpc == p[0].startpc + 4 ) { +// assert( p[1].pFnptr != 0 ); +// // already fn in place, so add to list +// AddBaseBlockEx(s_pCurBlockEx, 0); +// } +// else +// *(BASEBLOCKEX**)(p+1) = pex; +// } + + //PC_SETBLOCKEX(s_pCurBlock, s_pCurBlockEx); + + if( !(pc&0x10000000) ) + maxrecmem = max( (pc&~0xa0000000), maxrecmem ); + + if( branch == 2 ) { + iFlushCall(FLUSH_EVERYTHING); + + iBranchTest(0xffffffff, 1); + if( bExecBIOS ) CheckForBIOSEnd(); + + JMP32((u32)DispatcherReg - ( (u32)x86Ptr + 5 )); + } + else { + assert( branch != 3 ); + if( branch ) assert( !willbranch3 ); + else ADD32ItoM((int)&cpuRegs.cycle, s_nBlockCycles*EECYCLE_MULT); + + if( willbranch3 ) { + BASEBLOCK* pblock = PC_GETBLOCK(s_nEndBlock); + assert( pc == s_nEndBlock ); + iFlushCall(FLUSH_EVERYTHING); + MOV32ItoM((u32)&cpuRegs.pc, pc); + JMP32((u32)pblock->pFnptr - ((u32)x86Ptr + 5)); + branch = 3; + } + else if( !branch ) { + // didn't branch, but had to stop + MOV32ItoM( (u32)&cpuRegs.pc, pc ); + + iFlushCall(FLUSH_EVERYTHING); + + ptr = JMP32(0); + } + } + + assert( x86Ptr >= (s8*)s_pCurBlock->pFnptr + EE_MIN_BLOCK_BYTES ); + assert( x86Ptr < recMem+REC_CACHEMEM ); + assert( recStackPtr < recStack+RECSTACK_SIZE ); + assert( x86FpuState == 0 ); + + recPtr = x86Ptr; + + assert( (g_cpuHasConstReg&g_cpuFlushedConstReg) == g_cpuHasConstReg ); + + if( !branch ) { + BASEBLOCK* pcurblock = s_pCurBlock; + u32 nEndBlock = s_nEndBlock; + s_pCurBlock = PC_GETBLOCK(pc); + assert( ptr != NULL ); + + if( s_pCurBlock->startpc != pc ) + recRecompile(pc); + + if( pcurblock->startpc == startpc ) { + assert( pcurblock->pFnptr ); + assert( s_pCurBlock->startpc == nEndBlock ); + *ptr = s_pCurBlock->pFnptr - ( (u32)ptr + 4 ); + } + else { + recRecompile(startpc); + assert( pcurblock->pFnptr != 0 ); + } + } +} + +R5900cpu recCpu = { + recInit, + recReset, + recStep, + recExecute, + recExecuteBlock, + recExecuteVU0Block, + recExecuteVU1Block, + recEnableVU0micro, + recEnableVU1micro, + recClear, + recClearVU0, + recClearVU1, + recShutdown +}; + +#endif // PCSX2_NORECBUILD diff --git a/pcsx2/x86/ix86-32/iR5900Arit.c b/pcsx2/x86/ix86-32/iR5900Arit.c index bda9ea2..e1d21d5 100644 --- a/pcsx2/x86/ix86-32/iR5900Arit.c +++ b/pcsx2/x86/ix86-32/iR5900Arit.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ // stop compiling if NORECBUILD build (only for Visual Studio) diff --git a/pcsx2/x86/ix86-32/iR5900AritImm.c b/pcsx2/x86/ix86-32/iR5900AritImm.c index a15fd8d..c61be65 100644 --- a/pcsx2/x86/ix86-32/iR5900AritImm.c +++ b/pcsx2/x86/ix86-32/iR5900AritImm.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/pcsx2/x86/ix86-32/iR5900Branch.c b/pcsx2/x86/ix86-32/iR5900Branch.c index bfb0c15..a83099a 100644 --- a/pcsx2/x86/ix86-32/iR5900Branch.c +++ b/pcsx2/x86/ix86-32/iR5900Branch.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ // stop compiling if NORECBUILD build (only for Visual Studio) diff --git a/pcsx2/x86/ix86-32/iR5900Jump.c b/pcsx2/x86/ix86-32/iR5900Jump.c index e28f28e..0679b0b 100644 --- a/pcsx2/x86/ix86-32/iR5900Jump.c +++ b/pcsx2/x86/ix86-32/iR5900Jump.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ // stop compiling if NORECBUILD build (only for Visual Studio) diff --git a/pcsx2/x86/ix86-32/iR5900LoadStore.c b/pcsx2/x86/ix86-32/iR5900LoadStore.c index d00afc7..902a6ec 100644 --- a/pcsx2/x86/ix86-32/iR5900LoadStore.c +++ b/pcsx2/x86/ix86-32/iR5900LoadStore.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ // stop compiling if NORECBUILD build (only for Visual Studio) diff --git a/pcsx2/x86/ix86-32/iR5900Move.c b/pcsx2/x86/ix86-32/iR5900Move.c index 8eaf2c7..62e7be7 100644 --- a/pcsx2/x86/ix86-32/iR5900Move.c +++ b/pcsx2/x86/ix86-32/iR5900Move.c @@ -1,20 +1,20 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86-32/iR5900MultDiv.c b/pcsx2/x86/ix86-32/iR5900MultDiv.c index 7a25562..1d55b07 100644 --- a/pcsx2/x86/ix86-32/iR5900MultDiv.c +++ b/pcsx2/x86/ix86-32/iR5900MultDiv.c @@ -1,20 +1,21 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86-32/iR5900Shift.c b/pcsx2/x86/ix86-32/iR5900Shift.c index ff6ad41..b590063 100644 --- a/pcsx2/x86/ix86-32/iR5900Shift.c +++ b/pcsx2/x86/ix86-32/iR5900Shift.c @@ -1,20 +1,21 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86-64/fast_routines-64.asm b/pcsx2/x86/ix86-64/fast_routines-64.asm index e85c531..77e2744 100644 --- a/pcsx2/x86/ix86-64/fast_routines-64.asm +++ b/pcsx2/x86/ix86-64/fast_routines-64.asm @@ -1,5 +1,5 @@ ; Pcsx2 - Pc Ps2 Emulator -; Copyright (C) 2002-2007 Pcsx2 Team +; Copyright (C) 2002-2008 Pcsx2 Team ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software -; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ;; Fast assembly routines for x86-64 masm compiler ;; zerofrog(@gmail.com) diff --git a/pcsx2/x86/ix86-64/iCore-64.cpp b/pcsx2/x86/ix86-64/iCore-64.cpp index 0e00222..3446f9b 100644 --- a/pcsx2/x86/ix86-64/iCore-64.cpp +++ b/pcsx2/x86/ix86-64/iCore-64.cpp @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86-64/iR5900-64.c b/pcsx2/x86/ix86-64/iR5900-64.c index c23c379..a7d2650 100644 --- a/pcsx2/x86/ix86-64/iR5900-64.c +++ b/pcsx2/x86/ix86-64/iR5900-64.c @@ -1,19 +1,19 @@ /* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2005 Pcsx2 Team + * Copyright (C) 2002-2008 Pcsx2 Team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ // 64 bit recompiler - difference between 32bit is that mmx is gone diff --git a/pcsx2/x86/ix86-64/iR5900Arit-64.c b/pcsx2/x86/ix86-64/iR5900Arit-64.c index 851ec8f..dec9712 100644 --- a/pcsx2/x86/ix86-64/iR5900Arit-64.c +++ b/pcsx2/x86/ix86-64/iR5900Arit-64.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86-64/iR5900AritImm-64.c b/pcsx2/x86/ix86-64/iR5900AritImm-64.c index 5810dfc..fb1733e 100644 --- a/pcsx2/x86/ix86-64/iR5900AritImm-64.c +++ b/pcsx2/x86/ix86-64/iR5900AritImm-64.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86-64/iR5900Branch-64.c b/pcsx2/x86/ix86-64/iR5900Branch-64.c index 01b1464..4e988ac 100644 --- a/pcsx2/x86/ix86-64/iR5900Branch-64.c +++ b/pcsx2/x86/ix86-64/iR5900Branch-64.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86-64/iR5900Jump-64.c b/pcsx2/x86/ix86-64/iR5900Jump-64.c index 8eba163..da94b78 100644 --- a/pcsx2/x86/ix86-64/iR5900Jump-64.c +++ b/pcsx2/x86/ix86-64/iR5900Jump-64.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86-64/iR5900LoadStore-64.c b/pcsx2/x86/ix86-64/iR5900LoadStore-64.c index 136c300..5d4b276 100644 --- a/pcsx2/x86/ix86-64/iR5900LoadStore-64.c +++ b/pcsx2/x86/ix86-64/iR5900LoadStore-64.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86-64/iR5900Move-64.c b/pcsx2/x86/ix86-64/iR5900Move-64.c index bc31f4f..cb62a54 100644 --- a/pcsx2/x86/ix86-64/iR5900Move-64.c +++ b/pcsx2/x86/ix86-64/iR5900Move-64.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86-64/iR5900MultDiv-64.c b/pcsx2/x86/ix86-64/iR5900MultDiv-64.c index 36d68d9..7555c66 100644 --- a/pcsx2/x86/ix86-64/iR5900MultDiv-64.c +++ b/pcsx2/x86/ix86-64/iR5900MultDiv-64.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86-64/iR5900Shift-64.c b/pcsx2/x86/ix86-64/iR5900Shift-64.c index e1ca9a7..450927d 100644 --- a/pcsx2/x86/ix86-64/iR5900Shift-64.c +++ b/pcsx2/x86/ix86-64/iR5900Shift-64.c @@ -1,20 +1,21 @@ -/* Pcsx2 - Pc Ps2 Emulator - * Copyright (C) 2002-2003 Pcsx2 Team - * +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86/ix86.c b/pcsx2/x86/ix86/ix86.c index 7c6fb02..6d0664f 100644 --- a/pcsx2/x86/ix86/ix86.c +++ b/pcsx2/x86/ix86/ix86.c @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* * ix86 core v0.6.2 * Authors: linuzappz diff --git a/pcsx2/x86/ix86/ix86.h b/pcsx2/x86/ix86/ix86.h index b7a233c..cebaca2 100644 --- a/pcsx2/x86/ix86/ix86.h +++ b/pcsx2/x86/ix86/ix86.h @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ /* * ix86 definitions v0.6.2 * Authors: linuzappz diff --git a/pcsx2/x86/ix86/ix86_3dnow.c b/pcsx2/x86/ix86/ix86_3dnow.c index d35e16d..5a92ff4 100644 --- a/pcsx2/x86/ix86/ix86_3dnow.c +++ b/pcsx2/x86/ix86/ix86_3dnow.c @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86/ix86_cpudetect.c b/pcsx2/x86/ix86/ix86_cpudetect.c index 4e0b3c1..ecdd74e 100644 --- a/pcsx2/x86/ix86/ix86_cpudetect.c +++ b/pcsx2/x86/ix86/ix86_cpudetect.c @@ -1,20 +1,20 @@ /* Cpudetection lib - * Copyright (C) 2002-2003 Pcsx2 Team - * + * Copyright (C) 2002-2008 Pcsx2 Team + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #if defined (_WIN32) #include #endif diff --git a/pcsx2/x86/ix86/ix86_fpu.c b/pcsx2/x86/ix86/ix86_fpu.c index ccabb84..477132d 100644 --- a/pcsx2/x86/ix86/ix86_fpu.c +++ b/pcsx2/x86/ix86/ix86_fpu.c @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86/ix86_mmx.c b/pcsx2/x86/ix86/ix86_mmx.c index dd23f97..7a043d7 100644 --- a/pcsx2/x86/ix86/ix86_mmx.c +++ b/pcsx2/x86/ix86/ix86_mmx.c @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/x86/ix86/ix86_sse.c b/pcsx2/x86/ix86/ix86_sse.c index 04ae911..f0d463c 100644 --- a/pcsx2/x86/ix86/ix86_sse.c +++ b/pcsx2/x86/ix86/ix86_sse.c @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ // stop compiling if NORECBUILD build (only for Visual Studio) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) diff --git a/pcsx2/xmlpatchloader.cpp b/pcsx2/xmlpatchloader.cpp index 3d33841..05b6705 100644 --- a/pcsx2/xmlpatchloader.cpp +++ b/pcsx2/xmlpatchloader.cpp @@ -1,3 +1,20 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2008 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ #include #include #include