pcsx2 0.9.3 and a lot of other additions

git-svn-id: http://pcsx2.googlecode.com/svn/branches/pcsx2_0.9.2@159 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
zerofrog 2007-04-02 01:06:17 +00:00
commit afcd1c9784
320 changed files with 161833 additions and 0 deletions

1852
CDVD.c Normal file

File diff suppressed because it is too large Load Diff

144
CDVD.h Normal file
View File

@ -0,0 +1,144 @@
/* 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 __CDVD_H__
#define __CDVD_H__
#include "PsxCommon.h"
typedef struct {
u8 status;
u8 second;
u8 minute;
u8 hour;
u8 pad;
u8 day;
u8 month;
u8 year;
} cdvdRTC;
typedef struct {
u8 nCommand;
u8 Ready;
u8 Error;
u8 PwOff;
u8 Status;
u8 Type;
u8 sCommand;
u8 sDataIn;
u8 sDataOut;
u8 HowTo;
u8 Param[32];
u8 Result[32];
u8 ParamC;
u8 ParamP;
u8 ResultC;
u8 ResultP;
u8 CBlockIndex;
u8 COffset;
u8 CReadWrite;
u8 CNumBlocks;
int RTCcount;
cdvdRTC RTC;
u32 Sector;
int nSectors;
int Readed;
int Reading;
int ReadMode;
int BlockSize;
int Speed;
int RetryCnt;
int RetryCntP;
int RErr;
int SpindlCtrl;
u8 Key[16];
u8 KeyXor;
u8 decSet;
u8 mg_buffer[65536];
int mg_size;
int mg_maxsize;
int mg_datatype;//0-data(encrypted); 1-header
u8 mg_kbit[16];//last BIT key 'seen'
u8 mg_kcon[16];//last content key 'seen'
// char Unused[4096];
} cdvdStruct;
extern cdvdStruct cdvd;
void cdvdReset();
void cdvdReadTimeRcnt(int mode);
void cdvdVsync();
int cdvdInterrupt();
int cdvdFreeze(gzFile f, int Mode);
int cdvdReadInterrupt();
void cdvdNewDiskCB();
u8 cdvdRead04(void);
u8 cdvdRead05(void);
u8 cdvdRead06(void);
u8 cdvdRead07(void);
u8 cdvdRead08(void);
u8 cdvdRead0A(void);
u8 cdvdRead0B(void);
u8 cdvdRead0C(void);
u8 cdvdRead0D(void);
u8 cdvdRead0E(void);
u8 cdvdRead0F(void);
u8 cdvdRead13(void);
u8 cdvdRead15(void);
u8 cdvdRead16(void);
u8 cdvdRead17(void);
u8 cdvdRead18(void);
u8 cdvdRead20(void);
u8 cdvdRead21(void);
u8 cdvdRead22(void);
u8 cdvdRead23(void);
u8 cdvdRead24(void);
u8 cdvdRead28(void);
u8 cdvdRead29(void);
u8 cdvdRead2A(void);
u8 cdvdRead2B(void);
u8 cdvdRead2C(void);
u8 cdvdRead30(void);
u8 cdvdRead31(void);
u8 cdvdRead32(void);
u8 cdvdRead33(void);
u8 cdvdRead34(void);
u8 cdvdRead38(void);
u8 cdvdRead39(void);
u8 cdvdRead3A(void);
void cdvdWrite04(u8 rt);
void cdvdWrite05(u8 rt);
void cdvdWrite06(u8 rt);
void cdvdWrite07(u8 rt);
void cdvdWrite08(u8 rt);
void cdvdWrite0A(u8 rt);
void cdvdWrite0F(u8 rt);
void cdvdWrite14(u8 rt);
void cdvdWrite16(u8 rt);
void cdvdWrite17(u8 rt);
void cdvdWrite18(u8 rt);
void cdvdWrite3A(u8 rt);
#endif /* __CDVD_H__ */

835
CDVDiso.c Normal file
View File

@ -0,0 +1,835 @@
/*
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
* Modified by Florin for PCSX2 emu
* Fixed CdRead by linuzappz
*/
#include <string.h>
//#ifndef strnicmp
//#define strnicmp strncasecmp
//#endif
#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; i<sectors; i++){
if (CDVDreadTrack(lsn+i, rmode)==-1)
return 0;
buff = CDVDgetBuffer();
if (buff==NULL) return 0;
switch (mode->datapattern){
case CdSecS2048:
memcpy((void*)((uptr)buf+2048*i), buff, 2048);break;//only data
case CdSecS2328:
memcpy((void*)((uptr)buf+2328*i), buff, 2328);break;//without sync & head & sub
case CdSecS2340:
memcpy((void*)((uptr)buf+2340*i), buff, 2340);break;//without sync
}
}
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;
memcpy((u8*)buf+12, buff, 2048);
(u8*)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
printf("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))
{
memcpy(&CDVolDesc, &localVolDesc, sizeof(struct cdVolDesc));
}
}
else
break;
}
#ifdef DEBUG
if (CDVolDesc.filesystemType == 1)
printf("CD FileSystem is ISO9660\n");
else if (CDVolDesc.filesystemType == 2)
printf("CD FileSystem is Joliet\n");
else printf("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
printf("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
(char*)tocEntryPointer = toc;
num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; //round up fix
current_sector = tocEntryPointer->fileLBA;
(char*)tocEntryPointer += tocEntryPointer->length;
(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)
{
printf("Couldn't Read from CD !\n");
return -1;
}
// CdSync(0x00);
(char*)tocEntryPointer = 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
(char*)tocEntryPointer += tocEntryPointer->length;
}
// If we havent found the directory name we wanted then fail
if (found_dir != TRUE)
{
printf("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)
{
printf("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
(char*)tocEntryPointer = toc;
(char*)tocEntryPointer += tocEntryPointer->length;
(char*)tocEntryPointer += tocEntryPointer->length;
}
#ifdef DEBUG
printf("CDVD_findfile: found dir, now looking for file\n");
#endif
(char*)tocEntryPointer = toc;
num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; //round up fix
dir_lba = tocEntryPointer->fileLBA;
(char*)tocEntryPointer = toc;
(char*)tocEntryPointer += tocEntryPointer->length;
(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
printf("CDVD_findfile: found file\n");
#endif
return TRUE;
}
(char*)tocEntryPointer += tocEntryPointer->length;
}
num_dir_sectors--;
if (num_dir_sectors > 0)
{
dir_lba++;
if (CdRead(dir_lba,1,toc,&cdReadMode) != TRUE){
printf("Couldn't Read from CD !\n");
return -1;
}
// CdSync(0x00);
(char*)tocEntryPointer = toc;
}
}
#ifdef DEBUG
printf("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
(char*)tocEntryPointer = toc;
num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11;
current_sector = tocEntryPointer->fileLBA;
(char*)tocEntryPointer += tocEntryPointer->length;
(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);
(char*)tocEntryPointer = 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
(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
(char*)tocEntryPointer = toc;
(char*)tocEntryPointer += tocEntryPointer->length;
(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
(char*)tocEntryPointer = 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;
(char*)tocEntryPointer = toc;
(char*)tocEntryPointer += tocEntryPointer->length;
(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);
(char*)tocEntryPointer = 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++;
}
}
(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
(char*)tocEntryPointer = toc;
(char*)tocEntryPointer += tocEntryPointer->length;
(char*)tocEntryPointer += tocEntryPointer->length;
getDirTocData.current_sector_offset = (char*)tocEntryPointer - toc;
}
else{
(char*)tocEntryPointer = 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;
(char*)tocEntryPointer = 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;
(char*)tocEntryPointer = 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;
(char*)tocEntryPointer = toc + getDirTocData.current_sector_offset;
}
else{
toc_entry_num++;
getDirTocData.current_sector_offset += tocEntryPointer->length;
(char*)tocEntryPointer = 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);
}

131
CDVDiso.h Normal file
View File

@ -0,0 +1,131 @@
/*
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
* Modified by Florin for PCSX2 emu
*/
#ifndef __CDVDISO_H__
#define __CDVDISO_H__
#include "CDVDlib.h"
int CDVD_findfile(char* fname, struct TocEntry* tocEntry);
int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_dirs);
int CDVD_GetDir_RPC_get_entries(struct TocEntry tocEntry[], int req_entries);
#if defined(__WIN32__)
#pragma pack(1)
#endif
struct rootDirTocHeader
{
u16 length; //+00
u32 tocLBA; //+02
u32 tocLBA_bigend; //+06
u32 tocSize; //+0A
u32 tocSize_bigend; //+0E
u8 dateStamp[8]; //+12
u8 reserved[6]; //+1A
u8 reserved2; //+20
u8 reserved3; //+21
#if defined(__WIN32__)
}; //+22
#else
} __attribute__((packed));
#endif
struct asciiDate
{
char year[4];
char month[2];
char day[2];
char hours[2];
char minutes[2];
char seconds[2];
char hundreths[2];
char terminator[1];
#if defined(__WIN32__)
};
#else
} __attribute__((packed));
#endif
struct cdVolDesc
{
u8 filesystemType; // 0x01 = ISO9660, 0x02 = Joliet, 0xFF = NULL
u8 volID[5]; // "CD001"
u8 reserved2;
u8 reserved3;
u8 sysIdName[32];
u8 volName[32]; // The ISO9660 Volume Name
u8 reserved5[8];
u32 volSize; // Volume Size
u32 volSizeBig; // Volume Size Big-Endian
u8 reserved6[32];
u32 unknown1;
u32 unknown1_bigend;
u16 volDescSize; //+80
u16 volDescSize_bigend; //+82
u32 unknown3; //+84
u32 unknown3_bigend; //+88
u32 priDirTableLBA; // LBA of Primary Dir Table //+8C
u32 reserved7; //+90
u32 secDirTableLBA; // LBA of Secondary Dir Table //+94
u32 reserved8; //+98
struct rootDirTocHeader rootToc;
u8 volSetName[128];
u8 publisherName[128];
u8 preparerName[128];
u8 applicationName[128];
u8 copyrightFileName[37];
u8 abstractFileName[37];
u8 bibliographyFileName[37];
struct asciiDate creationDate;
struct asciiDate modificationDate;
struct asciiDate effectiveDate;
struct asciiDate expirationDate;
u8 reserved10;
u8 reserved11[1166];
#if defined(__WIN32__)
};
#else
} __attribute__((packed));
#endif
struct dirTableEntry
{
u8 dirNameLength;
u8 reserved;
u32 dirTOCLBA;
u16 dirDepth;
u8 dirName[32];
#if defined(__WIN32__)
};
#else
} __attribute__((packed));
#endif
struct dirTocEntry
{
short length;
unsigned int fileLBA;
unsigned int fileLBA_bigend;
unsigned int fileSize;
unsigned int fileSize_bigend;
unsigned char dateStamp[6];
unsigned char reserved1;
unsigned char fileProperties;
unsigned char reserved2[6];
unsigned char filenameLength;
unsigned char filename[128];
#if defined(__WIN32__)
};
#else
} __attribute__((packed));
#endif // This is the internal format on the CD
// TocEntry structure contains only the important stuff needed for export
#if defined(__WIN32__)
#pragma pack()
#endif
#endif//__CDVDISO_H__

263
CDVDisodrv.c Normal file
View File

@ -0,0 +1,263 @@
/*
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
* Modified by Florin for PCSX2 emu
*/
#include <string.h>
#include "CDVDiso.h"
#include "CDVDisodrv.h"
CdRMode cdReadMode;
struct fdtable{
//int fd;
int fileSize;
int LBA;
int filePos;
};
static struct fdtable fd_table[16];
static int fd_used[16];
static int files_open=0;
static int inited=FALSE;
/*************************************************************
* The functions below are the normal file-system operations, *
* used to provide a standard filesystem interface *
*************************************************************/
//////////////////////////////////////////////////////////////////////
// CDVDFS_init
// called by 80000592 sceCdInit()
//////////////////////////////////////////////////////////////////////
void CDVDFS_init(){
if (inited) return;//might change in the future as a param; forceInit/Reset
#ifdef RPC_LOG
RPC_LOG("[CDVDisodrv:init] CDVD Filesystem v1.00\n");
RPC_LOG("[CDVDisodrv ] \tby A.Lee (aka Hiryu) & Nicholas Van Veen (aka Sjeep)\n");
RPC_LOG("[CDVDisodrv ] Initializing '%s' file driver.\n", "cdfs");
#endif
//CdInit(0); already called by plugin loading system ;)
cdReadMode.trycount = 0;
cdReadMode.spindlctrl = CdSpinStm;
cdReadMode.datapattern = CdSecS2048; //isofs driver only needs
//2KB sectors
memset(fd_table, 0, sizeof(fd_table));
memset(fd_used, 0, 16*sizeof(int));
inited = TRUE;
return;
}
//////////////////////////////////////////////////////////////////////
// CDVDFS_open
// called by 80000001 fileio_open for devices: "cdrom:", "cdrom0:"
//////////////////////////////////////////////////////////////////////
int CDVDFS_open(char *name, int mode){
register int j;
static struct TocEntry tocEntry;
// check if the file exists
if (CDVD_findfile(name, &tocEntry) != TRUE)
return -1;
if(mode != 1) return -2; //SCE_RDONLY
// set up a new file descriptor
for(j=0; j < 16; j++) if(fd_used[j] == 0) break;
if(j >= 16) return -3;
fd_used[j] = 1;
files_open++;
#ifdef RPC_LOG
RPC_LOG("[CDVDisodrv:open] internal fd=%d\n", j);
#endif
fd_table[j].fileSize = tocEntry.fileSize;
fd_table[j].LBA = tocEntry.fileLBA;
fd_table[j].filePos = 0;
#ifdef RPC_LOG
RPC_LOG("[CDVDisodrv ] tocEntry.fileSize = %d\n",tocEntry.fileSize);
#endif
return j;
}
//////////////////////////////////////////////////////////////////////
// CDVDFS_lseek
// called by 80000001 fileio_lseek for devices: "cdrom:", "cdrom0:"
//////////////////////////////////////////////////////////////////////
int CDVDFS_lseek(int fd, int offset, int whence){
if ((fd >= 16) || (fd_used[fd]==0)){
#ifdef RPC_LOG
RPC_LOG("[CDVDisodrv:lseek] ERROR: File does not appear to be open!\n");
#endif
return -1;
}
switch(whence){
case SEEK_SET:
fd_table[fd].filePos = offset;
break;
case SEEK_CUR:
fd_table[fd].filePos += offset;
break;
case SEEK_END:
fd_table[fd].filePos = fd_table[fd].fileSize + offset;
break;
default:
return -1;
}
if (fd_table[fd].filePos < 0)
fd_table[fd].filePos = 0;
if (fd_table[fd].filePos > fd_table[fd].fileSize)
fd_table[fd].filePos = fd_table[fd].fileSize;
return fd_table[fd].filePos;
}
//////////////////////////////////////////////////////////////////////
// CDVDFS_read
// called by 80000001 fileio_read for devices: "cdrom:", "cdrom0:", "cdfs:"
//////////////////////////////////////////////////////////////////////
int CDVDFS_read( int fd, char *buffer, int size ){
// int start_sector;
int off_sector;
// int num_sectors;
//static char local_buffer[2024*2048]; //4MB
static char lb[2048]; //2KB
//Start, Aligned, End
int ssector, asector, esector;
int ssize=0, asize, esize;
if ((fd >= 16) || (fd_used[fd]==0)){
#ifdef RPC_LOG
RPC_LOG("[CDVDisodrv:read] ERROR: File does not appear to be open!\n");
#endif
return -1;
}
// A few sanity checks
if (fd_table[fd].filePos > fd_table[fd].fileSize){
// We cant start reading from past the beginning of the file
return 0; // File exists but we couldnt read anything from it
}
if ((fd_table[fd].filePos + size) > fd_table[fd].fileSize)
size = fd_table[fd].fileSize - fd_table[fd].filePos;
// Now work out where we want to start reading from
asector = ssector = fd_table[fd].LBA + (fd_table[fd].filePos >> 11);
off_sector = (fd_table[fd].filePos & 0x7FF);
if (off_sector){
ssize = min(2048 - off_sector, size);
size -= ssize;
asector++;
}
asize = size & 0xFFFFF800;
esize = size & 0x000007FF;
esector=asector + (asize >> 11);
size += ssize;
#ifdef RPC_LOG
RPC_LOG("[CDVDisodrv:read] read sectors 0x%08X to 0x%08X\n", ssector, esector-(esize==0));
#endif
if (ssize){ if (CdRead(ssector, 1, lb, &cdReadMode) != TRUE){
#ifdef RPC_LOG
RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason\n");
#endif
return 0;
}
memcpy(buffer, lb + off_sector, ssize);
}
if (asize) if (CdRead(asector, asize >> 11, buffer+ssize, &cdReadMode) != TRUE){
#ifdef RPC_LOG
RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason\n");
#endif
return 0;
}
if (esize){ if (CdRead(esector, 1, lb, &cdReadMode) != TRUE){
#ifdef RPC_LOG
RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason\n");
#endif
return 0;
}
memcpy(buffer+ssize+asize, lb, esize);
}
/***********************
// Now work out where we want to start reading from
start_sector = fd_table[fd].LBA + (fd_table[fd].filePos >> 11);
off_sector = (fd_table[fd].filePos & 0x7FF);
num_sectors = ((off_sector + size) >> 11) + 1;
#ifdef RPC_LOG
RPC_LOG("[CDVDisodrv:read] read sectors 0x%08X to 0x%08X\n",start_sector,start_sector+num_sectors);
#endif
// Read the data (we only ever get 16KB max request at once)
if (CdRead(start_sector, num_sectors, local_buffer, &cdReadMode) != TRUE){
#ifdef RPC_LOG
//RPC_LOG("sector = %d, start sector = %d\n",sector,start_sector);
RPC_LOG("[CDVDisodrv: ] Couldn't Read from file for some reason\n");
#endif
return 0;
}
//CdSync(0); hm, a wait function maybe...
memcpy(buffer,local_buffer+off_sector,size);
**************************/
fd_table[fd].filePos += size;
return (size);
}
//////////////////////////////////////////////////////////////////////
// CDVDFS_write
// called by 80000001 fileio_write for devices: "cdrom:", "cdrom0:"
// hehe, this ain't a CD writing option :D
//////////////////////////////////////////////////////////////////////
int CDVDFS_write( int fd, char * buffer, int size ){
if(size == 0) return 0;
else return -1;
}
//////////////////////////////////////////////////////////////////////
// CDVDFS_close
// called by 80000001 fileio_close for devices: "cdrom:", "cdrom0:"
//////////////////////////////////////////////////////////////////////
int CDVDFS_close( int fd){
if ((fd >= 16) || (fd_used[fd]==0)){
#ifdef RPC_LOG
RPC_LOG("[CDVDisodrv:close] ERROR: File does not appear to be open!\n");
#endif
return -1;
}
#ifdef RPC_LOG
RPC_LOG("[CDVDisodrv:close] internal fd %d\n", fd);
#endif
fd_used[fd] = 0;
files_open--;
return 0;
}

22
CDVDisodrv.h Normal file
View File

@ -0,0 +1,22 @@
/*
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
* Modified by Florin for PCSX2 emu
*/
#ifndef __CDVDISODRV_H__
#define __CDVDISODRV_H__
//#include "Common.h"
#include "CDVDlib.h"
extern CdRMode cdReadMode;
/* Filing-system exported functions */
void CDVDFS_init();
int CDVDFS_open(char *name, int mode);
int CDVDFS_lseek(int fd, int offset, int whence);
int CDVDFS_read( int fd, char * buffer, int size );
int CDVDFS_write( int fd, char * buffer, int size );
int CDVDFS_close( int fd);
#endif//__CDVDISODRV_H__

185
CDVDlib.h Normal file
View File

@ -0,0 +1,185 @@
/*
* Original code from libcdvd by Hiryu & Sjeep (C) 2002
* Linux kernel headers
* Modified by Florin for PCSX2 emu
*/
#ifndef _CDVDLIB_H
#define _CDVDLIB_H
#include "Common.h"
// Macros for READ Data pattan
#define CdSecS2048 0 // sector size 2048
#define CdSecS2328 1 // sector size 2328
#define CdSecS2340 2 // sector size 2340
//#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE) /*2340*/
//#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE) /*2336*/
//#define CD_HEAD_SIZE 4 /* header (address) bytes per raw data frame */
//#define CD_SUBHEAD_SIZE 8 /* subheader bytes per raw XA data frame */
//#define CD_XA_HEAD (CD_HEAD_SIZE+CD_SUBHEAD_SIZE) /* "before data" part of raw XA frame */
/*
* A CD-ROM physical sector size is 2048, 2052, 2056, 2324, 2332, 2336,
* 2340, or 2352 bytes long.
* Sector types of the standard CD-ROM data formats:
*
* format sector type user data size (bytes)
* -----------------------------------------------------------------------------
* 1 (Red Book) CD-DA 2352 (CD_FRAMESIZE_RAW)
* 2 (Yellow Book) Mode1 Form1 2048 (CD_FRAMESIZE)
* 3 (Yellow Book) Mode1 Form2 2336 (CD_FRAMESIZE_RAW0)
* 4 (Green Book) Mode2 Form1 2048 (CD_FRAMESIZE)
* 5 (Green Book) Mode2 Form2 2328 (2324+4 spare bytes)
*
*
* The layout of the standard CD-ROM data formats:
* -----------------------------------------------------------------------------
* - audio (red): | audio_sample_bytes |
* | 2352 |
*
* - data (yellow, mode1): | sync - head - data - EDC - zero - ECC |
* | 12 - 4 - 2048 - 4 - 8 - 276 |
*
* - data (yellow, mode2): | sync - head - data |
* | 12 - 4 - 2336 |
*
* - XA data (green, mode2 form1): | sync - head - sub - data - EDC - ECC |
* | 12 - 4 - 8 - 2048 - 4 - 276 |
*
* - XA data (green, mode2 form2): | sync - head - sub - data - Spare |
* | 12 - 4 - 8 - 2324 - 4 |
*
*/
// Macros for Spindle control
#define CdSpinMax 0
#define CdSpinNom 1 // Starts reading data at maximum rotational velocity and if a read error occurs, the rotational velocity is reduced.
#define CdSpinStm 0 // Recommended stream rotation speed.
// Macros for TrayReq
#define CdTrayOpen 0
#define CdTrayClose 1
#define CdTrayCheck 2
/*
* Macros for sceCdGetDiskType() //comments translated from japanese;)
*/
#define SCECdIllgalMedia 0xff
/* ILIMEDIA (Illegal Media)
A non-PS / non-PS2 Disc. */
#define SCECdDVDV 0xfe
/* DVDV (DVD Video)
A non-PS / non-PS2 Disc, but a DVD Video Disc */
#define SCECdCDDA 0xfd
/* CDDA (CD DA)
A non-PS / non-PS2 Disc that include a DA track */
#define SCECdPS2DVD 0x14
/* PS2DVD PS2 consumer DVD. */
#define SCECdPS2CDDA 0x13
/* PS2CDDA PS2 consumer CD that includes a DA track */
#define SCECdPS2CD 0x12
/* PS2CD PS2 consumer CD that does not include a DA track */
#define SCECdPSCDDA 0x11
/* PSCDDA PS CD that includes a DA track */
#define SCECdPSCD 0x10
/* PSCD PS CD that does not include a DA track */
#define SCECdDETCT 0x01
/* DETCT (Detecting) Disc distinction action */
#define SCECdNODISC 0x00
/* NODISC (No disc) No disc entered */
/*
* Media mode
*/
#define SCECdCD 1
#define SCECdDVD 2
typedef struct {
u8 stat; // 0: normal. Any other: error
u8 second; // second (BCD value)
u8 minute; // minute (BCD value)
u8 hour; // hour (BCD value)
u8 week; // week (BCD value)
u8 day; // day (BCD value)
u8 month; // month (BCD value)
u8 year; // year (BCD value)
} CdCLOCK;
typedef struct {
u32 lsn; // Logical sector number of file
u32 size; // File size (in bytes)
char name[16]; // Filename
u8 date[8]; // 1th: Seconds
// 2th: Minutes
// 3th: Hours
// 4th: Date
// 5th: Month
// 6th 7th: Year (4 digits)
} CdlFILE;
typedef struct {
u8 minute; // Minutes
u8 second; // Seconds
u8 sector; // Sector
u8 track; // Track number
} CdlLOCCD;
typedef struct {
u8 trycount; // Read try count (No. of error retries + 1) (0 - 255)
u8 spindlctrl; // SCECdSpinStm: Recommended stream rotation speed.
// SCECdSpinNom: Starts reading data at maximum rotational velocity and if a read error occurs, the rotational velocity is reduced.
u8 datapattern; // SCECdSecS2048: Data size 2048 bytes
// SCECdSecS2328: 2328 bytes
// SCECdSecS2340: 2340 bytes
u8 pad; // Padding data produced by alignment.
} CdRMode;
#if defined(__WIN32__)
#pragma pack(1)
#endif
struct TocEntry
{
u32 fileLBA;
u32 fileSize;
u8 fileProperties;
u8 padding1[3];
u8 filename[128+1];
u8 date[7];
#if defined(__WIN32__)
};
#else
} __attribute__((packed));
#endif
#if defined(__WIN32__)
#pragma pack()
#endif
int CDVD_findfile(char* fname, struct TocEntry* tocEntry);
/*
int CdBreak(void);
int CdCallback( void (*func)() );
int CdDiskReady(int mode);
int CdGetDiskType(void);
int CdGetError(void);
u32 CdGetReadPos(void);
int CdGetToc(u8 *toc);
int CdInit(int init_mode);
CdlLOCCD *CdIntToPos(int i, CdlLOCCD *p);
int CdPause(void);
int CdPosToInt(CdlLOCCD *p);*/
int CdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode);
int DvdRead(u32 lsn, u32 sectors, void *buf, CdRMode *mode);
/*int CdReadClock(CdCLOCK *rtc);
int CdSearchFile (CdlFILE *fp, const char *name);
int CdSeek(u32 lsn);
int CdStandby(void);
int CdStatus(void);
int CdStop(void);
int CdSync(int mode);
int CdTrayReq(int mode, u32 *traycnt);
*/
#endif // _CDVDLIB_H

363
COP0.c Normal file
View File

@ -0,0 +1,363 @@
/* 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
*/
#include <stdio.h>
#include "Common.h"
#include "R5900.h"
#include "InterTables.h"
extern BOOL bExecBIOS;
void COP0() {
Int_COP0PrintTable[_Rs_]();
}
void COP0_BC0() {
#ifdef COP0_LOG
COP0_LOG("%s\n", disR5900F(cpuRegs.code, cpuRegs.pc));
#endif
Int_COP0BC0PrintTable[(cpuRegs.code >> 16) & 0x03]();
}
void COP0_Func() {
#ifdef COP0_LOG
COP0_LOG("%s\n", disR5900F(cpuRegs.code, cpuRegs.pc));
#endif
Int_COP0C0PrintTable[_Funct_]();
}
void COP0_Unknown() {
#ifdef CPU_LOG
CPU_LOG("COP0 Unknown opcode called\n");
#endif
}
void UpdateCP0Status() {
u32 value = cpuRegs.CP0.n.Status.val;
if (value & 0x06 ||
(value & 0x18) == 0) { // Kernel Mode (KSU = 0 | EXL = 1 | ERL = 1)*/
memSetKernelMode(); // Kernel memory always
} else { // User Mode
memSetUserMode();
}
if ((cpuRegs.CP0.n.Status.val & 0x10007) == 0x10001)cpuTestHwInts();
}
void WriteCP0Status(u32 value) {
cpuRegs.CP0.n.Status.val = value;
UpdateCP0Status();
}
extern u32 s_iLastCOP0Cycle;
extern u32 s_iLastPERFCycle[2];
void MFC0() {
if (!_Rt_) return;
#ifdef COP0_LOG
if (_Rd_ != 9) { COP0_LOG("%s\n", disR5900F(cpuRegs.code, cpuRegs.pc)); }
#endif
//if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MFC0 _Rd_ %x = %x\n", _Rd_, cpuRegs.CP0.r[_Rd_]);
switch (_Rd_) {
case 12: cpuRegs.GPR.r[_Rt_].UD[0] = (s64)(cpuRegs.CP0.r[_Rd_] & 0xf0c79c1f); break;
case 25:
switch(_Imm_ & 0x3F){
case 0: cpuRegs.GPR.r[_Rt_].UD[0] = (s64)cpuRegs.PERF.n.pccr; break;
case 1:
if((cpuRegs.PERF.n.pccr & 0x800003E0) == 0x80000020) {
cpuRegs.PERF.n.pcr0 += cpuRegs.cycle-s_iLastPERFCycle[0];
s_iLastPERFCycle[0] = cpuRegs.cycle;
}
cpuRegs.GPR.r[_Rt_].UD[0] = (s64)cpuRegs.PERF.n.pcr0;
break;
case 3:
if((cpuRegs.PERF.n.pccr & 0x800F8000) == 0x80008000) {
cpuRegs.PERF.n.pcr1 += cpuRegs.cycle-s_iLastPERFCycle[1];
s_iLastPERFCycle[1] = cpuRegs.cycle;
}
cpuRegs.GPR.r[_Rt_].UD[0] = (s64)cpuRegs.PERF.n.pcr1;
break;
}
/*SysPrintf("MFC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x\n",
cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);*/
break;
case 9:
// update
cpuRegs.CP0.n.Count += cpuRegs.cycle-s_iLastCOP0Cycle;
s_iLastCOP0Cycle = cpuRegs.cycle;
default: cpuRegs.GPR.r[_Rt_].UD[0] = (s64)cpuRegs.CP0.r[_Rd_];
}
}
void MTC0() {
#ifdef COP0_LOG
COP0_LOG("%s\n", disR5900F(cpuRegs.code, cpuRegs.pc));
#endif
//if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MTC0 _Rd_ %x = %x\n", _Rd_, cpuRegs.CP0.r[_Rd_]);
switch (_Rd_) {
case 25:
/*if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MTC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x\n",
cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);*/
switch(_Imm_ & 0x3F){
case 0:
if((cpuRegs.PERF.n.pccr & 0x800003E0) == 0x80000020)
cpuRegs.PERF.n.pcr0 += cpuRegs.cycle-s_iLastPERFCycle[0];
if((cpuRegs.PERF.n.pccr & 0x800F8000) == 0x80008000)
cpuRegs.PERF.n.pcr1 += cpuRegs.cycle-s_iLastPERFCycle[1];
cpuRegs.PERF.n.pccr = cpuRegs.GPR.r[_Rt_].UL[0];
s_iLastPERFCycle[0] = cpuRegs.cycle;
s_iLastPERFCycle[1] = cpuRegs.cycle;
break;
case 1: cpuRegs.PERF.n.pcr0 = cpuRegs.GPR.r[_Rt_].UL[0]; s_iLastPERFCycle[0] = cpuRegs.cycle; break;
case 3: cpuRegs.PERF.n.pcr1 = cpuRegs.GPR.r[_Rt_].UL[0]; s_iLastPERFCycle[1] = cpuRegs.cycle; break;
}
break;
case 12: WriteCP0Status(cpuRegs.GPR.r[_Rt_].UL[0]); break;
case 9: s_iLastCOP0Cycle = cpuRegs.cycle; cpuRegs.CP0.r[9] = cpuRegs.GPR.r[_Rt_].UL[0]; break;
default: cpuRegs.CP0.r[_Rd_] = cpuRegs.GPR.r[_Rt_].UL[0]; break;
}
}
int CPCOND0() {
if(((psHu16(DMAC_STAT) & psHu16(DMAC_PCR)) & 0x3ff) == (psHu16(DMAC_PCR) & 0x3ff)) return 1;
else return 0;
}
//#define CPCOND0 1
#define BC0(cond) \
if (CPCOND0() cond) { \
intDoBranch(_BranchTarget_); \
}
void BC0F() {
BC0(== 0);
}
void BC0T() {
BC0(== 1);
}
#define BC0L(cond) \
if (CPCOND0() cond) { \
intDoBranch(_BranchTarget_); \
} else cpuRegs.pc+= 4;
void BC0FL() {
BC0L(== 0);
}
void BC0TL() {
BC0L(== 1);
}
void TLBR() {
#ifdef CPU_LOG
/* CPU_LOG("COP0_TLBR %d:%x,%x,%x,%x\n",
cpuRegs.CP0.n.Random, cpuRegs.CP0.n.PageMask, cpuRegs.CP0.n.EntryHi,
cpuRegs.CP0.n.EntryLo0, cpuRegs.CP0.n.EntryLo1);*/
#endif
int i = cpuRegs.CP0.n.Index&0x1f;
// if( !bExecBIOS )
// __Log("TLBR %d\n", cpuRegs.CP0.n.Index&0x1f);
SysPrintf("COP0_TLBR\n");
cpuRegs.CP0.n.PageMask = tlb[i].PageMask;
cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi&~(tlb[i].PageMask|0x1f00);
cpuRegs.CP0.n.EntryLo0 = (tlb[i].EntryLo0&~1)|((tlb[i].EntryHi>>12)&1);
cpuRegs.CP0.n.EntryLo1 =(tlb[i].EntryLo1&~1)|((tlb[i].EntryHi>>12)&1);
}
void ClearTLB(int i) {
u32 mask, addr;
u32 saddr, eaddr;
if (tlb[i].EntryLo0 & 0x2) {
mask = ((~tlb[i].Mask) << 1) & 0xfffff;
saddr = tlb[i].VPN2 >> 12;
eaddr = saddr + tlb[i].Mask + 1;
for (addr=saddr; addr<eaddr; addr++) {
if ((addr & mask) == ((tlb[i].VPN2 >> 12) & mask)) { //match
memClearPageAddr(addr << 12);
Cpu->Clear(addr << 12, 1);
}
}
}
if (tlb[i].EntryLo1 & 0x2) {
mask = ((~tlb[i].Mask) << 1) & 0xfffff;
saddr = (tlb[i].VPN2 >> 12) + tlb[i].Mask + 1;
eaddr = saddr + tlb[i].Mask + 1;
for (addr=saddr; addr<eaddr; addr++) {
if ((addr & mask) == ((tlb[i].VPN2 >> 12) & mask)) { //match
memClearPageAddr(addr << 12);
Cpu->Clear(addr << 12, 1);
}
}
}
}
void WriteTLB(int i) {
u32 mask, addr;
u32 saddr, eaddr;
tlb[i].PageMask = cpuRegs.CP0.n.PageMask;
tlb[i].EntryHi = cpuRegs.CP0.n.EntryHi;
tlb[i].EntryLo0 = cpuRegs.CP0.n.EntryLo0;
tlb[i].EntryLo1 = cpuRegs.CP0.n.EntryLo1;
tlb[i].Mask = (cpuRegs.CP0.n.PageMask >> 13) & 0xfff;
tlb[i].nMask = (~tlb[i].Mask) & 0xfff;
tlb[i].VPN2 = ((cpuRegs.CP0.n.EntryHi >> 13) & (~tlb[i].Mask)) << 13;
tlb[i].ASID = cpuRegs.CP0.n.EntryHi & 0xfff;
tlb[i].G = cpuRegs.CP0.n.EntryLo0 & cpuRegs.CP0.n.EntryLo1 & 0x1;
tlb[i].PFN0 = (((cpuRegs.CP0.n.EntryLo0 >> 6) & 0xFFFFF) & (~tlb[i].Mask)) << 12;
tlb[i].PFN0|= (0x80000000);
tlb[i].PFN1 = (((cpuRegs.CP0.n.EntryLo1 >> 6) & 0xFFFFF) & (~tlb[i].Mask)) << 12;
tlb[i].PFN1|= (0x80000000);
if (tlb[i].VPN2 == 0x70000000) return;
if (tlb[i].EntryLo0 & 0x2) {
mask = ((~tlb[i].Mask) << 1) & 0xfffff;
saddr = tlb[i].VPN2 >> 12;
eaddr = saddr + tlb[i].Mask + 1;
for (addr=saddr; addr<eaddr; addr++) {
if ((addr & mask) == ((tlb[i].VPN2 >> 12) & mask)) { //match
memSetPageAddr(addr << 12, tlb[i].PFN0 + ((addr - saddr) << 12));
Cpu->Clear(addr << 12, 1);
}
}
}
if (tlb[i].EntryLo1 & 0x2) {
mask = ((~tlb[i].Mask) << 1) & 0xfffff;
saddr = (tlb[i].VPN2 >> 12) + tlb[i].Mask + 1;
eaddr = saddr + tlb[i].Mask + 1;
for (addr=saddr; addr<eaddr; addr++) {
if ((addr & mask) == ((tlb[i].VPN2 >> 12) & mask)) { //match
memSetPageAddr(addr << 12, tlb[i].PFN1 + ((addr - saddr) << 12));
Cpu->Clear(addr << 12, 1);
}
}
}
}
void TLBWI() {
int j = cpuRegs.CP0.n.Index & 0x3f;
if (j > 48) return;
#ifdef CPU_LOG
/* CPU_LOG("COP0_TLBWI %d:%x,%x,%x,%x\n",
cpuRegs.CP0.n.Index, cpuRegs.CP0.n.PageMask, cpuRegs.CP0.n.EntryHi,
cpuRegs.CP0.n.EntryLo0, cpuRegs.CP0.n.EntryLo1);*/
#endif
// if( !bExecBIOS )
// __Log("TLBWI %d\n", j);
ClearTLB(j);
WriteTLB(j);
}
void TLBWR() {
int j = cpuRegs.CP0.n.Random & 0x3f;
if (j > 48) return;
#ifdef CPU_LOG
/* CPU_LOG("COP0_TLBWR %d:%x,%x,%x,%x\n",
cpuRegs.CP0.n.Random, cpuRegs.CP0.n.PageMask, cpuRegs.CP0.n.EntryHi,
cpuRegs.CP0.n.EntryLo0, cpuRegs.CP0.n.EntryLo1);*/
#endif
// if( !bExecBIOS )
// __Log("TLBWR %d\n", j);
ClearTLB(j);
WriteTLB(j);
}
void TLBP() {
int i;
union {
struct {
u32 VPN2:19;
u32 VPN2X:2;
u32 G:3;
u32 ASID:8;
} s;
u32 u;
} EntryHi32;
if( !bExecBIOS )
__Log("TLBP %x\n", cpuRegs.CP0.n.EntryHi);
EntryHi32.u=cpuRegs.CP0.n.EntryHi;
cpuRegs.CP0.n.Index=0xFFFFFFFF;
for(i=0;i<48;i++){
if(tlb[i].VPN2==((~tlb[i].Mask)&(EntryHi32.s.VPN2))
&&((tlb[i].G&1)||((tlb[i].ASID & 0xff) == EntryHi32.s.ASID))) {
cpuRegs.CP0.n.Index=i;
break;
}
}
if(cpuRegs.CP0.n.Index == 0xFFFFFFFF) cpuRegs.CP0.n.Index = 0x80000000;
}
void ERET() {
if (cpuRegs.CP0.n.Status.b.ERL) {
cpuRegs.pc = cpuRegs.CP0.n.ErrorEPC;
cpuRegs.CP0.n.Status.b.ERL = 0;
} else {
cpuRegs.pc = cpuRegs.CP0.n.EPC;
cpuRegs.CP0.n.Status.b.EXL = 0;
}
UpdateCP0Status();
intSetBranch();
}
void DI() {
if (cpuRegs.CP0.n.Status.b._EDI || cpuRegs.CP0.n.Status.b.EXL ||
cpuRegs.CP0.n.Status.b.ERL || (cpuRegs.CP0.n.Status.b.KSU == 0)) {
cpuRegs.CP0.n.Status.b.EIE = 0;
UpdateCP0Status();
}
}
void EI() {
if (cpuRegs.CP0.n.Status.b._EDI || cpuRegs.CP0.n.Status.b.EXL ||
cpuRegs.CP0.n.Status.b.ERL || (cpuRegs.CP0.n.Status.b.KSU == 0)) {
cpuRegs.CP0.n.Status.b.EIE = 1;
UpdateCP0Status();
}
}

27
COP0.h Normal file
View File

@ -0,0 +1,27 @@
/* 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 __COP0_H__
#define __COP0_H__
void WriteCP0Status(u32 value);
void UpdateCP0Status();
void WriteTLB(int i);
void ClearTLB(int i);
#endif /* __COP0_H__ */

355
Cache.c Normal file
View File

@ -0,0 +1,355 @@
/* 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 <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include "Common.h"
#include "Cache.h"
/*_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);
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);
*(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);
*(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);
*(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);
((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);
return pCache[i].data[number][(mem>>4) & 0x3].b8._8;
}
void CACHE() {
u32 addr;
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 GTE_LOG
GTE_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 GTE_LOG
GTE_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);
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);
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 GTE_LOG
GTE_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 GTE_LOG
GTE_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);
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 GTE_LOG
GTE_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 GTE_LOG
GTE_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 GTE_LOG
GTE_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 GTE_LOG
GTE_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 GTE_LOG
GTE_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);
break;
}
}
}*/
void CACHE() {
}

34
Cache.h Normal file
View File

@ -0,0 +1,34 @@
/* 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
*/
#ifndef __CACHE_H__
#define __CACHE_H__
#include "Common.h"
void freeCache(int i);
int getFreeCache();
void writeCache8(u32 mem, u8 value);
void writeCache16(u32 mem, u16 value);
void writeCache32(u32 mem, u32 value);
void writeCache64(u32 mem, u64 value);
void writeCache128(u32 mem, u64 *value);
u8 *readCache(u32 mem);
#endif /* __CACHE_H__ */

1078
CdRom.c Normal file

File diff suppressed because it is too large Load Diff

92
CdRom.h Normal file
View File

@ -0,0 +1,92 @@
/* 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 __CDROM_H__
#define __CDROM_H__
#include "PsxCommon.h"
#include "Decode_XA.h"
#include "PS2Edefs.h"
typedef struct {
u8 OCUP;
u8 Reg1Mode;
u8 Reg2;
u8 CmdProcess;
u8 Ctrl;
u8 Stat;
u8 StatP;
u8 Transfer[2352];
u8 *pTransfer;
u8 Prev[4];
u8 Param[8];
u8 Result[8];
u8 ParamC;
u8 ParamP;
u8 ResultC;
u8 ResultP;
u8 ResultReady;
u8 Cmd;
u8 Readed;
unsigned long Reading;
cdvdTN ResultTN;
u8 ResultTD[4];
u8 SetSector[4];
u8 SetSectorSeek[4];
u8 Track;
int Play;
int CurTrack;
int Mode, File, Channel, Muted;
int Reset;
int RErr;
int FirstSector;
xa_decode_t Xa;
int Init;
u8 Irq;
unsigned long eCycle;
char Unused[4087];
} cdrStruct;
cdrStruct cdr;
s32 MSFtoLSN(u8 *Time);
void LSNtoMSF(u8 *Time, s32 lsn);
void cdrReset();
int cdrInterrupt();
int cdrReadInterrupt();
u8 cdrRead0(void);
u8 cdrRead1(void);
u8 cdrRead2(void);
u8 cdrRead3(void);
void cdrWrite0(u8 rt);
void cdrWrite1(u8 rt);
void cdrWrite2(u8 rt);
void cdrWrite3(u8 rt);
int cdrFreeze(gzFile f, int Mode);
#endif /* __CDROM_H__ */

277
Common.h Normal file
View File

@ -0,0 +1,277 @@
/* 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 __COMMON_H__
#define __COMMON_H__
#if defined (__linux__) // some distributions are lower case
#define __LINUX__
#endif
#include <zlib.h>
#include <string.h>
#if defined(__WIN32__)
#include <windows.h>
typedef struct {
HWND hWnd; // Main window handle
HINSTANCE hInstance; // Application instance
HMENU hMenu; // Main window menu
HANDLE hConsole;
} AppData;
extern AppData gApp;
#define pthread_mutex__unlock pthread_mutex_unlock
#elif defined(__MINGW32__)
#include <sys/types.h>
#include <math.h>
#define BOOL int
#include <stdlib.h> // posix_memalign()
#undef TRUE
#define TRUE 1
#undef FALSE
#define FALSE 0
//#define max(a,b) (((a) > (b)) ? (a) : (b))
//#define min(a,b) (((a) < (b)) ? (a) : (b))
#define __declspec(x)
#define __assume(x) ;
#define strnicmp strncasecmp
#define stricmp strcasecmp
#include <winbase.h>
//#pragma intrinsic (InterlockedAnd)
// Definitions added Feb 16, 2006 by efp
//#define __declspec(x)
#include <malloc.h>
#define __forceinline inline
#define _aligned_malloc(x,y) __mingw_aligned_malloc(x,y)
#define _aligned_free(x) __mingw_aligned_free(x)
#define pthread_mutex__unlock pthread_mutex_unlock
#define fpusqrtf sqrtf
#define fpufabsf fabsf
#define fpusinf sinf
#define fpucosf cosf
#define fpuexpf expf
#define fpuatanf atanf
#define fpuatan2f atan2f
#else
#include <sys/types.h>
#include <stdlib.h> // posix_memalign()
#define BOOL int
#undef TRUE
#define TRUE 1
#undef FALSE
#define FALSE 0
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef strnicmp
#define strnicmp strncasecmp
#endif
#ifndef stricmp
#define stricmp strcasecmp
#endif
// Definitions added Feb 16, 2006 by efp
#ifndef __declspec
#define __declspec(x)
#endif
#define pthread_mutex__unlock pthread_mutex_unlock
#endif
#ifdef ENABLE_NLS
#ifdef __MSCW32__
#include "libintlmsc.h"
#else
#include "libintl.h"
#endif
#undef _
#define _(String) dgettext (PACKAGE, String)
#ifdef gettext_noop
# define N_(String) gettext_noop (String)
#else
# define N_(String) (String)
#endif
#else
#define _(msgid) msgid
#define N_(msgid) msgid
#endif
#include "PS2Etypes.h"
#ifdef PCSX2_DEVBUILD
typedef struct _TESTRUNARGS
{
u8 enabled;
u8 jpgcapture;
int frame; // if < 0, frame is unlimited (run until crash).
int numimages;
int curimage;
u32 autopad; // mask for auto buttons
int efile;
int snapdone;
char* ptitle;
char* pimagename;
char* plogname;
char* pgsdll, *pcdvddll, *pspudll;
} TESTRUNARGS;
extern TESTRUNARGS g_TestRun;
#endif
#define BIAS 2 // Bus is half of the actual ps2 speed
//#define PS2CLK 36864000 /* 294.912 mhz */
//#define PSXCLK 9216000 /* 36.864 Mhz */
//#define PSXCLK 186864000 /* 36.864 Mhz */
#define PS2CLK 294912000 /* 294.912 mhz */
#define PSXCLK 36864000 /* 36.864 Mhz */
/* Config.PsxType == 1: PAL:
VBlank interlaced 50.00 Hz
VBlank non-interlaced 49.76 Hz
HBlank 15.625 KHz
Config.PsxType == 0: NSTC
VBlank interlaced 59.94 Hz
VBlank non-interlaced 59.82 Hz
HBlank 15.73426573 KHz */
#define PS2VBLANK_NTSC_INT ((int)(PS2CLK / 59.94))
#define PS2VBLANK_NTSC ((int)(PS2CLK / 59.82))
#define PS2VBLANK_PAL_INT ((int)(PS2CLK / 50.00))
#define PS2VBLANK_PAL ((int)(PS2CLK / 49.76))
#define VBLANK_NTSC ((Config.PsxType & 2) ? 59.94 : 59.82)
#define VBLANK_PAL ((Config.PsxType & 2) ? 50.00 : 49.76)
#define HBLANK_NTSC (15734.26573)
#define HBLANK_PAL (15625)
#define PS2HBLANKEND_PAL (386*8)
#define PS2HBLANKEND_NTSC (371*8)
#define PS2VBLANKPAL ((Config.PsxType & 2) ? 312.5 : 314)
#define PS2VBLANKNTSC ((Config.PsxType & 2) ? 262.5 : 263)
#define PS2VBLANKEND_PAL ((int)(PS2HBLANK_PAL*6))
#define PS2VBLANKEND_NTSC ((int)(PS2HBLANK_NTSC*6))
#define PS2HBLANK_NTSC ((int)(PS2CLK / HBLANK_NTSC))
#define PS2HBLANK_PAL ((int)(PS2CLK / HBLANK_PAL))
#define PS2HBLANK ((int)((Config.PsxType & 1) ? PS2HBLANK_PAL : PS2HBLANK_NTSC))
#define PS2HBLANKEND ((int)((Config.PsxType & 1) ? PS2HBLANKEND_PAL : PS2HBLANKEND_NTSC))
#define PS2VBLANKEND ((int)((Config.PsxType & 1) ? PS2VBLANKEND_PAL : PS2VBLANKEND_NTSC))
#define PSXVBLANK_NTSC ((int)(PSXCLK / VBLANK_NTSC))
#define PSXVBLANK_PAL ((int)(PSXCLK / VBLANK_PAL))
#define PSXVBLANK ((int)((Config.PsxType & 1) ? PSXVBLANK_PAL : PSXVBLANK_NTSC))
#define PSXHBLANK_NTSC ((int)(PSXCLK / HBLANK_NTSC))
#define PSXHBLANK_PAL ((int)(PSXCLK / HBLANK_PAL))
#define PSXHBLANK ((int)((Config.PsxType & 1) ? PSXHBLANK_PAL : PSXHBLANK_NTSC))
#define PSXPIXEL ((int)(PSXCLK / 13500000))
#define PSXSOUNDCLK ((int)(48000))
#define COLOR_BLACK "\033[30m"
#define COLOR_RED "\033[31m"
#define COLOR_GREEN "\033[32m"
#define COLOR_YELLOW "\033[33m"
#define COLOR_BLUE "\033[34m"
#define COLOR_MAGENTA "\033[35m"
#define COLOR_CYAN "\033[36m"
#define COLOR_WHITE "\033[37m"
#define COLOR_RESET "\033[0m"
#include <pthread.h> // sync functions
#include "R5900.h"
#include "DebugTools/Debug.h"
#include "System.h"
#include "Memory.h"
#include "Elfheader.h"
#include "Hw.h"
//#include "GS.h"
#include "Vif.h"
#include "SPR.h"
#include "Sif.h"
#include "Plugins.h"
#include "PS2Edefs.h"
#include "Counters.h"
#include "IPU/IPU.h"
#include "Misc.h"
#include "Patch.h"
#include "COP0.h"
#include "VifDma.h"
#if (defined(__i386__) || defined(__x86_64__))
#include "x86/ix86/ix86.h"
#endif
int cdCaseopen;
extern void __Log(char *fmt, ...);
extern u16 logProtocol;
extern u8 logSource;
#define PCSX2_VERSION "0.9.2"
// C++ code for sqrtf
void InitFPUOps();
extern float (*fpusqrtf)(float fval);
extern float (*fpufabsf)(float fval);
extern float (*fpusinf)(float fval);
extern float (*fpucosf)(float fval);
extern float (*fpuexpf)(float fval);
extern float (*fpuatanf)(float fval);
extern float (*fpuatan2f)(float fvalx, float fvaly);
// Added Feb 16, 2006 by efp
#ifdef __LINUX__
#include <errno.h> // EBUSY
#endif /* __LINUX__ */
#define DESTROY_MUTEX(mutex) { \
int err = pthread_mutex_destroy(&mutex); \
if( err == EBUSY ) \
SysPrintf("cannot destroy"#mutex"\n"); \
} \
#define DESTROY_COND(cond) { \
int err = pthread_cond_destroy(&cond); \
if( err == EBUSY ) \
SysPrintf("cannot destroy"#cond"\n"); \
} \
#endif /* __COMMON_H__ */

654
Counters.c Normal file
View File

@ -0,0 +1,654 @@
/* 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
*/
#include <string.h>
#include <time.h>
#include <math.h>
#include "Common.h"
#include "PsxCommon.h"
#include "GS.h"
int gates = 0;
extern u8 psxhblankgate;
int hblankend = 0;
Counter counters[6];
u32 nextCounter, nextsCounter;
// 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 - (cpuRegs.cycle % counters[index].rate);
}
void rcntUpd(int index) {
counters[index].sCycle = cpuRegs.cycle - (cpuRegs.cycle % counters[index].rate);
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)) continue; // Stopped
c = (0xffff - rcntCycle(i)) * counters[i].rate;
if (c < nextCounter) {
nextCounter = c;
}
// the + 10 is just in case of overflow
if(eecntmask & (1<<i) || !(counters[i].mode & 0x100)) continue;
c = (counters[i].target - rcntCycle(i)) * counters[i].rate;
if (c < nextCounter) {
nextCounter = c;
}
}
//Calculate HBlank
c = counters[4].CycleT - (cpuRegs.cycle - counters[4].sCycleT);
if (c < nextCounter) {
nextCounter = c;
}
//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;
counters[4].sCycleT = cpuRegs.cycle;
counters[4].sCycle = cpuRegs.cycle;
counters[5].sCycleT = cpuRegs.cycle;
counters[5].sCycle = cpuRegs.cycle;
UpdateVSyncRate();
for (i=0; i<4; i++) rcntUpd(i);
rcntSet();
}
void UpdateVSyncRate() {
if (Config.PsxType & 1) {
SysPrintf("PAL\n");
counters[4].rate = PS2HBLANK_PAL;
if(Config.PsxType & 2)counters[5].rate = PS2VBLANK_PAL_INT;
else counters[5].rate = PS2VBLANK_PAL;
} else {
SysPrintf("NTSC\n");
counters[4].rate = PS2HBLANK_NTSC;
if(Config.PsxType & 2)counters[5].rate = PS2VBLANK_NTSC_INT;
else counters[5].rate = PS2VBLANK_NTSC;
}
counters[4].CycleT = PS2HBLANKEND;
counters[4].Cycle = counters[4].rate-PS2HBLANKEND;
counters[5].CycleT = PS2VBLANKEND;
counters[5].Cycle = counters[5].rate-PS2VBLANKEND;
}
// debug code, used for stats
int g_nCounters[4];
extern u32 s_lastvsync[2];
LARGE_INTEGER lfreq;
static int iFrame = 0;
void FrameLimiter()
{
static u32 dwStartTime = 0, dwEndTime = 0;
// do over 4 frames instead of 1
if( (iFrame&3) == 0 ) {
u32 frames = (Config.PsxType&1) ? (4000 / 50 - 4) : (4000 / 60 - 4);
dwEndTime = timeGetTime();
if( dwEndTime < dwStartTime + frames ) {
if( dwEndTime < dwStartTime + frames - 2 )
Sleep(frames-(dwEndTime-dwStartTime)-2);
while(dwEndTime < dwStartTime + frames) dwEndTime = timeGetTime();
}
dwStartTime = timeGetTime();
}
}
extern u32 CSRw;
extern u32 SuperVUGetRecTimes(int clear);
extern u32 vu0time;
extern void recExecuteVU1Block(void);
extern void DummyExecuteVU1Block(void);
#include "VU.h"
void VSync() {
//QueryPerformanceFrequency(&lfreq);
if (counters[5].mode & 0x10000) { // VSync End (22 hsyncs)
// swap the vsync field
u32 newfield = (*(u32*)(PS2MEM_GS+0x1000)&0x2000) ? 0 : 0x2000;
*(u32*)(PS2MEM_GS+0x1000) = (*(u32*)(PS2MEM_GS+0x1000) & ~(1<<13)) | newfield;
iFrame++;
// wait until GS stops
if( CHECK_MULTIGS ) {
GSRingBufSimplePacket(GS_RINGTYPE_VSYNC, newfield, 0, 0);
}
else {
GSvsync(newfield);
}
counters[5].mode&= ~0x10000;
hwIntcIrq(3);
psxVSyncEnd();
if(gates)rcntEndGate(0x8);
SysUpdate();
} else { // VSync Start (240 hsyncs)
//UpdateVSyncRateEnd();
//SysPrintf("c: %x, %x\n", cpuRegs.cycle, *(u32*)&VU1.Micro[16]);
//if( (iFrame%20) == 0 ) SysPrintf("svu time: %d\n", SuperVUGetRecTimes(1));
// 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
// used to limit frames
switch(CHECK_FRAMELIMIT) {
case PCSX2_FRAMELIMIT_LIMIT:
FrameLimiter();
break;
case PCSX2_FRAMELIMIT_SKIP:
case PCSX2_FRAMELIMIT_VUSKIP:
{
// the 6 was after trial and error
static u32 uPrevTimes[6] = {0}, uNextFrame = 0, uNumFrames = 0, uTotalTime = 0;
static u32 uLastTime = 0;
static int nConsecutiveSkip = 0, nConsecutiveRender = 0;
extern u32 g_bVUSkip;
static int changed = 0;
static int nNoSkipFrames = 0;
u32 uExpectedTime;
u32 uCurTime = timeGetTime();
u32 uDeltaTime = uCurTime - uLastTime;
assert( GSsetFrameSkip != NULL );
if( uLastTime > 0 ) {
if( uNumFrames == ARRAYSIZE(uPrevTimes) )
uTotalTime -= uPrevTimes[uNextFrame];
uPrevTimes[uNextFrame] = uDeltaTime;
uNextFrame = (uNextFrame + 1) % ARRAYSIZE(uPrevTimes);
uTotalTime += uDeltaTime;
if( uNumFrames < ARRAYSIZE(uPrevTimes) )
++uNumFrames;
}
uExpectedTime = (Config.PsxType&1) ? (ARRAYSIZE(uPrevTimes) * 1000 / 50 -1) : (ARRAYSIZE(uPrevTimes) * 1000 / 60 - 1);
if( nNoSkipFrames > 0 )
--nNoSkipFrames;
// hmm... this might be more complicated than it needs to be
if( changed != 0 ) {
if( changed > 0 ) {
++nConsecutiveRender;
--changed;
if( nConsecutiveRender > 20 && uTotalTime + 1 < uExpectedTime ) {
Sleep(uExpectedTime-uTotalTime);
nNoSkipFrames = ARRAYSIZE(uPrevTimes);
}
}
else {
++nConsecutiveSkip;
++changed;
}
}
else {
if( nNoSkipFrames == 0 && nConsecutiveRender > 3 && nConsecutiveSkip < 20 &&
(CHECK_MULTIGS? (uTotalTime >= uExpectedTime + uDeltaTime/4 && (uTotalTime >= uExpectedTime + uDeltaTime*3/4 || nConsecutiveSkip==0)) :
(uTotalTime >= uExpectedTime + (uDeltaTime/4))) ) {
if( CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_VUSKIP ) {
Cpu->ExecuteVU1Block = DummyExecuteVU1Block;
}
if( nConsecutiveSkip == 0 ) {
if( CHECK_MULTIGS ) GSRingBufSimplePacket(GS_RINGTYPE_FRAMESKIP, 1, 0, 0);
else GSsetFrameSkip(1);
}
changed = -3;
nConsecutiveSkip++;
}
else {
if( CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_VUSKIP ) {
Cpu->ExecuteVU1Block = recExecuteVU1Block;
}
if( nConsecutiveSkip ) {
if( CHECK_MULTIGS ) GSRingBufSimplePacket(GS_RINGTYPE_FRAMESKIP, 0, 0, 0);
else GSsetFrameSkip(0);
nConsecutiveRender = 0;
}
changed = 3;
nConsecutiveRender++;
nConsecutiveSkip = 0;
if( nConsecutiveRender > 20 && uTotalTime + 1 < uExpectedTime ) {
Sleep(uExpectedTime-uTotalTime);
nNoSkipFrames = ARRAYSIZE(uPrevTimes);
}
}
}
uLastTime = uCurTime;
break;
}
}
//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 (!(GSCSRr & 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;
for (i=0; i<=3; i++) {
if (!(counters[i].mode & 0x80)) continue; // Stopped
counters[i].count += (int)((cpuRegs.cycle - counters[i].sCycleT) / counters[i].rate);
counters[i].sCycleT = cpuRegs.cycle - (cpuRegs.cycle % counters[i].rate);
}
for (i=0; i<=3; i++) {
if (!(counters[i].mode & 0x80)) continue; // Stopped
if ((counters[i].count & ~0x3) == (counters[i].target & ~0x3)) { // Target interrupt
/*if (rcntCycle(i) != counters[i].target){
SysPrintf("rcntcycle = %d, target = %d, cyclet = %d\n", rcntCycle(i), counters[i].target, counters[i].sCycleT);
counters[i].sCycleT += (rcntCycle(i) - counters[i].target) * counters[i].rate;
SysPrintf("rcntcycle = %d, target = %d, cyclet = %d\n", rcntCycle(i), counters[i].target, counters[i].sCycleT);
}*/
//if ((eecntmask & (1 << i)) == 0) {
counters[i].mode|= 0x0400; // Target flag
if(counters[i].mode & 0x100) {
hwIntcIrq(counters[i].interrupt);
}
//eecntmask |= (1 << i);
//}
if (counters[i].mode & 0x40) { // Reset on target
counters[i].count = 0;
eecntmask &= ~(1 << i);
//rcntUpd(i);
}
}
if (counters[i].count >= 0xffff) {
eecntmask &= ~(1 << i);
counters[i].mode|= 0x0800; // Overflow flag
if (counters[i].mode & 0x0200) { // Overflow interrupt
hwIntcIrq(counters[i].interrupt);
// SysPrintf("counter[%d] overflow interrupt (%x)\n", i, cpuRegs.cycle);
}
counters[i].count = 0;
//rcntUpd(i);
}
// rcntUpd(i);
}
if ((cpuRegs.cycle - counters[4].sCycleT) >= counters[4].CycleT && hblankend == 1){
if (!(GSCSRr & 0x4)){
GSCSRr |= 4; // signal
}
if (!(GSIMR&0x400) )
gsIrq();
if(gates)rcntEndGate(0);
if(psxhblankgate)psxCheckEndGate(0);
hblankend = 0;
counters[4].CycleT = counters[4].rate;
}
if ((cpuRegs.cycle - counters[4].sCycleT) >= counters[4].CycleT) {
counters[4].sCycleT = cpuRegs.cycle;
counters[4].sCycle = cpuRegs.cycle;
counters[4].CycleT = counters[4].rate-PS2HBLANKEND;
counters[4].Cycle = counters[4].rate;
counters[4].count = 0;
if(gates)rcntStartGate(0);
if(psxhblankgate)psxCheckStartGate(0);
hblankend = 1;
}
if ((cpuRegs.cycle - counters[5].sCycleT)
>= counters[5].CycleT && (counters[5].mode & 0x10000)){
counters[5].CycleT = counters[5].rate;
VSync();
}
if ((cpuRegs.cycle - counters[5].sCycleT) >= counters[5].CycleT) {
counters[5].sCycleT = cpuRegs.cycle;
counters[5].sCycle = cpuRegs.cycle;
counters[5].CycleT = counters[5].rate-PS2VBLANKEND;
counters[5].Cycle = counters[5].rate;
counters[5].count = 0;
VSync();
}
rcntSet();
}
void rcntWcount(int index, u32 value) {
//SysPrintf ("writeCcount[%d] = %x\n", index, value);
#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
//if((u16)value < counters[index].target)
//eecntmask &= ~(1 << index);
counters[index].count = value & 0xffff;
rcntUpd(index);
rcntSet();
}
void rcntWmode(int index, u32 value)
{
if (value & 0xc00) { //Clear status flags, the ps2 only clears what is given in the value
eecntmask &= ~(1 << index);
counters[index].mode &= ~((value & 0xc00));
}
//if((value & 0x3ff) != (counters[index].mode & 0x3ff))eecntmask &= ~(1 << index);
counters[index].mode = (counters[index].mode & 0xc00) | (value & 0x3ff);
#ifdef EECNT_LOG
EECNT_LOG("EE counter set %d mode %x\n", index, counters[index].mode);
#endif
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<<index);
counters[index].mode &= ~0x80;
}else if(counters[index].mode & 0x4){
SysPrintf("Gate enable on counter %x mode %x\n", index, counters[index].mode);
gates |= 1<<index;
counters[index].mode &= ~0x80;
rcntReset(index);
}
else gates &= ~(1<<index);
//counters[index].count = 0;
rcntSet();
}
void rcntStartGate(int mode){
int i;
for(i=0; i <=3; i++){ //Gates for counters
if(!(gates & (1<<i))) continue;
if ((counters[i].mode & 0x8) != mode) continue;
//SysPrintf("Gate %d mode %d Start\n", i, (counters[i].mode & 0x30) >> 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);
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);
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<<i))) continue;
if ((counters[i].mode & 0x8) != mode) continue;
//SysPrintf("Gate %d mode %d End\n", i, (counters[i].mode & 0x30) >> 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);
break;
case 0x3: //Reset and start counting on Vsync start and end
counters[i].mode |= 0x80;
rcntReset(i);
break;
default:
SysPrintf("EE Start Counter %x Gate error\n", i);
break;
}
}
}
void rcntWtarget(int index, u32 value) {
eecntmask &= ~(1 << index);
counters[index].target = value & 0xffff;
#ifdef EECNT_LOG
EECNT_LOG("EE target write %d target %x value %x\n", index, counters[index].target, value);
#endif
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;
}
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;
}

46
Counters.h Normal file
View File

@ -0,0 +1,46 @@
/* 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 __COUNTERS_H__
#define __COUNTERS_H__
typedef struct {
u32 count, mode, target, hold;
u32 rate, interrupt;
u32 Cycle, sCycle;
u32 CycleT, sCycleT;
} Counter;
extern Counter counters[6];
extern u32 nextCounter, nextsCounter;
void rcntInit();
void rcntUpdate();
void rcntStartGate(int mode);
void rcntEndGate(int mode);
void rcntWcount(int index, u32 value);
void rcntWmode(int index, u32 value);
void rcntWtarget(int index, u32 value);
void rcntWhold(int index, u32 value);
u16 rcntRcount(int index);
u32 rcntCycle(int index);
int rcntFreeze(gzFile f, int Mode);
void UpdateVSyncRate();
#endif /* __COUNTERS_H__ */

137
DebugTools/Debug.h Normal file
View File

@ -0,0 +1,137 @@
/* 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 __DEBUG_H__
#define __DEBUG_H__
#include "Common.h"
FILE *emuLog;
char* disR5900F(u32 code, u32 pc);
char* disR5900Fasm(u32 code, u32 pc);
char* disR3000Fasm(u32 code, u32 pc);
void disR5900AddSym(u32 addr, char *name);
char* disR5900GetSym(u32 addr);
char* disR5900GetUpperSym(u32 addr);
void disR5900FreeSyms();
char* disVU0MicroUF(u32 code, u32 pc);
char* disVU0MicroLF(u32 code, u32 pc);
char* disVU1MicroUF(u32 code, u32 pc);
char* disVU1MicroLF(u32 code, u32 pc);
char* disR3000AF(u32 code, u32 pc);
extern char *CP2VFnames[];
extern char *disRNameCP2f[];
extern char *disRNameCP2i[];
//that way is slower but you now not need to compile every time ;P
#ifdef PCSX2_DEVBUILD
int Log;
u32 varLog;
//memcars has the same number as PAD_LOG
#define MEMCARDS_LOG if (varLog & 0x02000000) {logProtocol=7; logSource='I';} if (varLog & 0x02000000) __Log
#define CPU_LOG if (varLog & 0x00000001) {logProtocol=1; logSource='E';} if (varLog & 0x00000001) __Log
#define MEM_LOG if (varLog & 0x00000002) {logProtocol=6; logSource='E';} if (varLog & 0x00000002) __Log("%8.8lx: ", cpuRegs.pc); if (varLog & 0x00000002) __Log
#define HW_LOG if (varLog & 0x00000004) {logProtocol=6; logSource='E';} if (varLog & 0x00000004) __Log("%8.8lx: ", cpuRegs.pc); if (varLog & 0x00000004) __Log
#define DMA_LOG if (varLog & 0x00000008) {logProtocol=5; logSource='E';} if (varLog & 0x00000008) __Log
#define BIOS_LOG if (varLog & 0x00000010) {logProtocol=0; logSource='E';} if (varLog & 0x00000010) __Log("%8.8lx: ", cpuRegs.pc); if (varLog & 0x00000010) __Log
#define ELF_LOG if (varLog & 0x00000020) {logProtocol=7; logSource='E';} if (varLog & 0x00000020) __Log
#define FPU_LOG if (varLog & 0x00000040) {logProtocol=1; logSource='E';} if (varLog & 0x00000040) __Log
#define MMI_LOG if (varLog & 0x00000080) {logProtocol=1; logSource='E';} if (varLog & 0x00000080) __Log
#define VU0_LOG if (varLog & 0x00000100) {logProtocol=2; logSource='E';} if (varLog & 0x00000100) __Log
#define COP0_LOG if (varLog & 0x00000200) {logProtocol=1; logSource='E';} if (varLog & 0x00000200) __Log
#define VIF_LOG if (varLog & 0x00000400) {logProtocol=3; logSource='E';} if (varLog & 0x00000400) __Log
#define SPR_LOG if (varLog & 0x00000800) {logProtocol=7; logSource='E';} if (varLog & 0x00000800) __Log
#define GIF_LOG if (varLog & 0x00001000) {logProtocol=4; logSource='E';} if (varLog & 0x00001000) __Log
#define SIF_LOG if (varLog & 0x00002000) {logProtocol=9; logSource='E';} if (varLog & 0x00002000) __Log
#define IPU_LOG if (varLog & 0x00004000) {logProtocol=8; logSource='E';} if (varLog & 0x00004000) __Log
#define VUM_LOG if (varLog & 0x00008000) {logProtocol=2; logSource='E';} if (varLog & 0x00008000) __Log
#define RPC_LOG if (varLog & 0x00010000) {logProtocol=9; logSource='E';} if (varLog & 0x00010000) __Log
#define PSXCPU_LOG if (varLog & 0x00100000) {logProtocol=1; logSource='I';} if (varLog & 0x00100000) __Log
#define PSXMEM_LOG if (varLog & 0x00200000) {logProtocol=6; logSource='I';} if (varLog & 0x00200000) __Log("%8.8lx : ", psxRegs.pc); if (varLog & 0x00200000) __Log
#define PSXHW_LOG if (varLog & 0x00400000) {logProtocol=2; logSource='I';} if (varLog & 0x00400000) __Log("%8.8lx : ", psxRegs.pc); if (varLog & 0x00400000) __Log
#define PSXBIOS_LOG if (varLog & 0x00800000) {logProtocol=0; logSource='I';} if (varLog & 0x00800000) __Log("%8.8lx : ", psxRegs.pc); if (varLog & 0x00800000) __Log
#define PSXDMA_LOG if (varLog & 0x01000000) {logProtocol=5; logSource='I';} if (varLog & 0x01000000) __Log
#define PAD_LOG if (varLog & 0x02000000) {logProtocol=7; logSource='I';} if (varLog & 0x02000000) __Log
#define GTE_LOG if (varLog & 0x04000000) {logProtocol=3; logSource='I';} if (varLog & 0x04000000) __Log
#define CDR_LOG if (varLog & 0x08000000) {logProtocol=8; logSource='I';} if (varLog & 0x08000000) __Log("%8.8lx %8.8lx: ", psxRegs.pc, psxRegs.cycle); if (varLog & 0x08000000) __Log
#define GPU_LOG if (varLog & 0x10000000) {logProtocol=4; logSource='I';} if (varLog & 0x10000000) __Log
#define PSXCNT_LOG if (varLog & 0x20000000) {logProtocol=0; logSource='I';} if (varLog & 0x20000000) __Log("%8.8lx %8.8lx: ", psxRegs.pc, psxRegs.cycle); if (varLog & 0x20000000) __Log
#define EECNT_LOG if (varLog & 0x40000000) {logProtocol=0; logSource='I';} if (varLog & 0x40000000) __Log("%8.8lx %8.8lx: ", cpuRegs.pc, cpuRegs.cycle); if (varLog & 0x40000000) __Log
#if defined (CPU_LOG) || defined(MEM_LOG) || defined(HW_LOG) || defined(DMA_LOG) || \
defined(BIOS_LOG) || defined(ELF_LOG) || defined(FPU_LOG) || defined(MMI_LOG) || \
defined(VU0_LOG) || defined(COP0_LOG) || defined(VIF_LOG) || defined(SPR_LOG) || \
defined(GIF_LOG) || defined(SIF_LOG) || defined(IPU_LOG) || defined(VUM_log) || \
defined(PSXCPU_LOG) || defined(PSXMEM_LOG)|| defined(IOPBIOS_LOG)|| defined(IOPHW_LOG)|| \
defined(PAD_LOG) || defined(GTE_LOG) || defined(CDR_LOG) || defined(GPU_LOG) || \
defined(MEMCARDS_LOG)|| defined(PSXCNT_LOG) || defined(EECNT_LOG)
#define EMU_LOG __Log
#endif
#else // PCSX2_DEVBUILD
#define varLog 0
#define Log 0
#define CPU_LOG 0&&
#define MEM_LOG 0&&
#define HW_LOG 0&&
#define DMA_LOG 0&&
#define BIOS_LOG 0&&
#define ELF_LOG 0&&
#define FPU_LOG 0&&
#define MMI_LOG 0&&
#define VU0_LOG 0&&
#define COP0_LOG 0&&
#define VIF_LOG 0&&
#define SPR_LOG 0&&
#define GIF_LOG 0&&
#define SIF_LOG 0&&
#define IPU_LOG 0&&
#define VUM_LOG 0&&
#define RPC_LOG 0&&
#define PSXCPU_LOG 0&&
#define PSXMEM_LOG 0&&
#define PSXHW_LOG 0&&
#define PSXBIOS_LOG 0&&
#define PSXDMA_LOG 0&&
#define PAD_LOG 0&&
#define GTE_LOG 0&&
#define CDR_LOG 0&&
#define GPU_LOG 0&&
#define PSXCNT_LOG 0&&
#define EECNT_LOG 0&&
#define EMU_LOG 0&&
#endif
#endif /* __DEBUG_H__ */

54
DebugTools/DisASM.h Normal file
View File

@ -0,0 +1,54 @@
/* 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
*/
#include <stdio.h>
#include <string.h>
#include "R5900.h"
//DECODE PROCUDURES
//cop0
#define DECODE_FS (DECODE_RD)
#define DECODE_FT (DECODE_RT)
#define DECODE_FD (DECODE_SA)
///********
#define DECODE_FUNCTION ((cpuRegs.code) & 0x3F)
#define DECODE_RD ((cpuRegs.code >> 11) & 0x1F) // The rd part of the instruction register
#define DECODE_RT ((cpuRegs.code >> 16) & 0x1F) // The rt part of the instruction register
#define DECODE_RS ((cpuRegs.code >> 21) & 0x1F) // The rs part of the instruction register
#define DECODE_SA ((cpuRegs.code >> 6) & 0x1F) // The sa part of the instruction register
#define DECODE_IMMED ( cpuRegs.code & 0xFFFF) // The immediate part of the instruction register
#define DECODE_OFFSET ((((short)DECODE_IMMED * 4) + opcode_addr + 4))
#define DECODE_JUMP (opcode_addr & 0xf0000000)|((cpuRegs.code&0x3ffffff)<<2)
#define DECODE_SYSCALL ((opcode_addr & 0x03FFFFFF) >> 6)
#define DECODE_BREAK (DECODE_SYSCALL)
#define DECODE_C0BC ((cpuRegs.code >> 16) & 0x03)
#define DECODE_C1BC ((cpuRegs.code >> 16) & 0x03)
#define DECODE_C2BC ((cpuRegs.code >> 16) & 0x03)
//IOP
#define DECODE_RD_IOP ((psxRegs.code >> 11) & 0x1F)
#define DECODE_RT_IOP ((psxRegs.code >> 16) & 0x1F)
#define DECODE_RS_IOP ((psxRegs.code >> 21) & 0x1F)
#define DECODE_IMMED_IOP ( psxRegs.code & 0xFFFF)
#define DECODE_SA_IOP ((psxRegs.code >> 6) & 0x1F)
#define DECODE_FS_IOP (DECODE_RD_IOP)

318
DebugTools/DisR3000A.c Normal file
View File

@ -0,0 +1,318 @@
/* 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
*/
#include "Debug.h"
char ostr[256];
// Names of registers
static char *disRNameGPR[] = {
"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","fp", "ra"};
static char *disRNameCP0[] = {
"Index" , "Random" , "EntryLo0", "EntryLo1", "Context" , "PageMask" , "Wired" , "*Check me*",
"BadVAddr" , "Count" , "EntryHi" , "Compare" , "Status" , "Cause" , "ExceptPC" , "PRevID" ,
"Config" , "LLAddr" , "WatchLo" , "WatchHi" , "XContext", "*RES*" , "*RES*" , "*RES*" ,
"*RES*" , "*RES* " , "PErr" , "CacheErr", "TagLo" , "TagHi" , "ErrorEPC" , "*RES*" };
// Type deffinition of our functions
typedef char* (*TdisR3000AF)(u32 code, u32 pc);
// These macros are used to assemble the disassembler functions
#define MakeDisFg(fn, b) char* fn(u32 code, u32 pc) { b; return ostr; }
#define MakeDisF(fn, b) \
static char* fn(u32 code, u32 pc) { \
sprintf (ostr, "%8.8lx %8.8lx:", pc, code); \
b; /*ostr[(strlen(ostr) - 1)] = 0;*/ return ostr; \
}
#include "R3000A.h"
#undef _Funct_
#undef _Rd_
#undef _Rt_
#undef _Rs_
#undef _Sa_
#undef _Im_
#undef _Target_
#define _Funct_ ((code ) & 0x3F) // The funct part of the instruction register
#define _Rd_ ((code >> 11) & 0x1F) // The rd part of the instruction register
#define _Rt_ ((code >> 16) & 0x1F) // The rt part of the instruction register
#define _Rs_ ((code >> 21) & 0x1F) // The rs part of the instruction register
#define _Sa_ ((code >> 6) & 0x1F) // The sa part of the instruction register
#define _Im_ ( code & 0xFFFF) // The immediate part of the instruction register
#define _Target_ ((pc & 0xf0000000) + ((code & 0x03ffffff) * 4))
#define _Branch_ (pc + 4 + ((short)_Im_ * 4))
#define _OfB_ _Im_, _nRs_
#define dName(i) sprintf(ostr, "%s %-7s,", ostr, i)
#define dGPR(i) sprintf(ostr, "%s %8.8lx (%s),", ostr, psxRegs.GPR.r[i], disRNameGPR[i])
#define dCP0(i) sprintf(ostr, "%s %8.8lx (%s),", ostr, psxRegs.CP0.r[i], disRNameCP0[i])
#define dHI() sprintf(ostr, "%s %8.8lx (%s),", ostr, psxRegs.GPR.n.hi, "hi")
#define dLO() sprintf(ostr, "%s %8.8lx (%s),", ostr, psxRegs.GPR.n.lo, "lo")
#define dImm() sprintf(ostr, "%s %4.4lx (%ld),", ostr, _Im_, _Im_)
#define dTarget() sprintf(ostr, "%s %8.8lx,", ostr, _Target_)
#define dSa() sprintf(ostr, "%s %2.2lx (%ld),", ostr, _Sa_, _Sa_)
#define dOfB() sprintf(ostr, "%s %4.4lx (%8.8lx (%s)),", ostr, _Im_, psxRegs.GPR.r[_Rs_], disRNameGPR[_Rs_])
#define dOffset() sprintf(ostr, "%s %8.8lx,", ostr, _Branch_)
#define dCode() sprintf(ostr, "%s %8.8lx,", ostr, (code >> 6) & 0xffffff)
/*********************************************************
* Arithmetic with immediate operand *
* Format: OP rt, rs, immediate *
*********************************************************/
MakeDisF(disADDI, dName("ADDI"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
MakeDisF(disADDIU, dName("ADDIU"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
MakeDisF(disANDI, dName("ANDI"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
MakeDisF(disORI, dName("ORI"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
MakeDisF(disSLTI, dName("SLTI"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
MakeDisF(disSLTIU, dName("SLTIU"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
MakeDisF(disXORI, dName("XORI"); dGPR(_Rt_); dGPR(_Rs_); dImm();)
/*********************************************************
* Register arithmetic *
* Format: OP rd, rs, rt *
*********************************************************/
MakeDisF(disADD, dName("ADD"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
MakeDisF(disADDU, dName("ADDU"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
MakeDisF(disAND, dName("AND"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
MakeDisF(disNOR, dName("NOR"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
MakeDisF(disOR, dName("OR"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
MakeDisF(disSLT, dName("SLT"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
MakeDisF(disSLTU, dName("SLTU"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
MakeDisF(disSUB, dName("SUB"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
MakeDisF(disSUBU, dName("SUBU"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
MakeDisF(disXOR, dName("XOR"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);)
/*********************************************************
* Register arithmetic & Register trap logic *
* Format: OP rs, rt *
*********************************************************/
MakeDisF(disDIV, dName("DIV"); dGPR(_Rs_); dGPR(_Rt_);)
MakeDisF(disDIVU, dName("DIVU"); dGPR(_Rs_); dGPR(_Rt_);)
MakeDisF(disMULT, dName("MULT"); dGPR(_Rs_); dGPR(_Rt_);)
MakeDisF(disMULTU, dName("MULTU"); dGPR(_Rs_); dGPR(_Rt_);)
/*********************************************************
* Register branch logic *
* Format: OP rs, offset *
*********************************************************/
MakeDisF(disBGEZ, dName("BGEZ"); dGPR(_Rs_); dOffset();)
MakeDisF(disBGEZAL, dName("BGEZAL"); dGPR(_Rs_); dOffset();)
MakeDisF(disBGTZ, dName("BGTZ"); dGPR(_Rs_); dOffset();)
MakeDisF(disBLEZ, dName("BLEZ"); dGPR(_Rs_); dOffset();)
MakeDisF(disBLTZ, dName("BLTZ"); dGPR(_Rs_); dOffset();)
MakeDisF(disBLTZAL, dName("BLTZAL"); dGPR(_Rs_); dOffset();)
/*********************************************************
* Shift arithmetic with constant shift *
* Format: OP rd, rt, sa *
*********************************************************/
MakeDisF(disSLL, if (code) { dName("SLL"); dGPR(_Rd_); dGPR(_Rt_); dSa(); } else { dName("NOP"); })
MakeDisF(disSRA, dName("SRA"); dGPR(_Rd_); dGPR(_Rt_); dSa();)
MakeDisF(disSRL, dName("SRL"); dGPR(_Rd_); dGPR(_Rt_); dSa();)
/*********************************************************
* Shift arithmetic with variant register shift *
* Format: OP rd, rt, rs *
*********************************************************/
MakeDisF(disSLLV, dName("SLLV"); dGPR(_Rd_); dGPR(_Rt_); dGPR(_Rs_);)
MakeDisF(disSRAV, dName("SRAV"); dGPR(_Rd_); dGPR(_Rt_); dGPR(_Rs_);)
MakeDisF(disSRLV, dName("SRLV"); dGPR(_Rd_); dGPR(_Rt_); dGPR(_Rs_);)
/*********************************************************
* Load higher 16 bits of the first word in GPR with imm *
* Format: OP rt, immediate *
*********************************************************/
MakeDisF(disLUI, dName("LUI"); dGPR(_Rt_); dImm();)
/*********************************************************
* Move from HI/LO to GPR *
* Format: OP rd *
*********************************************************/
MakeDisF(disMFHI, dName("MFHI"); dGPR(_Rd_); dHI();)
MakeDisF(disMFLO, dName("MFLO"); dGPR(_Rd_); dLO();)
/*********************************************************
* Move from GPR to HI/LO *
* Format: OP rd *
*********************************************************/
MakeDisF(disMTHI, dName("MTHI"); dHI(); dGPR(_Rs_);)
MakeDisF(disMTLO, dName("MTLO"); dLO(); dGPR(_Rs_);)
/*********************************************************
* Special purpose instructions *
* Format: OP *
*********************************************************/
MakeDisF(disBREAK, dName("BREAK"))
MakeDisF(disRFE, dName("RFE"))
MakeDisF(disSYSCALL, dName("SYSCALL"))
MakeDisF(disRTPS, dName("RTPS"))
MakeDisF(disOP , dName("OP"))
MakeDisF(disNCLIP, dName("NCLIP"))
MakeDisF(disDPCS, dName("DPCS"))
MakeDisF(disINTPL, dName("INTPL"))
MakeDisF(disMVMVA, dName("MVMVA"))
MakeDisF(disNCDS , dName("NCDS"))
MakeDisF(disCDP , dName("CDP"))
MakeDisF(disNCDT , dName("NCDT"))
MakeDisF(disNCCS , dName("NCCS"))
MakeDisF(disCC , dName("CC"))
MakeDisF(disNCS , dName("NCS"))
MakeDisF(disNCT , dName("NCT"))
MakeDisF(disSQR , dName("SQR"))
MakeDisF(disDCPL , dName("DCPL"))
MakeDisF(disDPCT , dName("DPCT"))
MakeDisF(disAVSZ3, dName("AVSZ3"))
MakeDisF(disAVSZ4, dName("AVSZ4"))
MakeDisF(disRTPT , dName("RTPT"))
MakeDisF(disGPF , dName("GPF"))
MakeDisF(disGPL , dName("GPL"))
MakeDisF(disNCCT , dName("NCCT"))
MakeDisF(disMFC2, dName("MFC2"); dGPR(_Rt_);)
MakeDisF(disCFC2, dName("CFC2"); dGPR(_Rt_);)
MakeDisF(disMTC2, dName("MTC2"))
MakeDisF(disCTC2, dName("CTC2"))
/*********************************************************
* Register branch logic *
* Format: OP rs, rt, offset *
*********************************************************/
MakeDisF(disBEQ, dName("BEQ"); dGPR(_Rs_); dGPR(_Rt_); dOffset();)
MakeDisF(disBNE, dName("BNE"); dGPR(_Rs_); dGPR(_Rt_); dOffset();)
/*********************************************************
* Jump to target *
* Format: OP target *
*********************************************************/
MakeDisF(disJ, dName("J"); dTarget();)
MakeDisF(disJAL, dName("JAL"); dTarget(); dGPR(31);)
/*********************************************************
* Register jump *
* Format: OP rs, rd *
*********************************************************/
MakeDisF(disJR, dName("JR"); dGPR(_Rs_);)
MakeDisF(disJALR, dName("JALR"); dGPR(_Rs_); dGPR(_Rd_))
/*********************************************************
* Load and store for GPR *
* Format: OP rt, offset(base) *
*********************************************************/
MakeDisF(disLB, dName("LB"); dGPR(_Rt_); dOfB();)
MakeDisF(disLBU, dName("LBU"); dGPR(_Rt_); dOfB();)
MakeDisF(disLH, dName("LH"); dGPR(_Rt_); dOfB();)
MakeDisF(disLHU, dName("LHU"); dGPR(_Rt_); dOfB();)
MakeDisF(disLW, dName("LW"); dGPR(_Rt_); dOfB();)
MakeDisF(disLWL, dName("LWL"); dGPR(_Rt_); dOfB();)
MakeDisF(disLWR, dName("LWR"); dGPR(_Rt_); dOfB();)
MakeDisF(disLWC2, dName("LWC2"); dGPR(_Rt_); dOfB();)
MakeDisF(disSB, dName("SB"); dGPR(_Rt_); dOfB();)
MakeDisF(disSH, dName("SH"); dGPR(_Rt_); dOfB();)
MakeDisF(disSW, dName("SW"); dGPR(_Rt_); dOfB();)
MakeDisF(disSWL, dName("SWL"); dGPR(_Rt_); dOfB();)
MakeDisF(disSWR, dName("SWR"); dGPR(_Rt_); dOfB();)
MakeDisF(disSWC2, dName("SWC2"); dGPR(_Rt_); dOfB();)
/*********************************************************
* Moves between GPR and COPx *
* Format: OP rt, fs *
*********************************************************/
MakeDisF(disMFC0, dName("MFC0"); dGPR(_Rt_); dCP0(_Rd_);)
MakeDisF(disMTC0, dName("MTC0"); dCP0(_Rd_); dGPR(_Rt_);)
MakeDisF(disCFC0, dName("CFC0"); dGPR(_Rt_); dCP0(_Rd_);)
MakeDisF(disCTC0, dName("CTC0"); dCP0(_Rd_); dGPR(_Rt_);)
/*********************************************************
* Unknow instruction (would generate an exception) *
* Format: ? *
*********************************************************/
MakeDisF(disNULL, dName("*** Bad OP ***");)
TdisR3000AF disR3000A_SPECIAL[] = { // Subset of disSPECIAL
disSLL , disNULL , disSRL , disSRA , disSLLV , disNULL , disSRLV , disSRAV ,
disJR , disJALR , disNULL, disNULL, disSYSCALL, disBREAK , disNULL , disNULL ,
disMFHI, disMTHI , disMFLO, disMTLO, disNULL , disNULL , disNULL , disNULL ,
disMULT, disMULTU, disDIV , disDIVU, disNULL , disNULL , disNULL , disNULL ,
disADD , disADDU , disSUB , disSUBU, disAND , disOR , disXOR , disNOR ,
disNULL, disNULL , disSLT , disSLTU, disNULL , disNULL , disNULL , disNULL ,
disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL ,
disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL};
MakeDisF(disSPECIAL, disR3000A_SPECIAL[_Funct_](code, pc))
TdisR3000AF disR3000A_BCOND[] = { // Subset of disBCOND
disBLTZ , disBGEZ , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disBLTZAL, disBGEZAL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
MakeDisF(disBCOND, disR3000A_BCOND[_Rt_](code, pc))
TdisR3000AF disR3000A_COP0[] = { // Subset of disCOP0
disMFC0, disNULL, disCFC0, disNULL, disMTC0, disNULL, disCTC0, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disRFE , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
MakeDisF(disCOP0, disR3000A_COP0[_Rs_](code, pc))
TdisR3000AF disR3000A_BASIC[] = { // Subset of disBASIC (based on rs)
disMFC2, disNULL, disCFC2, disNULL, disMTC2, disNULL, disCTC2, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
MakeDisF(disBASIC, disR3000A_BASIC[_Rs_](code, pc))
TdisR3000AF disR3000A_COP2[] = { // Subset of disR3000F_COP2 (based on funct)
disBASIC, disRTPS , disNULL , disNULL , disNULL, disNULL , disNCLIP, disNULL,
disNULL , disNULL , disNULL , disNULL , disOP , disNULL , disNULL , disNULL,
disDPCS , disINTPL, disMVMVA, disNCDS , disCDP , disNULL , disNCDT , disNULL,
disNULL , disNULL , disNULL , disNCCS , disCC , disNULL , disNCS , disNULL,
disNCT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL,
disSQR , disDCPL , disDPCT , disNULL , disNULL, disAVSZ3, disAVSZ4, disNULL,
disRTPT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL,
disNULL , disNULL , disNULL , disNULL , disNULL, disGPF , disGPL , disNCCT };
MakeDisF(disCOP2, disR3000A_COP2[_Funct_](code, pc))
TdisR3000AF disR3000A[] = {
disSPECIAL , disBCOND , disJ , disJAL , disBEQ , disBNE , disBLEZ , disBGTZ ,
disADDI , disADDIU , disSLTI , disSLTIU, disANDI, disORI , disXORI , disLUI ,
disCOP0 , disNULL , disCOP2 , disNULL , disNULL, disNULL, disNULL , disNULL ,
disNULL , disNULL , disNULL , disNULL , disNULL, disNULL, disNULL , disNULL ,
disLB , disLH , disLWL , disLW , disLBU , disLHU , disLWR , disNULL ,
disSB , disSH , disSWL , disSW , disNULL, disNULL, disSWR , disNULL ,
disNULL , disNULL , disLWC2 , disNULL , disNULL, disNULL, disNULL , disNULL ,
disNULL , disNULL , disSWC2 , disNULL , disNULL, disNULL, disNULL , disNULL };
MakeDisFg(disR3000AF, disR3000A[code >> 26](code, pc))

361
DebugTools/DisR3000asm.c Normal file
View File

@ -0,0 +1,361 @@
/* 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
*/
#include <stdio.h>
#include <string.h>
#include "Debug.h"
#include "R5900.h"
#include "R3000A.h"
#include "DisASM.h"
unsigned long IOP_opcode_addr;
char *GPR_IOP_REG[32] = {
"zero", "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", "fp", "ra"
};
char *COP0_IOP_REG[32] ={
"Index","Random","EntryLo0","EntryLo1","Context","PageMask",
"Wired","C0r7","BadVaddr","Count","EntryHi","Compare","Status",
"Cause","EPC","PRId","Config","C0r17","C0r18","C0r19","C0r20",
"C0r21","C0r22","C0r23","Debug","Perf","C0r26","C0r27","TagLo",
"TagHi","ErrorPC","C0r31"
};
void IOPD_SPECIAL(char *buf);
void IOPD_REGIMM(char *buf);
void IOPD_J(char *buf);
void IOPD_JAL(char *buf);
void IOPD_BEQ(char *buf);
void IOPD_BNE(char *buf);
void IOPD_BLEZ(char *buf);
void IOPD_BGTZ(char *buf);
void IOPD_ADDI(char *buf);
void IOPD_ADDIU(char *buf);
void IOPD_SLTI(char *buf);
void IOPD_SLTIU(char *buf);
void IOPD_ANDI(char *buf);
void IOPD_ORI(char *buf);
void IOPD_XORI(char *buf);
void IOPD_LUI(char *buf);
void IOPD_COP0(char *buf);
void IOPD_COP2(char *buf);
void IOPD_LB(char *buf);
void IOPD_LH(char *buf);
void IOPD_LWL(char *buf);
void IOPD_LW(char *buf);
void IOPD_LBU(char *buf);
void IOPD_LHU(char *buf);
void IOPD_LWR(char *buf);
void IOPD_SB(char *buf);
void IOPD_SH(char *buf);
void IOPD_SWL(char *buf);
void IOPD_SW(char *buf);
void IOPD_SWR(char *buf);
void IOPD_LWC2(char *buf);
void IOPD_SWC2(char *buf);
void IOPD_SLL(char *buf);
void IOPD_SRL(char *buf);
void IOPD_SRA(char *buf);
void IOPD_SLLV(char *buf);
void IOPD_SRLV(char *buf);
void IOPD_SRAV(char *buf);
void IOPD_JR(char *buf);
void IOPD_JALR(char *buf);
void IOPD_SYSCALL(char *buf);
void IOPD_BREAK(char *buf);
void IOPD_MFHI(char *buf);
void IOPD_MTHI(char *buf);
void IOPD_MFLO(char *buf);
void IOPD_MTLO(char *buf);
void IOPD_MULT(char *buf);
void IOPD_MULTU(char *buf);
void IOPD_DIV(char *buf);
void IOPD_DIVU(char *buf);
void IOPD_ADD(char *buf);
void IOPD_ADDU(char *buf);
void IOPD_SUB(char *buf);
void IOPD_SUBU(char *buf);
void IOPD_AND(char *buf);
void IOPD_OR(char *buf);
void IOPD_XOR(char *buf);
void IOPD_NOR(char *buf);
void IOPD_SLT(char *buf);
void IOPD_SLTU(char *buf);
void IOPD_BLTZ(char *buf);
void IOPD_BGEZ(char *buf);
void IOPD_BLTZAL(char *buf);
void IOPD_BGEZAL(char *buf);
void IOPD_MFC0(char *buf);
void IOPD_CFC0(char *buf);
void IOPD_MTC0(char *buf);
void IOPD_CTC0(char *buf);
void IOPD_RFE(char *buf);
void IOPD_BASIC(char *buf);
void IOPD_RTPS(char *buf);
void IOPD_NCLIP(char *buf);
void IOPD_OP(char *buf);
void IOPD_DPCS(char *buf);
void IOPD_INTPL(char *buf);
void IOPD_MVMVA(char *buf);
void IOPD_NCDS(char *buf);
void IOPD_CDP(char *buf);
void IOPD_NCDT(char *buf);
void IOPD_NCCS(char *buf);
void IOPD_CC(char *buf);
void IOPD_NCS(char *buf);
void IOPD_NCT(char *buf);
void IOPD_SQR(char *buf);
void IOPD_DCPL(char *buf);
void IOPD_DPCT(char *buf);
void IOPD_AVSZ3(char *buf);
void IOPD_AVSZ4(char *buf);
void IOPD_RTPT(char *buf);
void IOPD_GPF(char *buf);
void IOPD_GPL(char *buf);
void IOPD_NCCT(char *buf);
void IOPD_MFC2(char *buf);
void IOPD_CFC2(char *buf);
void IOPD_MTC2(char *buf);
void IOPD_CTC2(char *buf);
void IOPD_NULL(char *buf);
void (*IOP_DEBUG_BSC[64])(char *buf) = {
IOPD_SPECIAL, IOPD_REGIMM, IOPD_J , IOPD_JAL , IOPD_BEQ , IOPD_BNE , IOPD_BLEZ, IOPD_BGTZ,
IOPD_ADDI , IOPD_ADDIU , IOPD_SLTI, IOPD_SLTIU, IOPD_ANDI, IOPD_ORI , IOPD_XORI, IOPD_LUI ,
IOPD_COP0 , IOPD_NULL , IOPD_COP2, IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL,
IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL,
IOPD_LB , IOPD_LH , IOPD_LWL , IOPD_LW , IOPD_LBU , IOPD_LHU , IOPD_LWR , IOPD_NULL,
IOPD_SB , IOPD_SH , IOPD_SWL , IOPD_SW , IOPD_NULL, IOPD_NULL, IOPD_SWR , IOPD_NULL,
IOPD_NULL , IOPD_NULL , IOPD_LWC2, IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL,
IOPD_NULL , IOPD_NULL , IOPD_SWC2, IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL
};
void (*IOP_DEBUG_SPC[64])(char *buf) = {
IOPD_SLL , IOPD_NULL , IOPD_SRL , IOPD_SRA , IOPD_SLLV , IOPD_NULL , IOPD_SRLV, IOPD_SRAV,
IOPD_JR , IOPD_JALR , IOPD_NULL, IOPD_NULL, IOPD_SYSCALL, IOPD_BREAK, IOPD_NULL, IOPD_NULL,
IOPD_MFHI, IOPD_MTHI , IOPD_MFLO, IOPD_MTLO, IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL,
IOPD_MULT, IOPD_MULTU, IOPD_DIV , IOPD_DIVU, IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL,
IOPD_ADD , IOPD_ADDU , IOPD_SUB , IOPD_SUBU, IOPD_AND , IOPD_OR , IOPD_XOR , IOPD_NOR ,
IOPD_NULL, IOPD_NULL , IOPD_SLT , IOPD_SLTU, IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL,
IOPD_NULL, IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL,
IOPD_NULL, IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL
};
void (*IOP_DEBUG_REG[32])(char *buf) = {
IOPD_BLTZ , IOPD_BGEZ , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL,
IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL,
IOPD_BLTZAL, IOPD_BGEZAL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL,
IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL
};
void (*IOP_DEBUG_CP0[32])(char *buf) = {
IOPD_MFC0, IOPD_NULL, IOPD_CFC0, IOPD_NULL, IOPD_MTC0, IOPD_NULL, IOPD_CTC0, IOPD_NULL,
IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL,
IOPD_RFE , IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL,
IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL
};
void (*IOP_DEBUG_CP2[64])(char *buf) = {
IOPD_BASIC, IOPD_RTPS , IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL , IOPD_NCLIP, IOPD_NULL,
IOPD_NULL , IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_OP , IOPD_NULL , IOPD_NULL , IOPD_NULL,
IOPD_DPCS , IOPD_INTPL, IOPD_MVMVA, IOPD_NCDS, IOPD_CDP , IOPD_NULL , IOPD_NCDT , IOPD_NULL,
IOPD_NULL , IOPD_NULL , IOPD_NULL , IOPD_NCCS, IOPD_CC , IOPD_NULL , IOPD_NCS , IOPD_NULL,
IOPD_NCT , IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL , IOPD_NULL , IOPD_NULL,
IOPD_SQR , IOPD_DCPL , IOPD_DPCT , IOPD_NULL, IOPD_NULL, IOPD_AVSZ3, IOPD_AVSZ4, IOPD_NULL,
IOPD_RTPT , IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_NULL , IOPD_NULL , IOPD_NULL,
IOPD_NULL , IOPD_NULL , IOPD_NULL , IOPD_NULL, IOPD_NULL, IOPD_GPF , IOPD_GPL , IOPD_NCCT
};
void (*IOP_DEBUG_CP2BSC[32])(char *buf) = {
IOPD_MFC2, IOPD_NULL, IOPD_CFC2, IOPD_NULL, IOPD_MTC2, IOPD_NULL, IOPD_CTC2, IOPD_NULL,
IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL,
IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL,
IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL, IOPD_NULL
};
static char dbuf2[1024];
static char obuf2[1024];
char *disR3000Fasm(u32 code, u32 pc) {
u32 scode = psxRegs.code;
IOP_opcode_addr = pc;
psxRegs.code = code;
IOP_DEBUG_BSC[(code) >> 26](dbuf2);
sprintf(obuf2, "%08lX:\t%s", pc, dbuf2);
psxRegs.code = scode;
return obuf2;
}
char *IOP_jump_decode(void)
{
static char buf[256];
unsigned long addr;
addr = (IOP_opcode_addr & 0xf0000000)|((psxRegs.code&0x3ffffff)<<2);
sprintf(buf, "0x%08lX", addr);
return buf;
}
char *IOP_offset_decode(void)
{
static char buf[256];
unsigned long addr;
addr = ((((short)( psxRegs.code & 0xFFFF) * 4) + IOP_opcode_addr + 4));
sprintf(buf, "0x%08lX", addr);
return buf;
}
//basic table
void IOPD_SPECIAL(char *buf){IOP_DEBUG_SPC[((psxRegs.code) & 0x3F)](buf);}
void IOPD_REGIMM(char *buf){IOP_DEBUG_REG[DECODE_RT_IOP](buf);}
void IOPD_J(char *buf) { sprintf(buf, "j\t%s", IOP_jump_decode());}
void IOPD_JAL(char *buf){sprintf(buf, "jal\t%s", IOP_jump_decode());}
void IOPD_BEQ(char *buf){sprintf(buf, "beq\t%s, %s, %s", GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP], IOP_offset_decode()); }
void IOPD_BNE(char *buf){sprintf(buf, "bne\t%s, %s, %s", GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP], IOP_offset_decode()); }
void IOPD_BLEZ(char *buf){sprintf(buf, "blez\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], IOP_offset_decode()); }
void IOPD_BGTZ(char *buf){sprintf(buf, "bgtz\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], IOP_offset_decode()); }
void IOPD_ADDI(char *buf){sprintf(buf, "addi\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP);}
void IOPD_ADDIU(char *buf){sprintf(buf, "addiu\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP);}
void IOPD_SLTI(char *buf){sprintf(buf, "slti\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP);}
void IOPD_SLTIU(char *buf){sprintf(buf, "sltiu\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP);}
void IOPD_ANDI(char *buf){sprintf(buf, "andi\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP);}
void IOPD_ORI(char *buf){sprintf(buf, "ori\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP); }
void IOPD_XORI(char *buf){sprintf(buf, "xori\t%s, %s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP], DECODE_IMMED_IOP); }
void IOPD_LUI(char *buf){sprintf(buf, "lui\t%s, 0x%04lX", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP); }
void IOPD_COP0(char *buf){IOP_DEBUG_CP0[DECODE_RS_IOP](buf);}
void IOPD_COP2(char *buf){IOP_DEBUG_CP2[((psxRegs.code) & 0x3F)](buf);}
void IOPD_LB(char *buf){sprintf(buf, "lb\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); }
void IOPD_LH(char *buf){sprintf(buf, "lh\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); }
void IOPD_LWL(char *buf){sprintf(buf, "lwl\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); }
void IOPD_LW(char *buf){sprintf(buf, "lw\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); }
void IOPD_LBU(char *buf){sprintf(buf, "lbu\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); }
void IOPD_LHU(char *buf){sprintf(buf, "lhu\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); }
void IOPD_LWR(char *buf){sprintf(buf, "lwr\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]);}
void IOPD_SB(char *buf){sprintf(buf, "sb\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]);}
void IOPD_SH(char *buf){sprintf(buf, "sh\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); }
void IOPD_SWL(char *buf){sprintf(buf, "swl\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); }
void IOPD_SW(char *buf){sprintf(buf, "sw\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]); }
void IOPD_SWR(char *buf){sprintf(buf, "swr\t%s, 0x%04lX(%s)", GPR_IOP_REG[DECODE_RT_IOP], DECODE_IMMED_IOP, GPR_IOP_REG[DECODE_RS_IOP]);}
void IOPD_LWC2(char *buf){strcpy(buf, "lwc2");}
void IOPD_SWC2(char *buf){strcpy(buf, "swc2");}
//special table
void IOPD_SLL(char *buf)
{
if (psxRegs.code == 0x00000000)
strcpy(buf, "nop");
else
sprintf(buf, "sll\t%s, %s, 0x%02lX", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RT_IOP], DECODE_SA_IOP);
}
void IOPD_SRL(char *buf){sprintf(buf, "srl\t%s, %s, 0x%02lX", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RT_IOP], DECODE_SA_IOP); }
void IOPD_SRA(char *buf){sprintf(buf, "sra\t%s, %s, 0x%02lX", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RT_IOP], DECODE_SA_IOP);}
void IOPD_SLLV(char *buf){sprintf(buf, "sllv\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP]); }
void IOPD_SRLV(char *buf){sprintf(buf, "srlv\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP]);}
void IOPD_SRAV(char *buf){sprintf(buf, "srav\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RT_IOP], GPR_IOP_REG[DECODE_RS_IOP]); }
void IOPD_JR(char *buf){sprintf(buf, "jr\t%s", GPR_IOP_REG[DECODE_RS_IOP]);}
void IOPD_JALR(char *buf)
{
int rd = DECODE_RD_IOP;
if (rd == 31)
sprintf(buf, "jalr\t%s", GPR_IOP_REG[DECODE_RS_IOP]);
else
sprintf(buf, "jalr\t%s, %s", GPR_IOP_REG[rd], GPR_IOP_REG[DECODE_RS_IOP]);
}
void IOPD_SYSCALL(char *buf){strcpy(buf, "syscall");}
void IOPD_BREAK(char *buf){strcpy(buf, "break");}
void IOPD_MFHI(char *buf){sprintf(buf, "mfhi\t%s", GPR_IOP_REG[DECODE_RD_IOP]); }
void IOPD_MTHI(char *buf){sprintf(buf, "mthi\t%s", GPR_IOP_REG[DECODE_RS_IOP]); }
void IOPD_MFLO(char *buf){sprintf(buf, "mflo\t%s", GPR_IOP_REG[DECODE_RD_IOP]); }
void IOPD_MTLO(char *buf){sprintf(buf, "mtlo\t%s", GPR_IOP_REG[DECODE_RS_IOP]); }
void IOPD_MULT(char *buf){sprintf(buf, "mult\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]);}
void IOPD_MULTU(char *buf){sprintf(buf, "multu\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]);}
void IOPD_DIV(char *buf){sprintf(buf, "div\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]);}
void IOPD_DIVU(char *buf){sprintf(buf, "divu\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); }
void IOPD_ADD(char *buf) { sprintf(buf, "add\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); }
void IOPD_ADDU(char *buf) { sprintf(buf, "addu\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); }
void IOPD_SUB(char *buf) { sprintf(buf, "sub\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); }
void IOPD_SUBU(char *buf) { sprintf(buf, "subu\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); }
void IOPD_AND(char *buf) { sprintf(buf, "and\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); }
void IOPD_OR(char *buf) { sprintf(buf, "or\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); }
void IOPD_XOR(char *buf) { sprintf(buf, "xor\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); }
void IOPD_NOR(char *buf) { sprintf(buf, "nor\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); }
void IOPD_SLT(char *buf) { sprintf(buf, "slt\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); }
void IOPD_SLTU(char *buf) { sprintf(buf, "sltu\t%s, %s, %s", GPR_IOP_REG[DECODE_RD_IOP], GPR_IOP_REG[DECODE_RS_IOP], GPR_IOP_REG[DECODE_RT_IOP]); }
//regimm
void IOPD_BLTZ(char *buf) { sprintf(buf, "bltz\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], IOP_offset_decode()); }
void IOPD_BGEZ(char *buf) { sprintf(buf, "bgez\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], IOP_offset_decode()); }
void IOPD_BLTZAL(char *buf) { sprintf(buf, "bltzal\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], IOP_offset_decode()); }
void IOPD_BGEZAL(char *buf) { sprintf(buf, "bgezal\t%s, %s", GPR_IOP_REG[DECODE_RS_IOP], IOP_offset_decode()); }
//cop0
void IOPD_MFC0(char *buf){ sprintf(buf, "mfc0\t%s, %s", GPR_IOP_REG[DECODE_RT_IOP], COP0_IOP_REG[DECODE_FS_IOP]); }
void IOPD_MTC0(char *buf){ sprintf(buf, "mtc0\t%s, %s", GPR_IOP_REG[DECODE_RT_IOP], COP0_IOP_REG[DECODE_FS_IOP]); }
void IOPD_CFC0(char *buf){ sprintf(buf, "cfc0\t%s, %s", GPR_IOP_REG[DECODE_RT_IOP], COP0_IOP_REG[DECODE_FS_IOP]); }
void IOPD_CTC0(char *buf){ sprintf(buf, "ctc0\t%s, %s", GPR_IOP_REG[DECODE_RT_IOP], COP0_IOP_REG[DECODE_FS_IOP]); }
void IOPD_RFE(char *buf){strcpy(buf, "rfe");}
//cop2
void IOPD_BASIC(char *buf){IOP_DEBUG_CP2BSC[DECODE_RS_IOP](buf);}
void IOPD_RTPS(char *buf){strcpy(buf, "rtps");}
void IOPD_NCLIP(char *buf){strcpy(buf, "nclip");}
void IOPD_OP(char *buf){strcpy(buf, "op");}
void IOPD_DPCS(char *buf){strcpy(buf, "dpcs");}
void IOPD_INTPL(char *buf){strcpy(buf, "intpl");}
void IOPD_MVMVA(char *buf){strcpy(buf, "mvmva");}
void IOPD_NCDS(char *buf){strcpy(buf, "ncds");}
void IOPD_CDP(char *buf){strcpy(buf, "cdp");}
void IOPD_NCDT(char *buf){strcpy(buf, "ncdt");}
void IOPD_NCCS(char *buf){strcpy(buf, "nccs");}
void IOPD_CC(char *buf){strcpy(buf, "cc");}
void IOPD_NCS(char *buf){strcpy(buf, "ncs");}
void IOPD_NCT(char *buf){strcpy(buf, "nct");}
void IOPD_SQR(char *buf){strcpy(buf, "sqr");}
void IOPD_DCPL(char *buf){strcpy(buf, "dcpl");}
void IOPD_DPCT(char *buf){strcpy(buf, "dpct");}
void IOPD_AVSZ3(char *buf){strcpy(buf, "avsz3");}
void IOPD_AVSZ4(char *buf){strcpy(buf, "avsz4");}
void IOPD_RTPT(char *buf){strcpy(buf, "rtpt");}
void IOPD_GPF(char *buf){strcpy(buf, "gpf");}
void IOPD_GPL(char *buf){strcpy(buf, "gpl");}
void IOPD_NCCT(char *buf){strcpy(buf, "ncct");}
//cop2 basic
void IOPD_MFC2(char *buf){strcpy(buf, "mfc2");}
void IOPD_CFC2(char *buf){strcpy(buf, "cfc2");}
void IOPD_MTC2(char *buf){strcpy(buf, "mtc2");}
void IOPD_CTC2(char *buf){strcpy(buf, "ctc2");}
//null
void IOPD_NULL(char *buf){strcpy(buf, "????");}

993
DebugTools/DisR5900.c Normal file
View File

@ -0,0 +1,993 @@
/* 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
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Debug.h"
#include "VU.h"
long jumpMode;
char ostr[1024];
// Names of registers
char *disRNameGPR[] = {
"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","fp", "ra", "hi", "lo"}; // lo,hi used in rec
char *disRNameCP0[] = {
"Index" , "Random" , "EntryLo0" , "EntryLo1", "Context" , "PageMask" , "Wired" , "*RES*",
"BadVAddr" , "Count" , "EntryHi" , "Compare" , "Status" , "Cause" , "ExceptPC" , "PRevID",
"Config" , "LLAddr" , "WatchLo" , "WatchHi" , "*RES*" , "*RES*" , "*RES*" , "Debug",
"DEPC" , "PerfCnt" , "ErrCtl" , "CacheErr", "TagLo" , "TagHi" , "ErrorEPC" , "DESAVE"};
char *disRNameCP1[] = {
"FPR0" , "FPR1" , "FPR2" , "FPR3" , "FPR4" , "FPR5" , "FPR6" , "FPR7",
"FPR8" , "FPR9" , "FPR10", "FPR11", "FPR12", "FPR13", "FPR14", "FPR15",
"FPR16", "FPR17", "FPR18", "FPR19", "FPR20", "FPR21", "FPR22", "FPR23",
"FPR24", "FPR25", "FPR26", "FPR27", "FPR28", "FPR29", "FPR30", "FPR31"};
char *disRNameCP1c[] = {
"FRevID", "*RES*", "*RES*", "*RES*", "*RES*", "*RES*", "*RES*", "*RES*",
"*RES*", "*RES*", "*RES*", "*RES*", "*RES*", "*RES*", "*RES*", "*RES*",
"*RES*", "*RES*", "*RES*", "*RES*", "*RES*", "*RES*", "*RES*", "*RES*",
"*RES*", "*RES*", "*RES*", "*RES*", "*RES*", "*RES*", "*RES*", "FStatus"};
char *disRNameCP2f[] = {
"VF00", "VF01", "VF02", "VF03", "VF04", "VF05", "VF06", "VF07",
"VF08", "VF09", "VF10", "VF11", "VF12", "VF13", "VF14", "VF15",
"VF16", "VF17", "VF18", "VF19", "VF20", "VF21", "VF22", "VF23",
"VF24", "VF25", "VF26", "VF27", "VF28", "VF29", "VF30", "VF31"};
char *disRNameCP2i[] = {
"VI00", "VI01", "VI02", "VI03", "VI04", "VI05", "VI06", "VI07",
"VI08", "VI09", "VI10", "VI11", "VI12", "VI13", "VI14", "VI15",
"Status", "MAC", "Clip", "*RES*", "R", "I", "Q", "*RES*",
"*RES*", "*RES*", "TPC", "CMSAR0", "FBRST", "VPU-STAT", "*RES*", "CMSAR1"};
char *CP2VFnames[] = { "x", "y", "z", "w" };
// Type deffinition of our functions
#define DisFInterface (u32 code, u32 pc)
#define DisFInterfaceT (u32, u32)
#define DisFInterfaceN (code, pc)
typedef char* (*TdisR5900F)DisFInterface;
// These macros are used to assemble the disassembler functions
#define MakeDisF(fn, b) \
char* fn DisFInterface { \
sprintf (ostr, "%8.8x %8.8x:", pc, code); \
b; /*ostr[(strlen(ostr) - 1)] = 0;*/ return ostr; \
}
#undef _Target_
#undef _Branch_
#undef _Funct_
#undef _Rd_
#undef _Rt_
#undef _Rs_
#undef _Sa_
#undef _Im_
#define _Funct_ ((code ) & 0x3F) // The funct part of the instruction register
#define _Rd_ ((code >> 11) & 0x1F) // The rd part of the instruction register
#define _Rt_ ((code >> 16) & 0x1F) // The rt part of the instruction register
#define _Rs_ ((code >> 21) & 0x1F) // The rs part of the instruction register
#define _Sa_ ((code >> 6) & 0x1F) // The sa part of the instruction register
#define _Im_ ( code & 0xFFFF) // The immediate part of the instruction register
#define _rRs_ cpuRegs.GPR.r[_Rs_].UL[1], cpuRegs.GPR.r[_Rs_].UL[0] // Rs register
#define _rRt_ cpuRegs.GPR.r[_Rt_].UL[1], cpuRegs.GPR.r[_Rt_].UL[0] // Rt register
#define _rRd_ cpuRegs.GPR.r[_Rd_].UL[1], cpuRegs.GPR.r[_Rd_].UL[0] // Rd register
#define _rSa_ cpuRegs.GPR.r[_Sa_].UL[1], cpuRegs.GPR.r[_Sa_].UL[0] // Sa register
#define _rFs_ cpuRegs.CP0.r[_Rd_] // Fs register
#define _rRs32_ cpuRegs.GPR.r[_Rs_].UL[0] // Rs register
#define _rRt32_ cpuRegs.GPR.r[_Rt_].UL[0] // Rt register
#define _rRd32_ cpuRegs.GPR.r[_Rd_].UL[0] // Rd register
#define _rSa32_ cpuRegs.GPR.r[_Sa_].UL[0] // Sa register
#define _nRs_ _rRs_, disRNameGPR[_Rs_]
#define _nRt_ _rRt_, disRNameGPR[_Rt_]
#define _nRd_ _rRd_, disRNameGPR[_Rd_]
#define _nSa_ _rSa_, disRNameGPR[_Sa_]
#define _nRd0_ _rFs_, disRNameCP0[_Rd_]
#define _nRs32_ _rRs32_, disRNameGPR[_Rs_]
#define _nRt32_ _rRt32_, disRNameGPR[_Rt_]
#define _nRd32_ _rRd32_, disRNameGPR[_Rd_]
#define _nSa32_ _rSa32_, disRNameGPR[_Sa_]
#define _I_ _Im_, _Im_
#define _Target_ ((pc & 0xf0000000) + ((code & 0x03ffffff) * 4))
#define _Branch_ (pc + 4 + ((short)_Im_ * 4))
#define _OfB_ _Im_, _nRs_
#define _Fsf_ ((code >> 21) & 0x03)
#define _Ftf_ ((code >> 23) & 0x03)
#define dName(i) sprintf(ostr, "%s %-7s,", ostr, i)
#define dGPR128(i) sprintf(ostr, "%s %8.8x_%8.8x_%8.8x_%8.8x (%s),", ostr, cpuRegs.GPR.r[i].UL[3], cpuRegs.GPR.r[i].UL[2], cpuRegs.GPR.r[i].UL[1], cpuRegs.GPR.r[i].UL[0], disRNameGPR[i])
#define dGPR64(i) sprintf(ostr, "%s %8.8x_%8.8x (%s),", ostr, cpuRegs.GPR.r[i].UL[1], cpuRegs.GPR.r[i].UL[0], disRNameGPR[i])
#define dGPR64U(i) sprintf(ostr, "%s %8.8x_%8.8x (%s),", ostr, cpuRegs.GPR.r[i].UL[3], cpuRegs.GPR.r[i].UL[2], disRNameGPR[i])
#define dGPR32(i) sprintf(ostr, "%s %8.8x (%s),", ostr, cpuRegs.GPR.r[i].UL[0], disRNameGPR[i])
#define dCP032(i) sprintf(ostr, "%s %8.8x (%s),", ostr, cpuRegs.CP0.r[i], disRNameCP0[i])
#define dCP132(i) sprintf(ostr, "%s %f (%s),", ostr, fpuRegs.fpr[i].f, disRNameCP1[i])
#define dCP1c32(i) sprintf(ostr, "%s %8.8x (%s),", ostr, fpuRegs.fprc[i], disRNameCP1c[i])
#define dCP1acc() sprintf(ostr, "%s %f (ACC),", ostr, fpuRegs.ACC.f)
#define dCP2128f(i) sprintf(ostr, "%s w=%f z=%f y=%f x=%f (%s),", ostr, VU0.VF[i].f.w, VU0.VF[i].f.z, VU0.VF[i].f.y, VU0.VF[i].f.x, disRNameCP2f[i])
#define dCP232x(i) sprintf(ostr, "%s x=%f (%s),", ostr, VU0.VF[i].f.x, disRNameCP2f[i])
#define dCP232y(i) sprintf(ostr, "%s y=%f (%s),", ostr, VU0.VF[i].f.y, disRNameCP2f[i])
#define dCP232z(i) sprintf(ostr, "%s z=%f (%s),", ostr, VU0.VF[i].f.z, disRNameCP2f[i])
#define dCP232w(i) sprintf(ostr, "%s w=%f (%s),", ostr, VU0.VF[i].f.w, disRNameCP2f[i])
#define dCP2ACCf() sprintf(ostr, "%s w=%f z=%f y=%f x=%f (ACC),", ostr, VU0.ACC.f.w, VU0.ACC.f.z, VU0.ACC.f.y, VU0.ACC.f.x)
#define dCP232i(i) sprintf(ostr, "%s %8.8x (%s),", ostr, VU0.VI[i].UL, disRNameCP2i[i])
#define dCP232iF(i) sprintf(ostr, "%s %f (%s),", ostr, VU0.VI[i].F, disRNameCP2i[i])
#define dCP232f(i, j) sprintf(ostr, "%s Q %s=%f (%s),", ostr, CP2VFnames[j], VU0.VF[i].F[j], disRNameCP2f[i])
#define dHI64() sprintf(ostr, "%s %8.8x_%8.8x (%s),", ostr, cpuRegs.HI.UL[1], cpuRegs.HI.UL[0], "hi")
#define dLO64() sprintf(ostr, "%s %8.8x_%8.8x (%s),", ostr, cpuRegs.LO.UL[1], cpuRegs.LO.UL[0], "lo")
#define dImm() sprintf(ostr, "%s %4.4x (%d),", ostr, _Im_, _Im_)
#define dTarget() sprintf(ostr, "%s %8.8x,", ostr, _Target_)
#define dSa() sprintf(ostr, "%s %2.2x (%d),", ostr, _Sa_, _Sa_)
#define dSa32() sprintf(ostr, "%s %2.2x (%d),", ostr, _Sa_+32, _Sa_+32)
#define dOfB() sprintf(ostr, "%s %4.4x (%8.8x (%s)),", ostr, _Im_, cpuRegs.GPR.r[_Rs_].UL[0], disRNameGPR[_Rs_])
#define dOffset() sprintf(ostr, "%s %8.8x,", ostr, _Branch_)
#define dCode() sprintf(ostr, "%s %8.8x,", ostr, (code >> 6) & 0xffffff)
#define dSaR() sprintf(ostr, "%s %8.8x,", ostr, cpuRegs.sa)
typedef struct {
u32 addr;
char name[32];
} sSymbol;
static sSymbol *dSyms = NULL;
static int nSyms = 0;
void disR5900AddSym(u32 addr, char *name) {
dSyms = (sSymbol*)realloc(dSyms, sizeof(sSymbol) * (nSyms+1));
if (dSyms == NULL) return;
dSyms[nSyms].addr = addr;
strncpy(dSyms[nSyms].name, name, 32);
nSyms++;
}
void disR5900FreeSyms() {
if (dSyms != NULL) { free(dSyms); dSyms = NULL; }
nSyms = 0;
}
char *disR5900GetSym(u32 addr) {
int i;
if (dSyms == NULL) return NULL;
for (i=0; i<nSyms; i++)
if (dSyms[i].addr == addr) return dSyms[i].name;
return NULL;
}
char *disR5900GetUpperSym(u32 addr) {
u32 laddr;
int i, j=-1;
if (dSyms == NULL) return NULL;
for (i=0, laddr=0; i<nSyms; i++) {
if (dSyms[i].addr < addr && dSyms[i].addr > laddr) {
laddr = dSyms[i].addr;
j = i;
}
}
if (j == -1) return NULL;
return dSyms[j].name;
}
#define dFindSym(i) { \
char *str = disR5900GetSym(i); \
if (str != NULL) sprintf(ostr, "%s %s", ostr, str); \
}
/*********************************************************
* Arithmetic with immediate operand *
* Format: OP rt, rs, immediate *
*********************************************************/
MakeDisF(disADDI, dName("ADDI"); dGPR64(_Rt_); dGPR32(_Rs_); dImm();)
MakeDisF(disADDIU, dName("ADDIU"); dGPR64(_Rt_); dGPR32(_Rs_); dImm();)
MakeDisF(disANDI, dName("ANDI"); dGPR64(_Rt_); dGPR64(_Rs_); dImm();)
MakeDisF(disORI, dName("ORI"); dGPR64(_Rt_); dGPR64(_Rs_); dImm();)
MakeDisF(disSLTI, dName("SLTI"); dGPR64(_Rt_); dGPR64(_Rs_); dImm();)
MakeDisF(disSLTIU, dName("SLTIU"); dGPR64(_Rt_); dGPR64(_Rs_); dImm();)
MakeDisF(disXORI, dName("XORI"); dGPR64(_Rt_); dGPR64(_Rs_); dImm();)
MakeDisF(disDADDI, dName("DADDI"); dGPR64(_Rt_); dGPR64(_Rs_); dImm();)
MakeDisF(disDADDIU, dName("DADDIU"); dGPR64(_Rt_); dGPR64(_Rs_); dImm();)
/*********************************************************
* Register arithmetic *
* Format: OP rd, rs, rt *
*********************************************************/
MakeDisF(disADD, dName("ADD"); dGPR64(_Rd_); dGPR32(_Rs_); dGPR32(_Rt_);)
MakeDisF(disADDU, dName("ADDU"); dGPR64(_Rd_); dGPR32(_Rs_); dGPR32(_Rt_);)
MakeDisF(disDADD, dName("DADD"); dGPR64(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disDADDU, dName("DADDU"); dGPR64(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disSUB, dName("SUB"); dGPR64(_Rd_); dGPR32(_Rs_); dGPR32(_Rt_);)
MakeDisF(disSUBU, dName("SUBU"); dGPR64(_Rd_); dGPR32(_Rs_); dGPR32(_Rt_);)
MakeDisF(disDSUB, dName("DSUB"); dGPR64(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disDSUBU, dName("DSDBU"); dGPR64(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disAND, dName("AND"); dGPR64(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disOR, dName("OR"); dGPR64(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disXOR, dName("XOR"); dGPR64(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disNOR, dName("NOR"); dGPR64(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disSLT, dName("SLT"); dGPR64(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disSLTU, dName("SLTU"); dGPR64(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
/*********************************************************
* Jump to target *
* Format: OP target *
*********************************************************/
MakeDisF(disJ, dName("J"); dTarget(); dFindSym(_Target_);)
MakeDisF(disJAL, dName("JAL"); dTarget(); dGPR32(31); dFindSym(_Target_);)
/*********************************************************
* Register jump *
* Format: OP rs, rd *
*********************************************************/
MakeDisF(disJR, dName("JR"); dGPR32(_Rs_); dFindSym(cpuRegs.GPR.r[_Rs_].UL[0]);)
MakeDisF(disJALR, dName("JALR"); dGPR32(_Rs_); dGPR32(_Rd_); dFindSym(cpuRegs.GPR.r[_Rs_].UL[0]);)
/*********************************************************
* Register mult/div & Register trap logic *
* Format: OP rs, rt *
*********************************************************/
MakeDisF(disDIV, dName("DIV"); dGPR32(_Rs_); dGPR32(_Rt_);)
MakeDisF(disDIVU, dName("DIVU"); dGPR32(_Rs_); dGPR32(_Rt_);)
MakeDisF(disMULT, dName("MULT"); dGPR32(_Rs_); dGPR32(_Rt_); dGPR32(_Rd_);)
MakeDisF(disMULTU, dName("MULTU"); dGPR32(_Rs_); dGPR32(_Rt_); dGPR32(_Rd_);)
/*********************************************************
* Load higher 16 bits of the first word in GPR with imm *
* Format: OP rt, immediate *
*********************************************************/
MakeDisF(disLUI, dName("LUI"); dGPR64(_Rt_); dImm();)
/*********************************************************
* Move from HI/LO to GPR *
* Format: OP rd *
*********************************************************/
MakeDisF(disMFHI, dName("MFHI"); dGPR64(_Rd_); dHI64();)
MakeDisF(disMFLO, dName("MFLO"); dGPR64(_Rd_); dLO64();)
/*********************************************************
* Move to GPR to HI/LO & Register jump *
* Format: OP rs *
*********************************************************/
MakeDisF(disMTHI, dName("MTHI"); dHI64(); dGPR64(_Rs_);)
MakeDisF(disMTLO, dName("MTLO"); dLO64(); dGPR64(_Rs_);)
/*********************************************************
* Shift arithmetic with constant shift *
* Format: OP rd, rt, sa *
*********************************************************/
MakeDisF(disSLL, if (code) { dName("SLL"); dGPR64(_Rd_); dGPR32(_Rt_); dSa(); } else { dName("NOP"); })
MakeDisF(disDSLL, dName("DSLL"); dGPR64(_Rd_); dGPR64(_Rt_); dSa();)
MakeDisF(disDSLL32, dName("DSLL32"); dGPR64(_Rd_); dGPR64(_Rt_); dSa32();)
MakeDisF(disSRA, dName("SRA"); dGPR64(_Rd_); dGPR32(_Rt_); dSa();)
MakeDisF(disDSRA, dName("DSRA"); dGPR64(_Rd_); dGPR64(_Rt_); dSa();)
MakeDisF(disDSRA32, dName("DSRA32"); dGPR64(_Rd_); dGPR64(_Rt_); dSa32();)
MakeDisF(disSRL, dName("SRL"); dGPR64(_Rd_); dGPR32(_Rt_); dSa();)
MakeDisF(disDSRL, dName("DSRL"); dGPR64(_Rd_); dGPR64(_Rt_); dSa();)
MakeDisF(disDSRL32, dName("DSRL32"); dGPR64(_Rd_); dGPR64(_Rt_); dSa32();)
/*********************************************************
* Shift arithmetic with variant register shift *
* Format: OP rd, rt, rs *
*********************************************************/
MakeDisF(disSLLV, dName("SLLV"); dGPR64(_Rd_); dGPR32(_Rt_); dGPR32(_Rs_);)
MakeDisF(disDSLLV, dName("DSLLV"); dGPR64(_Rd_); dGPR64(_Rt_); dGPR32(_Rs_);)
MakeDisF(disSRAV, dName("SRAV"); dGPR64(_Rd_); dGPR32(_Rt_); dGPR32(_Rs_);)
MakeDisF(disDSRAV, dName("DSRAV"); dGPR64(_Rd_); dGPR64(_Rt_); dGPR32(_Rs_);)
MakeDisF(disSRLV, dName("SRLV"); dGPR64(_Rd_); dGPR32(_Rt_); dGPR32(_Rs_);)
MakeDisF(disDSRLV, dName("DSRLV"); dGPR64(_Rd_); dGPR64(_Rt_); dGPR32(_Rs_);)
/*********************************************************
* Load and store for GPR *
* Format: OP rt, offset(base) *
*********************************************************/
MakeDisF(disLB, dName("LB"); dGPR64(_Rt_); dOfB();)
MakeDisF(disLBU, dName("LBU"); dGPR64(_Rt_); dOfB();)
MakeDisF(disLH, dName("LH"); dGPR64(_Rt_); dOfB();)
MakeDisF(disLHU, dName("LHU"); dGPR64(_Rt_); dOfB();)
MakeDisF(disLW, dName("LW"); dGPR64(_Rt_); dOfB();)
MakeDisF(disLWU, dName("LWU"); dGPR64(_Rt_); dOfB();)
MakeDisF(disLWL, dName("LWL"); dGPR64(_Rt_); dOfB();)
MakeDisF(disLWR, dName("LWR"); dGPR64(_Rt_); dOfB();)
MakeDisF(disLD, dName("LD"); dGPR64(_Rt_); dOfB();)
MakeDisF(disLDL, dName("LDL"); dGPR64(_Rt_); dOfB();)
MakeDisF(disLDR, dName("LDR"); dGPR64(_Rt_); dOfB();)
MakeDisF(disLQ, dName("LQ"); dGPR128(_Rt_); dOfB();)
MakeDisF(disSB, dName("SB"); dGPR64(_Rt_); dOfB();)
MakeDisF(disSH, dName("SH"); dGPR64(_Rt_); dOfB();)
MakeDisF(disSW, dName("SW"); dGPR64(_Rt_); dOfB();)
MakeDisF(disSWL, dName("SWL"); dGPR64(_Rt_); dOfB();)
MakeDisF(disSWR, dName("SWR"); dGPR64(_Rt_); dOfB();)
MakeDisF(disSD, dName("SD"); dGPR64(_Rt_); dOfB();)
MakeDisF(disSDL, dName("SDL"); dGPR64(_Rt_); dOfB();)
MakeDisF(disSDR, dName("SDR"); dGPR64(_Rt_); dOfB();)
MakeDisF(disSQ, dName("SQ"); dGPR128(_Rt_); dOfB();)
/*********************************************************
* Register branch logic *
* Format: OP rs, rt, offset *
*********************************************************/
MakeDisF(disBEQ, dName("BEQ"); dGPR64(_Rs_); dGPR64(_Rt_); dOffset();)
MakeDisF(disBNE, dName("BNE"); dGPR64(_Rs_); dGPR64(_Rt_); dOffset();)
/*********************************************************
* Moves between GPR and COPx *
* Format: OP rt, rd *
*********************************************************/
MakeDisF(disMFC0, dName("MFC0"); dGPR32(_Rt_); dCP032(_Rd_);)
MakeDisF(disMTC0, dName("MTC0"); dCP032(_Rd_); dGPR32(_Rt_);)
/*********************************************************
* Register branch logic *
* Format: OP rs, offset *
*********************************************************/
MakeDisF(disBGEZ, dName("BGEZ"); dGPR64(_Rs_); dOffset();)
MakeDisF(disBGEZAL, dName("BGEZAL"); dGPR64(_Rs_); dOffset();)
MakeDisF(disBGTZ, dName("BGTZ"); dGPR64(_Rs_); dOffset();)
MakeDisF(disBLEZ, dName("BLEZ"); dGPR64(_Rs_); dOffset();)
MakeDisF(disBLTZ, dName("BLTZ"); dGPR64(_Rs_); dOffset();)
MakeDisF(disBLTZAL, dName("BLTZAL"); dGPR64(_Rs_); dOffset();)
/*********************************************************
* Register branch logic Likely *
* Format: OP rs, offset *
*********************************************************/
MakeDisF(disBEQL, dName("BEQL"); dGPR64(_Rs_); dGPR64(_Rt_); dOffset();)
MakeDisF(disBNEL, dName("BNEL"); dGPR64(_Rs_); dGPR64(_Rt_); dOffset();)
MakeDisF(disBLEZL, dName("BLEZL"); dGPR64(_Rs_); dOffset();)
MakeDisF(disBGTZL, dName("BGTZL"); dGPR64(_Rs_); dOffset();)
MakeDisF(disBLTZL, dName("BLTZL"); dGPR64(_Rs_); dOffset();)
MakeDisF(disBGEZL, dName("BGEZL"); dGPR64(_Rs_); dOffset();)
MakeDisF(disBLTZALL, dName("BLTZALL"); dGPR64(_Rs_); dOffset();)
MakeDisF(disBGEZALL, dName("BGEZALL"); dGPR64(_Rs_); dOffset();)
/*********************************************************
* COP0 opcodes *
* *
*********************************************************/
MakeDisF(disBC0F, dName("BC0F"); dOffset();)
MakeDisF(disBC0T, dName("BC0T"); dOffset();)
MakeDisF(disBC0FL, dName("BC0FL"); dOffset();)
MakeDisF(disBC0TL, dName("BC0TL"); dOffset();)
MakeDisF(disTLBR, dName("TLBR");)
MakeDisF(disTLBWI, dName("TLBWI");)
MakeDisF(disTLBWR, dName("TLBWR");)
MakeDisF(disTLBP, dName("TLBP");)
MakeDisF(disERET, dName("ERET");)
MakeDisF(disEI, dName("EI");)
MakeDisF(disDI, dName("DI");)
/*********************************************************
* COP1 opcodes *
* *
*********************************************************/
#define _Ft_ _Rt_
#define _Fs_ _Rd_
#define _Fd_ _Sa_
MakeDisF(disMFC1, dName("MFC1"); dGPR64(_Rt_); dCP132(_Fs_);)
MakeDisF(disCFC1, dName("CFC1"); dGPR64(_Rt_); dCP1c32(_Fs_);)
MakeDisF(disMTC1, dName("MTC1"); dCP132(_Fs_); dGPR64(_Rt_);)
MakeDisF(disCTC1, dName("CTC1"); dCP1c32(_Fs_); dGPR64(_Rt_);)
MakeDisF(disBC1F, dName("BC1F");)
MakeDisF(disBC1T, dName("BC1T");)
MakeDisF(disBC1FL, dName("BC1FL");)
MakeDisF(disBC1TL, dName("BC1TL");)
MakeDisF(disADDs, dName("ADDs"); dCP132(_Fd_); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disSUBs, dName("SUBs"); dCP132(_Fd_); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disMULs, dName("MULs"); dCP132(_Fd_); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disDIVs, dName("DIVs"); dCP132(_Fd_); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disSQRTs, dName("SQRTs"); dCP132(_Fd_); dCP132(_Ft_);)
MakeDisF(disABSs, dName("ABSs"); dCP132(_Fd_); dCP132(_Fs_);)
MakeDisF(disMOVs, dName("MOVs"); dCP132(_Fd_); dCP132(_Fs_);)
MakeDisF(disNEGs, dName("NEGs"); dCP132(_Fd_); dCP132(_Fs_);)
MakeDisF(disRSQRTs, dName("RSQRTs"); dCP132(_Fd_); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disADDAs, dName("ADDAs"); dCP1acc(); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disSUBAs, dName("SUBAs"); dCP1acc(); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disMULAs, dName("MULAs"); dCP1acc(); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disMADDs, dName("MADDs"); dCP132(_Fd_); dCP1acc(); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disMSUBs, dName("MSUBs"); dCP132(_Fd_); dCP1acc(); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disMADDAs, dName("MADDAs"); dCP1acc(); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disMSUBAs, dName("MSUBAs"); dCP1acc(); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disCVTWs, dName("CVTWs"); dCP132(_Fd_); dCP132(_Fs_);)
MakeDisF(disMAXs, dName("MAXs"); dCP132(_Fd_); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disMINs, dName("MINs"); dCP132(_Fd_); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disCFs, dName("CFs"); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disCEQs, dName("CEQs"); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disCLTs, dName("CLTs"); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disCLEs, dName("CLEs"); dCP132(_Fs_); dCP132(_Ft_);)
MakeDisF(disCVTSw, dName("CVTSw"); dCP132(_Fd_); dCP132(_Fs_);)
/*********************************************************
* Load and store for COP1 *
* Format: OP rt, offset(base) *
*********************************************************/
MakeDisF(disLWC1, dName("LWC1"); dCP132(_Rt_); dOffset();)
MakeDisF(disSWC1, dName("SWC1"); dCP132(_Rt_); dOffset();)
/*********************************************************
* Conditional Move *
* Format: OP rd, rs, rt *
*********************************************************/
MakeDisF(disMOVZ, dName("MOVZ"); dGPR64(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disMOVN, dName("MOVN"); dGPR64(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
/*********************************************************
* MMI opcodes *
* *
*********************************************************/
MakeDisF(disMULT1, dName("MULT1");)
MakeDisF(disMULTU1, dName("MULTU1");)
/*********************************************************
* MMI0 opcodes *
* *
*********************************************************/
MakeDisF(disPADDW, dName("PADDW");)
MakeDisF(disPADDH, dName("PADDH");)
MakeDisF(disPADDB, dName("PADDB");)
MakeDisF(disPADDSW, dName("PADDSW");)
MakeDisF(disPADDSH, dName("PADDSH");)
MakeDisF(disPADDSB, dName("PADDSB");)
MakeDisF(disPSUBW, dName("PSUBW");)
MakeDisF(disPSUBH, dName("PSUBH");)
MakeDisF(disPSUBB, dName("PSUBB");)
MakeDisF(disPSUBSW, dName("PSUBSW");)
MakeDisF(disPSUBSH, dName("PSUBSH");)
MakeDisF(disPSUBSB, dName("PSUBSB");)
MakeDisF(disPCGTW, dName("PCGTW");)
MakeDisF(disPCGTH, dName("PCGTH");)
MakeDisF(disPCGTB, dName("PCGTB");)
MakeDisF(disPMAXW, dName("PMAXW");)
MakeDisF(disPMAXH, dName("PMAXH");)
MakeDisF(disPEXTLW, dName("PEXTLW"); dGPR128(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disPEXTLH, dName("PEXTLH"); dGPR128(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disPEXTLB, dName("PEXTLB");)
MakeDisF(disPEXTS, dName("PEXTS");)
MakeDisF(disPPACW, dName("PPACW");)
MakeDisF(disPPACH, dName("PPACH");)
MakeDisF(disPPACB, dName("PPACB");)
MakeDisF(disPPACS, dName("PPACS");)
/*********************************************************
* MMI1 opcodes *
* *
*********************************************************/
MakeDisF(disPADSBH, dName("PADSBH");)
MakeDisF(disPABSW, dName("PABSW");)
MakeDisF(disPABSH, dName("PABSH");)
MakeDisF(disPCEQW, dName("PCEQW");)
MakeDisF(disPCEQH, dName("PCEQH");)
MakeDisF(disPCEQB, dName("PCEQB");)
MakeDisF(disPMINW, dName("PMINW");)
MakeDisF(disPMINH, dName("PMINH");)
MakeDisF(disPADDUW, dName("PADDUW");)
MakeDisF(disPADDUH, dName("PADDUH");)
MakeDisF(disPADDUB, dName("PADDUB");)
MakeDisF(disPSUBUW, dName("PSUBUW");)
MakeDisF(disPSUBUH, dName("PSUBUH");)
MakeDisF(disPSUBUB, dName("PSUBUB");)
MakeDisF(disPEXTUW, dName("PEXTUW"); dGPR128(_Rd_); dGPR64U(_Rs_); dGPR64U(_Rt_);)
MakeDisF(disPEXTUH, dName("PEXTUH"); dGPR128(_Rd_); dGPR64U(_Rs_); dGPR64U(_Rt_);)
MakeDisF(disPEXTUB, dName("PEXTUB");)
MakeDisF(disQFSRV, dName("QFSRV");)
/*********************************************************
* MMI2 opcodes *
* *
*********************************************************/
MakeDisF(disPMADDW, dName("PMADDW");)
MakeDisF(disPMADDH, dName("PMADDH");)
MakeDisF(disPSLLVW, dName("PSLLVW");)
MakeDisF(disPSRLVW, dName("PSRLVW");)
MakeDisF(disPMFHI, dName("PMFHI");)
MakeDisF(disPMFLO, dName("PMFLO");)
MakeDisF(disPINTH, dName("PINTH");)
MakeDisF(disPMULTW, dName("PMULTW");)
MakeDisF(disPMULTH, dName("PMULTH");)
MakeDisF(disPDIVW, dName("PDIVW");)
MakeDisF(disPDIVH, dName("PDIVH");)
MakeDisF(disPCPYLD, dName("PCPYLD"); dGPR128(_Rd_); dGPR128(_Rs_); dGPR128(_Rt_);)
MakeDisF(disPAND, dName("PAND"); dGPR128(_Rd_); dGPR128(_Rs_); dGPR128(_Rt_);)
MakeDisF(disPXOR, dName("PXOR"); dGPR128(_Rd_); dGPR128(_Rs_); dGPR128(_Rt_);)
MakeDisF(disPMSUBW, dName("PMSUBW");)
MakeDisF(disPMSUBH, dName("PMSUBH");)
MakeDisF(disPHMADH, dName("PHMADH");)
MakeDisF(disPHMSBH, dName("PHMSBH");)
MakeDisF(disPEXEW, dName("PEXEW");)
MakeDisF(disPEXEH, dName("PEXEH");)
MakeDisF(disPREVH, dName("PREVH");)
MakeDisF(disPDIVBW, dName("PDIVBW");)
MakeDisF(disPROT3W, dName("PROT3W");)
/*********************************************************
* MMI3 opcodes *
* *
*********************************************************/
MakeDisF(disPMADDUW, dName("PMADDUW");)
MakeDisF(disPSRAVW, dName("PSRAVW");)
MakeDisF(disPMTHI, dName("PMTHI");)
MakeDisF(disPMTLO, dName("PMTLO");)
MakeDisF(disPINTEH, dName("PINTEH");)
MakeDisF(disPMULTUW, dName("PMULTUW");)
MakeDisF(disPDIVUW, dName("PDIVUW");)
MakeDisF(disPCPYUD, dName("PCPYUD"); dGPR128(_Rd_); dGPR128(_Rt_); dGPR128(_Rs_);)
MakeDisF(disPOR, dName("POR"); dGPR128(_Rd_); dGPR128(_Rs_); dGPR128(_Rt_);)
MakeDisF(disPNOR, dName("PNOR"); dGPR128(_Rd_); dGPR128(_Rs_); dGPR128(_Rt_);)
MakeDisF(disPEXCH, dName("PEXCH");)
MakeDisF(disPEXCW, dName("PEXCW");)
MakeDisF(disPCPYH, dName("PCPYH"); dGPR128(_Rd_); dGPR128(_Rt_);)
/*********************************************************
* COP2 opcodes *
* *
*********************************************************/
#define _Ft_ _Rt_
#define _Fs_ _Rd_
#define _Fd_ _Sa_
#define _X code>>24
#define _Y code>>23
#define _Z code>>22
#define _W code>>21
MakeDisF(disLQC2, dName("LQC2"); dCP2128f(_Rt_); dOfB();)
MakeDisF(disSQC2, dName("SQC2"); dCP2128f(_Rt_); dOfB();)
MakeDisF(disQMFC2, dName("QMFC2");)
MakeDisF(disQMTC2, dName("QMTC2");)
MakeDisF(disCFC2, dName("CFC2"); dGPR32(_Rt_); dCP232i(_Fs_);)
MakeDisF(disCTC2, dName("CTC2"); dCP232i(_Fs_); dGPR32(_Rt_);)
MakeDisF(disBC2F, dName("BC2F");)
MakeDisF(disBC2T, dName("BC2T");)
MakeDisF(disBC2FL, dName("BC2FL");)
MakeDisF(disBC2TL, dName("BC2TL");)
// SPEC1
MakeDisF(disVADD, dName("VADD");)
MakeDisF(disVADDx, dName("VADDx"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);)
MakeDisF(disVADDy, dName("VADDy"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);)
MakeDisF(disVADDz, dName("VADDz"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);)
MakeDisF(disVADDw, dName("VADDw"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);)
MakeDisF(disVADDq, dName("VADDq"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232iF(REG_Q);)
MakeDisF(disVADDi, dName("VADDi"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232iF(REG_I);)
MakeDisF(disVSUB, dName("VSUB");)
MakeDisF(disVSUBx, dName("VSUBx"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);)
MakeDisF(disVSUBy, dName("VSUBy"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);)
MakeDisF(disVSUBz, dName("VSUBz"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);)
MakeDisF(disVSUBw, dName("VSUBw"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);)
MakeDisF(disVSUBq, dName("VSUBq");)
MakeDisF(disVSUBi, dName("VSUBi");)
MakeDisF(disVMADD, dName("VMADD");)
MakeDisF(disVMADDx, dName("VMADDx"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232x(_Ft_);)
MakeDisF(disVMADDy, dName("VMADDy"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232y(_Ft_);)
MakeDisF(disVMADDz, dName("VMADDz"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232z(_Ft_);)
MakeDisF(disVMADDw, dName("VMADDw"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232w(_Ft_);)
MakeDisF(disVMADDq, dName("VMADDq");)
MakeDisF(disVMADDi, dName("VMADDi");)
MakeDisF(disVMSUB, dName("VMSUB");)
MakeDisF(disVMSUBx, dName("VMSUBx");)
MakeDisF(disVMSUBy, dName("VMSUBy");)
MakeDisF(disVMSUBz, dName("VMSUBz");)
MakeDisF(disVMSUBw, dName("VMSUBw");)
MakeDisF(disVMSUBq, dName("VMSUBq");)
MakeDisF(disVMSUBi, dName("VMSUBi");)
MakeDisF(disVMAX, dName("VMAX");)
MakeDisF(disVMAXx, dName("VMAXx");)
MakeDisF(disVMAXy, dName("VMAXy");)
MakeDisF(disVMAXz, dName("VMAXz");)
MakeDisF(disVMAXw, dName("VMAXw");)
MakeDisF(disVMAXi, dName("VMAXi");)
MakeDisF(disVMINI, dName("VMINI");)
MakeDisF(disVMINIx, dName("VMINIx");)
MakeDisF(disVMINIy, dName("VMINIy");)
MakeDisF(disVMINIz, dName("VMINIz");)
MakeDisF(disVMINIw, dName("VMINIw");)
MakeDisF(disVMINIi, dName("VMINIi");)
MakeDisF(disVMUL, dName("VMUL");)
MakeDisF(disVMULx, dName("VMULx");)
MakeDisF(disVMULy, dName("VMULy");)
MakeDisF(disVMULz, dName("VMULz");)
MakeDisF(disVMULw, dName("VMULw");)
MakeDisF(disVMULq, dName("VMULq");)
MakeDisF(disVMULi, dName("VMULi");)
MakeDisF(disVIADD, dName("VIADD");)
MakeDisF(disVIADDI, dName("VIADDI");)
MakeDisF(disVISUB, dName("VISUB");)
MakeDisF(disVIAND, dName("VIAND");)
MakeDisF(disVIOR, dName("VIOR");)
MakeDisF(disVOPMSUB, dName("VOPMSUB");)
MakeDisF(disVCALLMS, dName("VCALLMS");)
MakeDisF(disVCALLMSR, dName("VCALLMSR");)
// SPEC2
MakeDisF(disVADDA, dName("VADDA");)
MakeDisF(disVADDAx, dName("VADDAx");)
MakeDisF(disVADDAy, dName("VADDAy");)
MakeDisF(disVADDAz, dName("VADDAz");)
MakeDisF(disVADDAw, dName("VADDAw");)
MakeDisF(disVADDAq, dName("VADDAq");)
MakeDisF(disVADDAi, dName("VADDAi");)
MakeDisF(disVMADDA, dName("VMADDA");)
MakeDisF(disVMADDAx, dName("VMADDAx"); dCP2ACCf(); dCP2128f(_Fs_); dCP232x(_Ft_);)
MakeDisF(disVMADDAy, dName("VMADDAy"); dCP2ACCf(); dCP2128f(_Fs_); dCP232y(_Ft_);)
MakeDisF(disVMADDAz, dName("VMADDAz"); dCP2ACCf(); dCP2128f(_Fs_); dCP232z(_Ft_);)
MakeDisF(disVMADDAw, dName("VMADDAw"); dCP2ACCf(); dCP2128f(_Fs_); dCP232w(_Ft_);)
MakeDisF(disVMADDAq, dName("VMADDAq");)
MakeDisF(disVMADDAi, dName("VMADDAi");)
MakeDisF(disVSUBAx, dName("VSUBAx");)
MakeDisF(disVSUBAy, dName("VSUBAy");)
MakeDisF(disVSUBAz, dName("VSUBAz");)
MakeDisF(disVSUBAw, dName("VSUBAw");)
MakeDisF(disVMSUBAx, dName("VMSUBAx");)
MakeDisF(disVMSUBAy, dName("VMSUBAy");)
MakeDisF(disVMSUBAz, dName("VMSUBAz");)
MakeDisF(disVMSUBAw, dName("VMSUBAw");)
MakeDisF(disVITOF0, dName("VITOF0");)
MakeDisF(disVITOF4, dName("VITOF4");)
MakeDisF(disVITOF12, dName("VITOF12");)
MakeDisF(disVITOF15, dName("VITOF15");)
MakeDisF(disVFTOI0, dName("VFTOI0");)
MakeDisF(disVFTOI4, dName("VFTOI4");)
MakeDisF(disVFTOI12, dName("VFTOI12");)
MakeDisF(disVFTOI15, dName("VFTOI15");)
MakeDisF(disVMULA, dName("VMULA");)
MakeDisF(disVMULAx, dName("VMULAx"); dCP2ACCf(); dCP2128f(_Fs_); dCP232x(_Ft_);)
MakeDisF(disVMULAy, dName("VMULAy");)
MakeDisF(disVMULAz, dName("VMULAz");)
MakeDisF(disVMULAw, dName("VMULAw");)
MakeDisF(disVMOVE, dName("VMOVE"); dCP2128f(_Ft_); dCP2128f(_Fs_);)
MakeDisF(disVMR32, dName("VMR32");)
MakeDisF(disVDIV, dName("VDIV");)
MakeDisF(disVSQRT, dName("VSQRT"); dCP232f(_Ft_, _Ftf_);)
MakeDisF(disVRSQRT, dName("VRSQRT");)
MakeDisF(disVRNEXT, dName("VRNEXT");)
MakeDisF(disVRGET, dName("VRGET");)
MakeDisF(disVRINIT, dName("VRINIT");)
MakeDisF(disVRXOR, dName("VRXOR");)
MakeDisF(disVWAITQ, dName("VWAITQ");)
/*********************************************************
* Special purpose instructions *
* Format: OP *
*********************************************************/
MakeDisF(disSYNC, dName("SYNC");)
MakeDisF(disBREAK, dName("BREAK");)
MakeDisF(disSYSCALL, dName("SYSCALL"); dCode();)
MakeDisF(disCACHE, sprintf(ostr, "%s %-7s, %x,", ostr, "CACHE", _Rt_); dOfB();)
MakeDisF(disPREF, dName("PREF");)
MakeDisF(disMFSA, dName("MFSA"); dGPR64(_Rd_); dSaR();)
MakeDisF(disMTSA, dName("MTSA"); dGPR64(_Rs_); dSaR();)
MakeDisF(disMTSAB, dName("MTSAB");dGPR64(_Rs_); dImm();)
MakeDisF(disMTSAH, dName("MTSAH");dGPR64(_Rs_); dImm();)
MakeDisF(disTGE, dName("TGE"); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disTGEU, dName("TGEU"); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disTLT, dName("TLT"); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disTLTU, dName("TLTU"); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disTEQ, dName("TEQ"); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disTNE, dName("TNE"); dGPR64(_Rs_); dGPR64(_Rt_);)
MakeDisF(disTGEI, dName("TGEI"); dGPR64(_Rs_); dImm();)
MakeDisF(disTGEIU, dName("TGEIU"); dGPR64(_Rs_); dImm();)
MakeDisF(disTLTI, dName("TLTI"); dGPR64(_Rs_); dImm();)
MakeDisF(disTLTIU, dName("TLTIU"); dGPR64(_Rs_); dImm();)
MakeDisF(disTEQI, dName("TEQI"); dGPR64(_Rs_); dImm();)
MakeDisF(disTNEI, dName("TNEI"); dGPR64(_Rs_); dImm();)
/*********************************************************
* Unknow instruction (would generate an exception) *
* Format: ? *
*********************************************************/
MakeDisF(disNULL, dName("*** Bad OP ***");)
TdisR5900F disR5900_MMI0[] = { // Subset of disMMI0
disPADDW, disPSUBW, disPCGTW, disPMAXW,
disPADDH, disPSUBH, disPCGTH, disPMAXH,
disPADDB, disPSUBB, disPCGTB, disNULL,
disNULL, disNULL, disNULL, disNULL,
disPADDSW, disPSUBSW, disPEXTLW, disPPACW,
disPADDSH, disPSUBSH, disPEXTLH, disPPACH,
disPADDSB, disPSUBSB, disPEXTLB, disPPACB,
disNULL, disNULL, disPEXTS, disPPACS};
MakeDisF(disMMI0, disR5900_MMI0[_Sa_] DisFInterfaceN)
TdisR5900F disR5900_MMI1[] = { // Subset of disMMI1
disNULL, disPABSW, disPCEQW, disPMINW,
disPADSBH, disPABSH, disPCEQH, disPMINH,
disNULL, disNULL, disPCEQB, disNULL,
disNULL, disNULL, disNULL, disNULL,
disPADDUW, disPSUBUW, disPEXTUW, disNULL,
disPADDUH, disPSUBUH, disPEXTUH, disNULL,
disPADDUB, disPSUBUB, disPEXTUB, disQFSRV,
disNULL, disNULL, disNULL, disNULL};
MakeDisF(disMMI1, disR5900_MMI1[_Sa_] DisFInterfaceN)
TdisR5900F disR5900_MMI2[] = { // Subset of disMMI2
disPMADDW, disNULL, disPSLLVW, disPSRLVW,
disPMSUBW, disNULL, disNULL, disNULL,
disPMFHI, disPMFLO, disPINTH, disNULL,
disPMULTW, disPDIVW, disPCPYLD, disNULL,
disPMADDH, disPHMADH, disPAND, disPXOR,
disPMSUBH, disPHMSBH, disNULL, disNULL,
disNULL, disNULL, disPEXEH, disPREVH,
disPMULTH, disPDIVBW, disPEXEW, disPROT3W};
MakeDisF(disMMI2, disR5900_MMI2[_Sa_] DisFInterfaceN)
TdisR5900F disR5900_MMI3[] = { // Subset of disMMI3
disPMADDUW, disNULL, disNULL, disPSRAVW,
disNULL, disNULL, disNULL, disNULL,
disPMTHI, disPMTLO, disPINTEH, disNULL,
disPMULTUW, disPDIVUW, disPCPYUD, disNULL,
disNULL, disNULL, disPOR, disPNOR,
disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disPEXCH, disPCPYH,
disNULL, disNULL, disPEXCW, disNULL};
MakeDisF(disMMI3, disR5900_MMI3[_Sa_] DisFInterfaceN)
TdisR5900F disR5900_MMI[] = { // Subset of disMMI
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disMMI0, disMMI2, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disMULT1, disMULTU1, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disMMI1, disMMI3, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
MakeDisF(disMMI, disR5900_MMI[_Funct_] DisFInterfaceN)
TdisR5900F disR5900_COP0_BC0[] = { //subset of disCOP0 BC
disBC0F, disBC0T, disBC0FL, disBC0TL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL , disNULL , disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL , disNULL , disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL , disNULL , disNULL, disNULL, disNULL, disNULL,
};
MakeDisF(disCOP0_BC0, disR5900_COP0_BC0[_Rt_] DisFInterfaceN)
TdisR5900F disR5900_COP0_Func[] = { //subset of disCOP0 Function
disNULL, disTLBR, disTLBWI, disNULL, disNULL, disNULL, disTLBWR, disNULL,
disTLBP, disNULL, disNULL , disNULL, disNULL, disNULL, disNULL , disNULL,
disNULL, disNULL, disNULL , disNULL, disNULL, disNULL, disNULL , disNULL,
disERET, disNULL, disNULL , disNULL, disNULL, disNULL, disNULL , disNULL,
disNULL, disNULL, disNULL , disNULL, disNULL, disNULL, disNULL , disNULL,
disNULL, disNULL, disNULL , disNULL, disNULL, disNULL, disNULL , disNULL,
disNULL, disNULL, disNULL , disNULL, disNULL, disNULL, disNULL , disNULL,
disEI , disDI , disNULL , disNULL, disNULL, disNULL, disNULL , disNULL
};
MakeDisF(disCOP0_Func, disR5900_COP0_Func[_Funct_] DisFInterfaceN)
TdisR5900F disR5900_COP0[] = { // Subset of disCOP0
disMFC0, disNULL, disNULL, disNULL, disMTC0, disNULL, disNULL, disNULL,
disCOP0_BC0, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disCOP0_Func, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
MakeDisF(disCOP0, disR5900_COP0[_Rs_] DisFInterfaceN)
TdisR5900F disR5900_COP1_S[] = { //subset of disCOP1 S
disADDs, disSUBs, disMULs, disDIVs, disSQRTs, disABSs, disMOVs, disNEGs,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disRSQRTs, disNULL,
disADDAs, disSUBAs, disMULAs, disNULL, disMADDs, disMSUBs, disMADDAs, disMSUBAs,
disNULL, disNULL, disNULL, disNULL, disCVTWs, disNULL, disNULL, disNULL,
disMINs, disMAXs, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disCFs, disNULL, disCEQs, disNULL, disCLTs, disNULL, disCLEs, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
};
MakeDisF(disCOP1_S, disR5900_COP1_S[_Funct_] DisFInterfaceN)
TdisR5900F disR5900_COP1_W[] = { //subset of disCOP1 W
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disCVTSw, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
};
MakeDisF(disCOP1_W, disR5900_COP1_W[_Funct_] DisFInterfaceN)
TdisR5900F disR5900_COP1_BC1[] = { //subset of disCOP1 BC
disBC1F, disBC1T, disBC1FL, disBC1TL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL , disNULL , disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL , disNULL , disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL , disNULL , disNULL, disNULL, disNULL, disNULL,
};
MakeDisF(disCOP1_BC1, disR5900_COP1_BC1[_Rt_] DisFInterfaceN)
TdisR5900F disR5900_COP1[] = { // Subset of disCOP1
disMFC1, disNULL, disCFC1, disNULL, disMTC1, disNULL, disCTC1, disNULL,
disCOP1_BC1, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disCOP1_S, disNULL, disNULL, disNULL, disCOP1_W, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
MakeDisF(disCOP1, disR5900_COP1[_Rs_] DisFInterfaceN)
TdisR5900F disR5900_COP2_SPEC2[] = { //subset of disCOP2 SPEC2
disVADDAx, disVADDAy, disVADDAz, disVADDAw, disVSUBAx, disVSUBAy, disVSUBAz, disVSUBAw,
disVMADDAx, disVMADDAy, disVMADDAz, disVMADDAw, disVMSUBAx, disVMSUBAy, disVMSUBAz, disVMSUBAw,
disVITOF0, disVITOF4, disVITOF12, disVITOF15, disVFTOI0, disVFTOI4, disVFTOI12, disVFTOI15,
disVMULAx, disVMULAy, disVMULAz, disVMULAw, disNULL, disNULL, disNULL, disNULL,
disVADDAq, disVMADDAq, disVADDAi, disVMADDAi, disNULL, disNULL, disNULL, disNULL,
disVADDA, disVMADDA, disVMULA, disNULL, disNULL, disNULL, disNULL, disNULL,
disVMOVE, disVMR32, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disVDIV, disVSQRT, disVRSQRT, disVWAITQ, disNULL, disNULL, disNULL, disNULL,
disVRNEXT, disVRGET, disVRINIT, disVRXOR, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
};
MakeDisF(disCOP2_SPEC2, disR5900_COP2_SPEC2[(code & 0x3) | ((code >> 4) & 0x7c)] DisFInterfaceN)
TdisR5900F disR5900_COP2_SPEC1[] = { //subset of disCOP2 SPEC1
disVADDx, disVADDy, disVADDz, disVADDw, disVSUBx, disVSUBy, disVSUBz, disVSUBw,
disVMADDx, disVMADDy, disVMADDz, disVMADDw, disVMSUBx, disVMSUBy, disVMSUBz, disVMSUBw,
disVMAXx, disVMAXy, disVMAXz, disVMAXw, disVMINIx, disVMINIy, disVMINIz, disVMINIw,
disVMULx, disVMULy, disVMULz, disVMULw, disVMULq, disVMAXi, disVMULi, disVMINIi,
disVADDq, disVMADDq, disVADDi, disVMADDi, disVSUBq, disVMSUBq, disVSUBi, disVMSUBi,
disVADD, disVMADD, disVMUL, disVMAX, disVSUB, disVMSUB, disVOPMSUB, disVMINI,
disVIADD, disVISUB, disVIADDI, disNULL, disVIAND, disVIOR, disNULL, disNULL,
disVCALLMS, disVCALLMSR, disNULL, disNULL, disCOP2_SPEC2, disCOP2_SPEC2, disCOP2_SPEC2, disCOP2_SPEC2,
};
MakeDisF(disCOP2_SPEC1, disR5900_COP2_SPEC1[_Funct_] DisFInterfaceN)
TdisR5900F disR5900_COP2_BC2[] = { //subset of disCOP2 BC
disBC2F, disBC2T, disBC2FL, disBC2TL, disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL , disNULL , disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL , disNULL , disNULL, disNULL, disNULL, disNULL,
disNULL, disNULL, disNULL , disNULL , disNULL, disNULL, disNULL, disNULL,
};
MakeDisF(disCOP2_BC2, disR5900_COP2_BC2[_Rt_] DisFInterfaceN)
TdisR5900F disR5900_COP2[] = { // Subset of disCOP2
disNULL, disQMFC2, disCFC2, disNULL, disNULL, disQMTC2, disCTC2, disNULL,
disCOP2_BC2, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
disCOP2_SPEC1, disCOP2_SPEC1, disCOP2_SPEC1, disCOP2_SPEC1, disCOP2_SPEC1, disCOP2_SPEC1, disCOP2_SPEC1, disCOP2_SPEC1,
disCOP2_SPEC1, disCOP2_SPEC1, disCOP2_SPEC1, disCOP2_SPEC1, disCOP2_SPEC1, disCOP2_SPEC1, disCOP2_SPEC1, disCOP2_SPEC1};
MakeDisF(disCOP2, disR5900_COP2[_Rs_] DisFInterfaceN)
TdisR5900F disR5900_REGIMM[] = { // Subset of disREGIMM
disBLTZ, disBGEZ, disBLTZL, disBGEZL, disNULL, disNULL, disNULL, disNULL,
disTGEI, disTGEIU, disTLTI, disTLTIU, disTEQI, disNULL, disTNEI, disNULL,
disBLTZAL, disBGEZAL, disBLTZALL, disBGEZALL, disNULL, disNULL, disNULL, disNULL,
disMTSAB, disMTSAH , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
MakeDisF(disREGIMM, disR5900_REGIMM[_Rt_] DisFInterfaceN)
TdisR5900F disR5900_SPECIAL[] = {
disSLL, disNULL, disSRL, disSRA, disSLLV, disNULL, disSRLV, disSRAV,
disJR, disJALR, disMOVZ, disMOVN, disSYSCALL, disBREAK,disNULL, disSYNC,
disMFHI, disMTHI, disMFLO, disMTLO, disDSLLV, disNULL, disDSRLV, disDSRAV,
disMULT, disMULTU,disDIV, disDIVU, disNULL, disNULL, disNULL, disNULL,
disADD, disADDU, disSUB, disSUBU, disAND, disOR, disXOR, disNOR,
disMFSA , disMTSA, disSLT, disSLTU, disDADD, disDADDU,disDSUB, disDSUBU,
disTGE, disTGEU, disTLT, disTLTU, disTEQ, disNULL, disTNE, disNULL,
disDSLL, disNULL, disDSRL, disDSRA, disDSLL32, disNULL, disDSRL32,disDSRA32 };
MakeDisF(disSPECIAL, disR5900_SPECIAL[_Funct_] DisFInterfaceN)
TdisR5900F disR5900[] = {
disSPECIAL, disREGIMM, disJ , disJAL , disBEQ , disBNE , disBLEZ , disBGTZ ,
disADDI , disADDIU , disSLTI, disSLTIU, disANDI, disORI , disXORI , disLUI ,
disCOP0 , disCOP1 , disCOP2, disNULL , disBEQL, disBNEL, disBLEZL, disBGTZL,
disDADDI , disDADDIU, disLDL , disLDR , disMMI , disNULL, disLQ , disSQ ,
disLB , disLH , disLWL , disLW , disLBU , disLHU , disLWR , disLWU ,
disSB , disSH , disSWL , disSW , disSDL , disSDR , disSWR , disCACHE,
disNULL , disLWC1 , disNULL, disPREF , disNULL, disNULL, disLQC2 , disLD ,
disNULL , disSWC1 , disNULL, disNULL , disNULL, disNULL, disSQC2 , disSD };
MakeDisF(disR5900F, disR5900[code >> 26] DisFInterfaceN)

1679
DebugTools/DisR5900asm.c Normal file

File diff suppressed because it is too large Load Diff

84
DebugTools/DisVU0Micro.c Normal file
View File

@ -0,0 +1,84 @@
/* 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
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Debug.h"
char ostr[1024];
// Type deffinition of our functions
#define DisFInterface (u32 code, u32 pc)
#define DisFInterfaceT (u32, u32)
#define DisFInterfaceN (code, pc)
typedef char* (*TdisR5900F)DisFInterface;
// These macros are used to assemble the disassembler functions
#define MakeDisF(fn, b) \
char* fn DisFInterface { \
sprintf (ostr, "%8.8x %8.8x:", pc, code); \
b; /*ostr[(strlen(ostr) - 1)] = 0;*/ return ostr; \
}
//Lower/Upper instructions can use that..
#define _Ft_ ((code >> 16) & 0x1F) // The rt part of the instruction register
#define _Fs_ ((code >> 11) & 0x1F) // The rd part of the instruction register
#define _Fd_ ((code >> 6) & 0x1F) // The sa part of the instruction register
#define dName(i) sprintf(ostr, "%s %-7s,", ostr, i)
#define dNameU(i) { char op[256]; sprintf(op, "%s.%s%s%s%s", i, _X ? "x" : "", _Y ? "y" : "", _Z ? "z" : "", _W ? "w" : ""); sprintf(ostr, "%s %-7s,", ostr, op); }
#define dCP2128f(i) sprintf(ostr, "%s w=%f z=%f y=%f x=%f (%s),", ostr, VU0.VF[i].f.w, VU0.VF[i].f.z, VU0.VF[i].f.y, VU0.VF[i].f.x, disRNameCP2f[i])
#define dCP232x(i) sprintf(ostr, "%s x=%f (%s),", ostr, VU0.VF[i].f.x, disRNameCP2f[i])
#define dCP232y(i) sprintf(ostr, "%s y=%f (%s),", ostr, VU0.VF[i].f.y, disRNameCP2f[i])
#define dCP232z(i) sprintf(ostr, "%s z=%f (%s),", ostr, VU0.VF[i].f.z, disRNameCP2f[i])
#define dCP232w(i) sprintf(ostr, "%s w=%f (%s),", ostr, VU0.VF[i].f.w, disRNameCP2f[i])
#define dCP2ACCf() sprintf(ostr, "%s w=%f z=%f y=%f x=%f (ACC),", ostr, VU0.ACC.f.w, VU0.ACC.f.z, VU0.ACC.f.y, VU0.ACC.f.x)
#define dCP232i(i) sprintf(ostr, "%s %8.8x (%s),", ostr, VU0.VI[i].UL, disRNameCP2i[i])
#define dCP232iF(i) sprintf(ostr, "%s %f (%s),", ostr, VU0.VI[i].F, disRNameCP2i[i])
#define dCP232f(i, j) sprintf(ostr, "%s Q %s=%f (%s),", ostr, CP2VFnames[j], VU0.VF[i].F[j], disRNameCP2f[i])
#define dImm5() sprintf(ostr, "%s %d,", ostr, (code >> 6) & 0x1f)
#define dImm11() sprintf(ostr, "%s %d,", ostr, code & 0x7ff)
#define dImm15() sprintf(ostr, "%s %d,", ostr, ( ( code >> 10 ) & 0x7800 ) | ( code & 0x7ff ))
#define _X ((code>>24) & 0x1)
#define _Y ((code>>23) & 0x1)
#define _Z ((code>>22) & 0x1)
#define _W ((code>>21) & 0x1)
#define _Fsf_ ((code >> 21) & 0x03)
#define _Ftf_ ((code >> 23) & 0x03)
/*********************************************************
* Unknow instruction (would generate an exception) *
* Format: ? *
*********************************************************/
extern char* disNULL DisFInterface;
#include "DisVUmicro.h"
#include "DisVUops.h"
#include "VU.h"
_disVUOpcodes(VU0);
_disVUTables(VU0);

123
DebugTools/DisVU1Micro.c Normal file
View File

@ -0,0 +1,123 @@
/* 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
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Debug.h"
#include "VUmicro.h"
char ostr[1024];
// Type deffinition of our functions
#define DisFInterface (u32 code, u32 pc)
#define DisFInterfaceT (u32, u32)
#define DisFInterfaceN (code, pc)
typedef char* (*TdisR5900F)DisFInterface;
// These macros are used to assemble the disassembler functions
#define MakeDisF(fn, b) \
char* fn DisFInterface { \
if( !CHECK_VU1REC ) sprintf (ostr, "%8.8x %8.8x:", pc, code); \
else ostr[0] = 0; \
b; /*ostr[(strlen(ostr) - 1)] = 0;*/ return ostr; \
}
//Lower/Upper instructions can use that..
#define _Ft_ ((code >> 16) & 0x1F) // The rt part of the instruction register
#define _Fs_ ((code >> 11) & 0x1F) // The rd part of the instruction register
#define _Fd_ ((code >> 6) & 0x1F) // The sa part of the instruction register
#define dName(i) sprintf(ostr, "%s %-12s", ostr, i); \
#define dNameU(i) { \
char op[256]; sprintf(op, "%s.%s%s%s%s", i, _X ? "x" : "", _Y ? "y" : "", _Z ? "z" : "", _W ? "w" : ""); \
sprintf(ostr, "%s %-12s", ostr, op); \
}
#define dCP2128f(i) { \
if( CHECK_VU1REC ) sprintf(ostr, "%s %s,", ostr, disRNameCP2f[i]); \
else sprintf(ostr, "%s w=%f (%8.8x) z=%f (%8.8x) y=%f (%8.8xl) x=%f (%8.8x) (%s),", ostr, VU1.VF[i].f.w, VU1.VF[i].UL[3], VU1.VF[i].f.z, VU1.VF[i].UL[2], VU1.VF[i].f.y, VU1.VF[i].UL[1], VU1.VF[i].f.x, VU1.VF[i].UL[0], disRNameCP2f[i]); \
} \
#define dCP232x(i) { \
if( CHECK_VU1REC ) sprintf(ostr, "%s %s,", ostr, disRNameCP2f[i]); \
else sprintf(ostr, "%s x=%f (%s),", ostr, VU1.VF[i].f.x, disRNameCP2f[i]); \
} \
#define dCP232y(i) { \
if( CHECK_VU1REC ) sprintf(ostr, "%s %s,", ostr, disRNameCP2f[i]); \
else sprintf(ostr, "%s y=%f (%s),", ostr, VU1.VF[i].f.y, disRNameCP2f[i]); \
} \
#define dCP232z(i) { \
if( CHECK_VU1REC ) sprintf(ostr, "%s %s,", ostr, disRNameCP2f[i]); \
else sprintf(ostr, "%s z=%f (%s),", ostr, VU1.VF[i].f.z, disRNameCP2f[i]); \
}
#define dCP232w(i) { \
if( CHECK_VU1REC ) sprintf(ostr, "%s %s,", ostr, disRNameCP2f[i]); \
else sprintf(ostr, "%s w=%f (%s),", ostr, VU1.VF[i].f.w, disRNameCP2f[i]); \
}
#define dCP2ACCf() { \
if( CHECK_VU1REC ) sprintf(ostr, "%s ACC,", ostr); \
else sprintf(ostr, "%s w=%f z=%f y=%f x=%f (ACC),", ostr, VU1.ACC.f.w, VU1.ACC.f.z, VU1.ACC.f.y, VU1.ACC.f.x); \
} \
#define dCP232i(i) { \
if( CHECK_VU1REC ) sprintf(ostr, "%s %s,", ostr, disRNameCP2i[i]); \
else sprintf(ostr, "%s %8.8x (%s),", ostr, VU1.VI[i].UL, disRNameCP2i[i]); \
}
#define dCP232iF(i) { \
if( CHECK_VU1REC ) sprintf(ostr, "%s %s,", ostr, disRNameCP2i[i]); \
else sprintf(ostr, "%s %f (%s),", ostr, VU1.VI[i].F, disRNameCP2i[i]); \
}
#define dCP232f(i, j) { \
if( CHECK_VU1REC ) sprintf(ostr, "%s %s%s,", ostr, disRNameCP2f[i], CP2VFnames[j]); \
else sprintf(ostr, "%s %s=%f (%s),", ostr, CP2VFnames[j], VU1.VF[i].F[j], disRNameCP2f[i]); \
}
#define dImm5() sprintf(ostr, "%s %d,", ostr, (s16)((code >> 6) & 0x10 ? 0xfff0 | ((code >> 6) & 0xf) : (code >> 6) & 0xf))
#define dImm11() sprintf(ostr, "%s %d,", ostr, (s16)(code & 0x400 ? 0xfc00 | (code & 0x3ff) : code & 0x3ff))
#define dImm15() sprintf(ostr, "%s %d,", ostr, ( ( code >> 10 ) & 0x7800 ) | ( code & 0x7ff ))
#define _X ((code>>24) & 0x1)
#define _Y ((code>>23) & 0x1)
#define _Z ((code>>22) & 0x1)
#define _W ((code>>21) & 0x1)
#define _Fsf_ ((code >> 21) & 0x03)
#define _Ftf_ ((code >> 23) & 0x03)
/*********************************************************
* Unknow instruction (would generate an exception) *
* Format: ? *
*********************************************************/
extern char* disNULL DisFInterface;
#include "DisVUmicro.h"
#include "DisVUops.h"
_disVUOpcodes(VU1);
_disVUTables(VU1);

209
DebugTools/DisVUmicro.h Normal file
View File

@ -0,0 +1,209 @@
/* 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
*/
#define _disVUTables(VU) \
\
/****************/ \
/* LOWER TABLES */ \
/****************/ \
\
TdisR5900F dis##VU##LowerOP_T3_00_OPCODE[32] = { \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
dis##VU##MI_MOVE , dis##VU##MI_LQI , dis##VU##MI_DIV , dis##VU##MI_MTIR, \
dis##VU##MI_RNEXT , disNULL , disNULL , disNULL , /* 0x10 */ \
disNULL , disNULL , disNULL , disNULL , \
disNULL , dis##VU##MI_MFP , dis##VU##MI_XTOP , dis##VU##MI_XGKICK, \
dis##VU##MI_ESADD , dis##VU##MI_EATANxy, dis##VU##MI_ESQRT, dis##VU##MI_ESIN, \
}; \
\
TdisR5900F dis##VU##LowerOP_T3_01_OPCODE[32] = { \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
dis##VU##MI_MR32 , dis##VU##MI_SQI , dis##VU##MI_SQRT , dis##VU##MI_MFIR, \
dis##VU##MI_RGET , disNULL , disNULL , disNULL , /* 0x10 */ \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , dis##VU##MI_XITOP, disNULL , \
dis##VU##MI_ERSADD, dis##VU##MI_EATANxz, dis##VU##MI_ERSQRT, dis##VU##MI_EATAN, \
}; \
\
TdisR5900F dis##VU##LowerOP_T3_10_OPCODE[32] = { \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , dis##VU##MI_LQD , dis##VU##MI_RSQRT, dis##VU##MI_ILWR, \
dis##VU##MI_RINIT , disNULL , disNULL , disNULL , /* 0x10 */ \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
dis##VU##MI_ELENG , dis##VU##MI_ESUM , dis##VU##MI_ERCPR, dis##VU##MI_EEXP, \
}; \
\
TdisR5900F dis##VU##LowerOP_T3_11_OPCODE[32] = { \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , dis##VU##MI_SQD , dis##VU##MI_WAITQ, dis##VU##MI_ISWR, \
dis##VU##MI_RXOR , disNULL , disNULL , disNULL , /* 0x10 */ \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
dis##VU##MI_ERLENG, disNULL , dis##VU##MI_WAITP, disNULL , \
}; \
\
MakeDisF(dis##VU##LowerOP_T3_00, dis##VU##LowerOP_T3_00_OPCODE[_Fd_] DisFInterfaceN) \
MakeDisF(dis##VU##LowerOP_T3_01, dis##VU##LowerOP_T3_01_OPCODE[_Fd_] DisFInterfaceN) \
MakeDisF(dis##VU##LowerOP_T3_10, dis##VU##LowerOP_T3_10_OPCODE[_Fd_] DisFInterfaceN) \
MakeDisF(dis##VU##LowerOP_T3_11, dis##VU##LowerOP_T3_11_OPCODE[_Fd_] DisFInterfaceN) \
\
TdisR5900F dis##VU##LowerOP_OPCODE[64] = { \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , /* 0x10 */ \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , /* 0x20 */ \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
dis##VU##MI_IADD , dis##VU##MI_ISUB , dis##VU##MI_IADDI, disNULL , /* 0x30 */ \
dis##VU##MI_IAND , dis##VU##MI_IOR , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
dis##VU##LowerOP_T3_00, dis##VU##LowerOP_T3_01, dis##VU##LowerOP_T3_10, dis##VU##LowerOP_T3_11, \
}; \
\
MakeDisF(dis##VU##LowerOP, dis##VU##LowerOP_OPCODE[code & 0x3f] DisFInterfaceN) \
\
TdisR5900F dis##VU##MicroL[] = { \
dis##VU##MI_LQ , dis##VU##MI_SQ , disNULL , disNULL, \
dis##VU##MI_ILW , dis##VU##MI_ISW , disNULL , disNULL, \
dis##VU##MI_IADDIU, dis##VU##MI_ISUBIU, disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, \
dis##VU##MI_FCEQ , dis##VU##MI_FCSET , dis##VU##MI_FCAND, dis##VU##MI_FCOR, /* 0x10 */ \
dis##VU##MI_FSEQ , dis##VU##MI_FSSET , dis##VU##MI_FSAND, dis##VU##MI_FSOR, \
dis##VU##MI_FMEQ , disNULL , dis##VU##MI_FMAND, dis##VU##MI_FMOR, \
dis##VU##MI_FCGET , disNULL , disNULL , disNULL, \
dis##VU##MI_B , dis##VU##MI_BAL , disNULL , disNULL, /* 0x20 */ \
dis##VU##MI_JR , dis##VU##MI_JALR , disNULL , disNULL, \
dis##VU##MI_IBEQ , dis##VU##MI_IBNE , disNULL , disNULL, \
dis##VU##MI_IBLTZ , dis##VU##MI_IBGTZ , dis##VU##MI_IBLEZ, dis##VU##MI_IBGEZ, \
disNULL , disNULL , disNULL , disNULL, /* 0x30 */ \
disNULL , disNULL , disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, \
dis##VU##LowerOP , disNULL , disNULL , disNULL, /* 0x40*/ \
disNULL , disNULL , disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, /* 0x50 */ \
disNULL , disNULL , disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, /* 0x60 */ \
disNULL , disNULL , disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, /* 0x70 */ \
disNULL , disNULL , disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, \
disNULL , disNULL , disNULL , disNULL, \
}; \
\
\
MakeDisF(dis##VU##MicroLF, dis##VU##MicroL[code >> 25] DisFInterfaceN) \
\
\
/****************/ \
/* UPPER TABLES */ \
/****************/ \
\
TdisR5900F dis##VU##_UPPER_FD_00_TABLE[32] = { \
dis##VU##MI_ADDAx, dis##VU##MI_SUBx , dis##VU##MI_MADDAx, dis##VU##MI_MSUBAx, \
dis##VU##MI_ITOF0, dis##VU##MI_FTOI0, dis##VU##MI_MULAx , dis##VU##MI_MULAq , \
dis##VU##MI_ADDAq, dis##VU##MI_SUBAq, dis##VU##MI_ADDA , dis##VU##MI_SUBA , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
}; \
\
TdisR5900F dis##VU##_UPPER_FD_01_TABLE[32] = { \
dis##VU##MI_ADDAy , dis##VU##MI_SUBy , dis##VU##MI_MADDAy, dis##VU##MI_MSUBAy, \
dis##VU##MI_ITOF4 , dis##VU##MI_FTOI4 , dis##VU##MI_MULAy , dis##VU##MI_ABS , \
dis##VU##MI_MADDAq, dis##VU##MI_MSUBAq, dis##VU##MI_MADDA , dis##VU##MI_MSUBA , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
}; \
\
TdisR5900F dis##VU##_UPPER_FD_10_TABLE[32] = { \
dis##VU##MI_ADDAz , dis##VU##MI_SUBz , dis##VU##MI_MADDAz, dis##VU##MI_MSUBAz, \
dis##VU##MI_ITOF12, dis##VU##MI_FTOI12, dis##VU##MI_MULAz , dis##VU##MI_MULAi , \
dis##VU##MI_MADDAi, dis##VU##MI_SUBAi , dis##VU##MI_MULA , dis##VU##MI_OPMULA, \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
}; \
\
TdisR5900F dis##VU##_UPPER_FD_11_TABLE[32] = { \
dis##VU##MI_ADDAw , dis##VU##MI_SUBw , dis##VU##MI_MADDAw, dis##VU##MI_MSUBAw, \
dis##VU##MI_ITOF15, dis##VU##MI_FTOI15, dis##VU##MI_MULAw , dis##VU##MI_CLIP , \
dis##VU##MI_MADDAi, dis##VU##MI_MSUBAi, disNULL , dis##VU##MI_NOP , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
}; \
\
MakeDisF(dis##VU##_UPPER_FD_00, dis##VU##_UPPER_FD_00_TABLE[_Fd_] DisFInterfaceN) \
MakeDisF(dis##VU##_UPPER_FD_01, dis##VU##_UPPER_FD_01_TABLE[_Fd_] DisFInterfaceN) \
MakeDisF(dis##VU##_UPPER_FD_10, dis##VU##_UPPER_FD_10_TABLE[_Fd_] DisFInterfaceN) \
MakeDisF(dis##VU##_UPPER_FD_11, dis##VU##_UPPER_FD_11_TABLE[_Fd_] DisFInterfaceN) \
\
TdisR5900F dis##VU##MicroU[] = { \
dis##VU##MI_ADDx , dis##VU##MI_ADDy , dis##VU##MI_ADDz , dis##VU##MI_ADDw, \
dis##VU##MI_SUBx , dis##VU##MI_SUBy , dis##VU##MI_SUBz , dis##VU##MI_SUBw, \
dis##VU##MI_MADDx , dis##VU##MI_MADDy , dis##VU##MI_MADDz , dis##VU##MI_MADDw, \
dis##VU##MI_MSUBx , dis##VU##MI_MSUBy , dis##VU##MI_MSUBz , dis##VU##MI_MSUBw, \
dis##VU##MI_MAXx , dis##VU##MI_MAXy , dis##VU##MI_MAXz , dis##VU##MI_MAXw, /* 0x10 */ \
dis##VU##MI_MINIx , dis##VU##MI_MINIy , dis##VU##MI_MINIz , dis##VU##MI_MINIw, \
dis##VU##MI_MULx , dis##VU##MI_MULy , dis##VU##MI_MULz , dis##VU##MI_MULw, \
dis##VU##MI_MULq , dis##VU##MI_MAXi , dis##VU##MI_MULi , dis##VU##MI_MINIi, \
dis##VU##MI_ADDq , dis##VU##MI_MADDq , dis##VU##MI_ADDi , dis##VU##MI_MADDi, /* 0x20 */ \
dis##VU##MI_SUBq , dis##VU##MI_MSUBq , dis##VU##MI_SUBi , dis##VU##MI_MSUBi, \
dis##VU##MI_ADD , dis##VU##MI_MADD , dis##VU##MI_MUL , dis##VU##MI_MAX, \
dis##VU##MI_SUB , dis##VU##MI_MSUB , dis##VU##MI_OPMSUB, dis##VU##MI_MINI, \
disNULL , disNULL , disNULL , disNULL , /* 0x30 */ \
disNULL , disNULL , disNULL , disNULL , \
disNULL , disNULL , disNULL , disNULL , \
dis##VU##_UPPER_FD_00, dis##VU##_UPPER_FD_01, dis##VU##_UPPER_FD_10, dis##VU##_UPPER_FD_11, \
}; \
\
\
MakeDisF(dis##VU##MicroUF, dis##VU##MicroU[code & 0x3f] DisFInterfaceN) \

197
DebugTools/DisVUops.h Normal file
View File

@ -0,0 +1,197 @@
/* 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
*/
#define _disVUOpcodes(VU) \
\
/*****************/ \
/* LOWER OPCODES */ \
/*****************/ \
\
MakeDisF(dis##VU##MI_DIV, dName("DIV"); dCP232f(_Fs_, _Fsf_); dCP232f(_Ft_, _Ftf_);) \
MakeDisF(dis##VU##MI_SQRT, dName("SQRT"); dCP232f(_Ft_, _Ftf_);) \
MakeDisF(dis##VU##MI_RSQRT, dName("RSQRT"); dCP232f(_Fs_, _Fsf_); dCP232f(_Ft_, _Ftf_);) \
MakeDisF(dis##VU##MI_IADDI, dName("IADDI"); dCP232i(_Ft_); dCP232i(_Fs_); dImm5();) \
MakeDisF(dis##VU##MI_IADDIU, dName("IADDIU"); dCP232i(_Ft_); dCP232i(_Fs_); dImm15();) \
MakeDisF(dis##VU##MI_IADD, dName("IADD"); dCP232i(_Fd_); dCP232i(_Fs_); dCP232i(_Ft_);) \
MakeDisF(dis##VU##MI_IAND, dName("IAND"); dCP232i(_Fd_); dCP232i(_Fs_); dCP232i(_Ft_);) \
MakeDisF(dis##VU##MI_IOR, dName("IOR"); dCP232i(_Fd_); dCP232i(_Fs_); dCP232i(_Ft_);) \
MakeDisF(dis##VU##MI_ISUB, dName("ISUB"); dCP232i(_Fd_); dCP232i(_Fs_); dCP232i(_Ft_);) \
MakeDisF(dis##VU##MI_ISUBIU, dName("ISUBIU"); dCP232i(_Ft_); dCP232i(_Fs_); dImm15();) \
MakeDisF(dis##VU##MI_MOVE, if (_Fs_ == 0 && _Ft_ == 0) { dNameU("NOP"); } else { dNameU("MOVE"); dCP2128f(_Ft_); dCP2128f(_Fs_); }) \
MakeDisF(dis##VU##MI_MFIR, dNameU("MFIR"); dCP2128f(_Ft_); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_MTIR, dNameU("MTIR"); dCP232i(_Ft_); dCP232f(_Fs_, _Fsf_);) \
MakeDisF(dis##VU##MI_MR32, dNameU("MR32"); dCP2128f(_Ft_); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_LQ, dNameU("LQ"); dCP2128f(_Ft_); dCP232i(_Fs_); dImm11();) \
MakeDisF(dis##VU##MI_LQD, dNameU("LQD"); dCP2128f(_Ft_); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_LQI, dNameU("LQI"); dCP2128f(_Ft_); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_SQ, dNameU("SQ"); dCP2128f(_Fs_); dCP232i(_Ft_); dImm11(); ) \
MakeDisF(dis##VU##MI_SQD, dNameU("SQD"); dCP2128f(_Fs_); dCP232i(_Ft_);) \
MakeDisF(dis##VU##MI_SQI, dNameU("SQI"); dCP2128f(_Fs_); dCP232i(_Ft_);) \
MakeDisF(dis##VU##MI_ILW, dNameU("ILW"); dCP232i(_Ft_); dImm11(); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_ISW, dNameU("ISW"); dCP232i(_Ft_); dImm11(); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_ILWR, dNameU("ILWR"); dCP232i(_Ft_); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_ISWR, dNameU("ISWR"); dCP232i(_Ft_); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_LOI, dName("LOI"); ) \
MakeDisF(dis##VU##MI_RINIT, dNameU("RINIT"); dCP232i(REG_R); dCP232f(_Fs_, _Fsf_);) \
MakeDisF(dis##VU##MI_RGET, dNameU("RGET"); dCP232i(REG_R); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_RNEXT, dNameU("RNEXT"); dCP232i(REG_R); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_RXOR, dNameU("RXOR"); dCP232i(REG_R); dCP232f(_Fs_, _Fsf_);) \
MakeDisF(dis##VU##MI_WAITQ, dName("WAITQ"); ) \
MakeDisF(dis##VU##MI_FSAND, dName("FSAND"); dCP232i(_Ft_); dCP232i(REG_STATUS_FLAG); sprintf(ostr, "%s %.3x,", ostr, code&0xfff); ) \
MakeDisF(dis##VU##MI_FSEQ, dName("FSEQ"); dCP232i(_Ft_); dCP232i(REG_STATUS_FLAG); sprintf(ostr, "%s %.3x,", ostr, code&0xfff);) \
MakeDisF(dis##VU##MI_FSOR, dName("FSOR"); dCP232i(_Ft_); dCP232i(REG_STATUS_FLAG); sprintf(ostr, "%s %.3x,", ostr, code&0xfff);) \
MakeDisF(dis##VU##MI_FSSET, dName("FSSET"); dCP232i(REG_STATUS_FLAG);) \
MakeDisF(dis##VU##MI_FMAND, dName("FMAND"); dCP232i(_Ft_); dCP232i(REG_MAC_FLAG); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_FMEQ, dName("FMEQ"); dCP232i(_Ft_); dCP232i(REG_MAC_FLAG); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_FMOR, dName("FMOR"); dCP232i(_Ft_); dCP232i(REG_MAC_FLAG); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_FCAND, dName("FCAND"); dCP232i(1); sprintf(ostr, "%s %8.8x,", ostr, code&0xffffff); ) \
MakeDisF(dis##VU##MI_FCEQ, dName("FCEQ"); dCP232i(1); dCP232i(REG_CLIP_FLAG);) \
MakeDisF(dis##VU##MI_FCOR, dName("FCOR"); dCP232i(1); dCP232i(REG_CLIP_FLAG);) \
MakeDisF(dis##VU##MI_FCSET, dName("FCSET"); dCP232i(REG_CLIP_FLAG); sprintf(ostr, "%s %.6x,", ostr, code&0xffffff); ) \
MakeDisF(dis##VU##MI_FCGET, dName("FCGET"); dCP232i(_Ft_); dCP232i(REG_CLIP_FLAG);) \
MakeDisF(dis##VU##MI_IBEQ, dName("IBEQ"); dImm11(); dCP232i(_Ft_); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_IBGEZ, dName("IBEZ"); dImm11(); dCP232i(_Ft_); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_IBGTZ, dName("IBGTZ"); dImm11(); dCP232i(_Ft_); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_IBLEZ, dName("IBLEZ"); dImm11(); dCP232i(_Ft_); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_IBLTZ, dName("IBLTZ"); dImm11(); dCP232i(_Ft_); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_IBNE, dName("IBNE"); dImm11(); dCP232i(_Ft_); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_B, dName("B"); dImm11();) \
MakeDisF(dis##VU##MI_BAL, dName("BAL"); dImm11(); dCP232i(_Ft_);) \
MakeDisF(dis##VU##MI_JR, dName("JR"); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_JALR, dName("JALR"); dCP232i(_Ft_); dCP232i(_Fs_); ) \
MakeDisF(dis##VU##MI_MFP, dNameU("MFP"); dCP2128f(_Ft_); dCP232i(REG_P);) \
MakeDisF(dis##VU##MI_WAITP, dName("WAITP"); ) \
MakeDisF(dis##VU##MI_ESADD, dName("ESADD"); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_ERSADD, dName("ERSADD"); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_ELENG, dName("ELENG"); dCP2128f(_Fs_); ) \
MakeDisF(dis##VU##MI_ERLENG, dName("ERLENG"); dCP2128f(_Fs_); ) \
MakeDisF(dis##VU##MI_EATANxy, dName("EATANxy"); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_EATANxz, dName("EATANxz"); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_ESUM, dName("ESUM"); dCP232i(_Fs_); ) \
MakeDisF(dis##VU##MI_ERCPR, dName("ERCPR"); dCP232f(_Fs_, _Fsf_); ) \
MakeDisF(dis##VU##MI_ESQRT, dName("ESQRT"); dCP232f(_Fs_, _Fsf_); ) \
MakeDisF(dis##VU##MI_ERSQRT, dName("ERSQRT"); dCP232f(_Fs_, _Fsf_); ) \
MakeDisF(dis##VU##MI_ESIN, dName("ESIN"); dCP232f(_Fs_, _Fsf_); ) \
MakeDisF(dis##VU##MI_EATAN, dName("EATAN"); dCP232f(_Fs_, _Fsf_); ) \
MakeDisF(dis##VU##MI_EEXP, dName("EEXP"); dCP232f(_Fs_, _Fsf_); ) \
MakeDisF(dis##VU##MI_XITOP, dName("XITOP"); dCP232i(_Ft_);) \
MakeDisF(dis##VU##MI_XGKICK, dName("XGKICK"); dCP232i(_Fs_);) \
MakeDisF(dis##VU##MI_XTOP, dName("XTOP"); dCP232i(_Ft_);) \
\
\
/*****************/ \
/* UPPER OPCODES */ \
/*****************/ \
\
MakeDisF(dis##VU##MI_ABS, dNameU("ABS"); dCP2128f(_Ft_); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_ADD, dNameU("ADD"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_ADDi, dNameU("ADDi"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232iF(REG_I);) \
MakeDisF(dis##VU##MI_ADDq, dNameU("ADDq"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232iF(REG_Q);) \
MakeDisF(dis##VU##MI_ADDx, dNameU("ADDx"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232x(_Ft_);) \
MakeDisF(dis##VU##MI_ADDy, dNameU("ADDy"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232y(_Ft_);) \
MakeDisF(dis##VU##MI_ADDz, dNameU("ADDz"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232z(_Ft_);) \
MakeDisF(dis##VU##MI_ADDw, dNameU("ADDw"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232w(_Ft_);) \
MakeDisF(dis##VU##MI_ADDA, dNameU("ADDA"); dCP2ACCf(); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_ADDAi, dNameU("ADDAi"); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_I);) \
MakeDisF(dis##VU##MI_ADDAq, dNameU("ADDAq"); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_Q);) \
MakeDisF(dis##VU##MI_ADDAx, dNameU("ADDAx"); dCP2ACCf(); dCP2128f(_Fs_); dCP232x(_Ft_);) \
MakeDisF(dis##VU##MI_ADDAy, dNameU("ADDAy"); dCP2ACCf(); dCP2128f(_Fs_); dCP232y(_Ft_);) \
MakeDisF(dis##VU##MI_ADDAz, dNameU("ADDAz"); dCP2ACCf(); dCP2128f(_Fs_); dCP232z(_Ft_);) \
MakeDisF(dis##VU##MI_ADDAw, dNameU("ADDAw"); dCP2ACCf(); dCP2128f(_Fs_); dCP232w(_Ft_);) \
MakeDisF(dis##VU##MI_SUB, dNameU("SUB"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_SUBi, dNameU("SUBi"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232iF(REG_I);) \
MakeDisF(dis##VU##MI_SUBq, dNameU("SUBq"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232iF(REG_Q);) \
MakeDisF(dis##VU##MI_SUBx, dNameU("SUBx"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232x(_Ft_);) \
MakeDisF(dis##VU##MI_SUBy, dNameU("SUBy"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232y(_Ft_);) \
MakeDisF(dis##VU##MI_SUBz, dNameU("SUBz"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232z(_Ft_);) \
MakeDisF(dis##VU##MI_SUBw, dNameU("SUBw"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232w(_Ft_);) \
MakeDisF(dis##VU##MI_SUBA, dNameU("SUBA"); dCP2ACCf(); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_SUBAi, dNameU("SUBAi"); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_I);) \
MakeDisF(dis##VU##MI_SUBAq, dNameU("SUBAq"); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_Q);) \
MakeDisF(dis##VU##MI_SUBAx, dNameU("SUBAx"); dCP2ACCf(); dCP2128f(_Fs_); dCP232x(_Ft_);) \
MakeDisF(dis##VU##MI_SUBAy, dNameU("SUBAy"); dCP2ACCf(); dCP2128f(_Fs_); dCP232y(_Ft_);) \
MakeDisF(dis##VU##MI_SUBAz, dNameU("SUBAz"); dCP2ACCf(); dCP2128f(_Fs_); dCP232z(_Ft_);) \
MakeDisF(dis##VU##MI_SUBAw, dNameU("SUBAw"); dCP2ACCf(); dCP2128f(_Fs_); dCP232w(_Ft_);) \
MakeDisF(dis##VU##MI_MUL, dNameU("MUL"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_MULi, dNameU("MULi"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232iF(REG_I);) \
MakeDisF(dis##VU##MI_MULq, dNameU("MULq"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232iF(REG_Q);) \
MakeDisF(dis##VU##MI_MULx, dNameU("MULx"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232x(_Ft_);) \
MakeDisF(dis##VU##MI_MULy, dNameU("MULy"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232y(_Ft_);) \
MakeDisF(dis##VU##MI_MULz, dNameU("MULz"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232z(_Ft_);) \
MakeDisF(dis##VU##MI_MULw, dNameU("MULw"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232w(_Ft_);) \
MakeDisF(dis##VU##MI_MULA, dNameU("MULA"); dCP2ACCf(); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_MULAi, dNameU("MULAi"); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_I);) \
MakeDisF(dis##VU##MI_MULAq, dNameU("MULAq"); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_Q);) \
MakeDisF(dis##VU##MI_MULAx, dNameU("MULAx"); dCP2ACCf(); dCP2128f(_Fs_); dCP232x(_Ft_);) \
MakeDisF(dis##VU##MI_MULAy, dNameU("MULAy"); dCP2ACCf(); dCP2128f(_Fs_); dCP232y(_Ft_);) \
MakeDisF(dis##VU##MI_MULAz, dNameU("MULAz"); dCP2ACCf(); dCP2128f(_Fs_); dCP232z(_Ft_);) \
MakeDisF(dis##VU##MI_MULAw, dNameU("MULAw"); dCP2ACCf(); dCP2128f(_Fs_); dCP232w(_Ft_);) \
MakeDisF(dis##VU##MI_MADD, dNameU("MADD"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_MADDi, dNameU("MADDi"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_I);) \
MakeDisF(dis##VU##MI_MADDq, dNameU("MADDq"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_Q);) \
MakeDisF(dis##VU##MI_MADDx, dNameU("MADDx"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232x(_Ft_);) \
MakeDisF(dis##VU##MI_MADDy, dNameU("MADDy"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232y(_Ft_);) \
MakeDisF(dis##VU##MI_MADDz, dNameU("MADDz"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232z(_Ft_);) \
MakeDisF(dis##VU##MI_MADDw, dNameU("MADDw"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232w(_Ft_);) \
MakeDisF(dis##VU##MI_MADDA, dNameU("MADDA"); dCP2ACCf(); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_MADDAi, dNameU("MADDAi"); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_I);) \
MakeDisF(dis##VU##MI_MADDAq, dNameU("MADDAq"); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_Q);) \
MakeDisF(dis##VU##MI_MADDAx, dNameU("MADDAx"); dCP2ACCf(); dCP2128f(_Fs_); dCP232x(_Ft_);) \
MakeDisF(dis##VU##MI_MADDAy, dNameU("MADDAy"); dCP2ACCf(); dCP2128f(_Fs_); dCP232y(_Ft_);) \
MakeDisF(dis##VU##MI_MADDAz, dNameU("MADDAz"); dCP2ACCf(); dCP2128f(_Fs_); dCP232z(_Ft_);) \
MakeDisF(dis##VU##MI_MADDAw, dNameU("MADDAw"); dCP2ACCf(); dCP2128f(_Fs_); dCP232w(_Ft_);) \
MakeDisF(dis##VU##MI_MSUB, dNameU("MSUB"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_MSUBi, dNameU("MSUBi"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_I);) \
MakeDisF(dis##VU##MI_MSUBq, dNameU("MSUBq"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_Q);) \
MakeDisF(dis##VU##MI_MSUBx, dNameU("MSUBx"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232x(_Ft_);) \
MakeDisF(dis##VU##MI_MSUBy, dNameU("MSUBy"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232y(_Ft_);) \
MakeDisF(dis##VU##MI_MSUBz, dNameU("MSUBz"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232z(_Ft_);) \
MakeDisF(dis##VU##MI_MSUBw, dNameU("MSUBw"); dCP2128f(_Fd_); dCP2ACCf(); dCP2128f(_Fs_); dCP232w(_Ft_);) \
MakeDisF(dis##VU##MI_MSUBA, dNameU("MSUBA"); dCP2ACCf(); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_MSUBAi, dNameU("MSUBAi"); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_I);) \
MakeDisF(dis##VU##MI_MSUBAq, dNameU("MSUBAq"); dCP2ACCf(); dCP2128f(_Fs_); dCP232iF(REG_Q);) \
MakeDisF(dis##VU##MI_MSUBAx, dNameU("MSUBAx"); dCP2ACCf(); dCP2128f(_Fs_); dCP232x(_Ft_);) \
MakeDisF(dis##VU##MI_MSUBAy, dNameU("MSUBAy"); dCP2ACCf(); dCP2128f(_Fs_); dCP232y(_Ft_);) \
MakeDisF(dis##VU##MI_MSUBAz, dNameU("MSUBAz"); dCP2ACCf(); dCP2128f(_Fs_); dCP232z(_Ft_);) \
MakeDisF(dis##VU##MI_MSUBAw, dNameU("MSUBAw"); dCP2ACCf(); dCP2128f(_Fs_); dCP232w(_Ft_);) \
MakeDisF(dis##VU##MI_MAX, dNameU("MAX"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_MAXi, dNameU("MAXi"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232iF(REG_I);) \
MakeDisF(dis##VU##MI_MAXx, dNameU("MAXx"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232x(_Ft_);) \
MakeDisF(dis##VU##MI_MAXy, dNameU("MAXy"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232y(_Ft_);) \
MakeDisF(dis##VU##MI_MAXz, dNameU("MAXz"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232z(_Ft_);) \
MakeDisF(dis##VU##MI_MAXw, dNameU("MAXw"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232w(_Ft_);) \
MakeDisF(dis##VU##MI_MINI, dNameU("MINI"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_MINIi, dNameU("MINIi"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232iF(REG_I);) \
MakeDisF(dis##VU##MI_MINIx, dNameU("MINIx"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232x(_Ft_);) \
MakeDisF(dis##VU##MI_MINIy, dNameU("MINIy"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232y(_Ft_);) \
MakeDisF(dis##VU##MI_MINIz, dNameU("MINIz"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232z(_Ft_);) \
MakeDisF(dis##VU##MI_MINIw, dNameU("MINIw"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP232w(_Ft_);) \
MakeDisF(dis##VU##MI_OPMULA, dNameU("OPMULA"); dCP2ACCf(); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_OPMSUB, dNameU("OPMSUB"); dCP2128f(_Fd_); dCP2128f(_Fs_); dCP2128f(_Ft_);) \
MakeDisF(dis##VU##MI_NOP, dName("NOP");) \
MakeDisF(dis##VU##MI_FTOI0, dNameU("FTOI0"); dCP2128f(_Ft_); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_FTOI4, dNameU("FTOI4"); dCP2128f(_Ft_); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_FTOI12, dNameU("FTOI12"); dCP2128f(_Ft_); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_FTOI15, dNameU("FTOI15"); dCP2128f(_Ft_); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_ITOF0, dNameU("ITOF0"); dCP2128f(_Ft_); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_ITOF4, dNameU("ITOF4"); dCP2128f(_Ft_); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_ITOF12, dNameU("ITOF12"); dCP2128f(_Ft_); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_ITOF15, dNameU("ITOF15"); dCP2128f(_Ft_); dCP2128f(_Fs_);) \
MakeDisF(dis##VU##MI_CLIP, dNameU("CLIP"); dCP2128f(_Fs_); dCP232w(_Ft_);) \

7
DebugTools/Makefile.am Normal file
View File

@ -0,0 +1,7 @@
INCLUDES = -I../
noinst_LIBRARIES = libDebugTools.a
libDebugTools_a_SOURCES = \
cpuopsDebug.c Debug.h.bak DisR3000asm.c DisVU0Micro.c DisVUops.h \
cpuopsDebug.h DisASM.h DisR5900asm.c DisVU1Micro.c \
Debug.h DisR3000A.c DisR5900.c DisVUmicro.h

1063
DebugTools/cpuopsDebug.c Normal file

File diff suppressed because it is too large Load Diff

456
DebugTools/cpuopsDebug.h Normal file
View File

@ -0,0 +1,456 @@
/* 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
*/
void UpdateR5900op();
extern void (*LT_OpcodePrintTable[64])();
extern void (*LT_SpecialPrintTable[64])();
extern void (*LT_REGIMMPrintTable[32])();
extern void (*LT_MMIPrintTable[64])();
extern void (*LT_MMI0PrintTable[32])();
extern void (*LT_MMI1PrintTable[32])();
extern void (*LT_MMI2PrintTable[32])();
extern void (*LT_MMI3PrintTable[32])();
extern void (*LT_COP0PrintTable[32])();
extern void (*LT_COP0BC0PrintTable[32])();
extern void (*LT_COP0C0PrintTable[64])();
extern void (*LT_COP1PrintTable[32])();
extern void (*LT_COP1BC1PrintTable[32])();
extern void (*LT_COP1SPrintTable[64])();
extern void (*LT_COP1WPrintTable[64])();
extern void (*LT_COP2PrintTable[32])();
extern void (*LT_COP2BC2PrintTable[32])();
extern void (*LT_COP2SPECIAL1PrintTable[64])();
extern void (*LT_COP2SPECIAL2PrintTable[128])();
// **********************Standard Opcodes**************************
int L_ADD=0;
int L_ADDI=0;
int L_ADDIU=0;
int L_ADDU=0;
int L_AND=0;
int L_ANDI=0;
int L_BEQ=0;
int L_BEQL=0;
int L_BGEZ=0;
int L_BGEZAL=0;
int L_BGEZALL=0;
int L_BGEZL=0;
int L_BGTZ=0;
int L_BGTZL=0;
int L_BLEZ=0;
int L_BLEZL=0;
int L_BLTZ=0;
int L_BLTZAL=0;
int L_BLTZALL=0;
int L_BLTZL=0;
int L_BNE=0;
int L_BNEL=0;
int L_BREAK=0;
int L_CACHE=0;
int L_DADD=0;
int L_DADDI=0;
int L_DADDIU=0;
int L_DADDU=0;
int L_DIV=0;
int L_DIVU=0;
int L_DSLL=0;
int L_DSLL32=0;
int L_DSLLV=0;
int L_DSRA=0;
int L_DSRA32=0;
int L_DSRAV=0;
int L_DSRL=0;
int L_DSRL32=0;
int L_DSRLV=0;
int L_DSUB=0;
int L_DSUBU=0;
int L_J=0;
int L_JAL=0;
int L_JALR=0;
int L_JR=0;
int L_LB=0;
int L_LBU=0;
int L_LD=0;
int L_LDL=0;
int L_LDR=0;
int L_LH=0;
int L_LHU=0;
int L_LQ=0;
int L_LQC2=0;
int L_LUI=0;
int L_LW=0;
int L_LWC1=0;
int L_LWL=0;
int L_LWR=0;
int L_LWU=0;
int L_MFHI=0;
int L_MFLO=0;
int L_MFSA=0;
int L_MOVN=0;
int L_MOVZ=0;
int L_MTHI=0;
int L_MTLO=0;
int L_MTSA=0;
int L_MTSAB=0;
int L_MTSAH=0;
int L_MULT=0;
int L_MULTU=0;
int L_NOR=0;
int L_OR=0;
int L_ORI=0;
int L_PREF=0;
int L_SB=0;
int L_SD=0;
int L_SDL=0;
int L_SDR=0;
int L_SH=0;
int L_SLL=0;
int L_SLLV=0;
int L_SLT=0;
int L_SLTI=0;
int L_SLTIU=0;
int L_SLTU=0;
int L_SQ=0;
int L_SQC2=0;
int L_SRA=0;
int L_SRAV=0;
int L_SRL=0;
int L_SRLV=0;
int L_SUB=0;
int L_SUBU=0;
int L_SW=0;
int L_SWC1=0;
int L_SWL=0;
int L_SWR=0;
int L_SYNC=0;
int L_SYSCALL=0;
int L_TEQ=0;
int L_TEQI=0;
int L_TGE=0;
int L_TGEI=0;
int L_TGEIU=0;
int L_TGEU=0;
int L_TLT=0;
int L_TLTI=0;
int L_TLTIU=0;
int L_TLTU=0;
int L_TNE=0;
int L_TNEI=0;
int L_XOR=0;
int L_XORI=0;
//*****************MMI OPCODES*********************************
int L_MADD=0;
int L_MADDU=0;
int L_PLZCW=0;
int L_MADD1=0;
int L_MADDU1=0;
int L_MFHI1=0;
int L_MTHI1=0;
int L_MFLO1=0;
int L_MTLO1=0;
int L_MULT1=0;
int L_MULTU1=0;
int L_DIV1=0;
int L_DIVU1=0;
int L_PMFHL=0;
int L_PMTHL=0;
int L_PSLLH=0;
int L_PSRLH=0;
int L_PSRAH=0;
int L_PSLLW=0;
int L_PSRLW=0;
int L_PSRAW=0;
//*****************END OF MMI OPCODES**************************
//*************************MMI0 OPCODES************************
int L_PADDW=0;
int L_PSUBW=0;
int L_PCGTW=0;
int L_PMAXW=0;
int L_PADDH=0;
int L_PSUBH=0;
int L_PCGTH=0;
int L_PMAXH=0;
int L_PADDB=0;
int L_PSUBB=0;
int L_PCGTB=0;
int L_PADDSW=0;
int L_PSUBSW=0;
int L_PEXTLW=0;
int L_PPACW=0;
int L_PADDSH=0;
int L_PSUBSH=0;
int L_PEXTLH=0;
int L_PPACH=0;
int L_PADDSB=0;
int L_PSUBSB=0;
int L_PEXTLB=0;
int L_PPACB=0;
int L_PEXT5=0;
int L_PPAC5=0;
//***END OF MMI0 OPCODES******************************************
//**********MMI1 OPCODES**************************************
int L_PABSW=0;
int L_PCEQW=0;
int L_PMINW=0;
int L_PADSBH=0;
int L_PABSH=0;
int L_PCEQH=0;
int L_PMINH=0;
int L_PCEQB=0;
int L_PADDUW=0;
int L_PSUBUW=0;
int L_PEXTUW=0;
int L_PADDUH=0;
int L_PSUBUH=0;
int L_PEXTUH=0;
int L_PADDUB=0;
int L_PSUBUB=0;
int L_PEXTUB=0;
int L_QFSRV=0;
//********END OF MMI1 OPCODES***********************************
//*********MMI2 OPCODES***************************************
int L_PMADDW=0;
int L_PSLLVW=0;
int L_PSRLVW=0;
int L_PMSUBW=0;
int L_PMFHI=0;
int L_PMFLO=0;
int L_PINTH=0;
int L_PMULTW=0;
int L_PDIVW=0;
int L_PCPYLD=0;
int L_PMADDH=0;
int L_PHMADH=0;
int L_PAND=0;
int L_PXOR=0;
int L_PMSUBH=0;
int L_PHMSBH=0;
int L_PEXEH=0;
int L_PREVH=0;
int L_PMULTH=0;
int L_PDIVBW=0;
int L_PEXEW=0;
int L_PROT3W=0;
//*****END OF MMI2 OPCODES***********************************
//*************************MMI3 OPCODES************************
int L_PMADDUW=0;
int L_PSRAVW=0;
int L_PMTHI=0;
int L_PMTLO=0;
int L_PINTEH=0;
int L_PMULTUW=0;
int L_PDIVUW=0;
int L_PCPYUD=0;
int L_POR=0;
int L_PNOR=0;
int L_PEXCH=0;
int L_PCPYH=0;
int L_PEXCW=0;
//**********************END OF MMI3 OPCODES********************
//****************************************************************************
//** COP0 **
//****************************************************************************
int L_MFC0=0;
int L_MTC0=0;
int L_BC0F=0;
int L_BC0T=0;
int L_BC0FL=0;
int L_BC0TL=0;
int L_TLBR=0;
int L_TLBWI=0;
int L_TLBWR=0;
int L_TLBP=0;
int L_ERET=0;
int L_DI=0;
int L_EI=0;
//****************************************************************************
//** END OF COP0 **
//****************************************************************************
//****************************************************************************
//** COP1 - Floating Point Unit (FPU) **
//****************************************************************************
int L_MFC1=0;
int L_CFC1=0;
int L_MTC1=0;
int L_CTC1=0;
int L_BC1F=0;
int L_BC1T=0;
int L_BC1FL=0;
int L_BC1TL=0;
int L_ADD_S=0;
int L_SUB_S=0;
int L_MUL_S=0;
int L_DIV_S=0;
int L_SQRT_S=0;
int L_ABS_S=0;
int L_MOV_S=0;
int L_NEG_S=0;
int L_RSQRT_S=0;
int L_ADDA_S=0;
int L_SUBA_S=0;
int L_MULA_S=0;
int L_MADD_S=0;
int L_MSUB_S=0;
int L_MADDA_S=0;
int L_MSUBA_S=0;
int L_CVT_W=0;
int L_MAX_S=0;
int L_MIN_S=0;
int L_C_F=0;
int L_C_EQ=0;
int L_C_LT=0;
int L_C_LE=0;
int L_CVT_S=0;
//****************************************************************************
//** END OF COP1 **
//****************************************************************************
//****************************************************************************
//** COP2 - (VU0) **
//****************************************************************************
int L_QMFC2=0;
int L_CFC2=0;
int L_QMTC2=0;
int L_CTC2=0;
int L_BC2F=0;
int L_BC2T=0;
int L_BC2FL=0;
int L_BC2TL=0;
int L_VADDx=0;
int L_VADDy=0;
int L_VADDz=0;
int L_VADDw=0;
int L_VSUBx=0;
int L_VSUBy=0;
int L_VSUBz=0;
int L_VSUBw=0;
int L_VMADDx=0;
int L_VMADDy=0;
int L_VMADDz=0;
int L_VMADDw=0;
int L_VMSUBx=0;
int L_VMSUBy=0;
int L_VMSUBz=0;
int L_VMSUBw=0;
int L_VMAXx=0;
int L_VMAXy=0;
int L_VMAXz=0;
int L_VMAXw=0;
int L_VMINIx=0;
int L_VMINIy=0;
int L_VMINIz=0;
int L_VMINIw=0;
int L_VMULx=0;
int L_VMULy=0;
int L_VMULz=0;
int L_VMULw=0;
int L_VMULq=0;
int L_VMAXi=0;
int L_VMULi=0;
int L_VMINIi=0;
int L_VADDq=0;
int L_VMADDq=0;
int L_VADDi=0;
int L_VMADDi=0;
int L_VSUBq=0;
int L_VMSUBq=0;
int L_VSUBi=0;
int L_VMSUBi=0;
int L_VADD=0;
int L_VMADD=0;
int L_VMUL=0;
int L_VMAX=0;
int L_VSUB=0;
int L_VMSUB=0;
int L_VOPMSUB=0;
int L_VMINI=0;
int L_VIADD=0;
int L_VISUB=0;
int L_VIADDI=0;
int L_VIAND=0;
int L_VIOR=0;
int L_VCALLMS=0;
int L_VCALLMSR=0;
int L_VADDAx=0;
int L_VADDAy=0;
int L_VADDAz=0;
int L_VADDAw=0;
int L_VSUBAx=0;
int L_VSUBAy=0;
int L_VSUBAz=0;
int L_VSUBAw=0;
int L_VMADDAx=0;
int L_VMADDAy=0;
int L_VMADDAz=0;
int L_VMADDAw=0;
int L_VMSUBAx=0;
int L_VMSUBAy=0;
int L_VMSUBAz=0;
int L_VMSUBAw=0;
int L_VITOF0=0;
int L_VITOF4=0;
int L_VITOF12=0;
int L_VITOF15=0;
int L_VFTOI0=0;
int L_VFTOI4=0;
int L_VFTOI12=0;
int L_VFTOI15=0;
int L_VMULAx=0;
int L_VMULAy=0;
int L_VMULAz=0;
int L_VMULAw=0;
int L_VMULAq=0;
int L_VABS=0;
int L_VMULAi=0;
int L_VCLIPw=0;
int L_VADDAq=0;
int L_VMADDAq=0;
int L_VADDAi=0;
int L_VMADDAi=0;
int L_VSUBAq=0;
int L_VMSUBAq=0;
int L_VSUBAi=0;
int L_VMSUBAi=0;
int L_VADDA=0;
int L_VMADDA=0;
int L_VMULA=0;
int L_VSUBA=0;
int L_VMSUBA=0;
int L_VOPMULA=0;
int L_VNOP=0;
int L_VMOVE=0;
int L_VMR32=0;
int L_VLQI=0;
int L_VSQI=0;
int L_VLQD=0;
int L_VSQD=0;
int L_VDIV=0;
int L_VSQRT=0;
int L_VRSQRT=0;
int L_VWAITQ=0;
int L_VMTIR=0;
int L_VMFIR=0;
int L_VILWR=0;
int L_VISWR=0;
int L_VRNEXT=0;
int L_VRGET=0;
int L_VRINIT=0;
int L_VRXOR=0;

305
Decode_XA.c Normal file
View File

@ -0,0 +1,305 @@
//============================================
//=== Audio XA decoding
//=== Kazzuya
//============================================
//=== Modified by linuzappz
//============================================
#include <stdio.h>
#include "Decode_XA.h"
#ifdef __WIN32__
#pragma warning(disable:4244)
#endif
typedef unsigned char U8;
typedef unsigned short U16;
typedef unsigned long U32;
#define NOT(_X_) (!(_X_))
#define CLAMP(_X_,_MI_,_MA_) {if(_X_<_MI_)_X_=_MI_;if(_X_>_MA_)_X_=_MA_;}
//============================================
//=== ADPCM DECODING ROUTINES
//============================================
static double K0[4] = {
0.0,
0.9375,
1.796875,
1.53125
};
static double K1[4] = {
0.0,
0.0,
-0.8125,
-0.859375
};
#define BLKSIZ 28 /* block size (32 - 4 nibbles) */
//===========================================
void ADPCM_InitDecode( ADPCM_Decode_t *decp )
{
decp->y0 = 0;
decp->y1 = 0;
}
//===========================================
#define SH 4
#define SHC 10
#define IK0(fid) ((int)((-K0[fid]) * (1<<SHC)))
#define IK1(fid) ((int)((-K1[fid]) * (1<<SHC)))
void ADPCM_DecodeBlock16( ADPCM_Decode_t *decp, U8 filter_range, const void *vblockp, short *destp, int inc ) {
int i;
int range, filterid;
long fy0, fy1;
const U16 *blockp;
blockp = (const unsigned short *)vblockp;
filterid = (filter_range >> 4) & 0x0f;
range = (filter_range >> 0) & 0x0f;
fy0 = decp->y0;
fy1 = decp->y1;
for (i = BLKSIZ/4; i; --i) {
long y;
long x0, x1, x2, x3;
y = *blockp++;
x3 = (short)( y & 0xf000) >> range; x3 <<= SH;
x2 = (short)((y << 4) & 0xf000) >> range; x2 <<= SH;
x1 = (short)((y << 8) & 0xf000) >> range; x1 <<= SH;
x0 = (short)((y << 12) & 0xf000) >> range; x0 <<= SH;
x0 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x0;
x1 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x1;
x2 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x2;
x3 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x3;
CLAMP( x0, -32768<<SH, 32767<<SH ); *destp = x0 >> SH; destp += inc;
CLAMP( x1, -32768<<SH, 32767<<SH ); *destp = x1 >> SH; destp += inc;
CLAMP( x2, -32768<<SH, 32767<<SH ); *destp = x2 >> SH; destp += inc;
CLAMP( x3, -32768<<SH, 32767<<SH ); *destp = x3 >> SH; destp += inc;
}
decp->y0 = fy0;
decp->y1 = fy1;
}
static int headtable[4] = {0,2,8,10};
//===========================================
static void xa_decode_data( xa_decode_t *xdp, unsigned char *srcp ) {
const U8 *sound_groupsp;
const U8 *sound_datap, *sound_datap2;
int i, j, k, nbits;
U16 data[4096], *datap;
short *destp;
destp = xdp->pcm;
nbits = xdp->nbits == 4 ? 4 : 2;
if (xdp->stereo) { // stereo
for (j=0; j < 18; j++) {
sound_groupsp = srcp + j * 128; // sound groups header
sound_datap = sound_groupsp + 16; // sound data just after the header
for (i=0; i < nbits; i++) {
datap = data;
sound_datap2 = sound_datap + i;
if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A
for (k=0; k < 14; k++, sound_datap2 += 8) {
*(datap++) = (U16)sound_datap2[0] |
(U16)(sound_datap2[4] << 8);
}
} else { // level B/C
for (k=0; k < 7; k++, sound_datap2 += 16) {
*(datap++) = (U16)(sound_datap2[ 0] & 0x0f) |
((U16)(sound_datap2[ 4] & 0x0f) << 4) |
((U16)(sound_datap2[ 8] & 0x0f) << 8) |
((U16)(sound_datap2[12] & 0x0f) << 12);
}
}
ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data,
destp+0, 2 );
datap = data;
sound_datap2 = sound_datap + i;
if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A
for (k=0; k < 14; k++, sound_datap2 += 8) {
*(datap++) = (U16)sound_datap2[0] |
(U16)(sound_datap2[4] << 8);
}
} else { // level B/C
for (k=0; k < 7; k++, sound_datap2 += 16) {
*(datap++) = (U16)(sound_datap2[ 0] >> 4) |
((U16)(sound_datap2[ 4] >> 4) << 4) |
((U16)(sound_datap2[ 8] >> 4) << 8) |
((U16)(sound_datap2[12] >> 4) << 12);
}
}
ADPCM_DecodeBlock16( &xdp->right, sound_groupsp[headtable[i]+1], data,
destp+1, 2 );
destp += 28*2;
}
}
}
else { // mono
for (j=0; j < 18; j++) {
sound_groupsp = srcp + j * 128; // sound groups header
sound_datap = sound_groupsp + 16; // sound data just after the header
for (i=0; i < nbits; i++) {
datap = data;
sound_datap2 = sound_datap + i;
if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A
for (k=0; k < 14; k++, sound_datap2 += 8) {
*(datap++) = (U16)sound_datap2[0] |
(U16)(sound_datap2[4] << 8);
}
} else { // level B/C
for (k=0; k < 7; k++, sound_datap2 += 16) {
*(datap++) = (U16)(sound_datap2[ 0] & 0x0f) |
((U16)(sound_datap2[ 4] & 0x0f) << 4) |
((U16)(sound_datap2[ 8] & 0x0f) << 8) |
((U16)(sound_datap2[12] & 0x0f) << 12);
}
}
ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data,
destp, 1 );
destp += 28;
datap = data;
sound_datap2 = sound_datap + i;
if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A
for (k=0; k < 14; k++, sound_datap2 += 8) {
*(datap++) = (U16)sound_datap2[0] |
(U16)(sound_datap2[4] << 8);
}
} else { // level B/C
for (k=0; k < 7; k++, sound_datap2 += 16) {
*(datap++) = (U16)(sound_datap2[ 0] >> 4) |
((U16)(sound_datap2[ 4] >> 4) << 4) |
((U16)(sound_datap2[ 8] >> 4) << 8) |
((U16)(sound_datap2[12] >> 4) << 12);
}
}
ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+1], data,
destp, 1 );
destp += 28;
}
}
}
}
//============================================
//=== XA SPECIFIC ROUTINES
//============================================
typedef struct {
U8 filenum;
U8 channum;
U8 submode;
U8 coding;
U8 filenum2;
U8 channum2;
U8 submode2;
U8 coding2;
} xa_subheader_t;
#define SUB_SUB_EOF (1<<7) // end of file
#define SUB_SUB_RT (1<<6) // real-time sector
#define SUB_SUB_FORM (1<<5) // 0 form1 1 form2
#define SUB_SUB_TRIGGER (1<<4) // used for interrupt
#define SUB_SUB_DATA (1<<3) // contains data
#define SUB_SUB_AUDIO (1<<2) // contains audio
#define SUB_SUB_VIDEO (1<<1) // contains video
#define SUB_SUB_EOR (1<<0) // end of record
#define AUDIO_CODING_GET_STEREO(_X_) ( (_X_) & 3)
#define AUDIO_CODING_GET_FREQ(_X_) (((_X_) >> 2) & 3)
#define AUDIO_CODING_GET_BPS(_X_) (((_X_) >> 4) & 3)
#define AUDIO_CODING_GET_EMPHASIS(_X_) (((_X_) >> 6) & 1)
#define SUB_UNKNOWN 0
#define SUB_VIDEO 1
#define SUB_AUDIO 2
//============================================
static int parse_xa_audio_sector( xa_decode_t *xdp,
xa_subheader_t *subheadp,
unsigned char *sectorp,
int is_first_sector ) {
if ( is_first_sector ) {
switch ( AUDIO_CODING_GET_FREQ(subheadp->coding) ) {
case 0: xdp->freq = 37800; break;
case 1: xdp->freq = 18900; break;
default: xdp->freq = 0; break;
}
switch ( AUDIO_CODING_GET_BPS(subheadp->coding) ) {
case 0: xdp->nbits = 4; break;
case 1: xdp->nbits = 8; break;
default: xdp->nbits = 0; break;
}
switch ( AUDIO_CODING_GET_STEREO(subheadp->coding) ) {
case 0: xdp->stereo = 0; break;
case 1: xdp->stereo = 1; break;
default: xdp->stereo = 0; break;
}
if ( xdp->freq == 0 )
return -1;
ADPCM_InitDecode( &xdp->left );
ADPCM_InitDecode( &xdp->right );
xdp->nsamples = 18 * 28 * 8;
if (xdp->stereo == 1) xdp->nsamples /= 2;
}
xa_decode_data( xdp, sectorp );
return 0;
}
//================================================================
//=== THIS IS WHAT YOU HAVE TO CALL
//=== xdp - structure were all important data are returned
//=== sectorp - data in input
//=== pcmp - data in output
//=== is_first_sector - 1 if it's the 1st sector of the stream
//=== - 0 for any other successive sector
//=== return -1 if error
//================================================================
long xa_decode_sector( xa_decode_t *xdp,
unsigned char *sectorp, int is_first_sector ) {
if (parse_xa_audio_sector(xdp, (xa_subheader_t *)sectorp, sectorp + sizeof(xa_subheader_t), is_first_sector))
return -1;
return 0;
}
/* EXAMPLE:
"nsamples" is the number of 16 bit samples
every sample is 2 bytes in mono and 4 bytes in stereo
xa_decode_t xa;
sectorp = read_first_sector();
xa_decode_sector( &xa, sectorp, 1 );
play_wave( xa.pcm, xa.freq, xa.nsamples );
while ( --n_sectors )
{
sectorp = read_next_sector();
xa_decode_sector( &xa, sectorp, 0 );
play_wave( xa.pcm, xa.freq, xa.nsamples );
}
*/

26
Decode_XA.h Normal file
View File

@ -0,0 +1,26 @@
//============================================
//=== Audio XA decoding
//=== Kazzuya
//============================================
#ifndef DECODEXA_H
#define DECODEXA_H
typedef struct {
long y0, y1;
} ADPCM_Decode_t;
typedef struct {
int freq;
int nbits;
int stereo;
int nsamples;
ADPCM_Decode_t left, right;
short pcm[16384];
} xa_decode_t;
long xa_decode_sector( xa_decode_t *xdp,
unsigned char *sectorp,
int is_first_sector );
#endif

13
Docs/BetaTesters.txt Normal file
View File

@ -0,0 +1,13 @@
Current PCSX2 Beta-Testers-Slaves :P :
belmont
parotaku
bositman
CKemu
Raziel
Snake875
Elly
CpUMasteR
Falcon4Ever
Seta-San
Nave

2848
Docs/ChangeLog.txt Normal file

File diff suppressed because it is too large Load Diff

342
Docs/License.txt Normal file
View File

@ -0,0 +1,342 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

443
Docs/PS2Edefs.txt Normal file
View File

@ -0,0 +1,443 @@
PS2E Definitions v0.3.0 (beta)
------------------------------
Author: linuzappz@pcsx.net
Note: Refer to PS2Edefs.h for more info.
1) API Funcs
2) FAQs
3) Notes
1) API Funcs:
---------
Common stuff:
------------
// u32 CALLBACK PS2EgetLibType(void);
Gets the plugin type, from the following defines:
#define PS2E_LT_GS 0x01
#define PS2E_LT_PAD 0x02
#define PS2E_LT_SPU2 0x04
#define PS2E_LT_CDVD 0x08
#define PS2E_LT_DEV9 0x10
#define PS2E_LT_USB 0x20
#define PS2E_LT_FIREWIRE 0x40
Note that the types can be ORed so you can make an
ie. GS/PAD plugin in one dll.
// u32 CALLBACK PS2EgetLibVersion(void);
Will get the plugin version:
const unsigned char version = 1; // GS library v1
const unsigned char revision = VERSION;
const unsigned char build = BUILD; // increase that with each version
return version<<16|revision<<8|build;
'version' is the GS plugin API version, as this is beta,
it should be 1.
'revision' and 'build' are plugin defined values.
// char* CALLBACK PS2EgetLibName(void);
Get the LibName, ie. "GSsoftdx Driver";
GS plugin API:
-------------
Basic funcs
-----------
// s32 CALLBACK GSinit();
Inits the plugin, return 0 on success, else -1.
// s32 CALLBACK GSopen(void *pDsp, char *Title);
Opens the plugin, return 0 on success, else -1.
The plugin must fill the 'pDsp' arg (32bit) that'll be
passed to other plugins (*1), this is OS dependant (*2).
On Win32: pass a HWND value, ie:
*(long*)pDsp = (long)GShwnd;
On Linux: pass a Display value, ie:
*(long*)pDsp = (long)display;
*1 Even if this value is passed to every plugin, this
may not be used by the plugins.
*2 This could change anyways, ie. maybe you can code a
GS/PAD plugin for a speacial library, so the pDsp
will be a value that you need to communicate between
them (if you need to do this).
// void CALLBACK GSclose();
Close the plugin.
// void CALLBACK GSshutdown();
Shutdown the plugin.
// void CALLBACK GSvsync();
Called on every VSync.
// void CALLBACK GSgifTransfer(u32 *pMem, u32 size);
Transfer 'size' qwords (128bit) from 'pMem' to the Gif.
// void CALLBACK GSgifTransfer2(u32 *pMem);
Transfer a qwords (128bit) block from 'pMem' to the Gif.
// void CALLBACK GSwrite32(u32 mem, u32 value);
Writes to address 'mem' data 'value', 32bit.
Addresses can range from 0x12000000 to 0x14000000.
// void CALLBACK GSwrite64(u32 mem, u64 value);
Writes to address 'mem' data 'value', 64bit.
Addresses can range from 0x12000000 to 0x14000000.
// u32 CALLBACK GSread32(u32 mem);
Returns 32bit from address 'mem'.
Addresses can range from 0x12000000 to 0x14000000.
// u64 CALLBACK GSread64(u32 mem);
Returns 64bit from address 'mem'.
Addresses can range from 0x12000000 to 0x14000000.
Extended funcs
--------------
// void CALLBACK GSkeyEvent(keyEvent *ev);
Gets called when there is a keyEvent from the PAD plugin
// void CALLBACK GSmakeSnapshot(char *path);
Makes an snapshot of the vRam, can be a with the full
vRam or just the view area (as you prefer), to the dir
'path'.
// #ifdef __WIN32__
// s32 CALLBACK GSsetWindowInfo(winInfo *info);
// #endif
Windows only function, will pass the info struct to the
GS plugin, if the plugin will use this info it should
return 1 (TRUE), else the emu will destroy the window
handle and let the plugin take care of that.
This function must be called before the GSopen.
Note that the emu should hide the hMenu and the hStatusWnd
if it they are set.
The position and size of the window is not specified and
should be reset by the plugin, but the window passed should
be in a normal state, not maximized nor minimized.
After a GSclose the emu must destroy the window and
recreate it.
// void CALLBACK GSconfigure();
Configure the plugin.
// void CALLBACK GSabout();
Shows an About Dialog of the plugin.
// s32 CALLBACK GStest();
Returns 0 if the plugin should work ok, else -1.
PAD plugin API: -=[ OBSOLETE ]=-
--------------
Basic funcs
-----------
// s32 CALLBACK PADinit(u32 flags);
Inits the plugin, return 0 on success, else -1.
// s32 CALLBACK PADopen(void *pDsp);
Opens the plugin, return 0 on success, else -1.
The 'pDsp' is a value from the GS plugin (refer to
GSopen).
// void CALLBACK PADclose();
Close the plugin.
// void CALLBACK PADshutdown();
Shutdown the plugin.
// keyEvent* CALLBACK PADkeyEvent();
Called every vsync, return NULL if no event happened.
// u8 CALLBACK PADstartPoll(int pad);
Starts polling data from the PAD, 'pad' can be 1 (pad1)
or 2 (pad2).
Returns first byte from buffer;
// u8 CALLBACK PADpoll(u8 value);
Returns next byte from buffer;
Refer to "pad and mem card data.txt" or "padmem.txt",
for info about value/buffer data.
// u32 CALLBACK PADquery();
returns: 1 if supported pad1
2 if supported pad2
3 if both are supported
Extended funcs
--------------
// void CALLBACK PADconfigure();
Configure the plugin.
// void CALLBACK PADabout();
Shows an About Dialog of the plugin.
// s32 CALLBACK PADtest();
Returns 0 if the plugin should work ok, else -1.
SIO plugin API:
--------------
Basic funcs
-----------
// s32 CALLBACK SIOinit(u32 port, u32 slot, SIOchangeSlotCB f);
Inits the plugin, return 0 on success, else -1.
port/slot combination will be used to load the corresponding
configuration data from ini. It's like an id for the instance.
'f' is a callback function that is used by SIO_TYPE_MTAP capable
plugins to change active slot in emulator (since sio is emu-controled).
// s32 CALLBACK SIOopen(void *pDsp);
Opens the plugin, return 0 on success, else -1.
The 'pDsp' is a value from the GS plugin (refer to
GSopen).
// void CALLBACK SIOclose();
Close the plugin.
// void CALLBACK SIOshutdown();
Shutdown the plugin.
// u8 CALLBACK SIOstartPoll(u8 value);
Starts polling data from the SIO, 'value' is
0x01, 0x21, 0x61 and 0x81 corresponding to pad, mtap, rm and mc.
Returns first byte from buffer;
// u8 CALLBACK SIOpoll(u8 value);
Returns next byte from buffer;
Refer to "pad and mem card data.txt", "padmem.txt" or
"padspecs.txt" (http://ps2dev.ps2-scene.org/padspecs.txt),
for info about value/buffer data.
// u32 CALLBACK SIOquery();
#define SIO_TYPE_PAD 0x00000001
#define SIO_TYPE_MTAP 0x00000004
#define SIO_TYPE_RM 0x00000040
#define SIO_TYPE_MC 0x00000100
returns: ORed value of SIO_TYPE_xxxx - the capabilities of the plugin
eg. a remote control plugin will return SIO_TYPE_PAD | SIO_TYPE_RM
Extended funcs
--------------
// void CALLBACK SIOconfigure();
Configure the plugin.
// void CALLBACK SIOabout();
Shows an About Dialog of the plugin.
// s32 CALLBACK SIOtest();
Returns 0 if the plugin should work ok, else -1.
SPU2 plugin API:
---------------
TODO :)
Basic funcs
-----------
// s32 CALLBACK SPU2init();
// s32 CALLBACK SPU2open(void *pDsp);
// void CALLBACK SPU2close();
// void CALLBACK SPU2shutdown();
// void CALLBACK SPU2update();
// void CALLBACK SPU2dma(u32 *dmaAddr, char *pRam);
// void CALLBACK SPU2write(u32 mem, u16 value);
// u16 CALLBACK SPU2read(u32 mem);
Extended funcs
--------------
// void CALLBACK SPU2configure();
// void CALLBACK SPU2about();
// s32 CALLBACK SPU2test();
CDVD plugin API:
---------------
Basic funcs
-----------
// s32 CALLBACK CDVDinit();
Inits the plugin, return 0 on success, else -1.
// s32 CALLBACK CDVDopen();
Opens the plugin, return 0 on success, else -1.
// void CALLBACK CDVDclose();
Close the plugin.
// void CALLBACK CDVDshutdown();
Shutdown the plugin.
// s32 CALLBACK CDVDreadTrack(u32 lsn, int mode);
Starts reading from the specified 'lsn' sector location,
return 0 on success, else -1.
// u8* CALLBACK CDVDgetBuffer();
Gets a pointer to the buffer with the sector data
readed by a previously CDVDreadTrack call.
The buffer size depends on the mode used for readTrack.
note: return can be NULL (for async modes)
// s32 CALLBACK CDVDreadSubQ(u32 lsn, cdvdSubQ* subq);
Read subq data from disc at 'lsn' location (only cds have subq data),
return 0 on success, else -1.
// s32 CALLBACK CDVDgetTN(cdvdTN *Buffer);
Get the the cdvdTN data for the currect CdRom,
return 0 on success, else -1.
// s32 CALLBACK CDVDgetTD(u8 Track, cdvdLoc *Buffer);
Get the the cdvdTD data for the 'Track' track in the current CdRom,
return 0 on success, else -1.
// s32 CALLBACK CDVDgetTOC(void* toc);
Get ps2 style toc from disc, return 0 on success, else -1.
(ps2 toc isnt quite the same as a normal disc toc,
especially for dvds)
// s32 CALLBACK CDVDgetDiskType();
Returns disktype in the format CDVD_TYPE_xxxx
// s32 CALLBACK CDVDgetTrayStatus();
Returns tray status in the format CDVD_TRAY_xxxx
// s32 CALLBACK CDVDctrlTrayOpen();
Opens disc tray, return 0 on success, else -1.
// s32 CALLBACK CDVDctrlTrayClose();
Closes disc tray, return 0 on success, else -1.
Extended funcs
--------------
// void CALLBACK CDVDconfigure();
Configure the plugin.
// void CALLBACK CDVDabout();
Shows an About Dialog of the plugin.
// s32 CALLBACK CDVDtest();
Returns 0 if the plugin should work ok, else -1.
2) FAQs
* What's the right open/close sequence?
1. CDVD
2. GS
3. PAD1/2
4. SPU2
* Where to start coding a plugin?
Get an open source plugin, mine are all open source,
so you can freely base on them.
* Why GSgifTransfer2 exists?
GSgifTransfer2 is used by the XGKICK VU1 opcode, and
it doesn't has a size, the GSgifTransfer is used by he GIF
and the VIF dmas, and it has a size, so that's why :).
3) Notes
* CDVDgetBuffer should be used after CDVDreadTrack,
like this:
CDVDreadTrack(time);
ptr = CDVDgetBuffer();
but not like this;
ptr = CDVDgetBuffer();
CDVDreadTrack(time);
* Errors should be checked for both CDVDreadTrack and CDVDgetBuffer,
and not only CDVDreadTrack.

196
Docs/Readme.txt Normal file
View File

@ -0,0 +1,196 @@
PCSX2 - A PS2 EMU
------------------
Here it is. A first try for an ps2 emulator...
Of course it isn't very advance now but there are some stuff here...
Overview
--------
Well i will try to catch up some questions.
First of all pcsx2 don't run Ps2 games yet!
And of course it is far from doing this.
So pcsx2 don't run GT3, get it? :)
So what pcsx2 is? pcsx2 is a try to emulate sony's beast.
Of course it isn't so easy as it might seems.
So far you can consider pcsx2 as a develop tool althought
i suggest don't use pcsx2 as a tool for writing your ps2dev
stuff :). Consider the opinion that pcsx2 have bugs and we
wrote this emu by reverse enginnering ps2 demos that might
have bugs too :)
Hope you enjoy pcsx2..
The Pcsx2 team..
Configuration
-------------
Cpu Options:
Misc Options:
* Enable Console Output:
Displays the psx text output.
* Enable patches
Enable the patches for games.(if they exist).
Might fix some stuff might screw some stuff.
Enable it at your own risk.
* Enable pad hack.
if your pads doesn't seem to work if you enable that much fix the pads for the specific game.
Warning!! not leave that option checked might broke some other games as well
Recompiler options:
* Disable Recompiler (default). It will run with interpreter if it is ON.
Slower but more compatible.
* Disable Vu recompiler (default). Will disable the vu recompile
(of course if recompile mode is used). More compatible recompiler but slower.
* Enable reg caching (disabled in 0.6)
Enable the reg caching recompiler (you must have enable interpeter cpu off!)
It is more faster than the default recompiler
Quick Keys:
F1: Save state
F2: Change slot (0-5)
F3: Load State
F8: Makes a Snapshot
(debugger keys)
----------------
F11 un/sets Log
F12 un/sets symbol logging
Status
------
Most part of ps2 have been emulate.
Things that are still missing or uncomplete
IPU : decoding almost done. Pcsx2 can play *.ipu or *.m2v files but no pss yet
VU : there are several issues with graphics ingames. Still we are not sure if it is GS, VIF or VU problems
but we are looking for it
recompiler: planning for fast reg cache core and recompile of vus . Soon :P
and of course a million other bugs that exists and we hope they will be fixed ;0
How you can help
----------------
If you have any info you think we can use email us, but always ask before
sending files. If you want to help in some other way also email us.
The Team
--------
Nickname | Real Name | Place | Occupation | e-mail | Comments
---------------------------------------------------------------------------------------------------------------
Linuzappz | | Argentina | Main coder | linuzappz@pcsx.net | Master of The GS emulation and so many others..
Shadow | George Moralis | Greece | co-coder-webmaster| shadowpcsx2@yahoo.gr | Master of cpu, master of bugs, general coding...
florin | Florin Sasu | Romania | co-coder | florin@pcsx2.net | Master of HLE. Master of cd code and bios HLE..
asadr | | Pakistan | co-coder | | Fixing bugs around (FPU, Interpreter, VUs...)
Goldfinger | | Brazil | co-coder | | MMI,FPU and general stuff
Nachnbrenner| | Germany | co-coder | | patch freak :P
aumatt | | co-coder | | a bit of all mostly handles CDVD cmds
loser | | Australia | co-coder | loser@internalreality.com | obscure cdvd related stuff
refraction | Alex Brown | England | co-coder | refraction@gmail.com | General Coding DMA/VIF etc
ex-coders:
basara -co-coder . Recompiler programmer. general coding
[TyRaNiD] -co-coder . GS programmer.General coding
Roor -co-coder . General coding
Additional coding:
F|RES
Pofis
Gigaherz
nocomp
BETA testers
------------
belmont
parotaku
bositman
CKemu
Raziel
Snake875
Elly
CpUMasteR
Falcon4Ever
Team like to thanks the Follow people
-------------------------------------
Duke of NAPALM - for the 3d stars demo. The first demo that worked in pcsx2 :)
Tony Saveski (dreamtime) - for his great ps2tutorials!!
F|res - You will learn more about him soon. but a big thanks from shadow..
Now3d - The guy that helped me at my first steps..
Keith - Who believed in us..
Bobbi - Thorgal: for hosting us, for design or page and some many other
Sjeep - Help and info
BGnome - Help testing stuff
Dixon - Design the new pcsx2 page, and the pcsx2.net domain
bositman - pcsx2 beta tester :) (gia sou bositman pare ta credits sou )
No-Reccess- nice guy and great demo coder :)
nsx2 team - for help to vu ;)
razorblade - for the new pcsx2 logo,icon.
snake - he knows what for :P
ector - awesome emu :)
zezu - a good guy. good luck with your emu :P
Credits
--------------
Hiryu & Sjeep - for their libcdvd (iso parsing and filesystem driver code)
Sjeep - for SjDATA filesystem driver
F|res - for the original DECI2 implementation
libmpeg2 - for mpeg2 decoding routines
aumatt - for applying fixes to pcsx2
Microsoft - for vc.net 2003 :p (really faster than vc6) :P
NASM team - for nasm
CKemu - logos/design
and probably to a few more..
Special Shadow's thanks go to...
--------------------------------
My friends : Dimitris, james, thodoris, thanasis and probably to a few more..
and of course to a lady somewhere out there....
Log off/
Linuzappz/ shadow / florin / asad/ goldfinger / nachbrenner (others???)

105
Docs/RemoteDebugging.txt Normal file
View File

@ -0,0 +1,105 @@
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ºNOTE: 1. this is an internal pcsx2 team document, for developers ONLYº
º 2. lamers/gamers are excluded º
º 3. DECI2 will not run your games:P º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
RemoteDebugging
===============
This is a new feature available for debugging applications within pcsx2 emu.
Using a remote debugger is not wellcomed unless it is more featured.
Fortunately, there are such debuggers. Currently added support is for win32
target only; also, only TCP/IP remote connection and only for Sony's DECI2
app-level protocol. Future addition could be GNU debugger remote support.
Anyway, pcsx2 has a new menu item that allows one to start a debugging session
by specifying the listen port [default for DECI2 is 8510]. Pcsx2 will act like
a server for the remote debugger. It is set to accept connections on any IP.
For local debugging sessions, use IP=127.0.0.1 aka IP=localhost. On the
other hand, if a pcsx2 would be listening on an active IP in the Internet,
anyone could connect to it;) Only one connection is supported. After the
connection is closed by the client/remote tool, the only thing to do is to
"admire" the log window and then close it/restart the emu.
So, to start a debug session:
- first start the emu [quite reasonable; because it will be the server]. There
are some issues if you start the client first or if you didn't close ALL the
client subprograms in the last debugging session.
- choose from the menu, Debug->Remote Debugging. A dialog will pop asking for
the port to use. Also, if you have a non-HLE bios selected in the Config box,
ie. a true bios, there will be also an option weather to debug the bios. You
have 2 choices:
-not checked=Run Bios
before any debug is performed a bios run. ie. the emu
will run the bios up to the shell loading or a bit
further, to the moment when all the iop modules are
loaded. You will have then a full environment loaded.
-checked=Debug Bios
nothing is done further and the PC=0xBFC00000.
- after that a connection log window will be shown and you can follow the
connection data exchange. First, the emu is placed in a wait state.
- this is the moment you have to run the client. It will open the connection.
The emu accepts the connection and the DECI2 protocol is on;)
You'll see how the client queries for registers values & memory areas.
- the situation gets complicated since you can do many things from now on:
Debug bios:
- start with a bios selected and the check box checked (see above).
- PC=0xBFC00000 and you can trace the bios now. Anyway, there is no breakpoints
support for the bios as the client "thinks" you are debugging the real PS2,
so you cannot write to bios area. BTW: the breakpoints are implemented by
patching the code with a BREAK instruction. Since you cannot write such instr
you cannot put a breakpoint on the bios, cannot run to address and so on...
Run bios:
- start with a bios selected and the check box not checked (see above).
- wait till the emu runs the bios...it will take some time. After THAT the
connection log window will be displayed.
- PC=0x82000 or smth like that...you can check the environment set up while
running the bios. The modules window for instance. And various memory
structures. Also, this is the entrypoint of the shell loading. Try to trace
it;)
Debug an application:
- start with HLEbios selected (see above)
- since the debugger (the client) does debug whatever you want to. You can
load the elf to debug with pcsx2 loader (ie. with File->Load ELF file or
from the CDVD). But you will need to know the entrypoint to force it in
remote debugger (set PC to cursor or to address). This way is not recomended.
I like to use the loader of the debugger since it knows to load the source
also if available and does not cause troubles with setting the PC. Also, if
the ELF has symbols, it can run it to main;)
- now, you're on your own. Use step by step, step over, breakpoints, run to
cursor, run to address etc. HAPPY DEBUGGING!
KNOWN ISSUES and NOTES
======================
- use CDVDnull or another plugin as you like to have or not a src for cdvd
loading;)
- pcsx2 does not have support to debug the IOP. You can do this now but it is
a hard job. That is due to the fact that PS2 can run every processor
independently (ie. one can be stopped) and pcsx2 cannot. The emu runs either
all the procs or nothing. So, in the debugger, the debugged processor is on
stop and others are "running". When there will be added support for debugging
the IOP, also only one processor will run.
- do not step through the program very fast. Because of the communication speed
and a reentrancy issue, this will get the debugger in a FALSE run state. That
means that the debugger "thinks" that the PS2 (ie. pcsx2;)) is running,
although it is not. The simple solution to this is to press STOP/BREAK button
in the debugger. Notice also that some run states might be also true! When
you are stepping over a big loop...that might take some time, so if you stop
the emu you will get in the middle of the loop:P
- you can also notice the low speed that can also be met in the pcsx2 debugger.
That's because Cpu->Step() is used.
- also, notice that you cannot debug in recompiler mode! ONLY interpreter mode
works!
- IOP modules loading is not supported and the files loaded from host directory
are also loaded in pcsx2 way, ie. from host\ directory; not through remote
debugger.
- if you try to debug the bios and the code is not displayed...scroll down
in order to have only valid addresses on the screen; ie. the top address
to be 0xBFC00000 and in emu communication log there will be no ADDRESS ERROR.
===============================
Florin (florinsasu@yahoo.com)
2003/04/17

86
Docs/RunCDVD.txt Normal file
View File

@ -0,0 +1,86 @@
RunCDVD - New feature explained
===============================
Q: What CDVD stands for?
A: It is a short form for CD/DVD i.e. CD or DVD.
----------------------------------------------------
Q: Can I run games?
A: What do you mean by games?
There are two types of games: commercial ones and homebrew ones.
There are also two types of demos: from magazines and homebrew.
Homebrew SW will run first as they are simpler and are open-source sometimes.
----------------------------------------------------
Q: Can I run commercial games?
A: Yes, but this answer is not good for you:P
You cannot play them...
Technicaly, the game starts but it does not go very far,
because this is only the beginning...
----------------------------------------------------
Q: So, what's the deal then? Is there any game that run? more?
A: Yes, but as far as we know, not any comercial game.
Homebrew iso version of PSMS runs ok.
Also we cannot test with all the games as we don't have them all:P
----------------------------------------------------
Q: When can I play game X ?
A: Dunno, only time can say that...
We only added the CDVD loading option for now.
You will have to wait for another version of the emu to see any screenshot.
----------------------------------------------------
Q: How do I run a CD/DVD game or iso/bin?
A: You need a CDVD plugin.
Get the CDVDbin for Windows & CDVDlinuz for Linux
from http://pcsx2.ngemu.com (Download section) or from http://www.ngemu.com
Place it in Plugins directory. Run the emu and in configure dialog choose
that plugin. Then Run->Execute. When using the CDVDbin plugin
you will be promted to choose a file to use.
Select the iso or the bin of the game you own.
(To test that use psms.iso)
----------------------------------------------------
Q: I have the game X on CD/DVD. What's the iso/bin stuff anyway?
A: Well, if you have a game on CD/DVD and a bad CD/DVD drive,
you can backup it on the harddisk with a CD/DVD recording program or a simple
iso/bin ripper. That program will make an image of the CD/DVD disc
on the harddisk and you can use that image with the CDVDbin plugin.
----------------------------------------------------
Q: What's the difference between .iso and .bin formats?
A: Bin is an image with raw sectors of 2352 bytes.
Iso contains only the data part from a CD sector; ie. 2048 bytes
----------------------------------------------------
Q: I have more questions. Where are the answers?
A: First of all, think twice before asking a question.
It might be already answered or the answer is toooooo simple.
Also, there can be more questions that i missed. Use the PCSX2 forum
on http://www.ngemu.com for that. Thank you!
===============================
Florin (florin@ngemu.com)

22
Docs/ToDo.txt Normal file
View File

@ -0,0 +1,22 @@
To do for Pcsx2:
* Fix threads, semas & events (linuzappz, Florin)
* Deci2: iop debug (since pcsx2 cannot run only one processor) (Florin)
tty notifications
* Continue RunCDVD option for PS1 exes loading.
* Continue Bios emulation. (linuzappz)
* Continue Recompiler. (linuzappz, basara)
* Fix bios execution. (linuzappz)
* Recheck TLBS.
* Continue HW stuff. (linuzappz)
* Fix VU code. (shadow)
* Check MMI.c.
* Check FPU code.
* Implement remaining COP0 opcodes.
* Deci2:
-speed up execution with Cpu->ExecuteBlock();
-fix reentrancy problem with threads (if pressed step button to soon,
you get a false run state: the emu is on pause, but the debugger
thinks that it is running) (solution: critical zones)
-add drfp support [i guess this will not be done as it is not really needed]
-add iop files load&run support (iloadp; not a priority also)
(Florin)

24
Docs/Translating.txt Normal file
View File

@ -0,0 +1,24 @@
Translating PCSX2
-----------------
Just some small notes for translators.
PCSX2 translations are based on the gettext library:
http://www.gnu.org/software/gettext.
The main file to translate is pcsx2.po located at the
'Intl' dir, note that you must place the translated
strings over the msgstr and leave untouched the msgid.
To test the translation use the msgfmt.exe utility to
convert the translated pcsx2.po file to a pcsx2.mo file
with this command: 'msgfmt pcsx2.po -o pcsx2.mo', after translating
the file please send it to us and please ask before
translating it, maybe someone has already started it
for your language.
If you have any problems contact us and we'll try to
help you.
linuzappz

45
Docs/What_Is_Host.txt Normal file
View File

@ -0,0 +1,45 @@
I will try to explain in sorta how HOST is working..
-----------------------------------------------------
Ps2 have the ability to use loader also other than cd-rom.
That is done through special syscall. Of course the file that
you load must support that..
Basically we wrote that for PSMS1.2
As you can see in the psms1.2 zip there is a file called psms-naplink.elf.
Well that is basically created from sjeep (hi sjeep) for be able to
use psms through your USB naplink to your ps2. (so no need to burn a cd)
Well pcsx2 does exactly that. Emulate Host +client (host is your pc,
client is your ps2).
So how is work?
---------------
Imagine that HOst is your cd-rom .
For psms e.g
place FILES.TXT + roms in folders that specificate in files.txt and you are
ready..
e.g
Host
FILES.TXT
-ROMS1
--Alienstorm.sms
--IamLamer.sms
I think you get the Idea...
For more questions mail me..(shadow@pcsx.net)
About
-----
This doc has been written from shadow...
Host support was added kindly to pcsx2 by Linuzappz
Thanks to sjeep for his psms1.2 emu and his support..
Also thanks to Keith,bobbi,thorgal,akumax,now3d and probably to some more...
Log off
shadow/linuzappz

598
Docs/WhatsNew.txt Normal file
View File

@ -0,0 +1,598 @@
*********************************
*What's new in pcsx2 v0.8 * 13th release
*********************************
General
-------
Compatibility has been increased since last release. More games go ingame now and 3d is okay in most of
them. Vurecs improved and speeded up a lot (buggy in many causes so use the simple rec for compatibility)
and IPU should work in some cases.(e.g VF4)
CPUs
----
Fixed QFSRV/MTSAH/MTSAB
Fixed SBUS IRQ at iop
Fix for end chain mode at vif
Fixed SPR0 chain mode
Fixed intc/dmac interrupts that gets cleared right away
Added offset/difference UNPACK modes in vif
VIF irq by vifcode seems ok now
Added interleave mode for SPR
Fixed UNPACK V4_5 with mask
Fixed small bug over VIF1 dma FIFO
VIF1 doens't clears str on MFIFO
Fixed some MFIFO bugs in both GS/VIF1
Fixed bug in REF/REFS dma at VIF1/GS MFIFO
IPU
---
Finally fixed IPU. Mpegs and IPU streams run so do PSS files
Quality of ipu playback improved
PLUGINS
-------
Added GSsetCSR
added CDVDreadSubQ, CDVDgetTOC, CDVDctrlTrayOpen, CDVDctrlTrayClose to cdvd
CDVD
----
Added some more debug info to CDVD
Fixed cdReadKey function to emulate correctly.
Modified GetToc stuff in cdvd to support dvds
cdvdTD uses lsn now
Fixed NVM (eeprom) access from cdvd stuff
Added reading of mecha version from an external file
Fixed raw dvd sector readng for dvd9 discs (otp and ptp)
Added hw-reg read/write for DecSet register 0x1f40203A
Made cdSeek change the current cdvd sector
Fixed NReady busy stuff
Memory
------
Added more memRead/Write funcs for speed
VUS
---
Fixed bug in branch address in vus
Implemented MFLAG for VU0
Fixed some iVUmicro bugs
Fixed some VPU-STAT related issues
Fixed vu flushing over vuExecMicro
Fixed some pipelines bug within VU1,VU0
Reworked MAX/MINI
Fixed VU's JR/JALR/BAL,ISUBIU
Added EFU pipeline to VUmicro
Fixed DIV/RSQRT exceptions
GUI
---
Some improvements on interface.
Added placetopatch == 1, which means patches will be applied every vsync
*********************************
*What's new in pcsx2 v0.7 * 12th release
*********************************
GENERAL
-------
Memcards and pads should work okay now. More compatibility earned since so many things
have been fixed from previous release :)
VIF-VUS
-------
VIF-FIFO transfers seems to work better
VU1 regs now are mapped to VU0 mem
Implemented VU0 Interlocks over CFC2/CTC2/QMFC2/QMTC2
Fixed vu branch negative overflows
VU D/T flags are handled now
VU pointer gets aligned now
PLUGINS
-------
Added Firewire plugin protocol
SPU2
----
Fixed SPU2async cycle
SPUdma timings changed to 80
CDVD
----
Implemented ReadNVM/WriteNVM
BCR now decrements for each cdvdReadSector
Fixes to SCMD's
ReadILink/GetMecaconVersion are really implemented
CdReadConfig/CdWriteConfig now uses NVM
Interface
---------
sstates now use CRC
Added IOP disasm in the debugger
Added rom2/erom support
Added Patch Browser for win32
IPU
---
Several changes for IPU
HARDWARE
--------
Fixed bug IOP counters
Fixed some bugs over interrupts and exceptions
Newer bios will now work with pcsx2. Pads fixed, more compatibility
Fixed SIF0/1 when fifo got filled up
Fixed EXL bug
Fixed SIF SMFLAG/MSFLAG
Fixed MCDS
*********************************
*What's new in pcsx2 v0.6 * 11th release
*********************************
General
-------
pcsx2 is 3 years old. Happy birthday pcsx2 :)
Now you can run even more games. some 3d games should work too . so enjoy :)
CPUS
----
Recompiled VUs. Needs work but some stuff might work okay now
Fixed bug in Vif.c, masks hopefully are ok
Fixed alot of bugs in VUs, hopefully some stuff will now work as it should
Added Interlock for CFC2/CTC2
Improvements to TLB code
Restructured VU code and VIF. Fixed stuff in Interpreter and added CTC2 VU1 Microinstruction caller
Fixed UNPACK modes in VIF, the Indeterminate fields are now set to 1 by default
VUflags now should handle overflow/userflow ok
Hardware
--------
Fixed DMA8
Fixed bug in GS for CSR stuff
Fixed savestates
Fixed several SIF bugs
FIFO is now really 128bit as it should be
Added code for dma interrupts
Added some scmds to CDVD
Improved and fixed sio2 stuff
Modified the DEV9irq stuff
loadElfFile now reads the whole file first
DMA4/7 interrupt timings are more accurate now
Patches names are now using crc
GUI
---
Memory patcher (supports only 32bit patches so far)
Fixed Bios Detection for HK Bios
PLUGINS
-------
ADDED usb plugins
*********************************
*What's new in pcsx2 v0.5 * 10th release
*********************************
General
-------
A release that make you look things more promising. Several games can boot now and plenty of them can reach even ingame.
There are still big issues with graphics but many improvements have done from 0.41. Some games that now can reach ingame
are:
wild wild racing PAL (with patches)
Street fighter ex3 PAL (with patches)
Le Mans 24 Hours (24 Heures Du Mans) PAL (with patches)
V-rally 3 pal (with patches)
and probably a lot more :)
CPUs
---
Fixes to VUs
Handle for the EDI flag at ERET(cop0)
New improved cpu detection routine
Commented D/T flags for VUmicro
fixed some FPU bugs in recompiler
fixed PCPYLD in interpreter
Add compiler blocks for vu0, vu1 and few instructions
Several other fixes in cpu cores
Reg caching recompiler (not enable in 0.5 )
Debugger
--------
Fixed Debugger/rdebugger (there are still some issues)
Memory
------
Added TLB exceptions
Fixed IOP mem accesses from EE Memory
New memory routines
VIF
---
Fixed VIF Transfers to include MARK reg in VIF0 aswell.
FIFO for VIF0/1 now works
More improvements to VifDma
Improved VIF for transfers in parts
FiFo VIF1 can read data now
IPU
---
Fixed IDEC bitstream decoding. Now, all *.ipu files should work fine
bug fixes to IPU
Hardware
--------
Fixed clock in bios
Fixed MFIFO for GS dma
CDVDgetTD function need a 2nd parametre (new cdvd plugins needed!!)
cdgetTOC + cdReadSubq
HSync stuff, and better CSR/IMR handling
Implemented mskpath3 / m3r flags
Fixed VU memory64 writes masks
Implemented INTC_STAT/MASK and DMAC_STAT for 64bits
Added/fixed SCMDs (2,3,1A) in cdvd
Vif0/1 regs are now mapped to hardware
Fixes in sio, sio2
Destination Chain for SPR0 dma and added Vif masking
Now pad2 works in lle mode [tested with bios browser]
New SCMDs and MC commands
Fixed dmaIrq's for Source Chain mode
Fixed ret DMA op
Added a base interrupt delay for the dma7 (spu2)
Fixed pads. Now it should work okay most of the times
Changed the way we handle SPR TTE transfers
MISC
----
Added the possibility to load the System.map from ps2linux
Added patching system. *pnach files are used now
Added dev9 plugins
Savestates
*********************************
*What's new in pcsx2 v0.41 * 9th release ( Update )
*********************************
General
-------
This release fixes a minor issue with the DVD iso's not booting, as of now DVD iso booting
is fixed so please try all your games again !:)
Hardware (lle)
--------
Fixed bug in CDVD code for DvdReads, now DVD iso's should boot just fine.
*********************************
*What's new in pcsx2 v0.4 * 9th release
*********************************
General
-------
This release is how we wanted the first pcsx2 release to be. Finally bios is working so
many things can happend from now on. Also "Bust a Move" seems to work and other games
like Kengo 2 goes much further. All of course is done in LLE now :) .
CPUS
----
fix the recompiler bug that made recompiler not to work in pcsx2 0.3
new vu code. VU0 macromode should be perfect now.
new optimaze code for fpu
Rewrote VIF once again
bug fixes to MMI
reorganize recompiler
DMAS
----
Improved SIF0,SIF1,SRP1
Added IPU0,IP1 dmas
IPU
---
Added decoding and commands. Some samples are working. NO pss support yet!
IOP
---
improved the IOP stuff.IOP is functional under bios execution :)
HLE
---
more WIP in Threads .Much better now
more WIP in padman.
Hardware (lle)
--------
ADDED SPU2 functions. SPU2 is now possible if someone implement a SPU2 plugin.
Changed a bit the GS protocol. Gs plugins need to modificate in order to work with 0.4
SIO2 added .Pads seems to work . Memcard partial functional
CDVD emulation added.
IOP rootcounters fixed
IOP dmas implemented
MFIFO implemented
General
------
Fixed elf loader
*********************************
*What's new in pcsx2 v0.3 * 8th release
*********************************
General
-------
This version of pcsx is the first that shows ingame progress from 1 game "Sven Goran's World Manager 2002".IT is the first
ps2 emu that reaches ingame :) . Also this version have Deci2 support (usefull only for developers althought) and several
bugs have been fixed. Enjoy ;)
GUI
---
-Added MiltuLingual support( English,Catalan,German,greek,italiano,romanian,spanish)
CPUS
----
-Fake BC0 opcodes in cop0
-Trap instructions fixed in interpreter
-Fixed some fpu bugs in interpreter
-Fixed MMI bugs in interpreter
-VIF1 cmd now handles the i bit, still not 100% correct
-VIF1dma now handles 'from Memory' transfers
-More Unpack case in vif
-fixed several VIF1 bugs
-VIF0 fixed also
Hardware
--------
-8 bit DMAS
-mem128 read/write routines
-Implemented latency interrupt thingy
-Fixes to rootcounters
-FIFO fix
-IOPmem fix
-optimaze gs dma
Debugging
---------
-DECI 2 Protocol !!
-fix some stuff in pcsx2 debugger
-add cpu ops debug in debugger
-Logging to STDOUT added
-add more memory mapping for EE and IOP
HLE
---
-rewrote of HLE code for pads (padman-xpadman). This will solve some pad problems
-rewrote the HLE code for Loadmodule
-New INTC handling in HLE bios
-Implement VSyncSetFlag in HLE bios
-Added memory dummies in mcserv. Now memcards wil be appear as functional.
-sceCDReadIOPm in CDVD HLE
-Added dummy handles for mtapman901/3
-new Threads at BIOS HLE. Still not finished
*********************************
*What's new in pcsx2 v0.2 * 7th release
*********************************
General
-------
pcsx2 have now a more speedy recompiler using 3dnow-3dnow2-sse instructions. Vu macromode
have been recompiled with 3d now instructions so you can see more speed there if you have a
cpu that supports 3d now. The most speed is possible with an Athlon XP cpu or a Althon 4 mobile
More support for sse or probably for sse2 soon :)
rewrite of MMI
fix bugs in fileio
fix counters
new thread HLE code
fixes to CDVD HLE code
fixes-adds to VU code More vu opcodes
add some more cpu opcodes
more ipu code
add 3dnow-3dnow2-sse instructions to recompiler
*********************************
*What's new in pcsx2 v0.1 * 6th release
*********************************
General
-------
PSMS cd version seems to work. Pgen starts to work also.. (no roms seems to working althought)
and some games might boot now... This is the first ps2 emu that boots cds :)
GUI
---
Added command line parsing for main's argc
Added ps2 bios check for config dialog
Memory
------
Some more adds to memory maps
CPUS
----
Implement VU flags + some more vu0-vu1 opcodes
Fix some VIF unpack cases
Some more opcodes to R5900
HLE
---
better HLE +
RPC services for
014D704Enaplink
0B001337cdvd
80000001fileio
80000003sysmem
80000592cdvdfsv
80000597cdvdfsv
80000595cdvdfsv
+for some more but mostly dummies
CDVD iso parser (thanks Sjeep - hiryu)
support for SJDATA file system
*********************************
*What's new in pcsx2 v0.042 * 5th release
*********************************
GENERAL COMMENTS
----------------
Micromode works at the release. Also some more macromode demo should
work on this release.Enjoy ;)
NOTE: Logging has been disable from the release. If you need it
Mail me ( shadow@ngemu.com)
GUI
---
-ADD CDVD plugin (partially)
-change a bit the controller plugin protocol
-change a bit the GS plugin protocol (for the VUmicromode transfers)
CPUS
----
-FIXES to R5900
-FIXES to FPU
-More work in recompiler
-ADDS+fixes opcodes for MMI
-Rewritten/updated iop code
-More work to micromode (vu0-vu1)
DMA
---
-More to VIFS DMA
-More to SIFS DMA
-----------------------------------------------------------------------
*********************************
*What's new in pcsx2 v0.038 * 4th release
*********************************
GENERAL COMMENTS
----------------
Vu0 appears functional now. (Most of the causes )
CPUS
----
Fixes to main R5900.Many opcodes fixed ( thanks Goldfinger)
Fixes to FPU
Add some Framework for the IPU
Add some more opcodes to the recompiler including FPU opcodes
Debugger
--------
Logging system
BIOS HLE
--------
some support for sjpcm.irx
Fixed fileio for dummy files
-----------------------------------------------------------------------
*********************************
*What's new in pcsx2 v0.036 * 3rd release
*********************************
Debugger
-------
-Add VU0 - VU1 register window
-Add VU0 macromode in disasm (still not finished)
-Added support for Symbols
GUI
---
-Add SPU2 interface (very partial)
-change GS specifications a bit
CPUS
----
-Fixed some bugs in R5900.c
-Improve recompiler
-Add VIF0 - VIF1 (very partial)
-Add more VU0 macromode instructions
-Add IOP proccesor (partial)
-Add More opcodes in MMI
-better COP0 emulation (more tlbs)
DMA
---
-add Stratchpad DMAS
-add VIF dmas
-add SIF dmas (very partial)
Memory
------
-Total rewrite to support more HW
BIOS HLE
--------
Many more syscall is hle now. Compatibility increase a lot
General
------
Many stuff that we are not able to explain them in details :)
-----------------------------------------------------------------------
*********************************
*What's new in pcsx2 v0.031 * 2nd release
*********************************
-New icon
-New logo
-Some startup work on VU0.Many VUO macromode opcodes
-Some more opcodes in the main cpu. MFSA,MTSA,SQC2,LQC2
-More opcodes to the MMI.
-Finished R5900 FPU.
-pad emulation using HLE.. both pad1 + pad2
-more fixes to Recompiler (still far from finish)
-add the 4 Couters(partial)
-add FIFO registers
-Add support for HOST
-----------------------------------------------------------------------
*********************************
*What's new in pcsx2 v0.026 * 1st release
*********************************
FIRST RELEASE ALL ARE NEW :)

273
Docs/devblog.txt Normal file
View File

@ -0,0 +1,273 @@
Developers Blog
===============
This file is mainly an R&D document containing developers findings. The aim is
to have it as much accurate as possible. Each item has to contain a number(ID),
the name of developer, revisions history and a short description.
Also, this document will serve as a pinboard - will contain coding rules,
explanations on implementation of different parts of the emulator, suggestions,
questions and ideas.
==============================================================================
==============================================================================
==============================================================================
[ ID ] 4
[name] Florin
[desc] PS2 info dumping project
[hist] 2006-05-08 initial version
The emulator needs some information from a Playstation2 console.
We used to require the 'bios' software. In order to get better results
more and more information was needed. So here are some guidelines
on what we need and what we don't need from the console.
Also, a new dumper and handling of these infos in the emu are in work.
a. The so-called 'bios', is actualy rom0 found in consoles, devkits,
test-kits and PSX at address 0xBFC00000 on both EE and IOP.
[!] Note that on 75xxx the EE side bios mismatch zone fields,
so it is recomended to make a IOP side dump.
b. Rom1 and Erom contain DvdPlayer related software and are located
starting with 0xBE000000 on PS2s from 18000 and up. Over various
versions, the size of rom1 and size and position of erom changed.
They used to be dumped separately, the new dumper will simplify this,
there'll only one file containing both rom1 and erom (2M or 4M).
[!] Note that on 70xxx and 75xxx (PStwo's) the dumping of erom from EE
is not possible, the correct dump is done only from IOP!
[!] rom1 and erom are identical for same generation for all zones.
In order to be able to run the dvdplayer code in the emulator, it needs
to be pre-decrypted. EROMDRV and DVDELF will have some 'decrypt' patches.
c. NVM (Non Volatile Memory) is 1K of code and provide valuable info about
console model and region. 10000 and 15000 don't contain the model name.
PStwo's contain the zone codes making possible to have a single version
of the rom for all zones.
d. Rom2 is found only in Chinese PS2s (50009, 70009...) and contains
a font file: GB18030. It is located at 0xBE400000. It was (w/o
justification) assumed that it is as big as rom1. There is no need to
dump it on any other console than chinese. The size is to be calculated
from the filesystem (as rom0 and rom1, it has romfs).
e. BBA (BroadBand Adapter) info is not needed to be dumped. At least not
for the emulator itself, maybe for the DEV9 plugin. Anyway, it's just
a MAC address that can be made up.
f. The current dumper is reading CDVD Mecha version. This will be replaced
by a more complete information file that will contain the following info:
from [EE]
CPU revision - revision code from COP0->PRId register
easier read from (u16)GetCop0(15)
high byte is 0x2E for EE
low byte is: high nibble major, low nibble minor of revision
FPU revision - revision code from COP1->control register 0
same description as for cpu PRId
VUs revision - hum, i'm not aware of any revision for them :(
VUs memory - local and micro memory sizes are not detected
GS revision - upper halfword in CSR register
high byte is ID = 0x55
low bytes is major.minor (per nibbles)
GS mem - is 4M
IPU revision - hum, i'm not aware of any revision for IPU :(
Caches - instruction and data cache sizes are read from
COP0->Config register
easier read from GetCop0(16).
MEM - total RAM available
easier read with Syscall +127 - GetMemorySize()
the values are: 32M for console and test-kits,
128M for devkits and 64M for PSX
the size is not roughly detected. As devkits have multiple
boot modes (128M or 64M).
from [IOP]
CPU revision - revision code from COP0->PRId register
high byte seems to be 0
low byte is major.minor (per nibbles)
initial japs have major=1,
most of the consoles have major=2,
75xxx have a new IOP processor with major=3
Caches - are known to be 4K-I$; 1K-D$
0xFFFE0130 is CACHE_CONFIG register...
MEM - total RAM available
easier to read with QueryMemSize()
the values are: 2M for consoles and test-kits,
8M for devkits and PSX
again, the size is incorrectly read :)
SPU mem - 2M (any method of detection?)
CDVD mecha - version of CDVD controller
Scmd 0x03 with subcode 0x00 (outsize=4)
the first byte is the MG-encryption code
second is major, third is minor, fourth is [2b completed]
meka - i don't know; not supported on early consoles
Scmd 0x03 with subcode 0x90 (outsize=1+1)
DEV9 revision- type of DEV9 device: 0x2x for PCMCIA, 0x3x for EXPBAY
*(vu16*)BF80146E
USB OHCI rev - Hc_revision of the OHCI controller
*(vu32*)0xBF801600
ILINK rev/id - I'm not sure of this one, on ps2's that don't have
firewire anymore, the value is 0xFF; on 10000 is random
*(vu32*)0xBF808480 and *(vu32*)0xBF808500 (looks like mirror)
g. The dumper will sign the dumped content, so John Doe cannot play easily
with the bios data ;) The emu works correctly with good data/food.
h. I'm thinking of a method to check for modified content (dumps made with a
chipped console). Probably, it will be done in the emu and presented as a
warrning.
==============================================================================
==============================================================================
==============================================================================
[ ID ] 3
[name] auMatt
[desc] PS2 NVM Data not 100%
[hist] 2006-05-07 initial version
³v0-v8 ³ v9- ³ Bits ³ Bytes º
ÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍØÍÍÍÍÍÍÍØÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
ÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍØÍÍÍÍÍÍÍØÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
PS1 Disc Spd ³ 0x300 ³ 0x2c0 ³ ³ º
PS1 Texture ³ 0x300 ³ 0x2c0 ³ ³ º
Video Output ³ 0x300 ³ 0x2c0 ³ ³ º
SPDIF ³ 0x310 ³ 0x2c0 ³ 0 ³ º
A/R ³ 0x310 ³ 0x2c0 ³ 1 & 2 ³ º
Language ³ 0x311 ³ 0x2c1 ³ All ³ º
TimeZone ³ 0x312 ³ 0x2c2 ³ ³ º
Summer Time ³ 0x312 ³ 0x2c2 ³ 3 ³ º
Time Format ³ 0x312 ³ 0x2c2 ³ 5 ³ º
DateNotation ³ 0x312 ³ 0x2c2 ³ 6 & 7 ³ º
TimeZone ³ 0x313 ³ 0x2c3 ³ All ³ º
TimeZone ³ 0x315 ³ 0x2c5 ³ All ³ º
Model Number ³ 0x1a0 ³ 0x1b0 ³ ³ 16 º
Console ID ³ 0x1c8 ³ 0x1f0 ³ ³ 8 º
ILink ID ³ 0x1c0 ³ 0x1e0 ³ ³ 8 º
Date Stamp ³ 0x180 ³ ³ ³ 16 º
Date Stamp ³ 0x1e0 ³ ³ ³ 16 º
Date Stamp ³ 0x1f0 ³ ³ ³ 16 º
Rem. Control ³ ³ 0x2c4 ³ 5 ³ º
Checksum ³ 0x31f ³ 0x2cf ³ All ³ º
Checksum is calculated by the previous 15 bytes added together, then ANDed with 0xFF
Serial Number of Console can be obtained from bytes 7,6 & 5 of the Console ID in dec.
==============================================================================
==============================================================================
==============================================================================
[ ID ] 2
[name] Florin
[desc] PS2 bios versioning
[hist] 2006-04-30 initial version
MG zone - the MagicGate decryption zone. You can find the code as one of the bits
in the byte at offset +1C in MagicGate encrypted files
PS1 drv - the letter for PS1VERx files in PStwo rom0
ROMVER - has the following format VVvvZTYYYYMMDD in 14 bytes
VV, vv are the version of the bios in BCD
Z is zone code, see below
T is type of the console: C - consumer console, D - devkit/test console
YYYYMMDD is date of the bios
- BxDATA-SYSTEM, BxEXEC-SYSTEM, BxEXEC-DVDPLAYER uses Z code in place of 'x'
I: default, Japan; A: Usa, Asia; E: Europe, Oceania, Russia; C: China
VERSTR - the code from that file in rom0
OSDVER - VVvvZlng is the format of the file for scph5xxxx. in PStwo the last 4 letters
are read from NVM, offset +180 7 chars (ROMVER:1|OSDVER:4|VERSTR:1|DVDID:1)
mecha - version read from CDVD SCmd 0x03:0x00
The following table is far from complete...
³Japan ³ USA ³AusNz ³ UK ³Europe³Korea ³ HK ³Taiwan³Russia³China ³Mexic º
ÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍ͹
ÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍ͹
MG zone ³ 0/J ³ 1/U ³ 3/O ³ 2/E ³ 2/E ³ 4/A ³ 4/A ³ 4/A ³ 5/R ³ 6/C ³ 7/M º
PS1 drv ³ J ³ A ³ E ³ E ³ E ³ H ³ H ³ H ³ E ³ C ³ A º
ROMVER ³0 J ³1 A ³2 E ³2 E ³2 E ³1 H ³1 H ³1 H ³2 E ³3 C ³1 A º
VERSTR ³ J ³ A ³ E ³ E ³ E ³ J ³ J ³ J ³ E ³ J ³ A º
OSDVER ³0 Jjpn³1 Aeng³2 Eeng³2 Eeng³2 Eeng³5 Kkor³6 Htch³6 Htch³4 Rrus³3 Csch³ Aspa?º
ÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
v0 scph³10000 ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
mecha³0.12.0ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
ver³0100JCÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
date³000117ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
scph³15000 ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
mecha³0.18.0ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
ver³0101JCÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
date³000217ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
scph³18000 ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
mecha³0.22.0ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
ver³0120JCÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
date³001027ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
ÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍ͹
v1 scph³30000 ³30001 ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
v2 ³30000 ³30001 ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
v3 ³30000 ³30001 ³30002 ³30003 ³30004 ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
ÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍ͹
v4 scph³30000 ³30001 ³30002 ³30003 ³30004 ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
mecha³ ³ ³ ³ ³ ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
ver³ ³ ³ ³0120EC³ ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
date³ ³ ³ ³000902³ ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
³35000 ³35001 ³35002 ³35003 ³35004 ³35005 ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
ÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍ͹
v5 ³30000 ³30001 ³30002 ³30003 ³30004 ³30005 ³ ³ ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
scph³30000R³30001R³30002R³30003R³30004R³30005R³30006R³30007RÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
mecha³0.32.0³ ³ ³2.32.0³ ³ ³ ³ ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
ver³0160JC³ ³ ³0160EC³0160EC³ ³ ³ ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
date³011004³ ³ ³011004³011004³ ³ ³ ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
v6 ³ ³ ³ ³ ³ ³ ³ ³ ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
ÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍ͹
v7 scph³37000 ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
³39000 ³39001 ³39002 ³39003 ³39004 ³39005 ³39006 ³39007 ³39008 ÃÄÄÄÄÄÄÅÄÄÄÄÄĶ
mecha³ ³1.36.0³ ³ ³ ³ ³ ³ ³ ÃÄÄÄÄÄÄÅÄÄÄÄÄĶ
ver³ ³0160AC³ ³ ³ ³ ³ ³ ³ ÃÄÄÄÄÄÄÅÄÄÄÄÄĶ
date³ ³020207³ ³ ³ ³ ³ ³ ³ ÃÄÄÄÄÄÄÅÄÄÄÄÄĶ
ÃÄÄÄÄÄÄ´39001NÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄ´39010Nº
ÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
v8 scph³39000 ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄ´39006 ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
mecha³0.38.0³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
ver³0160JC³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
date³020426³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º
ÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍ͹
v9 scph³50000 ³50001 ³50002 ³50003 ³50004 ³50005N³50006 ³50007 ³50008 ³50009 ÃÄÄÄÄÄĶ
ÃÄÄÄÄÄÄ´50001NÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄ´50010Nº
³55000 ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄ´55005N³55006 ³55007 ÃÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
ÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄĶ
v10 scph³ ³50001 ³50002 ³50003 ³50004 ³ ³50006 ³50007 ³ ³50009 ³50010 º
mecha³ ³ ³ ³ ³ ³ ³4.54.0³4.??.0³ ³6.??.0³ º
ver³ ³ ³ ³ ³0190EC³ ³0190HC³0190HC³ ³0190CC³ º
date³ ³ ³ ³ ³030623³ ³030623³030623³ ³030623³ º
v11 ³ ³ ³ ³ ³50004 ³ ³ ³ ³ ³ ³ ºMexic USA
ÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍÎÍÍÍÍÍÍÑÍÍÍÍÍÍ»
v12 scph³70000 ÃÄÄÄÄÄÄ´70002 ³70003 ³70004 ³70005 ³70006 ³70007 ³70008 ³70009 ÃÄÄÄÄÄÄ´70011 ³70012 º
mecha³ ÃÄÄÄÄÄÄ´3.62.0³2.62.0³2.??.0³ ³4.64.0³ ³5.??.0³ ÃÄÄÄÄÄÄ´ ³1.60.0º
ver³0200JCÃÄÄÄÄÄÄ´0200EC³0200EC³0200EC³ ³0200HC³ ³0200EC³ ÃÄÄÄÄÄÄ´ ³0200ACº
date³040614ÃÄÄÄÄÄÄ´040614³040614³040614³ ³040614³ ³040614³ ÃÄÄÄÄÄÄ´ ³040614º
v13 scph³ ³70001 ³70002 ³70003 ³70004 ³ ³ ³ ³ ³ ³ ÌÍÍÍÍÍÍÏÍÍÍÍÍͼ
ÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍ͹
v14 scph³75000 ³75001 ³75002 ³75003 ³75004 ³75005 ³75006 ³75007 ³75008 ÃÄÄÄÄÄÄ´75010 º
mecha³ ³1.66.0³3.66.0³ ³ ³ ³ ³ ³ ÃÄÄÄÄÄÄ´ º
ver³ ³0220AC³0220EC³ ³ ³ ³ ³ ³ ÃÄÄÄÄÄÄ´ º
date³ ³050620³050620³ ³ ³ ³ ³ ³ ÃÄÄÄÄÄÄ´ º
ÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄĽ
==============================================================================
==============================================================================
==============================================================================
[ ID ] 1
[name] Florin
[desc] CVS management rules
[hist] 2006-04-30 initial version
Please do not commit on CVS temporary files or those made by development tools
(IDEs). Eg: *.suo/aps/opt/plg/ncb/exp
Keep it clean and before commiting a new module see the previous structure and
naming rules. If unsure about how to do any opperation please ASK. please ASK!
There's no rush ;)
Also, I'm considering switching to SVN, as CVS seems to be *abandoned* by
sourceforge.net
Any change to sources has to be commited to the public CVS. The risk of
stealing is faced by any open-source developer - the difference is the
quality! The original will always stand up ;)
Try not to break the source by your patches. Although linux and 64-bit versions
are not maintained atm, your changes should be done with all versions in mind.
Happy coding :)

View File

@ -0,0 +1,112 @@
Changes made to make v0.9 work in Linux:
Common.h - PCSX2_MULTICORE undefined.
In my version of linux, spinlocks are bleeding edge calls, and not
implemented as standard. There may be a #define that can be used, but
as it would likely include either a kernel rebuild or thread library,
I hadn't bothered.
Misc.c - SYNC_LOGGING undefined
I suspect because of PCSX2_MULTICORE being undefined, "g_mtxLog"
didn't get defined either.
Interpreter.c - all "_controlfp" calls commented out.
I suspect a .h file is missing for the above call.
Vif.c - Control of MMX, SSE, SSE2 (and SSE3) instructions.
Presence of the above CPU intrinsic calls can be detected using
__MMX__, __SSE__, __SSE2__, and __SSE3__. Header dependancies are
as follows:
__MMX__ can stand alone.
__SSE__ needs __MMX__.
__SSE2__ needs __SSE__ (which needs __MMX__)
__SSE3__ needs __SSE2__ and __SSE__ (which needs __MMX__)
Each of these flags can be used to load their own set of functions
as well as loading all functions in the dependant headers...
__MMX__ - #include <mmintrin.h>
__SSE__ - #include <xmmintrin.h>
__SSE2__ - #include <emmintrin.h>
__SSE3__ - #include <pmmintrin.h>
Since no tests for the above flags were conducted before loading
emmintrin.h, I blocked out that section of code with an "#if 0" line.
IPU/IPU.c - After finding out that a dozen mutexes were set here without
PCSX2_MULTICORE blocking, I went back to Common.h and turned back on
PCSX2_MULTICORE. I knew now I would have to hunt down all instances of
spinlocks and replace them with straight mutexes.
R5900.h lines 150-167 - Spinlock defines commented out.
R5900.c lines 32-38 - Spinlock define commented out.
IPU/IPU.c - invalid initializer - NULL on pthread_mutex_t / pthread_cond_t
Separated the variables initialized. Hunted up valid initializers in
pthread documentation in Linux.
__declspec() - In Common.h, I told Linux to ignore all references to this
function. #pragma pack(16) and/or __attribute__ ((?)) might be a better
choice for this. A couple of compiler flags also control byte alignment.
For dynamically allocatable blocks, memalign() might work.
Note: for 64 bit compiles (like athlon64), 16 byte alignment is assumed.
EBUSY undeclared - This relates to the define DESTROY_MUTEX in Common.h.
Included <errno.h> in Common.h so EBUSY is defined.
__forceinline - placed "#define __forceinline inline" in Common.h as Linux
has no equivlent (that I know of) to this.
IPU/Idct.o - no target
Moved to IPU/mpeg2lib. Adjusted Makefile to find it.
IPU/Mpeg.o - no target
Moved to IPU/mpeg2lib. Adjusted Makefile to find it.
VifDma.c - See Vif.c for complaints about __SSE__ detection.
Linux/Config.c - no member "PadHack"
Seems it was removed from the "Config" structure. Commented out the
set/get commands for it.
x86/iVU0micro.c line 494 - too many arguments in 'vurecAnalyzeBlock'
This might be leftover code from a testrun. I removed the extra 'old'
variables.
x86/iVU1micro.c - all "_controlfp" commands commented out.
See Interpreter.c above for details.
Then I finally got to the Link portion of the compiler...
Hw.o:
_aligned_malloc() is not defined in Linux. memalign() was obsoleted.
POSIX now recommends posix_memalign(boundary, size) from <stdlib.h>
for accurate boundary allocation... and working free() calls.
_aligned_free(), companion to the call above, is also not defined in
Linux. Fortunately, posix_memalign() only needs a free() call.
Both of the above was defined in Common.h
IPU/IPU.o:
couldn't find pthread_... calls. Added -lpthread to $(LIBS) in Makefile
FPU.o:
Certain math calls were added from <math.h>. FPU2.cpp compiles those
calls... and adds a C interface to get to them. Included FPU2.o in the
object list in the Makefile.
R5900.o:
pthread_mutex__unlock()? I thought it was just 1 underline there. Didn't
take any chances, though. Put in a define in Common.h to change it to
pthread_mutex_unlock().
Left to fix:
x86/iVUmicro.o:
__assume(0): I don't know what this is used for.
R5900.o:
InterlockedAnd(), InterlockedExchange(): Are these grouped mutex calls?
VifDma.o:
SetNewMask(), g_vif1Masks(), g_vif0Masks():
These were sliced off when I cut SSE off. Some work could bring them
back in, if they're needed for non-MMX/SSE/SSE2/SSE3 refrencing...
This doesn't even guarentee that once just these problems are fixed, the
compiled program will run. I only looked at compiling/linking.
efp - Feb 16, 2006

229
Docs/pcsx2_faq.txt Normal file
View File

@ -0,0 +1,229 @@
PPPP CCCC SSS X X 2222
P P C C S S X X 2 2
P P C S X X 2
P P C S X X 2
P P C S X X 2
P P C SSS X 2
PPPP C S X X 2
P C S X X 2
P C S X X 2
P C C S S X X 2
P CCCC SSS X X 2222222
****************
*PCSX2 FAQ v0.1*
****************
This FAQ has been written for PCSX2 v0.6
FAQ Written by: CKemu & shadow
_________________________________________________________
Q: What is PCSX2?
A: PCSX2 is a WIP PS2 (PlayStation 2) emulator, written by
linuzappz, shadow, florin. basara, asadr, goldfinger. PCSX2 is
constantly WIP (work in progress), and is in the early
stages of development (so don't expect much yet ;) ).
Q: Why doesn't XYZ game work?
A: PCSX2 is able to get many games to show 'screens'. Some of the games can reach ingame
and less more can be consider playable. Speed is too slow on many of them so 'viewable' is
a beter way to describe it :)
Q: Why don't these games work?
A: PCSX2 is in the early stages of development. It can run some games (many of them without glitches)
but the speed issue prevent us of making the emu more compatible.
Q: Where abouts do I find these demos?
A:You can find some demos at http://pcsx2.ngemu.com or
http://ps2dev.livemedia.com.au. There are proberbly more
sites with PS2 homebrew demos.
Q: Does PCSX2 require a 'real' PS2 BIOS.
A: PCSX2 can use a 'real' BIOS, and is preferable to HLE
BIOS as it is more compatible. But HLE does work well
with many homebrew demos.
Q: Why not use HLE?
A: HLE is a difficult thing to do for a PS2. Game
developers use their own modules for each game. That
would mean we would have to HLE each module. This would
be a massive task, and not a good idea, as emulating
the real BIOS will mean compatibility with all released
games.
Q: Where do I get a BIOS?
A: You can dump the BIOS from your own PS2, DO NOT ask us
or anyone else for a BIOS, the BIOS is copyright of SONY
and is illegal to download, so we won't help you with
that.
Q: I try to run a game, or the BIOS, but nothing happens!
A: If no BIOS screen shows from attempting to run a
CD/DVD, your BIOS maybe incorrect. Go to
'config>configure', and under the BIOS menu, check that
firstly you haven't got the HLE BIOS selected, if you do
change to a 'real' BIOS. If you have a 'real' BIOS
selected and it still doesn't work, check that NO
percentage is written next to the BIOS, if it is for
instance "40%", your BIOS is to small (by 60%), or
corrupt (by 60%), you may need to redump it. Also if no
'real' BIOS is listed, check its not compressed 'eg
*.zip / *.rar' and extract it to the BIOS dir (note
sub-folders NOT supported, it must be in /BIOS/).
If that is not the case, your BIOS isn't an actual PS2
BIOS. To ensure that doesn't happen, dump your own ;)
Q: I see lots of glitches with games/demos, why?
A: Incomplete emulation of the GS, Vector Units etc, this
is a WIP emulator, and will have many bugs for some time,
until more is known about the PS2 hardware. Things
generally improve with each release, so you never know,
it may be fixed in the next release.
Q: How can I help fix these bugs?
A: Report these bugs to us, post at the offical PCSX2
forums at http://www.ngemu.com. Make a post describing
the bug/glitch, perhaps with a screenshot showing it,
and details on your system setup, what plugins your
using etc.
If you find any other bugs, with regards to the debugger,
plugins, or differences between what you see in the
emulator and a real PS2, feel free to email us.
Q: How can I help develop for PCSX2?
A: You can find the open-source plugins at
http://pcsx2.ngemu.com , coding a GS plugin or and SPU2
plugin would help us greatly. Also if you have any
technical information on the PS2, please email us,
anyhelp is greatly appreciated.
Q: Your emulator sucks!! I don't want to use it!
A: Then don't, buy a real PS2. If you don't like it,
just don't and there is no need to tell us you don't
like it, the PCSX2 team put alot of hardwork into this
emulator, and don't care to know.
Q: Can you give me some more 'technical' answers?
A: A technical FAQ would be massive, and take months to
write. Instead email shadow / linuz with your questions.
Q: When is the next release?
A: The next release will happen when there is something
to show, internal changes, and technical changes don't
mean anything to the user, if they don't see something.
Pestering us will make no difference :P
Q: GSsoft is s..l..o..w!!
A: Then use one of the OpenGL plugins found at our site
http://pcsx2.ngemu.com or the GStaris plugin
( http://gstaris.ngemu.com ).
Q: The emulator even with GStaris / GSmax is slow! Why?
A: First of all, the PS2 is a powerfull piece of
hardware, and will require a powerfull machine to achive
NEAR correct speeds,
Given that PCSX2 does not run any 'complex' commercial
games, it is hard to judge the system requirements that
will be eventually needed. Plugins and Emulator will get
faster as new releases are made, but you can improve
preformance by turning OFF "Enable Console Output" and
"Enable Interpreter CPU" under 'config>CPU>' in the menu.
Q: Do I need a DVD drive?
A: Yes, if you want to read a DVDrom you will need a DVD
drive, many PS2 games are written to CDrom, so its not
essential, unless you have a DVD based game you wish to
try.
You can also use 'Linuz's CDVD ISO' plugin to run PS2
games in ISO / BIN format from your HDD. Note only
NTFS Format drives (eg not FAT32) can store greater than
4GB in a single file.
Q: I hear no sound!
A: SPU2 Plugins are being worked on by a few coders, but
as of now the only SPU2 plugin is nullSPU, which outputs
no sound, If you are a coder, and feel you can help with
SPU2, please email us.
Q: Where can I get help!!!
A: You can get help from the people over at
http://www.ngemu.com or on IRC. Using an IRC client, log
onto #PCSX2 or #NGEMU (EFnet). You can politly ask for
help there (No BIOS / ROM / ISO requests, or you shall be
banned). If you cannot get help there, email the PCSX2
team.
_________________________________________________________
This FAQ was based on shadow's original FAQ, so thanks to
him. This was written to clear up some of the basic
questions you may have, and I hope it was of help.
Written with very little sleep and too much coffee, so
please excuse the mistakes, they will be fixed shortly :D
************
*Thanks to:*
************
The PCSX2 team for making me a betatester, and providing us
with a fantastic PS2 emulator, and the opportinity for me to
work on SPU2 (highly WIP :P )
shadow, Linuzappz, Absolute0, [Tyranid], F|res, Roor,
Goldfinger, Florin, basara, asadr, CpUmaster, snake785,
mike9010, bositman, DWatcher, Keith, Martin64.....and many
more I am sure :D
My lady, Lucy. Without her I would be lost.
Coffee, where would we be without coffee :D
**********
*Contact:*
**********
If you think I should add something to this FAQ, or you
spotted a bug, you can contact me (CKemu) via IRC in
the #PCSX2 (EFnet) channel.
You can contact the authors via:
http://pcsx2.ngemu.com (homepage)
http://www.pcsx2.net (homepage)
http://www.ngemu.com (offical forums)
or on IRC:
#PCSX2 (EFnet)
Enjoy PCSX2!!
Best Regards CKemu ( http://www.ckemu.com ).
/EOF/

159
Docs/specs.tex Normal file
View File

@ -0,0 +1,159 @@
\documentclass[10pt]{article}
\begin{document}
\section{...stuff...}
-order the plugins are started\\
-platform dependent stuff, calling convention\\
\section{Generic functions}
The following three functions will be present in all the plugin libraries,
in order to be recognized as valid PS2E plugins. They will help
the emulator to find a plugin capabilities.
\subsection{PS2EgetLibType}
\begin{quote}\texttt{unsigned int} PS2EgetLibType(\texttt{void});\end{quote}
\begin{description}
\item[PS2EgetLibType] returns the type of the plugin.
In fact it indicates the APIs supported by the dynamic library.
The returned value can be one of:
\begin{itemize}
\item PS2E\_LT\_GS 0x01
\item PS2E\_LT\_PAD 0x02
\item PS2E\_LT\_SPU2 0x04
\item PS2E\_LT\_CDVD 0x08
\item PS2E\_LT\_DEV9 0x10
\end{itemize}
Currently, these are the only plugin types supported. Note that the values
can be ORed.
\end{description}
\subsection{PS2EgetLibVersion2}
\begin{quote}\texttt{unsigned int} PS2EgetLibVersion2(\texttt{unsigned int}
type);\end{quote}
\begin{description}
\item[PS2EgetLibVersion2] returns a combination of version numbers.
Parameter \emph{type} is used to select the functions set for which
the emulator requests version information. See \texttt{PS2EgetLibType}
for the values of this parameter.
The 5 APIs and their corresponding specs have changed over time.
In order to prevent crashes and incompatibilities, a spec version have
been introduced as the highest 16 bits of the returned value.
\begin{itemize}
\item PS2E\_GS\_VERSION 0x0002
\item PS2E\_PAD\_VERSION 0x0002
\item PS2E\_SPU2\_VERSION 0x0002
\item PS2E\_CDVD\_VERSION 0x0003
\item PS2E\_DEV9\_VERSION 0x0001
\end{itemize}
Notice that when the specs do change \texttt{and} the compatibility is broken,
this version number is increased. The emulator loading code will support
only one version for a certain library type at a time. If the internal
version and plugin API version does not match, the plugin
will not be loaded nor used.
The low half of the returned value reflects the version of the plugin itself.
A major.minor versioning scheme is used on the two bytes like this:
\begin{verbatim}
...//code
return (PS2E_CDVD_VERSION<<16) | (0<<8) | (67); //version 0.67
\end{verbatim}
\end{description}
\subsection{PS2EgetLibName}
\begin{quote}\texttt{char*} PS2EgetLibName(\texttt{void});\end{quote}
\begin{description}
\item[PS2EgetLibName] returns a string that contains a short\footnote{
less then 30 chars in one line} name. The string is stored
in the plugin and will be used to represent the plugin in a config dialog.
\end{description}
\section{CDVD functions}
This section describes the functions that corresponds to CDVD\footnote{short for CD/DVD}
API - type PS2E\_LT\_CDVD(0x08).
These specs are for PS2E\_CDVD\_VERSION(0x0003).
\subsection{CDVDinit}
\begin{quote}\texttt{int} CDVDinit(\texttt{void});\end{quote}
\begin{description}
\item[CDVDinit] does the initialization of the CDVD interface.
It is the first function called; so, it can be used to do all the
init stuff such as reading saved configuration, one-time hardware init and
preparing the internal structures, tables, etc\ldots
If an error is found the function will return -1, otherwise 0.
\end{description}
\subsection{CDVDshutdown}
\begin{quote}\texttt{void} CDVDshutdown(\texttt{void});\end{quote}
\begin{description}
\item[CDVDshutdown] is called when the emulator is closed. Do now the freeing
operations. DO NOT FORGET TO FREE the resources used. The OS will probably
free the garbage left, but some pieces of hardware might need a
``deinitialization'' procedure in order to work next time the emulator
is run. Imagine that the user will choose another plugin to run with
next time instead of yours, do not cause troubles.
\end{description}
\subsection{CDVDopen}
\begin{quote}\texttt{int} CDVDopen(\texttt{void});\end{quote}
\begin{description}
\item[CDVDopen] is called when the emulation starts.
It is recommended that functions called from now on (until
\texttt{CDVDclose} is met) to spend few processing time. Avoid calling
blocking functions and if you do, the user should be notified visualy.
Report errors by return value and warrings using a log.
If an error is found the function will return -1 and the emulation stops,
otherwise 0.
Do not report errors using message boxes while the emu runs, the GS plugin
might use a display mode that can cause troubles to windowing system
in showing your message.
\end{description}
\subsection{CDVDclose}
\begin{quote}\texttt{void} CDVDclose(\texttt{void});\end{quote}
\begin{description}
\item[CDVDclose] is called when the emulation is stopped. Some of the
resources that you aquired with \texttt{CDVDstart} have to be released now
in order that other programs to use them. If you locked the CD/DVD tray,
unlock it so the user can change the disc.
\end{description}
\subsection{CDVDreadTrack}
\begin{quote}\texttt{int} CDVDreadTrack(\texttt{unsigned int}
lsn, \texttt{int} mode);\end{quote}
\begin{description}
\item[CDVDreadTrack] is the function that performs the read of \texttt{a}
sector from the CD/DVD. Parameter \emph{lsn} specifies the absolute value
of the sector number in linear addressing mode without \emph{lead-in}\footnote{i.e.\
without leading 150 sectors == 2 seconds}. Usualy, the plugin will read
a full sector of 2352 bytes in its internal buffer.
The second parameter tells what port of ...
\end{description}
\end{document}

34
Docs/threads.txt Normal file
View File

@ -0,0 +1,34 @@
OK -> done & tested
---- -> not applicable
xxxx -> dummy
32łCreateThread ş OK ł----ł
33łDeleteThread ş----ł ł
34łStartThread ş----ł OK ł
35łExitThread ş----ł ł
36łExitDeleteThread ş----ł ł
37łTerminateThread ş----ł ł
38łiTerminateThread ş ł ł
39łDisableDispatchThread şxxxxłxxxxł
40łEnableDispatchThread şxxxxłxxxxł
41łChangeThreadPriority ş----ł OK ł
42łiChangeThreadPriority ş OK ł----ł
43łRotateThreadReadyQueue ş----ł ł
44łiRotateThreadReadyQueue ş ł ł
45łReleaseWaitThread ş----ł ł
46łiReleaseWaitThread ş ł ł
47łGetThreadId ş OK ł----ł
48łReferThreadStatus ÍÍť ş OK ł----ł
49łiReferThreadStatus ÍÍź ş OK ł----ł
50łSleepThread ş----ł ł
51łWakeupThread ş----ł ł
52łiWakeupThread ş ł ł
53łCancelWakeupThread ÍÍť şdoneł----ł
54łiCancelWakeupThread ÍÍź şdoneł----ł
55łSuspendThread ÍÍť ş ł ł
56łiSuspendThread ÍÍź ş ł ł
57łResumeThread ş----ł ł
58łiResumeThread ş ł ł
59łJoinThread şxxxxłxxxxł
60łRFU060_InitializeMainThreadş OK ł----ł
61łRFU061_InitializeHeapArea ş OK ł----ł
62łEndOfHeap ş OK ł----ł

40
EEregs.h Normal file
View File

@ -0,0 +1,40 @@
/* 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 __EEREGS_H__
#define __EEREGS_H__
#define at cpuRegs.GPR.n.at
#define k0 cpuRegs.GPR.n.k0
#define k1 cpuRegs.GPR.n.k1
#define v0 cpuRegs.GPR.n.v0
#define v1 cpuRegs.GPR.n.v1
#define a0 cpuRegs.GPR.n.a0
#define a1 cpuRegs.GPR.n.a1
#define a2 cpuRegs.GPR.n.a2
#define a3 cpuRegs.GPR.n.a3
#define t0 cpuRegs.GPR.n.t0
#define s0 cpuRegs.GPR.n.s0
#define gp cpuRegs.GPR.n.gp
#define fp cpuRegs.GPR.n.s8
#define sp cpuRegs.GPR.n.sp
#define ra cpuRegs.GPR.n.ra
#define pc0 cpuRegs.pc
#endif /* __EEREGS_H__ */

660
Elfheader.c Normal file
View File

@ -0,0 +1,660 @@
/* 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
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //2002-09-28 (Florin)
#include <sys/stat.h>
#include "Common.h"
#include "CDVDisodrv.h"
u32 ElfCRC;
typedef struct {
u8 e_ident[16]; //0x7f,"ELF" (ELF file identifier)
u16 e_type; //ELF type: 0=NONE, 1=REL, 2=EXEC, 3=SHARED, 4=CORE
u16 e_machine; //Processor: 8=MIPS R3000
u32 e_version; //Version: 1=current
u32 e_entry; //Entry point address
u32 e_phoff; //Start of program headers (offset from file start)
u32 e_shoff; //Start of section headers (offset from file start)
u32 e_flags; //Processor specific flags = 0x20924001 noreorder, mips
u16 e_ehsize; //ELF header size (0x34 = 52 bytes)
u16 e_phentsize; //Program headers entry size
u16 e_phnum; //Number of program headers
u16 e_shentsize; //Section headers entry size
u16 e_shnum; //Number of section headers
u16 e_shstrndx; //Section header stringtable index
} ELF_HEADER;
typedef struct {
u32 p_type; //see notes1
u32 p_offset; //Offset from file start to program segment.
u32 p_vaddr; //Virtual address of the segment
u32 p_paddr; //Physical address of the segment
u32 p_filesz; //Number of bytes in the file image of the segment
u32 p_memsz; //Number of bytes in the memory image of the segment
u32 p_flags; //Flags for segment
u32 p_align; //Alignment. The address of 0x08 and 0x0C must fit this alignment. 0=no alignment
} ELF_PHR;
/*
notes1
------
0=Inactive
1=Load the segment into memory, no. of bytes specified by 0x10 and 0x14
2=Dynamic linking
3=Interpreter. The array element must specify a path name
4=Note. The array element must specify the location and size of aux. info
5=reserved
6=The array element must specify location and size of the program header table.
*/
typedef struct {
u32 sh_name; //No. to the index of the Section header stringtable index
u32 sh_type; //See notes2
u32 sh_flags; //see notes3
u32 sh_addr; //Section start address
u32 sh_offset; //Offset from start of file to section
u32 sh_size; //Size of section
u32 sh_link; //Section header table index link
u32 sh_info; //Info
u32 sh_addralign; //Alignment. The adress of 0x0C must fit this alignment. 0=no alignment.
u32 sh_entsize; //Fixed size entries.
} ELF_SHR;
/*
notes 2
-------
Type:
0=Inactive
1=PROGBITS
2=SYMTAB symbol table
3=STRTAB string table
4=RELA relocation entries
5=HASH hash table
6=DYNAMIC dynamic linking information
7=NOTE
8=NOBITS
9=REL relocation entries
10=SHLIB
0x70000000=LOPROC processor specifc
0x7fffffff=HIPROC
0x80000000=LOUSER lower bound
0xffffffff=HIUSER upper bound
notes 3
-------
Section Flags: (1 bit, you may combine them like 3 = alloc & write permission)
1=Write section contains data the is be writeable during execution.
2=Alloc section occupies memory during execution
4=Exec section contains executable instructions
0xf0000000=Mask bits processor-specific
*/
typedef struct {
u32 st_name;
u32 st_value;
u32 st_size;
u8 st_info;
u8 st_other;
u16 st_shndx;
} Elf32_Sym;
#define ELF32_ST_TYPE(i) ((i)&0xf)
typedef struct {
u32 r_offset;
u32 r_info;
} Elf32_Rel;
//unfinished!!!!
char *sections_names;
ELF_HEADER *elfHeader;
ELF_PHR *elfProgH;
ELF_SHR *elfSectH;
char *name;
u8 *elfdata;
u32 elfsize;
struct stat sbuf;
struct TocEntry toc;
//2002-09-19 (Florin)
char args[256]="ez.m2v"; //to be accessed by other files
unsigned int args_ptr; //a big value; in fact, it is an address
//in a0 is passed the address of the command line args,
//i.e. a pointer to an area like this:
//+00 unknown/unused
//+04 argc; number of arguments
//+08 argv[0]; address of the first parameter - program name (char*) -
//+08 argv[1]; address of the second parameter (char*) |
//+0C argv[2]; and so on |
//........ |
//+08+4*argc the program name(first param) <--
//+08+4*argc+strlen(argv[0]+1) the rest of params; i.e. a copy of 'args'
// see above 'char args[256];'
unsigned int parseCommandLine( char *filename )
{
if ( ( args_ptr != 0xFFFFFFFF ) && ( args_ptr > 264 ) )
{ // 4 + 4 + 256
char * p;
int argc,
i;
args_ptr -= 256;
if ( args_ptr < 0 )
{
return 0;
}
args[ 255 ] = 0;
memcpy( &PS2MEM_BASE[ args_ptr ], args, 256 ); //params 1, 2, etc copied
memset( &PS2MEM_BASE[ args_ptr + strlen( args ) ], 0, 256 - strlen( args ) );
#ifdef __WIN32__
p = strrchr( filename, '\\' );
#else //linux
p = strrchr( filename, '/' );
#endif
if ( p )
{
p++;
}
else
{
p = filename;
}
args_ptr -= strlen( p ) + 1;
if ( args_ptr < 0 )
{
return 0;
}
strcpy( (char*)&PS2MEM_BASE[ args_ptr ], p ); //fill param 0; i.e. name of the program
for ( i = strlen( p ) + 1 + 256, argc = 0; i > 0; i-- )
{
while ( i && ( ( PS2MEM_BASE[ args_ptr + i ] == 0 ) || ( PS2MEM_BASE[ args_ptr + i ] == 32 ) ) )
{
i--;
}
if ( PS2MEM_BASE[ args_ptr + i + 1 ] == ' ' )
{
PS2MEM_BASE[ args_ptr + i + 1 ] = 0;
}
while ( i && ( PS2MEM_BASE[ args_ptr + i ] != 0 ) && ( PS2MEM_BASE[ args_ptr + i] != 32 ) )
{
i--;
}
if ( ( PS2MEM_BASE[ args_ptr + i ] != 0 ) && ( PS2MEM_BASE[ args_ptr + i ] != 32 ) )
{ //i==0
argc++;
if ( args_ptr - 4 - 4 - argc * 4 < 0 )
{
return 0;
}
((u32*)PS2MEM_BASE)[ args_ptr / 4 - argc ] = args_ptr + i;
}
else
{
if ( ( PS2MEM_BASE[ args_ptr + i + 1 ] != 0 ) && ( PS2MEM_BASE[ args_ptr + i + 1 ] != 32 ) )
{
argc++;
if ( args_ptr - 4 - 4 - argc * 4 < 0 )
{
return 0;
}
((u32*)PS2MEM_BASE)[ args_ptr / 4 - argc ] = args_ptr + i + 1;
}
}
}
((u32*)PS2MEM_BASE)[ args_ptr /4 - argc - 1 ] = argc; //how many args
((u32*)PS2MEM_BASE)[ args_ptr /4 - argc - 2 ] = ( argc > 0); //have args? //not used, cannot be filled at all
return ( args_ptr - argc * 4 - 8 );
}
return 0;
}
//---------------
int readFile( char *Exepath, char *ptr, u32 offset, int size ) {
FILE *f;
int fi;
if ((strnicmp( Exepath, "cdrom0:", strlen("cdrom0:")) == 0) ||
(strnicmp( Exepath, "cdrom1:", strlen("cdrom0:")) == 0)) {
if ((u32)offset >= toc.fileSize) return -1;
fi = CDVDFS_open(Exepath + strlen("cdromN:"), 1);//RDONLY
if (fi < 0) return -1;
CDVDFS_lseek(fi, offset, SEEK_SET);
size = CDVDFS_read(fi, ptr, size);
CDVDFS_close(fi );
} else {
f = fopen(Exepath, "rb");
if (f == NULL) return -1;
if ( offset >= (u64)sbuf.st_size) return -1;
fseek(f, offset, SEEK_SET);
size = fread(ptr, 1, size, f);
fclose(f);
}
return size;
}
int loadHeaders( char *Exepath ) {
elfHeader = (ELF_HEADER*)elfdata;
if ( ( elfHeader->e_shentsize != sizeof(ELF_SHR) ) && ( elfHeader->e_shnum > 0 ) ) {
SysMessage( "size of section header not standard\n" );
}
if((elfHeader->e_shnum * elfHeader->e_shentsize) != 0) {
elfSectH = (ELF_SHR *) malloc( elfHeader->e_shnum * elfHeader->e_shentsize );
} else {
elfSectH = NULL;
}
if ( ( elfHeader->e_phnum * elfHeader->e_phentsize ) != 0 ) {
elfProgH = (ELF_PHR *) malloc( elfHeader->e_phnum * elfHeader->e_phentsize );
} else {
elfProgH = NULL;
}
#ifdef ELF_LOG
ELF_LOG( "type: " );
#endif
switch( elfHeader->e_type )
{
default:
#ifdef ELF_LOG
ELF_LOG( "unknown %x", elfHeader->e_type );
#endif
break;
case 0x0:
#ifdef ELF_LOG
ELF_LOG( "no file type" );
#endif
break;
case 0x1:
#ifdef ELF_LOG
ELF_LOG( "relocatable" );
#endif
break;
case 0x2:
#ifdef ELF_LOG
ELF_LOG( "executable" );
#endif
break;
}
#ifdef ELF_LOG
ELF_LOG( "\n" );
ELF_LOG( "machine: " );
#endif
switch ( elfHeader->e_machine )
{
default:
#ifdef ELF_LOG
ELF_LOG( "unknown" );
#endif
break;
case 0x8:
#ifdef ELF_LOG
ELF_LOG( "mips_rs3000" );
#endif
break;
}
#ifdef ELF_LOG
ELF_LOG("\n");
ELF_LOG("version: %d\n",elfHeader->e_version);
ELF_LOG("entry: %08x\n",elfHeader->e_entry);
ELF_LOG("flags: %08x\n",elfHeader->e_flags);
ELF_LOG("eh size: %08x\n",elfHeader->e_ehsize);
ELF_LOG("ph off: %08x\n",elfHeader->e_phoff);
ELF_LOG("ph entsiz: %08x\n",elfHeader->e_phentsize);
ELF_LOG("ph num: %08x\n",elfHeader->e_phnum);
ELF_LOG("sh off: %08x\n",elfHeader->e_shoff);
ELF_LOG("sh entsiz: %08x\n",elfHeader->e_shentsize);
ELF_LOG("sh num: %08x\n",elfHeader->e_shnum);
ELF_LOG("sh strndx: %08x\n",elfHeader->e_shstrndx);
ELF_LOG("\n");
#endif
return TRUE;
}
BOOL loadProgramHeaders( char *Exepath )
{
int i;
if ( elfHeader->e_phnum == 0 )
{
return TRUE;
}
// is this critical, or warning?
if ( elfHeader->e_phentsize != sizeof( ELF_PHR ) )
{
SysMessage( "size of program header not standard\n" );
}
elfProgH = (ELF_PHR*)&elfdata[elfHeader->e_phoff];
for ( i = 0 ; i < elfHeader->e_phnum ; i++ ) {
#ifdef ELF_LOG
ELF_LOG( "Elf32 Program Header\n" );
ELF_LOG( "type: " );
#endif
switch ( elfProgH[ i ].p_type ) {
default:
#ifdef ELF_LOG
ELF_LOG( "unknown %x", (int)elfProgH[ i ].p_type );
#endif
break;
case 0x1:
#ifdef ELF_LOG
ELF_LOG("load");
#endif
if (elfProgH[ i ].p_offset < elfsize) {
int size;
if ((elfProgH[ i ].p_filesz + elfProgH[ i ].p_offset) > elfsize) {
size = elfsize - elfProgH[ i ].p_offset;
} else {
size = elfProgH[ i ].p_filesz;
}
memcpy(&PS2MEM_BASE[elfProgH[ i ].p_paddr & 0x1ffffff],
&elfdata[elfProgH[ i ].p_offset],
size);
#ifdef ELF_LOG
ELF_LOG("\t*LOADED*");
#endif
}
break;
}
#ifdef ELF_LOG
ELF_LOG("\n");
ELF_LOG("offset: %08x\n",(int)elfProgH[i].p_offset);
ELF_LOG("vaddr: %08x\n",(int)elfProgH[i].p_vaddr);
ELF_LOG("paddr: %08x\n",elfProgH[i].p_paddr);
ELF_LOG("file size: %08x\n",elfProgH[i].p_filesz);
ELF_LOG("mem size: %08x\n",elfProgH[i].p_memsz);
ELF_LOG("flags: %08x\n",elfProgH[i].p_flags);
ELF_LOG("palign: %08x\n",elfProgH[i].p_align);
ELF_LOG("\n");
#endif
}
return TRUE;
}
BOOL loadSectionHeaders( char * Exepath )
{
int i;
int i_st = -1;
int i_dt = -1;
if (elfHeader->e_shnum == 0 ||
elfHeader->e_shoff > elfsize) {
return TRUE;
}
elfSectH = (ELF_SHR*)&elfdata[elfHeader->e_shoff];
if ( elfHeader->e_shstrndx < elfHeader->e_shnum ) {
sections_names = (char *)&elfdata[elfSectH[ elfHeader->e_shstrndx ].sh_offset];
}
for ( i = 0 ; i < elfHeader->e_shnum ; i++ ) {
#ifdef ELF_LOG
ELF_LOG( "Elf32 Section Header [%x] %s", i, &sections_names[ elfSectH[ i ].sh_name ] );
#endif
if ( elfSectH[i].sh_flags & 0x2 ) {
//2002-09-19 (Florin)
args_ptr = min( args_ptr, elfSectH[ i ].sh_addr & 0x1ffffff );
//---------------
/* if (elfSectH[i].sh_offset < elfsize) {
int size;
if ((elfSectH[i].sh_size + elfSectH[i].sh_offset) > elfsize) {
size = elfsize - elfSectH[i].sh_offset;
} else {
size = elfSectH[i].sh_size;
}
memcpy(&PS2MEM_BASE[ elfSectH[ i ].sh_addr &0x1ffffff ],
&elfdata[elfSectH[i].sh_offset],
size);
}
#ifdef ELF_LOG
ELF_LOG( "\t*LOADED*" );
#endif*/
}
#ifdef ELF_LOG
ELF_LOG("\n");
ELF_LOG("type: ");
#endif
switch ( elfSectH[ i ].sh_type )
{
default:
#ifdef ELF_LOG
ELF_LOG("unknown %08x",elfSectH[i].sh_type);
#endif
break;
case 0x0:
#ifdef ELF_LOG
ELF_LOG("null");
#endif
break;
case 0x1:
#ifdef ELF_LOG
ELF_LOG("progbits");
#endif
break;
case 0x2:
#ifdef ELF_LOG
ELF_LOG("symtab");
#endif
break;
case 0x3:
#ifdef ELF_LOG
ELF_LOG("strtab");
#endif
break;
case 0x4:
#ifdef ELF_LOG
ELF_LOG("rela");
#endif
break;
case 0x8:
#ifdef ELF_LOG
ELF_LOG("no bits");
#endif
break;
case 0x9:
#ifdef ELF_LOG
ELF_LOG("rel");
#endif
break;
}
#ifdef ELF_LOG
ELF_LOG("\n");
ELF_LOG("flags: %08x\n", elfSectH[i].sh_flags);
ELF_LOG("addr: %08x\n", elfSectH[i].sh_addr);
ELF_LOG("offset: %08x\n", elfSectH[i].sh_offset);
ELF_LOG("size: %08x\n", elfSectH[i].sh_size);
ELF_LOG("link: %08x\n", elfSectH[i].sh_link);
ELF_LOG("info: %08x\n", elfSectH[i].sh_info);
ELF_LOG("addralign: %08x\n", elfSectH[i].sh_addralign);
ELF_LOG("entsize: %08x\n", elfSectH[i].sh_entsize);
#endif
// dump symbol table
if ( elfSectH[ i ].sh_type == 0x02 )
{
i_st = i;
i_dt = elfSectH[i].sh_link;
}
}
if ( ( i_st >= 0 ) && ( i_dt >= 0 ) )
{
char * SymNames;
Elf32_Sym * eS;
SymNames = (char*)&elfdata[elfSectH[ i_dt ].sh_offset];
eS = (Elf32_Sym*)&elfdata[elfSectH[ i_st ].sh_offset];
SysPrintf("found %d symbols\n", elfSectH[ i_st ].sh_size / sizeof( Elf32_Sym ));
for ( i = 1; i < (int)( elfSectH[ i_st ].sh_size / sizeof( Elf32_Sym ) ); i++ ) {
if ( ( eS[ i ].st_value != 0 ) && ( ELF32_ST_TYPE( eS[ i ].st_info ) == 2 ) ) {
// SysPrintf("%x:%s\n", eS[i].st_value, &SymNames[eS[i].st_name]);
disR5900AddSym( eS[i].st_value, &SymNames[ eS[ i ].st_name ] );
/* if (!strcmp(&SymNames[eS[i].st_name], "sceSifCheckStatRpc")) {
psMu32(eS[i].st_value & 0x1ffffff) = (0x3b << 26) | 1;
SysPrintf("found sceSifCheckStatRpc!!\n");
}*/
}
}
}
return TRUE;
}
extern int LoadPatch(char *patchfile);
extern void LoadGameSpecificSettings();
int loadElfFile(char *filename) {
char str[256];
char str2[256];
u32 crc;
u32 i;
SysPrintf("loadElfFile: %s\n", filename);
if (strnicmp( filename, "cdrom0:", strlen( "cdrom0:" ) ) &&
strnicmp( filename, "cdrom1:", strlen( "cdrom1:" ) ) ) {
if ( stat( filename, &sbuf ) != 0 )
return -1;
elfsize = sbuf.st_size;
} else {
CDVDFS_init( );
if ( CDVD_findfile( filename + strlen( "cdromN:" ), &toc ) == -1 )
return -1;
elfsize = toc.fileSize;
}
SysPrintf("loadElfFile: %d\n", elfsize);
elfdata = (u8*)malloc(elfsize);
if (elfdata == NULL) return -1;
readFile(filename, (char*)elfdata, 0, elfsize);
/* {
FILE *f = fopen("game.elf", "wb");
fwrite(elfdata, 1, elfsize, f);
fclose(f);
}*/
//2002-09-19 (Florin)
args_ptr = 0xFFFFFFFF; //big value, searching for minimum
//-------------------
loadHeaders( filename );
cpuRegs.pc = elfHeader->e_entry; //set pc to proper place
loadProgramHeaders( filename );
loadSectionHeaders( filename );
#ifdef ELF_LOG
ELF_LOG( "PC set to: %8.8lx\n", cpuRegs.pc );
#endif
cpuRegs.GPR.n.sp.UL[0] = 0x81f00000;
cpuRegs.GPR.n.gp.UL[0] = 0x81f80000; // might not be 100% ok
//2002-09-19 (Florin)
cpuRegs.GPR.n.a0.UL[0] = parseCommandLine( filename );
//---------------
for ( i = 0; i < 0x100000; i++ ) {
if ( strcmp( "rom0:OSDSYS", (char*)PSM( i ) ) == 0 ) {
strcpy( (char*)PSM( i ), filename );
SysPrintf( "addr %x \"%s\" -> \"%s\"\n", i, "rom0:OSDSYS", filename );
}
}
//CRC
for (i=0, crc=0; i<elfsize/4; i++) {
crc^= ((u32*)elfdata)[i];
}
ElfCRC = crc;
SysPrintf("loadElfFile: %s; CRC = %8.8X\n", filename, crc);
// Applying patches
if (Config.Patch) {
sprintf(str, "%8.8x", crc);
#ifdef __WIN32__
sprintf(str2,"patches not found can't apply patches crc=%8.8x",crc);//if patches found it will overwritten :p
if (gApp.hConsole) SetConsoleTitle(str2);
#endif
if(LoadPatch(str)!=0)
{
SysPrintf("XML Loader returned an error. Trying to load a pnach...\n");
inifile_read(str);
}
else SysPrintf("XML Loading success. Will not load from pnach...\n");
applypatch( 0 );
}
free(elfdata);
LoadGameSpecificSettings();
return 0;
}
extern int g_VUSignedZero;
extern int g_FFXHack;
extern int g_VUExtraFlags;
void LoadGameSpecificSettings()
{
if( ElfCRC==0x0c414549 ) { // spacefisherman
g_VUSignedZero = 1;
}
if( ElfCRC == 0x4C9EE7DF || ElfCRC == 0xC9C145BF ) { // crazy taxi
g_VUExtraFlags = 1;
}
// ffx, ffx2, harvest moon
if(ElfCRC==0xbb3d833a||ElfCRC==0xa39517ab||ElfCRC==0x6A4EFE60||ElfCRC==0x48FE0C71||ElfCRC==0x9aac530d||
ElfCRC==0x9AAC5309||ElfCRC==0x8A6D7F14||ElfCRC==0x304C115C||ElfCRC==0xF0A6D880||ElfCRC==0xa39517ae||
ElfCRC==0xa39517a9||ElfCRC==0x941bb7d9||ElfCRC==0x9AAC530B||ElfCRC==0x658597e2||ElfCRC==0x941BB7DE) {
g_FFXHack = 1;
}
}

30
Elfheader.h Normal file
View File

@ -0,0 +1,30 @@
/* 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 __ELF_H__
#define __ELF_H__
//2002-09-20 (Florin)
extern char args[256]; //to be filled by GUI
extern unsigned int args_ptr;
//-------------------
int loadElfFile(char *filename);
extern u32 ElfCRC;
#endif

174
FPU.c Normal file
View File

@ -0,0 +1,174 @@
/* 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
*/
#include <math.h>
#include "Common.h"
#include "R5900.h"
#include "InterTables.h"
// Helper Macros
//****************************************************************
#define _Ft_ ( ( cpuRegs.code >> 16 ) & 0x1F )
#define _Fs_ ( ( cpuRegs.code >> 11 ) & 0x1F )
#define _Fd_ ( ( cpuRegs.code >> 6 ) & 0x1F )
#define _FtValf_ fpuRegs.fpr[ _Ft_ ].f
#define _FsValf_ fpuRegs.fpr[ _Fs_ ].f
#define _FdValf_ fpuRegs.fpr[ _Fd_ ].f
#define _FAValf_ fpuRegs.ACC.f
#define _ContVal_ fpuRegs.fprc[ 31 ]
// Testing
#define _FtValUl_ fpuRegs.fpr[ _Ft_ ].UL
#define _FsValUl_ fpuRegs.fpr[ _Fs_ ].UL
#define _FdValUl_ fpuRegs.fpr[ _Fd_ ].UL
#define _FAValUl_ fpuRegs.ACC.UL
//****************************************************************
void COP1() {
#ifdef FPU_LOG
FPU_LOG("%s\n", disR5900F(cpuRegs.code, cpuRegs.pc));
#endif
Int_COP1PrintTable[_Rs_]();
}
/*********************************************************
* Load and store for COP1 *
* Format: OP rt, offset(base) *
*********************************************************/
void LWC1() {
s32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s16)(cpuRegs.code);// ((cpuRegs.code & 0x8000 ? 0xFFFF8000 : 0)| (cpuRegs.code & 0x7fff));
memRead32(addr, &fpuRegs.fpr[_Rt_].UL);
}
void SWC1() {
s32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s16)(cpuRegs.code);//((cpuRegs.code & 0x8000 ? 0xFFFF8000 : 0)| (cpuRegs.code & 0x7fff));
memWrite32(addr, fpuRegs.fpr[_Rt_].UL);
}
void COP1_BC1() {
Int_COP1BC1PrintTable[_Rt_]();
}
void COP1_S() {
Int_COP1SPrintTable[_Funct_]();
}
void COP1_W() {
Int_COP1WPrintTable[_Funct_]();
}
void COP1_Unknown() {
#ifdef FPU_LOG
FPU_LOG("Unknown FPU opcode called\n");
#endif
}
void MFC1() {
if ( !_Rt_ ) return;
cpuRegs.GPR.r[_Rt_].UD[0] = (s32)_FsValUl_;
}
void CFC1() {
if ( !_Rt_ || ( _Fs_ != 0 && _Fs_ != 31 ) ) return;
cpuRegs.GPR.r[_Rt_].UD[0] = (s32)fpuRegs.fprc[_Fs_];
}
void MTC1() {
_FsValUl_ = cpuRegs.GPR.r[_Rt_].UL[0];
}
void CTC1() {
if(_Fs_!=31) return;
fpuRegs.fprc[_Fs_] = cpuRegs.GPR.r[_Rt_].UL[0];
}
#define C_cond_S(cond) \
_ContVal_ = ( _FsValf_ cond _FtValf_ ) ? \
( _ContVal_ | 0x00800000 ) : \
( _ContVal_ & ~0x00800000 );
void C_F() { _ContVal_ &= ~0x00800000;} //clears C regardless
void C_EQ() { C_cond_S(==); }
void C_LT() { C_cond_S(<); }
void C_LE() { C_cond_S(<=); }
#define BC1(cond) \
if ( ( _ContVal_ & 0x00800000 ) cond 0 ) { \
intDoBranch( _BranchTarget_ ); \
}
void BC1F() { BC1(==); }
void BC1T() { BC1(!=); }
#define BC1L(cond) \
if ( ( _ContVal_ & 0x00800000 ) cond 0 ) { \
intDoBranch( _BranchTarget_ ); \
} else cpuRegs.pc += 4;
void BC1FL() { BC1L(==); } // Equal to 0
void BC1TL() { BC1L(!=); } // different from 0
void ADD_S() { _FdValf_ = _FsValf_ + _FtValf_; }
void SUB_S() { _FdValf_ = _FsValf_ - _FtValf_; }
void MUL_S() { _FdValf_ = _FsValf_ * _FtValf_; }
void MOV_S() { _FdValf_ = _FsValf_; }
void NEG_S() { _FdValf_ = -_FsValf_; }
void ADDA_S() { _FAValf_ = _FsValf_ + _FtValf_; }
void SUBA_S() { _FAValf_ = _FsValf_ - _FtValf_; }
void MULA_S() { _FAValf_ = _FsValf_ * _FtValf_; }
void MADD_S() { _FdValf_ = _FAValf_ + ( _FsValf_ * _FtValf_ ); }
void MSUB_S() { _FdValf_ = _FAValf_ - ( _FsValf_ * _FtValf_ ); }
void MADDA_S() { _FAValf_ += _FsValf_ * _FtValf_; }
void MSUBA_S() { _FAValf_ -= _FsValf_ * _FtValf_; }
void ABS_S() { _FdValf_ = fpufabsf(_FsValf_); }
void MAX_S() { _FdValf_ = max( _FsValf_, _FtValf_ ); }
void MIN_S() { _FdValf_ = min( _FsValf_, _FtValf_ ); }
void DIV_S() { if ( _FtValf_ ) { _FdValf_ = _FsValf_ / _FtValf_; } }
void SQRT_S() {
//if ( _FtValf_ >= 0.0f ) { _FdValf_ = fpusqrtf( _FtValf_ ); }
//else {
_FdValf_ = fpusqrtf(fpufabsf(_FtValf_));
//}
}
void CVT_S() { _FdValf_ = (float)(s32)_FsValUl_; }
void CVT_W() {
if ( ( _FsValUl_ & 0x7F800000 ) <= 0x4E800000 ) { _FdValUl_ = (s32)(float)_FsValf_; }
else if ( _FsValUl_ & 0x80000000 ) { _FdValUl_ = 0x80000000; }
else { _FdValUl_ = 0x7fffffff; }
}
void RSQRT_S() {
if ( _FtValf_ >= 0.0f ) {
float tmp = fpusqrtf( _FtValf_ );
if ( tmp != 0 ) { _FdValf_ = _FsValf_ / tmp; }
}
}
//3322 2222 2222 1111 1111 1100 0000 0000
//1098 7654 3210 9876 5432 1098 7654 3210
//0000 0000 0000 0000 0000 0000 0000 0000

25
FPU2.cpp Normal file
View File

@ -0,0 +1,25 @@
#include <math.h>
// sqrtf only defined in C++
extern "C" {
float (*fpusqrtf)(float fval) = 0;
float (*fpufabsf)(float fval) = 0;
float (*fpusinf)(float fval) = 0;
float (*fpucosf)(float fval) = 0;
float (*fpuexpf)(float fval) = 0;
float (*fpuatanf)(float fval) = 0;
float (*fpuatan2f)(float fvalx, float fvaly) = 0;
void InitFPUOps()
{
fpusqrtf = sqrtf;
fpufabsf = fabsf;
fpusinf = sinf;
fpucosf = cosf;
fpuexpf = expf;
fpuatanf = atanf;
fpuatan2f = atan2f;
}
}

177
FiFo.c Normal file
View File

@ -0,0 +1,177 @@
/* 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
*/
//well that might need a recheck :P
//(shadow bug0r work :P)
//plz, change this file according to FIFO defs in hw.h
/* u64 VIF0[0x1000];
u64 VIF1[0x1000];
u64 GIF[0x1000];
u64 IPU_out_FIFO[0x160]; // 128bit
u64 IPU_in_FIFO[0x160]; // 128bit
*/
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "Common.h"
#include "Hw.h"
#include "GS.h"
#include <assert.h>
//////////////////////////////////////////////////////////////////////////
/////////////////////////// Quick & dirty FIFO :D ////////////////////////
//////////////////////////////////////////////////////////////////////////
extern int FIFOto_write(u32* pMem, int size);
extern void FIFOfrom_readsingle(void *value);
extern int g_nIPU0Data;
extern u8* g_pIPU0Pointer;
extern int FOreadpos;
// NOTE: cannot use XMM/MMX regs
void ReadFIFO(u32 mem, u64 *out) {
if ((mem >= 0x10004000) && (mem < 0x10005000)) {
#ifdef VIF_LOG
VIF_LOG("ReadFIFO VIF0 0x%08X\n", mem);
#endif
out[0] = psHu64(mem );
out[1] = psHu64(mem+8);
return;
} else
if ((mem >= 0x10005000) && (mem < 0x10006000)) {
#ifdef PCSX2_DEVBUILD
VIF_LOG("ReadFIFO VIF1 0x%08X\n", mem);
if( vif1Regs->stat & (VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS) ) {
SysPrintf("reading from vif1 fifo when stalled\n");
}
#endif
if (vif1Regs->stat & 0x800000) {
if (--psHu32(D1_QWC) == 0) {
vif1Regs->stat&= ~0x1f000000;
} else {
}
}
out[0] = psHu64(mem );
out[1] = psHu64(mem+8);
return;
} else if( (mem&0xfffff010) == 0x10007000) {
if( g_nIPU0Data > 0 ) {
out[0] = *(u64*)(g_pIPU0Pointer);
out[1] = *(u64*)(g_pIPU0Pointer+8);
FOreadpos = (FOreadpos + 4) & 31;
g_nIPU0Data--;
g_pIPU0Pointer += 16;
}
return;
}else if ( (mem&0xfffff010) == 0x10007010) {
FIFOfrom_readsingle((void*)out);
return;
}
SysPrintf("ReadFIFO Unknown %x\n", mem);
}
void ConstReadFIFO(u32 mem)
{
// not done
}
extern HANDLE g_hGsEvent;
void WriteFIFO(u32 mem, u64 *value) {
int ret;
if ((mem >= 0x10004000) && (mem < 0x10005000)) {
#ifdef VIF_LOG
VIF_LOG("WriteFIFO VIF0 0x%08X\n", mem);
#endif
psHu64(mem ) = value[0];
psHu64(mem+8) = value[1];
vif0ch->qwc += 1;
ret = VIF0transfer((u32*)value, 4, 0);
assert(ret == 0 ); // vif stall code not implemented
FreezeXMMRegs(0);
}
else if ((mem >= 0x10005000) && (mem < 0x10006000)) {
#ifdef VIF_LOG
VIF_LOG("WriteFIFO VIF1 0x%08X\n", mem);
#endif
psHu64(mem ) = value[0];
psHu64(mem+8) = value[1];
#ifdef PCSX2_DEVBUILD
if(vif1Regs->stat & VIF1_STAT_FDR)
SysPrintf("writing to fifo when fdr is set!\n");
if( vif1Regs->stat & (VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS) ) {
SysPrintf("writing to vif1 fifo when stalled\n");
}
#endif
vif1ch->qwc += 1;
ret = VIF1transfer((u32*)value, 4, 0);
assert(ret == 0 ); // vif stall code not implemented
FreezeXMMRegs(0);
}
else if ((mem >= 0x10006000) && (mem < 0x10007000)) {
u64* data;
#ifdef GIF_LOG
GIF_LOG("WriteFIFO GIF 0x%08X\n", mem);
#endif
psHu64(mem ) = value[0];
psHu64(mem+8) = value[1];
if( CHECK_MULTIGS ) {
data = (u64*)GSRingBufCopy(NULL, 16, GS_RINGTYPE_P3);
data[0] = value[0];
data[1] = value[1];
GSgifTransferDummy(2, (u32*)data, 1);
GSRINGBUF_DONECOPY(data, 16);
if( !CHECK_DUALCORE )
SetEvent(g_hGsEvent);
}
else {
FreezeXMMRegs(1);
GSGIFTRANSFER3((u32*)value, 1);
FreezeXMMRegs(0);
}
} else
if ((mem&0xfffff010) == 0x10007010) {
#ifdef IPU_LOG
IPU_LOG("WriteFIFO IPU_in[%d] <- %8.8X_%8.8X_%8.8X_%8.8X\n", (mem - 0x10007010)/8, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]);
#endif
//commiting every 16 bytes
while( FIFOto_write((void*)value, 1) == 0 ) {
SysPrintf("IPU sleeping\n");
Sleep(1);
}
} else {
SysPrintf("WriteFIFO Unknown %x\n", mem);
}
}
void ConstWriteFIFO(u32 mem) {
}

1989
GS.cpp Normal file

File diff suppressed because it is too large Load Diff

218
GS.h Normal file
View File

@ -0,0 +1,218 @@
/* 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 __GS_H__
#define __GS_H__
typedef struct
{
u32 SIGID;
u32 LBLID;
} GSRegSIGBLID;
#ifdef WIN32_VIRTUAL_MEM
#define GSCSRr *((u64*)(PS2MEM_GS+0x1000))
#define GSIMR *((u32*)(PS2MEM_GS+0x1010))
#define GSSIGLBLID ((GSRegSIGBLID*)(PS2MEM_GS+0x1080))
#else
extern u8 g_RealGSMem[0x2000];
#define GSCSRr *((u64*)(g_RealGSMem+0x1000))
#define GSIMR *((u32*)(g_RealGSMem+0x1010))
#define GSSIGLBLID ((GSRegSIGBLID*)(g_RealGSMem+0x1080))
#endif
#define GS_RINGBUFFERBASE (u8*)(0x10200000)
#define GS_RINGBUFFERSIZE 0x00300000 // 2Mb
#define GS_RINGBUFFEREND (u8*)(GS_RINGBUFFERBASE+GS_RINGBUFFERSIZE)
#define GS_RINGTYPE_RESTART 0
#define GS_RINGTYPE_P1 1
#define GS_RINGTYPE_P2 2
#define GS_RINGTYPE_P3 3
#define GS_RINGTYPE_VSYNC 4
#define GS_RINGTYPE_VIFFIFO 5 // GSreadFIFO2
#define GS_RINGTYPE_FRAMESKIP 6
#define GS_RINGTYPE_MEMWRITE8 7
#define GS_RINGTYPE_MEMWRITE16 8
#define GS_RINGTYPE_MEMWRITE32 9
#define GS_RINGTYPE_MEMWRITE64 10
// if returns NULL, don't copy (memory is preserved)
u8* GSRingBufCopy(void* mem, u32 size, u32 type);
void GSRingBufSimplePacket(int type, int data0, int data1, int data2);
extern u8* g_pGSWritePos;
#ifdef PCSX2_DEVBUILD
// use for debugging MTGS
extern FILE* g_fMTGSWrite, *g_fMTGSRead;
extern u32 g_MTGSDebug, g_MTGSId;
#define MTGS_RECWRITE(start, size) { \
if( g_MTGSDebug & 1 ) { \
u32* pstart = (u32*)(start); \
u32 cursize = (u32)(size); \
fprintf(g_fMTGSWrite, "*%x-%x (%d)\n", (u32)(start), (u32)(size), ++g_MTGSId); \
/*while(cursize > 0) { \
fprintf(g_fMTGSWrite, "%x %x %x %x\n", pstart[0], pstart[1], pstart[2], pstart[3]); \
pstart += 4; \
cursize -= 16; \
}*/ \
if( g_MTGSDebug & 2 ) fflush(g_fMTGSWrite); \
} \
} \
#define MTGS_RECREAD(start, size) { \
if( g_MTGSDebug & 1 ) { \
u32* pstart = (u32*)(start); \
u32 cursize = (u32)(size); \
fprintf(g_fMTGSRead, "*%x-%x (%d)\n", (u32)(start), (u32)(size), ++g_MTGSId); \
/*while(cursize > 0) { \
fprintf(g_fMTGSRead, "%x %x %x %x\n", pstart[0], pstart[1], pstart[2], pstart[3]); \
pstart += 4; \
cursize -= 16; \
}*/ \
if( g_MTGSDebug & 4 ) fflush(g_fMTGSRead); \
} \
} \
#else
#define MTGS_RECWRITE 0&&
#define MTGS_RECREAD 0&&
#endif
// mem and size are the ones from GSRingBufCopy
#define GSRINGBUF_DONECOPY(mem, size) { \
u8* temp = (u8*)(mem) + (size); \
assert( temp <= GS_RINGBUFFEREND); \
MTGS_RECWRITE(mem, size); \
if( temp == GS_RINGBUFFEREND ) temp = GS_RINGBUFFERBASE; \
InterlockedExchangePointer(&g_pGSWritePos, temp); \
}
u32 GSgifTransferDummy(int path, u32 *pMem, u32 size);
void gsInit();
void gsShutdown();
void gsReset();
// used for resetting GIF fifo
void gsGIFReset();
void gsWrite8(u32 mem, u8 value);
void gsConstWrite8(u32 mem, int mmreg);
void gsWrite16(u32 mem, u16 value);
void gsConstWrite16(u32 mem, int mmreg);
void gsWrite32(u32 mem, u32 value);
void gsConstWrite32(u32 mem, int mmreg);
void gsWrite64(u32 mem, u64 value);
void gsConstWrite64(u32 mem, int mmreg);
void gsConstWrite128(u32 mem, int mmreg);
u8 gsRead8(u32 mem);
int gsConstRead8(u32 x86reg, u32 mem, u32 sign);
u16 gsRead16(u32 mem);
int gsConstRead16(u32 x86reg, u32 mem, u32 sign);
u32 gsRead32(u32 mem);
int gsConstRead32(u32 x86reg, u32 mem);
u64 gsRead64(u32 mem);
void gsConstRead64(u32 mem, int mmreg);
void gsConstRead128(u32 mem, int xmmreg);
void gsIrq();
int gsInterrupt();
void dmaGIF();
void mfifoGIFtransfer(int qwc);
int gsFreeze(gzFile f, int Mode);
int _GIFchain();
int gifMFIFOInterrupt();
// GS Playback
#define GSRUN_TRANS1 1
#define GSRUN_TRANS2 2
#define GSRUN_TRANS3 3
#define GSRUN_VSYNC 4
#ifdef PCSX2_DEVBUILD
extern int g_SaveGSStream;
extern int g_nLeftGSFrames;
extern gzFile g_fGSSave;
#define GSGIFTRANSFER1(pMem, addr) { \
if( g_SaveGSStream == 2) { \
int type = GSRUN_TRANS1; \
int size = (0x4000-(addr))/16; \
gzwrite(g_fGSSave, &type, sizeof(type)); \
gzwrite(g_fGSSave, &size, 4); \
gzwrite(g_fGSSave, ((u8*)pMem)+(addr), size*16); \
} \
GSgifTransfer1(pMem, addr); \
}
#define GSGIFTRANSFER2(pMem, size) { \
if( g_SaveGSStream == 2) { \
int type = GSRUN_TRANS2; \
int _size = size; \
gzwrite(g_fGSSave, &type, sizeof(type)); \
gzwrite(g_fGSSave, &_size, 4); \
gzwrite(g_fGSSave, pMem, _size*16); \
} \
GSgifTransfer2(pMem, size); \
}
#define GSGIFTRANSFER3(pMem, size) { \
if( g_SaveGSStream == 2 ) { \
int type = GSRUN_TRANS3; \
int _size = size; \
gzwrite(g_fGSSave, &type, sizeof(type)); \
gzwrite(g_fGSSave, &_size, 4); \
gzwrite(g_fGSSave, pMem, _size*16); \
} \
GSgifTransfer3(pMem, size); \
}
#define GSVSYNC() { \
if( g_SaveGSStream == 2 ) { \
int type = GSRUN_VSYNC; \
gzwrite(g_fGSSave, &type, sizeof(type)); \
} \
} \
#else
#define GSGIFTRANSFER1(pMem, size) GSgifTransfer1(pMem, size)
#define GSGIFTRANSFER2(pMem, size) GSgifTransfer2(pMem, size)
#define GSGIFTRANSFER3(pMem, size) GSgifTransfer3(pMem, size)
#define GSVSYNC()
#endif
void RunGSState(gzFile f);
#endif

52
Gte.h Normal file
View File

@ -0,0 +1,52 @@
/* 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 __GTE_H__
#define __GTE_H__
void gteMFC2();
void gteCFC2();
void gteMTC2();
void gteCTC2();
void gteLWC2();
void gteSWC2();
void gteRTPS();
void gteOP();
void gteNCLIP();
void gteDPCS();
void gteINTPL();
void gteMVMVA();
void gteNCDS();
void gteNCDT();
void gteCDP();
void gteNCCS();
void gteCC();
void gteNCS();
void gteNCT();
void gteSQR();
void gteDCPL();
void gteDPCT();
void gteAVSZ3();
void gteAVSZ4();
void gteRTPT();
void gteGPF();
void gteGPL();
void gteNCCT();
#endif /* __GTE_H__ */

2643
Hw.c Normal file

File diff suppressed because it is too large Load Diff

408
Hw.h Normal file
View File

@ -0,0 +1,408 @@
/* 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 __HW_H__
#define __HW_H__
#include "PS2Etypes.h"
#include <assert.h>
#ifndef WIN32_VIRTUAL_MEM
extern u8 *psH; // hw mem
extern u16 *psHW;
extern u32 *psHL;
extern u64 *psHD;
#endif
#define psHs8(mem) (*(s8 *)&PS2MEM_HW[(mem) & 0xffff])
#define psHs16(mem) (*(s16*)&PS2MEM_HW[(mem) & 0xffff])
#define psHs32(mem) (*(s32*)&PS2MEM_HW[(mem) & 0xffff])
#define psHs64(mem) (*(s64*)&PS2MEM_HW[(mem) & 0xffff])
#define psHu8(mem) (*(u8 *)&PS2MEM_HW[(mem) & 0xffff])
#define psHu16(mem) (*(u16*)&PS2MEM_HW[(mem) & 0xffff])
#define psHu32(mem) (*(u32*)&PS2MEM_HW[(mem) & 0xffff])
#define psHu64(mem) (*(u64*)&PS2MEM_HW[(mem) & 0xffff])
extern u32 g_nextBranchCycle;
#define INT(n, ecycle) { \
g_nextBranchCycle = min(g_nextBranchCycle, cpuRegs.cycle+ecycle); \
cpuRegs.interrupt|= 1 << n; \
cpuRegs.sCycle[n] = cpuRegs.cycle; \
cpuRegs.eCycle[n] = ecycle; \
}
// VIF0 -- 0x10004000 -- psH[0x4000]
// VIF1 -- 0x10005000 -- psH[0x5000]
// GIF -- 0x10006000 -- psH[0x6000]
// IPUout -- 0x10007000 -- psH[0x7000]
// IPUin -- 0x10007010 -- psH[0x7010]
void ReadFIFO(u32 mem, u64 *out);
void ConstReadFIFO(u32 mem);
void WriteFIFO(u32 mem, u64 *value);
void ConstWriteFIFO(u32 mem);
//
// --- DMA ---
//
typedef struct {
u32 chcr;
u32 null0[3];
u32 madr;
u32 null1[3];
u16 qwc; u16 pad;
u32 null2[3];
u32 tadr;
u32 null3[3];
u32 asr0;
u32 null4[3];
u32 asr1;
u32 null5[11];
u32 sadr;
} DMACh;
// HW defines
#define RCNT0_COUNT 0x10000000
#define RCNT0_MODE 0x10000010
#define RCNT0_TARGET 0x10000020
#define RCNT0_HOLD 0x10000030
#define RCNT1_COUNT 0x10000800
#define RCNT1_MODE 0x10000810
#define RCNT1_TARGET 0x10000820
#define RCNT1_HOLD 0x10000830
#define RCNT2_COUNT 0x10001000
#define RCNT2_MODE 0x10001010
#define RCNT2_TARGET 0x10001020
#define RCNT3_COUNT 0x10001800
#define RCNT3_MODE 0x10001810
#define RCNT3_TARGET 0x10001820
#define IPU_CMD 0x10002000
#define IPU_CTRL 0x10002010
#define IPU_BP 0x10002020
#define IPU_TOP 0x10002030
#define GIF_CTRL 0x10003000
#define GIF_MODE 0x10003010
#define GIF_STAT 0x10003020
#define GIF_TAG0 0x10003040
#define GIF_TAG1 0x10003050
#define GIF_TAG2 0x10003060
#define GIF_TAG3 0x10003070
#define GIF_CNT 0x10003080
#define GIF_P3CNT 0x10003090
#define GIF_P3TAG 0x100030A0
#define GIF_FIFO 0x10006000
#define IPUout_FIFO 0x10007000
#define IPUin_FIFO 0x10007010
//VIF0
#define D0_CHCR 0x10008000
#define D0_MADR 0x10008010
#define D0_QWC 0x10008020
//VIF1
#define D1_CHCR 0x10009000
#define D1_MADR 0x10009010
#define D1_QWC 0x10009020
#define D1_TADR 0x10009030
//GS
#define D2_CHCR 0x1000A000
#define D2_MADR 0x1000A010
#define D2_QWC 0x1000A020
#define D2_TADR 0x1000A030
//fromIPU
#define D3_CHCR 0x1000B000
#define D3_MADR 0x1000B010
#define D3_QWC 0x1000B020
//toIPU
#define D4_CHCR 0x1000B400
#define D4_MADR 0x1000B410
#define D4_QWC 0x1000B420
#define D4_TADR 0x1000B430
//SIF0
#define D5_CHCR 0x1000C000
#define D5_MADR 0x1000C010
#define D5_QWC 0x1000C020
//SIF1
#define D6_CHCR 0x1000C400
#define D6_MADR 0x1000C410
#define D6_QWC 0x1000C420
//SIF2
#define D7_CHCR 0x1000C800
#define D7_MADR 0x1000C810
#define D7_QWC 0x1000C820
//fromSPR
#define D8_CHCR 0x1000D000
#define D8_MADR 0x1000D010
#define D8_QWC 0x1000D020
#define D8_SADR 0x1000D080
#define DMAC_CTRL 0x1000E000
#define DMAC_STAT 0x1000E010
#define DMAC_PCR 0x1000E020
#define DMAC_SQWC 0x1000E030
#define DMAC_RBSR 0x1000E040
#define DMAC_RBOR 0x1000E050
#define DMAC_STADR 0x1000E060
#define INTC_STAT 0x1000F000
#define INTC_MASK 0x1000F010
#define SBUS_F220 0x1000F220
#define SBUS_SMFLG 0x1000F230
#define SBUS_F240 0x1000F240
#define DMAC_ENABLER 0x1000F520
#define DMAC_ENABLEW 0x1000F590
#define SBFLG_IOPALIVE 0x10000
#define SBFLG_IOPSYNC 0x40000
#define GS_PMODE 0x12000000
#define GS_SMODE1 0x12000010
#define GS_SMODE2 0x12000020
#define GS_SRFSH 0x12000030
#define GS_SYNCH1 0x12000040
#define GS_SYNCH2 0x12000050
#define GS_SYNCV 0x12000060
#define GS_DISPFB1 0x12000070
#define GS_DISPLAY1 0x12000080
#define GS_DISPFB2 0x12000090
#define GS_DISPLAY2 0x120000A0
#define GS_EXTBUF 0x120000B0
#define GS_EXTDATA 0x120000C0
#define GS_EXTWRITE 0x120000D0
#define GS_BGCOLOR 0x120000E0
#define GS_CSR 0x12001000
#define GS_IMR 0x12001010
#define GS_BUSDIR 0x12001040
#define GS_SIGLBLID 0x12001080
#define INTC_GS 0
#define INTC_SBUS 1
#define INTC_VBLANK_S 2
#define INTC_VBLANK_E 3
#define INTC_VIF0 4
#define INTC_VIF1 5
#define INTC_VU0 6
#define INTC_VU1 7
#define INTC_IPU 8
#define INTC_TIM0 9
#define INTC_TIM1 10
#define INTC_TIM2 11
#define INTC_TIM3 12
#define DMAC_STAT_SIS (1<<13) // stall condition
#define DMAC_STAT_MEIS (1<<14) // mfifo empty
#define DMAC_STAT_BEIS (1<<15) // bus error
#define DMAC_STAT_SIM (1<<29) // stall mask
#define DMAC_STAT_MEIM (1<<30) // mfifo mask
#define DMAC_VIF0 0
#define DMAC_VIF1 1
#define DMAC_GIF 2
#define DMAC_FROM_IPU 3
#define DMAC_TO_IPU 4
#define DMAC_SIF0 5
#define DMAC_SIF1 6
#define DMAC_SIF2 7
#define DMAC_FROM_SPR 8
#define DMAC_TO_SPR 9
#define DMAC_ERROR 15
#define VIF0_STAT_VPS_W (1)
#define VIF0_STAT_VPS_D (2)
#define VIF0_STAT_VPS_T (3)
#define VIF0_STAT_VPS (3)
#define VIF0_STAT_VEW (1<<2)
#define VIF0_STAT_MRK (1<<6)
#define VIF0_STAT_DBF (1<<7)
#define VIF0_STAT_VSS (1<<8)
#define VIF0_STAT_VFS (1<<9)
#define VIF0_STAT_VIS (1<<10)
#define VIF0_STAT_INT (1<<11)
#define VIF0_STAT_ER0 (1<<12)
#define VIF0_STAT_ER1 (1<<13)
#define VIF1_STAT_VPS_W (1)
#define VIF1_STAT_VPS_D (2)
#define VIF1_STAT_VPS_T (3)
#define VIF1_STAT_VPS (3)
#define VIF1_STAT_VEW (1<<2)
#define VIF1_STAT_VGW (1<<3)
#define VIF1_STAT_MRK (1<<6)
#define VIF1_STAT_DBF (1<<7)
#define VIF1_STAT_VSS (1<<8)
#define VIF1_STAT_VFS (1<<9)
#define VIF1_STAT_VIS (1<<10)
#define VIF1_STAT_INT (1<<11)
#define VIF1_STAT_ER0 (1<<12)
#define VIF1_STAT_ER1 (1<<13)
#define VIF1_STAT_FDR (1<<23)
//DMA interrupts & masks
#define BEISintr (0x8000)
#define VIF0intr (0x10001)
#define VIF1intr (0x20002)
#define GIFintr (0x40004)
#define IPU0intr (0x80008)
#define IPU1intr (0x100010)
#define SIF0intr (0x200020)
#define SIF1intr (0x400040)
#define SIF2intr (0x800080)
#define SPR0intr (0x1000100)
#define SPR1intr (0x2000200)
#define SISintr (0x20002000)
#define MEISintr (0x40004000)
#define DMAend(dma, num) { \
dma->chcr &= ~0x100; \
psHu32(DMAC_STAT)|= 1<<num; \
return; \
}
#define DMAerror(dma, num) { \
psHu32(DMAC_STAT)|= 1<<15; /* BUS error */ \
DMAend(dma, num); \
}
#define _dmaGetAddr(dma, ptr, addr, num) \
ptr = (u32*)dmaGetAddr(addr); \
if (ptr == NULL) DMAerror(dma, num);
#ifdef WIN32_VIRTUAL_MEM
#define dmaGetAddrBase(addr) (((addr) & 0x80000000) ? (void*)&PS2MEM_SCRATCH[(addr) & 0x3ff0] : (void*)(PS2MEM_BASE+TRANSFORM_ADDR(addr)))
extern PSMEMORYMAP *memLUT;
__forceinline u8* dmaGetAddr(u32 mem)
{
u8* p, *pbase;
mem &= ~0xf;
#ifdef _DEBUG
if( (mem & 0xffff0000) == 0x10000000 )
SysPrintf("dma to/from %x!\n", mem);
#endif
if( mem == 0x50000000 ) // reserved scratch pad mem
return NULL;
p = (u8*)dmaGetAddrBase(mem), *pbase;
// do manual LUT since IPU/SPR seems to use addrs 0x3000xxxx quite often
#ifndef PCSX2_RELEASE
if( memLUT[ (p-PS2MEM_BASE)>>12 ].aPFNs == NULL ) {
SysPrintf("*PCSX2*: DMA error: %8.8x\n", mem);
return NULL;
}
#endif
pbase = (u8*)memLUT[ (p-PS2MEM_BASE)>>12 ].aVFNs[0];
if( pbase != NULL )
p = pbase + ((u32)p&0xfff);
return p;
}
#else
__forceinline void *dmaGetAddr(u32 addr) {
u8 *ptr;
/*#ifdef DMA_LOG
if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x\n", addr); }
#endif*/
if (addr & 0x80000000) { // teh sux why the f00k 0xE0000000
return (void*)&psS[addr & 0x3ff0];
}
ptr = (u8*)memLUTR[addr >> 12];
if (ptr == NULL) {
SysPrintf("*PCSX2*: DMA error: %8.8x\n", addr);
return NULL;
}
return (void*)(ptr + (addr & 0xff0));
}
#endif
int hwInit();
void hwReset();
void hwShutdown();
// hw read functions
u8 hwRead8 (u32 mem);
int hwConstRead8 (u32 x86reg, u32 mem, u32 sign);
u16 hwRead16(u32 mem);
int hwConstRead16(u32 x86reg, u32 mem, u32 sign);
u32 hwRead32(u32 mem);
int hwConstRead32(u32 x86reg, u32 mem);
u64 hwRead64(u32 mem);
void hwConstRead64(u32 mem, int mmreg);
void hwRead128(u32 mem, u64 *out);
void hwConstRead128(u32 mem, int xmmreg);
// hw write functions
void hwWrite8 (u32 mem, u8 value);
void hwConstWrite8 (u32 mem, int mmreg);
void hwWrite16(u32 mem, u16 value);
void hwConstWrite16(u32 mem, int mmreg);
void hwWrite32(u32 mem, u32 value);
void hwConstWrite32(u32 mem, int mmreg);
void hwWrite64(u32 mem, u64 value);
void hwConstWrite64(u32 mem, int mmreg);
void hwWrite128(u32 mem, u64 *value);
void hwConstWrite128(u32 mem, int xmmreg);
void hwIntcIrq(int n);
void hwDmacIrq(int n);
int hwMFIFORead(u32 addr, u8 *data, int size);
int hwMFIFOWrite(u32 addr, u8 *data, int size);
int hwDmacSrcChainWithStack(DMACh *dma, int id);
int hwDmacSrcChain(DMACh *dma, int id);
int intcInterrupt();
int dmacInterrupt();
#endif /* __HW_H__ */

24
INSTALL.txt Normal file
View File

@ -0,0 +1,24 @@
Pcsx2 Emulator
Windows Compilation
-------------------
Goto windows/VCprojects, open up the appropriate sln and compile
Linux Compilation
-----------------
[Currently in beta stages]
in the main directory type:
aclocal
autoconf
automake
./configure [options]
make
[options] include
--enable-debug {Build with symbols and no optimizations}
--enable-devbuild {Build with extra tests}

1965
IPU/IPU.c Normal file

File diff suppressed because it is too large Load Diff

204
IPU/IPU.h Normal file
View File

@ -0,0 +1,204 @@
/* 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 __IPU_H__
#define __IPU_H__
#include "Common.h"
#ifdef __WIN32__
#pragma pack(1)
#endif
//
// Bitfield Structure
//
typedef union {
struct {
u32 OPTION : 28; // VDEC decoded value
u32 CMD : 4; // last command
u32 _BUSY;
};
struct {
u32 DATA;
u32 BUSY;
};
} tIPU_CMD;
#define IPU_CTRL_IFC_M (0x0f<< 0)
#define IPU_CTRL_OFC_M (0x0f<< 4)
#define IPU_CTRL_CBP_M (0x3f<< 8)
#define IPU_CTRL_ECD_M (0x01<<14)
#define IPU_CTRL_SCD_M (0x01<<15)
#define IPU_CTRL_IDP_M (0x03<<16)
#define IPU_CTRL_AS_M (0x01<<20)
#define IPU_CTRL_IVF_M (0x01<<21)
#define IPU_CTRL_QST_M (0x01<<22)
#define IPU_CTRL_MP1_M (0x01<<23)
#define IPU_CTRL_PCT_M (0x07<<24)
#define IPU_CTRL_RST_M (0x01<<30)
#define IPU_CTRL_BUSY_M (0x01<<31)
#define IPU_CTRL_IFC_O ( 0)
#define IPU_CTRL_OFC_O ( 4)
#define IPU_CTRL_CBP_O ( 8)
#define IPU_CTRL_ECD_O (14)
#define IPU_CTRL_SCD_O (15)
#define IPU_CTRL_IDP_O (16)
#define IPU_CTRL_AS_O (20)
#define IPU_CTRL_IVF_O (21)
#define IPU_CTRL_QST_O (22)
#define IPU_CTRL_MP1_O (23)
#define IPU_CTRL_PCT_O (24)
#define IPU_CTRL_RST_O (30)
#define IPU_CTRL_BUSY_O (31)
//
// Bitfield Structure
//
typedef union {
struct {
u32 IFC : 4; // Input FIFO counter
u32 OFC : 4; // Output FIFO counter
u32 CBP : 6; // Coded block pattern
u32 ECD : 1; // Error code pattern
u32 SCD : 1; // Start code detected
u32 IDP : 2; // Intra DC precision
u32 resv0 : 2;
u32 AS : 1; // Alternate scan
u32 IVF : 1; // Intra VLC format
u32 QST : 1; // Q scale step
u32 MP1 : 1; // MPEG1 bit strea
u32 PCT : 3; // Picture Type
u32 resv1 : 3;
u32 RST : 1; // Reset
u32 BUSY : 1; // Busy
};
u32 _u32;
} tIPU_CTRL;
#define IPU_BP_BP_M (0x7f<< 0)
#define IPU_BP_IFC_M (0x0f<< 8)
#define IPU_BP_FP_M (0x03<<16)
#define IPU_BP_BP_O ( 0)
#define IPU_BP_IFC_O ( 8)
#define IPU_BP_FP_O (16)
//
// Bitfield Structure
//
typedef struct {
u32 BP; // Bit stream point
u16 IFC; // Input FIFO counter
u8 FP; // FIFO point
u8 bufferhasnew;
} tIPU_BP;
#ifdef __WIN32__
#pragma pack()
#endif
typedef struct {
u32 FB : 6;
u32 UN2 :10;
u32 QSC : 5;
u32 UN1 : 3;
u32 DTD : 1;
u32 SGN : 1;
u32 DTE : 1;
u32 OFM : 1;
u32 cmd : 4;
} tIPU_CMD_IDEC;
typedef struct {
u32 FB : 6;
u32 UN2 :10;
u32 QSC : 5;
u32 UN1 : 4;
u32 DT : 1;
u32 DCR : 1;
u32 MBI : 1;
u32 cmd : 4;
} tIPU_CMD_BDEC;
typedef struct {
u32 MBC :11;
u32 UN2 :15;
u32 DTE : 1;
u32 OFM : 1;
u32 cmd : 4;
} tIPU_CMD_CSC;
#define SCE_IPU_BCLR 0x0
#define SCE_IPU_IDEC 0x1
#define SCE_IPU_BDEC 0x2
#define SCE_IPU_VDEC 0x3
#define SCE_IPU_FDEC 0x4
#define SCE_IPU_SETIQ 0x5
#define SCE_IPU_SETVQ 0x6
#define SCE_IPU_CSC 0x7
#define SCE_IPU_PACK 0x8
#define SCE_IPU_SETTH 0x9
typedef struct {
tIPU_CMD cmd;
u32 dummy0[2];
tIPU_CTRL ctrl;
u32 dummy1[3];
u32 ipubp;
u32 dummy2[3];
u32 top;
u32 topbusy;
u32 dummy3[2];
} IPUregisters, *PIPUregisters;
#define ipuRegs ((IPUregisters*)(PS2MEM_HW+0x2000))
void dmaIPU0();
void dmaIPU1();
int ipuInit();
void ipuReset();
void ipuShutdown();
int ipuFreeze(gzFile f, int Mode);
BOOL ipuCanFreeze();
u32 ipuRead32(u32 mem);
int ipuConstRead32(u32 x86reg, u32 mem);
u64 ipuRead64(u32 mem);
void ipuConstRead64(u32 mem, int mmreg);
void ipuWrite32(u32 mem,u32 value);
void ipuConstWrite32(u32 mem, int mmreg);
void ipuWrite64(u32 mem,u64 value);
void ipuConstWrite64(u32 mem, int mmreg);
int ipu0Interrupt();
int ipu1Interrupt();
u8 getBits32(u8 *address, u32 advance);
u8 getBits16(u8 *address, u32 advance);
u8 getBits8(u8 *address, u32 advance);
int getBits(u8 *address, u32 size, u32 advance);
#endif

8
IPU/Makefile.am Normal file
View File

@ -0,0 +1,8 @@
INCLUDES = -I../ -I../x86
noinst_LIBRARIES = libIPU.a
libIPU_a_SOURCES = IPU.c IPU.h yuv2rgb.c yuv2rgb.h
SUBDIRS = mpeg2lib
LDADD = libmpeg2IPU.a

BIN
IPU/idct_mmx.obj Normal file

Binary file not shown.

302
IPU/mpeg2lib/Idct.c Normal file
View File

@ -0,0 +1,302 @@
/*
* idct.c
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
* Modified by Florin for PCSX2 emu
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec 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.
*
* mpeg2dec 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 <stdlib.h>
#include "Common.h"
#include "ix86/ix86.h"
#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */
#define clp(val,res) res = (val < 0) ? 0 : ((val > 255) ? 255 : val);
#define clp2(val,res) res = (val < -255) ? -255 : ((val > 255) ? 255 : val);
/* idct main entry point */
void (* mpeg2_idct_copy) (s16 * block, u8 * dest, int stride);
/* JayteeMaster: changed dest to 16 bit signed */
void (* mpeg2_idct_add) (int last, s16 * block,
/*u8*/s16 * dest, int stride);
/*
* In legal streams, the IDCT output should be between -384 and +384.
* In corrupted streams, it is possible to force the IDCT output to go
* to +-3826 - this is the worst case for a column IDCT where the
* column inputs are 16-bit values.
*/
static u8 clip_lut[1024];
#define CLIP(i) ((clip_lut+384)[(i)])
#if 0
#define BUTTERFLY(t0,t1,W0,W1,d0,d1) \
do { \
t0 = W0*d0 + W1*d1; \
t1 = W0*d1 - W1*d0; \
} while (0)
#else
#define BUTTERFLY(t0,t1,W0,W1,d0,d1) \
do { \
int tmp = W0 * (d0 + d1); \
t0 = tmp + (W1 - W0) * d1; \
t1 = tmp - (W1 + W0) * d0; \
} while (0)
#endif
static void idct_row (s16 * const block)
{
int d0, d1, d2, d3;
int a0, a1, a2, a3, b0, b1, b2, b3;
int t0, t1, t2, t3;
/* shortcut */
if (!(block[1] | ((s32 *)block)[1] | ((s32 *)block)[2] |
((s32 *)block)[3])) {
u32 tmp = (u16) (block[0] << 3);
tmp |= tmp << 16;
((s32 *)block)[0] = tmp;
((s32 *)block)[1] = tmp;
((s32 *)block)[2] = tmp;
((s32 *)block)[3] = tmp;
return;
}
d0 = (block[0] << 11) + 128;
d1 = block[1];
d2 = block[2] << 11;
d3 = block[3];
t0 = d0 + d2;
t1 = d0 - d2;
BUTTERFLY (t2, t3, W6, W2, d3, d1);
a0 = t0 + t2;
a1 = t1 + t3;
a2 = t1 - t3;
a3 = t0 - t2;
d0 = block[4];
d1 = block[5];
d2 = block[6];
d3 = block[7];
BUTTERFLY (t0, t1, W7, W1, d3, d0);
BUTTERFLY (t2, t3, W3, W5, d1, d2);
b0 = t0 + t2;
b3 = t1 + t3;
t0 -= t2;
t1 -= t3;
b1 = ((t0 + t1) * 181) >> 8;
b2 = ((t0 - t1) * 181) >> 8;
block[0] = (a0 + b0) >> 8;
block[1] = (a1 + b1) >> 8;
block[2] = (a2 + b2) >> 8;
block[3] = (a3 + b3) >> 8;
block[4] = (a3 - b3) >> 8;
block[5] = (a2 - b2) >> 8;
block[6] = (a1 - b1) >> 8;
block[7] = (a0 - b0) >> 8;
}
static void idct_col (s16 * const block)
{
int d0, d1, d2, d3;
int a0, a1, a2, a3, b0, b1, b2, b3;
int t0, t1, t2, t3;
d0 = (block[8*0] << 11) + 65536;
d1 = block[8*1];
d2 = block[8*2] << 11;
d3 = block[8*3];
t0 = d0 + d2;
t1 = d0 - d2;
BUTTERFLY (t2, t3, W6, W2, d3, d1);
a0 = t0 + t2;
a1 = t1 + t3;
a2 = t1 - t3;
a3 = t0 - t2;
d0 = block[8*4];
d1 = block[8*5];
d2 = block[8*6];
d3 = block[8*7];
BUTTERFLY (t0, t1, W7, W1, d3, d0);
BUTTERFLY (t2, t3, W3, W5, d1, d2);
b0 = t0 + t2;
b3 = t1 + t3;
t0 = (t0 - t2) >> 8;
t1 = (t1 - t3) >> 8;
b1 = (t0 + t1) * 181;
b2 = (t0 - t1) * 181;
block[8*0] = (a0 + b0) >> 17;
block[8*1] = (a1 + b1) >> 17;
block[8*2] = (a2 + b2) >> 17;
block[8*3] = (a3 + b3) >> 17;
block[8*4] = (a3 - b3) >> 17;
block[8*5] = (a2 - b2) >> 17;
block[8*6] = (a1 - b1) >> 17;
block[8*7] = (a0 - b0) >> 17;
}
static void mpeg2_idct_copy_c (s16 * block, u8 * dest,
const int stride)
{
int i;
for (i = 0; i < 8; i++)
idct_row (block + 8 * i);
for (i = 0; i < 8; i++)
idct_col (block + i);
do {
dest[0] = CLIP (block[0]);
dest[1] = CLIP (block[1]);
dest[2] = CLIP (block[2]);
dest[3] = CLIP (block[3]);
dest[4] = CLIP (block[4]);
dest[5] = CLIP (block[5]);
dest[6] = CLIP (block[6]);
dest[7] = CLIP (block[7]);
block[0] = 0; block[1] = 0; block[2] = 0; block[3] = 0;
block[4] = 0; block[5] = 0; block[6] = 0; block[7] = 0;
dest += stride;
block += 8;
} while (--i);
}
/* JayteeMaster: changed dest to 16 bit signed */
static void mpeg2_idct_add_c (const int last, s16 * block,
/*u8*/s16 * dest, const int stride)
{
int i;
if (last != 129 || (block[0] & 7) == 4) {
for (i = 0; i < 8; i++)
idct_row (block + 8 * i);
for (i = 0; i < 8; i++)
idct_col (block + i);
do {
dest[0] = block[0];
dest[1] = block[1];
dest[2] = block[2];
dest[3] = block[3];
dest[4] = block[4];
dest[5] = block[5];
dest[6] = block[6];
dest[7] = block[7];
block[0] = 0; block[1] = 0; block[2] = 0; block[3] = 0;
block[4] = 0; block[5] = 0; block[6] = 0; block[7] = 0;
dest += stride;
block += 8;
} while (--i);
} else {
int DC;
DC = (block[0] + 4) >> 3;
block[0] = block[63] = 0;
i = 8;
do {
dest[0] = DC;
dest[1] = DC;
dest[2] = DC;
dest[3] = DC;
dest[4] = DC;
dest[5] = DC;
dest[6] = DC;
dest[7] = DC;
dest += stride;
} while (--i);
}
}
u8 mpeg2_scan_norm[64] = {
/* Zig-Zag scan pattern */
0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
};
u8 mpeg2_scan_alt[64] = {
/* Alternate scan pattern */
0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49,
41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43,
51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45,
53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63
};
/* idct_mmx.c */
void mpeg2_idct_copy_mmxext (s16 * block, u8 * dest, int stride);
void mpeg2_idct_add_mmxext (int last, s16 * block,
s16 * dest, int stride);
void mpeg2_idct_copy_mmx (s16 * block, u8 * dest, int stride);
void mpeg2_idct_add_mmx (int last, s16 * block,
s16 * dest, int stride);
void mpeg2_idct_mmx_init (void);
void mpeg2_idct_init()
{
#ifndef __VCNET2005__
int i, j;
/* if(hasMultimediaExtensions == 1)
{
mpeg2_idct_copy = mpeg2_idct_copy_mmx;
mpeg2_idct_add = mpeg2_idct_add_mmx;
mpeg2_idct_mmx_init ();
}else if(hasMultimediaExtensionsExt == 1)
{
mpeg2_idct_copy = mpeg2_idct_copy_mmxext;
mpeg2_idct_add = mpeg2_idct_add_mmxext;
mpeg2_idct_mmx_init ();
}else*/
{
mpeg2_idct_copy = mpeg2_idct_copy_c;
mpeg2_idct_add = mpeg2_idct_add_c;
for (i = -384; i < 640; i++)
clip_lut[i+384] = (i < 0) ? 0 : ((i > 255) ? 255 : i);
for (i = 0; i < 64; i++) {
j = mpeg2_scan_norm[i];
mpeg2_scan_norm[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2);
j = mpeg2_scan_alt[i];
mpeg2_scan_alt[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2);
}
}
#else //blah vcnet2005 idiocity :D
int i,j;
mpeg2_idct_copy = mpeg2_idct_copy_c;
mpeg2_idct_add = mpeg2_idct_add_c;
for (i = -384; i < 640; i++)
clip_lut[i+384] = (i < 0) ? 0 : ((i > 255) ? 255 : i);
for (i = 0; i < 64; i++) {
j = mpeg2_scan_norm[i];
mpeg2_scan_norm[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2);
j = mpeg2_scan_alt[i];
mpeg2_scan_alt[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2);
}
#endif
}

4
IPU/mpeg2lib/Makefile.am Normal file
View File

@ -0,0 +1,4 @@
INCLUDES = -I../ -I../../ -I../../x86
noinst_LIBRARIES = libmpeg2IPU.a
libmpeg2IPU_a_SOURCES = Idct.c Mpeg.c Mpeg.h Vlc.h

1281
IPU/mpeg2lib/Mpeg.c Normal file

File diff suppressed because it is too large Load Diff

186
IPU/mpeg2lib/Mpeg.h Normal file
View File

@ -0,0 +1,186 @@
/*
* Mpeg.h
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
* Modified by Florin for PCSX2 emu
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec 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.
*
* mpeg2dec 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 __MPEG_H__
#define __MPEG_H__
#include "Common.h"
/* macroblock modes */
#define MACROBLOCK_INTRA 1
#define MACROBLOCK_PATTERN 2
#define MACROBLOCK_MOTION_BACKWARD 4
#define MACROBLOCK_MOTION_FORWARD 8
#define MACROBLOCK_QUANT 16
#define DCT_TYPE_INTERLACED 32
/* motion_type */
#define MOTION_TYPE_SHIFT 6
#define MOTION_TYPE_MASK (3*64)
#define MOTION_TYPE_BASE 64
#define MC_FIELD (1*64)
#define MC_FRAME (2*64)
#define MC_16X8 (2*64)
#define MC_DMV (3*64)
/* picture structure */
#define TOP_FIELD 1
#define BOTTOM_FIELD 2
#define FRAME_PICTURE 3
/* picture coding type */
#define I_TYPE 1
#define P_TYPE 2
#define B_TYPE 3
#define D_TYPE 4
struct macroblock_8{
unsigned char Y[16][16]; //0
unsigned char Cb[8][8]; //1
unsigned char Cr[8][8]; //2
};
struct macroblock_16{
short Y[16][16]; //0
short Cb[8][8]; //1
short Cr[8][8]; //2
};
struct rgb32{
unsigned char r, g, b, a;
};
struct macroblock_rgb32{
struct rgb32 c[16][16];
};
struct rgb16{
unsigned short r:5, g:5, b:5, a:1;
};
struct macroblock_rgb16{
struct rgb16 c[16][16];
};
struct decoder_s {
/* first, state that carries information from one macroblock to the */
/* next inside a slice, and is never used outside of mpeg2_slice() */
/* DCT coefficients - should be kept aligned ! */
s16 DCTblock[64];
/* bit parsing stuff */
u32 bitstream_buf; /* current 32 bit working set */
int bitstream_bits; /* used bits in working set */
u8 * bitstream_ptr; /* buffer with stream data; 128 bits buffer */
struct macroblock_8 *mb8;
struct macroblock_16 *mb16;
struct macroblock_rgb32 *rgb32;
struct macroblock_rgb16 *rgb16;
int stride;
/* predictor for DC coefficients in intra blocks */
s16 dc_dct_pred[3];
int quantizer_scale; /* remove */
int dmv_offset; /* remove */
/* now non-slice-specific information */
/* sequence header stuff */
u8 *intra_quantizer_matrix;
u8 *non_intra_quantizer_matrix;
/* picture header stuff */
/* what type of picture this is (I, P, B, D) */
int coding_type;
/* picture coding extension stuff */
/* quantization factor for intra dc coefficients */
int intra_dc_precision;
/* top/bottom/both fields */
int picture_structure;
/* bool to indicate all predictions are frame based */
int frame_pred_frame_dct;
/* bool to indicate whether intra blocks have motion vectors */
/* (for concealment) */
int concealment_motion_vectors;
/* bit to indicate which quantization table to use */
int q_scale_type;
/* bool to use different vlc tables */
int intra_vlc_format;
/* used for DMV MC */
int top_field_first;
// Pseudo Sign Offset
int sgn;
// Dither Enable
int dte;
// Output Format
int ofm;
// Macroblock count
int mbc;
// Macroblock type
int macroblock_modes;
// DC Reset
int dcr;
// Coded block pattern
int coded_block_pattern;
/* stuff derived from bitstream */
/* pointer to the zigzag scan we're supposed to be using */
const u8 * scan;
int second_field;
int mpeg1;
};
typedef struct decoder_s decoder_t;
#define IDEC 0
#define BDEC 1
void mpeg2sliceIDEC(void* pdone);
void mpeg2_slice(void* pdone);
int get_macroblock_address_increment(decoder_t * const decoder);
int get_macroblock_modes (decoder_t * const decoder);
int get_motion_delta (decoder_t * const decoder,
const int f_code);
int get_dmv (decoder_t * const decoder);
int non_linear_quantizer_scale[]; // JayteeMaster: it is needed in Ipu.c
void ipu_csc(struct macroblock_8 *mb8, struct macroblock_rgb32 *rgb32, int sgn);
void ipu_dither(struct macroblock_8 *mb8, struct macroblock_rgb16 *rgb16, int dte);
void ipu_dither2(struct macroblock_rgb32* rgb32, struct macroblock_rgb16 *rgb16, int dte);
void ipu_vq(struct macroblock_rgb16 *rgb16, u8* indx4);
void ipu_copy(struct macroblock_8 *mb8, struct macroblock_16 *mb16);
int slice (decoder_t * const decoder, u8 * buffer);
/* idct.c */
void mpeg2_idct_init ();
#endif//__MPEG_H__

441
IPU/mpeg2lib/Vlc.h Normal file
View File

@ -0,0 +1,441 @@
/*
* vlc.h
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
* Modified by Florin for PCSX2 emu
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec 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.
*
* mpeg2dec 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 __VLC_H__
#define __VLC_H__
#include "IPU.h"
#include "pcl/pcl.h"
static u8 data[2];
static u8 dword[4];
static void GETWORD(u32 * bit_buf,int bits)
{
while(!getBits16(data,1))
co_resume();
*bit_buf |= ((data[0] << 8) | data[1]) << (bits);
}
static void bitstream_init (decoder_t * decoder){
decoder->bitstream_bits = -16;
while( !getBits32(dword, 1) )
co_resume();
decoder->bitstream_buf = (dword[0] << 24) | (dword[1] << 16) |
(dword[2] << 8) |dword[3];
}
/* make sure that there are at least 16 valid bits in bit_buf */
#define NEEDBITS(bit_buf,bits,bit_ptr) \
do { \
if (bits > 0) { \
GETWORD(&bit_buf,bits); \
bits -= 16; \
} \
} while (0)
/* remove num valid bits from bit_buf */
#define DUMPBITS(bit_buf,bits,num) \
do { \
/*IPU_LOG("DUMPBITS %d\n",num);*/ \
bit_buf <<= (num); \
bits += (num); \
} while (0)
/* take num bits from the high part of bit_buf and zero extend them */
#define UBITS(bit_buf,num) (((u32)(bit_buf)) >> (32 - (num)))
/* take num bits from the high part of bit_buf and sign extend them */
#define SBITS(bit_buf,num) (((s32)(bit_buf)) >> (32 - (num)))
typedef struct {
u8 modes;
u8 len;
} MBtab;
typedef struct {
u8 delta;
u8 len;
} MVtab;
typedef struct {
s8 dmv;
u8 len;
} DMVtab;
typedef struct {
u8 cbp;
u8 len;
} CBPtab;
typedef struct {
u8 size;
u8 len;
} DCtab;
typedef struct {
u8 run;
u8 level;
u8 len;
} DCTtab;
typedef struct {
u8 mba;
u8 len;
} MBAtab;
#define INTRA MACROBLOCK_INTRA
#define QUANT MACROBLOCK_QUANT
static const MBtab MB_I [] = {
{INTRA|QUANT, 2}, {INTRA, 1}
};
#define MC MACROBLOCK_MOTION_FORWARD
#define CODED MACROBLOCK_PATTERN
static const MBtab MB_P [] = {
{INTRA|QUANT, 6}, {CODED|QUANT, 5}, {MC|CODED|QUANT, 5}, {INTRA, 5},
{MC, 3}, {MC, 3}, {MC, 3}, {MC, 3},
{CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2},
{CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2},
{MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
{MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
{MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
{MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}
};
#define FWD MACROBLOCK_MOTION_FORWARD
#define BWD MACROBLOCK_MOTION_BACKWARD
#define INTER MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD
static const MBtab MB_B [] = {
{0, 0}, {INTRA|QUANT, 6},
{BWD|CODED|QUANT, 6}, {FWD|CODED|QUANT, 6},
{INTER|CODED|QUANT, 5}, {INTER|CODED|QUANT, 5},
{INTRA, 5}, {INTRA, 5},
{FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD, 4},
{FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4},
{BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3},
{BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3},
{BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3},
{BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3},
{INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
{INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
{INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
{INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
{INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
{INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
{INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
{INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}
};
#undef INTRA
#undef QUANT
#undef MC
#undef CODED
#undef FWD
#undef BWD
#undef INTER
static const MVtab MV_4 [] = {
{ 3, 6}, { 2, 4}, { 1, 3}, { 1, 3}, { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2}
};
static const MVtab MV_10 [] = {
{ 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10},
{ 0,10}, { 0,10}, { 0,10}, { 0,10}, {15,10}, {14,10}, {13,10}, {12,10},
{11,10}, {10,10}, { 9, 9}, { 9, 9}, { 8, 9}, { 8, 9}, { 7, 9}, { 7, 9},
{ 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7},
{ 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7},
{ 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}
};
static const DMVtab DMV_2 [] = {
{ 0, 1}, { 0, 1}, { 1, 2}, {-1, 2}
};
static const CBPtab CBP_7 [] = {
{0x22, 7}, {0x12, 7}, {0x0a, 7}, {0x06, 7},
{0x21, 7}, {0x11, 7}, {0x09, 7}, {0x05, 7},
{0x3f, 6}, {0x3f, 6}, {0x03, 6}, {0x03, 6},
{0x24, 6}, {0x24, 6}, {0x18, 6}, {0x18, 6},
{0x3e, 5}, {0x3e, 5}, {0x3e, 5}, {0x3e, 5},
{0x02, 5}, {0x02, 5}, {0x02, 5}, {0x02, 5},
{0x3d, 5}, {0x3d, 5}, {0x3d, 5}, {0x3d, 5},
{0x01, 5}, {0x01, 5}, {0x01, 5}, {0x01, 5},
{0x38, 5}, {0x38, 5}, {0x38, 5}, {0x38, 5},
{0x34, 5}, {0x34, 5}, {0x34, 5}, {0x34, 5},
{0x2c, 5}, {0x2c, 5}, {0x2c, 5}, {0x2c, 5},
{0x1c, 5}, {0x1c, 5}, {0x1c, 5}, {0x1c, 5},
{0x28, 5}, {0x28, 5}, {0x28, 5}, {0x28, 5},
{0x14, 5}, {0x14, 5}, {0x14, 5}, {0x14, 5},
{0x30, 5}, {0x30, 5}, {0x30, 5}, {0x30, 5},
{0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5},
{0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4},
{0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4},
{0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4},
{0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4},
{0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4},
{0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4},
{0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4},
{0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4},
{0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3},
{0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3},
{0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3},
{0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}
};
static const CBPtab CBP_9 [] = {
{0, 0}, {0x00, 9}, {0x27, 9}, {0x1b, 9},
{0x3b, 9}, {0x37, 9}, {0x2f, 9}, {0x1f, 9},
{0x3a, 8}, {0x3a, 8}, {0x36, 8}, {0x36, 8},
{0x2e, 8}, {0x2e, 8}, {0x1e, 8}, {0x1e, 8},
{0x39, 8}, {0x39, 8}, {0x35, 8}, {0x35, 8},
{0x2d, 8}, {0x2d, 8}, {0x1d, 8}, {0x1d, 8},
{0x26, 8}, {0x26, 8}, {0x1a, 8}, {0x1a, 8},
{0x25, 8}, {0x25, 8}, {0x19, 8}, {0x19, 8},
{0x2b, 8}, {0x2b, 8}, {0x17, 8}, {0x17, 8},
{0x33, 8}, {0x33, 8}, {0x0f, 8}, {0x0f, 8},
{0x2a, 8}, {0x2a, 8}, {0x16, 8}, {0x16, 8},
{0x32, 8}, {0x32, 8}, {0x0e, 8}, {0x0e, 8},
{0x29, 8}, {0x29, 8}, {0x15, 8}, {0x15, 8},
{0x31, 8}, {0x31, 8}, {0x0d, 8}, {0x0d, 8},
{0x23, 8}, {0x23, 8}, {0x13, 8}, {0x13, 8},
{0x0b, 8}, {0x0b, 8}, {0x07, 8}, {0x07, 8}
};
static const DCtab DC_lum_5 [] = {
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
{0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3},
{4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}
};
static const DCtab DC_chrom_5 [] = {
{0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
{3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}
};
static const DCtab DC_long [] = {
{6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5},
{6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5},
{7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, { 7, 6}, { 7, 6},
{8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10, 9}, {11, 9}
};
static const DCTtab DCT_16 [] = {
{129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
{129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
{129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
{129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
{ 2,18, 0}, { 2,17, 0}, { 2,16, 0}, { 2,15, 0},
{ 7, 3, 0}, { 17, 2, 0}, { 16, 2, 0}, { 15, 2, 0},
{ 14, 2, 0}, { 13, 2, 0}, { 12, 2, 0}, { 32, 1, 0},
{ 31, 1, 0}, { 30, 1, 0}, { 29, 1, 0}, { 28, 1, 0}
};
static const DCTtab DCT_15 [] = {
{ 1,40,15}, { 1,39,15}, { 1,38,15}, { 1,37,15},
{ 1,36,15}, { 1,35,15}, { 1,34,15}, { 1,33,15},
{ 1,32,15}, { 2,14,15}, { 2,13,15}, { 2,12,15},
{ 2,11,15}, { 2,10,15}, { 2, 9,15}, { 2, 8,15},
{ 1,31,14}, { 1,31,14}, { 1,30,14}, { 1,30,14},
{ 1,29,14}, { 1,29,14}, { 1,28,14}, { 1,28,14},
{ 1,27,14}, { 1,27,14}, { 1,26,14}, { 1,26,14},
{ 1,25,14}, { 1,25,14}, { 1,24,14}, { 1,24,14},
{ 1,23,14}, { 1,23,14}, { 1,22,14}, { 1,22,14},
{ 1,21,14}, { 1,21,14}, { 1,20,14}, { 1,20,14},
{ 1,19,14}, { 1,19,14}, { 1,18,14}, { 1,18,14},
{ 1,17,14}, { 1,17,14}, { 1,16,14}, { 1,16,14}
};
static const DCTtab DCT_13 [] = {
{ 11, 2,13}, { 10, 2,13}, { 6, 3,13}, { 4, 4,13},
{ 3, 5,13}, { 2, 7,13}, { 2, 6,13}, { 1,15,13},
{ 1,14,13}, { 1,13,13}, { 1,12,13}, { 27, 1,13},
{ 26, 1,13}, { 25, 1,13}, { 24, 1,13}, { 23, 1,13},
{ 1,11,12}, { 1,11,12}, { 9, 2,12}, { 9, 2,12},
{ 5, 3,12}, { 5, 3,12}, { 1,10,12}, { 1,10,12},
{ 3, 4,12}, { 3, 4,12}, { 8, 2,12}, { 8, 2,12},
{ 22, 1,12}, { 22, 1,12}, { 21, 1,12}, { 21, 1,12},
{ 1, 9,12}, { 1, 9,12}, { 20, 1,12}, { 20, 1,12},
{ 19, 1,12}, { 19, 1,12}, { 2, 5,12}, { 2, 5,12},
{ 4, 3,12}, { 4, 3,12}, { 1, 8,12}, { 1, 8,12},
{ 7, 2,12}, { 7, 2,12}, { 18, 1,12}, { 18, 1,12}
};
static const DCTtab DCT_B14_10 [] = {
{ 17, 1,10}, { 6, 2,10}, { 1, 7,10}, { 3, 3,10},
{ 2, 4,10}, { 16, 1,10}, { 15, 1,10}, { 5, 2,10}
};
static const DCTtab DCT_B14_8 [] = {
{ 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6},
{ 3, 2, 7}, { 3, 2, 7}, { 10, 1, 7}, { 10, 1, 7},
{ 1, 4, 7}, { 1, 4, 7}, { 9, 1, 7}, { 9, 1, 7},
{ 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6},
{ 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6},
{ 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6},
{ 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
{ 14, 1, 8}, { 1, 6, 8}, { 13, 1, 8}, { 12, 1, 8},
{ 4, 2, 8}, { 2, 3, 8}, { 1, 5, 8}, { 11, 1, 8}
};
static const DCTtab DCT_B14AC_5 [] = {
{ 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
{ 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
{129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}
};
static const DCTtab DCT_B14DC_5 [] = {
{ 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
{ 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
{ 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
{ 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
{ 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}
};
static const DCTtab DCT_B15_10 [] = {
{ 6, 2, 9}, { 6, 2, 9}, { 15, 1, 9}, { 15, 1, 9},
{ 3, 4,10}, { 17, 1,10}, { 16, 1, 9}, { 16, 1, 9}
};
static const DCTtab DCT_B15_8 [] = {
{ 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6},
{ 8, 1, 7}, { 8, 1, 7}, { 9, 1, 7}, { 9, 1, 7},
{ 7, 1, 7}, { 7, 1, 7}, { 3, 2, 7}, { 3, 2, 7},
{ 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6},
{ 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6},
{ 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6},
{ 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
{ 2, 5, 8}, { 12, 1, 8}, { 1,11, 8}, { 1,10, 8},
{ 14, 1, 8}, { 13, 1, 8}, { 4, 2, 8}, { 2, 4, 8},
{ 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
{ 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
{ 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5},
{ 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5},
{ 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5},
{ 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{ 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
{129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
{129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
{129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
{129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
{ 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
{ 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
{ 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
{ 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
{ 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
{ 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
{ 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
{ 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
{ 10, 1, 7}, { 10, 1, 7}, { 2, 3, 7}, { 2, 3, 7},
{ 11, 1, 7}, { 11, 1, 7}, { 1, 8, 7}, { 1, 8, 7},
{ 1, 9, 7}, { 1, 9, 7}, { 1,12, 8}, { 1,13, 8},
{ 3, 3, 8}, { 5, 2, 8}, { 1,14, 8}, { 1,15, 8}
};
static const MBAtab MBA_5 [] = {
{6, 5}, {5, 5}, {4, 4}, {4, 4}, {3, 4}, {3, 4},
{2, 3}, {2, 3}, {2, 3}, {2, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}
};
static const MBAtab MBA_11 [] = {
{32, 11}, {31, 11}, {30, 11}, {29, 11},
{28, 11}, {27, 11}, {26, 11}, {25, 11},
{24, 11}, {23, 11}, {22, 11}, {21, 11},
{20, 10}, {20, 10}, {19, 10}, {19, 10},
{18, 10}, {18, 10}, {17, 10}, {17, 10},
{16, 10}, {16, 10}, {15, 10}, {15, 10},
{14, 8}, {14, 8}, {14, 8}, {14, 8},
{14, 8}, {14, 8}, {14, 8}, {14, 8},
{13, 8}, {13, 8}, {13, 8}, {13, 8},
{13, 8}, {13, 8}, {13, 8}, {13, 8},
{12, 8}, {12, 8}, {12, 8}, {12, 8},
{12, 8}, {12, 8}, {12, 8}, {12, 8},
{11, 8}, {11, 8}, {11, 8}, {11, 8},
{11, 8}, {11, 8}, {11, 8}, {11, 8},
{10, 8}, {10, 8}, {10, 8}, {10, 8},
{10, 8}, {10, 8}, {10, 8}, {10, 8},
{ 9, 8}, { 9, 8}, { 9, 8}, { 9, 8},
{ 9, 8}, { 9, 8}, { 9, 8}, { 9, 8},
{ 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
{ 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
{ 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
{ 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
{ 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
{ 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
{ 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
{ 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}
};
#endif//__VLC_H__

242
IPU/yuv2rgb.asm Normal file
View File

@ -0,0 +1,242 @@
;/********************************************************
; * Some code. Copyright (C) 2003 by Pascal Massimino. *
; * All Rights Reserved. (http://skal.planet-d.net) *
; * For Educational/Academic use ONLY. See 'LICENSE.TXT'.*
; ********************************************************/
;//////////////////////////////////////////////////////////
;// NASM macros
;//////////////////////////////////////////////////////////
%ifdef LINUX
;//////////////////////////////////////////////////////////
; LINUX / egcs / macros
;//////////////////////////////////////////////////////////
%macro extrn 1
extern %1
%define %1 %1
%endmacro
%macro globl 1
global %1
%define %1 %1
%endmacro
%macro DATA 0
[section data align=16 write alloc USE32]
%endmacro
%macro TEXT 0
[section text align=16 nowrite alloc exec USE32]
%endmacro
%endif ; LINUX
;//////////////////////////////////////////////////////////
%ifdef WIN32
%macro extrn 1
extern _%1
%define %1 _%1
%endmacro
%macro globl 1
global _%1
%define %1 _%1
%endmacro
%macro DATA 0
[section .data align=16 write alloc USE32]
%endmacro
%macro TEXT 0
[section .text align=16 nowrite alloc exec USE32]
%endmacro
%endif ; WIN32
;//////////////////////////////////////////////////////////
;
; MACRO for timing. NASM.
; Total additional code size is 0xb0.
; this keep code alignment right.
extrn Skl_Cur_Count_
extrn Skl_Print_Tics
%macro SKL_USE_RDSTC 0
extrn SKL_RDTSC_0_ASM
extrn SKL_RDTSC_1_ASM
extrn SKL_RDTSC_2_ASM
%endmacro
%define SKL_RDTSC_OFFSET 15 ; check value with skl_rdtsc.h...
%macro SKL_RDTSC_IN 0
SKL_USE_RDSTC
call SKL_RDTSC_0_ASM
.Skl_RDTSC_Loop_:
call SKL_RDTSC_1_ASM
%endmacro
%macro SKL_RDTSC_OUT 0
call SKL_RDTSC_2_ASM
dec dword [Skl_Cur_Count_]
jge near .Skl_RDTSC_Loop_
push dword 53
call Skl_Print_Tics
%endmacro
;//////////////////////////////////////////////////////////
globl Skl_YUV_To_RGB32_MMX
;//////////////////////////////////////////////////////////////////////
; eax: *U
; ebx: *V
; esi: *Y
; edx: Src_BpS
; edi: *Dst
; ebx: Dst_BpS
; ecx: Counter
%define RGBp esp+20
%define Yp esp+16
%define Up esp+12
%define Vp esp+8
%define xCnt esp+4
%define yCnt esp+0
Skl_YUV_To_RGB32_MMX:
push ebx
push esi
push edi
push ebp
mov edi, [esp+4 +16] ; RGB
mov ebp, [esp+12 +16] ; Y
mov eax, [esp+16 +16] ; U
mov ebx, [esp+20 +16] ; V
mov edx, [esp+24 +16] ; Src_BpS
mov ecx, [esp+28 +16] ; Width
lea edi, [edi+4*ecx] ; RGB += Width*sizeof(32b)
lea ebp, [ebp+ecx] ; ebp: Y1 = Y + Width
add edx, ebp ; edx: Y2 = Y1+ BpS
push edi ; [RGBp]
push ebp ; [Yp]
shr ecx, 1 ; Width/=2
lea eax, [eax+ecx] ; U += W/2
lea ebx, [ebx+ecx] ; V += W/2
push eax ; [Up]
push ebx ; [Vp]
neg ecx ; ecx = -Width/2
push ecx ; save [xCnt]
push eax ; fake ([yCnt])
mov ecx, [esp+32 +40] ; Height
shr ecx, 1 ; /2
mov esi, [Up]
mov edi, [Vp]
jmp .Go
align 16
.Loop_y
dec ecx
jg .Add
add esp, 24 ; rid of all tmp
pop ebp
pop edi
pop esi
pop ebx
ret
align 16
.Add
mov edi, [esp+8 +40] ; Dst_BpS
mov esi, [esp+24 +40] ; Src_BpS
mov edx, [RGBp]
mov ebp, [Yp]
lea edx, [edx+2*edi] ; RGB += 2*Dst_BpS
lea ebp, [ebp+2*esi] ; Y += 2*Src_BpS
mov [RGBp], edx
mov edi, [Vp]
mov [Yp], ebp ; Y1
lea edx, [ebp+esi] ; Y2
lea edi, [edi+esi] ; V += Src_BpS
add esi, [Up] ; U += Src_BpS
mov [Vp], edi
mov [Up], esi
.Go
mov [yCnt], ecx
mov ecx, [xCnt]
; 5210c@640x480
.Loop_x ; edi,esi: U,V; ebp,edx: Y1, Y2; ecx: xCnt
; R = Y + a.U
; G = Y + c.V + b.U
; B = Y + d.V
movzx eax, byte [edi+ecx+0]
movzx ebx, byte [esi+ecx+0]
movq mm0, [Skl_YUV_Tab32_MMX+0*2048 + eax*8]
movzx eax, byte [edi+ecx+1]
paddw mm0, [Skl_YUV_Tab32_MMX+1*2048 + ebx*8]
movzx ebx, byte [esi+ecx+1]
movq mm4, [Skl_YUV_Tab32_MMX+0*2048 + eax*8]
movzx eax, byte [ebp + 2*ecx+0]
paddw mm4, [Skl_YUV_Tab32_MMX+1*2048 + ebx*8]
movzx ebx, byte [ebp + 2*ecx+1]
movq mm1, mm0
movq mm2, mm0
movq mm3, mm0
movq mm5, mm4
movq mm6, mm4
movq mm7, mm4
paddw mm0, [Skl_YUV_Tab32_MMX+2*2048 + eax*8]
movzx eax, byte [ebp + 2*ecx+2]
paddw mm1, [Skl_YUV_Tab32_MMX+2*2048 + ebx*8]
movzx ebx, byte [ebp + 2*ecx+3]
packuswb mm0, mm1
paddw mm4, [Skl_YUV_Tab32_MMX+2*2048 + eax*8]
movzx eax, byte [edx + 2*ecx+0]
paddw mm5, [Skl_YUV_Tab32_MMX+2*2048 + ebx*8]
packuswb mm4, mm5
mov esi, [RGBp]
movzx ebx, byte [edx + 2*ecx+1]
movq [esi+8*ecx+0], mm0 ; 2x32b
movq [esi+8*ecx+8], mm4 ; 2x32b
paddw mm2, [Skl_YUV_Tab32_MMX+2*2048 + eax*8]
movzx eax, byte [edx + 2*ecx+2]
paddw mm3, [Skl_YUV_Tab32_MMX+2*2048 + ebx*8]
movzx ebx, byte [edx + 2*ecx+3]
packuswb mm2, mm3
paddw mm6, [Skl_YUV_Tab32_MMX+2*2048 + eax*8]
add esi, [esp+8 +40]
paddw mm7, [Skl_YUV_Tab32_MMX+2*2048 + ebx*8]
mov edi, [Vp]
packuswb mm6, mm7
movq [esi+8*ecx+0], mm2 ; 2x32b
movq [esi+8*ecx+8], mm6 ; 2x32b
add ecx, 2
mov esi, [Up]
jl near .Loop_x
mov ecx, [yCnt]
jmp .Loop_y

510
IPU/yuv2rgb.c Normal file
View File

@ -0,0 +1,510 @@
/*
* yuv2rgb.c
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
* Modified by Florin for PCSX2 emu
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec 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.
*
* mpeg2dec 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 <stdio.h>
#include <stdlib.h>
#include "mpeg2lib/Mpeg.h"
#include "yuv2rgb.h"
//#include "convert_internal.h" //START
typedef struct {
u8 * rgb_ptr;
int width;
int uv_stride, uv_stride_frame;
int rgb_stride, rgb_stride_frame;
void (* yuv2rgb) (u8 *, u8 *, u8 *, u8 *,
void *, void *, int);
} convert_rgb_t;
typedef void yuv2rgb_copy (void * id, u8 * const * src,
unsigned int v_offset);
yuv2rgb_copy * yuv2rgb_init_mmxext (int bpp, int mode);
yuv2rgb_copy * yuv2rgb_init_mmx (int bpp, int mode);
yuv2rgb_copy * yuv2rgb_init_mlib (int bpp, int mode);
//#include "convert_internal.h" //END
static u32 matrix_coefficients = 6;
const s32 Inverse_Table_6_9[8][4] = {
{117504, 138453, 13954, 34903}, /*0 no sequence_display_extension */
{117504, 138453, 13954, 34903}, /*1 ITU-R Rec. 709 (1990) */
{104597, 132201, 25675, 53279}, /*2 unspecified */
{104597, 132201, 25675, 53279}, /*3 reserved */
{104448, 132798, 24759, 53109}, /*4 FCC */
{104597, 132201, 25675, 53279}, /*5 ITU-R Rec. 624-4 System B, G */
{104597, 132201, 25675, 53279}, /*6 SMPTE 170M */
{117579, 136230, 16907, 35559} /*7 SMPTE 240M (1987) */
};
typedef void yuv2rgb_c_internal (u8 *, u8 *, u8 *, u8 *,
void *, void *, int);
void * table_rV[256];
void * table_gU[256];
int table_gV[256];
void * table_bU[256];
#define _RGB(type,i) \
U = pu[i]; \
V = pv[i]; \
r = (type *) table_rV[V]; \
g = (type *) (((u8 *)table_gU[U]) + table_gV[V]); \
b = (type *) table_bU[U];
#define DST(py,dst,i) \
Y = py[2*i]; \
dst[2*i] = r[Y] + g[Y] + b[Y]; \
Y = py[2*i+1]; \
dst[2*i+1] = r[Y] + g[Y] + b[Y];
#define DSTRGB(py,dst,i) \
Y = py[2*i]; \
dst[6*i] = r[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = b[Y]; \
Y = py[2*i+1]; \
dst[6*i+3] = r[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = b[Y];
#define DSTBGR(py,dst,i) \
Y = py[2*i]; \
dst[6*i] = b[Y]; dst[6*i+1] = g[Y]; dst[6*i+2] = r[Y]; \
Y = py[2*i+1]; \
dst[6*i+3] = b[Y]; dst[6*i+4] = g[Y]; dst[6*i+5] = r[Y];
static void yuv2rgb_c_32 (u8 * py_1, u8 * py_2,
u8 * pu, u8 * pv,
void * _dst_1, void * _dst_2, int width)
{
int U, V, Y;
u32 * r, * g, * b;
u32 * dst_1, * dst_2;
width >>= 3;
dst_1 = (u32 *) _dst_1;
dst_2 = (u32 *) _dst_2;
do {
_RGB (u32, 0);
DST (py_1, dst_1, 0);
DST (py_2, dst_2, 0);
_RGB (u32, 1);
DST (py_2, dst_2, 1);
DST (py_1, dst_1, 1);
_RGB (u32, 2);
DST (py_1, dst_1, 2);
DST (py_2, dst_2, 2);
_RGB (u32, 3);
DST (py_2, dst_2, 3);
DST (py_1, dst_1, 3);
pu += 4;
pv += 4;
py_1 += 8;
py_2 += 8;
dst_1 += 8;
dst_2 += 8;
} while (--width);
}
/* This is very near from the yuv2rgb_c_32 code */
static void yuv2rgb_c_24_rgb (u8 * py_1, u8 * py_2,
u8 * pu, u8 * pv,
void * _dst_1, void * _dst_2, int width)
{
int U, V, Y;
u8 * r, * g, * b;
u8 * dst_1, * dst_2;
width >>= 3;
dst_1 = (u8 *) _dst_1;
dst_2 = (u8 *) _dst_2;
do {
_RGB (u8, 0);
DSTRGB (py_1, dst_1, 0);
DSTRGB (py_2, dst_2, 0);
_RGB (u8, 1);
DSTRGB (py_2, dst_2, 1);
DSTRGB (py_1, dst_1, 1);
_RGB (u8, 2);
DSTRGB (py_1, dst_1, 2);
DSTRGB (py_2, dst_2, 2);
_RGB (u8, 3);
DSTRGB (py_2, dst_2, 3);
DSTRGB (py_1, dst_1, 3);
pu += 4;
pv += 4;
py_1 += 8;
py_2 += 8;
dst_1 += 24;
dst_2 += 24;
} while (--width);
}
/* only trivial mods from yuv2rgb_c_24_rgb */
static void yuv2rgb_c_24_bgr (u8 * py_1, u8 * py_2,
u8 * pu, u8 * pv,
void * _dst_1, void * _dst_2, int width)
{
int U, V, Y;
u8 * r, * g, * b;
u8 * dst_1, * dst_2;
width >>= 3;
dst_1 = (u8 *) _dst_1;
dst_2 = (u8 *) _dst_2;
do {
_RGB (u8, 0);
DSTBGR (py_1, dst_1, 0);
DSTBGR (py_2, dst_2, 0);
_RGB (u8, 1);
DSTBGR (py_2, dst_2, 1);
DSTBGR (py_1, dst_1, 1);
_RGB (u8, 2);
DSTBGR (py_1, dst_1, 2);
DSTBGR (py_2, dst_2, 2);
_RGB (u8, 3);
DSTBGR (py_2, dst_2, 3);
DSTBGR (py_1, dst_1, 3);
pu += 4;
pv += 4;
py_1 += 8;
py_2 += 8;
dst_1 += 24;
dst_2 += 24;
} while (--width);
}
/* This is exactly the same code as yuv2rgb_c_32 except for the types of */
/* r, g, b, dst_1, dst_2 */
static void yuv2rgb_c_16 (u8 * py_1, u8 * py_2,
u8 * pu, u8 * pv,
void * _dst_1, void * _dst_2, int width)
{
int U, V, Y;
u16 * r, * g, * b;
u16 * dst_1, * dst_2;
width >>= 3;
dst_1 = (u16 *) _dst_1;
dst_2 = (u16 *) _dst_2;
do {
_RGB (u16, 0);
DST (py_1, dst_1, 0);
DST (py_2, dst_2, 0);
_RGB (u16, 1);
DST (py_2, dst_2, 1);
DST (py_1, dst_1, 1);
_RGB (u16, 2);
DST (py_1, dst_1, 2);
DST (py_2, dst_2, 2);
_RGB (u16, 3);
DST (py_2, dst_2, 3);
DST (py_1, dst_1, 3);
pu += 4;
pv += 4;
py_1 += 8;
py_2 += 8;
dst_1 += 8;
dst_2 += 8;
} while (--width);
}
static int div_round (int dividend, int divisor)
{
if (dividend > 0)
return (dividend + (divisor>>1)) / divisor;
else
return -((-dividend + (divisor>>1)) / divisor);
}
static yuv2rgb_c_internal * yuv2rgb_c_init (int order, int bpp)
{
int i;
u8 table_Y[1024];
u32 * table_32 = 0;
u16 * table_16 = 0;
u8 * table_8 = 0;
int entry_size = 0;
void * table_r = 0;
void * table_g = 0;
void * table_b = 0;
yuv2rgb_c_internal * yuv2rgb;
int crv = Inverse_Table_6_9[matrix_coefficients][0];
int cbu = Inverse_Table_6_9[matrix_coefficients][1];
int cgu = -Inverse_Table_6_9[matrix_coefficients][2];
int cgv = -Inverse_Table_6_9[matrix_coefficients][3];
for (i = 0; i < 1024; i++) {
int j;
j = (76309 * (i - 384 - 16) + 32768) >> 16;
j = (j < 0) ? 0 : ((j > 255) ? 255 : j);
table_Y[i] = j;
}
switch (bpp) {
case 32:
yuv2rgb = yuv2rgb_c_32;
table_32 = (u32 *) malloc ((197 + 2*682 + 256 + 132) *
sizeof (u32));
entry_size = sizeof (u32);
table_r = table_32 + 197;
table_b = table_32 + 197 + 685;
table_g = table_32 + 197 + 2*682;
for (i = -197; i < 256+197; i++)
((u32 *) table_r)[i] =
table_Y[i+384] << ((order == CONVERT_RGB) ? 16 : 0);
for (i = -132; i < 256+132; i++)
((u32 *) table_g)[i] = table_Y[i+384] << 8;
for (i = -232; i < 256+232; i++)
((u32 *) table_b)[i] =
table_Y[i+384] << ((order == CONVERT_RGB) ? 0 : 16);
break;
case 24:
yuv2rgb = (order == CONVERT_RGB) ? yuv2rgb_c_24_rgb : yuv2rgb_c_24_bgr;
table_8 = (u8 *) malloc ((256 + 2*232) * sizeof (u8));
entry_size = sizeof (u8);
table_r = table_g = table_b = table_8 + 232;
for (i = -232; i < 256+232; i++)
((u8 * )table_b)[i] = table_Y[i+384];
break;
case 15:
case 16:
yuv2rgb = yuv2rgb_c_16;
table_16 = (u16 *) malloc ((197 + 2*682 + 256 + 132) *
sizeof (u16));
entry_size = sizeof (u16);
table_r = table_16 + 197;
table_b = table_16 + 197 + 685;
table_g = table_16 + 197 + 2*682;
for (i = -197; i < 256+197; i++) {
int j = table_Y[i+384] >> 3;
if (order == CONVERT_RGB)
j <<= ((bpp==16) ? 11 : 10);
((u16 *)table_r)[i] = j;
}
for (i = -132; i < 256+132; i++) {
int j = table_Y[i+384] >> ((bpp==16) ? 2 : 3);
((u16 *)table_g)[i] = j << 5;
}
for (i = -232; i < 256+232; i++) {
int j = table_Y[i+384] >> 3;
if (order == CONVERT_RGB)
j <<= ((bpp==16) ? 11 : 10);
((u16 *)table_b)[i] = j;
}
break;
default:
fprintf (stderr, "%ibpp not supported by yuv2rgb\n", bpp);
exit (1);
}
for (i = 0; i < 256; i++) {
table_rV[i] = (((u8 *)table_r) +
entry_size * div_round (crv * (i-128), 76309));
table_gU[i] = (((u8 *)table_g) +
entry_size * div_round (cgu * (i-128), 76309));
table_gV[i] = entry_size * div_round (cgv * (i-128), 76309);
table_bU[i] = (((u8 *)table_b) +
entry_size * div_round (cbu * (i-128), 76309));
}
return yuv2rgb;
}
static void convert_yuv2rgb_c (void * _id, u8 * Y, u8 * Cr, u8 * Cb,
unsigned int v_offset)
{
convert_rgb_t * id = (convert_rgb_t *) _id;
u8 * dst;
u8 * py;
u8 * pu;
u8 * pv;
int loop;
dst = id->rgb_ptr + id->rgb_stride * v_offset;
py = Y; pu = Cr; pv = Cb;
loop = 8;
do {
id->yuv2rgb (py, py + (id->uv_stride << 1), pu, pv,
dst, dst + id->rgb_stride, id->width);
py += id->uv_stride << 2;
pu += id->uv_stride;
pv += id->uv_stride;
dst += 2 * id->rgb_stride;
} while (--loop);
}
static void convert_start (void * _id, u8 * dest, int flags)
{
convert_rgb_t * id = (convert_rgb_t *) _id;
id->rgb_ptr = dest;
switch (flags) {
case CONVERT_BOTTOM_FIELD:
id->rgb_ptr += id->rgb_stride_frame;
/* break thru */
case CONVERT_TOP_FIELD:
id->uv_stride = id->uv_stride_frame << 1;
id->rgb_stride = id->rgb_stride_frame << 1;
break;
default:
id->uv_stride = id->uv_stride_frame;
id->rgb_stride = id->rgb_stride_frame;
}
}
static void convert_internal (int order, int bpp, int width, int height,
u32 accel, void * arg,
convert_init_t * result)
{
convert_rgb_t * id = (convert_rgb_t *) result->id;
if (!id) {
result->id_size = sizeof (convert_rgb_t);
} else {
id->width = width;
id->uv_stride_frame = width >> 1;
id->rgb_stride_frame = ((bpp + 7) >> 3) * width;
result->buf_size[0] = id->rgb_stride_frame * height;
result->buf_size[1] = result->buf_size[2] = 0;
result->start = convert_start;
result->copy = NULL;
#ifdef ARCH_X86
if ((result->copy == NULL) && (accel & MPEG2_ACCEL_X86_MMXEXT)) {
result->copy = yuv2rgb_init_mmxext (order, bpp);
}
if ((result->copy == NULL) && (accel & MPEG2_ACCEL_X86_MMX)) {
result->copy = yuv2rgb_init_mmx (order, bpp);
}
#endif
#ifdef LIBVO_MLIB
if ((result->copy == NULL) && (accel & MPEG2_ACCEL_MLIB)) {
result->copy = yuv2rgb_init_mlib (order, bpp);
}
#endif
if (result->copy == NULL) {
result->copy = convert_yuv2rgb_c;
id->yuv2rgb = yuv2rgb_c_init (order, bpp);
}
}
}
void convert_rgb32 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_RGB, 32, width, height, accel, arg, result);
}
void convert_rgb24 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_RGB, 24, width, height, accel, arg, result);
}
void convert_rgb16 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_RGB, 16, width, height, accel, arg, result);
}
void convert_rgb15 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_RGB, 15, width, height, accel, arg, result);
}
void convert_bgr32 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_BGR, 32, width, height, accel, arg, result);
}
void convert_bgr24 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_BGR, 24, width, height, accel, arg, result);
}
void convert_bgr16 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_BGR, 16, width, height, accel, arg, result);
}
void convert_bgr15 (int width, int height, u32 accel, void * arg,
convert_init_t * result)
{
convert_internal (CONVERT_BGR, 15, width, height, accel, arg, result);
}
convert_t* convert_rgb (int order, int bpp)
{
if (order == CONVERT_RGB || order == CONVERT_BGR)
switch (bpp) {
case 32: return (order == CONVERT_RGB) ? convert_rgb32 : convert_bgr32;
case 24: return (order == CONVERT_RGB) ? convert_rgb24 : convert_bgr24;
case 16: return (order == CONVERT_RGB) ? convert_rgb16 : convert_bgr16;
case 15: return (order == CONVERT_RGB) ? convert_rgb15 : convert_bgr15;
}
return NULL;
}

57
IPU/yuv2rgb.h Normal file
View File

@ -0,0 +1,57 @@
/*
* yuv2rgb.h
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
* Modified by Florin for PCSX2 emu
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec 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.
*
* mpeg2dec 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 YUV2RGB_H
#define YUV2RGB_H
#define CONVERT_FRAME 0
#define CONVERT_TOP_FIELD 1
#define CONVERT_BOTTOM_FIELD 2
#define CONVERT_BOTH_FIELDS 3
typedef struct convert_init_s {
void * id;
int id_size;
int buf_size[3];
void (* start) (void * id, u8 * dest, int flags);
void (* copy) (void * id, u8 * Y, u8 * Cr, u8 * Cb, unsigned int v_offset);
} convert_init_t;
typedef void convert_t (int width, int height, u32 accel, void * arg,
convert_init_t * result);
convert_t convert_rgb32;
convert_t convert_rgb24;
convert_t convert_rgb16;
convert_t convert_rgb15;
convert_t convert_bgr32;
convert_t convert_bgr24;
convert_t convert_bgr16;
convert_t convert_bgr15;
#define CONVERT_RGB 0
#define CONVERT_BGR 1
convert_t * convert_rgb (int order, int bpp);
#endif /* YUV2RGB_H */

224
InterTables.c Normal file
View File

@ -0,0 +1,224 @@
/* 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
*/
//all tables for R5900 are define here..
#include "InterTables.h"
void (*Int_OpcodePrintTable[64])() =
{
SPECIAL, REGIMM, J, JAL, BEQ, BNE, BLEZ, BGTZ,
ADDI, ADDIU, SLTI, SLTIU, ANDI, ORI, XORI, LUI,
COP0, COP1, COP2, UnknownOpcode, BEQL, BNEL, BLEZL, BGTZL,
DADDI, DADDIU, LDL, LDR, MMI, UnknownOpcode, LQ, SQ,
LB, LH, LWL, LW, LBU, LHU, LWR, LWU,
SB, SH, SWL, SW, SDL, SDR, SWR, CACHE,
UnknownOpcode, LWC1, UnknownOpcode, PREF, UnknownOpcode,UnknownOpcode, LQC2, LD,
UnknownOpcode, SWC1, UnknownOpcode, UnknownOpcode, UnknownOpcode,UnknownOpcode, SQC2, SD
};
void (*Int_SpecialPrintTable[64])() =
{
SLL, UnknownOpcode, SRL, SRA, SLLV, UnknownOpcode, SRLV, SRAV,
JR, JALR, MOVZ, MOVN, SYSCALL, BREAK, UnknownOpcode, SYNC,
MFHI, MTHI, MFLO, MTLO, DSLLV, UnknownOpcode, DSRLV, DSRAV,
MULT, MULTU, DIV, DIVU, UnknownOpcode,UnknownOpcode,UnknownOpcode,UnknownOpcode,
ADD, ADDU, SUB, SUBU, AND, OR, XOR, NOR,
MFSA , MTSA , SLT, SLTU, DADD, DADDU, DSUB, DSUBU,
TGE, TGEU, TLT, TLTU, TEQ, UnknownOpcode, TNE, UnknownOpcode,
DSLL, UnknownOpcode, DSRL, DSRA, DSLL32, UnknownOpcode, DSRL32, DSRA32
};
void (*Int_REGIMMPrintTable[32])() = {
BLTZ, BGEZ, BLTZL, BGEZL, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode,
TGEI, TGEIU, TLTI, TLTIU, TEQI, UnknownOpcode, TNEI, UnknownOpcode,
BLTZAL, BGEZAL, BLTZALL, BGEZALL, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode,
MTSAB, MTSAH , UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode,
};
void (*Int_MMIPrintTable[64])() =
{
MADD, MADDU, MMI_Unknown, MMI_Unknown, PLZCW, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MMI0, MMI2, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MFHI1, MTHI1, MFLO1, MTLO1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MULT1, MULTU1, DIV1, DIVU1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MADD1, MADDU1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MMI1 , MMI3, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMFHL, PMTHL, MMI_Unknown, MMI_Unknown, PSLLH, MMI_Unknown, PSRLH, PSRAH,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, PSLLW, MMI_Unknown, PSRLW, PSRAW,
};
void (*Int_MMI0PrintTable[32])() =
{
PADDW, PSUBW, PCGTW, PMAXW,
PADDH, PSUBH, PCGTH, PMAXH,
PADDB, PSUBB, PCGTB, MMI_Unknown,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PADDSW, PSUBSW, PEXTLW, PPACW,
PADDSH, PSUBSH, PEXTLH, PPACH,
PADDSB, PSUBSB, PEXTLB, PPACB,
MMI_Unknown, MMI_Unknown, PEXT5, PPAC5,
};
void (*Int_MMI1PrintTable[32])() =
{
MMI_Unknown, PABSW, PCEQW, PMINW,
PADSBH, PABSH, PCEQH, PMINH,
MMI_Unknown, MMI_Unknown, PCEQB, MMI_Unknown,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PADDUW, PSUBUW, PEXTUW, MMI_Unknown,
PADDUH, PSUBUH, PEXTUH, MMI_Unknown,
PADDUB, PSUBUB, PEXTUB, QFSRV,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
};
void (*Int_MMI2PrintTable[32])() =
{
PMADDW, MMI_Unknown, PSLLVW, PSRLVW,
PMSUBW, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMFHI, PMFLO, PINTH, MMI_Unknown,
PMULTW, PDIVW, PCPYLD, MMI_Unknown,
PMADDH, PHMADH, PAND, PXOR,
PMSUBH, PHMSBH, MMI_Unknown, MMI_Unknown,
MMI_Unknown, MMI_Unknown, PEXEH, PREVH,
PMULTH, PDIVBW, PEXEW, PROT3W,
};
void (*Int_MMI3PrintTable[32])() =
{
PMADDUW, MMI_Unknown, MMI_Unknown, PSRAVW,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMTHI, PMTLO, PINTEH, MMI_Unknown,
PMULTUW, PDIVUW, PCPYUD, MMI_Unknown,
MMI_Unknown, MMI_Unknown, POR, PNOR,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MMI_Unknown, MMI_Unknown, PEXCH, PCPYH,
MMI_Unknown, MMI_Unknown, PEXCW, MMI_Unknown,
};
void (*Int_COP0PrintTable[32])() =
{
MFC0, COP0_Unknown, COP0_Unknown, COP0_Unknown, MTC0, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_BC0, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Func, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
};
void (*Int_COP0BC0PrintTable[32])() =
{
BC0F, BC0T, BC0FL, BC0TL, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
};
void (*Int_COP0C0PrintTable[64])() = {
COP0_Unknown, TLBR, TLBWI, COP0_Unknown, COP0_Unknown, COP0_Unknown, TLBWR, COP0_Unknown,
TLBP, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
ERET, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
EI, DI, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown
};
void (*Int_COP1PrintTable[32])() = {
MFC1, COP1_Unknown, CFC1, COP1_Unknown, MTC1, COP1_Unknown, CTC1, COP1_Unknown,
COP1_BC1, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown,
COP1_S, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_W, COP1_Unknown, COP1_Unknown, COP1_Unknown,
COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown,
};
void (*Int_COP1BC1PrintTable[32])() = {
BC1F, BC1T, BC1FL, BC1TL, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown,
COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown,
COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown,
COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown,
};
void (*Int_COP1SPrintTable[64])() = {
ADD_S, SUB_S, MUL_S, DIV_S, SQRT_S, ABS_S, MOV_S, NEG_S,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,RSQRT_S, COP1_Unknown,
ADDA_S, SUBA_S, MULA_S, COP1_Unknown,MADD_S, MSUB_S, MADDA_S, MSUBA_S,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,CVT_W, COP1_Unknown,COP1_Unknown,COP1_Unknown,
MAX_S, MIN_S, COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
C_F, COP1_Unknown,C_EQ, COP1_Unknown,C_LT, COP1_Unknown,C_LE, COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
};
void (*Int_COP1WPrintTable[64])() = {
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
CVT_S, COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
};
void (*Int_COP2PrintTable[32])() = {
COP2_Unknown, QMFC2, CFC2, COP2_Unknown, COP2_Unknown, QMTC2, CTC2, COP2_Unknown,
COP2_BC2, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown,
COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL,
COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL,
};
void (*Int_COP2BC2PrintTable[32])() = {
BC2F, BC2T, BC2FL, BC2TL, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown,
COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown,
COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown,
COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown,
};
void (*Int_COP2SPECIAL1PrintTable[64])() =
{
VADDx, VADDy, VADDz, VADDw, VSUBx, VSUBy, VSUBz, VSUBw,
VMADDx, VMADDy, VMADDz, VMADDw, VMSUBx, VMSUBy, VMSUBz, VMSUBw,
VMAXx, VMAXy, VMAXz, VMAXw, VMINIx, VMINIy, VMINIz, VMINIw,
VMULx, VMULy, VMULz, VMULw, VMULq, VMAXi, VMULi, VMINIi,
VADDq, VMADDq, VADDi, VMADDi, VSUBq, VMSUBq, VSUBi, VMSUBi,
VADD, VMADD, VMUL, VMAX, VSUB, VMSUB, VOPMSUB, VMINI,
VIADD, VISUB, VIADDI, COP2_Unknown,VIAND, VIOR, COP2_Unknown, COP2_Unknown,
VCALLMS, VCALLMSR, COP2_Unknown,COP2_Unknown,COP2_SPECIAL2,COP2_SPECIAL2,COP2_SPECIAL2,COP2_SPECIAL2,
};
void (*Int_COP2SPECIAL2PrintTable[128])() =
{
VADDAx ,VADDAy ,VADDAz ,VADDAw ,VSUBAx ,VSUBAy ,VSUBAz ,VSUBAw,
VMADDAx ,VMADDAy ,VMADDAz ,VMADDAw ,VMSUBAx ,VMSUBAy ,VMSUBAz ,VMSUBAw,
VITOF0 ,VITOF4 ,VITOF12 ,VITOF15 ,VFTOI0 ,VFTOI4 ,VFTOI12 ,VFTOI15,
VMULAx ,VMULAy ,VMULAz ,VMULAw ,VMULAq ,VABS ,VMULAi ,VCLIPw,
VADDAq ,VMADDAq ,VADDAi ,VMADDAi ,VSUBAq ,VMSUBAq ,VSUBAi ,VMSUBAi,
VADDA ,VMADDA ,VMULA ,COP2_Unknown,VSUBA ,VMSUBA ,VOPMULA ,VNOP,
VMOVE ,VMR32 ,COP2_Unknown,COP2_Unknown,VLQI ,VSQI ,VLQD ,VSQD,
VDIV ,VSQRT ,VRSQRT ,VWAITQ ,VMTIR ,VMFIR ,VILWR ,VISWR,
VRNEXT ,VRGET ,VRINIT ,VRXOR ,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
};

491
InterTables.h Normal file
View File

@ -0,0 +1,491 @@
/* 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 INTERTABLES_H
#define INTERTABLES_H
extern void (*Int_OpcodePrintTable[64])();
extern void (*Int_SpecialPrintTable[64])();
extern void (*Int_REGIMMPrintTable[32])();
extern void (*Int_MMIPrintTable[64])();
extern void (*Int_MMI0PrintTable[32])();
extern void (*Int_MMI1PrintTable[32])();
extern void (*Int_MMI2PrintTable[32])();
extern void (*Int_MMI3PrintTable[32])();
extern void (*Int_COP0PrintTable[32])();
extern void (*Int_COP0BC0PrintTable[32])();
extern void (*Int_COP0C0PrintTable[64])();
extern void (*Int_COP1PrintTable[32])();
extern void (*Int_COP1BC1PrintTable[32])();
extern void (*Int_COP1SPrintTable[64])();
extern void (*Int_COP1WPrintTable[64])();
extern void (*Int_COP2PrintTable[32])();
extern void (*Int_COP2BC2PrintTable[32])();
extern void (*Int_COP2SPECIAL1PrintTable[64])();
extern void (*Int_COP2SPECIAL2PrintTable[128])();
void SPECIAL();
void REGIMM();
void UnknownOpcode();
void COP0();
void COP1();
void COP2();
void MMI_Unknown();
void MMI();
void MMI0();
void MMI1();
void MMI2();
void MMI3();
void COP0_Unknown();
void COP0_BC0();
void COP0_Func();
void COP1_BC1();
void COP1_S();
void COP1_W();
void COP1_Unknown();
void COP2_BC2();
void COP2_SPECIAL();
void COP2_Unknown();
void COP2_SPECIAL2();
// **********************Standard Opcodes**************************
void J();
void JAL();
void BEQ();
void BNE();
void BLEZ();
void BGTZ();
void ADDI();
void ADDIU();
void SLTI();
void SLTIU();
void ANDI();
void ORI();
void XORI();
void LUI();
void BEQL();
void BNEL();
void BLEZL();
void BGTZL();
void DADDI();
void DADDIU();
void LDL();
void LDR();
void LB();
void LH();
void LWL();
void LW();
void LBU();
void LHU();
void LWR();
void LWU();
void SB();
void SH();
void SWL();
void SW();
void SDL();
void SDR();
void SWR();
void CACHE();
void LWC1();
void PREF();
void LQC2();
void LD();
void SQC2();
void SD();
void LQ();
void SQ();
void SWC1();
//***************end of standard opcodes*************************
//***************SPECIAL OPCODES**********************************
void SLL();
void SRL();
void SRA();
void SLLV();
void SRLV();
void SRAV();
void JR();
void JALR();
void SYSCALL();
void BREAK();
void SYNC();
void MFHI();
void MTHI();
void MFLO();
void MTLO();
void DSLLV();
void DSRLV();
void DSRAV();
void MULT();
void MULTU();
void DIV();
void DIVU();
void ADD();
void ADDU();
void SUB();
void SUBU();
void AND();
void OR();
void XOR();
void NOR();
void SLT();
void SLTU();
void DADD();
void DADDU();
void DSUB();
void DSUBU();
void TGE();
void TGEU();
void TLT();
void TLTU();
void TEQ();
void TNE();
void DSLL();
void DSRL();
void DSRA();
void DSLL32();
void DSRL32();
void DSRA32();
void MOVZ();
void MOVN();
void MFSA();
void MTSA();
//******************END OF SPECIAL OPCODES**************************
//******************REGIMM OPCODES**********************************
void BLTZ();
void BGEZ();
void BLTZL();
void BGEZL();
void TGEI();
void TGEIU();
void TLTI();
void TLTIU();
void TEQI();
void TNEI();
void BLTZAL();
void BGEZAL();
void BLTZALL();
void BGEZALL();
void MTSAB();
void MTSAH();
//*****************END OF REGIMM OPCODES*****************************
//*****************MMI OPCODES*********************************
void MADD();
void MADDU();
void PLZCW();
void MADD1();
void MADDU1();
void MFHI1();
void MTHI1();
void MFLO1();
void MTLO1();
void MULT1();
void MULTU1();
void DIV1();
void DIVU1();
void PMFHL();
void PMTHL();
void PSLLH();
void PSRLH();
void PSRAH();
void PSLLW();
void PSRLW();
void PSRAW();
//*****************END OF MMI OPCODES**************************
//*************************MMI0 OPCODES************************
void PADDW();
void PSUBW();
void PCGTW();
void PMAXW();
void PADDH();
void PSUBH();
void PCGTH();
void PMAXH();
void PADDB();
void PSUBB();
void PCGTB();
void PADDSW();
void PSUBSW();
void PEXTLW();
void PPACW();
void PADDSH();
void PSUBSH();
void PEXTLH();
void PPACH();
void PADDSB();
void PSUBSB();
void PEXTLB();
void PPACB();
void PEXT5();
void PPAC5();
//***END OF MMI0 OPCODES******************************************
//**********MMI1 OPCODES**************************************
void PABSW();
void PCEQW();
void PMINW();
void PADSBH();
void PABSH();
void PCEQH();
void PMINH();
void PCEQB();
void PADDUW();
void PSUBUW();
void PEXTUW();
void PADDUH();
void PSUBUH();
void PEXTUH();
void PADDUB();
void PSUBUB();
void PEXTUB();
void QFSRV();
//********END OF MMI1 OPCODES***********************************
//*********MMI2 OPCODES***************************************
void PMADDW();
void PSLLVW();
void PSRLVW();
void PMSUBW();
void PMFHI();
void PMFLO();
void PINTH();
void PMULTW();
void PDIVW();
void PCPYLD();
void PMADDH();
void PHMADH();
void PAND();
void PXOR();
void PMSUBH();
void PHMSBH();
void PEXEH();
void PREVH();
void PMULTH();
void PDIVBW();
void PEXEW();
void PROT3W();
//*****END OF MMI2 OPCODES***********************************
//*************************MMI3 OPCODES************************
void PMADDUW();
void PSRAVW();
void PMTHI();
void PMTLO();
void PINTEH();
void PMULTUW();
void PDIVUW();
void PCPYUD();
void POR();
void PNOR();
void PEXCH();
void PCPYH();
void PEXCW();
//**********************END OF MMI3 OPCODES********************
//****************************************************************************
//** COP0 **
//****************************************************************************
void MFC0();
void MTC0();
void BC0F();
void BC0T();
void BC0FL();
void BC0TL();
void TLBR();
void TLBWI();
void TLBWR();
void TLBP();
void ERET();
void DI();
void EI();
//****************************************************************************
//** END OF COP0 **
//****************************************************************************
//****************************************************************************
//** COP1 - Floating Point Unit (FPU) **
//****************************************************************************
void MFC1();
void CFC1();
void MTC1();
void CTC1();
void BC1F();
void BC1T();
void BC1FL();
void BC1TL();
void ADD_S();
void SUB_S();
void MUL_S();
void DIV_S();
void SQRT_S();
void ABS_S();
void MOV_S();
void NEG_S();
void RSQRT_S();
void ADDA_S();
void SUBA_S();
void MULA_S();
void MADD_S();
void MSUB_S();
void MADDA_S();
void MSUBA_S();
void CVT_W();
void MAX_S();
void MIN_S();
void C_F();
void C_EQ();
void C_LT();
void C_LE();
void CVT_S();
//****************************************************************************
//** END OF COP1 **
//****************************************************************************
//****************************************************************************
//** COP2 - (VU0) **
//****************************************************************************
void QMFC2();
void CFC2();
void QMTC2();
void CTC2();
void BC2F();
void BC2T();
void BC2FL();
void BC2TL();
//*****************SPECIAL 1 VUO TABLE*******************************
void VADDx();
void VADDy();
void VADDz();
void VADDw();
void VSUBx();
void VSUBy();
void VSUBz();
void VSUBw();
void VMADDx();
void VMADDy();
void VMADDz();
void VMADDw();
void VMSUBx();
void VMSUBy();
void VMSUBz();
void VMSUBw();
void VMAXx();
void VMAXy();
void VMAXz();
void VMAXw();
void VMINIx();
void VMINIy();
void VMINIz();
void VMINIw();
void VMULx();
void VMULy();
void VMULz();
void VMULw();
void VMULq();
void VMAXi();
void VMULi();
void VMINIi();
void VADDq();
void VMADDq();
void VADDi();
void VMADDi();
void VSUBq();
void VMSUBq();
void VSUBi();
void VMSUBi();
void VADD();
void VMADD();
void VMUL();
void VMAX();
void VSUB();
void VMSUB();
void VOPMSUB();
void VMINI();
void VIADD();
void VISUB();
void VIADDI();
void VIAND();
void VIOR();
void VCALLMS();
void VCALLMSR();
//***********************************END OF SPECIAL1 VU0 TABLE*****************************
//******************************SPECIAL2 VUO TABLE*****************************************
void VADDAx();
void VADDAy();
void VADDAz();
void VADDAw();
void VSUBAx();
void VSUBAy();
void VSUBAz();
void VSUBAw();
void VMADDAx();
void VMADDAy();
void VMADDAz();
void VMADDAw();
void VMSUBAx();
void VMSUBAy();
void VMSUBAz();
void VMSUBAw();
void VITOF0();
void VITOF4();
void VITOF12();
void VITOF15();
void VFTOI0();
void VFTOI4();
void VFTOI12();
void VFTOI15();
void VMULAx();
void VMULAy();
void VMULAz();
void VMULAw();
void VMULAq();
void VABS();
void VMULAi();
void VCLIPw();
void VADDAq();
void VMADDAq();
void VADDAi();
void VMADDAi();
void VSUBAq();
void VMSUBAq();
void VSUBAi();
void VMSUBAi();
void VADDA();
void VMADDA();
void VMULA();
void VSUBA();
void VMSUBA();
void VOPMULA();
void VNOP();
void VMOVE();
void VMR32();
void VLQI();
void VSQI();
void VLQD();
void VSQD();
void VDIV();
void VSQRT();
void VRSQRT();
void VWAITQ();
void VMTIR();
void VMFIR();
void VILWR();
void VISWR();
void VRNEXT();
void VRGET();
void VRINIT();
void VRXOR();
//************************************END OF SPECIAL2 ************
#endif

1058
Interpreter.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,334 @@
/* XPM */
static char *pcsxAbout[] = {
/* columns rows colors chars-per-pixel */
"314 176 152 2",
" c #252d42",
". c #282e45",
"X c #282f48",
"o c #273046",
"O c #283046",
"+ c #2a334b",
"@ c #2d3650",
"# c #2e3853",
"$ c #303651",
"% c #303955",
"& c #333d5b",
"* c #383f57",
"= c #383e5d",
"- c #35405e",
"; c #39415d",
": c #364161",
"> c #384465",
", c #3a4668",
"< c #3e4866",
"1 c #3c496c",
"2 c #3e4b70",
"3 c #40475b",
"4 c #41485d",
"5 c #404767",
"6 c #424a63",
"7 c #434c6c",
"8 c #484f61",
"9 c #464e70",
"0 c #44506f",
"q c #4c5263",
"w c #465071",
"e c #495273",
"r c #4d5679",
"t c #4e5974",
"y c #4e587b",
"u c #515665",
"i c #535866",
"p c #545968",
"a c #595d69",
"s c #50577b",
"d c #505a75",
"f c #51597d",
"g c #5c606a",
"h c #55617f",
"j c #5a637b",
"k c #64666d",
"l c #65686e",
"z c #666870",
"x c #6b6d71",
"c c #6e7073",
"v c #767676",
"b c #545d81",
"n c #566085",
"m c #586185",
"M c #5b648a",
"N c #5e6883",
"B c #5e688d",
"V c #666d84",
"C c #606a8b",
"Z c #686f86",
"A c #626b93",
"S c #656f98",
"D c #687085",
"F c #6a738c",
"G c #667097",
"H c #667098",
"J c #6d7691",
"K c #6b749d",
"L c #6e7893",
"P c #72788c",
"I c #757d93",
"U c #6d76a0",
"Y c #6e78a1",
"T c #717ba4",
"R c #747ea8",
"E c #7c8397",
"W c #79829a",
"Q c #7680ab",
"! c #7a84ae",
"~ c #7c85b1",
"^ c #7e88b3",
"/ c #808080",
"( c #80838f",
") c #888888",
"_ c #808799",
"` c #82899d",
"' c gray57",
"] c gray60",
"[ c #858da3",
"{ c #858eba",
"} c #8d93a5",
"| c #8f95a8",
" . c #8690bc",
".. c #8891bd",
"X. c #9096a9",
"o. c #999ead",
"O. c #9aa0af",
"+. c #9ca2b4",
"@. c #a2a2a2",
"#. c #aaaaaa",
"$. c #a5a9b6",
"%. c #a7acba",
"&. c #a8adbc",
"*. c #aab0bf",
"=. c #bababa",
"-. c #8e96c3",
";. c #8e98c4",
":. c #9099c6",
">. c #959dca",
",. c #96a0cc",
"<. c #98a0cd",
"1. c #9ca5d1",
"2. c #a4add9",
"3. c #aab0c0",
"4. c #b3b6c2",
"5. c #b4b8c4",
"6. c #b6bbc8",
"7. c #adb5e1",
"8. c #b0b7e3",
"9. c #b0b8e3",
"0. c #bec2cb",
"q. c #bfc7ef",
"w. c #bfc7f0",
"e. c #c2c2c2",
"r. c #c0c3cd",
"t. c gray80",
"y. c #c2c6d1",
"u. c #ccced6",
"i. c #cdd0d7",
"p. c #ced1d9",
"a. c #d0d2d7",
"s. c #d4d5d9",
"d. c #dddddd",
"f. c #c0c7f0",
"g. c #c3cbf2",
"h. c #c8cef4",
"j. c #cad0f5",
"k. c #d9dbe1",
"l. c #d2d8f6",
"z. c #dbdff8",
"x. c #dce0f8",
"c. c gray90",
"v. c #e5e7eb",
"b. c #e6e8ec",
"n. c #eeeeee",
"m. c #e1e5f9",
"M. c #ebeefb",
"N. c #eff1fc",
"B. c #f2f3f5",
"V. c #f0f1fc",
"C. c #f7f8fd",
"Z. c #fefefe",
/* pixels */
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 1 2 1 1 2 1 1 2 2 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 1 1 2 , , , 1 , 1 , 1 1 , , , , 1 , , , , 1 , , , , , , > , > > , > , , : , , : , : , : , : > > > > : > > , : : : : > : : > : : : : : : : - : : - : - - : - - - - - - & - - & - - & & & & & & : & & & & & & & & & & & & & # # # # # & & # & # & # # & # # # # # # & # # & # # # # # # # # # # # @ # @ @ # @ @ @ @ @ @ @ @ @ X @ @ + @ @ + @ + @ + @ + + @ + + @ + + @ + + + + + + + + + + + + + + o + + o + + + o + X o X X + o o O O O O O X X O . . . . . . . . . o o . . . . o . o ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 2 2 1 1 2 2 1 2 1 2 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 , 1 , , , , 2 1 , 1 , , , , , 1 , , , , , , , , , , , , > , , , > , > : , , : : , , : , : , : > > , : : > > : : : , : : : : > : : : : : : : : : - : - - - : - - - - - - & - - & - - & : & : & : & & & & & & & & & # & & # & & & & & : & # # & # & # & & # # & & # & # # # # # # # # # # # # # # @ # @ @ # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ + @ + @ + @ + @ @ + + @ + + + + + + + + + + + + + + + o X + + o o + o + o + X X + + + o X o X X O O O O o o O X O . . . o o . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 2 1 2 1 1 1 1 1 2 1 1 1 1 1 1 1 , 2 , 1 1 1 , 1 1 1 1 , , 1 , 1 1 , 1 1 , 1 , 1 , , , , , , , , , , , > , , > , , > , , , : , : : , : , > : , > > : : > > : > : : > : : : : : > - : : - : - - : : : - : - - - - - & - & & - & - & & & & & & & & & & & & & & & & & # & # : # # # & & & & & # & # # & & # & # # # # # # # # & # # % # @ # # @ # # @ % @ @ @ @ @ @ @ @ @ @ @ @ X @ @ + @ @ @ + @ + @ + + + + + + + + + + + + + + + + o + + + + X + o + + o + o o @ + X + X o o o X + X O O O O X X . . . o o . . o . . . . . . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 2 1 2 1 2 1 1 2 1 1 1 1 1 1 2 , 2 2 1 1 1 1 , , 1 1 1 , 1 , , 1 , , , , , , , , , , , , , , > , , > , > , > , > : , , > , , , : , : > > : > > > : > : > : : > : : : : : : : : - : : - : : - - - - - - - - - - - - - - - - & : & & : & & & & & & & & & # & & & & & & & # & : # & # # & # # & # # & # # # & & & # # & # # # # # # # # # # @ # @ @ # @ % @ @ @ @ @ @ @ @ @ @ @ + @ + + @ + + @ + + @ + + @ + + + @ + + + + + + + X + + + + + X + o + + o + o o X X X o o + o X O O O O X O O O O . . . o . o . . o . . . . ",
"2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 1 2 1 1 1 2 1 2 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 , 2 , 1 , 1 1 , 1 1 , , , , , , , , , , , , , , , , , , , > , , > , : , : : : , : , > : , , : , : > > , : > : : , : , : : : : > : : : : : : : : - - - - - - - - - : & & - - - & & & : & & & & & & & & & & & & & & & & : # # & & # # & # & # & # & & # # & # # # # & # # & # # # # @ # % % # # # # @ # @ @ @ @ @ @ X @ @ @ @ @ @ @ + @ @ @ + @ @ + @ + + @ + + @ + + + + + + + + + + + + + + + + + + o o @ X o + o + o + o + + X X O O + O O O . . O . . . o o o o o . o o . . . . ",
"9 2 2 2 w 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 2 2 2 1 2 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 , 1 , 1 , 1 , , , 1 1 1 , 1 , , , , , , , , , , , , > , > > , , , > , , , : , : , , : : , : > > : : : , : : : : : : > : : : : : : - : : : - : : - - - - - - - & - : - & - & - & & & & & & & & & & & & & & & # & : # # # : # & & # & # & # & # # & # & # & # & # # # # # # # # % # @ # # # @ # # @ # @ @ @ @ @ # @ @ @ @ X @ @ @ + + @ @ @ + + + + + @ + @ + + + @ + + + + + + + X + X + o + o X + + o o + o o o + o o o o o o O O O O O O O . . O . o . o . . o . . . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 1 2 2 2 1 1 2 1 2 1 1 2 1 1 1 1 1 1 1 , 1 1 , 1 1 1 , , 1 1 , 1 , 1 , 1 , , 1 , , , , , , , , , : , > , , , , > , > > , , , : , , : , : : > , : , : > > : , : : : > : : : : : : : : : : : : - : - : : : - - : - - - : & & - & - - - & : & & : & & & & & & & & & & & # & : & & : # : & & # & # & # & # & # # # # # # # # # # # # # # # # # # # @ @ # @ @ # @ # @ @ @ # @ @ @ @ @ X @ @ @ + + + @ + @ @ + @ + + + + + + @ + + + + + + + + + o + o + X + o + + + X o + + o o + o o + o O O O O O O . . O . o . . o . . . o . . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 1 1 1 , 1 , 1 , 1 , 1 , , , 1 , , , , , , , , , , , > , > , > , , > : , , > > , , : , > > > : > : > : : > : > : : > : : : : : : : : - : : - : - - - - - - - - - & : - - & - & & & : & & & & & : & & & & & & & & & & # # & # # & # & & # & # # & & # & # & # & # # & & # # # # & # # # # # # # # @ # @ # @ @ @ @ @ @ @ @ @ @ @ @ @ + @ @ @ + + @ + @ + + + @ + @ + + + + + + + + + + + + + + X + X + o + o @ + o o + o o + o X + O O O O O O O O o o . . o o . . . o . . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 1 2 1 2 2 1 2 1 2 1 2 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 2 , , , , , 1 , , 1 , , , , , , , , , , , , , , > , , > , , , , , , : , , : , , : > > , > > > > , : : , : : , : > : : : : : : > : : : - : - - : - - - - - - - - - : & & & & : & & : & & & & & & & & & & & & & # & # & # & # & & & # & # & # & # & # # & & # % # # & # # % @ & & @ & @ @ @ # @ @ # # @ @ @ @ @ @ @ @ # @ @ @ @ @ + @ + + @ @ + @ + @ @ + + @ + @ + + + + + + + + + + + o + + o + o + + + O + + O + + + X X o o o O O O O O X X O O O O O O . . . . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , , , 2 2 , 2 , , , , , , 1 , , , , , , , , , , , , , , , > , : , : , : , : , , : , > > : > : : > : : , : , : : : : > : : : : : : : : : : - : - : - - : - - - - - : & & : : & & : & & : & & & & & & & & & & & & & & & & & & & & # & # # & # & # & # & # # # % % # # # # # % @ @ @ @ @ % @ # # @ # @ # @ # # @ # @ X @ # X X # @ @ @ @ @ @ @ + + + @ + + + + + + + + + + + + + + + o + + + + o + + X + O O + + o O o X X X + o O X X X O O O O X . o O O O X o O . . o o o o o ",
"2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 1 2 1 2 1 1 2 1 2 2 2 1 1 2 2 1 2 1 1 1 1 , 1 1 1 1 , 1 1 1 , , 2 , 2 , 1 1 1 , 2 , , 1 , , , , , , , , , , , , , > , : : , , , : , , : : , > > : , : : : , , : : : , : > : , : , : : : : : - : : - : - : - - - - - - - & & : & : & & & & & & & : & & & & & & & & & & & & # & # & & & # & & # # & # # & & # # & # & # & # # # & & @ @ @ % @ @ % # @ @ @ # @ # @ @ @ # @ # X # # @ @ X @ @ @ @ @ + @ + @ + + @ + @ + + + + + + + + + + + + + + + X + X + + + o + o X o + X X X + o + + o O + O O O O O O X o o O O o . . . . o . o ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 2 , 1 , , , , , , , , , , , 1 , , , , , , , , , > , , > , , , , : , , , : , , > , : , : , , : : : : , : : : : : : : : : : : : : : - : : - : - : - - - - - - : : : & & : & : & : & & & & & & # & & & & & & & & & & & & # & & # & & & # & & # # & & # # # # # & # # # @ @ & @ @ % # @ # # # @ @ # @ @ @ @ @ @ # # # @ @ @ @ @ + @ + + @ + + @ + @ + @ + + + @ + + + @ + + + + + + + + + + + + O + + + O + + X + o X X O O o o O O O O O O X X O X O O O o . . o . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 1 2 1 2 2 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 , , 1 , , 1 , 2 1 , , , , , 1 , , , , , > , , , , , , > , : , , , , : , , : : , > > , : , : : > , : , : : : : : : : , : : : : : : : : : : : : - - - - - - - - & : & : & - & & & : & : & & & & & & & & & & & & & & & & # # & # & # & # & & & & # # # & # % & # & # # # # & # # & & @ % @ @ % @ @ @ @ @ # @ @ @ @ @ @ @ @ @ @ @ @ @ + @ @ + @ @ + @ @ + + @ + + + + + + + + + + + X + + + o + + X + + O + X + X + + O + O O O O O O O O O O O O . X O O o . o O . . o . o o . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 2 1 1 2 2 1 2 1 1 1 2 1 1 2 1 1 1 2 1 1 1 1 1 1 1 , 1 1 1 1 2 1 , 1 , 1 1 , , , 1 1 , , , , , , , , , , , , , > , , , , , : , : , : , , , : > > : , : , > > : > > : , : , : : : : : : : : : : : : : : : - : : - : - - - - - & : & & & : : & & & & & & & & : & & & & & & # & # & & & & & # & & & & # # # # & & # & # # # # # # # # # # # @ @ % @ @ @ @ @ & @ @ # # @ @ @ @ @ @ @ @ @ X @ X @ @ + + @ @ + @ @ + + @ + + + + + + + + + + + + + + + + + + + + + O + + o X + + o O O O O O + O O O O O O O o O . O O . . O . . . . o . o ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 1 2 1 2 2 2 1 2 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 1 1 1 , 1 , 1 1 , 1 , , , , , , , , , , , , , , , : , : , , : , , : , , : , , > > , : > , : : : > > : , : , : : : : : : : : : : : : : : : - - : : - - - - - - : : & : : : & & : & & & : & & & # & & & & & & # & & & & & # & # & # # & & # & # & # # & # & # # & # # # # # # & @ @ @ % # # # # # @ @ @ @ @ @ @ @ @ @ @ X @ @ @ @ @ @ + + @ + + @ + + @ @ + + + + + + + + + + + o + + + o + + o o + + o O + + O + X O + O O O O O O O O O X O o O O O X o . . . . . o . . . o ",
"e 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 1 1 1 2 1 1 1 2 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 1 , 1 1 , , , , 1 , , 1 , , , , , , , , > , , , , , , , : , , , : , : , > > : > , : : , , : > > : : : : : , > : : : : : : : : : : : : : - - - - - - - - : & & - & & : & & & : & & & & & & & & & & & & & & & & # & & & & & # & & # & # & # & # # # & % & # # & # # # # # @ & % @ # @ @ # # @ # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ + @ + @ @ + + @ + + + @ + + @ + + + + + + + + + + o + + X + + + + X X + X X + O O O + + O O O O O O O . X O . . . . . o . . o . . . . . . ",
"2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 1 2 1 1 2 2 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 , 1 1 , 1 , 1 1 1 1 , , 1 > , 1 > , , 1 , , , , , , , , , , , , , , , , : : , , : > > > > > , > > > : : , : > : : > : > : > : : : : : : : - : - - - - - - - - - & - - : & & & & : - & & : & & & & : & & & & & & # & & & # & & & # & # & # & # & # & & # # # & # % % % % % % % % @ # # # # # @ @ @ # # @ @ # @ @ @ @ @ @ @ @ @ @ X @ @ @ @ @ @ @ X X @ + + @ + + @ + + + + + + + + + + + O + + + o + o + + O + O O O + O + X O O + O + X O X o O . . . . o o . . . . o . O O O O ",
"2 2 2 2 2 2 2 e 2 2 2 2 2 2 2 1 2 2 2 1 2 2 2 1 1 1 1 2 1 1 2 1 2 1 1 1 2 1 1 1 1 1 1 1 1 , 1 1 , 1 1 , 1 1 1 1 1 , , 1 1 , , 1 , , , , , , , , , : , , , , : , , : , , , , : , > > > > : : > : , : > : : : , : : > : : : : : : : : - : : : - : : : - : - - - - - - & : : : & & - - & & : & & & & & & & & & & & & & & & & # & & & # % & # & # & # # # & # & # # % % % @ % @ % % @ % @ # # @ % # @ @ # @ @ @ @ @ @ @ X @ @ @ @ @ @ @ X @ X @ X @ @ + @ + + + + + + + + + + + + + + + + + O X + + o + X o O O O + O O O O O O X X O O O O O O . . . o . . . . o o . o . O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 1 2 1 2 1 1 2 1 2 2 2 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 , 1 , , , , , 1 , , , 1 , , , , , , , , , , : , : : , : , : , , : , : > > > > > > > > > > : > : : : : : : : : : > : : : : : : - : : - - - : - - - - - & : & & & : : & & - - & & & & - & & # : & & & & & & & & & # # & & & & # & # & # # & & # % # # # @ % % % @ % % @ % # # # @ % # # @ # @ @ @ @ @ @ @ @ @ @ @ @ @ @ X @ @ @ @ @ @ @ + @ @ + @ + + + + + + + + + + + + O + + + + O + O O + + O + o + O + O + O o O + O O O O O O O X . . . o . . O O . o O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 , 1 1 , , 2 , , 1 , , 1 , 1 , , > 1 , , , , , , , , , , , , , , , , , , > , : , , , : > > > > > > > : : : , : > , : > > : > : : : : : : : : : : : - : : - - - - : - - - - : & : & & & - & & & & & & & & & & & # : # & # & & & & & & # # & % & & # # & % # & # # & % & % % % @ % % % # # # # # @ # @ # # @ @ # @ # @ @ @ @ @ @ @ @ X @ @ @ X @ @ @ X @ + @ + + + + + @ @ + + + X + + + + + + + O + + + + + o + + o + X + O O O O O X O O O O O X X . . . . o . X O o . . o O . O O O ",
"2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 1 2 2 2 1 2 2 1 1 2 2 2 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 , , 2 , 1 , 1 , , 1 , 1 , 1 , , , , , , , , , > , , , : , : , , : , > , : , > , , , > > > > > > > > : > > : : > : > : > : : : : : : > - : > - : : - - : - - - - - - - & - & & & : & & & & - & & & & & & & & & # & & & & & # & & & # # & & & & # # # % % & % # % # # % # @ % % # # % % @ % @ # # # $ # @ # @ @ @ @ @ @ @ @ @ @ # @ @ + @ @ @ X @ X @ @ + @ @ + + + + + + + + + + + + + + X + + + O O + O O + O O + o O + O + O O O O + X O O O O O . o . . . . o . O O . O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 2 1 2 2 1 1 1 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 1 , 1 1 1 , , , , , , 1 , , , , , , , , , , , , , , > , , , , > , > > > , : > > > > : > > > > > : > > : : : : > : > : : > : - - : - : - - : : - - - - - - - - - - : : & & : & - - & - & - & & & & & & : & & & # & & # & & & & # # # # & & & & % % % % % % # % % @ % % # % @ # # @ % # # @ # @ # @ @ # @ @ @ @ @ @ @ @ X @ @ @ @ + @ @ @ @ @ + + + + @ @ + + + + + + + + + + + + + + + + + + + + + + O + o + + O O O O + O O O O X O o O O . o O . o . . o O O O O O . O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 1 2 2 2 1 1 1 2 1 2 2 1 1 1 1 1 1 1 1 1 1 , 1 1 , 1 , 1 1 1 , 1 , 1 1 , 1 , , , , , , , , , , , , , , , , , , : , , , , : , > > > > > > > > > > : > > > > : > : , : : : : > : : : : - > > - - - : - - : : - - - - - & : & : : & & : : & & & & & & & & & & & # & & # & & & & & & # & & & & # & # & # % % % % # # % & # % % % # # # # @ % # # # # # @ @ # # @ # @ @ @ @ @ # X @ @ @ @ @ @ @ X + @ X @ + @ @ + + + + + + + + + + + + + o + O + + O + O O + O O + + o o O + O O O + + O O O O O O X O . o . o o . . . . O O O O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 2 2 2 1 1 2 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 , 1 , , 1 , , 1 , , , , , , , , , , , , , : , , , : , : , : , , > > > > > > > > > > : : > > > : > : : > : : : : > : : > - - - - : - : : - - : - - - - : & : & & & : & & & - & & & : & & & & & & & & & & # & & # & # & & # & # & & # & % % % % & # % # % # % % % % # # % @ % @ $ # # @ # @ @ # @ @ @ @ @ @ @ @ @ @ X @ @ X @ + @ @ X @ + @ + + @ + @ + + + @ + + + + + + + + + + O + + + O + O + o X + O X + O O O O O O O O O O O . O o o . o o . . O O O . O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 2 1 1 1 1 1 1 2 1 1 1 2 1 1 1 1 1 1 1 1 , , 1 1 , 1 1 1 , , 1 1 , 1 > 1 1 > 1 , , , , > , , , , , : , , : , , , , , > , > > > : , > > > > > > > > : > : , : , > : : : > : : : - : : : - : - : - : : - - - - - & : & : & & : & & & & & & : & & & & & : & & & : & & : & & & & # # & & # & # & # # & % % % % % % % # # # % % # # # % # @ % @ @ % @ # @ # @ # @ # @ @ @ @ # @ @ @ @ @ @ + + @ + + + @ + + + + + + @ + + @ + + + + X + + X + + O + + X X X + O + O O + + o o O O O O O O O O O X . . . o . . o . o . . . o o O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 2 2 1 2 1 1 2 1 2 1 2 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , , 1 , 1 , 1 , 1 1 1 > 1 > , , 1 , , , , , , , , , , , , , , > : , > > > > > , : , > : : > : > : > : : : : : > : : : : : : > : : : : : : - : - : - - - - - : & : & & : & & & : : & & & & & & & & # & & & & # & # # # & # & & # # & # & # & & % % % % % # % % % % # # # % # # @ @ % # # # # @ @ @ @ @ @ @ @ @ @ @ @ X @ @ @ @ + + @ @ + + @ @ + @ + + @ @ + + + + + + + + + + + + + X + + + + + + + X + O X O X X + O O O + O X O O O O O O . . o . o . O o O . o O O ",
"y 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 1 2 2 2 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 , 1 1 1 , 1 , 1 1 , , 1 > 1 1 > , 1 , , , , , > , , , , , , > , : , > , > , > , , : , : > > : > > : > : , : , : : : > : : : : : : - : : : - - - - - - - - - - - : : & : : & : & & & & - & : & & & & & & & & : # & & & & # & & & & & & & & # & # # % % % % % % % # # # % % # # # # % @ # @ # # @ # # # @ @ # @ @ @ @ @ @ # # @ @ @ @ @ + + @ @ X + @ + + @ X + + + + + + + + + + + + + O + + + X X + X X O + O + O O X X O O O O X O O O O X o O . . o . . o . . o O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 2 1 2 1 1 1 2 1 2 1 2 1 1 1 1 1 1 1 1 1 1 , 1 , 1 , 1 , 1 , , , 1 , 1 1 , 1 1 > 1 , , , , , , , , : , , , : , : , , , > > > > > > > > > > > > > > > > : , : : : : , : : : > : : : : : : : - : : : : - - : - - - - & & : & & & : & : & & & & & & & & & & : # # # # & & # & & & # & # & # # # & # & # & % % % % % % % % # % % % % # # # % # # # @ # @ # @ @ @ @ @ @ @ # X @ # X @ @ X + @ @ @ + @ @ @ + @ + + + @ + + + + + + + + + + + + + + + X + O O + + O X X + + O + X O O + O X + O O O O o O . O . . . . o . o . . . . O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 1 1 1 1 2 1 2 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 , 1 1 , , 1 , , , 1 > , , , , , , > , , , , , , , , , , , > : > > > > : , > , : : > , : > > : : : , : : : : : : : : : : : : : - - : - : - - - - - - - : : & : : & - & & & - & : & & & & & & & & & & & & : & & & & # & & # & & & # % % % % % % % % % % % % % % # # # % % # % # % # # # # # @ # @ @ @ @ @ @ @ @ @ @ X # @ @ @ + @ + @ + + + @ + + + + @ + + + + + + + + + + O + + + O + + + + O + O + O O O O O + O + X O X O O O O O O O o o o o o . . . . . . o ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 1 2 2 2 1 2 2 1 1 2 1 1 1 1 2 1 1 1 1 1 1 1 1 , 1 , 1 1 1 1 , 1 , , , , , , , , , 1 , , , , , , , , , , , : , : : , , , , , > , > > , > : : , , : : , : > : : , : : : : , : : : : : : : : : : : - - - : - - - - - - & & : & & - : & : & & & & & & & & & & & & # & & & # # # & # & & % % & # % & % % % & % % % % % % # % # # # # # # # # # @ @ @ % @ # @ @ @ @ # @ @ @ @ @ X @ @ @ @ @ @ @ @ + @ @ X + @ + @ @ + + + + + + + + + + + + + + + O O + + + O O + O + O + + + O X O O O X O O O O O O O . O o o o . . . o . . . o o o o O ",
"2 2 2 2 2 2 2 y 2 2 2 2 2 2 2 2 2 1 2 1 1 2 1 1 2 1 1 1 1 1 2 1 1 2 1 1 1 1 1 1 1 1 , 1 1 1 1 1 1 1 , , , , , , 1 , 1 , , , , , , , , , , , , , , , > , , , > , : , , , > > , > : , , > > > , : : : > > : : : : : : : : : : : : : : : : - : : : - - - - - - - - : & : & : & & & & & & & & & & & & & & & & & & & & # & & & & # & % & % & % & % & % % % % % % % % % # % # # % # # % @ # # @ # @ @ @ # # # @ @ @ @ @ @ @ @ @ @ @ # + + @ + @ @ + @ @ @ + + + @ + + + + + + + + + + + + + + + + + O + O + O O X + O O O O + O O O O O O O O O O O o O . . . o . . o o o . o o ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 1 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 , 1 1 1 1 1 1 , , 1 , , , 1 , , , , , , , , , > , , > , , , > : , , > > , > > > > : > > > : > : , > : , : , : , : : : : : : , : : : - : - - : : - - : - - - - & : & : & - & : : & & : & & & & & & & & & & & & : # & & # : # # & % & # & # % % % & % % % % % % % # # % # # # # $ # # # @ % % # @ @ @ @ @ @ @ @ @ @ @ @ X # @ X @ @ @ + @ + @ + + + @ + + + + @ + @ + + + + + + + + O O + + + O + + O + + + O O + O + O O + O O O O O O O O O O . . O . . . o . . . . o o O ",
"2 0 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 1 2 1 2 2 1 1 2 2 1 2 1 1 1 2 1 1 1 1 1 1 1 1 , 1 , 1 1 , 1 , 1 , 1 , 1 , 1 , 1 , , , , , , , , , , > , , , > > > > > , > , > > , : , : , : > : : > > > > > : : > : : > : : : : : : : : : : : : : & : & & : - - : - & : & : # : : : # : : & & & : & @ - - - # - - - @ - - @ # - # # - - # # - # # # # % % - # # % % # # # # # # # # # # % # # @ % # # @ @ @ @ @ @ @ @ @ @ + @ @ @ + @ + @ + + @ + + + + @ + @ + + + + + + + + + + + + + X X + + + + X + o + O + O O O + X O X o O + O O O O O O . . . . . o . . . . o o . o . O O ",
"2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 1 1 2 2 1 2 1 2 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 , 1 1 1 1 , 1 , , 1 1 1 1 , , , , 1 , , 1 , , , , , , , , , , , , > 1 > 1 > 1 > > , > > , , : , > > : , , : : > : > : > : > > : : : : : : : : & : : : : : : : : : : - : & : : & : & : : : # # : : # # : : # - - # - @ - @ - - @ @ - - # - # # % # - # # % - - % % % # % # % % # & # # # # # # # # # # # @ @ # # @ # @ @ @ @ @ @ @ @ @ @ + @ @ # + @ @ + @ # @ @ + @ + + @ + @ + + + + + + + + + + + + X + + + o X + + O O + O O o o + o o o O O O O + O X X . . . o . . o . o . o . ",
"2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 1 2 2 2 2 2 1 1 2 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 , 1 , 1 , 1 , , , , , , , , , , , , , , , > , , , 1 > > 1 > > > > , : : , > > , : , : , , > > > > > : : : : > > : > : : : : : : - & : : : : : - & : & : & : & & : : # : : : # : : & : & & # - - - - - # - - - - - # - - # # - - # # - # - # % % % % % % % & # # # % # & # % @ % % # # # # @ # # @ @ @ @ @ @ @ @ @ @ @ @ @ @ + + @ @ + @ + + + + + + + @ + + + + + + + + + + + o + + + + o X + o + O + X o + o + + + O O O O O O O X o X O . o o . O X O . . . . o O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 1 2 1 1 1 1 1 2 2 1 1 1 1 1 1 1 , 1 , 1 1 1 1 , 1 1 , 1 , 1 , 1 1 , , 1 1 , , 1 , , , , , , , , , > > > > > > > , > , , , : > , : > : , : : : > > > : > > : : : : : : : > : : : : : : : : : : & : : & : & : : & : & : : # & : : & & # : # & - - # # - # - # @ # - @ # - # - - # - # # - # % # % % % % % % % # # # & # # # # @ % @ % # @ @ # # @ @ @ # @ @ @ @ @ @ @ @ + @ + + # @ @ + @ + @ + @ + @ + @ + + + + + + + + + + + + + + o + + X + + X + + X + + O + o o O O + O O O O O X o O . . o . X . X . o o . o O O O O ",
"2 2 2 2 2 2 0 2 2 2 2 2 1 2 2 1 2 1 2 2 2 1 2 1 1 2 1 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 1 , 1 , 1 1 , , , , 1 , , 1 1 , , , , 1 , , , , , , > > 1 > > > > , , > , : > > , , : , > , : > , > > > : : > : > : : > : : : : : : : : : : & : & : : : & & : - - & : & & : & : & & : : # : # : # @ - - - - # - - - @ - # - # - # # % # - # # # % & % % % % % % % # % # # # % # % % # # # # # # @ # @ # @ # @ @ @ @ @ @ @ @ @ @ @ # + # + + @ + + # @ + + + + + + + + + + + + + + + + + + + + + o + X + + + o o X O O O X O O O O O + X O O . X X . . O o . . . . . . o O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 2 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 , , 1 , 1 1 , , 1 , 1 , , , , , , , , , > , , , , , , , > , 1 : > > > , > , : : , : , > > : : > : : > > : > : : > : : : : : : : : : = : : : : & : & : : : & : : & : & & : & & : : # : & : : : - - @ - - - # @ - - # - - # # # - % - # # - - % % % % % % % % % % % % # # # % # # # # # @ # # @ @ @ # @ @ @ @ @ @ @ @ @ @ @ + @ + # # + @ + @ + + + + @ + # @ + + + + + + + + + o + + o X + + + + X X + o + + X + + O + O O O O O O O X . O o O O . o o . O . o o . o . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 2 1 2 1 2 1 1 1 2 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 1 1 1 1 , 1 1 1 , , , 1 , , 1 , , , , , , , , > > , > > > 1 > , , : , , , > > , : : , : > , > > > > : : > : > : : > : > : : : : : : : : : : & & : : : - & - : & : & : : : & : # : & & & & # : - - @ - # - - - # - # @ # - # - # - # # # # - % % % % % % % % % # # # % % # # # # @ % @ # @ @ @ @ @ @ @ @ @ @ @ @ @ @ + @ + @ @ @ @ + @ + @ + + @ + + + + + + + + + + + + + + + + + X + + + + + X X X X + o X + O + + O + O O O O O O O O . O O o o . O . X o o . . o . . O O O O ",
"2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 1 2 1 2 1 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 , , , , 1 , , 1 , 1 , , , , , , , , , , , > , , , , , 1 > > > , : , > > : , > , : > > > > : : : : > > > : > : > > : : : : : : : : : : : : : : : : : & : & : & : & & : & & & & # : : # : & & & # - - - - # # - - # - - - # - # - # # - - # # # % & % % % % # % % % % % % # # # # # @ % # # % @ # @ # @ @ @ @ + @ @ @ @ @ @ + @ + @ @ @ @ + @ # + + + # + @ + @ + + + + + + + + + + + + + X o + + + X + X + + o + X O O O O + O O O O O O O O O . . . . O O . . . . . O O ",
"2 2 2 2 2 2 r 2 2 2 2 2 2 2 2 2 2 1 1 2 1 2 1 1 1 1 2 1 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 , 1 , 1 1 , , 1 1 , , , 1 1 , , , 1 , , , , , , > , > , , > > , , , : , : , : : , : , : > : > , > > > : > : : : : : : : : : : : : : : - : - : - : - - - - - & : : & : & : : : : : : & : # & # : # - - - # - - # - - # - - # - # # & & # # & # & % % & # # & # # # # # - # # % # + - - + - + + - # @ @ @ # @ # @ @ + # # @ + @ + @ + + @ @ + @ + + + # + @ + + + + + + + + + + + o + + o + o + + + O O + O + O X X O X O O O + X O O O O O O X . . . . . o . . . o . o . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 1 2 2 1 1 2 1 2 1 1 1 2 1 2 1 1 1 2 1 1 1 , 2 1 1 1 1 1 1 1 1 1 , , 1 , , , , , 1 , , , , , , , , , , , , , > > 1 > : , , , , , , , : , , , > , > : > : : > > : > : : > : > : > : : : : : - - : - : - : - : - - : : & : & & & : # # : # : # : : : # - - # - - # - # @ # - # # - # # & # & & & # & # % & # & # % # % # # # # # # # # @ + + - O - + $ # # @ # @ @ @ @ # + @ + @ # @ @ + + # + @ + @ @ @ + + + @ + + + @ + + + + + + + + + + + + + + o + + + O + O + + + O + O X O X X O + O O O X O O . . . o o o . . . . . . . . O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 1 2 1 1 2 1 2 1 2 2 1 1 1 1 1 1 1 2 , 1 1 1 , , 1 1 1 1 , , 1 , 1 , , , 1 , , , , , , , , , , , > , , , > , > > , , : : , , : , : , : : > , : > : > : > > > : > > > : : > : : : : : : : : : : : - : - - : - & : & : & & : : # : : : : & : & : & & # - - # # # - - - # # - - # # - & # & # # & # & & & # # # & % % # # + - # # # # - + + + - O o + @ @ @ @ @ @ @ @ # # @ @ @ @ + @ # + @ @ @ + @ + + + @ + + @ + @ + + + + + + + + + + + + + + + o X + + X O + O O X + O + o o X X O O O O O X O O . . . o . . . . . . . o o . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 1 2 2 1 2 2 2 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , , 1 1 , 1 , , 1 1 , , 1 , , 1 , , , , , , , > , > , , , , > , , > , , : , , , : , , : , : , : > > : : : > : : > : : : : > : - : : : - : - : - : - - - - & : & : : & : : : # # : & & # : # : - - # - - - - # - - - - # - - # # & & # & # & # # % & # # % % # - # # # # # % # - @ - @ O - - + # @ # @ @ @ @ @ + @ @ # + # # @ + @ @ + + @ + @ # + + @ + + + + @ + + + + + + + + + o + + o + + + O X + O O + + O O O O X + X X O O O O + X O X O O o . . . o o o . o . o . o ",
"2 y 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 1 2 1 1 1 1 1 1 1 , 2 1 1 1 1 1 , 1 1 , 1 1 , , , 1 1 1 , 1 , , 1 1 , 1 , , , , , , , , , , > , > , , , > > > , : > , : , , : : , : , : : > : : , , : > > : : : : > : : : : : : : : : : - : - - - : - - - - - : & : & # : : : : # & : : : & # - # - - - @ @ - @ + - - # - # - & & & # # & # & # & # # % % % & - + # # - @ + - + - + @ + + - - # # # @ @ # @ @ # @ + + + @ @ @ @ @ + o @ @ @ @ + # + + + + + @ + + + + + + + + + + + + + + + o + + X O + O + O O O O O + + O + + + + O O + O O O O X X . . O . . . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 2 1 2 1 2 1 1 2 2 1 1 1 2 2 1 2 1 1 2 1 1 1 1 1 2 1 1 1 1 1 1 , 1 1 1 , , 1 , 1 1 , , 1 , , , 1 1 , , , , , , , , , , , , > , , , , , , , : , : , : , : : , : , > : : > > : : > > : : : : : : : : : : = : : - : : - - - - - - & & : : & : : # : : : & : & & : : - # - # - - - - - - - @ - # - # & # # & & # & # # # & & % # # # # + - + + + - @ @ @ + - - + + + @ # + # @ @ @ @ # + # @ # # + + + + # @ @ o + o + @ + + @ + + + + + + + + + + + + + o + o + + + O + X + O O O O + O + + + + + + + $ $ $ + $ + + + O O O O . . . . . . . o ",
"2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 1 2 2 1 2 2 2 1 2 1 1 2 1 1 1 1 1 2 1 1 1 1 , 1 1 1 1 , 1 1 1 1 , 1 1 , , 1 , 1 , , 1 , , , , , , , , , , , > , > , , > , > , , : : , , : , : , : , , : > : > : : : : > > : : : : : : : : : - : : : : : : - - : - - - - - - : & & : # : : # & # : # & & & & - - # - # - - # @ - - @ # - # - # & & # # & % & & # % % & % # % + - - + @ # + @ + - @ @ - + + - # @ # @ # @ @ @ + # + # @ + + @ @ + @ @ + @ @ + + + + + + + + + + @ + + + + + + + + o + + + o o + O O + O + O O + O + + @ + % % $ * # * * @ $ + + + O O O O o o o o . . o . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 1 2 2 1 2 2 1 2 2 1 1 2 1 1 1 1 1 1 1 1 1 2 1 , 1 1 1 1 1 , 1 , 1 , 1 1 , 1 , 1 , , , , , , , , , > , , , , , , > , > > , : , , , > > , : , : , : : , : , : , , : : : : : : : > : : : : : : : : - : - : - - : : - - - : & & : : & : & : : : : # : & : # & # - - - @ - - # - - @ - - # - - & # & & & # & # # & % # # # # & - @ + - + - - O - @ + - + - + + @ # # # + @ @ @ @ @ # # + # # @ + # @ @ + + @ @ @ + @ @ + + @ + + + + + + + + + + + + + + + + + O + + O + O + + + + + + % # * ; ; > : ; ; = * $ $ + + + O . . . . . o . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 1 1 1 2 1 1 2 2 1 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 1 1 1 , , , , 1 1 , 1 , , 1 1 , , , , , , , , , > , , , > , : , , , : , , : : , : , : , > : > : : , : > > : : : : : > : : : : : : : - : - : - - - - - - & - & : & : & & & : # : & & # : : & & & & & # & & & - 8 4 4 4 8 < 4 , , , < 4 4 4 8 4 4 4 4 4 4 4 4 4 4 4 4 8 4 4 - $ @ $ - + + - o # @ @ @ @ @ + @ + # @ + @ + # + @ @ + @ @ + @ + + + @ + + + @ + @ + + + + + + + + + + O + + + O + + X + + o + + + + + # = ; 5 7 2 e e e 1 7 < = # @ + + + O X . . . . . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 1 2 2 , 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 , 1 1 1 1 1 , 1 1 1 , , , , , , , , , , , , , , , , , , , > , > > , , : : , , : , , : , : , : > , : , > : : > : > : : : : : : : : : : - : : : : - : - - : - - : - : & : & & : & & & : & : & & & & & & & & & & & & 4 v v v v v v v v c v v v v v v v v v v v v v v v v v v v v v v k ; - + + - - $ # # @ # # @ # # @ @ @ @ @ @ + @ + @ @ + + @ @ + @ + @ + + @ + + + + + + O + + + + + + + O O + + O + X + o + O + + @ * * > 7 e s n M M m n f e 7 > * # + + O . . . . . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 1 2 2 2 1 2 2 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 > 1 , 1 1 , , , , , , , , , , , , , , , , , , , > , , , > , , , , , , : : , , : > , : > , : : , : > , : > : , : : : : : : : - : : : : : - : - : - - : - : & : : & : : & : & & & & : : & & & & & & & & & & # 4 v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v k $ @ O - $ @ # @ @ @ @ @ @ @ # @ # @ # # @ + @ @ + @ + @ + @ + + + + + + + + + + + + + + + + + + + + + O + + X + o + o + + $ # * > w f M S U T R T K S m f 9 : * % + + O X . . . X . . X . X ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 , 2 2 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 , 1 1 1 1 , 1 , 1 , 1 1 , 1 , , 1 , , , , , , > > , , , : , , , : : , , , , : > > , : , : : , > : > : : : : : : : , : : : : : > - : - - - : - : - : - - : & : & & : & & & : & : & & & & & & & & & & & & & & & 8 v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v x ; - + O # @ @ # @ @ @ # @ + @ + + + # + @ + @ @ + @ + @ + + @ + + @ + + + + + + + + O + + X + O + + + + + + + X + + + @ $ ; > 0 f C K ! ..;.;.;. .~ Y B f 7 : * $ + O . . . . . X X X X X X X X X . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 2 1 2 2 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 , 1 1 , 1 1 > 1 1 , , 1 > 1 > 1 , , , , , , , , , , , , , > > , , , : , , , : , > , > : , > > : > : : > : : > > : : : : , : : : - - : : : - : - - : - : & : & - : & : & & & : & & & & : & & & : & & & & & & # & < v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v l - # @ @ @ @ @ # @ @ @ @ @ + @ # + @ + @ @ + @ + @ + @ @ + + + + @ + @ + + + + + + + + + + O + + + O O X + + o X + + $ # ; 7 y A R { <.2.7.9.7.2.>.{ R A r 7 = $ $ + X O . O X + X X $ + + + X X X X ",
"2 2 2 y 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 2 1 2 2 1 1 1 1 1 1 , 1 1 1 1 1 1 , 1 1 1 1 > 1 1 , , , , 1 , 1 > , , , , , , , > > , , : , , , > : , : , : , , > , : , , : > : > : > , : : > : : : > : > : : : : > : : : - : - > - - : - : & : - : : & & : & : & & : : # & : # & & & & & & & & & < v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v k # $ # @ # @ @ @ @ @ @ @ @ @ @ @ @ # + @ @ + @ + @ + @ + @ + + + + @ + + + @ + + + + + + + + O + + + O + + O + + + % = , e M K ..1.9.w.j.j.j.w.7.1.{ Y M w 5 * $ + + O O . + + + $ $ $ $ $ * $ $ $ + ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 1 2 2 2 1 1 1 2 1 1 2 1 1 1 1 1 1 1 , 1 1 , 1 , 1 1 1 , 1 > 1 1 , , 1 , , , 1 , , 1 , , , , , , , , , , > , , , , > : , , , , : > : > > : , , : : , , , : : , : : > , : : : : : : : - : : - : : : - : : - - : - - - & : & : : - & & & & & : : & & & # & & & & & & # 8 v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v 8 $ # @ @ @ # # # @ @ @ @ @ @ + @ + + # @ @ + @ @ + + + + + @ + @ + + + + + + + + + + + + + + + O + + + O + + + + # ; 7 f S ~ <.9.g.l.x.x.x.l.h.9.>.! G r 6 & $ + + O O + + + % * * = = 3 * * = $ $ ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 2 2 1 2 1 2 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 1 , , 1 , 1 , 1 > , 1 > , , , , , , , , , , , , > > > , , , : , > > , , > > > : : , : > : : : , : : > : > : : : > : : : : : : : : : - - - - : - & : : & : & : & & & : & & : & & : # : # : & & & & & & & 0 v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v c # # @ # # @ + @ @ @ @ @ @ @ @ @ @ @ @ + + @ + + @ + @ @ + + + + + + @ + + + + + + + + O + O + + O + o + o + + @ % : 7 n U ..2.w.l.m.M.N.M.m.l.w.2.{ Y b 9 = $ + + + + + $ % = > 6 7 9 9 9 7 5 5 = ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 1 2 1 2 1 1 2 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , , 1 , 1 , , 1 , , 1 , , , , , 1 , , , , , > , > > , , , , , > , > , : , , : , : , : , : : > > : , : : > : : : : : : : : : : : - : - - - : : : & : & & & & : & & : - & : & # : : # : & : & & & & & & & & , D c v c v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v 8 # @ @ # # @ # @ @ @ @ + @ @ @ + @ + @ @ + @ @ + @ + @ + @ + + + + + + + + + + + + + + + + + + + + O + + + + + * > e m T :.8.h.z.M.C.C.C.M.z.j.7.;.T M w ; $ $ X + $ $ * ; 7 w r b m M m b s 9 5 = % $ X $ . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 2 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 , 1 1 1 1 1 1 1 1 1 1 , 1 , , 1 , 1 , , 1 , , , , , , , , , , , , , , , > > > , , > > > , : : , : , : , : : , : > , : : : : > : > : > : : : : : - : - : > - & & : : : : : : & : & : : # - & & - & & : : # : & & & & & & & # : h l l l l l l l l l l l l l l l l l l l l l l v v v v v v v v v v v v v v v c @ # @ @ @ @ # + @ @ @ @ @ @ @ @ @ @ @ + @ + + @ + @ + + + + @ + + + + + + # + @ @ + $ + + + + O + X + X + + $ & ; e C R :.9.h.m.V.Z.Z.Z.V.x.j.7.:.T M e 5 $ $ + + $ * : 7 r b S K T T T K A m s 7 3 * $ . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 1 1 2 1 2 1 2 1 2 2 2 2 1 1 1 1 2 1 1 1 1 1 1 1 1 , , 1 , 1 , , , , 1 , , , , 1 , 1 , , , , 1 , , , , , , , > , > > , > , , > , , > , > , , : , : , : > , : > : : > : > : > : > : : : : > : : > - : - > - : : & : & : : & : & : & - - : & : & & & & # & : & & & & & & & & & & - & & # & # - # - - # & - % # - # # # & % % # g v v v v v v v v v v v v v v - - # @ @ @ @ @ @ @ @ @ @ @ + @ @ + + @ + @ + + @ X + @ + + + + @ + + + @ % # # # @ % $ % + + + + X + X + + + & > e M R ;.7.h.m.M.C.C.C.M.x.h.7.;.T M w ; * $ + $ * ; 7 s A T R ..-.-.-.{ ! K B s 7 3 $ + . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 , 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 , 1 , , , , , , , , , , , , , , > > , > , > , > > , > > , > , : > , : , : , > : , : > : > > : : : : : : : : : : : - - : - : - - & : : : & : : & & - - - - & & - & & & : : : # # & & & & & # & & & & & & & & # & # - # # - # # # # # # & % % # # # @ g v v v v v v v v v v v v v i o @ @ # @ # @ @ + @ @ @ @ + @ + @ @ + @ + @ + @ @ + @ + @ + @ + @ @ # % # % % = # * * * @ # % $ + + + + + @ * ; w b K { 2.q.l.m.M.V.M.m.l.w.2.{ K b 7 ; $ $ $ $ = 6 r C R { >.2.2.8.7.2.>.{ Y C s 4 * * + . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 1 2 2 1 1 1 2 1 1 2 1 2 1 1 2 1 1 1 1 1 1 1 1 1 , 1 , 1 , 1 1 1 , 1 , , , 1 , , , , , , , , , , , , , , , , , > , , > , , , : , : > , : : , : : > : : , : : > : : : > > : : > : : : : : - : : : > - - > : : & : : : & : : - : & : # - & & : # : & : : & & & & & & & & & # & # & & # & # - # # - # # % % & # # # & # & # # # - v v v v v v v v v v v v v c @ @ @ + # # @ # + + # @ @ @ @ @ + @ @ @ + @ + + X @ + + @ X + + @ $ % & = = : < < > : ; = # @ $ + + + + + $ # = 7 b S ~ <.9.h.l.z.x.x.l.h.9.>.~ G s 7 * % $ $ % 3 e m K { 1.8.f.h.j.h.f.8.1.{ U b r ; * . . . ",
"2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 , 1 , , , 1 1 1 , , , , , , , , , , , > , , , : , , > : > , > , > , > , : , > > > , : : , > > > > : : : > : : > : : : : : - : - - - - - : & : & : : & : & & : : : & & & & : & # & : # & & & & & & # & & & & & & & & # # - - # # - # - & % & % & # % # # # # p v v v v v v v v v v v v v - @ @ @ # + # + # # # @ + @ + @ + + @ @ @ + + + @ + @ + + @ @ @ # * = : 5 7 e e e e e 7 5 > = $ $ $ + + + + $ & , e b Y { 1.9.w.g.j.j.w.9.1.{ K M e : % % $ % = 7 s G R <.8.h.l.z.m.z.l.h.8.>.R A s 5 * + . . ",
"2 2 2 2 2 2 2 2 1 2 2 2 2 2 1 2 2 1 2 1 1 2 1 2 2 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , , 1 , 1 1 , , 1 , 1 1 , , , , 1 1 , , , , , , , > , , > , > > , > , , , , > > > > > , , > , > : > > > : : > > : : : > : : : > : : : : : - > - > - - : - : - & : : & & : & : & # : : : & : & : # : & & & & & & & & & # & & & & & & & # - # # # # - % # & # % # # & % - # # ; v v v v v v v v v v v v v < @ @ @ @ @ # # # # + + @ @ + @ @ + @ + @ + @ + + + @ + @ + $ % % : 5 7 r b b M M M m f r 7 < = # $ + + + + $ % = 7 y A T { >.2.7.7.7.2.>.{ T A r 7 = * + % % = 7 b K .2.f.l.m.M.M.M.m.l.g.2...K b 7 . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 1 2 2 1 2 1 2 2 1 2 2 2 1 2 1 1 1 1 1 1 1 1 1 , 1 1 1 1 1 1 1 1 , 1 1 , 1 , 1 , 1 , , , , , , , , , , , , , , , , , , , , > , > , > > , > > : : , : > , : , : , : : > > : : > : > : : : : : : : : - - - : - - & : : : : & : : & : # - : - & & & # : : & # : & & & & & & & & & & & # # & # & - # # - - # # # % # & # # % # # # # # # l v v v v v v v v v v v v q - @ @ @ @ @ @ @ + @ # @ @ @ + @ @ @ + + @ + @ @ + + @ + $ % & : 5 w f M K K R Q R K S M b 9 5 = & $ + + + $ $ = > 7 b A Y ~ -.;.:.-.-.~ Y C f 9 > * $ + $ % : w b Y ;.8.h.z.M.C.C.C.M.z.j.2.-.T b 9 ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 2 1 2 2 1 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 , 1 , 2 , 2 , , 1 , 1 , , , 1 , 1 , , , , , , , , , , , , , , > > > , , > > > > > > : , > : , : > > > > : > > : > > : : : > > : : : : : : : : : : : & : : & : : - & - - & & & : & E u.u.u.u.u.u.u.u.u.u.u.u.u.u.u.u.u.u.v.u.} 6 % & & # & & # # # & % % % % % # # % # % # * i v v v v v v v v v v v v a - o - O + + + - + + + + + @ @ + @ @ + @ # + + + @ + $ @ @ # = < e f G Y ^ ..:.>.;...^ K S b 9 < = @ + + + + $ % = : 9 s M S K T R T K A m s 7 : * $ $ + $ $ ; e C T :.8.h.m.N.C.Z.C.N.x.h.8.:.T N w ; $ + O . . ",
"2 2 2 2 2 y 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 , 2 , , 1 , 1 , , 1 , , , , , , , 1 , , , , , > , > , > , > , > > , > , > , > , : > : : , , : > : > : > : : : : : : : : : : : : : : : : & : : : : & : : & : & = - - : & & : o.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.B.E % & & # # & & & # & % % % % % % % % # # # q v v v v v v v v v v v v k o - @ @ - + + O - + - O - + @ + @ + + + + + @ + + @ @ @ $ ; ; 0 f A R .<.2.7.9.7.2.<...R C f 7 : # $ $ + + + $ % * 3 7 e s m M M m m f w 7 > * % $ + + + * ; w b T ;.8.g.z.M.C.Z.C.M.z.h.7...T b 9 * $ + O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 2 2 2 1 2 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 2 1 1 , 1 , 1 , 1 , 1 , , , , , , , , , , , , , > , > , > , > > > > > > > > : > : > , : : , > > > > > > : > : : : > : : : : : : : : : - & : & : & : : & : : : & : & : & & +.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.E # & # & & # & # % % % % % % % % % % $ # 3 v v v v v v v v v v v v k - o O @ + O - - O @ + + + + + # @ @ # + # @ + + + @ + # % ; < r M Y .1.9.w.j.j.j.q.9.1...K M e 7 = $ + + + + + $ % = : < 5 w w e w 7 5 5 ; * % + + + + + $ ; 7 b K { 2.f.l.m.M.N.N.m.l.f.2.{ K b 9 * $ + . ",
"2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 1 1 1 2 1 1 2 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 , 1 1 , 1 , , , 1 , 1 1 , , , , , 1 , , , , , , , , , > , , , , , , > > 1 > > > , > , , > , > : : , : : > : : : : > : : > : : : : : : : : : : : : : - : : : & & : : & & : & : & : & o.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.m & & & # & # & & % % % % % % % % # # # 4 v v v v v v v v v v v v k o - - @ @ - O + + @ - o - + + # + + + @ + + @ # + + @ @ ; ; 0 f S ^ <.9.j.l.x.x.x.l.j.9.<.^ S s 7 = $ $ + + + + + $ @ # = = ; > ; ; ; = * % + + + + O + + $ * 7 r A { >.8.g.l.z.x.z.l.g.8.>.R S s 6 * $ O . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 1 2 2 1 2 1 2 , 2 2 2 1 1 2 1 1 1 1 1 1 1 1 1 , 1 , , 1 , 1 1 1 , , , 1 , 1 1 , , 1 , , , , , , , , > , , , , > , > 1 > , > > > > > , : , : , , : , > : > > > : > : > : : > : : : : : : : : : : - : : : & : : & & : : & : & : & & o.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.k.# & & % % % # % % % % % % % % % # # # 4 v v v v v v v v v v v v k + O $ - + + + + # + + - + + @ @ + + + + + + + @ + + @ # ; ; w n Y ..2.g.l.m.M.N.M.m.l.f.2. .K m w ; * + + + + O + + O $ $ % % $ * % * $ $ $ + + O O O O + $ % 5 r b K { 1.8.f.g.h.h.f.8.1.{ Y b w : $ $ X . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 1 2 1 1 2 1 1 2 2 2 , 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 , 1 , 1 1 1 1 1 , , 1 , , , , , , , , , , , , , > , , , > > , > , > > > , , > > > : , : , : : , : > > : > : > : > > : > : : : : : : : - : - : : - : & : : & : : & & : & : & = : o.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.C.L & # & % & & % % % % % % % % % % # % 4 v v v v v v v v v v v v k - O - + - + + - + # + + @ + + @ @ @ @ @ @ @ # + @ @ # # - > e M Q :.7.j.x.N.C.Z.C.M.x.h.8.:.Y B e > * % + + + X + + + + + + $ $ + $ + + + + + O X O O + + % = 5 s C U { >.2.8.8.8.2.>.{ T C s 5 * $ + . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 1 2 2 2 1 2 2 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 , 1 , , 1 , 1 , , 1 , , , , , , , , , , , , , , , > , , > > > > , > > > > > > , : , : , : : , > : > > : > : : : : : : : : : : : : : : : : : & : : : & : : : : & : & : : & & t D V V V N D V N V V V x V V V o.Z.Z.Z.Z.Z.Z.Z.Z.Z.0.# & & % % % % % % % % % % & % # % # 4 v v v v v v v v v v v v k - - o + + + @ @ + # # + + # + @ @ @ @ + @ + + @ + + # # - < r B Q :.9.j.x.N.C.Z.Z.B.m.j.9.>.Q B e > # @ + + X O + X X + + + + + + + O + O O O X X X O X O + $ % ; 7 f C K ! { ;.:.-.{ R Y C s 7 = $ + + . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 1 2 1 1 2 1 , 2 1 1 1 1 1 1 1 2 , 1 1 1 1 1 , 1 1 1 1 1 , 1 , 1 , , 1 , , , 1 1 , , , , , , > , , > , , , , , > , , > > , , > , > : , : , : , : : > > : : > : > : : > > : > : : : : : : : - : : : & : : : : & & : : & : & & : & & & - & & & - - - & & - & & & % # } Z.Z.Z.Z.Z.Z.Z.Z.Z.< # % & % & % % % % % % % # % % % % 8 v v v v v v v v v v v v k o O + - - o @ @ @ # + o - + @ @ + + + @ + @ + + @ @ # # - < e M Q ;.7.h.x.N.C.C.C.N.x.h.9.:.R M e > * + + + + O O O O X O + O O + O O O X O X O O O O O O + $ % 5 7 f b S K T T Y K S b s 7 > = $ + X . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 1 1 2 , 2 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 , 1 1 , 1 , 1 , 1 , 1 , 1 , 1 , , , 1 , , , , , , , , > , , > , > , , > > , > > > > > > , , > > > > > > > > : > : > : > > - > : : : : : - : : : - - - : : - - - : & : : & : & : & : & : & - & & & & & & & & & # & & & & = v.Z.Z.Z.Z.Z.Z.Z.Z.P # % % & # # # # # & # # # # % # # i v v v v v v v v v v v v k @ @ - + @ @ @ @ @ @ + @ @ + @ @ + @ @ + @ + + + + $ + % = < w n Y ..2.f.l.m.N.B.N.x.l.f.2...U b 9 : # @ + + O O O O O O O O O O O O O O o . O O X O O O O O X + $ * ; 6 e r b m M b b r e 7 3 * $ + + ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 2 2 1 , , 1 2 2 2 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 1 1 1 1 1 , 1 , 1 , 1 1 , 1 , , , 1 , , , , , , , , , , , , > , > , > , > , > , > , : : > : > , : : : > > > : > : : > : : > : : : : : : : > - > : & - : - : & & & & : : & & & & & & - & - & & & & & & & & & & & & # } Z.Z.Z.Z.Z.Z.Z.Z.o.& & # & # & & & # # & & # % # # # l v v v v v v v v v v v v u # @ + o - @ @ @ @ @ @ @ o - + @ @ + @ + + + @ @ + @ + % % ; 9 b H ^ <.9.h.l.x.x.x.l.g.8.<.! S b 7 = % @ + X O + + O + O O O + O O O X X o o O O X O O X + + $ * ; : 6 9 w e e 7 6 : * $ $ + X . ",
"2 y 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 2 1 2 : , & 1 : 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 , 1 1 , , , , 1 , , , , 1 , , , , , , , , > , , > , , , , > > > > , > > > > , > > > , : : > > > > > > : > : > : > : : : : : : : : - : - - - : : - : : : : : & & & : & : & : - & & - - & & - & & & & & & & % & j Z.Z.Z.Z.Z.Z.Z.Z.u.% & % % & # # & # # # # # % % # - v v v v v v v v v v v v v q - o + @ @ @ @ @ @ @ @ + + @ + @ @ + + @ + @ + @ + + % # % ; 1 r M Y .1.9.f.j.j.j.q.9.2...K M r < = # @ + + O O O O O X + O O O O O O O X X O O o O . . X X + $ $ $ ; ; ; = = * * * $ + + X . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 L J J L J W W W W W W B Q L L L C 7 2 1 1 1 1 1 1 , 1 1 1 1 1 1 , , , C J F J J F F L F F J J F J , , , , , > , , , > 9 F F F F F F F F F C F F F 2 , : > > > : : F D F D D D F 7 : : : - - : : : Z F Z Z Z Z Z - & : & & : : : & : & - & & & - & & - & & & & & & & & & & # & Z.Z.Z.Z.Z.Z.Z.Z.u.# # & % # # & # & # & # & % # % u v v v v v v v v v v v v v ; @ @ o - @ @ @ @ @ + @ @ @ @ @ @ + @ @ + @ + + + + + + $ % = > 1 b A R ..<.2.9.9.9.2.<. .R A f 1 ; * % + O + + O + O O + O O O O O O O X o o O O O O X . . X . X + + + + $ $ $ $ * $ $ + + + X . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 Z.Z.Z.Z.Z.Z.Z.Z.Z.m.C.C.Z.Z.Z.Z.Z.b.J 1 1 1 1 1 1 1 1 , , 1 , 1 1 I b.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.> , , , , > , > w &.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.F : , : > : > > 6.Z.Z.Z.Z.Z.Z.` : : : > : : : I Z.Z.Z.Z.Z.Z.u.& : & & : : & : & & & & & - & & & & & & & & & & & & & & % & & B.Z.Z.Z.Z.Z.Z.Z.B.# & & # % & # & # # % % # # # - c v v v v v v v v v v v v v + + - # @ @ @ @ @ @ @ @ @ @ @ @ @ + @ @ + @ + @ + + @ + @ % # ; < w b A K ^ ..;.>.;...^ Y A f e < = @ + + + + O + O + O O O O O + O O O . O O O . o . . . . . . + + + + + + $ + + + O . . + . . O . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 Z.Z.Z.Z.Z.Z.Z.Z.Z.N.V.Z.Z.Z.Z.Z.Z.Z.Z.I 1 1 1 1 1 1 1 1 1 1 1 , [ Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z., , , > , , , , k.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.F > : > > > : > D Z.Z.Z.Z.Z.Z.r.: > : : : : > 6.Z.Z.Z.Z.Z.Z.I : : - : : & - & : & : & : & - - & & & - & & & & & & & & & % & u.Z.Z.Z.Z.Z.Z.Z.Z.& % % # & # & # % & % # # # @ a v v v v v v v v v v v v v k - - O @ @ - o @ @ @ @ + @ @ + + @ @ + + @ + @ + @ + + @ + @ % # ; 5 w b B S Y Y Q R Y S M s w < * % @ @ O O O + O O O + X + O O O O O O O o . O X O O o o . o . . . . . . O O O . + O O O O + + + + + + + + ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.B.e 1 1 1 1 , 1 , 1 1 1 H Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z., , , , , , , &.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.C.Z.F > , : > : : > > v.Z.Z.Z.Z.Z.Z.7 : : : : : 7 Z.Z.Z.Z.Z.Z.v.: : & & : & : - - & & : - & & & & & - & & & & & & & & & & & & & B.Z.Z.Z.Z.Z.Z.Z.B.# & % & # # # % # # # # # % i v v v v v v v v v v v v v v 4 - O + @ @ @ @ @ @ @ @ @ @ @ + + @ + @ @ + @ + @ + @ + + @ + # % = - > 7 r f m B B M n b e 7 > = % @ + + + O O O + O O O X O O O O O O O O O o . o o . . . . X . . . . . . X . . X . O + O X $ $ $ $ $ $ + ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.3.1 1 1 1 1 1 1 1 , , p.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z., , , , , > y Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.C.C.F > : , : , : > : | Z.Z.Z.Z.Z.Z.` : : : : : ` Z.Z.Z.Z.Z.Z.o.: & : : & : : & - & : & : & - & - - & & & & & & & & # & & & # & Z.Z.Z.Z.Z.Z.Z.Z.s.i i i p p p i p i p p a k v v v v v v v v v v v v v v v c $ + + - # @ @ + @ @ @ @ + @ @ @ @ @ @ @ + @ + @ + @ + + @ + @ + % # = = > < 7 e e e e e 7 , > ; # $ @ + + O + + O X X + O + O O O O O O O O O O o X O . . O . . . o X . . O + + $ $ % * * 3 * 3 * * $ $ ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 Z.Z.Z.Z.Z.Z.k.L L L L L L +.Z.Z.Z.Z.Z.Z.B.1 1 1 1 , 2 , 1 1 C Z.Z.Z.Z.Z.Z.Z.+.J J J J P F F J J F , , , > , , &.Z.Z.Z.Z.Z.Z.k.W F F F F F F F F F 2 > > > : > : : : 0 B.Z.Z.Z.Z.Z.r.: : : : : k.Z.Z.Z.Z.Z.Z.7 : - : - - - : & : & - - - & - - - & = & & : & & & & # - # - & V Z.Z.Z.Z.Z.Z.Z.Z.d.v v v v v v v v v v v v v v v v v v v v v v v v v v v v a - + @ @ - @ @ @ + @ @ o + # # @ @ @ @ + @ + @ + + @ + + @ + + @ $ $ % & = * : : < < > : ; * # % $ $ + + + O O O + X X O O X O X O + X O O X O O O O O . . o . X O o X X X X X $ % & 3 5 9 9 9 e 7 5 ; = % $ X X ",
"2 2 2 2 2 2 2 2 2 2 2 1 1 2 2 2 2 1 1 Z.Z.Z.Z.Z.Z.p.2 1 1 1 1 1 2 +.Z.Z.Z.Z.Z.Z.W 1 1 1 1 1 1 1 1 &.Z.Z.Z.Z.Z.Z.+., , , , , , 1 , , , , , , , , , , b.Z.Z.Z.Z.Z.B.9 > > , > > > > > > > > > > : > > > > : > 5.Z.Z.Z.Z.Z.Z.7 : : : d Z.Z.Z.Z.Z.Z.4.- : - - - - - & : & : & - & & & & & & & & & & - & & & & & - # 8 0.Z.Z.Z.Z.Z.Z.Z.Z.e.v v v v v v v v v v v v v v v v v v v v v v v v v v v v ; $ + O - O @ @ @ + - + - # + + @ @ + + + @ + @ @ + @ @ + @ @ @ + $ $ $ % % % = & & * * * # % % $ + + + O + O + X O + + O O + X X O O X X O X O O O O . O . o o O o X + + $ * = 5 9 s b b b b b s 9 7 = * $ O X X ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 2 Z.Z.Z.Z.Z.Z.p.2 2 1 2 1 1 2 e Z.Z.Z.Z.Z.Z.+.1 1 1 , 1 1 1 , p.Z.Z.Z.Z.Z.Z.w , 1 , , 1 , , , , , , , , , , , d Z.Z.Z.Z.Z.Z.&.> > > , > > > > > > > > > > > > : > > > : N Z.Z.Z.Z.Z.Z.` > - : %.Z.Z.Z.Z.Z.Z.C = - - - - - - & : & : - & - - & & : & : & & & & & & = & - & q / B.Z.Z.Z.Z.Z.Z.Z.Z.#.v v v v v v v v v v v v v v v v v v v v v v v v v v v u # - - O + - + @ @ @ + @ @ @ @ + # @ @ @ @ @ + o + @ + @ $ @ # # % # # $ # % # # * $ % # % $ $ $ + + + + X + X + O O O O O + X X + O O O O O O X O o X X o . . X X o O X O + $ * = 7 r b C S T T T K A b s 7 : * + X X ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 Z.Z.Z.Z.Z.Z.p.1 1 1 1 1 2 1 2 0.Z.Z.Z.Z.Z.p., 1 1 1 1 , , 1 Z.Z.Z.Z.Z.Z.0., 1 1 , , , , 1 , , , , , > , , , F Z.Z.Z.Z.Z.Z.F , > > > > , > > > > > > > : > > > - > > : : k.Z.Z.Z.Z.Z.u.- - - v.Z.Z.Z.Z.Z.k.- - - : - - - - : & : & - & & & & - & & & & & & & & & % & # 8 v t.Z.Z.Z.Z.Z.Z.Z.Z.Z.) v v v v v v v v v v v v v v v v v v v v v v v v v v l * @ + + - O + O - @ @ @ @ @ + # # + @ o @ @ + @ + @ @ + $ # # % = = = ; * = & & & # $ @ + $ + + + + X + O + + O O O + O + O o X o o O O O O X X O O O O . o . . O O X X + + * = 7 s C Y { { -.-.-.{ ! K C s 7 * % $ O ",
"2 2 2 2 9 2 2 2 2 2 2 1 2 2 1 2 2 2 2 Z.Z.Z.Z.Z.Z.p.1 2 2 1 1 2 1 2 +.Z.Z.Z.Z.Z.b.1 1 1 1 1 1 1 1 Z.Z.Z.Z.Z.Z.+.1 , , 1 1 , , , , , , , , , , > , +.Z.Z.Z.Z.Z.Z.9 , > , > > , > > > > : > > > > > : > : - > > W Z.Z.Z.Z.Z.Z.t > I Z.Z.Z.Z.Z.Z._ - : - - - - - - & : & : & & - - - 5 V V V V V V V V V V V V =.d.Z.Z.Z.Z.Z.Z.Z.Z.Z.d.v v v v v v v v v v v v v v v v v v v v v v v v v v c ; # # + - - @ + + - + + + + + + + + + # + # + @ + @ @ @ # # # ; - > , < , 5 > : = = # % $ @ + + + + O O + X O O + + + + O O O O o O o O O O X O O X O O O O X o o . O . o O O + $ * 7 s C T { >.2.2.8.8.2.>.{ Y M s 7 * $ + ",
"2 2 2 2 2 2 2 2 2 2 9 2 2 1 2 2 2 1 1 Z.Z.Z.Z.Z.Z.p.2 7 1 2 1 1 1 1 L Z.Z.Z.Z.Z.Z.1 , 1 1 1 1 , 1 Z.Z.Z.Z.Z.Z.+., 1 , , , , , , 1 , , , > , , , , +.Z.Z.Z.Z.Z.Z., > > , > > > > > > > > > > : > > > > : > > > : B.Z.Z.Z.Z.Z.} - 6.Z.Z.Z.Z.Z.B.7 - - : - - - - - : & : & & : - e 4.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.#.v v v v v v v v v v v v v v v v v v v v v v v v v v ; $ # % + + O O - O - + - + - o + - + + + @ + + + @ # @ $ # = = > 7 1 9 e e e w 7 < : = # % @ + + + + O + + + + O O O O O + O + + O O O O O + X O o X X . X o o o . . O o o o O O O $ * : e m K { 1.8.f.h.j.h.f.8.1.{ K m 9 ; $ + ",
"2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 Z.Z.Z.Z.Z.Z.p.1 2 1 1 1 2 1 1 L Z.Z.Z.Z.Z.Z.1 1 1 1 1 , 1 1 Z.Z.Z.Z.Z.Z.+., 1 1 , 1 , , 1 , , , , , , , , , +.Z.Z.Z.Z.Z.Z., , > > , , > > > > > > > > > > > : - > > - - > %.Z.Z.Z.Z.Z.k.1 Z.Z.Z.Z.Z.Z.5.- : - - - - - - - & : & : : - j B.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.c.v v v v v v v v v v v v v v v v v v v v v v v v v k * % % $ # - + + - O - O + # @ - + - o - + @ @ + # # + + - # = : , 7 t b n M A M M b r 7 5 = % $ @ + + + + X + O O + O + O O + O O O O O O O O O O o O O O . o . . . . o . . X X X + $ * 5 r C ! >.8.h.l.z.z.z.l.g.9.>.~ C r 5 * + ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 Z.Z.Z.Z.Z.Z.p.2 1 2 2 1 1 1 1 L Z.Z.Z.Z.Z.Z.1 1 1 1 , 1 1 , Z.Z.Z.Z.Z.Z.+., , , , , , , , , , , , , , , , , +.Z.Z.Z.Z.Z.Z.F > > , > > > > > > > > > > > > > > > > > > > : t Z.Z.Z.Z.Z.Z.+.Z.Z.Z.Z.Z.Z.r : - : - - - - - - : & - & & e B.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.' v v v v v v v v v v v v v v v v v v v v v v v k 8 $ % $ $ @ + @ @ + - + + + - @ + o o - + + + # + # + + + @ @ & ; 7 e b M H Y R R R K S M b w , = * $ + + + O + X O + + O O + O O + O O + O O O O O O . o o O o o . o o . o . . o O + + = 7 f K .2.f.l.m.M.V.M.m.l.q.2.{ K f 7 = $ ",
"2 e 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 2 1 Z.Z.Z.Z.Z.Z.p.2 1 2 1 2 1 1 1 W Z.Z.Z.Z.Z.Z.1 1 1 , 1 1 1 1 Z.Z.Z.Z.Z.Z.+., , , , 1 , , , , 1 , , , , , , , I Z.Z.Z.Z.Z.Z.%., > , > > > > > > > : > : > > > : > : : > > > : u.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.u.- : - - : - - - - - - = - - = u.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.#.v v c a p p q t p i p p u i i i u u u p u 6 4 & # # # # # # # # @ O @ @ - + + + - - O + + + + + + # + + @ @ @ - ; < 0 n A Y ^ -.:.>.:...^ T C f e < = @ + + + + + O + X + O + O O + + X O O O O O O O O O O O O . . o . . . o o . . . . . O + $ ; 9 m T ;.7.h.z.N.C.Z.C.M.z.h.7...T m 9 = $ ",
"2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 1 2 2 Z.Z.Z.Z.Z.Z.p.1 2 1 1 1 1 1 1 +.Z.Z.Z.Z.Z.b.1 1 1 1 1 , 1 1 Z.Z.Z.Z.Z.Z.+.1 1 1 , , , , , , , , , , , , , , N Z.Z.Z.Z.Z.Z.B.w > , , , > > > > , : > > > > > > : , > : - > > I Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z._ : - - & - - - - - - - - & - V Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.n.' v v c - & % & # & % # % % # % % # % % # # $ % @ % # # # # # @ # @ @ - - @ + O - O o + + @ + - - + # + # @ $ # # ; ; 0 f A Q ..<.2.7.9.9.2.<. .Q A f 1 : * % @ + + X + X + O + O O O O O X O O O + O O O O O O o . o . . o . . . . . o . O O % ; e m T -.8.h.z.N.Z.Z.C.N.x.h.8.:.T m 9 ; $ ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 Z.Z.Z.Z.Z.Z.p.1 1 1 2 2 1 1 1 p.Z.Z.Z.Z.Z.p.1 1 , 1 1 1 , 1 Z.Z.Z.Z.Z.Z.+., , 1 , 1 , , 1 , 1 , , , > , , > , B.Z.Z.Z.Z.Z.Z.k.I F D F F F F N > : > : > : > : , : : > > : : : v.Z.Z.Z.Z.Z.Z.Z.Z.Z.v.: - : : : : : : - - - - & - - 0.Z.Z.Z.Z.Z.Z.Z.Z.Z.v.u.u.u.u.s.d.d.d.d.d.d.t.=.O.v v v v ; % # % # % % % % % & % % % % # & # # % @ % % # # # # @ # @ # @ @ O @ + - O - + @ - + + + + @ @ @ + @ $ # - ; 1 t B Y .1.9.w.j.j.j.f.9.1. .T M r < = % + + + + O + O + O O + + O + X + X X X O O O O O O O X . . . . . o . . . X o . . . O $ $ = 9 m T ;.7.h.l.M.C.C.C.M.x.h.7.;.K m 7 = $ ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 Z.Z.Z.Z.Z.Z.p.2 1 1 1 1 2 1 n Z.Z.Z.Z.Z.Z.&.1 1 1 1 1 1 , , Z.Z.Z.Z.Z.Z.+.1 , , , , , , , , , , , , , , , , , 6.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.C.Z.v.W > > > > : , : : > : : > > : O.Z.Z.Z.Z.Z.Z.Z.Z.Z.O.- : - : & : & - - - - - - - 5 Z.Z.Z.Z.Z.Z.Z.Z.Z.4.= & & & ; c v v v v v v v v v v v v k - & & # & % & % % % % % % # % # # & % % % % @ # # # # @ # # @ - O - @ + - + + @ @ @ + + - + + + @ @ @ @ # - ; 1 n H ^ 1.9.j.l.x.x.x.l.j.9.,.^ S b 7 ; % $ + + O + + O O + + O O + X O o X X + O O O O O O X X . . . . . . o . O O O + $ = 7 b K .2.f.l.m.M.N.M.m.l.f.2. .K h 7 = $ ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 Z.Z.Z.Z.Z.Z.p.2 1 1 2 2 2 1 0.Z.Z.Z.Z.Z.Z.W 1 1 1 , 1 1 1 1 Z.Z.Z.Z.Z.Z.+., , 1 1 1 , , 1 , , , , , , , , , > d Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.! ; > > : : : > , : : : : : d Z.Z.Z.Z.Z.Z.Z.Z.Z.d : - : : & : : & : : : - - - I Z.Z.Z.Z.Z.Z.Z.Z.B.< & & & & - v v v v v v v v v v v v v q % % % % & % % % % & % % % % # & # # # # # # # # # # # # @ # # + + - O @ @ - + @ @ @ + - O + + @ @ @ @ @ # - ; e m Y -.2.q.l.x.M.N.M.m.l.q.2...Y m w : % % + O + + X + O O + + O O O O O + o o X X O O O O . O . . o o . . o o . . o . . O + $ * 6 s S R >.8.h.l.z.x.z.l.g.8.>.! S r 5 * $ . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 Z.Z.Z.Z.Z.Z.p.[ +.+.+.+.+.p.Z.Z.Z.Z.Z.Z.B.1 1 1 1 1 1 , 1 , Z.Z.Z.Z.Z.Z.+., 1 1 , , , , , , , , , , , , , , > , 6.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.B.t > > , > , : : > : , > : : 6.Z.Z.Z.Z.Z.Z.Z.6.: - : - : : : & : : & & - & & o.Z.Z.Z.Z.Z.Z.Z.Z.4.& & & & & 4 v v v v v v v v v v v v v ; % % & % & % % & % # % % % % % # # # # # & # # # # # # # # @ @ @ @ @ @ - @ + O @ @ @ @ @ + - + @ + + @ # # - < e B Q ;.7.h.x.N.C.Z.C.M.x.j.7.;.R M e < ; # + + + X + O + X O O + + O + O X O O + O O o O O . O . . o o . . . . . . . . . O X $ * ; e b Y { <.8.f.g.j.h.f.7.<.{ Y b w ; $ + . ",
"2 2 2 r 2 2 2 2 2 2 2 2 2 1 1 2 2 2 1 Z.Z.Z.Z.Z.Z.p.p.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.+., 1 1 1 1 1 1 1 1 Z.Z.Z.Z.Z.Z.+., 1 , , , , , , 1 , , , , , , , , , , 0 k.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.C.0.> > , : : : : > : : : , : 4.Z.Z.Z.Z.Z.Z.Z.4.: - - : & - : : & - & : - - & 0.Z.Z.Z.Z.Z.Z.Z.Z.E & & & & & q v v v v v v v v v v v v v - # & % % % % % % % % % & % % % # & & # # # # # # # # # # @ # @ - @ @ @ O O @ - + + @ @ + + + + @ + @ @ # @ ; < r B Q >.9.j.x.N.C.Z.Z.N.x.j.9.>.Q B e < = + @ + O + O + O + O + O O O O O O O + O O O O O O . . o . . o . . . . O . . O X + $ = 7 s C U .>.2.7.9.7.2.>.{ Y M r 5 * $ O . ",
"2 2 2 2 2 2 2 2 2 2 2 2 7 2 2 1 2 2 1 Z.Z.Z.Z.Z.Z.p.p.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.B.e 1 1 1 1 1 , 1 , 1 Z.Z.Z.Z.Z.Z.+.1 , 1 1 , 1 , , , , , , , , , > , , , , w 6.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.C.B.> - : : , : , : > : : : 7 B.Z.Z.Z.Z.Z.Z.Z.B.7 : : - : : & & : : : & & : & p.Z.Z.Z.Z.Z.Z.Z.Z.D - & & & * i v v v v v v v v v v v v z # & % % % & % % % % % % # # % % # # # # # # # # # # # # # # # @ + @ - O + - @ @ - + + # - + - o + @ @ @ $ - ; ; t B R ;.9.h.x.N.C.Z.C.N.x.j.7.:.Y M e < * # # + + + O X + O + O O + O + O O O O O O O o O O . . . . . o . . . . o . o X X X $ % = 7 f C K ! .;.:.;.{ ! K C s 7 ; % + O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 Z.Z.Z.Z.Z.Z.p.p.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.B.V 1 1 1 1 1 , 1 1 1 1 Z.Z.Z.Z.Z.Z.+., 1 , , , , , 1 , , , , , > , , , > , > , , 0 F F F F F F W 5.Z.Z.Z.Z.Z.Z.Z.I : > > : > > : > > : > | Z.Z.Z.Z.Z.Z.Z.Z.Z.} : : = : : - - : : & : : & : u.Z.Z.Z.Z.Z.Z.Z.Z.V & & & & # a v v v v v v v v v v v v z - # & # & # - # # # & # % % % % # % # # % % # # # # # # # # # # @ # # @ @ @ @ @ @ @ @ @ + @ @ + @ @ @ + @ * & < 9 M U -.2.w.l.m.M.N.N.x.l.g.2...K M w : = $ + + + + + O O + O O + O X O O X X X O O O O X O o o o o o . o . . . . . o o . O + $ * 3 7 r b S K T R K K A b r 7 * ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 Z.Z.Z.Z.Z.Z.p.p.Z.Z.Z.Z.Z.Z.Z.Z.B.6.n 1 1 1 1 1 1 1 1 1 , 1 Z.Z.Z.Z.Z.Z.+.1 , , 1 1 , , , , , , , , , , , , , , , ; , , , > > > > > > , I Z.Z.Z.Z.Z.Z.+.> : > : > : > : : : : v.Z.Z.Z.Z.Z.Z.Z.Z.Z.v.: : : : & - - : & : & : - & u.Z.Z.Z.Z.Z.Z.Z.Z.V & - & - & p v v v v v v v v v v v v z # # # & # & # # & # & # % % % % # % % % # # # # # @ # # @ % # # # @ @ @ @ @ @ @ + @ @ @ @ @ @ @ + + @ @ @ # # > 2 b H ^ 1.9.j.l.x.x.x.l.h.9.,.^ S f 7 ; = + + + O O O + + X + X + O + O O + o + O O O O X O X X o o X o . . . o o o . . . X O + + $ % = 5 w r b m M m f r e 6 ; * ",
"2 2 2 2 r 2 2 2 2 2 2 2 2 2 2 2 2 1 1 Z.Z.Z.Z.Z.Z.p.2 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 , Z.Z.Z.Z.Z.Z.+., 1 , 1 1 , , , , , , , , , , > , , > > ; , , , , > > , > > > > b.Z.Z.Z.Z.Z.0.> : > > : > : : > > I Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.I : : : & : - & : : & & = : u.Z.Z.Z.Z.Z.Z.Z.Z.V & & & & & g v v v v v v v v v v v v g # - # & & # - - # # # & % % % % % % % # % # % # # % # # # % @ # @ @ @ @ # @ @ @ @ @ @ @ @ @ @ @ @ @ + @ @ # * ; 1 r B T ..1.9.q.h.j.j.q.9.1. .Y M r < = $ + + + O + + O O + O + O + O O O O X o O O O O O O O O O . o o . . . X . X . O O O X $ % * ; 7 7 7 9 9 8 5 ; * + + ",
"2 2 r 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 Z.Z.Z.Z.Z.Z.p.1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 1 1 Z.Z.Z.Z.Z.Z.+., , , , , , , 1 , , , 1 , , , , , > , , , > , > > , > , > > , > 5.Z.Z.Z.Z.Z.p.> > > : > : > > : : p.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.u.- - : : = : : : & : - - & p.Z.Z.Z.Z.Z.Z.Z.Z.V & - & & - p v v v v v v v v v v v v p - # - # # & # # & & # # % % % % % # # % % % # # # # # $ # @ @ $ @ # # @ @ # @ @ @ @ @ + @ @ @ @ # + @ + @ % # = , w f A Q ..1.2.7.9.9.2.<. .Q A b 7 ; = # + + + + O + + + O + O O O O + + O O O O X O O X O O X X O . O . . . o . . . . . O O X $ + % % % = ; ; * * * $ % ",
"2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 1 2 Z.Z.Z.Z.Z.Z.p.2 1 2 1 1 2 2 1 1 1 1 1 1 1 1 , 1 1 1 1 1 1 , Z.Z.Z.Z.Z.Z.+.1 , , , , 1 1 , 1 , , , , , , , , > , > , , > , > , , > , : > > +.Z.Z.Z.Z.Z.u.: > > > > : > : : d Z.Z.Z.Z.Z.Z.u.Z.Z.Z.Z.Z.Z.t - : : & : : & : & & - & u.Z.Z.Z.Z.Z.Z.Z.Z.V & & & & & p v v v v v v v v v v v v p - # - - & # - # # & & # & % % % % % % # # # # % % @ # @ % @ % @ # @ @ # @ # @ @ @ @ @ @ @ @ @ + + + @ + + # % # - < w n A R ^ ..>.>.>...^ Y A f 9 < = # % + + + O + O + O + + O + + O O O + X o X O O O O O O X . . o o . . . . O . . . + + $ $ $ $ $ $ $ $ $ + . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 Z.Z.Z.Z.Z.Z.p.2 7 1 1 1 2 2 1 1 2 1 1 1 1 1 1 1 1 , 1 , 1 1 Z.Z.Z.Z.Z.Z.+., 1 1 , , , , , , , , , , , , , , , , , , > , > > > > > > , > > +.Z.Z.Z.Z.Z.p.> > : : > > : > , %.Z.Z.Z.Z.Z.Z.j v.Z.Z.Z.Z.Z.4.- : & : : - - : - - - - u.Z.Z.Z.Z.Z.Z.Z.Z.Z & & - & & p v v v v v v v v v v v v p # # # # # & # % & # # # % % % % # # # % # % # % # # # % @ # @ # @ # # @ # @ @ @ @ @ @ @ @ + @ + @ @ + # @ # # % = - 1 e f B H Y Y Q Y Y S M y e 5 ; # % + + + O O + + O O X O O O O O + O O o + X X O O O O O X O O o . . o . o . o o X o X . . . O X X O + + + + O X X . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 Z.Z.Z.Z.Z.Z.p.1 1 2 1 2 1 1 1 1 1 2 1 1 1 1 1 1 , , 1 1 1 , Z.Z.Z.Z.Z.Z.+.1 , , , , , 1 , , , , , , , , , , , , , , > , > , , > > > , : , +.Z.Z.Z.Z.Z.u.: > > : > > > : 1 B.Z.Z.Z.Z.Z.b.: %.Z.Z.Z.Z.Z.B.7 : : : & - - - - : & : p.Z.Z.Z.Z.Z.Z.Z.Z.V & & & & & p v v v v v v v v v v v v p # - & % - # % % # # & & % % % % % % % # # # # # # # @ % % @ @ $ @ @ @ @ @ @ @ @ @ # @ @ @ @ + @ # + # + @ + @ % # = ; < 0 t f m B B B m f r w < = % % % + + + + + O + + + + O X O O + O + O o o O + O O O O O O X o o . . o . . . o X X . . X X . . X . O . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 Z.Z.Z.Z.Z.Z.p.2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Z.Z.Z.Z.Z.Z.&., 1 , 1 1 , , , , 1 , , , , , , , , > , , , > , > > , , > > , , u.Z.Z.Z.Z.Z.%.> : > > : : : : ` Z.Z.Z.Z.Z.Z.| : d Z.Z.Z.Z.Z.Z.} : & & : - - : & - - & u.Z.Z.Z.Z.Z.Z.Z.Z.F & & & & & p v v v v v v v v v v v v p # - # # - # & % # & # # % % % % % # # # % # % # $ # % @ @ % @ % @ @ + - @ @ @ @ @ @ @ + @ @ @ # + # + @ + @ + + # % & ; > 7 0 w e r e e 1 < - ; * % + + + + O + + + O + + O + + O + O O O O O O O O O O O X X O X o . . o . X O . . . O O . . . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 Z.Z.Z.Z.Z.Z.p.2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 , 1 b.Z.Z.Z.Z.Z.k., 1 1 , , , , , , , , , , , > , , , , , : , , : , > , > > > > 0 Z.Z.Z.Z.Z.Z.| , > : : > : > : v.Z.Z.Z.Z.Z.Z.t : : k.Z.Z.Z.Z.Z.v.: : & : : & : : - : & p.Z.Z.Z.Z.Z.Z.Z.Z.V & & & & & p v v v v v v v v v v v v i = % % & # % & # - - @ - + - + - % % % % # % # # % # # # # # # % @ @ # @ # @ @ @ @ @ @ + @ @ @ + # + @ @ + + @ @ @ # # # - - ; > , > < > - ; % # # @ + + + + + + + + + + $ + + X + O + O O X O O X O O O O O O O . X O O X X X X X O + + X X X X X . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 Z.Z.Z.Z.Z.Z.f.1 1 1 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0.Z.Z.Z.Z.Z.Z.J , , , , 1 , , 1 , , , , , , , , , , , , , , , > , > , > > , X.Z.Z.Z.Z.Z.Z.h > > > > > > , D Z.Z.Z.Z.Z.Z.k.: : : } Z.Z.Z.Z.Z.Z.I : : & & : & & - & - u.Z.Z.Z.Z.Z.Z.Z.Z.V & & & & & p v v v v v v v v v v v v p % # & # # & # & + + - + - + - + % # % # # % # # # # # # # @ + # - # @ @ @ @ @ @ @ @ @ @ @ @ + @ + @ + # @ + + @ @ @ # # # # # - ; & ; % * # $ @ $ + + $ + + + $ + $ % $ + @ $ + @ + + O X + O + X + O O O X X . O O O X X O X O + + + $ + + + O O O . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 Z.Z.Z.Z.Z.Z.p.1 2 1 2 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 , 1 [ Z.Z.Z.Z.Z.Z.k.e , 1 1 , , , , , , , , , , , , , , , , , , , , > , > > > m B.Z.Z.Z.Z.Z.v.> > > > > : : > r.Z.Z.Z.Z.Z.Z.X.: : : d Z.Z.Z.Z.Z.Z.u.& : : : : & : & - & p.Z.Z.Z.Z.Z.Z.Z.Z.k.u.u.u.u.u.s.d.d.d.d.d.d.d.d.d.d.d.d.s.u.$.% & & # & # - + + - + - + - % # # # % % # # # # # # # # % # + @ @ @ @ @ @ @ # @ @ @ + # + # # + @ + @ @ @ + + + + # # @ @ # # # @ $ # $ @ @ + + + + + # @ $ * # * = & * * @ @ + + + + O O O O O O O O O O O . . O O O O + + $ $ $ * $ * $ $ $ + + . X . X ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 Z.Z.Z.Z.Z.Z.p.2 1 2 1 1 1 1 1 1 1 2 1 1 1 1 1 , 1 1 1 1 , 1 e B.Z.Z.Z.Z.Z.Z.B.p.p.p.p.p.p.i.i.i.i., , , , , : N i.i.i.i.i.u.p.u.p.p.p.Z.Z.Z.Z.Z.Z.Z.O.: > > : : > > t Z.Z.Z.Z.Z.Z.Z.7 : : : - k.Z.Z.Z.Z.Z.Z.e : & : & : : - : & u.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.u.& % # & # & + - - + - @ - + % % # % # # % # % # # # # @ @ @ @ @ @ @ # @ # @ @ @ + @ # + # + + # + @ + + + @ @ @ + @ @ @ @ @ @ @ @ + @ + + + + + + @ @ @ * = ; > : 5 : ; = & # # % + + + O O O O O O X O O o . O O O + + $ % * * * ; = = = * * $ $ + O X . ",
"2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 2 2 1 Z.Z.Z.Z.Z.Z.p.1 2 1 1 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 , 2 1 1 +.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z., , , , , , F Z.C.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.M.1 : > > > > : > %.Z.Z.Z.Z.Z.Z.r.: : : : : ` Z.Z.Z.Z.Z.Z.4.- - : : & & - : & p.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.u.% % - - - - - @ - + O $ - - % % # # & % # # # # # # @ # @ # @ @ - # @ @ @ @ @ @ @ @ @ @ + @ + @ + + @ + @ + + + @ + + @ @ + $ + + $ + + + + + + + # * ; > 5 7 e w e e 9 7 5 : * * + + + + X O O O O O O O O O O + + $ $ % = : 5 9 9 e 9 9 5 ; * * @ X X X ",
"2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 1 2 Z.Z.Z.Z.Z.Z.p.1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 , , 1 e k.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z., , , , > , F Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.W : : > > : > > 7 B.Z.Z.Z.Z.Z.Z.` : : : : : 7 Z.Z.Z.Z.Z.Z.B.7 - & : & : - & & u.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.t.% % + $ + O @ - + - - + - + # # # # # # # # # # # % # # # @ @ @ + @ @ @ @ @ @ + @ @ + @ @ @ @ @ @ @ + @ + @ @ + + + + + + + + + + + + + + + @ # $ % = > 0 e f m M M C b f e 9 : & $ $ + + X O O O O O X X O O O + + $ = = 6 e r b b C b b f e 6 ; & $ $ X ",
"2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 Z.Z.Z.Z.Z.Z.p.1 2 1 1 1 1 1 1 2 1 1 1 , 1 , 2 1 1 1 , 1 1 1 , , C k.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z., , > , , , F Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.W : , : , : > : > ` Z.Z.Z.Z.Z.Z.B.7 : : : : : : r.Z.Z.Z.Z.Z.Z.} - & : : & - & - p.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.t.- ; - - ; - - - - @ ; - - $ % # # # # # # # % % # # @ # # # - + @ @ # # @ @ @ @ @ + @ @ @ @ @ @ @ + + @ @ @ + @ + + @ + @ + + + + + + + + + @ $ * = < e s B G U R R T K G M s 9 5 = $ $ + O X X O X O O O X O + + $ * > 9 s m S K T T T K G m r 7 ; * $ X X . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 p.p.p.p.p.p.3.1 2 2 1 2 1 1 1 1 1 1 1 2 2 1 , 1 1 1 1 1 1 1 , 1 1 , [ 0.p.p.p.p.p.p.p.p.p.p.p.p.p., , , , , > N p.p.p.u.u.u.p.u.p.u.p.p.p.p.&.d , , : , : > > > : %.u.p.u.p.u.p.+.: : : : : : - I u.u.u.p.u.u.4.- : : & : - - & I B.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.t.; 4 3 ; 3 3 ; 4 8 ; 4 4 ; 4 , > 4 4 4 4 4 < 3 3 3 3 3 3 3 3 - + @ @ @ @ @ @ @ @ @ @ @ @ @ + + @ @ + @ @ + + + # + # + + + + $ + + + + + + + @ # ; > 0 f A K ! { ;.>.:...! Y A f w : * $ + + + O O O O O O O O + $ * : 7 s M Y ! .;.:.-.{ R Y C s 7 = % $ X . ",
"2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 1 1 1 1 2 1 2 1 1 2 2 1 1 1 1 1 1 1 2 1 , 2 , 1 1 1 , 1 1 1 , 1 , 1 , 1 , , , 1 , , > , , , , , , , , , , , , > , > , > > > > > , > : , , : , > , : : > > : : : , : : : > : : : : : : : : : : : - : : - : : & : & : - - - - - & V D V V V V V V V N V V E ] ] ] ] ] ] ] ] ] ] ] ] ] ] ' v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v ; O - o O - O O + $ O + - + - O @ @ + @ + @ + @ + + + @ + + @ + + @ + + + + + % + = : 7 f S T ..<.2.8.9.7.2.<.{ R B y 7 : * + + O O O O O X O + + + # : 7 s A Y { >.2.8.8.8.2.>.{ T A s 5 = $ + + . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 2 1 2 2 2 2 1 2 1 1 2 1 1 1 1 1 2 1 1 , 1 2 , , 1 1 , 2 , 1 , 1 , , , , 1 , 1 , , 1 , , , , , , , , , > , , > , , , > > , > , > > > > , : : > , : : , : > > : : > : : > : : : > : : : : : : : - - - : : & & : & : : & - - & - & - & - - & & - & - - & & & i v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v ; - o - - + + - O - - $ O + - + + @ @ + @ + + @ @ + @ + + + + + + + + + + + + + * = 5 e M K .1.9.g.h.h.j.q.9.1.{ Y M e > & @ + + O O O O O O O + @ * : e b U { <.7.f.h.h.h.f.8.1.{ K b e ; % X X . . ",
"r 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 2 2 2 2 2 1 1 2 1 1 2 1 2 1 1 1 1 1 1 1 2 1 1 1 1 1 , 1 , 1 , 1 1 1 1 1 , , , , , , , , , , , , , , , , , , > , > > , > , > , > > > > > , , , : : > > : > : > : > : : , : > : : : : : : > : : : : - : - : : : : : & : : - - - - - - - & - & & - - & & & & & i v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v 3 $ - o - O O - + + - + + @ O + + @ + @ @ + @ + + @ + + @ + + + + + + + + + + % # : 7 b S ! <.9.h.l.x.m.x.l.g.9.>.~ A b 7 = % + + X O O O O O O + % = 5 s S ! >.8.h.l.z.m.z.l.h.8.>.R S s 5 * $ + . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 2 2 1 2 1 1 1 1 1 1 2 2 1 1 1 , 1 1 1 1 1 1 1 1 , 1 1 , , 1 , 1 , 1 1 1 , , , 1 , , , , , , > , , , , , , , > > , : , > , > > : , : : , : : , > > > : : > : : : : > : : : > : : : : : : : - : : & : & : & : & & - & - - & & & & & & - & & & & & ; i v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v 3 O o - O - + O - o o + @ @ @ + @ @ + + + @ + @ + + @ + + + # + + + + + + + + # * > e m Y ..2.g.l.m.M.V.M.m.l.w.2.-.U b 7 ; % $ + O O O O O O + $ $ : 7 b U { 2.f.l.m.M.N.M.m.l.f.2.{ K b 7 * $ + . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 1 2 1 2 1 2 1 2 1 2 2 1 2 1 1 1 1 1 1 1 1 , , 1 , 1 1 , 1 1 1 , 1 , , 1 , , , , , , , , , , , , , > , > , , > , , > > > > > , > , > , > : , , : > : > > > : > > : > : : : > > : : : : - : : : : & : : & : : & : : : - - - & - & - - : & & & - & & & & & p v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v 3 $ O - o - O - @ @ @ @ @ - O + + @ @ @ @ + @ + # + + @ + + + + + @ + + + + # $ & 5 e M T :.8.h.x.M.C.C.C.N.x.h.8.:.T m w : * $ + + O O O O X + + $ : w b R -.8.h.z.N.C.Z.C.M.z.h.7...T b e ; * + . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , , , 1 1 , , 1 , 1 1 , 1 , , , , , , , , , , , , > , > , , , , , , > > > > : , , > : , : , > > : > : : > : > : : : : : : : : : : : : - : : : : : & - : & & - - - - & - - & & - & - & & & & & & i v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v ; - - O + o O - @ @ @ @ @ + @ @ @ + + @ + @ @ + @ + + # + + @ + + + + + + + @ % & > r M R >.9.h.x.V.C.Z.C.N.m.h.9.:.R M e > $ + + O O O O X O + + * 3 w M R ;.9.h.m.B.C.Z.C.N.z.j.8.:.R b e ; % + . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 1 1 1 2 1 1 2 , 1 1 1 , 1 1 , 1 1 1 1 1 1 , 1 , 1 , 1 , , , , 1 , , , , , , , , , > > , , , , > > , > > , > > > , : : , : , : : : > : > > : : : : : : : : : : : : : - : : : : - : & : : : : : & & - - - - & & - & & & - & & & & - & u v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v 3 o - - - - O O + - @ @ O - + @ @ @ @ + + @ + @ + + + + + + + + + @ + + + $ + @ = 5 e M R :.8.h.x.N.C.Z.C.M.x.j.7.;.T C e > * + + O O O O O O + + % ; w b R -.8.h.z.M.C.C.C.M.x.h.7.-.T b e = $ + . . ",
"2 2 r 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 2 1 2 1 1 2 2 1 2 1 1 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 , , 1 , 1 , 1 , 1 , , 1 , , , , , , , , , , , , , , , , > > , , > > , > > > , : , , : , : , : > : : , : : : , > > : > : : : : : : : : : - : - : & : & : & : & - - - & - - & & - - - & - & - & % - ; v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v 3 - o O O + + - + O @ @ + + @ @ + + @ @ @ + @ + + @ @ + @ + @ + + + + + + + + @ * : e b K ..2.w.l.m.M.V.N.m.l.q.2. .K m 9 : # $ O O O X O O X O $ $ ; 7 b Y { 2.f.l.m.M.B.M.m.l.f.2.{ K f 9 * $ + . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 1 2 2 1 1 1 2 1 2 1 2 1 1 1 1 1 1 1 1 1 1 , 1 1 1 , 1 , , 1 , 1 1 , , 1 , , , , , , , 1 , > , , , , > , , , , > , > > , > > > > : , , > : > > : > > > : > > > : : > > : : : : : : : : : - : : & : : - : - : : & : - & : & : - & : & - & & & & - & & & & - u p g z l l l l l l l l g l l k g l k k k k k k k k k k l l k l k k k k k k k k k k k k ; @ # @ # @ @ @ - + + - O O + @ @ @ + + @ + + @ @ + + + + + + + + + + + + + + % % : 7 f S ~ <.9.h.l.z.m.z.l.g.8.>.! G f 7 = $ + O O O O X O X + + $ * 7 s S ! >.8.h.l.z.z.z.l.h.8.>.! A s 5 % $ ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 2 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 , 1 1 1 1 , 1 , 1 , 1 , 1 1 , 1 , , , , , , , , , , , , > , > > > , > > > , > > , > : : , , : > > : > > : : : > : : : > : : > : : : : : : : : : : & - : : & : : & - - & : & & : & - & & - & - & & & & & & & & & & & - & & & % % & - # - - - - @ - - @ - @ - @ - # @ - + - # - @ + + - + - # + # @ @ # @ @ @ @ @ @ + + + O + - - + @ + @ @ + @ + @ + @ + @ @ @ + + + + + + + + + @ $ = 5 r M T ..1.9.q.h.h.h.f.9.1. .T m e 5 * @ + + O O O O X + O + $ & : e M Y { 1.8.f.h.h.h.f.8.1.{ U b 9 5 * $ ",
"r 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 1 1 1 2 2 1 1 2 2 1 1 1 1 1 , 1 1 1 1 , , 1 1 1 , 1 , , 1 , , 1 , , , , , , , , , , , , , , , > , > > , , , > , , > > > > > , > , : : , , : > : > > > > > > : : : : : : : : : : : : & : : : : : & : : & : : : & : - : & & & - & & & & - & & & - & & & & - # % & % % & & & # - @ - @ + + - @ @ - + - + - - @ - + - # + - - + - + + + - - + + - O @ # # @ @ @ - - o - @ @ O + @ @ + @ @ @ + + + @ + + + + + @ + + + @ + + + # $ * : 9 f A T ..<.2.8.8.8.2.>.{ T A s 7 = * $ + O O O O O O O O + $ $ = 7 r A Y { >.2.8.8.7.2.>.{ T C s 5 = $ + ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 2 1 1 1 2 1 1 1 1 1 , 1 1 1 1 1 1 1 1 , , 1 1 , 1 1 , 1 1 , , 1 1 1 , , 1 , , , , , , , , , , , , , > > , > > , , > > , : , : , > > : > > > > : : : : : > > : : : : : > : : : - : : : : & : : & : - & & & : & & & & : & & - - & & & & & - # & - # & - # & & & & & # & & # - @ - - - + - - + - @ - + # + + - + # - @ + - @ + - - + + + - $ @ @ # @ @ @ @ + + + @ @ + @ @ + @ @ + @ + + @ + + @ + + @ + + @ + + + + + + + $ % = 5 e f A K ! ..;.>.;.{ { Y A f 9 5 = # + O O O O X O O X O O X $ & ; 7 s C U ! { ;.:.;. .! U C s 7 ; % $ X ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 1 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , , 1 , , 1 , , , 1 , 1 , , , , , , , , , , , , , > > , > , , > > > > > , : : , : , > > > : > > : : : : : : : : : > : : : : : : : & : : : : : & : & & : - - - : - & & - - & & - - & & & & - - & & & & - & # % & # & # & - @ - @ - @ - # @ - + - @ # # - # - + - + @ + - - + + @ - + + + @ # @ # @ @ @ @ @ @ @ + + @ @ @ @ + @ @ + @ + @ + @ + + @ + + + + + + + + + + + @ $ # = 5 9 s M S K T R T U S M f w 5 * @ + + + O O O X O O o O O + + % * : 7 s m A K T T T K A m s 7 ; $ ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 1 2 1 2 2 1 2 1 1 1 1 1 2 1 1 1 1 1 1 1 1 , 1 1 1 , 1 , , 1 , 1 1 , 1 , 1 , 1 , , , , , , , , , , > > , , , > , , > > > > , > > : , , : > : : , > > : > > > > : : : : : : : : : - : : : : : : & : & : : : : : : - & - & & : - & & - & & & & & & - # - # # & & # & & & & & & & # @ - @ - @ - @ @ - + @ @ - # - + # # # # @ - # + @ + - + + + - - @ $ - @ @ @ @ @ @ @ @ @ @ @ @ + @ @ @ + @ + @ + @ + + @ + + + @ + @ + + + + + + + $ % % = 5 9 e b m M C C b f e 7 : = $ @ + O O O O O + O X O X X + + $ = ; 7 e s b b m m b r e 6 = * $ ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 2 1 1 2 2 1 2 1 1 1 1 2 1 1 1 1 1 1 1 , 1 1 , 1 1 1 1 1 1 1 , 1 , , , , , 1 , , , , , , , , , , , > , , , , > > > > , , > > > , , , : > , , : : > > : > : : > > > : > > : > : : : : : : : : & : : & : - : & : & - & & - - & & - & - & - - & & & & & - & & & & & & & # & & # & % - @ - @ - + @ - # @ - @ - @ - # # # + # - # - + + - - @ - + + + - @ + + @ @ @ @ @ - @ @ + O @ + @ + @ + @ + + @ @ + @ + + @ + + + @ + + + + + + + + @ $ % = : 5 7 e e e e w 7 5 ; * # % + + + O O O O O O O O X X O O + $ $ * = 5 6 9 e w w 9 6 3 * * $ . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 1 1 2 2 1 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 , , 1 1 , , , 1 , , 1 , , , , 1 , , , , , , , , , > , > , , > > , > > , > > > , : : , : : , : : > : > > : : > : > : : : : : : : : : : : : : : : : : & & : & : & : - - & - - & - & & & & & & - & & - # & & & & # & & & & & % & @ - @ - # - - @ - - + - # # @ @ - # - # + # # # - + + + - + - + + # @ # # @ @ @ + O @ @ @ - + @ @ + @ @ + @ + @ + @ + + + + @ + + + + + + + + + + + + @ @ % * & : 3 : > : : * = & $ $ + + O + O O O X O O O O O . X O O X + + % & * = = = ; = = * $ . $ . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 , 1 , 1 1 1 , , 1 1 , 1 , , , 1 , , , , , , , , , , , , , , , , , , > , : > > > > , , : : , : , : > > , : : > : > : : : : : : : : : : : : : : : : - : : - & : - : : & : & & : & & & : & - & & & - & - & & & & & & & & & & # & & & & # & # & # & & & # & # # & & @ # & @ # @ & @ @ & @ & @ @ @ @ @ @ @ & @ @ @ @ @ # @ @ @ @ @ @ @ X @ @ + @ @ @ + @ + + @ + @ + + + + @ + + + + + + + + + + @ + @ @ # % % & % & & # @ @ @ + + + X X + O O O O X O O O O O O O O + + $ $ $ * $ * $ + $ + O O O . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 2 1 1 2 2 2 1 1 2 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 , 1 , 1 , 1 , , , , , , , , , , , , , : , , , : , , : > > , : , > : , > , , : : : : : > > > > > > : > > : : > : : > : - : : - - : - & : : & & - - : & : : & & : & & - & & & & & & & & & & & & & & # & & & & # & & & & # # & # # # & # & # # # # & @ & # % # # % & @ # # @ & # @ # # @ @ @ @ @ # @ @ @ @ # X @ @ @ @ @ + @ + @ + + @ @ + + + @ + + + + + + + + + + + + + + + o @ @ @ @ # # # @ @ + @ + + + X o o o o O O O O O O X X O O X X O O + + + + + + + + + + O O . . ",
"2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 2 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 , 1 1 , , 1 1 , , 1 , , , , 1 , , , , , , , , , , , , , : , > , , , > > , : : , : , , : , : , , > > : : > : > : : : : : : : : : : : : : : : - : : : - : : & - & : & : : & : : & - & - & & & & & & & & & & & & # & & & & & & # & # & & & & & # # # & & # @ & @ & @ @ # @ % # @ @ @ @ # # # @ @ @ & # @ # @ @ @ # @ @ @ @ @ @ @ @ @ @ + + + @ + + + @ @ + @ + @ + + + + + + + + + o + + X + + + @ + + + @ + + + + + + X o O O o X X O O O O O O O O O O . X O O . O O + + . O + . O o . ",
"2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 2 2 1 2 2 1 1 2 1 2 1 2 1 1 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 , 1 , 1 1 , 1 , , 1 1 , 1 , , 1 , , , , , , , , , , , , : , , , > , , , > , , , , : , : : : , , : : > : > > : > : > : > : > : : : : : : : : : - : - - : : - : : : : & : & & : & : & & & - & & - & - & & & & & & & & # & # & # & # & & & # # & # & # & # & # & @ & # # & # & # # # # & # # @ & @ @ # @ @ @ @ @ @ @ @ @ @ @ @ @ @ X @ + @ @ @ @ @ + @ + + @ + + + + + + @ + + + + + + + @ o @ + + X o o + + o + + X + X X + o + O + X X + X O O O O X O O X X O . o O O . . . . o o ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 1 2 2 2 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 1 1 , , 1 , , , 1 , , , , , , , , , , , , , , , , , , > , > , : : , , , : , , , : : , , : : > > : : > > > : > > : : : : : : : : : : : : : - : : - - - - & : & & & : & & & & : & & - & & & & & & & & & & & & & & & & & & & & # # # & & & # & # # # & # # & & @ & # # # % # # % @ # # # # @ @ & @ @ @ @ @ @ @ @ @ @ X @ @ # @ @ @ @ + @ @ + @ + @ + + @ + + + + + + + + + + + + + + + o + o + o + + o + X + + o O O O O O o o o O O O O O O O o o O O X O X o . . . . . . O . ",
"2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 2 1 2 1 2 1 2 2 1 1 1 2 2 2 2 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 , 1 , , 1 1 , 1 , 1 , , 1 1 , 1 , , , , , , , : , , : , , > , , > , , , : , , , : : , , : , : , , : , , : : : > : : > > : : : : : - : - : : : - - - : - : : : : & : : & : : & : & : & - & & - & & & & & & & & & & & & # & & # & & & & & # # & # & # & # & & @ # @ @ @ & % # % # # & # # # # @ @ # @ @ @ @ @ @ @ @ @ # # @ @ X # X @ + @ + + @ + @ @ + @ + + + @ + + @ + + + + o + X @ + + + + + + + o + + + o o X + + O + o + O X O X O O O O O X o o X O O O . . . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 1 2 2 1 1 1 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 1 , 1 1 , , 1 , 1 1 , , 1 , , , , , , , , , , , , , , > , : , , : , : , : : > , : : , : : : , : : > : > : : > : : > : : : : : : : : - : : - - - - : & : & : & : & : & & & - & & : & - & & & & & & & & & & & # & # # & # & & # & # & # & # & # % # @ # # & % # % @ # % # # # # # # @ # # @ @ & @ @ @ # @ @ @ @ # @ # X @ @ + @ + @ @ + @ + + @ + + @ @ + + + + + + + + + + + o o @ + + + X + + o o X o + + O O O O o + + o O O O O O O O X O O O O o X o . . . . . . ",
"2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 2 2 1 2 2 1 1 1 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 , , 1 1 1 1 , 1 , 1 , 1 1 , , , 1 , , , , , , , , , , , , , , : , > , , > , , , , : > , > , , , : , : , , : : > > : > : > : : : > : : : : : : : - - : - - : - : - & : & : & : & : & & : & & - & & & & - & & & & & & & & # & & & & & & & # & # & & # & # # # & & # & @ & # % % % % # # # % @ # # # # # @ # @ @ @ @ @ @ @ @ @ @ # X # & X @ @ @ @ + @ @ + @ @ + @ + + + + + + @ + + + + + + + X @ o + X + X + o + + + X o + O + + O O X o o O O O O X O X o o O X . . . . . . . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 2 2 1 2 2 1 2 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 1 , 1 1 , 1 , , 1 , , , , 1 , , , , , , , , , , , , , , , : , : , > > > > > > > > > , : , : : > : : > : > : : : > : : : : : : : - : - : : : : & : & : & : & : & - - & - & - & - - & & & & & & & & & & & & & # & & & # & & # & & # # # & # & @ & # # @ & # # % # @ # # # # # @ # # # @ @ # # # @ # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ + @ + @ @ @ + + + + + + + + + + + X + + + + + X + + X + + + + + X + O O O O O + + X X O O O O O O X O . o . . X O O O O . . o . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 1 2 2 1 1 2 1 2 2 1 1 2 1 1 1 1 2 1 1 1 1 1 1 1 1 , 1 , 1 , 1 , 1 1 , 1 , , , 1 , , 1 1 , , , , , , , , , , , , : , , : , , , , , , , , , : > > > > : > : , : > > > > > > : : > : : : : : : : : : : : - : - & - - : & : : & & : : & & & - & - & & & & & & & & & & & # & & # & # & & & # & & & # # & & & & # & # & @ & & # # % % & # & # # % @ % # # @ @ # @ @ @ @ @ @ @ @ @ @ @ @ # X # # X + @ + + + @ + @ + + + + + @ + @ + + + + + + + + + + + + + + X + + X o O O + X o + O O O O O + o O O O O O O X X . o o . o . o . . . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 2 1 1 2 1 2 1 2 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 , 1 , 1 , , , , 1 , , , , , , , , , , , > , , , , , > > : > > : , > > > > : , : : > > : : > : : : : : : > : : : : : : : - - : - : : : : & : : & : & : & : & : & : & & - & & & & & & & & & & & & & % & & & & & # & # & & # # # # & # # # & @ & & @ & # @ # # # % % @ & & X @ @ @ @ @ @ @ # @ # @ @ @ @ @ X @ @ @ @ + @ @ @ @ @ + + + @ + @ @ + + + @ + + + + + + + o + X + X + o + o X + + + O + o O O + + o + o O O O X + X O O o O O o o . . . O O . . o o O . o ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 2 2 2 2 2 2 1 2 1 2 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 , 1 1 , , 1 , 1 , 1 , 1 , 1 , , , , , 1 , , 1 , , , , , , : , , , : , : , , : , > , > , > > > > : : , : > : > > > : > > > : : : : : : : : - : : : : - : & : : : : & : & : & : & & : & & : - & & - & - & & & & & & & & & & & # & # & # & & & # & & & & # # & & @ & @ @ & # @ & # # % @ @ @ @ @ & & @ @ @ # # @ # @ @ @ @ @ @ @ @ X @ @ @ @ @ + + @ + + @ @ + + @ + + + @ + + + + + + + + + + + + + + + + + + o + o + + + O + O O X O X O O O X O X X O O . O . o o . . . O . . o o ",
"2 2 y 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 2 1 2 2 1 1 2 2 1 1 1 2 1 1 2 1 1 1 1 1 1 , 1 1 1 , 1 1 1 1 1 1 1 , 1 , , 1 , , , 1 , 1 , , , , , , , , , , , , , : , > , > > , : , , > > > > > > > > > > : : > > > : : > : : : : : : : : : : : - : : - : & : & - - : & & : : & : & & & & & & & : & & & & & & & & & & & & & & # & & & # & & # & & # & & # # & # & @ # # # # # # # # # # @ & & @ @ @ @ & @ @ @ # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ + + @ + + + + @ + + @ + + + + + + + + + + + + + + o + + o + + o O O + O X O O O O + O O O O O O O O O O O O O X X . . O o . o . o . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 1 1 1 2 2 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 , , 1 , 1 , 1 , 1 , , 1 , , , , , , , , , , , , , > > , , > , > , > , , , : , : > > > > : > > : > > > : : : : > : : > : > : : : : : : : : - - : : & : : - - - - : & & : & : : & : & & & & & & - & & & & & & # & & & & & & # # & # & & # # & # # & # & # @ & & @ @ & & # & # % # @ @ @ @ @ @ @ @ # @ # # @ @ @ @ X @ @ @ @ @ @ @ + @ + @ @ + @ @ + @ @ + + + + + + + @ + + + + + + + + + + + + + O + + O + O + X + + O O o O O + O O O O O O O O O O O O O X o O o . . o ",
"2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 2 1 1 2 1 2 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , , 1 1 , 1 1 1 , 1 , 1 , , 1 , 1 , , , , , , , , , : , , , , , , > , > , > : , : , > > > > > > > > > > > > > : > > : > : : > : : : : : : : - : - : - - : - - - - & - & : & & & : & & & : & - & - & & & & & & & & & # # & # & & # & & # & # & & # & # # & # & # @ & # # # # # @ # % # @ @ @ @ & @ & @ @ @ # @ @ @ @ @ # @ @ @ @ @ X @ @ + @ + @ + @ + @ + + + @ + + + @ + + + + + + + + + o + + o + o + + O + O + O + O O O + O O O O O O O O O O O X o O O . O . X O o o o o . ",
"2 2 2 2 2 2 2 2 1 2 2 2 2 2 1 2 2 2 2 1 2 2 1 2 2 1 2 1 2 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , , 1 , 1 1 , 1 , , , , , , , , , , , , , , , > , , > , , > , > , > , , , : > > > > > > > > : : : > > : > : : : > : : : : : : : : : - : - : : - - : - - : - : & : & : & & : & & & & & & & & & & & & & & & & & & & & & & & # & # & & # & # & # # & # & # @ # & @ & @ # # # # & @ & @ @ @ @ @ # @ # @ # @ @ @ @ @ @ # X @ @ @ @ @ + @ + @ + @ + + + @ + @ + + + + + + + + + + + + + + X + + + O O + O + O + O O + O + O + O O O O O X O X O O O . . O o O o . . . . . ",
"2 2 2 2 2 2 2 2 y 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 , 2 1 1 , , 1 , 1 , 1 1 , 1 1 , 1 , , , , , , , , , , , , , , : , , : , , : , , : , , , > , > > > : , : > > > : > : > : : > : : : > : : : : : > : : : : : - - - : : - - : - - - & : & & & : : - & - - & - & & & & & & & & & # & & & & # & # & # & & # & # & # & # # & # & # & & & # # & # # # # # # # # # # @ # # @ @ @ @ @ # @ @ @ @ X @ @ @ @ @ @ @ @ X @ X @ + @ + @ + + @ + + + @ + + + + + + O + + + + + + + + X O + O O O + O + O O o X O O O O O O O o o o X X o O X . O O O O O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 1 2 2 2 1 1 1 1 2 1 2 1 1 1 1 1 1 1 2 , 1 , 2 1 1 1 , 1 , 1 1 , , 1 , 1 , 1 1 , , 1 , , , , , , , , , , , , , , , , , > , : , : > , : , > , > > > > > > : > > : > : > : : > : : : : : : : : : : - - - - - - & : : & : & : : & & & & & & & - & & & & & & & & & & & & & # & & & & & & # & & # & # & # & # & # # # @ # # # # # # & # # # # # # # # @ @ @ # # @ @ @ @ @ @ @ @ @ @ @ @ @ X @ @ X @ @ X @ + @ + + + @ + + @ + + + X + + + + + + + + + X o + O + + O + + O + O O O X + O o O O O O O O o O O O O o O O O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 1 2 1 2 1 2 1 2 1 1 2 1 2 1 1 1 1 1 1 1 , 2 1 1 1 , , 1 1 1 1 , 1 , , 1 , 1 , , 1 , 1 , , , , , , , , : , , , , , : > , : , , : , : : , > > > : > > > : > : > : > : : > : > > : : : : : : : - - : : : - - : & : - - & : - & : & : & - & & & & & & & & & & & & & & & & & # # & & # & & # # & # & # & & # # & & # # & # # # # # # # # # # # @ @ # # # # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ X @ X @ @ @ + + + + + + + + + + + + + + + + + + + O o + + + + O + O O O O o O O O + + O O O O O O O O X O O X O o o O . O O O O O O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 2 2 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 , 1 , 1 1 1 , 1 , , 1 , 1 , , , , 1 , , , , , , , , , , , , , , , , : , , , , , , : , > , , : , : > > > : : > > > : > : > : : : : : : : : : : : : : : : - - - - : - - - - : & : & & : & & & - - & & - & & & & & & & & & # & & & & & # & & & # & # & # & # # # & @ # & # # & # # # & # # # # # # # # # # # # @ # @ @ @ @ @ @ @ @ @ @ @ X @ @ @ @ @ @ @ @ X @ + @ @ + @ + @ + + + + + + + + O + + + O + + X + o + + o + + + O + O O o O + O O X O O O O O X O O X O O O O O O . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 1 2 1 2 1 1 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 , 1 1 , 1 , 1 , 1 , 1 , 1 , , , , , , , , , , , , , > , , , > , , > , , > : , : , > : , , : , : > > > : : > : > > : : > : : : : : : : - : : : - : - : - : - - - - - & : & & - & : : & - & & & & & & & & & & # & & & & & & & # # & & & # & & # & # & & # # & # # # # # & # # # & # # # # # & # # @ @ @ @ # @ # @ @ # @ @ @ X @ @ @ @ @ @ @ @ @ @ @ @ + @ + + @ + + @ @ + + + + + + + + + + + + X + + O + O + o + + X + O O O O O O O O + X O O O O O O O . . o . O O O O o O O o ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 1 1 2 2 1 2 2 1 2 1 2 2 1 2 1 1 1 1 1 1 , 1 1 1 1 1 , 1 1 , 1 1 , 1 , 1 , 1 , 1 1 , 1 , , , , , , , , , , , > , , > , , : , > , , , : , : , : > > > > > > > > > > : > : > : : : : : : : : : : - : : - - - : - - - - - - : & & : & : & & - & & & - & - & & & & & & & & & & & # & & & & # # & # & & # & # & # & # # & # # # # # # # # # # # # # # # # # # # @ # @ @ @ @ @ @ @ @ @ @ @ X @ @ @ X + X @ @ X @ + + + + + + + + + + + + + + + + + + + + o + o + X + O + o O + X X + + O O O O O O X X O O O . X O . o . o o O O O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 , , 1 1 1 1 1 1 , 1 , 1 , 1 , , , , 1 , , , , , , , , , , , , , > , > > > , , : , : , , : > , > > > > > > : > > : : > : > : : : > : > : : : : : : - : : - - : - - - - - - : & : & & & : & & & & & - & & - & & & & & & & & & & & # & & # & # & & # & # # & & & # # # # # & # % & # # # # # # # # # # @ # # @ # # @ @ @ @ @ @ @ @ X @ @ @ @ @ X + @ X @ @ X @ + + @ + @ + + + + + + + + X + + + + O + + + + + + O + + O + X O O O O O + + O O O O O O O O . . o . o o . O o O o O O o ",
"2 y 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 1 2 2 2 2 1 1 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 , 1 , 1 1 , 1 , 1 1 , , , , , , , , , , , , , , > > , , , > , : , , , : , : , , : > > > > > : > > : > > : : : : > : > : : : : : : : : - : : - : - - : - - - - & : & : : & & & : - & - & & & & & & & & & & # & & # & & # & # & & & # & # & & # # # # & & # & # % % # # # # # # # # # # # # @ @ # # @ @ # @ @ @ # @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ + @ + + + + + @ + + + + + + + + + + + + + X + o + X + O o O + o + O + O O O O O O O O O O O . . O X . . . . o o o O O o O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 1 2 1 2 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 1 , 1 , 1 , 1 1 , 1 1 , , , , , , , , , , , , , : , , , , > , , > , , , : > , : : , : > > , > > : > > > > : : > : > : > : : : : : : : : : : : - : : : & : : & : : & : & : & : : & & & & - & - & & & & & & & & & & & & & & # & & & # & & # & & @ & # & # # # # & # & % # # % # # # & # # # # # # # @ @ @ # @ @ @ @ @ @ @ @ @ @ @ @ X @ @ @ @ + @ + @ X + @ + + + @ + + @ + + + + + + O @ O + O + + + O + + X + O O + O O O O O X + X O O O O O X X o O O . . o . . . O o . . o . O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , , 1 1 , , 1 , 1 , 1 , , 1 , 1 , , , , , , , > , , > , > , > : , , , , , , : , > > > > > > > : : > > > > : : : : > : : : > : : : : : : : - : : : & : : : & : & : & : & & : & : & & & & & & & & & & & & & & # # & & & & # & & # & & # # & # & & # & & & & # # & # % # # # # @ # # # # @ # @ # # @ # @ @ @ @ @ @ @ @ @ @ @ @ @ @ X X @ @ @ @ + @ + @ + + + + + + + + @ + + + + + + + + O + o + + + O + X + O O O + O X + X O X O O O O O O O o . . . o . . . . o o o . . O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 2 2 1 1 2 1 2 2 1 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 , 1 1 1 1 1 , 1 , , 1 , , , 1 , 1 , , , , , , , , , , , > , , , , > : , : , > : , , > > , : > > > > > : > : > : : > > : : > : : : : : : - : - - : - : : : & : & & : : & : : & : & & - & - & & & & & & & & & & # & & & # & & & & # & & # & # & # & # # # # # # # # # # % # # # % # # # # # # # @ # @ # @ @ @ # @ @ @ # # @ @ @ @ @ @ @ @ @ @ @ + + @ + @ + + + @ + + + + + + + + + X + + + + + O + + O + O O + X O + + O + X o + + o O O O X O X X o . O o . o o o o . O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 2 1 1 1 1 2 2 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 , 1 1 , 1 1 1 , 1 , 1 1 , 1 , 1 , 1 , , , , , , , , , , , , , , , , : , , > , , , , > , > > , : : > > > > > > > > : > : > > : > : : > : : : : - : : : : - - : & & - : : - : & : & & & & & : & & - & & : & & & & & & & & & & & & & # & # & & & # & & # & # & & # & # # & & # # # # & & # # # # # # # # # # @ @ @ # @ @ @ @ @ @ X @ @ @ @ X @ @ X @ @ @ X @ + @ + + @ + + @ + + + + + + + + + + + O + + + + O O + + X + O + O O O + X O O O O O O O X O O X o o . . . . o . o . o . o . O O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 1 1 2 1 1 1 2 1 1 2 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 , 1 , 1 1 1 1 , 1 , 1 , , , 1 , , , , 1 , , , , , , , , , , , , , : , , : : , > , > , : , : > : > > : : > > > : > : : > : : : : : : : : : - : : : : : : : : : & : & : : & : : & : & & & & & & - & & & & & & & & & & & & & & # # & & # & & # & # & # & & # & & # # # # # # % # % # # # # # # @ # # # # @ @ @ # @ @ # @ @ @ @ @ X X @ + @ + @ @ + + @ + + + + + @ + + + + + + + + + + + X + + + + + X + + X O O + O O O O O O O + o O O O + O O . . O . o o . . . . . . . o O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 1 2 2 1 1 1 2 1 1 1 1 1 1 1 1 1 , 1 1 1 1 1 1 , , 1 , 1 , 1 , 1 1 , , , , 1 , , , , , , , , , , , , , , , , , : , , : , : > : , : , > > > : > > : : > : > : : : > : : : : : : : : : : : - : : & : & : & & : & & : & : & & & & - : & & & & & & & & & & & # & & & # # & & & # & # # & & & # & # # # # # # # & # # # # # # # # # # # # # # # # @ # @ # # @ @ @ @ @ @ @ @ # @ @ + @ @ @ + @ @ + + @ @ + + + @ + + + + + + + + + + + + O + X + + + X O + + O + X + + O + O O + X O O O O O . O . O . . o o . . . o o . . . O O ",
"2 2 2 2 2 2 2 2 1 2 2 2 2 , 2 2 1 2 2 1 1 2 2 1 1 1 2 1 1 2 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 , 1 , , 1 1 , , , , , , 1 , , , , , , , : , : , : , , , : , > > > : > , : > > > > > > > : : : > : > : : > : : : : : : : : & : : & : & : - : & : & & : : & : & : & - & & - - & & & & & & & & & & & & # & & & & & # & & & & # & & # & # & # & # # & & # % # # # % % # # # # # @ @ @ # # @ @ @ @ @ @ @ X # @ @ @ X @ @ @ @ + @ + @ @ @ @ + + + + @ + @ + + + + + + + + + + + + O + + O + + O O + + O O O + O O O o O O O O O O O . . o o . . . . . o o o . O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 1 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 , 1 1 , 1 1 , 1 , , 1 , 1 , , , 1 , , , , , , , , , , : , , , , , , > > , , > , , > , , : , > > > : > : > > > > : : > : > : : > : : : : : : : : : : : : - - : & : - : & & : & : & & - & & & - & & & & & & & # & & & & & & & # # & & # & # # & # # # & # & # # # & # # # # % % % % @ # # # # # # # # @ # @ # @ @ @ @ @ @ @ # @ @ # @ @ + + @ + @ + + + + @ + @ + + + + + + + + + + + + + + X + + O + + + O + + O O + O + O O O O O o O O O O O O . o . O . O o . . . o . o o O O ",
"2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 1 2 2 1 2 2 2 1 1 2 1 2 1 1 1 2 1 2 , 1 1 1 1 1 , 2 2 , 1 1 1 , 1 1 , , 1 1 , , 1 1 , , , , , 1 , , , , , , , , > , , > , > , > , : > , : , > : : , : > > > > > > : > > : : > : : : > : : : > : : : : : : - : - : - : & & : - & : : : & : & & : : & & & & & & : & & & & & & & & # & & & # & # & & & & # & # & # # & # # # & # & # # & # # # # # # # # # # # # @ @ - @ @ @ @ o - + o - @ @ @ @ @ @ @ + @ + + @ @ + @ + @ + @ + @ + + + + + + + + + + + + + + + + o + + X X + O + + X + + O O o O O O O O X X O X O X O o o O o O X X O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 2 2 2 1 1 2 2 1 2 1 1 2 1 2 1 1 2 , , 1 1 1 , 1 1 1 1 , 1 , , 1 , 1 1 , , 1 , 1 , , 1 , , , , , , , , , , > , > , , , , , , : , , , > , > , : , > : > > : > > : > : : > : > : : : : : : : : : - : - - : : : : - : : & & & : : : & & : & : & & & & & & & & & & & & & & & & & & & & # # & & # & # & # # & & # # # & # # # # # & # # # # # # # # @ @ # + # @ o @ - o @ @ + @ @ @ + @ + @ @ + @ @ + @ @ + + @ + + + + + + + + + + + + + + + + X + + + o + o + + O + O O X X O O O + O O O O O + O O o X O O O O X O O X O o o O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 2 2 1 1 1 2 , 2 1 2 1 1 1 2 , 1 , , 1 1 1 1 1 , 1 , 1 1 , 1 , 1 , , , , , , , , 1 , , , , > , , , > , > > , : , : : , , : > : , : : > > > > : > : > > : : : > : : : : : : : : : : : - : - : - : : & & : & & : & : & & & & & & : & & & & & & & & & & & & & & & # & & # # & & & # & # & # & & & # & & # # # # & # & # # # & # # # # # # # # + @ @ - @ - o @ @ @ @ @ @ @ + @ + @ @ + @ @ + + @ + @ + + + + + @ + + + + + + + + X X + + + + + + o o + O O O o + o X O O O + O O O O O O O X X o o O X o O X o o ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 1 1 2 1 1 1 1 2 1 1 1 1 1 , 2 1 1 1 1 1 1 1 1 1 , 1 1 1 1 1 , 1 , , 1 , , 1 , 1 , , , , , , , , , , , > , , , > , , , > , , > > , > > : , > > > > > > : > : : > > : : > : : > : : : : : - : : - : : : & : : - : & : & : & : & : : & & & & & & & & & & & & & & # & # & & & # & & & # & # & & # & # # # # # # # & # # # # # # # # # # # # # # # # @ + - @ @ @ o - + @ @ @ @ @ + o - + @ + @ @ + @ + + @ + + + @ @ + + + + + + + + + + + + + X + o + o + + O + + O + X + + o O O O O O O O O O O X X . . . . o O o O X . O O ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 1 2 2 1 1 2 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , 1 1 , 1 , 1 , 1 , , , , , , , , , , , , , > , , , , , > > , , : , , , : > > , > , : > > : > > : > > : > > : > : : : : : : > : : - : : : - : & : : & : & : & : & : & & : & & & & & & : & & & & & & & & & # & & & & & & # # & & & # & # & # & # & # # # # # & & # # # & # # # # # # # # # # @ + + - o + + @ o + @ @ + @ @ + + @ @ + @ @ + + @ @ @ + + + @ + + + + + + + + + + + X + + + + + X + X + O + O o O X + O O O O O O O O O O X O o . o O . . o o o . o . X O O . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 2 2 2 1 2 2 2 1 1 1 1 2 1 1 1 1 1 1 1 , 1 , , 1 1 1 1 1 , , 1 , 1 , , , , 1 1 , 1 1 1 , , , , , , , , , , : , , , > , , : , > , > , : : , : > > : > > > > : > > : : > : > > > : : : & : : : - : - - : - & : - - - : : & & : : & : & & : & & & & & & & & & # & & & & & & # & & & & & & # & & & # & # # # & & # & # # # # # # # # # # # # # # # # @ # - + o - - @ @ - - o @ @ @ + @ @ @ + + @ @ + @ + + + + @ + + + + + + + + + + + + + + + + X + X + X + O + O + + o O O + + + O + O O O O O o X O . X o o O o O X O o . . O . O ",
"y 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 1 2 1 1 1 1 1 2 1 2 , 1 1 1 2 2 1 1 1 1 1 1 1 1 1 , 1 1 1 1 , , 1 1 , 1 , , , , , , , , , , , , , , , : , > , , > > > > , > , > : , : : , : , , : : > > : : : : > : > : : : : : : : : : : : - : : - : : & : & : & & & : & & : & & : & & : & : & & & & & & & & & & # & # & # & # # # # & # # & & & & # # # & # & # & # & # # # # # # # # # # @ # # @ + @ @ @ @ @ @ o - @ @ @ @ + @ + @ @ + @ + @ + @ + @ + + @ + + + @ + + + + + + + X + + + + + X + O + O + o + + + X O O O + O O O O O O X O X . . . . o X O X . o . . O . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 1 1 2 2 1 2 1 2 1 2 1 1 1 1 1 2 , 1 1 1 1 1 1 1 1 1 , 1 , , 1 , 1 1 , , 1 , , , 1 , , , , , , > , , , , > , , , , , , , , , : , : > , > , , : , > : > > > : > > > > : : : : : : : > : : : : : : : : - : : - : - : - - & : : & & & : & : & & & & & & & & & & & & & & & & & & & & & & & & & # & & # # # # & & # # & # # # # # # # # # & # # # # # # @ # @ - @ @ @ @ @ @ @ @ + @ @ @ @ @ # + @ @ @ + + @ + @ + + + + @ + + + + + + + + + + + + + o + + + X + O + O + o X O O + O O O O O O O O O O O O o . o . O o X . . . . O O . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 1 2 2 1 2 1 1 1 1 2 1 2 , 1 2 1 2 , 1 1 2 , 1 1 1 1 1 , 1 1 1 , 1 , 1 1 , 1 1 , , , , , , , , , , > , > , , , > > > , : , , , > , > : , , : > : , > > : > : > > > : : : : > > : : : : : : : : & : & : : & : - - - - & : & : & : - & & & : & & & & & & & & & & & # & & # & & & # & # # & & # # & # & & # # & # # # # # # # # # # # # # # # # # # # # - o # @ @ @ @ @ + @ @ @ @ + @ + + @ @ @ + + + + @ + + + + + @ + + @ + + + + + + + + o + o + + + O + X + O O + + O + O + O + O O O O O O O O O O X . . . . o o . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 1 2 2 2 1 1 1 1 1 2 1 1 1 1 , 2 , 1 , , 1 1 , 1 1 , 1 , , 1 , , , , , , , 1 , 1 , , , , , , , , , > , , , > , , , : > , : > , : : , > > : > > : > : : : : > > > : : : : : : : : : : : : : : : : - : - - - - - & : & & & - - : & & & & & & & & & & & & & & & & & & # & & & & & # & & & # & # & # & # # & & # & # & # # # # # # # # # # @ # # - @ # @ @ @ @ @ @ @ @ @ @ @ @ + @ @ + @ @ @ @ @ @ + + @ + @ + + + + + + + + + + + + + + + + + o + X + + + + O O + O O O O O O O O O O X O O O X O X . . . . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 1 2 2 1 2 1 1 1 2 1 1 1 1 2 2 , 1 1 1 1 2 1 1 1 1 1 1 , 1 1 1 , , 1 1 , 1 , , 1 1 , 1 , , , , , , , , > , , , > > > > > : , : , > , , > , > > : : , > > > > : > > > : : : : > : : : : : : : : : : : & : : & - : & : - - - : : & - & & - & & & & - & & - & & & & & # & & & & & & # & # & & # & # # & # & # & # # & # # # # # & # & # # # # # # # # @ # @ o @ @ # # @ @ @ @ @ @ @ @ + @ @ + @ @ + @ + + + + + + + + + + + + + + + + + + o + + + o o + o + + O + O + O O O X + X + + O O + O O X O O O X O O X o o o o . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 1 1 2 2 1 1 2 1 2 1 2 1 2 1 1 1 1 2 , 1 , 1 1 1 1 , 1 1 , 1 , 1 , , 1 , , , , , , , , , , , , , , , > , , , > , , : , , > , : : , : , : , > : , : > : > : > : : > : > : > : : : : : : : : : : : : : : : & : : & - : & & : & : & - & : & : & & & & & & & & & & & & # & & # & & & & & & & # & # # & & # # & # # & # & # # # # # # # # # # # # @ # @ @ @ # @ @ @ @ @ @ @ @ @ @ @ @ + @ + + @ @ @ + @ @ + @ @ @ + @ + + + + + + + + + + + + + + + + + X + O + O + + + O O O O O O O X O O O O O O O X X O . . . . . o . o ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 1 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , , 1 , 1 , 1 , , 1 , 1 , 1 , , , , 1 , , , , , , , , > , > > > , , , : , , : , > : , > , : > > > : > : > > : > : : > : > : : > : : : : : : : & : & & : : & : & & - & : & : - & - & - & - & & - & & & & & & & & # & & & & # & & # & # & & # & # & # # & & # # # # & # # & # # # & # # # # # # # # # # @ # @ # @ @ @ @ @ @ + @ @ @ @ @ # @ + + + @ + + + + + + + + @ + @ @ + + + + + + + + o + + + X + + O + + O + O + O + O O X O X O O O X o o O O o O O X o . o . o . . . . ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 2 1 1 , 1 , 1 , 1 1 1 1 1 1 , , 1 1 , 1 , , 1 1 , , 1 , , , , , , , , , , , , , > , > , , : , , , > , : , : , > > : , > : : > : : > > : : : : : : : : : : : : : : : : : : : : - : : : : & : & - & & - & - & & & & & & & & & & & & & & & & & & & # & # & # # & # & # & & & # # & # # # # & # # & # # # # # # # # # @ @ @ # @ @ @ @ @ @ @ + @ @ @ @ + + @ + @ @ + @ + @ @ @ @ + + @ + + + + + + + + + + + o + + + o + + X O + O O + O O O O O O O + O O O O O O O o O O O o o o . o . . . . . ",
"2 2 y 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 1 1 2 1 2 2 2 1 1 1 2 , 2 1 1 1 1 1 1 2 , 1 1 , 1 1 1 1 1 1 , 1 1 , , , , , 1 , , , , , , , , , , , , , , , , > , , : , > , : : , , : , : : , , : : > > > > : > : : > : > > : : : : : : : : : & & : : & & : - - & : & & & - - & - & - & & & - & & & & & & & & & & # & & # & & & # # & & # & # & # # # & # # # & # # # # # # # # # # # # # # # # # # @ # @ @ @ @ @ @ @ + @ @ @ @ @ @ @ + @ @ + @ + + + @ + @ + + + + + + + + + + + + + + + + + + + X + + + X O O + + O X O O O + X O X O O O O O O O O O O . . o o . . o o ",
"2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 1 2 1 1 1 2 1 2 1 1 1 1 1 1 1 2 , 2 1 1 1 1 , 1 , , , 1 , , , 1 , 1 , , , , , , , , , , > , , > , > > , , > , , > , > > , , : , : > > : , : > > : : > > : > : : : : : : : : : : : - : : : : & : : : & : - - : : & : & - - - & & - - & & & & & & & & & & & & & & & & & # & # & # & & # & # & # # & # # # & # # # & # # # # # # # # # # # # # # @ @ # @ @ @ @ @ @ @ @ @ + @ + @ + @ + @ @ + @ @ + + @ + + + + + + + + + + + + + + o + + o + o + + X X + O + O + O + O + O X O O O O O O O O O O O . o . . . . . o o "
};

137
Linux/Config.c Normal file
View File

@ -0,0 +1,137 @@
/* 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
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "Linux.h"
#define GetValue(name, var) \
tmp = strstr(data, name); \
if (tmp != NULL) { \
tmp+=strlen(name); \
while ((*tmp == ' ') || (*tmp == '=')) tmp++; \
if (*tmp != '\n') sscanf(tmp, "%s", var); \
}
#define GetValuel(name, var) \
tmp = strstr(data, name); \
if (tmp != NULL) { \
tmp+=strlen(name); \
while ((*tmp == ' ') || (*tmp == '=')) tmp++; \
if (*tmp != '\n') sscanf(tmp, "%x", &var); \
}
#define SetValue(name, var) \
fprintf (f,"%s = %s\n", name, var);
#define SetValuel(name, var) \
fprintf (f,"%s = %x\n", name, var);
int LoadConfig(PcsxConfig *Conf) {
struct stat buf;
FILE *f;
int size;
char *data,*tmp;
if (stat(cfgfile, &buf) == -1) return -1;
size = buf.st_size;
f = fopen(cfgfile,"r");
if (f == NULL) return -1;
data = (char*)malloc(size);
if (data == NULL) return -1;
fread(data, 1, size, f);
fclose(f);
GetValue("Bios", Config.Bios);
GetValue("GS", Config.GS);
GetValue("PAD1", Config.PAD1);
GetValue("PAD2", Config.PAD2);
GetValue("SPU2", Config.SPU2);
GetValue("CDVD", Config.CDVD);
GetValue("DEV9", Config.DEV9);
GetValue("USB", Config.USB);
GetValue("FW", Config.FW);
GetValue("Mcd1", Config.Mcd1);
GetValue("Mcd2", Config.Mcd2);
GetValue("PluginsDir", Config.PluginsDir);
GetValue("BiosDir", Config.BiosDir);
GetValuel("Cpu", Config.Cpu);
GetValuel("PsxOut", Config.PsxOut);
GetValuel("RegCaching", Config.Regcaching);
GetValuel("Patch", Config.Patch);
GetValuel("VUrec", Config.VUrec);
// GetValuel("PadHack", Config.PadHack);
GetValuel("varLog", varLog);
Config.Lang[0] = 0;
GetValue("Lang", Config.Lang);
free(data);
#ifdef ENABLE_NLS
if (Config.Lang[0]) {
extern int _nl_msg_cat_cntr;
setenv("LANGUAGE", Config.Lang, 1);
++_nl_msg_cat_cntr;
}
#endif
return 0;
}
/////////////////////////////////////////////////////////
void SaveConfig() {
FILE *f;
f = fopen(cfgfile,"w");
if (f == NULL) return;
SetValue("Bios", Config.Bios);
SetValue("GS", Config.GS);
SetValue("PAD1", Config.PAD1);
SetValue("PAD2", Config.PAD2);
SetValue("SPU2", Config.SPU2);
SetValue("CDVD", Config.CDVD);
SetValue("DEV9", Config.DEV9);
SetValue("USB", Config.USB);
SetValue("FW", Config.FW);
SetValue("Mcd1", Config.Mcd1);
SetValue("Mcd2", Config.Mcd2);
SetValue("PluginsDir", Config.PluginsDir);
SetValue("BiosDir", Config.BiosDir);
SetValuel("Cpu", Config.Cpu);
SetValuel("PsxOut", Config.PsxOut);
SetValuel("RegCaching", Config.Regcaching);
SetValuel("Patch", Config.Patch);
SetValuel("VUrec", Config.VUrec);
// SetValuel("PadHack", Config.PadHack);
SetValuel("varLog", varLog);
SetValue("Lang", Config.Lang);
fclose(f);
return;
}

828
Linux/GladeCalls.c Normal file
View File

@ -0,0 +1,828 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtk/gtk.h>
#include "GladeCalls.h"
#include "GladeGui.h"
#include "GladeFuncs.h"
void
OnDestroy (GtkObject *object,
gpointer user_data)
{
}
void
OnFile_LoadElf (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnFile_Exit (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnEmu_Run (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnEmu_Reset (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnConf_Conf (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnConf_Gpu (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnConf_Pads (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnConf_Cpu (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnHelp_About (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnHelpAbout_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_Pad2Conf (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_Pad2Test (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_Pad2About (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_Pad1Conf (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_Pad1Test (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_Pad1About (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_GpuConf (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_GpuTest (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_GpuAbout (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_PluginsPath (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_BiosPath (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_Cancel (GtkButton *button,
gpointer user_data)
{
}
void
OnCpu_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnCpu_Cancel (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_GsConf (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_GsTest (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_GsAbout (GtkButton *button,
gpointer user_data)
{
}
void
OnConf_Gs (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnConfConf_Spu2Conf (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_Spu2Test (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_Spu2About (GtkButton *button,
gpointer user_data)
{
}
void
OnDebug_Debugger (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnDebug_Close (GtkButton *button,
gpointer user_data)
{
}
gboolean
OnDebug_ScrollBtn (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
return FALSE;
}
void
OnSetPC_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnSetPC_Cancel (GtkButton *button,
gpointer user_data)
{
}
void
OnDebug_SetPC (GtkButton *button,
gpointer user_data)
{
}
void
OnDebug_Step (GtkButton *button,
gpointer user_data)
{
}
void
OnDebug_Go (GtkButton *button,
gpointer user_data)
{
}
void
OnDebug_Log (GtkButton *button,
gpointer user_data)
{
}
void
OnSetBPA_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnSetBPA_Cancel (GtkButton *button,
gpointer user_data)
{
}
void
OnDebug_SetBPA (GtkButton *button,
gpointer user_data)
{
}
void
OnDebug_SetBPC (GtkButton *button,
gpointer user_data)
{
}
void
OnDebug_ClearBPs (GtkButton *button,
gpointer user_data)
{
}
void
OnDebug_DumpCode (GtkButton *button,
gpointer user_data)
{
}
void
OnDebug_RawDump (GtkButton *button,
gpointer user_data)
{
}
void
OnDumpC_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnDumpC_Cancel (GtkButton *button,
gpointer user_data)
{
}
void
OnDumpR_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnDumpR_Cancel (GtkButton *button,
gpointer user_data)
{
}
void
OnSetBPC_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnSetBPC_Cancel (GtkButton *button,
gpointer user_data)
{
}
void
OnDebug_Skip (GtkButton *button,
gpointer user_data)
{
}
void
OnDebug_Logging (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnLogging_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnLoggin_Cancel (GtkButton *button,
gpointer user_data)
{
}
void
OnLogging_Cancel (GtkButton *button,
gpointer user_data)
{
}
void
OnDebug_EEMode (GtkToggleButton *togglebutton,
gpointer user_data)
{
}
void
OnDebug_IOPMode (GtkToggleButton *togglebutton,
gpointer user_data)
{
}
void
OnConfConf_CdvdConf (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_CdvdTest (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_CdvdAbout (GtkButton *button,
gpointer user_data)
{
}
void
OnConf_Spu2 (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnConf_Cdvd (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnArguments_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnArguments_Cancel (GtkButton *button,
gpointer user_data)
{
}
void
OnEmu_Arguments (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_GtkMenuItem_Language_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
on_item1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnFile_RunCD (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnConfConf_Dev9Conf (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_Dev9Test (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_Dev9About (GtkButton *button,
gpointer user_data)
{
}
void
OnConf_Dev9 (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnDebug_memWrite32 (GtkButton *button,
gpointer user_data)
{
}
void
OnMemWrite_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnMemWrite32_Cancel (GtkButton *button,
gpointer user_data)
{
}
void
OnMemWrite32_Ok (GtkButton *button,
gpointer user_data)
{
}
void
OnStates_Load1 (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnStates_Load2 (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnStates_Load3 (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnStates_Load4 (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnStates_Load5 (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnStates_LoadOther (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnStates_Save1 (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnStates_Save2 (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnStates_Save3 (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnStates_Save4 (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnStates_Save5 (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnStates_SaveOther (GtkMenuItem *menuitem,
gpointer user_data)
{
}
void
OnConfConf_UsbConf (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_UsbTest (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_UsbAbout (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_FwConf (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_FwTest (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_FwAbout (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_FWConf (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_FWTest (GtkButton *button,
gpointer user_data)
{
}
void
OnConfConf_FWAbout (GtkButton *button,
gpointer user_data)
{
}

411
Linux/GladeCalls.h Normal file
View File

@ -0,0 +1,411 @@
#include <gtk/gtk.h>
void
OnDestroy (GtkObject *object,
gpointer user_data);
void
OnFile_LoadElf (GtkMenuItem *menuitem,
gpointer user_data);
void
OnFile_Exit (GtkMenuItem *menuitem,
gpointer user_data);
void
OnEmu_Run (GtkMenuItem *menuitem,
gpointer user_data);
void
OnEmu_Reset (GtkMenuItem *menuitem,
gpointer user_data);
void
OnConf_Conf (GtkMenuItem *menuitem,
gpointer user_data);
void
OnConf_Gpu (GtkMenuItem *menuitem,
gpointer user_data);
void
OnConf_Pads (GtkMenuItem *menuitem,
gpointer user_data);
void
OnConf_Cpu (GtkMenuItem *menuitem,
gpointer user_data);
void
OnHelp_About (GtkMenuItem *menuitem,
gpointer user_data);
void
OnHelpAbout_Ok (GtkButton *button,
gpointer user_data);
void
OnConfConf_Pad2Conf (GtkButton *button,
gpointer user_data);
void
OnConfConf_Pad2Test (GtkButton *button,
gpointer user_data);
void
OnConfConf_Pad2About (GtkButton *button,
gpointer user_data);
void
OnConfConf_Pad1Conf (GtkButton *button,
gpointer user_data);
void
OnConfConf_Pad1Test (GtkButton *button,
gpointer user_data);
void
OnConfConf_Pad1About (GtkButton *button,
gpointer user_data);
void
OnConfConf_GpuConf (GtkButton *button,
gpointer user_data);
void
OnConfConf_GpuTest (GtkButton *button,
gpointer user_data);
void
OnConfConf_GpuAbout (GtkButton *button,
gpointer user_data);
void
OnConfConf_PluginsPath (GtkButton *button,
gpointer user_data);
void
OnConfConf_BiosPath (GtkButton *button,
gpointer user_data);
void
OnConfConf_Ok (GtkButton *button,
gpointer user_data);
void
OnConfConf_Cancel (GtkButton *button,
gpointer user_data);
void
OnCpu_Ok (GtkButton *button,
gpointer user_data);
void
OnCpu_Cancel (GtkButton *button,
gpointer user_data);
void
OnConfConf_GsConf (GtkButton *button,
gpointer user_data);
void
OnConfConf_GsTest (GtkButton *button,
gpointer user_data);
void
OnConfConf_GsAbout (GtkButton *button,
gpointer user_data);
void
OnConf_Gs (GtkMenuItem *menuitem,
gpointer user_data);
void
OnConfConf_Spu2Conf (GtkButton *button,
gpointer user_data);
void
OnConfConf_Spu2Test (GtkButton *button,
gpointer user_data);
void
OnConfConf_Spu2About (GtkButton *button,
gpointer user_data);
void
OnDebug_Debugger (GtkMenuItem *menuitem,
gpointer user_data);
void
OnDebug_Close (GtkButton *button,
gpointer user_data);
gboolean
OnDebug_ScrollBtn (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data);
void
OnSetPC_Ok (GtkButton *button,
gpointer user_data);
void
OnSetPC_Cancel (GtkButton *button,
gpointer user_data);
void
OnDebug_SetPC (GtkButton *button,
gpointer user_data);
void
OnDebug_Step (GtkButton *button,
gpointer user_data);
void
OnDebug_Go (GtkButton *button,
gpointer user_data);
void
OnDebug_Log (GtkButton *button,
gpointer user_data);
void
OnSetBPA_Ok (GtkButton *button,
gpointer user_data);
void
OnSetBPA_Cancel (GtkButton *button,
gpointer user_data);
void
OnDebug_SetBPA (GtkButton *button,
gpointer user_data);
void
OnDebug_SetBPC (GtkButton *button,
gpointer user_data);
void
OnDebug_ClearBPs (GtkButton *button,
gpointer user_data);
void
OnDebug_DumpCode (GtkButton *button,
gpointer user_data);
void
OnDebug_RawDump (GtkButton *button,
gpointer user_data);
void
OnDumpC_Ok (GtkButton *button,
gpointer user_data);
void
OnDumpC_Cancel (GtkButton *button,
gpointer user_data);
void
OnDumpR_Ok (GtkButton *button,
gpointer user_data);
void
OnDumpR_Cancel (GtkButton *button,
gpointer user_data);
void
OnSetBPC_Ok (GtkButton *button,
gpointer user_data);
void
OnSetBPC_Cancel (GtkButton *button,
gpointer user_data);
void
OnDebug_Skip (GtkButton *button,
gpointer user_data);
void
OnDebug_Logging (GtkMenuItem *menuitem,
gpointer user_data);
void
OnLogging_Ok (GtkButton *button,
gpointer user_data);
void
OnLoggin_Cancel (GtkButton *button,
gpointer user_data);
void
OnLogging_Cancel (GtkButton *button,
gpointer user_data);
void
OnDebug_EEMode (GtkToggleButton *togglebutton,
gpointer user_data);
void
OnDebug_IOPMode (GtkToggleButton *togglebutton,
gpointer user_data);
void
OnConfConf_CdvdConf (GtkButton *button,
gpointer user_data);
void
OnConfConf_CdvdTest (GtkButton *button,
gpointer user_data);
void
OnConfConf_CdvdAbout (GtkButton *button,
gpointer user_data);
void
OnConf_Spu2 (GtkMenuItem *menuitem,
gpointer user_data);
void
OnConf_Cdvd (GtkMenuItem *menuitem,
gpointer user_data);
void
OnArguments_Ok (GtkButton *button,
gpointer user_data);
void
OnArguments_Cancel (GtkButton *button,
gpointer user_data);
void
OnEmu_Arguments (GtkMenuItem *menuitem,
gpointer user_data);
void
on_GtkMenuItem_Language_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
on_item1_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
OnFile_RunCD (GtkMenuItem *menuitem,
gpointer user_data);
void
OnConfConf_Dev9Conf (GtkButton *button,
gpointer user_data);
void
OnConfConf_Dev9Test (GtkButton *button,
gpointer user_data);
void
OnConfConf_Dev9About (GtkButton *button,
gpointer user_data);
void
OnConf_Dev9 (GtkMenuItem *menuitem,
gpointer user_data);
void
OnDebug_memWrite32 (GtkButton *button,
gpointer user_data);
void
OnMemWrite_Ok (GtkButton *button,
gpointer user_data);
void
OnMemWrite32_Cancel (GtkButton *button,
gpointer user_data);
void
OnMemWrite32_Ok (GtkButton *button,
gpointer user_data);
void
OnStates_Load1 (GtkMenuItem *menuitem,
gpointer user_data);
void
OnStates_Load2 (GtkMenuItem *menuitem,
gpointer user_data);
void
OnStates_Load3 (GtkMenuItem *menuitem,
gpointer user_data);
void
OnStates_Load4 (GtkMenuItem *menuitem,
gpointer user_data);
void
OnStates_Load5 (GtkMenuItem *menuitem,
gpointer user_data);
void
OnStates_LoadOther (GtkMenuItem *menuitem,
gpointer user_data);
void
OnStates_Save1 (GtkMenuItem *menuitem,
gpointer user_data);
void
OnStates_Save2 (GtkMenuItem *menuitem,
gpointer user_data);
void
OnStates_Save3 (GtkMenuItem *menuitem,
gpointer user_data);
void
OnStates_Save4 (GtkMenuItem *menuitem,
gpointer user_data);
void
OnStates_Save5 (GtkMenuItem *menuitem,
gpointer user_data);
void
OnStates_SaveOther (GtkMenuItem *menuitem,
gpointer user_data);
void
OnConfConf_UsbConf (GtkButton *button,
gpointer user_data);
void
OnConfConf_UsbTest (GtkButton *button,
gpointer user_data);
void
OnConfConf_UsbAbout (GtkButton *button,
gpointer user_data);
void
OnConfConf_FwConf (GtkButton *button,
gpointer user_data);
void
OnConfConf_FwTest (GtkButton *button,
gpointer user_data);
void
OnConfConf_FwAbout (GtkButton *button,
gpointer user_data);
void
OnConfConf_FWConf (GtkButton *button,
gpointer user_data);
void
OnConfConf_FWTest (GtkButton *button,
gpointer user_data);
void
OnConfConf_FWAbout (GtkButton *button,
gpointer user_data);

162
Linux/GladeFuncs.c Normal file
View File

@ -0,0 +1,162 @@
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <gtk/gtk.h>
#include "GladeFuncs.h"
/* This is an internally used function to check if a pixmap file exists. */
static gchar* check_file_exists (const gchar *directory,
const gchar *filename);
/* This is an internally used function to create pixmaps. */
static GtkWidget* create_dummy_pixmap (GtkWidget *widget);
GtkWidget*
lookup_widget (GtkWidget *widget,
const gchar *widget_name)
{
GtkWidget *parent, *found_widget;
for (;;)
{
if (GTK_IS_MENU (widget))
parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
else
parent = widget->parent;
if (parent == NULL)
break;
widget = parent;
}
found_widget = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget),
widget_name);
if (!found_widget)
g_warning ("Widget not found: %s", widget_name);
return found_widget;
}
/* This is a dummy pixmap we use when a pixmap can't be found. */
static char *dummy_pixmap_xpm[] = {
/* columns rows colors chars-per-pixel */
"1 1 1 1",
" c None",
/* pixels */
" "
};
/* This is an internally used function to create pixmaps. */
static GtkWidget*
create_dummy_pixmap (GtkWidget *widget)
{
GdkColormap *colormap;
GdkPixmap *gdkpixmap;
GdkBitmap *mask;
GtkWidget *pixmap;
colormap = gtk_widget_get_colormap (widget);
gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask,
NULL, dummy_pixmap_xpm);
if (gdkpixmap == NULL)
g_error ("Couldn't create replacement pixmap.");
pixmap = gtk_pixmap_new (gdkpixmap, mask);
gdk_pixmap_unref (gdkpixmap);
gdk_bitmap_unref (mask);
return pixmap;
}
static GList *pixmaps_directories = NULL;
/* Use this function to set the directory containing installed pixmaps. */
void
add_pixmap_directory (const gchar *directory)
{
pixmaps_directories = g_list_prepend (pixmaps_directories,
g_strdup (directory));
}
/* This is an internally used function to create pixmaps. */
GtkWidget*
create_pixmap (GtkWidget *widget,
const gchar *filename)
{
gchar *found_filename = NULL;
GdkColormap *colormap;
GdkPixmap *gdkpixmap;
GdkBitmap *mask;
GtkWidget *pixmap;
GList *elem;
if (!filename || !filename[0])
return create_dummy_pixmap (widget);
/* We first try any pixmaps directories set by the application. */
elem = pixmaps_directories;
while (elem)
{
found_filename = check_file_exists ((gchar*)elem->data, filename);
if (found_filename)
break;
elem = elem->next;
}
/* If we haven't found the pixmap, try the source directory. */
if (!found_filename)
{
found_filename = check_file_exists (".pixmaps", filename);
}
if (!found_filename)
{
g_warning (_("Couldn't find pixmap file: %s"), filename);
return create_dummy_pixmap (widget);
}
colormap = gtk_widget_get_colormap (widget);
gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask,
NULL, found_filename);
if (gdkpixmap == NULL)
{
g_warning (_("Error loading pixmap file: %s"), found_filename);
g_free (found_filename);
return create_dummy_pixmap (widget);
}
g_free (found_filename);
pixmap = gtk_pixmap_new (gdkpixmap, mask);
gdk_pixmap_unref (gdkpixmap);
gdk_bitmap_unref (mask);
return pixmap;
}
/* This is an internally used function to check if a pixmap file exists. */
gchar*
check_file_exists (const gchar *directory,
const gchar *filename)
{
gchar *full_filename;
struct stat s;
gint status;
full_filename = (gchar*) g_malloc (strlen (directory) + 1
+ strlen (filename) + 1);
strcpy (full_filename, directory);
strcat (full_filename, G_DIR_SEPARATOR_S);
strcat (full_filename, filename);
status = stat (full_filename, &s);
if (status == 0 && S_ISREG (s.st_mode))
return full_filename;
g_free (full_filename);
return NULL;
}

61
Linux/GladeFuncs.h Normal file
View File

@ -0,0 +1,61 @@
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtk/gtk.h>
/*
* Standard gettext macros.
*/
#ifdef ENABLE_NLS
# include <libintl.h>
# undef _
# define _(String) dgettext (PACKAGE, String)
# ifdef gettext_noop
# define N_(String) gettext_noop (String)
# else
# define N_(String) (String)
# endif
#else
# define textdomain(String) (String)
# define gettext(String) (String)
# define dgettext(Domain,Message) (Message)
# define dcgettext(Domain,Message,Type) (Message)
# define bindtextdomain(Domain,Directory) (Domain)
# define _(String) (String)
# define N_(String) (String)
#endif
/*
* Public Functions.
*/
/*
* This function returns a widget in a component created by Glade.
* Call it with the toplevel widget in the component (i.e. a window/dialog),
* or alternatively any widget in the component, and the name of the widget
* you want returned.
*/
GtkWidget* lookup_widget (GtkWidget *widget,
const gchar *widget_name);
/* get_widget() is deprecated. Use lookup_widget instead. */
#define get_widget lookup_widget
/* Use this function to set the directory containing installed pixmaps. */
void add_pixmap_directory (const gchar *directory);
/*
* Private Functions.
*/
/* This is used to create the pixmaps in the interface. */
GtkWidget* create_pixmap (GtkWidget *widget,
const gchar *filename);

3008
Linux/GladeGui.c Normal file

File diff suppressed because it is too large Load Diff

17
Linux/GladeGui.h Normal file
View File

@ -0,0 +1,17 @@
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
GtkWidget* create_MainWindow (void);
GtkWidget* create_AboutDlg (void);
GtkWidget* create_ConfDlg (void);
GtkWidget* create_CpuDlg (void);
GtkWidget* create_DebugWnd (void);
GtkWidget* create_SetPCDlg (void);
GtkWidget* create_SetBPADlg (void);
GtkWidget* create_SetBPCDlg (void);
GtkWidget* create_DumpCDlg (void);
GtkWidget* create_DumpRDlg (void);
GtkWidget* create_Logging (void);
GtkWidget* create_CmdLine (void);
GtkWidget* create_MemWrite32 (void);

1481
Linux/GtkGui.c Normal file

File diff suppressed because it is too large Load Diff

47
Linux/Linux.h Normal file
View File

@ -0,0 +1,47 @@
/* 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 __LINUX_H__
#define __LINUX_H__
#include "Common.h"
typedef struct {
char lang[256];
} _langs;
_langs *langs;
unsigned int langsMax;
extern int UseGui;
char cfgfile[256];
int LoadConfig();
void SaveConfig();
void StartGui();
void RunGui();
int Pcsx2Configure();
void InitLanguages();
char *GetLanguageNext();
void CloseLanguages();
void ChangeLanguage(char *lang);
#endif /* __LINUX_H__ */

327
Linux/LnxMain.c Normal file
View File

@ -0,0 +1,327 @@
/* 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
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <X11/keysym.h>
#include <gtk/gtk.h>
#include <signal.h>
#include <sys/types.h>
#include <dirent.h>
#include "Common.h"
#include "PsxCommon.h"
#include "Linux.h"
static char Pcsx2Help[] = {
"Pcsx2 " PCSX2_VERSION "\n"
" pcsx2 [options] [file]\n"
"\toptions:\n"
"\t-nogui\t\tDon't open GtkGui\n"
"\t-cfg FILE\tLoads desired configuration file (def:Pcsx2.cfg)\n"
"\t-psxout\t\tEnable psx output\n"
"\t-h -help\tThis help\n"
"\tfile\t\tLoads file\n"
};
int UseGui = 1;
int needReset = 1;
int main(int argc, char *argv[]) {
char *file = NULL;
char elfname[256];
char *lang;
int runcd=0;
int efile;
int i;
#ifdef ENABLE_NLS
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, "Langs");
textdomain(PACKAGE);
#endif
strcpy(cfgfile, "Pcsx2.cfg");
for (i=1; i<argc; i++) {
if (!strcmp(argv[i], "-nogui")) UseGui = 0;
else if (!strcmp(argv[i], "-runcd")) runcd = 1;
else if (!strcmp(argv[i], "-psxout")) Config.PsxOut = 1;
else if (!strcmp(argv[i], "-cfg")) strcpy(cfgfile, argv[++i]);
else if (!strcmp(argv[i], "-h") ||
!strcmp(argv[i], "-help")) { printf ("%s\n", Pcsx2Help); return 0; }
else file = argv[i];
}
if (UseGui) gtk_init(NULL, NULL);
#ifdef EMU_LOG
#ifndef LOG_STDOUT
mkdir("logs", 0755);
emuLog = fopen("logs/emuLog.txt","wb");
#else
emuLog = stdout;
#endif
if (emuLog == NULL) {
SysMessage("Can't open emuLog.txt");
return -1;
}
setvbuf(emuLog, NULL, _IONBF, 0);
#endif
if (LoadConfig() == -1) {
memset(&Config, 0, sizeof(Config));
strcpy(Config.BiosDir, "Bios/");
strcpy(Config.PluginsDir, "Plugins/");
Config.Cpu = 1;
SysMessage(_("Pcsx2 needs to be configured"));
Pcsx2Configure();
return 0;
}
if (Config.Lang[0] == 0) {
strcpy(Config.Lang, "en");
}
langs = (_langs*)malloc(sizeof(_langs));
strcpy(langs[0].lang, "en");
InitLanguages(); i=1;
while ((lang = GetLanguageNext()) != NULL) {
langs = (_langs*)realloc(langs, sizeof(_langs)*(i+1));
strcpy(langs[i].lang, lang);
i++;
}
CloseLanguages();
langsMax = i;
if (SysInit() == -1) return 1;
if (UseGui) {
StartGui();
return 0;
}
if (OpenPlugins() == -1) {
return 1;
}
SysReset();
cpuExecuteBios();
if (file) strcpy(elfname, file);
if (runcd)
efile=GetPS2ElfName(elfname);
if (efile)
loadElfFile(elfname);
Cpu->Execute();
return 0;
}
DIR *dir;
void InitLanguages() {
dir = opendir("Langs");
}
char *GetLanguageNext() {
struct dirent *ent;
if (dir == NULL) return NULL;
for (;;) {
ent = readdir(dir);
if (ent == NULL) return NULL;
if (!strcmp(ent->d_name, ".")) continue;
if (!strcmp(ent->d_name, "..")) continue;
break;
}
return ent->d_name;
}
void CloseLanguages() {
if (dir) closedir(dir);
}
void ChangeLanguage(char *lang) {
strcpy(Config.Lang, lang);
SaveConfig();
LoadConfig();
}
int StatesC = 0;
void KeyEvent(keyEvent* ev) {
char Text[256];
int ret;
if (ev == NULL) return;
if (ev->event == KEYRELEASE) {
GSkeyEvent(ev); return;
}
if (ev->event != KEYPRESS) return;
switch (ev->key) {
case XK_F1:
sprintf(Text, "sstates/%8.8X.%3.3d", ElfCRC, StatesC);
ret = SaveState(Text);
/* if (ret == 0)
sprintf(Text, _("*PCSX*: Saved State %d"), StatesC+1);
else sprintf(Text, _("*PCSX*: Error Saving State %d"), StatesC+1);
GPU_displayText(Text);
if (ShowPic) { ShowPic = 0; gpuShowPic(); }*/
break;
case XK_F2:
if (StatesC < 4) StatesC++;
else StatesC = 0;
SysPrintf("*PCSX2*: Selected State %ld\n", StatesC);
/* GPU_freeze(2, (GPUFreeze_t *)&StatesC);
if (ShowPic) { ShowPic = 0; gpuShowPic(); }*/
break;
case XK_F3:
sprintf (Text, "sstates/%8.8X.%3.3d", ElfCRC, StatesC);
ret = LoadState(Text);
/* if (ret == 0)
sprintf(Text, _("*PCSX*: Loaded State %d"), StatesC+1);
else sprintf(Text, _("*PCSX*: Error Loading State %d"), StatesC+1);
GPU_displayText(Text);*/
break;
case XK_F5:
// if (sio2.hackedRecv==0x1D100) sio2.hackedRecv=0x1100;
// else sio2.hackedRecv=0x1D100;
// SysPrintf("hackedRecv : %x\n", sio2.hackedRecv);
break;
case XK_F8:
GSmakeSnapshot("snap/");
break;
#ifdef CPU_LOG
case XK_F9:
Log = 1 - Log;
SysPrintf("Log : %d\n", Log);
break;
case XK_F10:
/* if (varLog & 0x40000000) varLog&=~0x40000000;
else varLog|= 0x40000000;
SysPrintf("varLog %x\n", varLog);*/
SysPrintf("hack\n");
psxSu32(0x30) = 0x20000;
// psMu32(0x8010c904) = 0;
break;
#endif
case XK_F11:
SysPrintf("Open\n");
cdCaseopen = 1;
break;
case XK_F12:
SysPrintf("Close\n");
cdCaseopen = 0;
break;
case XK_Escape:
signal(SIGINT, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
ClosePlugins();
if (!UseGui) exit(0);
RunGui();
break;
default:
GSkeyEvent(ev);
break;
}
}
int SysInit() {
mkdir("sstates", 0755);
mkdir("memcards", 0755);
cpuInit();
while (LoadPlugins() == -1) {
if (Pcsx2Configure() == 0) exit(1);
}
return 0;
}
void SysReset() {
cpuReset();
}
void SysClose() {
cpuShutdown();
ReleasePlugins();
if (emuLog != NULL) fclose(emuLog);
}
void SysPrintf(char *fmt, ...) {
va_list list;
char msg[512];
va_start(list, fmt);
vsprintf(msg, fmt, list);
va_end(list);
if (Config.PsxOut) { printf("%s", msg); fflush(stdout); }
#ifdef EMU_LOG
fprintf(emuLog, "%s", msg);
#endif
}
void *SysLoadLibrary(char *lib) {
return dlopen(lib, RTLD_NOW);
}
void *SysLoadSym(void *lib, char *sym) {
return dlsym(lib, sym);
}
char *SysLibError() {
return dlerror();
}
void SysCloseLibrary(void *lib) {
dlclose(lib);
}
void SysUpdate() {
KeyEvent(PAD1keyEvent());
KeyEvent(PAD1keyEvent());
}
void SysRunGui() {
RunGui();
}
void *SysMmap(uptr base, u32 size) {
return mmap((uptr*)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
}
void SysMunmap(uptr base, u32 size) {
munmap((uptr*)base, size);
}

16
Linux/Makefile.am Normal file
View File

@ -0,0 +1,16 @@
LIBS = "-L/usr/lib/ $(QTDIR)/lib/ -L/usr/X11R6/lib/ -lqt-mt -lXext -lX11 -lpthread"
INCLUDES = "-I$(QTDIR)/include"
noinst_PROGRAMS = pcsx2
# the application source, library search path, and link libraries
pcsx2_SOURCES = LnxMain.c
pcsx2_LDFLAGS =
LDADD = ../libpcsx2.a ../DebugTools/libDebugTools.a ../IPU/libIPU.a ../x86/ix86/libix86.a ../pcl/libpcl.a ../RDebug/libRDebug.a ../zlib/libpcsx2zlib.a
if X86_64
LDADD += ../x86/ix86-64/libx86-64recomp.a
else
LDADD += ../x86/ix86-32/libx86-32recomp.a
endif

1475
MMI.c Normal file

File diff suppressed because it is too large Load Diff

23
Makefile.am Normal file
View File

@ -0,0 +1,23 @@
AUTOMAKE_OPTIONS = foreign
INCLUDES = -IDebugTools/ -Ix86/
noinst_LIBRARIES = libpcsx2.a
libpcsx2_a_SOURCES = \
CdRom.c Decode_XA.h Mdec.h PsxBios.h R3000A.c Vif.h \
CdRom.h EEregs.h memcpy_amd.cpp PsxCommon.h R3000A.h VU0.c \
CDVD.c Elfheader.c Memory.c PsxCounters.c R5900.c VU0.h \
CDVD.h Elfheader.h Memory.h PsxCounters.h R5900.h VU0micro.c \
CDVDiso.c FiFo.c Misc.c PsxDma.c Sif.c VU1micro.c \
CDVDisodrv.c FPU2.cpp Misc.h PsxDma.h Sifcmd.h VUflags.c \
CDVDisodrv.h FPU.c MMI.c PsxGPU.c Sif.h VUflags.h \
CDVDiso.h GS.cpp Patch.c PsxGPU.h Sio.c VU.h \
CDVDlib.h GS.h Patch.h PsxHw.c Sio.h VUmicro.h \
Common.h Hw.c Plugins.c PsxHw.h SPR.c VUops.c \
COP0.c Hw.h Plugins.h PsxInterpreter.c SPR.h VUops.h \
COP0.h Interpreter.c PS2Edefs.h PsxMem.c System.h \
Counters.c InterTables.c PS2Etypes.h PsxMem.h Vif.c \
Counters.h InterTables.h PsxBios2.h PsxSio2.c VifDma.c \
Decode_XA.c Mdec.c PsxBios.c PsxSio2.h VifDma.h
SUBDIRS = . DebugTools IPU pcl RDebug zlib tinyxml x86 Linux

521
Mdec.c Normal file
View File

@ -0,0 +1,521 @@
/* 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
*/
/* This code was based on the FPSE v0.08 Mdec decoder*/
#include <stdio.h>
#include <string.h>
#include "PsxCommon.h"
#include "Mdec.h"
#define FIXED
#define CONST_BITS 8
#define PASS1_BITS 2
#define FIX_1_082392200 (277)
#define FIX_1_414213562 (362)
#define FIX_1_847759065 (473)
#define FIX_2_613125930 (669)
#define MULTIPLY(var,const) (DESCALE((var) * (const), CONST_BITS))
#define DEQUANTIZE(coef,quantval) (coef)
#define DESCALE(x,n) ((x)>>(n))
#define RANGE(n) (n)
#define DCTSIZE 8
#define DCTSIZE2 64
static void idct1(int *block)
{
int val = RANGE(DESCALE(block[0], PASS1_BITS+3));
int i;
for(i=0;i<DCTSIZE2;i++) block[i]=val;
}
void idct(int *block,int k)
{
int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
int z5, z10, z11, z12, z13;
int *ptr;
int i;
if (!k) { idct1(block); return; }
ptr = block;
for (i = 0; i< DCTSIZE; i++,ptr++) {
if ((ptr[DCTSIZE*1] | ptr[DCTSIZE*2] | ptr[DCTSIZE*3] |
ptr[DCTSIZE*4] | ptr[DCTSIZE*5] | ptr[DCTSIZE*6] |
ptr[DCTSIZE*7]) == 0) {
ptr[DCTSIZE*0] =
ptr[DCTSIZE*1] =
ptr[DCTSIZE*2] =
ptr[DCTSIZE*3] =
ptr[DCTSIZE*4] =
ptr[DCTSIZE*5] =
ptr[DCTSIZE*6] =
ptr[DCTSIZE*7] =
ptr[DCTSIZE*0];
continue;
}
z10 = ptr[DCTSIZE*0] + ptr[DCTSIZE*4];
z11 = ptr[DCTSIZE*0] - ptr[DCTSIZE*4];
z13 = ptr[DCTSIZE*2] + ptr[DCTSIZE*6];
z12 = MULTIPLY(ptr[DCTSIZE*2] - ptr[DCTSIZE*6], FIX_1_414213562) - z13;
tmp0 = z10 + z13;
tmp3 = z10 - z13;
tmp1 = z11 + z12;
tmp2 = z11 - z12;
z13 = ptr[DCTSIZE*3] + ptr[DCTSIZE*5];
z10 = ptr[DCTSIZE*3] - ptr[DCTSIZE*5];
z11 = ptr[DCTSIZE*1] + ptr[DCTSIZE*7];
z12 = ptr[DCTSIZE*1] - ptr[DCTSIZE*7];
z5 = MULTIPLY(z12 - z10, FIX_1_847759065);
tmp7 = z11 + z13;
tmp6 = MULTIPLY(z10, FIX_2_613125930) + z5 - tmp7;
tmp5 = MULTIPLY(z11 - z13, FIX_1_414213562) - tmp6;
tmp4 = MULTIPLY(z12, FIX_1_082392200) - z5 + tmp5;
ptr[DCTSIZE*0] = (tmp0 + tmp7);
ptr[DCTSIZE*7] = (tmp0 - tmp7);
ptr[DCTSIZE*1] = (tmp1 + tmp6);
ptr[DCTSIZE*6] = (tmp1 - tmp6);
ptr[DCTSIZE*2] = (tmp2 + tmp5);
ptr[DCTSIZE*5] = (tmp2 - tmp5);
ptr[DCTSIZE*4] = (tmp3 + tmp4);
ptr[DCTSIZE*3] = (tmp3 - tmp4);
}
ptr = block;
for (i = 0; i < DCTSIZE; i++ ,ptr+=DCTSIZE) {
if ((ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5] | ptr[6] |
ptr[7]) == 0) {
ptr[0] =
ptr[1] =
ptr[2] =
ptr[3] =
ptr[4] =
ptr[5] =
ptr[6] =
ptr[7] =
RANGE(DESCALE(ptr[0], PASS1_BITS+3));;
continue;
}
z10 = ptr[0] + ptr[4];
z11 = ptr[0] - ptr[4];
z13 = ptr[2] + ptr[6];
z12 = MULTIPLY(ptr[2] - ptr[6], FIX_1_414213562) - z13;
tmp0 = z10 + z13;
tmp3 = z10 - z13;
tmp1 = z11 + z12;
tmp2 = z11 - z12;
z13 = ptr[3] + ptr[5];
z10 = ptr[3] - ptr[5];
z11 = ptr[1] + ptr[7];
z12 = ptr[1] - ptr[7];
z5 = MULTIPLY(z12 - z10, FIX_1_847759065);
tmp7 = z11 + z13;
tmp6 = MULTIPLY(z10, FIX_2_613125930) + z5 - tmp7;
tmp5 = MULTIPLY(z11 - z13, FIX_1_414213562) - tmp6;
tmp4 = MULTIPLY(z12, FIX_1_082392200) - z5 + tmp5;
ptr[0] = RANGE(DESCALE(tmp0 + tmp7, PASS1_BITS+3));;
ptr[7] = RANGE(DESCALE(tmp0 - tmp7, PASS1_BITS+3));;
ptr[1] = RANGE(DESCALE(tmp1 + tmp6, PASS1_BITS+3));;
ptr[6] = RANGE(DESCALE(tmp1 - tmp6, PASS1_BITS+3));;
ptr[2] = RANGE(DESCALE(tmp2 + tmp5, PASS1_BITS+3));;
ptr[5] = RANGE(DESCALE(tmp2 - tmp5, PASS1_BITS+3));;
ptr[4] = RANGE(DESCALE(tmp3 + tmp4, PASS1_BITS+3));;
ptr[3] = RANGE(DESCALE(tmp3 - tmp4, PASS1_BITS+3));;
}
}
unsigned short* rl2blk(int *blk,unsigned short *mdec_rl);
void iqtab_init(int *iqtab,unsigned char *iq_y);
void round_init(void);
void yuv2rgb24(int *blk,unsigned char *image);
void yuv2rgb15(int *blk,unsigned short *image);
struct {
unsigned long command;
unsigned long status;
unsigned short *rl;
int rlsize;
} mdec;
int iq_y[DCTSIZE2],iq_uv[DCTSIZE2];
void mdecInit(void) {
mdec.rl = (u16*)&psxM[0x100000];
mdec.command = 0;
mdec.status = 0;
round_init();
}
void mdecWrite0(u32 data) {
#ifdef CDR_LOG
CDR_LOG("mdec0 write %lx\n", data);
#endif
mdec.command = data;
if ((data&0xf5ff0000)==0x30000000) {
mdec.rlsize = data&0xffff;
}
}
void mdecWrite1(u32 data) {
#ifdef CDR_LOG
CDR_LOG("mdec1 write %lx\n", data);
#endif
if (data&0x80000000) { // mdec reset
round_init();
// mdecInit();
}
}
u32 mdecRead0(void) {
#ifdef CDR_LOG
CDR_LOG("mdec0 read %lx\n", mdec.command);
#endif
return mdec.command;
}
// mdec status:
#define MDEC_BUSY 0x20000000
#define MDEC_DREQ 0x18000000
#define MDEC_FIFO 0xc0000000
#define MDEC_RGB24 0x02000000
#define MDEC_STP 0x00800000
u32 mdecRead1(void) {
#ifdef CDR_LOG
CDR_LOG("mdec1 read %lx\n", mdec.status);
#endif
return mdec.status;
}
void psxDma0(u32 adr, u32 bcr, u32 chcr) {
int cmd = mdec.command;
int size;
#ifdef CDR_LOG
CDR_LOG("DMA0 %lx %lx %lx\n", adr, bcr, chcr);
#endif
if (chcr!=0x01000201) return;
size = (bcr>>16)*(bcr&0xffff);
if (cmd==0x60000000) {
} else
if (cmd==0x40000001) {
u8 *p = (u8*)PSXM(adr);
iqtab_init(iq_y,p);
iqtab_init(iq_uv,p+64);
} else
if ((cmd&0xf5ff0000)==0x30000000) {
mdec.rl = (u16*)PSXM(adr);
}
else {
}
HW_DMA0_CHCR &= ~0x01000000;
psxDmaInterrupt(0);
}
void psxDma1(u32 adr, u32 bcr, u32 chcr) {
int blk[DCTSIZE2*6];
unsigned short *image;
int size;
#ifdef CDR_LOG
CDR_LOG("DMA1 %lx %lx %lx (cmd = %lx)\n", adr, bcr, chcr, mdec.command);
#endif
if (chcr!=0x01000200) return;
size = (bcr>>16)*(bcr&0xffff);
image = (u16*)PSXM(adr);
if (mdec.command&0x08000000) {
for (;size>0;size-=(16*16)/2,image+=(16*16)) {
mdec.rl = rl2blk(blk,mdec.rl);
yuv2rgb15(blk,image);
}
} else {
for (;size>0;size-=(24*16)/2,image+=(24*16)) {
mdec.rl = rl2blk(blk,mdec.rl);
yuv2rgb24(blk,(u8 *)image);
}
}
HW_DMA1_CHCR &= ~0x01000000;
psxDmaInterrupt(1);
}
#define RUNOF(a) ((a)>>10)
#define VALOF(a) (((int)(a)<<(32-10))>>(32-10))
static int zscan[DCTSIZE2] = {
0 ,1 ,8 ,16,9 ,2 ,3 ,10,
17,24,32,25,18,11,4 ,5 ,
12,19,26,33,40,48,41,34,
27,20,13,6 ,7 ,14,21,28,
35,42,49,56,57,50,43,36,
29,22,15,23,30,37,44,51,
58,59,52,45,38,31,39,46,
53,60,61,54,47,55,62,63
};
static int aanscales[DCTSIZE2] = {
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
};
void iqtab_init(int *iqtab,unsigned char *iq_y)
{
#define CONST_BITS14 14
#define IFAST_SCALE_BITS 2
int i;
for(i=0;i<DCTSIZE2;i++) {
iqtab[i] =iq_y[i] *aanscales[zscan[i]]>>(CONST_BITS14-IFAST_SCALE_BITS);
}
}
#define NOP 0xfe00
unsigned short* rl2blk(int *blk,unsigned short *mdec_rl) {
int i,k,q_scale,rl;
int *iqtab;
memset (blk, 0, 6*DCTSIZE2*4);
iqtab = iq_uv;
for(i=0;i<6;i++) { // decode blocks (Cr,Cb,Y1,Y2,Y3,Y4)
if (i>1) iqtab = iq_y;
// zigzag transformation
rl = *mdec_rl++;
q_scale = RUNOF(rl);
blk[0] = iqtab[0]*VALOF(rl);
for(k = 0;;) {
rl = *mdec_rl++;
if (rl==NOP) break;
k += RUNOF(rl)+1; // skip level zero-coefficients
if (k > 63) break;
blk[zscan[k]] = (VALOF(rl) * iqtab[k] * q_scale) / 8; // / 16;
}
// blk[0] = (blk[0] * iq_t[0] * 8) / 16;
// for(int j=1;j<64;j++)
// blk[j] = blk[j] * iq_t[j] * q_scale;
// idct
idct(blk,k+1);
blk+=DCTSIZE2;
}
return mdec_rl;
}
#ifdef FIXED
#define MULR(a) ((((int)0x0000059B) * (a)) >> 10)
#define MULG(a) ((((int)0xFFFFFEA1) * (a)) >> 10)
#define MULG2(a) ((((int)0xFFFFFD25) * (a)) >> 10)
#define MULB(a) ((((int)0x00000716) * (a)) >> 10)
#else
#define MULR(a) ((int)((float)1.40200 * (a)))
#define MULG(a) ((int)((float)-0.3437 * (a)))
#define MULG2(a) ((int)((float)-0.7143 * (a)))
#define MULB(a) ((int)((float)1.77200 * (a)))
#endif
#define MAKERGB15(r,g,b) ( (((r)>>3)<<10)|(((g)>>3)<<5)|((b)>>3) )
#define ROUND(c) roundtbl[((c)+128+256)]//&0x3ff]
/*#define ROUND(c) round(c+128)
int round(int r) {
if (r<0) return 0;
if (r>255) return 255;
return r;
}*/
#define RGB15(n, Y) \
image[n] = MAKERGB15(ROUND(Y + R),ROUND(Y + G),ROUND(Y + B));
#define RGB15BW(n, Y) \
image[n] = MAKERGB15(ROUND(Y),ROUND(Y),ROUND(Y));
#define RGB24(n, Y) \
image[n+2] = ROUND(Y + R); \
image[n+1] = ROUND(Y + G); \
image[n+0] = ROUND(Y + B);
#define RGB24BW(n, Y) \
image[n+2] = ROUND(Y); \
image[n+1] = ROUND(Y); \
image[n+0] = ROUND(Y);
unsigned char roundtbl[256*3];
void round_init(void) {
int i;
for(i=0;i<256;i++) {
roundtbl[i]=0;
roundtbl[i+256]=i;
roundtbl[i+512]=255;
}
}
void yuv2rgb15(int *blk,unsigned short *image) {
int x,y;
int *Yblk = blk+DCTSIZE2*2;
int Cb,Cr,R,G,B;
int *Cbblk = blk;
int *Crblk = blk+DCTSIZE2;
if (!(Config.Mdec&0x1))
for (y=0;y<16;y+=2,Crblk+=4,Cbblk+=4,Yblk+=8,image+=24) {
if (y==8) Yblk+=DCTSIZE2;
for (x=0;x<4;x++,image+=2,Crblk++,Cbblk++,Yblk+=2) {
Cr = *Crblk;
Cb = *Cbblk;
R = MULR(Cr);
G = MULG(Cb) + MULG2(Cr);
B = MULB(Cb);
RGB15(0, Yblk[0]);
RGB15(1, Yblk[1]);
RGB15(16, Yblk[8]);
RGB15(17, Yblk[9]);
Cr = *(Crblk+4);
Cb = *(Cbblk+4);
R = MULR(Cr);
G = MULG(Cb) + MULG2(Cr);
B = MULB(Cb);
RGB15(8, Yblk[DCTSIZE2+0]);
RGB15(9, Yblk[DCTSIZE2+1]);
RGB15(24, Yblk[DCTSIZE2+8]);
RGB15(25, Yblk[DCTSIZE2+9]);
}
} else
for (y=0;y<16;y+=2,Yblk+=8,image+=24) {
if (y==8) Yblk+=DCTSIZE2;
for (x=0;x<4;x++,image+=2,Yblk+=2) {
RGB15BW(0, Yblk[0]);
RGB15BW(1, Yblk[1]);
RGB15BW(16, Yblk[8]);
RGB15BW(17, Yblk[9]);
RGB15BW(8, Yblk[DCTSIZE2+0]);
RGB15BW(9, Yblk[DCTSIZE2+1]);
RGB15BW(24, Yblk[DCTSIZE2+8]);
RGB15BW(25, Yblk[DCTSIZE2+9]);
}
}
}
void yuv2rgb24(int *blk,unsigned char *image) {
int x,y;
int *Yblk = blk+DCTSIZE2*2;
int Cb,Cr,R,G,B;
int *Cbblk = blk;
int *Crblk = blk+DCTSIZE2;
if (!(Config.Mdec&0x1))
for (y=0;y<16;y+=2,Crblk+=4,Cbblk+=4,Yblk+=8,image+=24*3) {
if (y==8) Yblk+=DCTSIZE2;
for (x=0;x<4;x++,image+=6,Crblk++,Cbblk++,Yblk+=2) {
Cr = *Crblk;
Cb = *Cbblk;
R = MULR(Cr);
G = MULG(Cb) + MULG2(Cr);
B = MULB(Cb);
RGB24(0, Yblk[0]);
RGB24(1*3, Yblk[1]);
RGB24(16*3, Yblk[8]);
RGB24(17*3, Yblk[9]);
Cr = *(Crblk+4);
Cb = *(Cbblk+4);
R = MULR(Cr);
G = MULG(Cb) + MULG2(Cr);
B = MULB(Cb);
RGB24(8*3, Yblk[DCTSIZE2+0]);
RGB24(9*3, Yblk[DCTSIZE2+1]);
RGB24(24*3, Yblk[DCTSIZE2+8]);
RGB24(25*3, Yblk[DCTSIZE2+9]);
}
} else
for (y=0;y<16;y+=2,Yblk+=8,image+=24*3) {
if (y==8) Yblk+=DCTSIZE2;
for (x=0;x<4;x++,image+=6,Yblk+=2) {
RGB24BW(0, Yblk[0]);
RGB24BW(1*3, Yblk[1]);
RGB24BW(16*3, Yblk[8]);
RGB24BW(17*3, Yblk[9]);
RGB24BW(8*3, Yblk[DCTSIZE2+0]);
RGB24BW(9*3, Yblk[DCTSIZE2+1]);
RGB24BW(24*3, Yblk[DCTSIZE2+8]);
RGB24BW(25*3, Yblk[DCTSIZE2+9]);
}
}
}
int mdecFreeze(gzFile f, int Mode) {
gzfreeze(&mdec, sizeof(mdec));
gzfreezel(iq_y);
gzfreezel(iq_uv);
return 0;
}

31
Mdec.h Normal file
View File

@ -0,0 +1,31 @@
/* 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 __MDEC_H__
#define __MDEC_H__
void mdecInit();
void mdecWrite0(u32 data);
void mdecWrite1(u32 data);
u32 mdecRead0();
u32 mdecRead1();
void psxDma0(u32 madr, u32 bcr, u32 chcr);
void psxDma1(u32 madr, u32 bcr, u32 chcr);
int mdecFreeze(gzFile f, int Mode);
#endif /* __MDEC_H__ */

3056
Memory.c Normal file

File diff suppressed because it is too large Load Diff

263
Memory.h Normal file
View File

@ -0,0 +1,263 @@
/* 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
*/
//////////
// Rewritten by zerofrog to add os virtual memory
//////////
#ifndef __MEMORY_H__
#define __MEMORY_H__
//#define ENABLECACHE
#ifdef WIN32_VIRTUAL_MEM
typedef struct _PSMEMORYMAP
{
ULONG_PTR* aPFNs, *aVFNs;
} PSMEMORYMAP;
#define TRANSFORM_ADDR(memaddr) ( ((u32)(memaddr)>=0x40000000) ? ((memaddr)&~0xa0000000) : (memaddr) )
//new memory model
#define PS2MEM_BASE_ 0x18000000
#define PS2MEM_PSX_ (PS2MEM_BASE_+0x1c000000)
#define PS2MEM_BASE ((u8*)PS2MEM_BASE_)
#define PS2MEM_HW ((u8*)((u32)PS2MEM_BASE+0x10000000))
#define PS2MEM_ROM ((u8*)((u32)PS2MEM_BASE+0x1fc00000))
#define PS2MEM_ROM1 ((u8*)((u32)PS2MEM_BASE+0x1e000000))
#define PS2MEM_ROM2 ((u8*)((u32)PS2MEM_BASE+0x1e400000))
#define PS2MEM_EROM ((u8*)((u32)PS2MEM_BASE+0x1e040000))
#define PS2MEM_PSX ((u8*)PS2MEM_PSX_)
#define PS2MEM_SCRATCH ((u8*)((u32)PS2MEM_BASE+0x50000000))
#define PS2MEM_VU0MICRO ((u8*)((u32)PS2MEM_BASE+0x11000000))
#define PS2MEM_VU0MEM ((u8*)((u32)PS2MEM_BASE+0x11004000))
#define PS2MEM_VU1MICRO ((u8*)((u32)PS2MEM_BASE+0x11008000))
#define PS2MEM_VU1MEM ((u8*)((u32)PS2MEM_BASE+0x1100c000))
// function for mapping memory
#define PS2MEM_PSXHW ((u8*)((u32)PS2MEM_BASE+0x1f800000))
#define PS2MEM_PSXHW4 ((u8*)((u32)PS2MEM_BASE+0x1f400000))
#define PS2MEM_GS ((u8*)((u32)PS2MEM_BASE+0x12000000))
#define PS2MEM_DEV9 ((u8*)((u32)PS2MEM_BASE+0x14000000))
#define PS2MEM_SPU2 ((u8*)((u32)PS2MEM_BASE+0x1f900000))
#define PS2MEM_SPU2_ ((u8*)((u32)PS2MEM_BASE+0x1f000000)) // ?
#define PS2MEM_B80 ((u8*)((u32)PS2MEM_BASE+0x18000000))
#define PS2MEM_BA0 ((u8*)((u32)PS2MEM_BASE+0x1a000000))
#define PSM(mem) (PS2MEM_BASE + TRANSFORM_ADDR(mem))
#else
extern u8 *psM; //32mb Main Ram
extern u8 *psR; //4mb rom area
extern u8 *psR1; //256kb rom1 area (actually 196kb, but can't mask this)
extern u8 *psR2; // 0x00080000
extern u8 *psER; // 0x001C0000
extern u8 *psS; //0.015 mb, scratch pad
#define PS2MEM_BASE psM
#define PS2MEM_HW psH
#define PS2MEM_ROM psR
#define PS2MEM_ROM1 psR1
#define PS2MEM_ROM2 psR2
#define PS2MEM_EROM psER
#define PS2MEM_SCRATCH psS
extern u8 g_RealGSMem[0x2000];
#define PS2MEM_GS g_RealGSMem
//#define _PSM(mem) (memLUTR[(mem) >> 12] == 0 ? NULL : (void*)(memLUTR[(mem) >> 12] + ((mem) & 0xfff)))
#define PSM(mem) ((void*)(memLUTR[(mem) >> 12] + ((mem) & 0xfff)))
#define FREE(ptr) _aligned_free(ptr)
extern uptr *memLUTR;
extern uptr *memLUTW;
extern uptr *memLUTRK;
extern uptr *memLUTWK;
extern uptr *memLUTRU;
extern uptr *memLUTWU;
#endif
#define psMs8(mem) (*(s8 *)&PS2MEM_BASE[(mem) & 0x1ffffff])
#define psMs16(mem) (*(s16*)&PS2MEM_BASE[(mem) & 0x1ffffff])
#define psMs32(mem) (*(s32*)&PS2MEM_BASE[(mem) & 0x1ffffff])
#define psMs64(mem) (*(s64*)&PS2MEM_BASE[(mem) & 0x1ffffff])
#define psMu8(mem) (*(u8 *)&PS2MEM_BASE[(mem) & 0x1ffffff])
#define psMu16(mem) (*(u16*)&PS2MEM_BASE[(mem) & 0x1ffffff])
#define psMu32(mem) (*(u32*)&PS2MEM_BASE[(mem) & 0x1ffffff])
#define psMu64(mem) (*(u64*)&PS2MEM_BASE[(mem) & 0x1ffffff])
#define psRs8(mem) (*(s8 *)&PS2MEM_ROM[(mem) & 0x3fffff])
#define psRs16(mem) (*(s16*)&PS2MEM_ROM[(mem) & 0x3fffff])
#define psRs32(mem) (*(s32*)&PS2MEM_ROM[(mem) & 0x3fffff])
#define psRs64(mem) (*(s64*)&PS2MEM_ROM[(mem) & 0x3fffff])
#define psRu8(mem) (*(u8 *)&PS2MEM_ROM[(mem) & 0x3fffff])
#define psRu16(mem) (*(u16*)&PS2MEM_ROM[(mem) & 0x3fffff])
#define psRu32(mem) (*(u32*)&PS2MEM_ROM[(mem) & 0x3fffff])
#define psRu64(mem) (*(u64*)&PS2MEM_ROM[(mem) & 0x3fffff])
#define psR1s8(mem) (*(s8 *)&PS2MEM_ROM1[(mem) & 0x3ffff])
#define psR1s16(mem) (*(s16*)&PS2MEM_ROM1[(mem) & 0x3ffff])
#define psR1s32(mem) (*(s32*)&PS2MEM_ROM1[(mem) & 0x3ffff])
#define psR1s64(mem) (*(s64*)&PS2MEM_ROM1[(mem) & 0x3ffff])
#define psR1u8(mem) (*(u8 *)&PS2MEM_ROM1[(mem) & 0x3ffff])
#define psR1u16(mem) (*(u16*)&PS2MEM_ROM1[(mem) & 0x3ffff])
#define psR1u32(mem) (*(u32*)&PS2MEM_ROM1[(mem) & 0x3ffff])
#define psR1u64(mem) (*(u64*)&PS2MEM_ROM1[(mem) & 0x3ffff])
#define psR2s8(mem) (*(s8 *)&PS2MEM_ROM2[(mem) & 0x3ffff])
#define psR2s16(mem) (*(s16*)&PS2MEM_ROM2[(mem) & 0x3ffff])
#define psR2s32(mem) (*(s32*)&PS2MEM_ROM2[(mem) & 0x3ffff])
#define psR2s64(mem) (*(s64*)&PS2MEM_ROM2[(mem) & 0x3ffff])
#define psR2u8(mem) (*(u8 *)&PS2MEM_ROM2[(mem) & 0x3ffff])
#define psR2u16(mem) (*(u16*)&PS2MEM_ROM2[(mem) & 0x3ffff])
#define psR2u32(mem) (*(u32*)&PS2MEM_ROM2[(mem) & 0x3ffff])
#define psR2u64(mem) (*(u64*)&PS2MEM_ROM2[(mem) & 0x3ffff])
#define psERs8(mem) (*(s8 *)&PS2MEM_EROM[(mem) & 0x3ffff])
#define psERs16(mem) (*(s16*)&PS2MEM_EROM[(mem) & 0x3ffff])
#define psERs32(mem) (*(s32*)&PS2MEM_EROM[(mem) & 0x3ffff])
#define psERs64(mem) (*(s64*)&PS2MEM_EROM[(mem) & 0x3ffff])
#define psERu8(mem) (*(u8 *)&PS2MEM_EROM[(mem) & 0x3ffff])
#define psERu16(mem) (*(u16*)&PS2MEM_EROM[(mem) & 0x3ffff])
#define psERu32(mem) (*(u32*)&PS2MEM_EROM[(mem) & 0x3ffff])
#define psERu64(mem) (*(u64*)&PS2MEM_EROM[(mem) & 0x3ffff])
#define psSs8(mem) (*(s8 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSs16(mem) (*(s16*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSs32(mem) (*(s32*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSs64(mem) (*(s64*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSu8(mem) (*(u8 *)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSu16(mem) (*(u16*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSu32(mem) (*(u32*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSu64(mem) (*(u64*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define PSMs8(mem) (*(s8 *)PSM(mem))
#define PSMs16(mem) (*(s16*)PSM(mem))
#define PSMs32(mem) (*(s32*)PSM(mem))
#define PSMs64(mem) (*(s64*)PSM(mem))
#define PSMu8(mem) (*(u8 *)PSM(mem))
#define PSMu16(mem) (*(u16*)PSM(mem))
#define PSMu32(mem) (*(u32*)PSM(mem))
#define PSMu64(mem) (*(u64*)PSM(mem))
int memInit();
void memReset();
void memSetKernelMode();
void memSetSupervisorMode();
void memSetUserMode();
void memSetPageAddr(u32 vaddr, u32 paddr);
void memClearPageAddr(u32 vaddr);
void memShutdown();
int memRead8(u32 mem, u8 *out);
int memRead8RS(u32 mem, u64 *out);
int memRead8RU(u32 mem, u64 *out);
int memRead16(u32 mem, u16 *out);
int memRead16RS(u32 mem, u64 *out);
int memRead16RU(u32 mem, u64 *out);
int memRead32(u32 mem, u32 *out);
int memRead32RS(u32 mem, u64 *out);
int memRead32RU(u32 mem, u64 *out);
int memRead64(u32 mem, u64 *out);
int memRead128(u32 mem, u64 *out);
void memWrite8 (u32 mem, u8 value);
void memWrite16(u32 mem, u16 value);
void memWrite32(u32 mem, u32 value);
void memWrite64(u32 mem, u64 value);
void memWrite128(u32 mem, u64 *value);
// recMemConstRead8, recMemConstRead16, recMemConstRead32 return 1 if a call was made, 0 otherwise
u8 recMemRead8();
u16 recMemRead16();
u32 recMemRead32();
void recMemRead64(u64 *out);
void recMemRead128(u64 *out);
// returns 1 if mem should be cleared
void recMemWrite8();
void recMemWrite16();
void recMemWrite32();
void recMemWrite64();
void recMemWrite128();
// VM only functions
#ifdef WIN32_VIRTUAL_MEM
void _eeReadConstMem8(int mmreg, u32 mem, int sign);
void _eeReadConstMem16(int mmreg, u32 mem, int sign);
void _eeReadConstMem32(int mmreg, u32 mem);
void _eeReadConstMem128(int mmreg, u32 mem);
void _eeWriteConstMem8(u32 mem, int mmreg);
void _eeWriteConstMem16(u32 mem, int mmreg);
void _eeWriteConstMem32(u32 mem, int mmreg);
void _eeWriteConstMem64(u32 mem, int mmreg);
void _eeWriteConstMem128(u32 mem, int mmreg);
void _eeMoveMMREGtoR(int to, int mmreg);
// extra ops
void _eeWriteConstMem16OP(u32 mem, int mmreg, int op);
void _eeWriteConstMem32OP(u32 mem, int mmreg, int op);
int recMemConstRead8(u32 x86reg, u32 mem, u32 sign);
int recMemConstRead16(u32 x86reg, u32 mem, u32 sign);
int recMemConstRead32(u32 x86reg, u32 mem);
void recMemConstRead64(u32 mem, int mmreg);
void recMemConstRead128(u32 mem, int xmmreg);
int recMemConstWrite8(u32 mem, int mmreg);
int recMemConstWrite16(u32 mem, int mmreg);
int recMemConstWrite32(u32 mem, int mmreg);
int recMemConstWrite64(u32 mem, int mmreg);
int recMemConstWrite128(u32 mem, int xmmreg);
#else
#define _eeReadConstMem8 0&&
#define _eeReadConstMem16 0&&
#define _eeReadConstMem32 0&&
#define _eeReadConstMem128 0&&
#define _eeWriteConstMem8 0&&
#define _eeWriteConstMem16 0&&
#define _eeWriteConstMem32 0&&
#define _eeWriteConstMem64 0&&
#define _eeWriteConstMem128 0&&
#define _eeMoveMMREGtoR 0&&
// extra ops
#define _eeWriteConstMem16OP 0&&
#define _eeWriteConstMem32OP 0&&
#define recMemConstRead8 0&&
#define recMemConstRead16 0&&
#define recMemConstRead32 0&&
#define recMemConstRead64 0&&
#define recMemConstRead128 0&&
#define recMemConstWrite8 0&&
#define recMemConstWrite16 0&&
#define recMemConstWrite32 0&&
#define recMemConstWrite64 0&&
#define recMemConstWrite128 0&&
#endif
#endif

895
Misc.c Normal file
View File

@ -0,0 +1,895 @@
/* 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
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/stat.h>
#include <ctype.h>
#include "Common.h"
#include "PsxCommon.h"
#include "CDVDisodrv.h"
#include "VUmicro.h"
#ifdef __WIN32__
#include "RDebug/deci2.h"
#endif
#include "GS.h"
u32 dwSaveVersion = 0x7a30000e;
extern u32 s_iLastCOP0Cycle;
extern u32 s_iLastPERFCycle[2];
extern int g_psxWriteOk;
PcsxConfig Config;
u32 BiosVersion;
char CdromId[12];
char *LabelAuthors = { N_(
"PCSX2 a PS2 emulator\n\n"
"written by:\n"
"saqib, refraction, zerofrog,\n"
"shadow, linuzappz, florin,\n"
"nachbrenner, auMatt, loser, \n"
"alexey silinov, goldfinger,\n"
"\n"
"Webmasters: CKemu, Falcon4ever")
};
char *LabelGreets = { N_(
"Greets to: Bobbi, Keith, CpUMasteR, Nave, Snake785, Raziel\n"
"Special thanks to: Sjeep, Dreamtime, F|RES, BGnome, MrBrown, \n"
"Seta-San, Skarmeth, blackd_wd, _Demo_\n"
"\n"
"Credits: Hiryu && Sjeep for their libcdvd (iso parsing and filesystem driver code)\n"
"\n"
"Some betatester/support dudes: Belmont, bositman, ChaosCode, CKemu, crushtest,"
"falcon4ever, GeneralPlot, jegHegy, parotaku, Prafull, Razorblade, Rudy_X, Seta-san")
};
static struct {
char *name;
u32 size;
} ioprps[]={
{"IOPRP14", 43845},
{"IOPRP142", 48109},
{"IOPRP143", 58317},
{"IOPRP144", 58525},
{"IOPRP15", 82741},
{"IOPRP151", 82917},
{"IOPRP153", 82949},
{"IOPRP16", 91909},
{"IOPRP165", 98901},
{"IOPRP20", 109809},
{"IOPRP202", 110993},
{"IOPRP205", 119797},
{"IOPRP21", 126857},
{"IOPRP211", 129577},
{"IOPRP213", 129577},
{"IOPRP214", 140945},
{"IOPRP22", 199257},
{"IOPRP221", 196937},
{"IOPRP222", 198233},
{"IOPRP224", 201065},
{"IOPRP23", 230329},
{"IOPRP234", 247641},
{"IOPRP24", 251065},
{"IOPRP241", 251049},
{"IOPRP242", 252409},
{"IOPRP243", 253201},
{"IOPRP250", 264897},
{"IOPRP252", 265233},
{"IOPRP253", 267217},
{"IOPRP254", 264449},
{"IOPRP255", 264449},
{"IOPRP260", 248945},
{"IOPRP270", 249121},
{"IOPRP271", 266817},
{"IOPRP280", 269889},
{"IOPRP300", 275345},
{"DNAS280", 272753},
{"DNAS270", 251729},
{"DNAS271", 268977},
{"DNAS300", 278641},
{"DNAS280", 272705},
{"DNAS255", 264945},
{NULL, 0}
};
void GetRPCVersion(char *ioprp, char *rpcver){
char *p=ioprp; int i;
struct TocEntry te;
if (p && (CDVD_findfile(p+strlen("cdromN:"), &te) != -1)){
for (i=0; ioprps[i].size>0; i++)
if (te.fileSize==ioprps[i].size)
break;
if (ioprps[i].size>0)
p=ioprps[i].name;
}
if (p && (p=strstr(p, "IOPRP")+strlen("IOPRP"))){
for (i=0;(i<4) && p && (*p>='0') && (*p<='9');i++, p++) rpcver[i]=*p;
for ( ; i<4 ;i++ ) rpcver[i]='0';
}
}
u32 GetBiosVersion() {
unsigned int fileOffset=0;
char *ROMVER;
char vermaj[8];
char vermin[8];
struct romdir *rd;
u32 version;
int i;
for (i=0; i<512*1024; i++) {
rd = (struct romdir*)&psRu8(i);
if (strncmp(rd->fileName, "RESET", 5) == 0)
break; /* found romdir */
}
if (i == 512*1024) return -1;
while(strlen(rd->fileName) > 0){
if (strcmp(rd->fileName, "ROMVER") == 0){ // found romver
ROMVER = &psRs8(fileOffset);
strncpy(vermaj, ROMVER+ 0, 2); vermaj[2] = 0;
strncpy(vermin, ROMVER+ 2, 2); vermin[2] = 0;
version = strtol(vermaj, (char**)NULL, 0) << 8;
version|= strtol(vermin, (char**)NULL, 0);
return version;
}
if ((rd->fileSize % 0x10)==0)
fileOffset += rd->fileSize;
else
fileOffset += (rd->fileSize + 0x10) & 0xfffffff0;
rd++;
}
return -1;
}
//2002-09-22 (Florin)
int IsBIOS(char *filename, char *description){
struct stat buf;
char Bios[260], ROMVER[14+1], zone[12+1];
FILE *fp;
unsigned int fileOffset=0, found=FALSE;
struct romdir rd;
strcpy(Bios, Config.BiosDir);
strcat(Bios, filename);
if (stat(Bios, &buf) == -1) return FALSE;
fp = fopen(Bios, "rb");
if (fp == NULL) return FALSE;
while ((ftell(fp)<512*1024) && (fread(&rd, DIRENTRY_SIZE, 1, fp)==1))
if (strcmp(rd.fileName, "RESET") == 0)
break; /* found romdir */
if ((strcmp(rd.fileName, "RESET") != 0) || (rd.fileSize == 0)) {
fclose(fp);
return FALSE; //Unable to locate ROMDIR structure in file or a ioprpXXX.img
}
while(strlen(rd.fileName) > 0){
if (strcmp(rd.fileName, "ROMVER") == 0){ // found romver
unsigned int filepos=ftell(fp);
fseek(fp, fileOffset, SEEK_SET);
if (fread(&ROMVER, 14, 1, fp) == 0) break;
fseek(fp, filepos, SEEK_SET);//go back
switch(ROMVER[4]){
case 'T':sprintf(zone, "T10K "); break;
case 'X':sprintf(zone, "Test ");break;
case 'J':sprintf(zone, "Japan "); break;
case 'A':sprintf(zone, "USA "); break;
case 'E':sprintf(zone, "Europe"); break;
case 'H':sprintf(zone, "HK "); break;
case 'P':sprintf(zone, "Free "); break;
case 'C':sprintf(zone, "China "); break;
default: sprintf(zone, "%c ",ROMVER[4]); break;//shoudn't show
}
sprintf(description, "%s vXX.XX(XX/XX/XXXX) %s", zone,
ROMVER[5]=='C'?"Console":ROMVER[5]=='D'?"Devel":"");
strncpy(description+ 8, ROMVER+ 0, 2);//ver major
strncpy(description+11, ROMVER+ 2, 2);//ver minor
strncpy(description+14, ROMVER+12, 2);//day
strncpy(description+17, ROMVER+10, 2);//month
strncpy(description+20, ROMVER+ 6, 4);//year
found = TRUE;
}
if ((rd.fileSize % 0x10)==0)
fileOffset += rd.fileSize;
else
fileOffset += (rd.fileSize + 0x10) & 0xfffffff0;
if (fread(&rd, DIRENTRY_SIZE, 1, fp)==0) break;
}
fileOffset-=((rd.fileSize + 0x10) & 0xfffffff0) - rd.fileSize;
fclose(fp);
if (found) {
char percent[6];
if (buf.st_size<(int)fileOffset){
sprintf(percent, " %d%%", buf.st_size*100/(int)fileOffset);
strcat(description, percent);//we force users to have correct bioses,
//not that lame scph10000 of 513KB ;-)
}
return TRUE;
}
return FALSE; //fail quietly
}
// LOAD STUFF
#define ISODCL(from, to) (to - from + 1)
struct iso_directory_record {
char length [ISODCL (1, 1)]; /* 711 */
char ext_attr_length [ISODCL (2, 2)]; /* 711 */
char extent [ISODCL (3, 10)]; /* 733 */
char size [ISODCL (11, 18)]; /* 733 */
char date [ISODCL (19, 25)]; /* 7 by 711 */
char flags [ISODCL (26, 26)];
char file_unit_size [ISODCL (27, 27)]; /* 711 */
char interleave [ISODCL (28, 28)]; /* 711 */
char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
unsigned char name_len [ISODCL (33, 33)]; /* 711 */
char name [1];
};
#define READTRACK(lsn) \
if (CDVDreadTrack(lsn, CDVD_MODE_2352) == -1) return -1; \
buf = CDVDgetBuffer(); if (buf == NULL) return -1;
int LoadCdrom() {
return 0;
}
int CheckCdrom() {
u8 *buf;
READTRACK(16);
strncpy(CdromId, (char*)buf+52, 10);
return 0;
}
int GetPS2ElfName(char *name){
FILE *fp;
int f;
char buffer[256];//if a file is longer...it should be shorter :D
char *pos;
static struct TocEntry tocEntry;
int i;
CDVDFS_init();
// check if the file exists
if (CDVD_findfile("SYSTEM.CNF;1", &tocEntry) != TRUE){
SysPrintf("SYSTEM.CNF not found\n");
return 0;//could not find; not a PS/PS2 cdvd
}
f=CDVDFS_open("SYSTEM.CNF;1", 1);
CDVDFS_read(f, buffer, 256);
CDVDFS_close(f);
buffer[tocEntry.fileSize]='\0';
// SysPrintf(
// "---------------------SYSTEM.CNF---------------------\n"
// "%s"
// "----------------------------------------------------\n", buffer);
pos=strstr(buffer, "BOOT2");
if (pos==NULL){
pos=strstr(buffer, "BOOT");
if (pos==NULL) {
SysPrintf("This is not a PS2 game!\n");
return 0;
}
return 1;
}
pos+=strlen("BOOT2");
while (pos && *pos && pos<=&buffer[255]
&& (*pos<'A' || (*pos>'Z' && *pos<'a') || *pos>'z'))
pos++;
if (!pos || *pos==0)
return 0;
sscanf(pos, "%s", name);
//SysPrintf("ELF name: '%s'\n", name);
if (strncmp("cdrom0:\\", name, 8) == 0) {
strncpy(CdromId, name+8, 11); CdromId[11] = 0;
}
// inifile_read(CdromId);
fp = fopen("System.map", "r");
if (fp) {
u32 addr;
SysPrintf("Loading System.map\n", fp);
while (!feof(fp)) {
fseek(fp, 8, SEEK_CUR);
buffer[0] = '0'; buffer[1] = 'x';
for (i=2; i<10; i++) buffer[i] = fgetc(fp); buffer[i] = 0;
addr = strtoul(buffer, (char**)NULL, 0);
fseek(fp, 3, SEEK_CUR);
for (i=0; i<256; i++) {
buffer[i] = fgetc(fp);
if (buffer[i] == '\n' || buffer[i] == 0) break;
}
if (buffer[i] == 0) break;
buffer[i] = 0;
disR5900AddSym(addr, buffer);
}
fclose(fp);
}
return 2;
}
/*#define PSX_EXE 1
#define CPE_EXE 2
#define COFF_EXE 3
#define INVALID_EXE 4
static int PSXGetFileType(FILE *f) {
unsigned long current;
unsigned long mybuf[2048];
EXE_HEADER *exe_hdr;
FILHDR *coff_hdr;
current = ftell(f);
fseek(f,0L,SEEK_SET);
fread(mybuf,2048,1,f);
fseek(f,current,SEEK_SET);
exe_hdr = (EXE_HEADER *)mybuf;
if (memcmp(exe_hdr->id,"PS-X EXE",8)==0)
return PSX_EXE;
if (mybuf[0]=='C' && mybuf[1]=='P' && mybuf[2]=='E')
return CPE_EXE;
coff_hdr = (FILHDR *)mybuf;
if (coff_hdr->f_magic == 0x0162)
return COFF_EXE;
return INVALID_EXE;
}
int Load(char *ExePath) {
FILE *tmpFile;
EXE_HEADER tmpHead;
int type;
strcpy(CdromId, "SLUS_999.99");
tmpFile = fopen(ExePath,"rb");
if (tmpFile == NULL) { SysMessage("Error opening file: %s", ExePath); return 0; }
type = PSXGetFileType(tmpFile);
switch (type) {
case PSX_EXE:
fread(&tmpHead,sizeof(EXE_HEADER),1,tmpFile);
fseek(tmpFile, 0x800, SEEK_SET);
fread((void *)PSXM(tmpHead.t_addr), tmpHead.t_size,1,tmpFile);
fclose(tmpFile);
psxRegs.pc = tmpHead.pc0;
psxRegs.GPR.n.gp = tmpHead.gp0;
psxRegs.GPR.n.sp = tmpHead.s_addr;
if (psxRegs.GPR.n.sp == 0) psxRegs.GPR.n.sp = 0x801fff00;
break;
case CPE_EXE:
SysMessage("Pcsx found that you wanna use a CPE file. CPE files not support yet");
break;
case COFF_EXE:
SysMessage("Pcsx found that you wanna use a COFF file.COFF files not support yet");
break;
case INVALID_EXE:
SysMessage("This file is not a psx file");
break;
}
return 1;
}
*/
u16 logProtocol;
u8 logSource;
int connected=0;
#define SYNC_LOGGING
void __Log(char *fmt, ...) {
#ifdef EMU_LOG
va_list list;
static char tmp[2024]; //hm, should be enough
va_start(list, fmt);
#ifdef __WIN32__
if (connected && logProtocol>=0 && logProtocol<0x10){
vsprintf(tmp, fmt, list);
sendTTYP(logProtocol, logSource, tmp);
}//else //!!!!! is disabled, so the text goes to ttyp AND log
#endif
{
#ifndef LOG_STDOUT
if (varLog & 0x80000000) {
vsprintf(tmp, fmt, list);
SysPrintf(tmp);
} else if( emuLog != NULL ) {
vfprintf(emuLog, fmt, list);
}
#else //i assume that this will not be used (Florin)
vsprintf(tmp, fmt, list);
SysPrintf(tmp);
#endif
}
va_end(list);
#endif
}
// STATES
#define STATE_VERSION "STv6"
const char Pcsx2Header[32] = STATE_VERSION " PCSX2 v" PCSX2_VERSION;
#define _PS2Esave(type) \
if (type##freeze(FREEZE_SIZE, &fP) == -1) { \
gzclose(f); \
return -1; \
} \
fP.data = (s8*)malloc(fP.size); \
if (fP.data == NULL) return -1; \
\
if (type##freeze(FREEZE_SAVE, &fP) == -1) { \
gzclose(f); \
return -1; \
} \
\
gzwrite(f, &fP.size, sizeof(fP.size)); \
if (fP.size) { \
gzwrite(f, fP.data, fP.size); \
free(fP.data); \
}
#define _PS2Eload(type) \
gzread(f, &fP.size, sizeof(fP.size)); \
if (fP.size) { \
fP.data = (s8*)malloc(fP.size); \
if (fP.data == NULL) return -1; \
gzread(f, fP.data, fP.size); \
} \
if (type##freeze(FREEZE_LOAD, &fP) == -1) { \
/* skip */ \
/*if (fP.size) free(fP.data); \
gzclose(f); \
return -1;*/ \
} \
if (fP.size) free(fP.data);
extern void gsWaitGS();
extern u32 g_nextBranchCycle, g_psxNextBranchCycle;
int SaveState(char *file) {
gzFile f;
freezeData fP;
gsWaitGS();
SysPrintf("SaveState: %s\n", file);
f = gzopen(file, "wb");
if (f == NULL) return -1;
gzwrite(f, &dwSaveVersion, 4);
gzwrite(f, PS2MEM_BASE, 0x02000000); // 32 MB main memory
gzwrite(f, PS2MEM_ROM, 0x00400000); // 4 mb rom memory
gzwrite(f, PS2MEM_ROM1,0x00040000); // 256kb rom1 memory
gzwrite(f, PS2MEM_SCRATCH, 0x00004000); // scratch pad
gzwrite(f, PS2MEM_HW, 0x00010000); // hardware memory
gzwrite(f, (void*)&cpuRegs, sizeof(cpuRegs)); // cpu regs + COP0
gzwrite(f, (void*)&psxRegs, sizeof(psxRegs)); // iop regs]
gzwrite(f, (void*)&fpuRegs, sizeof(fpuRegs)); // fpu regs
gzwrite(f, (void*)&tlb, sizeof(tlb)); // tlbs
gzwrite(f, &EEsCycle, sizeof(EEsCycle));
gzwrite(f, &EEoCycle, sizeof(EEoCycle));
gzwrite(f, &IOPoCycle, sizeof(IOPoCycle));
gzwrite(f, &g_nextBranchCycle, sizeof(g_nextBranchCycle));
gzwrite(f, &g_psxNextBranchCycle, sizeof(g_psxNextBranchCycle));
gzwrite(f, &s_iLastCOP0Cycle, sizeof(s_iLastCOP0Cycle));
gzwrite(f, s_iLastPERFCycle, sizeof(u32)*2);
gzwrite(f, &g_psxWriteOk, sizeof(g_psxWriteOk));
//gzwrite(f, (void*)&ipuRegs, sizeof(IPUregisters)); // ipu regs
//hope didn't forgot any cpu....
rcntFreeze(f, 1);
gsFreeze(f, 1);
vu0Freeze(f, 1);
vu1Freeze(f, 1);
vif0Freeze(f, 1);
vif1Freeze(f, 1);
sifFreeze(f, 1);
ipuFreeze(f, 1);
// iop now
gzwrite(f, psxM, 0x00200000); // 2 MB main memory
//gzwrite(f, psxP, 0x00010000); // pralell memory
gzwrite(f, psxH, 0x00010000); // hardware memory
//gzwrite(f, psxS, 0x00010000); // sif memory
sioFreeze(f, 1);
cdrFreeze(f, 1);
cdvdFreeze(f, 1);
psxRcntFreeze(f, 1);
//mdecFreeze(f, 1);
sio2Freeze(f, 1);
SysPrintf("Saving GS\n");
_PS2Esave(GS);
SysPrintf("Saving SPU2\n");
_PS2Esave(SPU2);
SysPrintf("Saving DEV9\n");
_PS2Esave(DEV9);
SysPrintf("Saving USB\n");
_PS2Esave(USB);
SysPrintf("Saving ok\n");
gzclose(f);
return 0;
}
extern u32 dumplog;
extern u32 s_vucount;
int LoadState(char *file) {
gzFile f;
freezeData fP;
int i;
u32 OldProtect;
u32 dwVer;
#ifdef _DEBUG
s_vucount = 0;
//dumplog |= 2;
#endif
SysPrintf("LoadState: %s\n", file);
f = gzopen(file, "rb");
if (f == NULL) return -1;
gzread(f, &dwVer, 4);
if( dwVer != dwSaveVersion ) {
if( dwVer != 0x7a30000d ) {
gzclose(f);
SysPrintf("Save state wrong version\n");
return 0;
}
}
// stop and reset the system first
gsWaitGS();
for (i=0; i<48; i++) ClearTLB(i);
Cpu->Reset();
recResetVU0();
recResetVU1();
psxCpu->Reset();
SysPrintf("Loading memory\n");
#ifdef WIN32_VIRTUAL_MEM
// make sure can write
VirtualProtect(PS2MEM_ROM, 0x00400000, PAGE_READWRITE, &OldProtect);
VirtualProtect(PS2MEM_ROM1, 0x00040000, PAGE_READWRITE, &OldProtect);
VirtualProtect(PS2MEM_ROM2, 0x00080000, PAGE_READWRITE, &OldProtect);
VirtualProtect(PS2MEM_EROM, 0x001C0000, PAGE_READWRITE, &OldProtect);
#endif
gzread(f, PS2MEM_BASE, 0x02000000); // 32 MB main memory
gzread(f, PS2MEM_ROM, 0x00400000); // 4 mb rom memory
gzread(f, PS2MEM_ROM1,0x00040000); // 256kb rom1 memory
gzread(f, PS2MEM_SCRATCH, 0x00004000); // scratch pad
#ifdef WIN32_VIRTUAL_MEM
VirtualProtect(PS2MEM_ROM, 0x00400000, PAGE_READONLY, &OldProtect);
VirtualProtect(PS2MEM_ROM1, 0x00040000, PAGE_READONLY, &OldProtect);
VirtualProtect(PS2MEM_ROM2, 0x00080000, PAGE_READONLY, &OldProtect);
VirtualProtect(PS2MEM_EROM, 0x001C0000, PAGE_READONLY, &OldProtect);
#endif
gzread(f, PS2MEM_HW, 0x00010000); // hardware memory
SysPrintf("Loading structs\n");
gzread(f, (void*)&cpuRegs, sizeof(cpuRegs)); // cpu regs + COP0
gzread(f, (void*)&psxRegs, sizeof(psxRegs)); // iop regs
gzread(f, (void*)&fpuRegs, sizeof(fpuRegs)); // fpu regs
gzread(f, (void*)&tlb, sizeof(tlb)); // tlbs
gzread(f, &EEsCycle, sizeof(EEsCycle));
gzread(f, &EEoCycle, sizeof(EEoCycle));
gzread(f, &IOPoCycle, sizeof(IOPoCycle));
gzread(f, &g_nextBranchCycle, sizeof(g_nextBranchCycle));
gzread(f, &g_psxNextBranchCycle, sizeof(g_psxNextBranchCycle));
gzread(f, &s_iLastCOP0Cycle, sizeof(s_iLastCOP0Cycle));
if( dwVer >= 0x7a30000e ) {
gzread(f, s_iLastPERFCycle, sizeof(u32)*2);
}
gzread(f, &g_psxWriteOk, sizeof(g_psxWriteOk));
rcntFreeze(f, 0);
gsFreeze(f, 0);
vu0Freeze(f, 0);
vu1Freeze(f, 0);
vif0Freeze(f, 0);
vif1Freeze(f, 0);
sifFreeze(f, 0);
ipuFreeze(f, 0);
// iop now
SysPrintf("Loading iop mem\n");
gzread(f, psxM, 0x00200000); // 2 MB main memory
//gzread(f, psxP, 0x00010000); // pralell memory
gzread(f, psxH, 0x00010000); // hardware memory
//gzread(f, psxS, 0x00010000); // sif memory
SysPrintf("Loading iop stuff\n");
sioFreeze(f, 0);
cdrFreeze(f, 0);
cdvdFreeze(f, 0);
psxRcntFreeze(f, 0);
//mdecFreeze(f, 0);
sio2Freeze(f, 0);
SysPrintf("Loading GS\n");
_PS2Eload(GS);
SysPrintf("Loading SPU2\n");
_PS2Eload(SPU2);
SysPrintf("Loading DEV9\n");
_PS2Eload(DEV9);
SysPrintf("Loading USB\n");
_PS2Eload(USB);
SysPrintf("Loading ok\n");
gzclose(f);
//dumplog |= 4;
WriteCP0Status(cpuRegs.CP0.n.Status.val);
for (i=0; i<48; i++) WriteTLB(i);
return 0;
}
#ifdef PCSX2_DEVBUILD
int SaveGSState(char *file)
{
if( g_SaveGSStream ) return -1;
SysPrintf("SaveGSState: %s\n", file);
g_fGSSave = gzopen(file, "wb");
if (g_fGSSave == NULL) return -1;
g_SaveGSStream = 1;
g_nLeftGSFrames = 2;
gzwrite(g_fGSSave, &g_nLeftGSFrames, sizeof(g_nLeftGSFrames));
return 0;
}
extern long pDsp;
int LoadGSState(char *file)
{
int ret;
char strfile[255];
gzFile f;
freezeData fP;
f = gzopen(file, "rb");
if (f == NULL) {
_snprintf(strfile, 255, "sstates\\%s", file);
// try prefixing with sstates
f = gzopen(strfile, "rb");
if( f == NULL ) {
SysPrintf("Failed to find gs state\n");
return -1;
}
file = strfile;
}
SysPrintf("LoadGSState: %s\n", file);
GSirqCallback(gsIrq);
ret = GSopen(&pDsp, "PCSX2", 0);
if (ret != 0) {
SysMessage (_("Error Opening GS Plugin"));
return -1;
}
ret = PAD1open((void *)&pDsp);
gzread(f, &g_nLeftGSFrames, sizeof(g_nLeftGSFrames));
gsFreeze(f, 0);
_PS2Eload(GS);
RunGSState(f);
gzclose(f);
GSclose();
PAD1close();
return 0;
}
#endif
int CheckState(char *file) {
gzFile f;
char header[32];
f = gzopen(file, "rb");
if (f == NULL) return -1;
gzread(f, header, 32);
gzclose(f);
if (strncmp(STATE_VERSION " PCSX2", header, 10)) return -1;
return 0;
}
typedef struct {
char id[8];
char name[64];
} LangDef;
LangDef sLangs[] = {
{ "ar_AR", N_("Arabic") },
{ "bg_BG", N_("Bulgarian") },
{ "ca_CA", N_("Catalan") },
{ "du_DU", N_("Dutch") },
{ "de_DE", N_("German") },
{ "el_EL", N_("Greek") },
{ "en_US", N_("English") },
{ "fr_FR", N_("French") },
{ "hb_HB" , N_("Hebrew") },
{ "hu_HU", N_("Hungarian") },
{ "it_IT", N_("Italian") },
{ "ja_JA", N_("Japanese") },
{ "po_PO", N_("Portuguese") },
{ "pl_PL" , N_("Polish") },
{ "ro_RO", N_("Romanian") },
{ "ru_RU", N_("Russian") },
{ "es_ES", N_("Spanish") },
{ "sh_SH" , N_("S-Chinese") },
{ "sw_SW", N_("Swedish") },
{ "tc_TC", N_("T-Chinese") },
{ "tr_TR", N_("Turkish") },
{ "", "" },
};
char *ParseLang(char *id) {
int i=0;
while (sLangs[i].id[0] != 0) {
if (!strcmp(id, sLangs[i].id))
return _(sLangs[i].name);
i++;
}
return id;
}
void injectIRX(char *filename){
struct stat buf;
char path[260], name[260], *p, *q;
struct romdir *rd;
int iROMDIR=-1, iIOPBTCONF=-1, iBLANK=-1, i, filesize;
FILE *fp;
strcpy(name, filename);
for (i=0; name[i] && name[i]!='.' && i<10; i++) name[i]=toupper(name[i]);name[i]=0;
//phase 1: find ROMDIR in bios
for (p=(char*)PS2MEM_ROM; p<(char*)PS2MEM_ROM+0x80000; p++)
if (strncmp(p, "RESET", 5)==0)
break;
rd=(struct romdir*)p;
for (i=0; rd[i].fileName[0]; i++)if (strncmp(rd[i].fileName, name, strlen(name))==0)break;
if (rd[i].fileName[0])return;//already in;)
//phase 2: make room in IOPBTCONF & ROMDIR
for (i=0; rd[i].fileName[0]; i++)if (strncmp(rd[i].fileName, "ROMDIR", 6)==0)iROMDIR=i;
for (i=0; rd[i].fileName[0]; i++)if (strncmp(rd[i].fileName, "IOPBTCONF", 9)==0)iIOPBTCONF=i;
for (i=0; rd[i].fileName[0]; i++)if (rd[i].fileName[0]=='-')break; iBLANK=i;
rd[iBLANK].fileSize-=DIRENTRY_SIZE+DIRENTRY_SIZE;
p=(char*)PS2MEM_ROM;for (i=0; i<iBLANK; i++)p+=(rd[i].fileSize+0xF)&(~0xF);p+=DIRENTRY_SIZE;
q=(char*)PS2MEM_ROM;for (i=0; i<=iIOPBTCONF; i++) q+=(rd[i].fileSize+0xF)&(~0xF);
while (p-16>q){*((u64*)p)=*((u64*)p-4);*((u64*)p+1)=*((u64*)p-3);p-=DIRENTRY_SIZE;}
*((u64*)p)=*((u64*)p+1)=0;p-=DIRENTRY_SIZE;rd[iIOPBTCONF].fileSize+=DIRENTRY_SIZE;
q=(char*)PS2MEM_ROM;for (i=0; i<=iROMDIR; i++) q+=(rd[i].fileSize+0xF)&(~0xF);
while (p >q){*((u64*)p)=*((u64*)p-2);*((u64*)p+1)=*((u64*)p-1);p-=DIRENTRY_SIZE;}
*((u64*)p)=*((u64*)p+1)=0;p-=DIRENTRY_SIZE;rd[iROMDIR].fileSize+=DIRENTRY_SIZE;
//phase 3: add the name to the end of IOPBTCONF
p=(char*)PS2MEM_ROM;for (i=0; i<iIOPBTCONF; i++) p+=(rd[i].fileSize+0xF)&(~0xF);while(*p) p++;//go to end of file
strcpy(p, name);p[strlen(name)]=0xA;
//phase 4: find file
strcpy(path, Config.BiosDir);
strcat(path, filename);
if (stat(path, &buf) == -1){
SysMessage(_("Unable to hack in %s%s\n"), Config.BiosDir, filename);
return;
}
//phase 5: add the file to the end of the bios
p=(char*)PS2MEM_ROM;for (i=0; rd[i].fileName[0]; i++)p+=(rd[i].fileSize+0xF)&(~0xF);
fp=fopen(path, "rb");
fseek(fp, 0, SEEK_END);
filesize=ftell(fp);
fseek(fp, 0, SEEK_SET);
fread(p, 1, filesize, fp);
fclose(fp);
//phase 6: register it in ROMDIR
memset(rd[i].fileName, 0, 10);
memcpy(rd[i].fileName, name, strlen(name));
rd[i].fileSize=filesize;
rd[i].extInfoSize=0;
}

210
Misc.h Normal file
View File

@ -0,0 +1,210 @@
/* 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 __MISC_H__
#define __MISC_H__
#include <stddef.h>
#include <malloc.h>
#undef s_addr
// compile-time assert
#ifndef C_ASSERT
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
#endif
#define PCSX2_GSMULTITHREAD 1 // uses multithreaded gs
#define PCSX2_DUALCORE 2 // speed up for dual cores
#define PCSX2_FRAMELIMIT 4 // limits frames to normal speeds
#define PCSX2_EEREC 0x10
#define PCSX2_VU0REC 0x20
#define PCSX2_VU1REC 0x40
#define PCSX2_COP2REC 0x80
#define PCSX2_FORCEABS 0x100
#define PCSX2_FRAMELIMIT_MASK 0xc00
#define PCSX2_FRAMELIMIT_NORMAL 0x000
#define PCSX2_FRAMELIMIT_LIMIT 0x400
#define PCSX2_FRAMELIMIT_SKIP 0x800
#define PCSX2_FRAMELIMIT_VUSKIP 0xc00
#define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD)
#define CHECK_DUALCORE (Config.Options&PCSX2_DUALCORE)
#define CHECK_EEREC (Config.Options&PCSX2_EEREC)
#define CHECK_COP2REC (Config.Options&PCSX2_COP2REC) // goes with ee option
#define CHECK_FORCEABS 1// always on, (Config.Options&PCSX2_FORCEABS)
#define CHECK_FRAMELIMIT (Config.Options&PCSX2_FRAMELIMIT_MASK)
//#ifdef PCSX2_DEVBUILD
#define CHECK_VU0REC (Config.Options&PCSX2_VU0REC)
#define CHECK_VU1REC (Config.Options&PCSX2_VU1REC)
//#else
//// force to VU recs all the time
//#define CHECK_VU0REC 1
//#define CHECK_VU1REC 1
//
//#endif
typedef struct {
char Bios[256];
char GS[256];
char PAD1[256];
char PAD2[256];
char SPU2[256];
char CDVD[256];
char DEV9[256];
char USB[256];
char FW[256];
char Mcd1[256];
char Mcd2[256];
char PluginsDir[256];
char BiosDir[256];
char Lang[256];
u32 Options; // PCSX2_X options
int PsxOut;
int PsxType;
int Cdda;
int Mdec;
int Patch;
int ThPriority;
int SafeCnts;
} PcsxConfig;
extern PcsxConfig Config;
extern u32 BiosVersion;
extern char CdromId[12];
#define gzfreeze(ptr, size) \
if (Mode == 1) gzwrite(f, ptr, size); \
else if (Mode == 0) gzread(f, ptr, size);
#define gzfreezel(ptr) gzfreeze(ptr, sizeof(ptr))
int LoadCdrom();
int CheckCdrom();
int GetPS2ElfName(char*);
extern char *LabelAuthors;
extern char *LabelGreets;
int SaveState(char *file);
int LoadState(char *file);
int CheckState(char *file);
int SaveGSState(char *file);
int LoadGSState(char *file);
char *ParseLang(char *id);
#ifdef __WIN32__
void ListPatches (HWND hW);
int ReadPatch (HWND hW, char fileName[1024]);
char * lTrim (char *s);
BOOL Save_Patch_Proc( char * filename );
#endif
#define DIRENTRY_SIZE 16
#if defined(__WIN32__)
#pragma pack(1)
#endif
struct romdir{
char fileName[10];
u16 extInfoSize;
u32 fileSize;
#if defined(__WIN32__)
}; //+22
#else
} __attribute__((packed));
#endif
u32 GetBiosVersion();
int IsBIOS(char *filename, char *description);
void * memcpy_amd(void *dest, const void *src, size_t n);
u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize);
void memxor_mmx(void* dst, const void* src1, int cmpsize);
#ifdef __WIN32__
#pragma pack()
#endif
void __Log(char *fmt, ...);
void injectIRX(char *filename);
#if !defined(_MSC_VER) && !defined(HAVE_ALIGNED_MALLOC)
// declare linux equivalents
inline void* pcsx2_aligned_malloc(size_t size, size_t align)
{
char* p = (char*)malloc(size+align+1);
int off = 1+align - ((int)(p+1) % align);
p += off;
p[-1] = off;
return p;
}
inline void pcsx2_aligned_free(void* pmem)
{
char* p = (char*)pmem;
free(p - (int)p[-1]);
}
#define _aligned_malloc pcsx2_aligned_malloc
#define _aligned_free pcsx2_aligned_free
#endif
// cross-platform atomic operations
#if defined (__MSCW32__)
LONG __cdecl _InterlockedIncrement(LONG volatile *Addend);
LONG __cdecl _InterlockedDecrement(LONG volatile *Addend);
LONG __cdecl _InterlockedCompareExchange(LPLONG volatile Dest, LONG Exchange, LONG Comp);
LONG __cdecl _InterlockedExchange(LPLONG volatile Target, LONG Value);
PVOID __cdecl _InterlockedExchangePointer(PVOID volatile* Target, PVOID Value);
LONG __cdecl _InterlockedExchangeAdd(LPLONG volatile Addend, LONG Value);
LONG __cdecl _InterlockedAnd(LPLONG volatile Addend, LONG Value);
#pragma intrinsic (_InterlockedCompareExchange)
#define InterlockedCompareExchange _InterlockedCompareExchange
#pragma intrinsic (_InterlockedExchange)
#define InterlockedExchange _InterlockedExchange
#pragma intrinsic (_InterlockedExchangeAdd)
#define InterlockedExchangeAdd _InterlockedExchangeAdd
#pragma intrinsic (_InterlockedIncrement)
#define InterlockedIncrement _InterlockedIncrement
#pragma intrinsic (_InterlockedDecrement)
#define InterlockedDecrement _InterlockedDecrement
#pragma intrinsic (_InterlockedAnd)
#define InterlockedAnd _InterlockedAnd
#elif defined(__LINUX__)
#endif
#endif /* __MISC_H__ */

805
PS2Edefs.h Normal file
View File

@ -0,0 +1,805 @@
#ifndef __PS2EDEFS_H__
#define __PS2EDEFS_H__
/*
* PS2E Definitions v0.6.2 (beta)
*
* Author: linuzappz@hotmail.com
* shadowpcsx2@yahoo.gr
* florinsasu@hotmail.com
*/
/*
Notes:
* Since this is still beta things may change.
* OSflags:
__LINUX__ (linux OS)
__WIN32__ (win32 OS)
* common return values (for ie. GSinit):
0 - success
-1 - error
* reserved keys:
F1 to F10 are reserved for the emulator
* plugins should NOT change the current
working directory.
(on win32, add flag OFN_NOCHANGEDIR for
GetOpenFileName)
*/
#include "PS2Etypes.h"
#ifdef __LINUX__
#define CALLBACK
#else
#include <windows.h>
#endif
/* common defines */
#if defined(GSdefs) || defined(PADdefs) || defined(SIOdefs) || \
defined(SPU2defs) || defined(CDVDdefs) || defined(DEV9defs) || \
defined(USBdefs) || defined(FWdefs)
#define COMMONdefs
#endif
// PS2EgetLibType returns (may be OR'd)
#define PS2E_LT_GS 0x01
#define PS2E_LT_PAD 0x02 // -=[ OBSOLETE ]=-
#define PS2E_LT_SPU2 0x04
#define PS2E_LT_CDVD 0x08
#define PS2E_LT_DEV9 0x10
#define PS2E_LT_USB 0x20
#define PS2E_LT_FW 0x40
#define PS2E_LT_SIO 0x80
// PS2EgetLibVersion2 (high 16 bits)
#define PS2E_GS_VERSION 0x0006
#define PS2E_PAD_VERSION 0x0002 // -=[ OBSOLETE ]=-
#define PS2E_SPU2_VERSION 0x0005
#define PS2E_CDVD_VERSION 0x0005
#define PS2E_DEV9_VERSION 0x0003
#define PS2E_USB_VERSION 0x0003
#define PS2E_FW_VERSION 0x0002
#define PS2E_SIO_VERSION 0x0001
#ifdef COMMONdefs
u32 CALLBACK PS2EgetLibType(void);
u32 CALLBACK PS2EgetLibVersion2(u32 type);
char* CALLBACK PS2EgetLibName(void);
#endif
// key values:
/* key values must be OS dependant:
win32: the VK_XXX will be used (WinUser)
linux: the XK_XXX will be used (XFree86)
*/
// event values:
#define KEYPRESS 1
#define KEYRELEASE 2
typedef struct {
u32 key;
u32 event;
} keyEvent;
// plugin types
#define SIO_TYPE_PAD 0x00000001
#define SIO_TYPE_MTAP 0x00000004
#define SIO_TYPE_RM 0x00000040
#define SIO_TYPE_MC 0x00000100
typedef int (CALLBACK * SIOchangeSlotCB)(int slot);
typedef struct {
u8 ctrl:4; // control and mode bits
u8 mode:4; // control and mode bits
u8 trackNum; // current track number (1 to 99)
u8 trackIndex; // current index within track (0 to 99)
u8 trackM; // current minute location on the disc (BCD encoded)
u8 trackS; // current sector location on the disc (BCD encoded)
u8 trackF; // current frame location on the disc (BCD encoded)
u8 pad; // unused
u8 discM; // current minute offset from first track (BCD encoded)
u8 discS; // current sector offset from first track (BCD encoded)
u8 discF; // current frame offset from first track (BCD encoded)
} cdvdSubQ;
typedef struct { // NOT bcd coded
u32 lsn;
u8 type;
} cdvdTD;
typedef struct {
u8 strack; //number of the first track (usually 1)
u8 etrack; //number of the last track
} cdvdTN;
// CDVDreadTrack mode values:
#define CDVD_MODE_2352 0 // full 2352 bytes
#define CDVD_MODE_2340 1 // skip sync (12) bytes
#define CDVD_MODE_2328 2 // skip sync+head+sub (24) bytes
#define CDVD_MODE_2048 3 // skip sync+head+sub (24) bytes
#define CDVD_MODE_2368 4 // full 2352 bytes + 16 subq
// CDVDgetDiskType returns:
#define CDVD_TYPE_ILLEGAL 0xff // Illegal Disc
#define CDVD_TYPE_DVDV 0xfe // DVD Video
#define CDVD_TYPE_CDDA 0xfd // Audio CD
#define CDVD_TYPE_PS2DVD 0x14 // PS2 DVD
#define CDVD_TYPE_PS2CDDA 0x13 // PS2 CD (with audio)
#define CDVD_TYPE_PS2CD 0x12 // PS2 CD
#define CDVD_TYPE_PSCDDA 0x11 // PS CD (with audio)
#define CDVD_TYPE_PSCD 0x10 // PS CD
#define CDVD_TYPE_UNKNOWN 0x05 // Unknown
#define CDVD_TYPE_DETCTDVDD 0x04 // Detecting Dvd Dual Sided
#define CDVD_TYPE_DETCTDVDS 0x03 // Detecting Dvd Single Sided
#define CDVD_TYPE_DETCTCD 0x02 // Detecting Cd
#define CDVD_TYPE_DETCT 0x01 // Detecting
#define CDVD_TYPE_NODISC 0x00 // No Disc
// CDVDgetTrayStatus returns:
#define CDVD_TRAY_CLOSE 0x00
#define CDVD_TRAY_OPEN 0x01
// cdvdTD.type (track types for cds)
#define CDVD_AUDIO_TRACK 0x01
#define CDVD_MODE1_TRACK 0x41
#define CDVD_MODE2_TRACK 0x61
#define CDVD_AUDIO_MASK 0x00
#define CDVD_DATA_MASK 0x40
// CDROM_DATA_TRACK 0x04 //do not enable this! (from linux kernel)
typedef void (*DEV9callback)(int cycles);
typedef int (*DEV9handler)(void);
typedef void (*USBcallback)(int cycles);
typedef int (*USBhandler)(void);
// freeze modes:
#define FREEZE_LOAD 0
#define FREEZE_SAVE 1
#define FREEZE_SIZE 2
typedef struct {
char name[8];
void *common;
} GSdriverInfo;
#ifdef __WIN32__
typedef struct { // unsupported values must be set to zero
HWND hWnd;
HMENU hMenu;
HWND hStatusWnd;
} winInfo;
#endif
/* GS plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef GSdefs
// basic funcs
s32 CALLBACK GSinit();
s32 CALLBACK GSopen(void *pDsp, char *Title, int multithread);
void CALLBACK GSclose();
void CALLBACK GSshutdown();
void CALLBACK GSvsync(int field);
void CALLBACK GSgifTransfer1(u32 *pMem, u32 addr);
void CALLBACK GSgifTransfer2(u32 *pMem, u32 size);
void CALLBACK GSgifTransfer3(u32 *pMem, u32 size);
void CALLBACK GSgifSoftReset(u32 mask);
void CALLBACK GSreadFIFO(u64 *mem);
void CALLBACK GSreadFIFO2(u64 *mem, int qwc);
// extended funcs
// GSkeyEvent gets called when there is a keyEvent from the PAD plugin
void CALLBACK GSkeyEvent(keyEvent *ev);
void CALLBACK GSchangeSaveState(int, const char* filename);
void CALLBACK GSmakeSnapshot(char *path);
void CALLBACK GSmakeSnapshot2(char *pathname, int* snapdone, int savejpg);
void CALLBACK GSirqCallback(void (*callback)());
void CALLBACK GSprintf(int timeout, char *fmt, ...);
void CALLBACK GSsetBaseMem(void*);
void CALLBACK GSsetGameCRC(int);
// controls frame skipping in the GS, if this routine isn't present, frame skipping won't be done
void CALLBACK GSsetFrameSkip(int frameskip);
void CALLBACK GSreset();
void CALLBACK GSwriteCSR(u32 value);
void CALLBACK GSgetDriverInfo(GSdriverInfo *info);
#ifdef __WIN32__
s32 CALLBACK GSsetWindowInfo(winInfo *info);
#endif
s32 CALLBACK GSfreeze(int mode, freezeData *data);
void CALLBACK GSconfigure();
void CALLBACK GSabout();
s32 CALLBACK GStest();
#endif
/* PAD plugin API -=[ OBSOLETE ]=- */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef PADdefs
// basic funcs
s32 CALLBACK PADinit(u32 flags);
s32 CALLBACK PADopen(void *pDsp);
void CALLBACK PADclose();
void CALLBACK PADshutdown();
// PADkeyEvent is called every vsync (return NULL if no event)
keyEvent* CALLBACK PADkeyEvent();
u8 CALLBACK PADstartPoll(int pad);
u8 CALLBACK PADpoll(u8 value);
// returns: 1 if supported pad1
// 2 if supported pad2
// 3 if both are supported
u32 CALLBACK PADquery();
// extended funcs
void CALLBACK PADgsDriverInfo(GSdriverInfo *info);
void CALLBACK PADconfigure();
void CALLBACK PADabout();
s32 CALLBACK PADtest();
#endif
/* SIO plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef SIOdefs
// basic funcs
s32 CALLBACK SIOinit(u32 port, u32 slot, SIOchangeSlotCB f);
s32 CALLBACK SIOopen(void *pDsp);
void CALLBACK SIOclose();
void CALLBACK SIOshutdown();
u8 CALLBACK SIOstartPoll(u8 value);
u8 CALLBACK SIOpoll(u8 value);
// returns: SIO_TYPE_{PAD,MTAP,RM,MC}
u32 CALLBACK SIOquery();
// extended funcs
void CALLBACK SIOconfigure();
void CALLBACK SIOabout();
s32 CALLBACK SIOtest();
#endif
/* SPU2 plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef SPU2defs
// basic funcs
s32 CALLBACK SPU2init();
s32 CALLBACK SPU2open(void *pDsp);
void CALLBACK SPU2close();
void CALLBACK SPU2shutdown();
void CALLBACK SPU2write(u32 mem, u16 value);
u16 CALLBACK SPU2read(u32 mem);
void CALLBACK SPU2readDMA4Mem(u16 *pMem, int size);
void CALLBACK SPU2writeDMA4Mem(u16 *pMem, int size);
void CALLBACK SPU2interruptDMA4();
void CALLBACK SPU2readDMA7Mem(u16* pMem, int size);
void CALLBACK SPU2writeDMA7Mem(u16 *pMem, int size);
void CALLBACK SPU2interruptDMA7();
u32 CALLBACK SPU2ReadMemAddr(int core);
void CALLBACK SPU2WriteMemAddr(int core,u32 value);
void CALLBACK SPU2irqCallback(void (*SPU2callback)(),void (*DMA4callback)(),void (*DMA7callback)());
// extended funcs
void CALLBACK SPU2async(u32 cycles);
s32 CALLBACK SPU2freeze(int mode, freezeData *data);
void CALLBACK SPU2configure();
void CALLBACK SPU2about();
s32 CALLBACK SPU2test();
#endif
/* CDVD plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef CDVDdefs
// basic funcs
s32 CALLBACK CDVDinit();
s32 CALLBACK CDVDopen();
void CALLBACK CDVDclose();
void CALLBACK CDVDshutdown();
s32 CALLBACK CDVDreadTrack(u32 lsn, int mode);
// return can be NULL (for async modes)
u8* CALLBACK CDVDgetBuffer();
s32 CALLBACK CDVDreadSubQ(u32 lsn, cdvdSubQ* subq);//read subq from disc (only cds have subq data)
s32 CALLBACK CDVDgetTN(cdvdTN *Buffer); //disk information
s32 CALLBACK CDVDgetTD(u8 Track, cdvdTD *Buffer); //track info: min,sec,frame,type
s32 CALLBACK CDVDgetTOC(void* toc); //gets ps2 style toc from disc
s32 CALLBACK CDVDgetDiskType(); //CDVD_TYPE_xxxx
s32 CALLBACK CDVDgetTrayStatus(); //CDVD_TRAY_xxxx
s32 CALLBACK CDVDctrlTrayOpen(); //open disc tray
s32 CALLBACK CDVDctrlTrayClose(); //close disc tray
// extended funcs
void CALLBACK CDVDconfigure();
void CALLBACK CDVDabout();
s32 CALLBACK CDVDtest();
void CALLBACK CDVDnewDiskCB(void (*callback)());
#endif
/* DEV9 plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef DEV9defs
// basic funcs
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
s32 CALLBACK DEV9init();
s32 CALLBACK DEV9open(void *pDsp);
void CALLBACK DEV9close();
void CALLBACK DEV9shutdown();
u8 CALLBACK DEV9read8(u32 addr);
u16 CALLBACK DEV9read16(u32 addr);
u32 CALLBACK DEV9read32(u32 addr);
void CALLBACK DEV9write8(u32 addr, u8 value);
void CALLBACK DEV9write16(u32 addr, u16 value);
void CALLBACK DEV9write32(u32 addr, u32 value);
void CALLBACK DEV9readDMA8Mem(u32 *pMem, int size);
void CALLBACK DEV9writeDMA8Mem(u32 *pMem, int size);
// cycles = IOP cycles before calling callback,
// if callback returns 1 the irq is triggered, else not
void CALLBACK DEV9irqCallback(DEV9callback callback);
DEV9handler CALLBACK DEV9irqHandler(void);
// extended funcs
s32 CALLBACK DEV9freeze(int mode, freezeData *data);
void CALLBACK DEV9configure();
void CALLBACK DEV9about();
s32 CALLBACK DEV9test();
#endif
/* USB plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef USBdefs
// basic funcs
s32 CALLBACK USBinit();
s32 CALLBACK USBopen(void *pDsp);
void CALLBACK USBclose();
void CALLBACK USBshutdown();
u8 CALLBACK USBread8(u32 addr);
u16 CALLBACK USBread16(u32 addr);
u32 CALLBACK USBread32(u32 addr);
void CALLBACK USBwrite8(u32 addr, u8 value);
void CALLBACK USBwrite16(u32 addr, u16 value);
void CALLBACK USBwrite32(u32 addr, u32 value);
// cycles = IOP cycles before calling callback,
// if callback returns 1 the irq is triggered, else not
void CALLBACK USBirqCallback(USBcallback callback);
USBhandler CALLBACK USBirqHandler(void);
void CALLBACK USBsetRAM(void *mem);
// extended funcs
s32 CALLBACK USBfreeze(int mode, freezeData *data);
void CALLBACK USBconfigure();
void CALLBACK USBabout();
s32 CALLBACK USBtest();
#endif
/* FW plugin API */
// if this file is included with this define
// the next api will not be skipped by the compiler
#ifdef FWdefs
// basic funcs
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
s32 CALLBACK FWinit();
s32 CALLBACK FWopen(void *pDsp);
void CALLBACK FWclose();
void CALLBACK FWshutdown();
u32 CALLBACK FWread32(u32 addr);
void CALLBACK FWwrite32(u32 addr, u32 value);
void CALLBACK FWirqCallback(void (*callback)());
// extended funcs
s32 CALLBACK FWfreeze(int mode, freezeData *data);
void CALLBACK FWconfigure();
void CALLBACK FWabout();
s32 CALLBACK FWtest();
#endif
// might be useful for emulators
#ifdef PLUGINtypedefs
typedef u32 (CALLBACK* _PS2EgetLibType)(void);
typedef u32 (CALLBACK* _PS2EgetLibVersion2)(u32 type);
typedef char*(CALLBACK* _PS2EgetLibName)(void);
// GS
// NOTE: GSreadFIFOX/GSwriteCSR functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32 (CALLBACK* _GSinit)();
typedef s32 (CALLBACK* _GSopen)(void *pDsp, char *Title, int multithread);
typedef void (CALLBACK* _GSclose)();
typedef void (CALLBACK* _GSshutdown)();
typedef void (CALLBACK* _GSvsync)(int field);
typedef void (CALLBACK* _GSgifTransfer1)(u32 *pMem, u32 addr);
typedef void (CALLBACK* _GSgifTransfer2)(u32 *pMem, u32 size);
typedef void (CALLBACK* _GSgifTransfer3)(u32 *pMem, u32 size);
typedef void (CALLBACK* _GSgifSoftReset)(u32 mask);
typedef void (CALLBACK* _GSreadFIFO)(u64 *pMem);
typedef void (CALLBACK* _GSreadFIFO2)(u64 *pMem, int qwc);
typedef void (CALLBACK* _GSkeyEvent)(keyEvent* ev);
typedef void (CALLBACK* _GSchangeSaveState)(int, const char* filename);
typedef void (CALLBACK* _GSirqCallback)(void (*callback)());
typedef void (CALLBACK* _GSprintf)(int timeout, char *fmt, ...);
typedef void (CALLBACK* _GSsetBaseMem)(void*);
typedef void (CALLBACK* _GSsetGameCRC)(int);
typedef void (CALLBACK* _GSsetFrameSkip)(int frameskip);
typedef void (CALLBACK* _GSreset)();
typedef void (CALLBACK* _GSwriteCSR)(u32 value);
typedef void (CALLBACK* _GSgetDriverInfo)(GSdriverInfo *info);
#ifdef __WIN32__
typedef s32 (CALLBACK* _GSsetWindowInfo)(winInfo *info);
#endif
typedef void (CALLBACK* _GSmakeSnapshot)(char *path);
typedef void (CALLBACK* _GSmakeSnapshot2)(char *path, int*, int);
typedef s32 (CALLBACK* _GSfreeze)(int mode, freezeData *data);
typedef void (CALLBACK* _GSconfigure)();
typedef s32 (CALLBACK* _GStest)();
typedef void (CALLBACK* _GSabout)();
// PAD
typedef s32 (CALLBACK* _PADinit)(u32 flags);
typedef s32 (CALLBACK* _PADopen)(void *pDsp);
typedef void (CALLBACK* _PADclose)();
typedef void (CALLBACK* _PADshutdown)();
typedef keyEvent* (CALLBACK* _PADkeyEvent)();
typedef u8 (CALLBACK* _PADstartPoll)(int pad);
typedef u8 (CALLBACK* _PADpoll)(u8 value);
typedef u32 (CALLBACK* _PADquery)();
typedef void (CALLBACK* _PADgsDriverInfo)(GSdriverInfo *info);
typedef void (CALLBACK* _PADconfigure)();
typedef s32 (CALLBACK* _PADtest)();
typedef void (CALLBACK* _PADabout)();
// SIO
typedef s32 (CALLBACK* _SIOinit)(u32 port, u32 slot, SIOchangeSlotCB f);
typedef s32 (CALLBACK* _SIOopen)(void *pDsp);
typedef void (CALLBACK* _SIOclose)();
typedef void (CALLBACK* _SIOshutdown)();
typedef u8 (CALLBACK* _SIOstartPoll)(u8 value);
typedef u8 (CALLBACK* _SIOpoll)(u8 value);
typedef u32 (CALLBACK* _SIOquery)();
typedef void (CALLBACK* _SIOconfigure)();
typedef s32 (CALLBACK* _SIOtest)();
typedef void (CALLBACK* _SIOabout)();
// SPU2
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32 (CALLBACK* _SPU2init)();
typedef s32 (CALLBACK* _SPU2open)(void *pDsp);
typedef void (CALLBACK* _SPU2close)();
typedef void (CALLBACK* _SPU2shutdown)();
typedef void (CALLBACK* _SPU2write)(u32 mem, u16 value);
typedef u16 (CALLBACK* _SPU2read)(u32 mem);
typedef void (CALLBACK* _SPU2readDMA4Mem)(u16 *pMem, int size);
typedef void (CALLBACK* _SPU2writeDMA4Mem)(u16 *pMem, int size);
typedef void (CALLBACK* _SPU2interruptDMA4)();
typedef void (CALLBACK* _SPU2readDMA7Mem)(u16 *pMem, int size);
typedef void (CALLBACK* _SPU2writeDMA7Mem)(u16 *pMem, int size);
typedef void (CALLBACK* _SPU2interruptDMA7)();
typedef void (CALLBACK* _SPU2irqCallback)(void (*SPU2callback)(),void (*DMA4callback)(),void (*DMA7callback)());
typedef u32 (CALLBACK* _SPU2ReadMemAddr)(int core);
typedef void (CALLBACK* _SPU2WriteMemAddr)(int core,u32 value);
typedef void (CALLBACK* _SPU2async)(u32 cycles);
typedef s32 (CALLBACK* _SPU2freeze)(int mode, freezeData *data);
typedef void (CALLBACK* _SPU2configure)();
typedef s32 (CALLBACK* _SPU2test)();
typedef void (CALLBACK* _SPU2about)();
// CDVD
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32 (CALLBACK* _CDVDinit)();
typedef s32 (CALLBACK* _CDVDopen)();
typedef void (CALLBACK* _CDVDclose)();
typedef void (CALLBACK* _CDVDshutdown)();
typedef s32 (CALLBACK* _CDVDreadTrack)(u32 lsn, int mode);
typedef u8* (CALLBACK* _CDVDgetBuffer)();
typedef s32 (CALLBACK* _CDVDreadSubQ)(u32 lsn, cdvdSubQ* subq);
typedef s32 (CALLBACK* _CDVDgetTN)(cdvdTN *Buffer);
typedef s32 (CALLBACK* _CDVDgetTD)(u8 Track, cdvdTD *Buffer);
typedef s32 (CALLBACK* _CDVDgetTOC)(void* toc);
typedef s32 (CALLBACK* _CDVDgetDiskType)();
typedef s32 (CALLBACK* _CDVDgetTrayStatus)();
typedef s32 (CALLBACK* _CDVDctrlTrayOpen)();
typedef s32 (CALLBACK* _CDVDctrlTrayClose)();
typedef void (CALLBACK* _CDVDconfigure)();
typedef s32 (CALLBACK* _CDVDtest)();
typedef void (CALLBACK* _CDVDabout)();
typedef void (CALLBACK* _CDVDnewDiskCB)(void (*callback)());
// DEV9
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32 (CALLBACK* _DEV9init)();
typedef s32 (CALLBACK* _DEV9open)(void *pDsp);
typedef void (CALLBACK* _DEV9close)();
typedef void (CALLBACK* _DEV9shutdown)();
typedef u8 (CALLBACK* _DEV9read8)(u32 mem);
typedef u16 (CALLBACK* _DEV9read16)(u32 mem);
typedef u32 (CALLBACK* _DEV9read32)(u32 mem);
typedef void (CALLBACK* _DEV9write8)(u32 mem, u8 value);
typedef void (CALLBACK* _DEV9write16)(u32 mem, u16 value);
typedef void (CALLBACK* _DEV9write32)(u32 mem, u32 value);
typedef void (CALLBACK* _DEV9readDMA8Mem)(u32 *pMem, int size);
typedef void (CALLBACK* _DEV9writeDMA8Mem)(u32 *pMem, int size);
typedef void (CALLBACK* _DEV9irqCallback)(DEV9callback callback);
typedef DEV9handler (CALLBACK* _DEV9irqHandler)(void);
typedef s32 (CALLBACK* _DEV9freeze)(int mode, freezeData *data);
typedef void (CALLBACK* _DEV9configure)();
typedef s32 (CALLBACK* _DEV9test)();
typedef void (CALLBACK* _DEV9about)();
// USB
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32 (CALLBACK* _USBinit)();
typedef s32 (CALLBACK* _USBopen)(void *pDsp);
typedef void (CALLBACK* _USBclose)();
typedef void (CALLBACK* _USBshutdown)();
typedef u8 (CALLBACK* _USBread8)(u32 mem);
typedef u16 (CALLBACK* _USBread16)(u32 mem);
typedef u32 (CALLBACK* _USBread32)(u32 mem);
typedef void (CALLBACK* _USBwrite8)(u32 mem, u8 value);
typedef void (CALLBACK* _USBwrite16)(u32 mem, u16 value);
typedef void (CALLBACK* _USBwrite32)(u32 mem, u32 value);
typedef void (CALLBACK* _USBirqCallback)(USBcallback callback);
typedef USBhandler (CALLBACK* _USBirqHandler)(void);
typedef void (CALLBACK* _USBsetRAM)(void *mem);
typedef s32 (CALLBACK* _USBfreeze)(int mode, freezeData *data);
typedef void (CALLBACK* _USBconfigure)();
typedef s32 (CALLBACK* _USBtest)();
typedef void (CALLBACK* _USBabout)();
//FW
typedef s32 (CALLBACK* _FWinit)();
typedef s32 (CALLBACK* _FWopen)(void *pDsp);
typedef void (CALLBACK* _FWclose)();
typedef void (CALLBACK* _FWshutdown)();
typedef u32 (CALLBACK* _FWread32)(u32 mem);
typedef void (CALLBACK* _FWwrite32)(u32 mem, u32 value);
typedef void (CALLBACK* _FWirqCallback)(void (*callback)());
typedef s32 (CALLBACK* _FWfreeze)(int mode, freezeData *data);
typedef void (CALLBACK* _FWconfigure)();
typedef s32 (CALLBACK* _FWtest)();
typedef void (CALLBACK* _FWabout)();
#endif
#ifdef PLUGINfuncs
// GS
_GSinit GSinit;
_GSopen GSopen;
_GSclose GSclose;
_GSshutdown GSshutdown;
_GSvsync GSvsync;
_GSgifTransfer1 GSgifTransfer1;
_GSgifTransfer2 GSgifTransfer2;
_GSgifTransfer3 GSgifTransfer3;
_GSgifSoftReset GSgifSoftReset;
_GSreadFIFO GSreadFIFO;
_GSreadFIFO2 GSreadFIFO2;
_GSkeyEvent GSkeyEvent;
_GSchangeSaveState GSchangeSaveState;
_GSmakeSnapshot GSmakeSnapshot;
_GSmakeSnapshot2 GSmakeSnapshot2;
_GSirqCallback GSirqCallback;
_GSprintf GSprintf;
_GSsetBaseMem GSsetBaseMem;
_GSsetGameCRC GSsetGameCRC;
_GSsetFrameSkip GSsetFrameSkip;
_GSreset GSreset;
_GSwriteCSR GSwriteCSR;
_GSgetDriverInfo GSgetDriverInfo;
#ifdef __WIN32__
_GSsetWindowInfo GSsetWindowInfo;
#endif
_GSfreeze GSfreeze;
_GSconfigure GSconfigure;
_GStest GStest;
_GSabout GSabout;
// PAD1
_PADinit PAD1init;
_PADopen PAD1open;
_PADclose PAD1close;
_PADshutdown PAD1shutdown;
_PADkeyEvent PAD1keyEvent;
_PADstartPoll PAD1startPoll;
_PADpoll PAD1poll;
_PADquery PAD1query;
_PADgsDriverInfo PAD1gsDriverInfo;
_PADconfigure PAD1configure;
_PADtest PAD1test;
_PADabout PAD1about;
// PAD2
_PADinit PAD2init;
_PADopen PAD2open;
_PADclose PAD2close;
_PADshutdown PAD2shutdown;
_PADkeyEvent PAD2keyEvent;
_PADstartPoll PAD2startPoll;
_PADpoll PAD2poll;
_PADquery PAD2query;
_PADgsDriverInfo PAD2gsDriverInfo;
_PADconfigure PAD2configure;
_PADtest PAD2test;
_PADabout PAD2about;
// SIO[2]
_SIOinit SIOinit[2][9];
_SIOopen SIOopen[2][9];
_SIOclose SIOclose[2][9];
_SIOshutdown SIOshutdown[2][9];
_SIOstartPoll SIOstartPoll[2][9];
_SIOpoll SIOpoll[2][9];
_SIOquery SIOquery[2][9];
_SIOconfigure SIOconfigure[2][9];
_SIOtest SIOtest[2][9];
_SIOabout SIOabout[2][9];
// SPU2
_SPU2init SPU2init;
_SPU2open SPU2open;
_SPU2close SPU2close;
_SPU2shutdown SPU2shutdown;
_SPU2write SPU2write;
_SPU2read SPU2read;
_SPU2readDMA4Mem SPU2readDMA4Mem;
_SPU2writeDMA4Mem SPU2writeDMA4Mem;
_SPU2interruptDMA4 SPU2interruptDMA4;
_SPU2readDMA7Mem SPU2readDMA7Mem;
_SPU2writeDMA7Mem SPU2writeDMA7Mem;
_SPU2interruptDMA7 SPU2interruptDMA7;
_SPU2ReadMemAddr SPU2ReadMemAddr;
_SPU2WriteMemAddr SPU2WriteMemAddr;
_SPU2irqCallback SPU2irqCallback;
_SPU2async SPU2async;
_SPU2freeze SPU2freeze;
_SPU2configure SPU2configure;
_SPU2test SPU2test;
_SPU2about SPU2about;
// CDVD
_CDVDinit CDVDinit;
_CDVDopen CDVDopen;
_CDVDclose CDVDclose;
_CDVDshutdown CDVDshutdown;
_CDVDreadTrack CDVDreadTrack;
_CDVDgetBuffer CDVDgetBuffer;
_CDVDreadSubQ CDVDreadSubQ;
_CDVDgetTN CDVDgetTN;
_CDVDgetTD CDVDgetTD;
_CDVDgetTOC CDVDgetTOC;
_CDVDgetDiskType CDVDgetDiskType;
_CDVDgetTrayStatus CDVDgetTrayStatus;
_CDVDctrlTrayOpen CDVDctrlTrayOpen;
_CDVDctrlTrayClose CDVDctrlTrayClose;
_CDVDconfigure CDVDconfigure;
_CDVDtest CDVDtest;
_CDVDabout CDVDabout;
_CDVDnewDiskCB CDVDnewDiskCB;
// DEV9
_DEV9init DEV9init;
_DEV9open DEV9open;
_DEV9close DEV9close;
_DEV9shutdown DEV9shutdown;
_DEV9read8 DEV9read8;
_DEV9read16 DEV9read16;
_DEV9read32 DEV9read32;
_DEV9write8 DEV9write8;
_DEV9write16 DEV9write16;
_DEV9write32 DEV9write32;
_DEV9readDMA8Mem DEV9readDMA8Mem;
_DEV9writeDMA8Mem DEV9writeDMA8Mem;
_DEV9irqCallback DEV9irqCallback;
_DEV9irqHandler DEV9irqHandler;
_DEV9configure DEV9configure;
_DEV9freeze DEV9freeze;
_DEV9test DEV9test;
_DEV9about DEV9about;
// USB
_USBinit USBinit;
_USBopen USBopen;
_USBclose USBclose;
_USBshutdown USBshutdown;
_USBread8 USBread8;
_USBread16 USBread16;
_USBread32 USBread32;
_USBwrite8 USBwrite8;
_USBwrite16 USBwrite16;
_USBwrite32 USBwrite32;
_USBirqCallback USBirqCallback;
_USBirqHandler USBirqHandler;
_USBsetRAM USBsetRAM;
_USBconfigure USBconfigure;
_USBfreeze USBfreeze;
_USBtest USBtest;
_USBabout USBabout;
// FW
_FWinit FWinit;
_FWopen FWopen;
_FWclose FWclose;
_FWshutdown FWshutdown;
_FWread32 FWread32;
_FWwrite32 FWwrite32;
_FWirqCallback FWirqCallback;
_FWconfigure FWconfigure;
_FWfreeze FWfreeze;
_FWtest FWtest;
_FWabout FWabout;
#endif
#endif /* __PS2EDEFS_H__ */

75
PS2Etypes.h Normal file
View File

@ -0,0 +1,75 @@
#ifndef __PS2ETYPES_H__
#define __PS2ETYPES_H__
#ifndef ARRAYSIZE
#define ARRAYSIZE(x) (sizeof(x)/sizeof((x)[0]))
#endif
#if defined (__linux__) // some distributions are lower case
#define __LINUX__
#endif
// Basic types
#if defined(_WIN32)
typedef __int8 s8;
typedef __int16 s16;
typedef __int32 s32;
typedef __int64 s64;
typedef unsigned __int8 u8;
typedef unsigned __int16 u16;
typedef unsigned __int32 u32;
typedef unsigned __int64 u64;
#if defined(__x86_64__)
typedef u64 uptr;
#else
typedef u32 uptr;
#endif
#define PCSX2_ALIGNED16(x) __declspec(align(16)) x
#else
typedef char s8;
typedef short s16;
typedef int s32;
typedef long long s64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
#if defined(__x86_64__)
typedef u64 uptr;
#else
typedef u32 uptr;
#endif
#ifdef __LINUX__
typedef union _LARGE_INTEGER
{
long long QuadPart;
} LARGE_INTEGER;
#endif
#if defined(__MINGW32__)
#define PCSX2_ALIGNED16(x) __declspec(align(16)) x
#else
#define PCSX2_ALIGNED16(x) x __attribute((aligned(16)))
#endif
#ifndef __forceinline
#define __forceinline inline
#endif
#endif
typedef struct {
int size;
s8 *data;
} freezeData;
#endif /* __PS2ETYPES_H__ */

381
Patch.c Normal file
View File

@ -0,0 +1,381 @@
/* 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
*/
//
// Includes
//
#include <stdlib.h>
#include <string.h>
#include "PsxCommon.h"
#include "windows/cheats/cheats.h"
#include "patch.h"
//
// Variables
//
PatchTextTable commands[] =
{
{ "comment", 1, patchFunc_comment },
{ "gametitle", 2, patchFunc_gametitle },
{ "patch", 3, patchFunc_patch },
{ "fastmemory", 4, patchFunc_fastmemory }, // enable for faster but bugger mem (mvc2 is faster)
{ "roundmode", 5, patchFunc_roundmode }, // changes rounding mode for floating point
// syntax: roundmode=X,Y
// possible values for X,Y: NEAR, DOWN, UP, CHOP
// X - EE rounding mode (default is NEAR)
// Y - VU rounding mode (default is CHOP)
{ "", 0, NULL }
};
PatchTextTable dataType[] =
{
{ "byte", 1, NULL },
{ "short", 2, NULL },
{ "word", 3, NULL },
{ "double", 4, NULL },
{ "", 0, NULL }
};
PatchTextTable cpuCore[] =
{
{ "EE", 1, NULL },
{ "IOP", 2, NULL },
{ "", 0, NULL }
};
IniPatch patch[ MAX_PATCH ];
int patchnumber;
//
// Function Implementations
//
int PatchTableExecute( char * text1, char * text2, PatchTextTable * Table )
{
int i = 0;
while ( Table[ i ].text[ 0 ] )
{
if ( !strcmp( Table[ i ].text, text1 ) )
{
if ( Table[ i ].func )
{
Table[ i ].func( text1, text2 );
}
break;
}
i++;
}
return Table[ i ].code;
}
void _applypatch(int place, IniPatch *p) {
if (p->placetopatch != place) return;
if (p->enabled == 0) return;
if (p->cpu == 1) { //EE
if (p->type == 1) { //byte
memWrite8(p->addr, (u8)p->data);
} else
if (p->type == 2) { //short
memWrite16(p->addr, (u16)p->data);
} else
if (p->type == 3) { //word
memWrite32(p->addr, (u32)p->data);
} else
if (p->type == 4) { //double
memWrite64(p->addr, p->data);
}
} else
if (p->cpu == 2) { //IOP
if (p->type == 1) { //byte
psxMemWrite8(p->addr, (u8)p->data);
} else
if (p->type == 2) { //short
psxMemWrite16(p->addr, (u16)p->data);
} else
if (p->type == 3) { //word
psxMemWrite32(p->addr, (u32)p->data);
}
}
}
//this is for apply patches directly to memory
void applypatch(int place) {
int i;
if (place == 0) {
SysPrintf(" patchnumber: %d\n", patchnumber);
}
for ( i = 0; i < patchnumber; i++ ) {
_applypatch(place, &patch[i]);
}
}
void patchFunc_comment( char * text1, char * text2 )
{
SysPrintf( "comment: %s \n", text2 );
}
char strgametitle[256] = {0};
void patchFunc_gametitle( char * text1, char * text2 )
{
SysPrintf( "gametitle: %s \n", text2 );
#ifdef __WIN32__
sprintf(strgametitle,"%s",text2);
if (gApp.hConsole) SetConsoleTitle(strgametitle);
#endif
}
void patchFunc_patch( char * cmd, char * param )
{
//patch=placetopatch,cpucore,address,type,data
char * pText;
if ( patchnumber >= MAX_PATCH )
{
SysPrintf( "Patch ERROR: Maximum number of patches reached: %s=%s\n", cmd, param );
return;
}
pText = strtok( param, "," );
pText = param;
// inifile_trim( pText );
patch[ patchnumber ].placetopatch = strtol( pText, (char **)NULL, 0 );
pText = strtok( NULL, "," );
inifile_trim( pText );
patch[ patchnumber ].cpu = PatchTableExecute( pText, NULL, cpuCore );
if ( patch[ patchnumber ].cpu == 0 )
{
SysPrintf( "Unrecognized patch '%s'\n", pText );
return;
}
pText = strtok( NULL, "," );
inifile_trim( pText );
sscanf( pText, "%X", &patch[ patchnumber ].addr );
pText = strtok( NULL, "," );
inifile_trim( pText );
patch[ patchnumber ].type = PatchTableExecute( pText, NULL, dataType );
if ( patch[ patchnumber ].type == 0 )
{
SysPrintf( "Unrecognized patch '%s'\n", pText );
return;
}
pText = strtok( NULL, "," );
inifile_trim( pText );
sscanf( pText, "%I64X", &patch[ patchnumber ].data );
patch[ patchnumber ].enabled = 1;
patchnumber++;
}
//this routine is for execute the commands of the ini file
void inifile_command( char * cmd )
{
int code;
char command[ 256 ];
char parameter[ 256 ];
// extract param part (after '=')
char * pEqual = strchr( cmd, '=' );
if ( ! pEqual )
{
// fastmemory doesn't have =
pEqual = cmd+strlen(cmd);
// SysPrintf( "Ini file ERROR: unknow line: %s \n", cmd );
// return;
}
memset( command, 0, sizeof( command ) );
memset( parameter, 0, sizeof( parameter ) );
strncpy( command, cmd, pEqual - cmd );
strncpy( parameter, pEqual + 1, sizeof( parameter ) );
inifile_trim( command );
inifile_trim( parameter );
code = PatchTableExecute( command, parameter, commands );
}
void inifile_trim( char * buffer )
{
char * pInit = buffer;
char * pEnd = NULL;
while ( ( *pInit == ' ' ) || ( *pInit == '\t' ) ) //skip space
{
pInit++;
}
if ( ( pInit[ 0 ] == '/' ) && ( pInit[ 1 ] == '/' ) ) //remove comment
{
buffer[ 0 ] = '\0';
return;
}
pEnd = pInit + strlen( pInit ) - 1;
if ( pEnd <= pInit )
{
buffer[ 0 ] = '\0';
return;
}
while ( ( *pEnd == '\r' ) || ( *pEnd == '\n' ) ||
( *pEnd == ' ' ) || ( *pEnd == '\t' ) )
{
pEnd--;
}
if ( pEnd <= pInit )
{
buffer[ 0 ] = '\0';
return;
}
memmove( buffer, pInit, pEnd - pInit + 1 );
buffer[ pEnd - pInit + 1 ] = '\0';
}
void inisection_process( FILE * f1 )
{
char buffer[ 1024 ];
while( fgets( buffer, sizeof( buffer ), f1 ) )
{
inifile_trim( buffer );
if ( buffer[ 0 ] )
{
inifile_command( buffer );
}
}
}
//this routine is for reading the ini file
void inifile_read( char * name )
{
FILE * f1;
char buffer[ 1024 ];
patchnumber = 0;
#ifdef __WIN32__
sprintf( buffer, "patches\\%s.pnach", name );
#else
sprintf( buffer, "patches/%s.pnach", name );
#endif
f1 = fopen( buffer, "rt" );
if( !f1 )
{
SysPrintf( _( "patch file for this game not found. Can't apply any patches\n" ) );
return;
}
inisection_process( f1 );
fclose( f1 );
}
void resetpatch( void )
{
patchnumber = 0;
}
int AddPatch(int Mode, int Place, int Address, int Size, u64 data)
{
if ( patchnumber >= MAX_PATCH )
{
SysPrintf( "Patch ERROR: Maximum number of patches reached.\n");
return -1;
}
patch[patchnumber].placetopatch = Mode;
patch[patchnumber].cpu = Place;
patch[patchnumber].addr=Address;
patch[patchnumber].type=Size;
patch[patchnumber].data = data;
return patchnumber++;
}
void patchFunc_fastmemory( char * cmd, char * param )
{
SetFastMemory(1);
}
void patchFunc_roundmode( char * cmd, char * param )
{
//roundmode = X,Y
int index;
char * pText;
u32 eetype=0x0000;
u32 vutype=0x6000;
index = 0;
pText = strtok( param, ", " );
while(pText != NULL) {
u32 type = 0xffff;
if( stricmp(pText, "near") == 0 ) {
type = 0x0000;
}
else if( stricmp(pText, "down") == 0 ) {
type = 0x2000;
}
else if( stricmp(pText, "up") == 0 ) {
type = 0x4000;
}
else if( stricmp(pText, "chop") == 0 ) {
type = 0x6000;
}
if( type == 0xffff ) {
printf("bad argument (%s) to round mode! skipping...\n", pText);
break;
}
if( index == 0 ) eetype=type;
else vutype=type;
if( index == 1 )
break;
index++;
pText = strtok(NULL, ", ");
}
SetRoundMode(eetype,vutype);
}
void SetRoundMode(u32 ee, u32 vu)
{
g_sseMXCSR = 0x9f80|ee;
g_sseVUMXCSR = 0x9f80|vu;
SetCPUState();
}

78
Patch.h Normal file
View File

@ -0,0 +1,78 @@
#ifndef __PATCH_H__
#define __PATCH_H__
//
// Defines
//
#define MAX_PATCH 1024
#define IFIS(x,str) if(!strnicmp(x,str,sizeof(str)-1))
#define GETNEXT_PARAM() \
while ( *param && ( *param != ',' ) ) param++; \
if ( *param ) param++; \
while ( *param && ( *param == ' ' ) ) param++; \
if ( *param == 0 ) { SysPrintf( _( "Not enough params for inicommand\n" ) ); return; }
//
// Typedefs
//
typedef void (*PATCHTABLEFUNC)( char * text1, char * text2 );
typedef struct
{
char * text;
int code;
PATCHTABLEFUNC func;
} PatchTextTable;
typedef struct
{
int enabled;
int group;
int type;
int cpu;
int placetopatch;
u32 addr;
u64 data;
} IniPatch;
//
// Function prototypes
//
void patchFunc_comment( char * text1, char * text2 );
void patchFunc_gametitle( char * text1, char * text2 );
void patchFunc_patch( char * text1, char * text2 );
void patchFunc_fastmemory( char * text1, char * text2 );
void patchFunc_roundmode( char * text1, char * text2 );
void inifile_trim( char * buffer );
//
// Variables
//
extern PatchTextTable commands[];
extern PatchTextTable dataType[];
extern PatchTextTable cpuCore[];
extern IniPatch patch[ MAX_PATCH ];
extern int patchnumber;
void applypatch( int place );
void inifile_read( char * name );
void inifile_command( char * cmd );
void resetpatch( void );
int AddPatch(int Mode, int Place, int Address, int Size, u64 data);
void SetFastMemory(int); // iR5900LoadStore.c
extern u32 g_sseMXCSR, g_sseVUMXCSR; // iR5900.c
void SetCPUState();
void SetRoundMode(u32 ee, u32 vu);
#endif /* __PATCH_H__ */

607
Plugins.c Normal file
View File

@ -0,0 +1,607 @@
/* 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
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "Common.h"
#include "PsxCommon.h"
#include "GS.h"
#ifdef __MSCW32__
#pragma warning(disable:4244)
#endif
#define CheckErr(func) \
err = SysLibError(); \
if (err != NULL) { SysMessage (_("%s: Error loading %s: %s"), filename, func, err); return -1; }
#define LoadSym(dest, src, name, checkerr) \
dest = (src) SysLoadSym(drv, name); if (checkerr == 1) CheckErr(name); \
if (checkerr == 2) { err = SysLibError(); if (err != NULL) errval = 1; }
#define TestPS2Esyms(type) { \
_PS2EgetLibVersion2 PS2EgetLibVersion2; \
SysLoadSym(drv, "PS2EgetLibType"); CheckErr("PS2EgetLibType"); \
PS2EgetLibVersion2 = (_PS2EgetLibVersion2) SysLoadSym(drv, "PS2EgetLibVersion2"); CheckErr("PS2EgetLibVersion2"); \
SysLoadSym(drv, "PS2EgetLibName"); CheckErr("PS2EgetLibName"); \
if( ((PS2EgetLibVersion2(PS2E_LT_##type) >> 16)&0xff) != PS2E_##type##_VERSION) { \
SysMessage (_("Can't load '%s', wrong PS2E version (%x != %x)"), filename, (PS2EgetLibVersion2(PS2E_LT_##type) >> 16)&0xff, PS2E_##type##_VERSION); return -1; \
} \
}
static char *err;
static int errval;
void *GSplugin;
void CALLBACK GS_printf(int timeout, char *fmt, ...) {
va_list list;
char msg[512];
va_start(list, fmt);
vsprintf(msg, fmt, list);
va_end(list);
SysPrintf(msg);
}
s32 CALLBACK GS_freeze(int mode, freezeData *data) { data->size = 0; return 0; }
void CALLBACK GS_keyEvent(keyEvent *ev) {}
void CALLBACK GS_makeSnapshot(char *path) {}
void CALLBACK GS_irqCallback(void (*callback)()) {}
void CALLBACK GS_configure() {}
void CALLBACK GS_about() {}
long CALLBACK GS_test() { return 0; }
#define LoadGSsym1(dest, name) \
LoadSym(GS##dest, _GS##dest, name, 1);
#define LoadGSsym0(dest, name) \
LoadSym(GS##dest, _GS##dest, name, 0); \
if (GS##dest == NULL) GS##dest = (_GS##dest) GS_##dest;
#define LoadGSsymN(dest, name) \
LoadSym(GS##dest, _GS##dest, name, 0);
int LoadGSplugin(char *filename) {
void *drv;
GSplugin = SysLoadLibrary(filename);
if (GSplugin == NULL) { SysMessage (_("Could Not Load GS Plugin '%s': %s"), filename, SysLibError()); return -1; }
drv = GSplugin;
TestPS2Esyms(GS);
LoadGSsym1(init, "GSinit");
LoadGSsym1(shutdown, "GSshutdown");
LoadGSsym1(open, "GSopen");
LoadGSsym1(close, "GSclose");
LoadGSsym1(gifTransfer1, "GSgifTransfer1");
LoadGSsym1(gifTransfer2, "GSgifTransfer2");
LoadGSsym1(gifTransfer3, "GSgifTransfer3");
LoadGSsym1(readFIFO, "GSreadFIFO");
LoadGSsymN(readFIFO2, "GSreadFIFO2"); // optional
LoadGSsym1(vsync, "GSvsync");
LoadGSsym0(keyEvent, "GSkeyEvent");
LoadGSsymN(changeSaveState, "GSchangeSaveState");
LoadGSsymN(gifSoftReset, "GSgifSoftReset");
LoadGSsym0(makeSnapshot, "GSmakeSnapshot");
LoadGSsym0(irqCallback, "GSirqCallback");
LoadGSsym0(printf, "GSprintf");
LoadGSsym1(setBaseMem, "GSsetBaseMem");
LoadGSsymN(setGameCRC, "GSsetGameCRC");
LoadGSsym1(reset, "GSreset");
LoadGSsym1(writeCSR, "GSwriteCSR");
LoadGSsymN(makeSnapshot2,"GSmakeSnapshot2");
LoadGSsymN(getDriverInfo,"GSgetDriverInfo");
LoadGSsymN(setFrameSkip, "GSsetFrameSkip");
#ifdef __WIN32__
LoadGSsymN(setWindowInfo,"GSsetWindowInfo");
#endif
LoadGSsym0(freeze, "GSfreeze");
LoadGSsym0(configure, "GSconfigure");
LoadGSsym0(about, "GSabout");
LoadGSsym0(test, "GStest");
return 0;
}
void *PAD1plugin;
void CALLBACK PAD1_configure() {}
void CALLBACK PAD1_about() {}
long CALLBACK PAD1_test() { return 0; }
#define LoadPAD1sym1(dest, name) \
LoadSym(PAD1##dest, _PAD##dest, name, 1);
#define LoadPAD1sym0(dest, name) \
LoadSym(PAD1##dest, _PAD##dest, name, 0); \
if (PAD1##dest == NULL) PAD1##dest = (_PAD##dest) PAD1_##dest;
#define LoadPAD1symN(dest, name) \
LoadSym(PAD1##dest, _PAD##dest, name, 0);
int LoadPAD1plugin(char *filename) {
void *drv;
PAD1plugin = SysLoadLibrary(filename);
if (PAD1plugin == NULL) { SysMessage (_("Could Not Load PAD1 Plugin '%s': %s"), filename, SysLibError()); return -1; }
drv = PAD1plugin;
TestPS2Esyms(PAD);
LoadPAD1sym1(init, "PADinit");
LoadPAD1sym1(shutdown, "PADshutdown");
LoadPAD1sym1(open, "PADopen");
LoadPAD1sym1(close, "PADclose");
LoadPAD1sym1(keyEvent, "PADkeyEvent");
LoadPAD1sym1(startPoll, "PADstartPoll");
LoadPAD1sym1(poll, "PADpoll");
LoadPAD1sym1(query, "PADquery");
LoadPAD1symN(gsDriverInfo, "PADgsDriverInfo");
LoadPAD1sym0(configure, "PADconfigure");
LoadPAD1sym0(about, "PADabout");
LoadPAD1sym0(test, "PADtest");
return 0;
}
void *PAD2plugin;
void CALLBACK PAD2_configure() {}
void CALLBACK PAD2_about() {}
long CALLBACK PAD2_test() { return 0; }
#define LoadPAD2sym1(dest, name) \
LoadSym(PAD2##dest, _PAD##dest, name, 1);
#define LoadPAD2sym0(dest, name) \
LoadSym(PAD2##dest, _PAD##dest, name, 0); \
if (PAD2##dest == NULL) PAD2##dest = (_PAD##dest) PAD2_##dest;
#define LoadPAD2symN(dest, name) \
LoadSym(PAD2##dest, _PAD##dest, name, 0);
int LoadPAD2plugin(char *filename) {
void *drv;
PAD2plugin = SysLoadLibrary(filename);
if (PAD2plugin == NULL) { SysMessage (_("Could Not Load PAD2 Plugin '%s': %s"), filename, SysLibError()); return -1; }
drv = PAD2plugin;
TestPS2Esyms(PAD);
LoadPAD2sym1(init, "PADinit");
LoadPAD2sym1(shutdown, "PADshutdown");
LoadPAD2sym1(open, "PADopen");
LoadPAD2sym1(close, "PADclose");
LoadPAD2sym1(keyEvent, "PADkeyEvent");
LoadPAD2sym1(startPoll, "PADstartPoll");
LoadPAD2sym1(poll, "PADpoll");
LoadPAD2sym1(query, "PADquery");
LoadPAD2symN(gsDriverInfo, "PADgsDriverInfo");
LoadPAD2sym0(configure, "PADconfigure");
LoadPAD2sym0(about, "PADabout");
LoadPAD2sym0(test, "PADtest");
return 0;
}
void *SPU2plugin;
s32 CALLBACK SPU2_freeze(int mode, freezeData *data) { data->size = 0; return 0; }
void CALLBACK SPU2_configure() {}
void CALLBACK SPU2_about() {}
s32 CALLBACK SPU2_test() { return 0; }
#define LoadSPU2sym1(dest, name) \
LoadSym(SPU2##dest, _SPU2##dest, name, 1);
#define LoadSPU2sym0(dest, name) \
LoadSym(SPU2##dest, _SPU2##dest, name, 0); \
if (SPU2##dest == NULL) SPU2##dest = (_SPU2##dest) SPU2_##dest;
#define LoadSPU2symN(dest, name) \
LoadSym(SPU2##dest, _SPU2##dest, name, 0);
int LoadSPU2plugin(char *filename) {
void *drv;
SPU2plugin = SysLoadLibrary(filename);
if (SPU2plugin == NULL) { SysMessage (_("Could Not Load SPU2 Plugin '%s': %s"), filename, SysLibError()); return -1; }
drv = SPU2plugin;
TestPS2Esyms(SPU2);
LoadSPU2sym1(init, "SPU2init");
LoadSPU2sym1(shutdown, "SPU2shutdown");
LoadSPU2sym1(open, "SPU2open");
LoadSPU2sym1(close, "SPU2close");
LoadSPU2sym1(write, "SPU2write");
LoadSPU2sym1(read, "SPU2read");
LoadSPU2sym1(readDMA4Mem, "SPU2readDMA4Mem");
LoadSPU2sym1(writeDMA4Mem, "SPU2writeDMA4Mem");
LoadSPU2sym1(interruptDMA4,"SPU2interruptDMA4");
LoadSPU2sym1(readDMA7Mem, "SPU2readDMA7Mem");
LoadSPU2sym1(writeDMA7Mem, "SPU2writeDMA7Mem");
LoadSPU2sym1(interruptDMA7,"SPU2interruptDMA7");
LoadSPU2sym1(ReadMemAddr, "SPU2ReadMemAddr");
LoadSPU2sym1(WriteMemAddr, "SPU2WriteMemAddr");
LoadSPU2sym1(irqCallback, "SPU2irqCallback");
LoadSPU2sym0(freeze, "SPU2freeze");
LoadSPU2sym0(configure, "SPU2configure");
LoadSPU2sym0(about, "SPU2about");
LoadSPU2sym0(test, "SPU2test");
LoadSPU2symN(async, "SPU2async");
return 0;
}
void *CDVDplugin;
void CALLBACK CDVD_configure() {}
void CALLBACK CDVD_about() {}
long CALLBACK CDVD_test() { return 0; }
#define LoadCDVDsym1(dest, name) \
LoadSym(CDVD##dest, _CDVD##dest, name, 1);
#define LoadCDVDsym0(dest, name) \
LoadSym(CDVD##dest, _CDVD##dest, name, 0); \
if (CDVD##dest == NULL) CDVD##dest = (_CDVD##dest) CDVD_##dest;
#define LoadCDVDsymN(dest, name) \
LoadSym(CDVD##dest, _CDVD##dest, name, 0); \
int LoadCDVDplugin(char *filename) {
void *drv;
CDVDplugin = SysLoadLibrary(filename);
if (CDVDplugin == NULL) { SysMessage (_("Could Not Load CDVD Plugin '%s': %s"), filename, SysLibError()); return -1; }
drv = CDVDplugin;
TestPS2Esyms(CDVD);
LoadCDVDsym1(init, "CDVDinit");
LoadCDVDsym1(shutdown, "CDVDshutdown");
LoadCDVDsym1(open, "CDVDopen");
LoadCDVDsym1(close, "CDVDclose");
LoadCDVDsym1(readTrack, "CDVDreadTrack");
LoadCDVDsym1(getBuffer, "CDVDgetBuffer");
LoadCDVDsym1(readSubQ, "CDVDreadSubQ");
LoadCDVDsym1(getTN, "CDVDgetTN");
LoadCDVDsym1(getTD, "CDVDgetTD");
LoadCDVDsym1(getTOC, "CDVDgetTOC");
LoadCDVDsym1(getDiskType, "CDVDgetDiskType");
LoadCDVDsym1(getTrayStatus, "CDVDgetTrayStatus");
LoadCDVDsym1(ctrlTrayOpen, "CDVDctrlTrayOpen");
LoadCDVDsym1(ctrlTrayClose, "CDVDctrlTrayClose");
LoadCDVDsym0(configure, "CDVDconfigure");
LoadCDVDsym0(about, "CDVDabout");
LoadCDVDsym0(test, "CDVDtest");
LoadCDVDsymN(newDiskCB, "CDVDnewDiskCB");
return 0;
}
void *DEV9plugin;
s32 CALLBACK DEV9_freeze(int mode, freezeData *data) { data->size = 0; return 0; }
void CALLBACK DEV9_configure() {}
void CALLBACK DEV9_about() {}
long CALLBACK DEV9_test() { return 0; }
#define LoadDEV9sym1(dest, name) \
LoadSym(DEV9##dest, _DEV9##dest, name, 1);
#define LoadDEV9sym0(dest, name) \
LoadSym(DEV9##dest, _DEV9##dest, name, 0); \
if (DEV9##dest == NULL) DEV9##dest = (_DEV9##dest) DEV9_##dest;
int LoadDEV9plugin(char *filename) {
void *drv;
DEV9plugin = SysLoadLibrary(filename);
if (DEV9plugin == NULL) { SysMessage (_("Could Not Load DEV9 Plugin '%s': %s"), filename, SysLibError()); return -1; }
drv = DEV9plugin;
TestPS2Esyms(DEV9);
LoadDEV9sym1(init, "DEV9init");
LoadDEV9sym1(shutdown, "DEV9shutdown");
LoadDEV9sym1(open, "DEV9open");
LoadDEV9sym1(close, "DEV9close");
LoadDEV9sym1(read8, "DEV9read8");
LoadDEV9sym1(read16, "DEV9read16");
LoadDEV9sym1(read32, "DEV9read32");
LoadDEV9sym1(write8, "DEV9write8");
LoadDEV9sym1(write16, "DEV9write16");
LoadDEV9sym1(write32, "DEV9write32");
LoadDEV9sym1(readDMA8Mem, "DEV9readDMA8Mem");
LoadDEV9sym1(writeDMA8Mem, "DEV9writeDMA8Mem");
LoadDEV9sym1(irqCallback, "DEV9irqCallback");
LoadDEV9sym1(irqHandler, "DEV9irqHandler");
LoadDEV9sym0(freeze, "DEV9freeze");
LoadDEV9sym0(configure, "DEV9configure");
LoadDEV9sym0(about, "DEV9about");
LoadDEV9sym0(test, "DEV9test");
return 0;
}
void *USBplugin;
s32 CALLBACK USB_freeze(int mode, freezeData *data) { data->size = 0; return 0; }
void CALLBACK USB_configure() {}
void CALLBACK USB_about() {}
long CALLBACK USB_test() { return 0; }
#define LoadUSBsym1(dest, name) \
LoadSym(USB##dest, _USB##dest, name, 1);
#define LoadUSBsym0(dest, name) \
LoadSym(USB##dest, _USB##dest, name, 0); \
if (USB##dest == NULL) USB##dest = (_USB##dest) USB_##dest;
int LoadUSBplugin(char *filename) {
void *drv;
USBplugin = SysLoadLibrary(filename);
if (USBplugin == NULL) { SysMessage (_("Could Not Load USB Plugin '%s': %s"), filename, SysLibError()); return -1; }
drv = USBplugin;
TestPS2Esyms(USB);
LoadUSBsym1(init, "USBinit");
LoadUSBsym1(shutdown, "USBshutdown");
LoadUSBsym1(open, "USBopen");
LoadUSBsym1(close, "USBclose");
LoadUSBsym1(read8, "USBread8");
LoadUSBsym1(read16, "USBread16");
LoadUSBsym1(read32, "USBread32");
LoadUSBsym1(write8, "USBwrite8");
LoadUSBsym1(write16, "USBwrite16");
LoadUSBsym1(write32, "USBwrite32");
LoadUSBsym1(irqCallback, "USBirqCallback");
LoadUSBsym1(irqHandler, "USBirqHandler");
LoadUSBsym1(setRAM, "USBsetRAM");
LoadUSBsym0(freeze, "USBfreeze");
LoadUSBsym0(configure, "USBconfigure");
LoadUSBsym0(about, "USBabout");
LoadUSBsym0(test, "USBtest");
return 0;
}
void *FWplugin;
s32 CALLBACK FW_freeze(int mode, freezeData *data) { data->size = 0; return 0; }
void CALLBACK FW_configure() {}
void CALLBACK FW_about() {}
long CALLBACK FW_test() { return 0; }
#define LoadFWsym1(dest, name) \
LoadSym(FW##dest, _FW##dest, name, 1);
#define LoadFWsym0(dest, name) \
LoadSym(FW##dest, _FW##dest, name, 0); \
if (FW##dest == NULL) FW##dest = (_FW##dest) FW_##dest;
int LoadFWplugin(char *filename) {
void *drv;
FWplugin = SysLoadLibrary(filename);
if (FWplugin == NULL) { SysMessage (_("Could Not Load FW Plugin '%s': %s"), filename, SysLibError()); return -1; }
drv = FWplugin;
TestPS2Esyms(FW);
LoadFWsym1(init, "FWinit");
LoadFWsym1(shutdown, "FWshutdown");
LoadFWsym1(open, "FWopen");
LoadFWsym1(close, "FWclose");
LoadFWsym1(read32, "FWread32");
LoadFWsym1(write32, "FWwrite32");
LoadFWsym1(irqCallback, "FWirqCallback");
LoadFWsym0(freeze, "FWfreeze");
LoadFWsym0(configure, "FWconfigure");
LoadFWsym0(about, "FWabout");
LoadFWsym0(test, "FWtest");
return 0;
}
static int loadp=0;
int InitPlugins() {
int ret;
if( GSsetBaseMem ) {
if( CHECK_MULTIGS ) {
extern u8 g_MTGSMem[];
GSsetBaseMem(g_MTGSMem);
}
else {
GSsetBaseMem(PS2MEM_GS);
}
}
ret = GSinit();
if (ret != 0) { SysMessage (_("GSinit error: %d"), ret); return -1; }
ret = PAD1init(1);
if (ret != 0) { SysMessage (_("PAD1init error: %d"), ret); return -1; }
ret = PAD2init(2);
if (ret != 0) { SysMessage (_("PAD2init error: %d"), ret); return -1; }
ret = SPU2init();
if (ret != 0) { SysMessage (_("SPU2init error: %d"), ret); return -1; }
ret = CDVDinit();
if (ret != 0) { SysMessage (_("CDVDinit error: %d"), ret); return -1; }
ret = DEV9init();
if (ret != 0) { SysMessage (_("DEV9init error: %d"), ret); return -1; }
ret = USBinit();
if (ret != 0) { SysMessage (_("USBinit error: %d"), ret); return -1; }
ret = FWinit();
if (ret != 0) { SysMessage (_("FWinit error: %d"), ret); return -1; }
return 0;
}
void ShutdownPlugins() {
GSshutdown();
PAD1shutdown();
PAD2shutdown();
SPU2shutdown();
CDVDshutdown();
DEV9shutdown();
USBshutdown();
FWshutdown();
}
int LoadPlugins() {
char Plugin[256];
sprintf(Plugin, "%s%s", Config.PluginsDir, Config.GS);
if (LoadGSplugin(Plugin) == -1) return -1;
sprintf(Plugin, "%s%s", Config.PluginsDir, Config.PAD1);
if (LoadPAD1plugin(Plugin) == -1) return -1;
sprintf(Plugin, "%s%s", Config.PluginsDir, Config.PAD2);
if (LoadPAD2plugin(Plugin) == -1) return -1;
sprintf(Plugin, "%s%s", Config.PluginsDir, Config.SPU2);
if (LoadSPU2plugin(Plugin) == -1) return -1;
sprintf(Plugin, "%s%s", Config.PluginsDir, Config.CDVD);
if (LoadCDVDplugin(Plugin) == -1) return -1;
sprintf(Plugin, "%s%s", Config.PluginsDir, Config.DEV9);
if (LoadDEV9plugin(Plugin) == -1) return -1;
sprintf(Plugin, "%s%s", Config.PluginsDir, Config.USB);
if (LoadUSBplugin(Plugin) == -1) return -1;
sprintf(Plugin, "%s%s", Config.PluginsDir, Config.FW);
if (LoadFWplugin(Plugin) == -1) return -1;
if (InitPlugins() == -1) return -1;
loadp=1;
return 0;
}
long pDsp;
static pluginsopened = 0;
extern void spu2DMA4Irq();
extern void spu2DMA7Irq();
extern void spu2Irq();
extern HANDLE g_hGSOpen, g_hGSDone;
int OpenPlugins() {
GSdriverInfo info;
int ret;
if (loadp == 0) return -1;
//first we need the data
if (CDVDnewDiskCB) CDVDnewDiskCB(cdvdNewDiskCB);
ret = CDVDopen();
if (ret != 0) { SysMessage (_("Error Opening CDVD Plugin")); return -1; }
cdvdNewDiskCB();
//video
GSirqCallback(gsIrq);
// make sure only call open once per instance
if( !pluginsopened ) {
if( CHECK_MULTIGS ) {
SetEvent(g_hGSOpen);
WaitForSingleObject(g_hGSDone, INFINITE);
}
else {
ret = GSopen((void *)&pDsp, "PCSX2", 0);
if (ret != 0) { SysMessage (_("Error Opening GS Plugin")); return -1; }
}
}
//then the user input
if (GSgetDriverInfo) {
GSgetDriverInfo(&info);
if (PAD1gsDriverInfo) PAD1gsDriverInfo(&info);
if (PAD2gsDriverInfo) PAD2gsDriverInfo(&info);
}
ret = PAD1open((void *)&pDsp);
if (ret != 0) { SysMessage (_("Error Opening PAD1 Plugin")); return -1; }
ret = PAD2open((void *)&pDsp);
if (ret != 0) { SysMessage (_("Error Opening PAD2 Plugin")); return -1; }
//the sound
SPU2irqCallback(spu2Irq,spu2DMA4Irq,spu2DMA7Irq);
ret = SPU2open((void*)&pDsp);
if (ret != 0) { SysMessage (_("Error Opening SPU2 Plugin")); return -1; }
//and last the dev9
DEV9irqCallback(dev9Irq);
dev9Handler = DEV9irqHandler();
ret = DEV9open((void *)&pDsp);
if (ret != 0) { SysMessage (_("Error Opening DEV9 Plugin")); return -1; }
USBirqCallback(usbIrq);
usbHandler = USBirqHandler();
USBsetRAM(psxM);
ret = USBopen((void *)&pDsp);
if (ret != 0) { SysMessage (_("Error Opening USB Plugin")); return -1; }
FWirqCallback(fwIrq);
ret = FWopen((void *)&pDsp);
if (ret != 0) { SysMessage (_("Error Opening FW Plugin")); return -1; }
pluginsopened = 1;
return 0;
}
extern void gsWaitGS();
void ClosePlugins()
{
gsWaitGS();
CDVDclose();
DEV9close();
USBclose();
FWclose();
SPU2close();
PAD1close();
PAD2close();
}
void ResetPlugins() {
gsWaitGS();
ShutdownPlugins();
InitPlugins();
}
void ReleasePlugins() {
if (loadp == 0) return;
if (GSplugin == NULL || PAD1plugin == NULL || PAD2plugin == NULL ||
SPU2plugin == NULL || CDVDplugin == NULL || DEV9plugin == NULL ||
USBplugin == NULL || FWplugin == NULL) return;
ShutdownPlugins();
SysCloseLibrary(GSplugin); GSplugin = NULL;
SysCloseLibrary(PAD1plugin); PAD1plugin = NULL;
SysCloseLibrary(PAD2plugin); PAD2plugin = NULL;
SysCloseLibrary(SPU2plugin); SPU2plugin = NULL;
SysCloseLibrary(CDVDplugin); CDVDplugin = NULL;
SysCloseLibrary(DEV9plugin); DEV9plugin = NULL;
SysCloseLibrary(USBplugin); USBplugin = NULL;
SysCloseLibrary(FWplugin); FWplugin = NULL;
loadp=0;
}

32
Plugins.h Normal file
View File

@ -0,0 +1,32 @@
/* 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 __PLUGINS_H__
#define __PLUGINS_H__
#define PLUGINtypedefs
#define PLUGINfuncs
#include "PS2Edefs.h"
int LoadPlugins();
void ReleasePlugins();
int OpenPlugins();
void ClosePlugins();
void ResetPlugins();
#endif /* __PLUGINS_H__ */

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