aboutsummaryrefslogtreecommitdiff
path: root/libpcsxcore
diff options
context:
space:
mode:
Diffstat (limited to 'libpcsxcore')
-rw-r--r--libpcsxcore/cdriso.c455
-rw-r--r--libpcsxcore/cdrom.c3
-rw-r--r--libpcsxcore/debug.c2
-rw-r--r--libpcsxcore/gte.c6
-rw-r--r--libpcsxcore/gte.h4
-rw-r--r--libpcsxcore/gte_neon.S4
-rw-r--r--libpcsxcore/lightrec/plugin.c600
-rw-r--r--libpcsxcore/misc.c41
-rw-r--r--libpcsxcore/new_dynarec/arm/assem_arm.c (renamed from libpcsxcore/new_dynarec/assem_arm.c)12
-rw-r--r--libpcsxcore/new_dynarec/arm/assem_arm.h (renamed from libpcsxcore/new_dynarec/assem_arm.h)0
-rw-r--r--libpcsxcore/new_dynarec/arm/linkage_arm.S (renamed from libpcsxcore/new_dynarec/linkage_arm.S)2
-rw-r--r--libpcsxcore/new_dynarec/arm/linkage_offsets.h (renamed from libpcsxcore/new_dynarec/linkage_offsets.h)0
-rw-r--r--libpcsxcore/new_dynarec/backends/psx/emu_if.c (renamed from libpcsxcore/new_dynarec/emu_if.c)23
-rw-r--r--libpcsxcore/new_dynarec/backends/psx/emu_if.h (renamed from libpcsxcore/new_dynarec/emu_if.h)6
-rw-r--r--libpcsxcore/new_dynarec/backends/psx/pcsxmem.c (renamed from libpcsxcore/new_dynarec/pcsxmem.c)10
-rw-r--r--libpcsxcore/new_dynarec/backends/psx/pcsxmem.h (renamed from libpcsxcore/new_dynarec/pcsxmem.h)0
-rw-r--r--libpcsxcore/new_dynarec/backends/psx/pcsxmem_inline.c (renamed from libpcsxcore/new_dynarec/pcsxmem_inline.c)0
-rw-r--r--libpcsxcore/new_dynarec/new_dynarec.c254
-rw-r--r--libpcsxcore/new_dynarec/new_dynarec.h12
-rw-r--r--libpcsxcore/new_dynarec/new_dynarec_config.h2
-rw-r--r--libpcsxcore/plugins.c2076
-rw-r--r--libpcsxcore/ppf.c2
-rw-r--r--libpcsxcore/psxbios.c203
-rw-r--r--libpcsxcore/psxcommon.h4
-rw-r--r--libpcsxcore/psxcounters.c2
-rw-r--r--libpcsxcore/psxhle.c12
-rw-r--r--libpcsxcore/psxmem.c26
-rw-r--r--libpcsxcore/psxmem.h4
-rw-r--r--libpcsxcore/r3000a.c6
-rw-r--r--libpcsxcore/sio.c20
-rw-r--r--libpcsxcore/sio.h1
-rw-r--r--libpcsxcore/socket.c19
-rw-r--r--libpcsxcore/system.h1
33 files changed, 2688 insertions, 1124 deletions
diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c
index dca64fa..c8eacb8 100644
--- a/libpcsxcore/cdriso.c
+++ b/libpcsxcore/cdriso.c
@@ -25,19 +25,23 @@
#include "cdriso.h"
#include "ppf.h"
+#include <errno.h>
+#include <zlib.h>
+#ifdef HAVE_CHD
+#include <chd.h>
+#endif
+
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <process.h>
#include <windows.h>
#define strcasecmp _stricmp
-#define usleep(x) Sleep((x) / 1000)
+#define usleep(x) (Sleep((x) / 1000))
#else
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#endif
-#include <errno.h>
-#include <zlib.h>
#define OFF_T_MSB ((off_t)1 << (sizeof(off_t) * 8 - 1))
@@ -92,6 +96,17 @@ static struct {
unsigned int sector_in_blk;
} *compr_img;
+#ifdef HAVE_CHD
+static struct {
+ unsigned char (*buffer)[CD_FRAMESIZE_RAW + SUB_FRAMESIZE];
+ chd_file* chd;
+ const chd_header* header;
+ unsigned int sectors_per_hunk;
+ unsigned int current_hunk;
+ unsigned int sector_in_hunk;
+} *chd_img;
+#endif
+
int (*cdimg_read_func)(FILE *f, unsigned int base, void *dest, int sector);
char* CALLBACK CDR__getDriveLetter(void);
@@ -225,7 +240,9 @@ static void *playthread(void *param)
do {
ret = SPU_playCDDAchannel((short *)sndbuffer, s);
if (ret == 0x7761)
+ {
usleep(6 * 1000);
+ }
} while (ret == 0x7761 && playing); // rearmed_wait
}
@@ -236,7 +253,9 @@ static void *playthread(void *param)
// HACK: stop feeding data while emu is paused
extern int stop;
while (stop && playing)
+ {
usleep(10000);
+ }
now = GetTickCount();
osleep = t - now;
@@ -560,20 +579,15 @@ static int parsecue(const char *isofile) {
if (t != 1)
sscanf(linebuf, " FILE %255s", tmpb);
- // absolute path?
- ti[numtracks + 1].handle = fopen(tmpb, "rb");
- if (ti[numtracks + 1].handle == NULL) {
- // relative to .cue?
- tmp = strrchr(tmpb, '\\');
- if (tmp == NULL)
- tmp = strrchr(tmpb, '/');
- if (tmp != NULL)
- tmp++;
- else
- tmp = tmpb;
- strncpy(incue_fname, tmp, incue_max_len);
- ti[numtracks + 1].handle = fopen(filepath, "rb");
- }
+ tmp = strrchr(tmpb, '\\');
+ if (tmp == NULL)
+ tmp = strrchr(tmpb, '/');
+ if (tmp != NULL)
+ tmp++;
+ else
+ tmp = tmpb;
+ strncpy(incue_fname, tmp, incue_max_len);
+ ti[numtracks + 1].handle = fopen(filepath, "rb");
// update global offset if this is not first file in this .cue
if (numtracks + 1 > 1) {
@@ -1029,6 +1043,80 @@ fail_io:
return -1;
}
+#ifdef HAVE_CHD
+static int handlechd(const char *isofile) {
+ chd_img = calloc(1, sizeof(*chd_img));
+ if (chd_img == NULL)
+ goto fail_io;
+
+ if(chd_open(isofile, CHD_OPEN_READ, NULL, &chd_img->chd) != CHDERR_NONE)
+ goto fail_io;
+
+ chd_img->header = chd_get_header(chd_img->chd);
+
+ chd_img->buffer = malloc(chd_img->header->hunkbytes);
+ if (chd_img->buffer == NULL)
+ goto fail_io;
+
+ chd_img->sectors_per_hunk = chd_img->header->hunkbytes / (CD_FRAMESIZE_RAW + SUB_FRAMESIZE);
+ chd_img->current_hunk = (unsigned int)-1;
+
+ cddaBigEndian = TRUE;
+
+ numtracks = 0;
+ int frame_offset = 150;
+ memset(ti, 0, sizeof(ti));
+
+ while (1)
+ {
+ struct {
+ char type[64];
+ char subtype[32];
+ char pgtype[32];
+ char pgsub[32];
+ uint32_t track;
+ uint32_t frames;
+ uint32_t pregap;
+ uint32_t postgap;
+ } md = {};
+ char meta[256];
+ uint32_t meta_size = 0;
+
+ if (chd_get_metadata(chd_img->chd, CDROM_TRACK_METADATA2_TAG, numtracks, meta, sizeof(meta), &meta_size, NULL, NULL) == CHDERR_NONE)
+ sscanf(meta, CDROM_TRACK_METADATA2_FORMAT, &md.track, md.type, md.subtype, &md.frames, &md.pregap, md.pgtype, md.pgsub, &md.postgap);
+ else if (chd_get_metadata(chd_img->chd, CDROM_TRACK_METADATA_TAG, numtracks, meta, sizeof(meta), &meta_size, NULL, NULL) == CHDERR_NONE)
+ sscanf(meta, CDROM_TRACK_METADATA_FORMAT, &md.track, md.type, md.subtype, &md.frames);
+ else
+ break;
+
+ ti[md.track].type = !strncmp(md.type, "AUDIO", 5) ? CDDA : DATA;
+
+ sec2msf(frame_offset + md.pregap, ti[md.track].start);
+ sec2msf(md.frames - md.pregap, ti[md.track].length);
+
+ if (!strcmp(md.type, md.pgtype))
+ frame_offset += md.pregap;
+
+ ti[md.track].start_offset = frame_offset * CD_FRAMESIZE_RAW;
+
+ frame_offset += md.frames;
+ frame_offset += md.postgap;
+ numtracks++;
+ }
+
+ if (numtracks)
+ return 0;
+
+fail_io:
+ if (chd_img != NULL) {
+ free(chd_img->buffer);
+ free(chd_img);
+ chd_img = NULL;
+ }
+ return -1;
+}
+#endif
+
// this function tries to get the .sub file of the given .img
static int opensubfile(const char *isoname) {
char subname[MAXPATHLEN];
@@ -1052,13 +1140,18 @@ static int opensubfile(const char *isoname) {
}
static int opensbifile(const char *isoname) {
- char sbiname[MAXPATHLEN];
+ char sbiname[MAXPATHLEN], disknum[MAXPATHLEN] = "0";
int s;
strncpy(sbiname, isoname, sizeof(sbiname));
sbiname[MAXPATHLEN - 1] = '\0';
if (strlen(sbiname) >= 4) {
- strcpy(sbiname + strlen(sbiname) - 4, ".sbi");
+ if (cdrIsoMultidiskCount > 1) {
+ sprintf(disknum, "_%i.sbi", cdrIsoMultidiskSelect + 1);
+ strcpy(sbiname + strlen(sbiname) - 4, disknum);
+ }
+ else
+ strcpy(sbiname + strlen(sbiname) - 4, ".sbi");
}
else {
return -1;
@@ -1070,6 +1163,194 @@ static int opensbifile(const char *isoname) {
return LoadSBI(sbiname, s);
}
+#ifdef _WIN32
+static void readThreadStop() {}
+static void readThreadStart() {}
+#else
+static pthread_t read_thread_id;
+
+static pthread_cond_t read_thread_msg_avail;
+static pthread_cond_t read_thread_msg_done;
+static pthread_mutex_t read_thread_msg_lock;
+
+static pthread_cond_t sectorbuffer_cond;
+static pthread_mutex_t sectorbuffer_lock;
+
+static boolean read_thread_running = FALSE;
+static int read_thread_sector_start = -1;
+static int read_thread_sector_end = -1;
+
+typedef struct {
+ int sector;
+ long ret;
+ unsigned char data[CD_FRAMESIZE_RAW];
+} SectorBufferEntry;
+
+#define SECTOR_BUFFER_SIZE 4096
+
+static SectorBufferEntry *sectorbuffer;
+static size_t sectorbuffer_index;
+
+int (*sync_cdimg_read_func)(FILE *f, unsigned int base, void *dest, int sector);
+unsigned char *(*sync_CDR_getBuffer)(void);
+
+static unsigned char * CALLBACK ISOgetBuffer_async(void);
+static int cdread_async(FILE *f, unsigned int base, void *dest, int sector);
+
+static void *readThreadMain(void *param) {
+ int max_sector = -1;
+ int requested_sector_start = -1;
+ int requested_sector_end = -1;
+ int last_read_sector = -1;
+ int index = 0;
+
+ int ra_sector = -1;
+ int max_ra = 128;
+ int initial_ra = 1;
+ int speedmult_ra = 4;
+
+ int ra_count = 0;
+ int how_far_ahead = 0;
+
+ unsigned char tmpdata[CD_FRAMESIZE_RAW];
+ long ret;
+
+ max_sector = msf2sec(ti[numtracks].start) + msf2sec(ti[numtracks].length);
+
+ while(1) {
+ pthread_mutex_lock(&read_thread_msg_lock);
+
+ // If we don't have readahead and we don't have a sector request, wait for one.
+ // If we still have readahead to go, don't block, just keep going.
+ // And if we ever have a sector request pending, acknowledge and reset it.
+
+ if (!ra_count) {
+ if (read_thread_sector_start == -1 && read_thread_running) {
+ pthread_cond_wait(&read_thread_msg_avail, &read_thread_msg_lock);
+ }
+ }
+
+ if (read_thread_sector_start != -1) {
+ requested_sector_start = read_thread_sector_start;
+ requested_sector_end = read_thread_sector_end;
+ read_thread_sector_start = -1;
+ read_thread_sector_end = -1;
+ pthread_cond_signal(&read_thread_msg_done);
+ }
+
+ pthread_mutex_unlock(&read_thread_msg_lock);
+
+ if (!read_thread_running)
+ break;
+
+ // Readahead code, based on the implementation in mednafen psx's cdromif.cpp
+ if (requested_sector_start != -1) {
+ if (last_read_sector != -1 && last_read_sector == (requested_sector_start - 1)) {
+ how_far_ahead = ra_sector - requested_sector_end;
+
+ if(how_far_ahead <= max_ra)
+ ra_count = (max_ra - how_far_ahead + 1 ? max_ra - how_far_ahead + 1 : speedmult_ra);
+ else
+ ra_count++;
+ } else if (requested_sector_end != last_read_sector) {
+ ra_sector = requested_sector_end;
+ ra_count = initial_ra;
+ }
+
+ last_read_sector = requested_sector_end;
+ }
+
+ // check for end of CD
+ if (ra_count && ra_sector >= max_sector) {
+ ra_count = 0;
+ }
+
+ if (ra_count) {
+
+ index = ra_sector % SECTOR_BUFFER_SIZE;
+ pthread_mutex_lock(&sectorbuffer_lock);
+ if (sectorbuffer[index].sector != ra_sector) {
+ pthread_mutex_unlock(&sectorbuffer_lock);
+
+ ret = sync_cdimg_read_func(cdHandle, 0, tmpdata, ra_sector);
+
+ pthread_mutex_lock(&sectorbuffer_lock);
+ sectorbuffer[index].ret = ret;
+ sectorbuffer[index].sector = ra_sector;
+ memcpy(sectorbuffer[index].data, tmpdata, CD_FRAMESIZE_RAW);
+ }
+ pthread_cond_signal(&sectorbuffer_cond);
+ pthread_mutex_unlock(&sectorbuffer_lock);
+
+ ra_sector++;
+ ra_count--;
+ }
+ }
+
+ return NULL;
+}
+
+static void readThreadStop() {
+ if (read_thread_running == TRUE) {
+ read_thread_running = FALSE;
+ pthread_cond_signal(&read_thread_msg_avail);
+ pthread_join(read_thread_id, NULL);
+ }
+
+ pthread_cond_destroy(&read_thread_msg_done);
+ pthread_cond_destroy(&read_thread_msg_avail);
+ pthread_mutex_destroy(&read_thread_msg_lock);
+
+ pthread_cond_destroy(&sectorbuffer_cond);
+ pthread_mutex_destroy(&sectorbuffer_lock);
+
+ CDR_getBuffer = sync_CDR_getBuffer;
+ cdimg_read_func = sync_cdimg_read_func;
+
+ free(sectorbuffer);
+ sectorbuffer = NULL;
+}
+
+static void readThreadStart() {
+ SysPrintf("Starting async CD thread\n");
+
+ if (read_thread_running == TRUE)
+ return;
+
+ read_thread_running = TRUE;
+ read_thread_sector_start = -1;
+ read_thread_sector_end = -1;
+ sectorbuffer_index = 0;
+
+ sectorbuffer = calloc(SECTOR_BUFFER_SIZE, sizeof(SectorBufferEntry));
+ if(!sectorbuffer)
+ goto error;
+
+ sectorbuffer[0].sector = -1; // Otherwise we might think we've already fetched sector 0!
+
+ sync_CDR_getBuffer = CDR_getBuffer;
+ CDR_getBuffer = ISOgetBuffer_async;
+ sync_cdimg_read_func = cdimg_read_func;
+ cdimg_read_func = cdread_async;
+
+ if (pthread_cond_init(&read_thread_msg_avail, NULL) ||
+ pthread_cond_init(&read_thread_msg_done, NULL) ||
+ pthread_mutex_init(&read_thread_msg_lock, NULL) ||
+ pthread_cond_init(&sectorbuffer_cond, NULL) ||
+ pthread_mutex_init(&sectorbuffer_lock, NULL) ||
+ pthread_create(&read_thread_id, NULL, readThreadMain, NULL))
+ goto error;
+
+ return;
+
+ error:
+ SysPrintf("Error starting async CD thread\n");
+ SysPrintf("Falling back to sync\n");
+
+ readThreadStop();
+}
+#endif
+
static int cdread_normal(FILE *f, unsigned int base, void *dest, int sector)
{
fseek(f, base + sector * CD_FRAMESIZE_RAW, SEEK_SET);
@@ -1190,6 +1471,31 @@ finish:
return CD_FRAMESIZE_RAW;
}
+#ifdef HAVE_CHD
+static int cdread_chd(FILE *f, unsigned int base, void *dest, int sector)
+{
+ int hunk;
+
+ if (base)
+ sector += base / CD_FRAMESIZE_RAW;
+
+ hunk = sector / chd_img->sectors_per_hunk;
+ chd_img->sector_in_hunk = sector % chd_img->sectors_per_hunk;
+
+ if (hunk == chd_img->current_hunk)
+ goto finish;
+
+ chd_read(chd_img->chd, hunk, chd_img->buffer);
+
+ chd_img->current_hunk = hunk;
+
+finish:
+ if (dest != cdbuffer) // copy avoid HACK
+ memcpy(dest, chd_img->buffer[chd_img->sector_in_hunk],
+ CD_FRAMESIZE_RAW);
+ return CD_FRAMESIZE_RAW;
+}
+#endif
static int cdread_2048(FILE *f, unsigned int base, void *dest, int sector)
{
int ret;
@@ -1205,10 +1511,75 @@ static int cdread_2048(FILE *f, unsigned int base, void *dest, int sector)
return ret;
}
+#ifndef _WIN32
+
+static int cdread_async(FILE *f, unsigned int base, void *dest, int sector) {
+ boolean found = FALSE;
+ int i = sector % SECTOR_BUFFER_SIZE;
+ long ret;
+
+ if (f != cdHandle || base != 0 || dest != cdbuffer) {
+ // Async reads are only supported for cdbuffer, so call the sync
+ // function directly.
+ return sync_cdimg_read_func(f, base, dest, sector);
+ }
+
+ pthread_mutex_lock(&read_thread_msg_lock);
+
+ // Only wait if we're not trying to read the next sector and
+ // sector_start is set (meaning the last request hasn't been
+ // processed yet)
+ while(read_thread_sector_start != -1 && read_thread_sector_end + 1 != sector) {
+ pthread_cond_wait(&read_thread_msg_done, &read_thread_msg_lock);
+ }
+
+ if (read_thread_sector_start == -1)
+ read_thread_sector_start = sector;
+
+ read_thread_sector_end = sector;
+ pthread_cond_signal(&read_thread_msg_avail);
+ pthread_mutex_unlock(&read_thread_msg_lock);
+
+ do {
+ pthread_mutex_lock(&sectorbuffer_lock);
+ if (sectorbuffer[i].sector == sector) {
+ sectorbuffer_index = i;
+ ret = sectorbuffer[i].ret;
+ found = TRUE;
+ }
+
+ if (!found) {
+ pthread_cond_wait(&sectorbuffer_cond, &sectorbuffer_lock);
+ }
+ pthread_mutex_unlock(&sectorbuffer_lock);
+ } while (!found);
+
+ return ret;
+}
+
+#endif
+
static unsigned char * CALLBACK ISOgetBuffer_compr(void) {
return compr_img->buff_raw[compr_img->sector_in_blk] + 12;
}
+#ifdef HAVE_CHD
+static unsigned char * CALLBACK ISOgetBuffer_chd(void) {
+ return chd_img->buffer[chd_img->sector_in_hunk] + 12;
+}
+#endif
+
+#ifndef _WIN32
+static unsigned char * CALLBACK ISOgetBuffer_async(void) {
+ unsigned char *buffer;
+ pthread_mutex_lock(&sectorbuffer_lock);
+ buffer = sectorbuffer[sectorbuffer_index].data;
+ pthread_mutex_unlock(&sectorbuffer_lock);
+ return buffer + 12;
+}
+
+#endif
+
static unsigned char * CALLBACK ISOgetBuffer(void) {
return cdbuffer + 12;
}
@@ -1230,6 +1601,7 @@ static long CALLBACK ISOopen(void) {
boolean isMode1ISO = FALSE;
char alt_bin_filename[MAXPATHLEN];
const char *bin_filename;
+ char image_str[1024] = {0};
if (cdHandle != NULL) {
return 0; // it's already open
@@ -1242,7 +1614,7 @@ static long CALLBACK ISOopen(void) {
return -1;
}
- SysPrintf(_("Loaded CD Image: %s"), GetIsoFile());
+ sprintf(image_str, "Loaded CD Image: %s", GetIsoFile());
cddaBigEndian = FALSE;
subChanMixed = FALSE;
@@ -1255,33 +1627,40 @@ static long CALLBACK ISOopen(void) {
cdimg_read_func = cdread_normal;
if (parsetoc(GetIsoFile()) == 0) {
- SysPrintf("[+toc]");
+ strcat(image_str, "[+toc]");
}
else if (parseccd(GetIsoFile()) == 0) {
- SysPrintf("[+ccd]");
+ strcat(image_str, "[+ccd]");
}
else if (parsemds(GetIsoFile()) == 0) {
- SysPrintf("[+mds]");
+ strcat(image_str, "[+mds]");
}
else if (parsecue(GetIsoFile()) == 0) {
- SysPrintf("[+cue]");
+ strcat(image_str, "[+cue]");
}
if (handlepbp(GetIsoFile()) == 0) {
- SysPrintf("[pbp]");
+ strcat(image_str, "[+pbp]");
CDR_getBuffer = ISOgetBuffer_compr;
cdimg_read_func = cdread_compressed;
}
else if (handlecbin(GetIsoFile()) == 0) {
- SysPrintf("[cbin]");
+ strcat(image_str, "[+cbin]");
CDR_getBuffer = ISOgetBuffer_compr;
cdimg_read_func = cdread_compressed;
}
+#ifdef HAVE_CHD
+ else if (handlechd(GetIsoFile()) == 0) {
+ strcat(image_str, "[+chd]");
+ CDR_getBuffer = ISOgetBuffer_chd;
+ cdimg_read_func = cdread_chd;
+ }
+#endif
if (!subChanMixed && opensubfile(GetIsoFile()) == 0) {
- SysPrintf("[+sub]");
+ strcat(image_str, "[+sub]");
}
if (opensbifile(GetIsoFile()) == 0) {
- SysPrintf("[+sbi]");
+ strcat(image_str, "[+sbi]");
}
fseeko(cdHandle, 0, SEEK_END);
@@ -1319,13 +1698,13 @@ static long CALLBACK ISOopen(void) {
fseek(cdHandle, 0, SEEK_SET);
fread(&modeTest, 4, 1, cdHandle);
if (SWAP32(modeTest) != 0xffffff00) {
- SysPrintf("[2048]");
+ strcat(image_str, "[2048]");
isMode1ISO = TRUE;
}
}
fseek(cdHandle, 0, SEEK_SET);
- SysPrintf(".\n");
+ SysPrintf("%s.\n", image_str);
PrintTracks();
@@ -1341,6 +1720,9 @@ static long CALLBACK ISOopen(void) {
cdda_cur_sector = 0;
cdda_file_offset = 0;
+ if (Config.AsyncCD) {
+ readThreadStart();
+ }
return 0;
}
@@ -1364,6 +1746,15 @@ static long CALLBACK ISOclose(void) {
compr_img = NULL;
}
+#ifdef HAVE_CHD
+ if (chd_img != NULL) {
+ chd_close(chd_img->chd);
+ free(chd_img->buffer);
+ free(chd_img);
+ chd_img = NULL;
+ }
+#endif
+
for (i = 1; i <= numtracks; i++) {
if (ti[i].handle != NULL) {
fclose(ti[i].handle);
@@ -1377,6 +1768,10 @@ static long CALLBACK ISOclose(void) {
memset(cdbuffer, 0, sizeof(cdbuffer));
CDR_getBuffer = ISOgetBuffer;
+ if (Config.AsyncCD) {
+ readThreadStop();
+ }
+
return 0;
}
diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c
index a725efa..43d25d3 100644
--- a/libpcsxcore/cdrom.c
+++ b/libpcsxcore/cdrom.c
@@ -878,7 +878,8 @@ void cdrInterrupt() {
}
cdr.Result[0] |= (cdr.Result[1] >> 4) & 0x08;
- strncpy((char *)&cdr.Result[4], "PCSX", 4);
+ /* This adds the string "PCSX" in Playstation bios boot screen */
+ memcpy((char *)&cdr.Result[4], "PCSX", 4);
cdr.Stat = Complete;
break;
diff --git a/libpcsxcore/debug.c b/libpcsxcore/debug.c
index 763dc45..4ba7f57 100644
--- a/libpcsxcore/debug.c
+++ b/libpcsxcore/debug.c
@@ -445,7 +445,7 @@ static void ProcessCommands() {
sprintf(reply, "200 %s\r\n", arguments == NULL ? "OK" : arguments);
break;
case 0x101:
- sprintf(reply, "201 %s\r\n", PACKAGE_VERSION);
+ sprintf(reply, "201 %s\r\n", PCSX_VERSION);
break;
case 0x102:
sprintf(reply, "202 1.0\r\n");
diff --git a/libpcsxcore/gte.c b/libpcsxcore/gte.c
index 77dff1b..83bb4b6 100644
--- a/libpcsxcore/gte.c
+++ b/libpcsxcore/gte.c
@@ -258,7 +258,7 @@ static inline u32 limE_(psxCP2Regs *regs, u32 result) {
#ifndef FLAGLESS
-static inline u32 MFC2(int reg) {
+u32 MFC2(int reg) {
psxCP2Regs *regs = &psxRegs.CP2;
switch (reg) {
case 1:
@@ -293,7 +293,7 @@ static inline u32 MFC2(int reg) {
return psxRegs.CP2D.r[reg];
}
-static inline void MTC2(u32 value, int reg) {
+void MTC2(u32 value, int reg) {
psxCP2Regs *regs = &psxRegs.CP2;
switch (reg) {
case 15:
@@ -339,7 +339,7 @@ static inline void MTC2(u32 value, int reg) {
}
}
-static inline void CTC2(u32 value, int reg) {
+void CTC2(u32 value, int reg) {
switch (reg) {
case 4:
case 12:
diff --git a/libpcsxcore/gte.h b/libpcsxcore/gte.h
index 7646226..8bc6988 100644
--- a/libpcsxcore/gte.h
+++ b/libpcsxcore/gte.h
@@ -67,6 +67,10 @@ extern "C" {
struct psxCP2Regs;
+u32 MFC2(int reg);
+void MTC2(u32 value, int reg);
+void CTC2(u32 value, int reg);
+
void gteMFC2();
void gteCFC2();
void gteMTC2();
diff --git a/libpcsxcore/gte_neon.S b/libpcsxcore/gte_neon.S
index 7d97ff3..60065f8 100644
--- a/libpcsxcore/gte_neon.S
+++ b/libpcsxcore/gte_neon.S
@@ -1,12 +1,12 @@
/*
- * (C) GraÅžvydas "notaz" Ignotas, 2011
+ * (C) Gražvydas "notaz" Ignotas, 2011
*
* This work is licensed under the terms of GNU GPL version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "arm_features.h"
-#include "new_dynarec/linkage_offsets.h"
+#include "new_dynarec/arm/linkage_offsets.h"
.syntax unified
.text
diff --git a/libpcsxcore/lightrec/plugin.c b/libpcsxcore/lightrec/plugin.c
new file mode 100644
index 0000000..9e3c0c7
--- /dev/null
+++ b/libpcsxcore/lightrec/plugin.c
@@ -0,0 +1,600 @@
+#include <lightrec.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include "../cdrom.h"
+#include "../gpu.h"
+#include "../gte.h"
+#include "../mdec.h"
+#include "../psxdma.h"
+#include "../psxhw.h"
+#include "../psxmem.h"
+#include "../r3000a.h"
+
+#include "../frontend/main.h"
+
+#define ARRAY_SIZE(x) (sizeof(x) ? sizeof(x) / sizeof((x)[0]) : 0)
+
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define LE32TOH(x) __builtin_bswap32(x)
+# define HTOLE32(x) __builtin_bswap32(x)
+# define LE16TOH(x) __builtin_bswap16(x)
+# define HTOLE16(x) __builtin_bswap16(x)
+#else
+# define LE32TOH(x) (x)
+# define HTOLE32(x) (x)
+# define LE16TOH(x) (x)
+# define HTOLE16(x) (x)
+#endif
+
+#ifdef __GNUC__
+# define likely(x) __builtin_expect(!!(x),1)
+# define unlikely(x) __builtin_expect(!!(x),0)
+#else
+# define likely(x) (x)
+# define unlikely(x) (x)
+#endif
+
+static struct lightrec_state *lightrec_state;
+
+static char *name = "retroarch.exe";
+
+static bool use_lightrec_interpreter;
+static bool use_pcsx_interpreter;
+static bool lightrec_debug;
+static bool lightrec_very_debug;
+static u32 lightrec_begin_cycles;
+
+int stop;
+u32 cycle_multiplier;
+int new_dynarec_hacks;
+
+/* Unused for now */
+u32 event_cycles[PSXINT_COUNT];
+u32 next_interupt;
+
+void new_dyna_before_save() {}
+void new_dyna_after_save() {}
+void new_dyna_freeze(void *f, int i) {}
+
+enum my_cp2_opcodes {
+ OP_CP2_RTPS = 0x01,
+ OP_CP2_NCLIP = 0x06,
+ OP_CP2_OP = 0x0c,
+ OP_CP2_DPCS = 0x10,
+ OP_CP2_INTPL = 0x11,
+ OP_CP2_MVMVA = 0x12,
+ OP_CP2_NCDS = 0x13,
+ OP_CP2_CDP = 0x14,
+ OP_CP2_NCDT = 0x16,
+ OP_CP2_NCCS = 0x1b,
+ OP_CP2_CC = 0x1c,
+ OP_CP2_NCS = 0x1e,
+ OP_CP2_NCT = 0x20,
+ OP_CP2_SQR = 0x28,
+ OP_CP2_DCPL = 0x29,
+ OP_CP2_DPCT = 0x2a,
+ OP_CP2_AVSZ3 = 0x2d,
+ OP_CP2_AVSZ4 = 0x2e,
+ OP_CP2_RTPT = 0x30,
+ OP_CP2_GPF = 0x3d,
+ OP_CP2_GPL = 0x3e,
+ OP_CP2_NCCT = 0x3f,
+};
+
+static void (*cp2_ops[])(struct psxCP2Regs *) = {
+ [OP_CP2_RTPS] = gteRTPS,
+ [OP_CP2_RTPS] = gteRTPS,
+ [OP_CP2_NCLIP] = gteNCLIP,
+ [OP_CP2_OP] = gteOP,
+ [OP_CP2_DPCS] = gteDPCS,
+ [OP_CP2_INTPL] = gteINTPL,
+ [OP_CP2_MVMVA] = gteMVMVA,
+ [OP_CP2_NCDS] = gteNCDS,
+ [OP_CP2_CDP] = gteCDP,
+ [OP_CP2_NCDT] = gteNCDT,
+ [OP_CP2_NCCS] = gteNCCS,
+ [OP_CP2_CC] = gteCC,
+ [OP_CP2_NCS] = gteNCS,
+ [OP_CP2_NCT] = gteNCT,
+ [OP_CP2_SQR] = gteSQR,
+ [OP_CP2_DCPL] = gteDCPL,
+ [OP_CP2_DPCT] = gteDPCT,
+ [OP_CP2_AVSZ3] = gteAVSZ3,
+ [OP_CP2_AVSZ4] = gteAVSZ4,
+ [OP_CP2_RTPT] = gteRTPT,
+ [OP_CP2_GPF] = gteGPF,
+ [OP_CP2_GPL] = gteGPL,
+ [OP_CP2_NCCT] = gteNCCT,
+};
+
+static char cache_buf[64 * 1024];
+
+static u32 cop0_mfc(struct lightrec_state *state, u32 op, u8 reg)
+{
+ return psxRegs.CP0.r[reg];
+}
+
+static u32 cop2_mfc_cfc(struct lightrec_state *state, u8 reg, bool cfc)
+{
+ if (cfc)
+ return psxRegs.CP2C.r[reg];
+ else
+ return MFC2(reg);
+}
+
+static u32 cop2_mfc(struct lightrec_state *state, u32 op, u8 reg)
+{
+ return cop2_mfc_cfc(state, reg, false);
+}
+
+static u32 cop2_cfc(struct lightrec_state *state, u32 op, u8 reg)
+{
+ return cop2_mfc_cfc(state, reg, true);
+}
+
+static void cop0_mtc_ctc(struct lightrec_state *state,
+ u8 reg, u32 value, bool ctc)
+{
+ switch (reg) {
+ case 1:
+ case 4:
+ case 8:
+ case 14:
+ case 15:
+ /* Those registers are read-only */
+ break;
+ case 12: /* Status */
+ if ((psxRegs.CP0.n.Status & ~value) & (1 << 16)) {
+ memcpy(psxM, cache_buf, sizeof(cache_buf));
+ lightrec_invalidate_all(state);
+ } else if ((~psxRegs.CP0.n.Status & value) & (1 << 16)) {
+ memcpy(cache_buf, psxM, sizeof(cache_buf));
+ }
+
+ psxRegs.CP0.n.Status = value;
+ lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT);
+ break;
+ case 13: /* Cause */
+ psxRegs.CP0.n.Cause &= ~0x0300;
+ psxRegs.CP0.n.Cause |= value & 0x0300;
+ lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT);
+ break;
+ default:
+ psxRegs.CP0.r[reg] = value;
+ break;
+ }
+}
+
+static void cop2_mtc_ctc(struct lightrec_state *state,
+ u8 reg, u32 value, bool ctc)
+{
+ if (ctc)
+ CTC2(value, reg);
+ else
+ MTC2(value, reg);
+}
+
+static void cop0_mtc(struct lightrec_state *state, u32 op, u8 reg, u32 value)
+{
+ cop0_mtc_ctc(state, reg, value, false);
+}
+
+static void cop0_ctc(struct lightrec_state *state, u32 op, u8 reg, u32 value)
+{
+ cop0_mtc_ctc(state, reg, value, true);
+}
+
+static void cop2_mtc(struct lightrec_state *state, u32 op, u8 reg, u32 value)
+{
+ cop2_mtc_ctc(state, reg, value, false);
+}
+
+static void cop2_ctc(struct lightrec_state *state, u32 op, u8 reg, u32 value)
+{
+ cop2_mtc_ctc(state, reg, value, true);
+}
+
+static void cop0_op(struct lightrec_state *state, u32 func)
+{
+ fprintf(stderr, "Invalid access to COP0\n");
+}
+
+static void cop2_op(struct lightrec_state *state, u32 func)
+{
+ psxRegs.code = func;
+
+ if (unlikely(!cp2_ops[func & 0x3f]))
+ fprintf(stderr, "Invalid CP2 function %u\n", func);
+ else
+ cp2_ops[func & 0x3f](&psxRegs.CP2);
+}
+
+static void hw_write_byte(struct lightrec_state *state,
+ u32 op, void *host, u32 mem, u8 val)
+{
+ psxRegs.cycle = lightrec_current_cycle_count(state);
+
+ psxHwWrite8(mem, val);
+ lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT);
+
+ lightrec_reset_cycle_count(state, psxRegs.cycle);
+}
+
+static void hw_write_half(struct lightrec_state *state,
+ u32 op, void *host, u32 mem, u16 val)
+{
+ psxRegs.cycle = lightrec_current_cycle_count(state);
+
+ psxHwWrite16(mem, val);
+ lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT);
+
+ lightrec_reset_cycle_count(state, psxRegs.cycle);
+}
+
+static void hw_write_word(struct lightrec_state *state,
+ u32 op, void *host, u32 mem, u32 val)
+{
+ psxRegs.cycle = lightrec_current_cycle_count(state);
+
+ psxHwWrite32(mem, val);
+ lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT);
+
+ lightrec_reset_cycle_count(state, psxRegs.cycle);
+}
+
+static u8 hw_read_byte(struct lightrec_state *state, u32 op, void *host, u32 mem)
+{
+ u8 val;
+
+ psxRegs.cycle = lightrec_current_cycle_count(state);
+
+ lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT);
+ val = psxHwRead8(mem);
+ lightrec_reset_cycle_count(state, psxRegs.cycle);
+
+ return val;
+}
+
+static u16 hw_read_half(struct lightrec_state *state,
+ u32 op, void *host, u32 mem)
+{
+ u16 val;
+
+ psxRegs.cycle = lightrec_current_cycle_count(state);
+
+ lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT);
+ val = psxHwRead16(mem);
+ lightrec_reset_cycle_count(state, psxRegs.cycle);
+
+ return val;
+}
+
+static u32 hw_read_word(struct lightrec_state *state,
+ u32 op, void *host, u32 mem)
+{
+ u32 val;
+
+ psxRegs.cycle = lightrec_current_cycle_count(state);
+
+ lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT);
+ val = psxHwRead32(mem);
+ lightrec_reset_cycle_count(state, psxRegs.cycle);
+
+ return val;
+}
+
+static struct lightrec_mem_map_ops hw_regs_ops = {
+ .sb = hw_write_byte,
+ .sh = hw_write_half,
+ .sw = hw_write_word,
+ .lb = hw_read_byte,
+ .lh = hw_read_half,
+ .lw = hw_read_word,
+};
+
+static u32 cache_ctrl;
+
+static void cache_ctrl_write_word(struct lightrec_state *state,
+ u32 op, void *host, u32 mem, u32 val)
+{
+ cache_ctrl = val;
+}
+
+static u32 cache_ctrl_read_word(struct lightrec_state *state,
+ u32 op, void *host, u32 mem)
+{
+ return cache_ctrl;
+}
+
+static struct lightrec_mem_map_ops cache_ctrl_ops = {
+ .sw = cache_ctrl_write_word,
+ .lw = cache_ctrl_read_word,
+};
+
+static struct lightrec_mem_map lightrec_map[] = {
+ [PSX_MAP_KERNEL_USER_RAM] = {
+ /* Kernel and user memory */
+ .pc = 0x00000000,
+ .length = 0x200000,
+ },
+ [PSX_MAP_BIOS] = {
+ /* BIOS */
+ .pc = 0x1fc00000,
+ .length = 0x80000,
+ },
+ [PSX_MAP_SCRATCH_PAD] = {
+ /* Scratch pad */
+ .pc = 0x1f800000,
+ .length = 0x400,
+ },
+ [PSX_MAP_PARALLEL_PORT] = {
+ /* Parallel port */
+ .pc = 0x1f000000,
+ .length = 0x10000,
+ },
+ [PSX_MAP_HW_REGISTERS] = {
+ /* Hardware registers */
+ .pc = 0x1f801000,
+ .length = 0x2000,
+ .ops = &hw_regs_ops,
+ },
+ [PSX_MAP_CACHE_CONTROL] = {
+ /* Cache control */
+ .pc = 0x5ffe0130,
+ .length = 4,
+ .ops = &cache_ctrl_ops,
+ },
+
+ /* Mirrors of the kernel/user memory */
+ [PSX_MAP_MIRROR1] = {
+ .pc = 0x00200000,
+ .length = 0x200000,
+ .mirror_of = &lightrec_map[PSX_MAP_KERNEL_USER_RAM],
+ },
+ [PSX_MAP_MIRROR2] = {
+ .pc = 0x00400000,
+ .length = 0x200000,
+ .mirror_of = &lightrec_map[PSX_MAP_KERNEL_USER_RAM],
+ },
+ [PSX_MAP_MIRROR3] = {
+ .pc = 0x00600000,
+ .length = 0x200000,
+ .mirror_of = &lightrec_map[PSX_MAP_KERNEL_USER_RAM],
+ },
+};
+
+static const struct lightrec_ops lightrec_ops = {
+ .cop0_ops = {
+ .mfc = cop0_mfc,
+ .cfc = cop0_mfc,
+ .mtc = cop0_mtc,
+ .ctc = cop0_ctc,
+ .op = cop0_op,
+ },
+ .cop2_ops = {
+ .mfc = cop2_mfc,
+ .cfc = cop2_cfc,
+ .mtc = cop2_mtc,
+ .ctc = cop2_ctc,
+ .op = cop2_op,
+ },
+};
+
+static int lightrec_plugin_init(void)
+{
+ lightrec_map[PSX_MAP_KERNEL_USER_RAM].address = psxM;
+ lightrec_map[PSX_MAP_BIOS].address = psxR;
+ lightrec_map[PSX_MAP_SCRATCH_PAD].address = psxH;
+ lightrec_map[PSX_MAP_PARALLEL_PORT].address = psxP;
+
+ lightrec_debug = !!getenv("LIGHTREC_DEBUG");
+ lightrec_very_debug = !!getenv("LIGHTREC_VERY_DEBUG");
+ use_lightrec_interpreter = !!getenv("LIGHTREC_INTERPRETER");
+ if (getenv("LIGHTREC_BEGIN_CYCLES"))
+ lightrec_begin_cycles = (unsigned int) strtol(
+ getenv("LIGHTREC_BEGIN_CYCLES"), NULL, 0);
+
+ lightrec_state = lightrec_init(name,
+ lightrec_map, ARRAY_SIZE(lightrec_map),
+ &lightrec_ops);
+
+ fprintf(stderr, "M=0x%lx, P=0x%lx, R=0x%lx, H=0x%lx\n",
+ (uintptr_t) psxM,
+ (uintptr_t) psxP,
+ (uintptr_t) psxR,
+ (uintptr_t) psxH);
+
+#ifndef _WIN32
+ signal(SIGPIPE, exit);
+#endif
+ return 0;
+}
+
+static u32 hash_calculate_le(const void *buffer, u32 count)
+{
+ unsigned int i;
+ u32 *data = (u32 *) buffer;
+ u32 hash = 0xffffffff;
+
+ count /= 4;
+ for(i = 0; i < count; ++i) {
+ hash += LE32TOH(data[i]);
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ }
+
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ hash += (hash << 15);
+ return hash;
+}
+
+static u32 hash_calculate(const void *buffer, u32 count)
+{
+ unsigned int i;
+ u32 *data = (u32 *) buffer;
+ u32 hash = 0xffffffff;
+
+ count /= 4;
+ for(i = 0; i < count; ++i) {
+ hash += data[i];
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ }
+
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ hash += (hash << 15);
+ return hash;
+}
+
+static const char * const mips_regs[] = {
+ "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",
+ "lo", "hi",
+};
+
+static void print_for_big_ass_debugger(void)
+{
+ unsigned int i;
+
+ printf("CYCLE 0x%08x PC 0x%08x", psxRegs.cycle, psxRegs.pc);
+
+ if (lightrec_very_debug)
+ printf(" RAM 0x%08x SCRATCH 0x%08x HW 0x%08x",
+ hash_calculate_le(psxM, 0x200000),
+ hash_calculate_le(psxH, 0x400),
+ hash_calculate_le(psxH + 0x1000, 0x2000));
+
+ printf(" CP0 0x%08x CP2D 0x%08x CP2C 0x%08x INT 0x%04x INTCYCLE 0x%08x GPU 0x%08x",
+ hash_calculate(&psxRegs.CP0.r,
+ sizeof(psxRegs.CP0.r)),
+ hash_calculate(&psxRegs.CP2D.r,
+ sizeof(psxRegs.CP2D.r)),
+ hash_calculate(&psxRegs.CP2C.r,
+ sizeof(psxRegs.CP2C.r)),
+ psxRegs.interrupt,
+ hash_calculate(psxRegs.intCycle,
+ sizeof(psxRegs.intCycle)),
+ LE32TOH(HW_GPU_STATUS));
+
+ if (lightrec_very_debug)
+ for (i = 0; i < 34; i++)
+ printf(" %s 0x%08x", mips_regs[i], psxRegs.GPR.r[i]);
+ else
+ printf(" GPR 0x%08x", hash_calculate(&psxRegs.GPR.r,
+ sizeof(psxRegs.GPR.r)));
+ printf("\n");
+}
+
+
+extern void intExecuteBlock();
+
+static u32 old_cycle_counter;
+
+static void lightrec_plugin_execute_block(void)
+{
+ u32 old_pc = psxRegs.pc;
+ u32 flags;
+
+ if (use_pcsx_interpreter) {
+ intExecuteBlock();
+ } else {
+ lightrec_reset_cycle_count(lightrec_state, psxRegs.cycle);
+ lightrec_restore_registers(lightrec_state, psxRegs.GPR.r);
+
+ if (use_lightrec_interpreter)
+ psxRegs.pc = lightrec_run_interpreter(lightrec_state,
+ psxRegs.pc);
+ else
+ psxRegs.pc = lightrec_execute_one(lightrec_state,
+ psxRegs.pc);
+
+ psxRegs.cycle = lightrec_current_cycle_count(lightrec_state);
+
+ lightrec_dump_registers(lightrec_state, psxRegs.GPR.r);
+ flags = lightrec_exit_flags(lightrec_state);
+
+ if (flags & LIGHTREC_EXIT_SEGFAULT) {
+ fprintf(stderr, "Exiting at cycle 0x%08x\n",
+ psxRegs.cycle);
+ exit(1);
+ }
+
+ if (flags & LIGHTREC_EXIT_SYSCALL)
+ psxException(0x20, 0);
+ }
+
+ psxBranchTest();
+
+ if (lightrec_debug && psxRegs.cycle >= lightrec_begin_cycles
+ && psxRegs.pc != old_pc)
+ print_for_big_ass_debugger();
+
+ if ((psxRegs.CP0.n.Cause & psxRegs.CP0.n.Status & 0x300) &&
+ (psxRegs.CP0.n.Status & 0x1)) {
+ /* Handle software interrupts */
+ psxRegs.CP0.n.Cause &= ~0x7c;
+ psxException(psxRegs.CP0.n.Cause, 0);
+ }
+
+ if ((psxRegs.cycle & ~0xfffffff) != old_cycle_counter) {
+ SysDLog("RAM usage: Lightrec %u KiB, IR %u KiB, CODE %u KiB, "
+ "MIPS %u KiB, TOTAL %u KiB, avg. IPI %f\n",
+ lightrec_get_mem_usage(MEM_FOR_LIGHTREC) / 1024,
+ lightrec_get_mem_usage(MEM_FOR_IR) / 1024,
+ lightrec_get_mem_usage(MEM_FOR_CODE) / 1024,
+ lightrec_get_mem_usage(MEM_FOR_MIPS_CODE) / 1024,
+ lightrec_get_total_mem_usage() / 1024,
+ lightrec_get_average_ipi());
+ old_cycle_counter = psxRegs.cycle & ~0xfffffff;
+ }
+}
+
+static void lightrec_plugin_execute(void)
+{
+ extern int stop;
+
+ while (!stop)
+ lightrec_plugin_execute_block();
+}
+
+static void lightrec_plugin_clear(u32 addr, u32 size)
+{
+ if (addr == 0 && size == UINT32_MAX)
+ lightrec_invalidate_all(lightrec_state);
+ else
+ /* size * 4: PCSX uses DMA units */
+ lightrec_invalidate(lightrec_state, addr, size * 4);
+}
+
+static void lightrec_plugin_shutdown(void)
+{
+ lightrec_destroy(lightrec_state);
+}
+
+static void lightrec_plugin_reset(void)
+{
+ lightrec_plugin_shutdown();
+ lightrec_plugin_init();
+}
+
+R3000Acpu psxRec =
+{
+ lightrec_plugin_init,
+ lightrec_plugin_reset,
+ lightrec_plugin_execute,
+ lightrec_plugin_execute_block,
+ lightrec_plugin_clear,
+ lightrec_plugin_shutdown,
+};
diff --git a/libpcsxcore/misc.c b/libpcsxcore/misc.c
index 58170cf..d42576c 100644
--- a/libpcsxcore/misc.c
+++ b/libpcsxcore/misc.c
@@ -73,7 +73,7 @@ void mmssdd( char *b, char *p )
m = ((m / 10) << 4) | m % 10;
s = ((s / 10) << 4) | s % 10;
- d = ((d / 10) << 4) | d % 10;
+ d = ((d / 10) << 4) | d % 10;
p[0] = m;
p[1] = s;
@@ -180,7 +180,7 @@ int LoadCdrom() {
// is just below, do it here
fake_bios_gpu_setup();
- if (!Config.HLE) {
+ if (!Config.HLE && !Config.SlowBoot) {
// skip BIOS logos
psxRegs.pc = psxRegs.GPR.n.ra;
return 0;
@@ -191,7 +191,7 @@ int LoadCdrom() {
READTRACK();
// skip head and sub, and go to the root directory record
- dir = (struct iso_directory_record*) &buf[12+156];
+ dir = (struct iso_directory_record*) &buf[12+156];
mmssdd(dir->extent, (char*)time);
@@ -236,7 +236,7 @@ int LoadCdrom() {
psxRegs.pc = SWAP32(tmpHead.pc0);
psxRegs.GPR.n.gp = SWAP32(tmpHead.gp0);
- psxRegs.GPR.n.sp = SWAP32(tmpHead.s_addr);
+ psxRegs.GPR.n.sp = SWAP32(tmpHead.s_addr);
if (psxRegs.GPR.n.sp == 0) psxRegs.GPR.n.sp = 0x801fff00;
tmpHead.t_size = SWAP32(tmpHead.t_size);
@@ -275,7 +275,7 @@ int LoadCdromFile(const char *filename, EXE_HEADER *head) {
READTRACK();
// skip head and sub, and go to the root directory record
- dir = (struct iso_directory_record *)&buf[12 + 156];
+ dir = (struct iso_directory_record *)&buf[12 + 156];
mmssdd(dir->extent, (char*)time);
@@ -329,7 +329,7 @@ int CheckCdrom() {
strncpy(CdromLabel, buf + 52, 32);
// skip head and sub, and go to the root directory record
- dir = (struct iso_directory_record *)&buf[12 + 156];
+ dir = (struct iso_directory_record *)&buf[12 + 156];
mmssdd(dir->extent, (char *)time);
@@ -357,6 +357,14 @@ int CheckCdrom() {
return -1;
}
}
+ /* Workaround for Wild Arms EU/US which has non-standard string causing incorrect region detection */
+ if (exename[0] == 'E' && exename[1] == 'X' && exename[2] == 'E' && exename[3] == '\\') {
+ size_t offset = 4;
+ size_t i, len = strlen(exename) - offset;
+ for (i = 0; i < len; i++)
+ exename[i] = exename[i + offset];
+ exename[i] = '\0';
+ }
} else if (GetCdromFile(mdir, time, "PSX.EXE;1") != -1) {
strcpy(exename, "PSX.EXE;1");
strcpy(CdromId, "SLUS99999");
@@ -384,7 +392,7 @@ int CheckCdrom() {
}
if (CdromLabel[0] == ' ') {
- strncpy(CdromLabel, CdromId, 9);
+ memcpy(CdromLabel, CdromId, 9);
}
SysPrintf(_("CD-ROM Label: %.32s\n"), CdromLabel);
SysPrintf(_("CD-ROM ID: %.9s\n"), CdromId);
@@ -426,7 +434,7 @@ size_t fread_to_ram(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
void *tmp;
size_t ret = 0;
-
+
tmp = malloc(size * nmemb);
if (tmp) {
ret = fread(tmp, size, nmemb, stream);
@@ -445,8 +453,8 @@ int Load(const char *ExePath) {
u32 section_address, section_size;
void *mem;
- strncpy(CdromId, "SLUS99999", 9);
- strncpy(CdromLabel, "SLUS_999.99", 11);
+ strcpy(CdromId, "SLUS99999");
+ strcpy(CdromLabel, "SLUS_999.99");
tmpFile = fopen(ExePath, "rb");
if (tmpFile == NULL) {
@@ -461,14 +469,14 @@ int Load(const char *ExePath) {
section_size = SWAP32(tmpHead.t_size);
mem = PSXM(section_address);
if (mem != NULL) {
- fseek(tmpFile, 0x800, SEEK_SET);
+ fseek(tmpFile, 0x800, SEEK_SET);
fread_to_ram(mem, section_size, 1, tmpFile);
psxCpu->Clear(section_address, section_size / 4);
}
fclose(tmpFile);
psxRegs.pc = SWAP32(tmpHead.pc0);
psxRegs.GPR.n.gp = SWAP32(tmpHead.gp0);
- psxRegs.GPR.n.sp = SWAP32(tmpHead.s_addr);
+ psxRegs.GPR.n.sp = SWAP32(tmpHead.s_addr);
if (psxRegs.GPR.n.sp == 0)
psxRegs.GPR.n.sp = 0x801fff00;
retval = 0;
@@ -557,7 +565,7 @@ struct PcsxSaveFuncs SaveFuncs = {
zlib_open, zlib_read, zlib_write, zlib_seek, zlib_close
};
-static const char PcsxHeader[32] = "STv4 PCSX v" PACKAGE_VERSION;
+static const char PcsxHeader[32] = "STv4 PCSX v" PCSX_VERSION;
// Savestate Versioning!
// If you make changes to the savestate version, please increment the value below.
@@ -649,6 +657,11 @@ int LoadState(const char *file) {
if (Config.HLE)
psxBiosInit();
+#if defined(LIGHTREC)
+ if (Config.Cpu != CPU_INTERPRETER)
+ psxCpu->Clear(0, UINT32_MAX); //clear all
+ else
+#endif
psxCpu->Reset();
SaveFuncs.seek(f, 128 * 96 * 3, SEEK_CUR);
@@ -742,7 +755,7 @@ int RecvPcsxInfo() {
NET_recvData(&Config.Cpu, sizeof(Config.Cpu), PSE_NET_BLOCKING);
if (tmp != Config.Cpu) {
psxCpu->Shutdown();
-#ifdef PSXREC
+#if defined(NEW_DYNAREC) || defined(LIGHTREC)
if (Config.Cpu == CPU_INTERPRETER) psxCpu = &psxInt;
else psxCpu = &psxRec;
#else
diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/arm/assem_arm.c
index 21640f8..db1d2af 100644
--- a/libpcsxcore/new_dynarec/assem_arm.c
+++ b/libpcsxcore/new_dynarec/arm/assem_arm.c
@@ -19,12 +19,12 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include "../gte.h"
+#include "../../gte.h"
#define FLAGLESS
-#include "../gte.h"
+#include "../../gte.h"
#undef FLAGLESS
-#include "../gte_arm.h"
-#include "../gte_neon.h"
+#include "../../gte_arm.h"
+#include "../../gte_neon.h"
#include "pcnt.h"
#include "arm_features.h"
@@ -2518,8 +2518,8 @@ static void mov_loadtype_adj(int type,int rs,int rt)
}
}
-#include "pcsxmem.h"
-#include "pcsxmem_inline.c"
+#include "../backends/psx/pcsxmem.h"
+#include "../backends/psx/pcsxmem_inline.c"
static void do_readstub(int n)
{
diff --git a/libpcsxcore/new_dynarec/assem_arm.h b/libpcsxcore/new_dynarec/arm/assem_arm.h
index bb6114c..bb6114c 100644
--- a/libpcsxcore/new_dynarec/assem_arm.h
+++ b/libpcsxcore/new_dynarec/arm/assem_arm.h
diff --git a/libpcsxcore/new_dynarec/linkage_arm.S b/libpcsxcore/new_dynarec/arm/linkage_arm.S
index d32dc0b..269eb99 100644
--- a/libpcsxcore/new_dynarec/linkage_arm.S
+++ b/libpcsxcore/new_dynarec/arm/linkage_arm.S
@@ -20,7 +20,7 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "arm_features.h"
-#include "new_dynarec_config.h"
+#include "../new_dynarec_config.h"
#include "linkage_offsets.h"
diff --git a/libpcsxcore/new_dynarec/linkage_offsets.h b/libpcsxcore/new_dynarec/arm/linkage_offsets.h
index f7e1911..f7e1911 100644
--- a/libpcsxcore/new_dynarec/linkage_offsets.h
+++ b/libpcsxcore/new_dynarec/arm/linkage_offsets.h
diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/backends/psx/emu_if.c
index 22db5d1..2a090a0 100644
--- a/libpcsxcore/new_dynarec/emu_if.c
+++ b/libpcsxcore/new_dynarec/backends/psx/emu_if.c
@@ -9,15 +9,19 @@
#include "emu_if.h"
#include "pcsxmem.h"
-#include "../psxhle.h"
-#include "../r3000a.h"
-#include "../cdrom.h"
-#include "../psxdma.h"
-#include "../mdec.h"
-#include "../gte_arm.h"
-#include "../gte_neon.h"
+#include "../../../psxhle.h"
+#include "../../../r3000a.h"
+#include "../../../cdrom.h"
+#include "../../../psxdma.h"
+#include "../../../mdec.h"
+#include "../../../gte_arm.h"
+#include "../../../gte_neon.h"
+
+#include "../../../gte.h"
+
#define FLAGLESS
-#include "../gte.h"
+#include "../../../gte.h"
+#undef FLAGLESS
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
@@ -331,6 +335,7 @@ static int ari64_init()
#ifdef DRC_DBG
memcpy(gte_handlers_nf, gte_handlers, sizeof(gte_handlers_nf));
#endif
+
psxH_ptr = psxH;
zeromem_ptr = zero_mem;
scratch_buf_ptr = scratch_buf;
@@ -431,7 +436,7 @@ void do_insn_cmp() {}
#ifdef DRC_DISABLE
unsigned int address;
int pending_exception, stop;
-unsigned int next_interupt;
+u32 next_interupt;
int new_dynarec_did_compile;
int cycle_multiplier;
int new_dynarec_hacks;
diff --git a/libpcsxcore/new_dynarec/emu_if.h b/libpcsxcore/new_dynarec/backends/psx/emu_if.h
index 3980490..d8c7990 100644
--- a/libpcsxcore/new_dynarec/emu_if.h
+++ b/libpcsxcore/new_dynarec/backends/psx/emu_if.h
@@ -1,5 +1,5 @@
-#include "new_dynarec.h"
-#include "../r3000a.h"
+#include "../../new_dynarec.h"
+#include "../../../r3000a.h"
extern char invalid_code[0x100000];
@@ -89,7 +89,7 @@ extern void *scratch_buf_ptr;
extern u32 inv_code_start, inv_code_end;
/* cycles/irqs */
-extern unsigned int next_interupt;
+extern u32 next_interupt;
extern int pending_exception;
/* called by drc */
diff --git a/libpcsxcore/new_dynarec/pcsxmem.c b/libpcsxcore/new_dynarec/backends/psx/pcsxmem.c
index 9376ff4..647981e 100644
--- a/libpcsxcore/new_dynarec/pcsxmem.c
+++ b/libpcsxcore/new_dynarec/backends/psx/pcsxmem.c
@@ -6,11 +6,11 @@
*/
#include <stdio.h>
-#include "../psxhw.h"
-#include "../cdrom.h"
-#include "../mdec.h"
-#include "../gpu.h"
-#include "../psxmem_map.h"
+#include "../../../psxhw.h"
+#include "../../../cdrom.h"
+#include "../../../mdec.h"
+#include "../../../gpu.h"
+#include "../../../psxmem_map.h"
#include "emu_if.h"
#include "pcsxmem.h"
diff --git a/libpcsxcore/new_dynarec/pcsxmem.h b/libpcsxcore/new_dynarec/backends/psx/pcsxmem.h
index 72892a8..72892a8 100644
--- a/libpcsxcore/new_dynarec/pcsxmem.h
+++ b/libpcsxcore/new_dynarec/backends/psx/pcsxmem.h
diff --git a/libpcsxcore/new_dynarec/pcsxmem_inline.c b/libpcsxcore/new_dynarec/backends/psx/pcsxmem_inline.c
index 305931a..305931a 100644
--- a/libpcsxcore/new_dynarec/pcsxmem_inline.c
+++ b/libpcsxcore/new_dynarec/backends/psx/pcsxmem_inline.c
diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c
index cd63d2b..bb6ff0b 100644
--- a/libpcsxcore/new_dynarec/new_dynarec.c
+++ b/libpcsxcore/new_dynarec/new_dynarec.c
@@ -32,10 +32,11 @@
#ifdef VITA
#include <psp2/kernel/sysmem.h>
static int sceBlock;
+int getVMBlock();
#endif
#include "new_dynarec_config.h"
-#include "emu_if.h" //emulator interface
+#include "backends/psx/emu_if.h" //emulator interface
//#define DISASM
//#define assem_debug printf
@@ -44,13 +45,17 @@ static int sceBlock;
#define inv_debug(...)
#ifdef __i386__
-#include "assem_x86.h"
+#include "x86/assem_x86.h"
#endif
#ifdef __x86_64__
-#include "assem_x64.h"
+#include "x64/assem_x64.h"
#endif
#ifdef __arm__
-#include "assem_arm.h"
+#include "arm/assem_arm.h"
+#endif
+
+#ifdef VITA
+int _newlib_vm_size_user = 1 << TARGET_SIZE_2;
#endif
#define MAXBLOCK 4096
@@ -361,14 +366,16 @@ static u_int get_vpage(u_int vaddr)
// This is called from the recompiled JR/JALR instructions
void *get_addr(u_int vaddr)
{
- u_int page=get_page(vaddr);
- u_int vpage=get_vpage(vaddr);
- struct ll_entry *head;
+ struct ll_entry *head = NULL;
+ u_int page = get_page(vaddr);
+ u_int vpage = get_vpage(vaddr);
//printf("TRACE: count=%d next=%d (get_addr %x,page %d)\n",Count,next_interupt,vaddr,page);
head=jump_in[page];
- while(head!=NULL) {
- if(head->vaddr==vaddr) {
- //printf("TRACE: count=%d next=%d (get_addr match %x: %x)\n",Count,next_interupt,vaddr,(int)head->addr);
+ while(head!=NULL)
+ {
+ if(head->vaddr==vaddr)
+ {
+ //printf("TRACE: count=%d next=%d (get_addr match %x: %x)\n",Count,next_interupt,vaddr,(int)head->addr);
u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF];
ht_bin[3]=ht_bin[1];
ht_bin[2]=ht_bin[0];
@@ -379,39 +386,47 @@ void *get_addr(u_int vaddr)
head=head->next;
}
head=jump_dirty[vpage];
- while(head!=NULL) {
- if(head->vaddr==vaddr) {
+ while(head!=NULL)
+ {
+ if(head->vaddr==vaddr)
+ {
//printf("TRACE: count=%d next=%d (get_addr match dirty %x: %x)\n",Count,next_interupt,vaddr,(int)head->addr);
// Don't restore blocks which are about to expire from the cache
if((((u_int)head->addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2)))
- if(verify_dirty(head->addr)) {
- //printf("restore candidate: %x (%d) d=%d\n",vaddr,page,invalid_code[vaddr>>12]);
- invalid_code[vaddr>>12]=0;
- inv_code_start=inv_code_end=~0;
- if(vpage<2048) {
- restore_candidate[vpage>>3]|=1<<(vpage&7);
- }
- else restore_candidate[page>>3]|=1<<(page&7);
- u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF];
- if(ht_bin[0]==vaddr) {
- ht_bin[1]=(u_int)head->addr; // Replace existing entry
- }
- else
+ if(verify_dirty(head->addr))
{
- ht_bin[3]=ht_bin[1];
- ht_bin[2]=ht_bin[0];
- ht_bin[1]=(int)head->addr;
- ht_bin[0]=vaddr;
+ //printf("restore candidate: %x (%d) d=%d\n",vaddr,page,invalid_code[vaddr>>12]);
+ invalid_code[vaddr>>12]=0;
+ inv_code_start=inv_code_end=~0;
+ if(vpage<2048)
+ {
+ restore_candidate[vpage>>3]|=1<<(vpage&7);
+ }
+ else
+ {
+ restore_candidate[page>>3]|=1<<(page&7);
+ }
+ u_int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF];
+
+ if(ht_bin[0]==vaddr)
+ ht_bin[1]=(u_int)head->addr; // Replace existing entry
+ else
+ {
+ ht_bin[3]=ht_bin[1];
+ ht_bin[2]=ht_bin[0];
+ ht_bin[1]=(int)head->addr;
+ ht_bin[0]=vaddr;
+ }
+ return head->addr;
}
- return head->addr;
- }
}
head=head->next;
}
//printf("TRACE: count=%d next=%d (get_addr no-match %x)\n",Count,next_interupt,vaddr);
int r=new_recompile_block(vaddr);
- if(r==0) return get_addr(vaddr);
- // Execute in unmapped page, generate pagefault execption
+ if(r==0)
+ return get_addr(vaddr);
+ // Execute in unmapped page, generate pagefault exception
Status|=2;
Cause=(vaddr<<31)|0x8;
EPC=(vaddr&1)?vaddr-5:vaddr;
@@ -420,6 +435,7 @@ void *get_addr(u_int vaddr)
EntryHi=BadVAddr&0xFFFFE000;
return get_addr_ht(0x80000000);
}
+
// Look up address in hash table first
void *get_addr_ht(u_int vaddr)
{
@@ -763,13 +779,13 @@ void alloc_all(struct regstat *cur,int i)
}
#ifdef __i386__
-#include "assem_x86.c"
+#include "x86/assem_x86.c"
#endif
#ifdef __x86_64__
-#include "assem_x64.c"
+#include "x64/assem_x64.c"
#endif
#ifdef __arm__
-#include "assem_arm.c"
+#include "arm/assem_arm.c"
#endif
// Add virtual address mapping to linked list
@@ -943,23 +959,26 @@ static void invalidate_block_range(u_int block, u_int first, u_int last)
assert(first+5>page); // NB: this assumes MAXBLOCK<=4096 (4 pages)
assert(last<page+5);
// Invalidate the adjacent pages if a block crosses a 4K boundary
- while(first<page) {
+ while(first<page)
+ {
invalidate_page(first);
first++;
}
- for(first=page+1;first<last;first++) {
+ for(first=page+1;first<last;first++)
+ {
invalidate_page(first);
}
- #ifdef __arm__
- do_clear_cache();
- #endif
+
+#ifdef __arm__
+ do_clear_cache();
+#endif
// Don't trap writes
invalid_code[block]=1;
- #ifdef USE_MINI_HT
+#ifdef USE_MINI_HT
memset(mini_ht,-1,sizeof(mini_ht));
- #endif
+#endif
}
void invalidate_block(u_int block)
@@ -967,19 +986,22 @@ void invalidate_block(u_int block)
u_int page=get_page(block<<12);
u_int vpage=get_vpage(block<<12);
inv_debug("INVALIDATE: %x (%d)\n",block<<12,page);
- //inv_debug("invalid_code[block]=%d\n",invalid_code[block]);
u_int first,last;
first=last=page;
struct ll_entry *head;
head=jump_dirty[vpage];
//printf("page=%d vpage=%d\n",page,vpage);
- while(head!=NULL) {
+ while(head!=NULL)
+ {
u_int start,end;
- if(vpage>2047||(head->vaddr>>12)==block) { // Ignore vaddr hash collision
+ if(vpage>2047||(head->vaddr>>12)==block)
+ { // Ignore vaddr hash collision
get_bounds((int)head->addr,&start,&end);
//printf("start: %x end: %x\n",start,end);
- if(page<2048&&start>=(u_int)rdram&&end<(u_int)rdram+RAM_SIZE) {
- if(((start-(u_int)rdram)>>12)<=page&&((end-1-(u_int)rdram)>>12)>=page) {
+ if(page<2048&&start>=(u_int)rdram&&end<(u_int)rdram+RAM_SIZE)
+ {
+ if(((start-(u_int)rdram)>>12)<=page&&((end-1-(u_int)rdram)>>12)>=page)
+ {
if((((start-(u_int)rdram)>>12)&2047)<first) first=((start-(u_int)rdram)>>12)&2047;
if((((end-1-(u_int)rdram)>>12)&2047)>last) last=((end-1-(u_int)rdram)>>12)&2047;
}
@@ -1050,19 +1072,23 @@ void invalidate_addr(u_int addr)
// This is called when loading a save state.
// Anything could have changed, so invalidate everything.
-void invalidate_all_pages()
+void invalidate_all_pages(void)
{
u_int page;
for(page=0;page<4096;page++)
invalidate_page(page);
for(page=0;page<1048576;page++)
- if(!invalid_code[page]) {
+ {
+ if(!invalid_code[page])
+ {
restore_candidate[(page&2047)>>3]|=1<<(page&7);
restore_candidate[((page&2047)>>3)+256]|=1<<(page&7);
}
- #ifdef USE_MINI_HT
+ }
+
+#ifdef USE_MINI_HT
memset(mini_ht,-1,sizeof(mini_ht));
- #endif
+#endif
}
// Add an entry to jump_out after making a link
@@ -1087,37 +1113,48 @@ void clean_blocks(u_int page)
struct ll_entry *head;
inv_debug("INV: clean_blocks page=%d\n",page);
head=jump_dirty[page];
- while(head!=NULL) {
- if(!invalid_code[head->vaddr>>12]) {
+ while(head!=NULL)
+ {
+ if(!invalid_code[head->vaddr>>12])
+ {
// Don't restore blocks which are about to expire from the cache
- if((((u_int)head->addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) {
+ if((((u_int)head->addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2)))
+ {
u_int start,end;
- if(verify_dirty(head->addr)) {
+ if(verify_dirty(head->addr))
+ {
//printf("Possibly Restore %x (%x)\n",head->vaddr, (int)head->addr);
u_int i;
u_int inv=0;
get_bounds((int)head->addr,&start,&end);
- if(start-(u_int)rdram<RAM_SIZE) {
- for(i=(start-(u_int)rdram+0x80000000)>>12;i<=(end-1-(u_int)rdram+0x80000000)>>12;i++) {
+ if(start-(u_int)rdram<RAM_SIZE)
+ {
+ for(i=(start-(u_int)rdram+0x80000000)>>12;i<=(end-1-(u_int)rdram+0x80000000)>>12;i++)
+ {
inv|=invalid_code[i];
}
}
- else if((signed int)head->vaddr>=(signed int)0x80000000+RAM_SIZE) {
+ else if((signed int)head->vaddr>=(signed int)0x80000000+RAM_SIZE)
+ {
inv=1;
}
- if(!inv) {
+ if(!inv)
+ {
void * clean_addr=(void *)get_clean_addr((int)head->addr);
- if((((u_int)clean_addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2))) {
+ if((((u_int)clean_addr-(u_int)out)<<(32-TARGET_SIZE_2))>0x60000000+(MAX_OUTPUT_BLOCK_SIZE<<(32-TARGET_SIZE_2)))
+ {
u_int ppage=page;
inv_debug("INV: Restored %x (%x/%x)\n",head->vaddr, (int)head->addr, (int)clean_addr);
//printf("page=%x, addr=%x\n",page,head->vaddr);
//assert(head->vaddr>>12==(page|0x80000));
ll_add_flags(jump_in+ppage,head->vaddr,head->reg_sv_flags,clean_addr);
u_int *ht_bin=hash_table[((head->vaddr>>16)^head->vaddr)&0xFFFF];
- if(ht_bin[0]==head->vaddr) {
+ if(ht_bin[0]==head->vaddr)
+ {
ht_bin[1]=(u_int)clean_addr; // Replace existing entry
}
- if(ht_bin[2]==head->vaddr) {
+ if(ht_bin[2]==head->vaddr)
+ {
ht_bin[3]=(u_int)clean_addr; // Replace existing entry
}
}
@@ -1129,15 +1166,17 @@ void clean_blocks(u_int page)
}
}
-
-void mov_alloc(struct regstat *current,int i)
+static void mov_alloc(struct regstat *current,int i)
{
// Note: Don't need to actually alloc the source registers
- if((~current->is32>>rs1[i])&1) {
+ if((~current->is32>>rs1[i])&1)
+ {
//alloc_reg64(current,i,rs1[i]);
alloc_reg64(current,i,rt1[i]);
current->is32&=~(1LL<<rt1[i]);
- } else {
+ }
+ else
+ {
//alloc_reg(current,i,rs1[i]);
alloc_reg(current,i,rt1[i]);
current->is32|=(1LL<<rt1[i]);
@@ -1695,7 +1734,8 @@ void syscall_alloc(struct regstat *current,int i)
void delayslot_alloc(struct regstat *current,int i)
{
- switch(itype[i]) {
+ switch(itype[i])
+ {
case UJUMP:
case CJUMP:
case SJUMP:
@@ -1845,7 +1885,8 @@ void wb_register(signed char r,signed char regmap[],uint64_t dirty,uint64_t is32
}
}
-int mchecksum()
+#if 0
+static int mchecksum(void)
{
//if(!tracedebug) return 0;
int i;
@@ -1858,7 +1899,8 @@ int mchecksum()
}
return sum;
}
-int rchecksum()
+
+static int rchecksum(void)
{
int i;
int sum=0;
@@ -1866,7 +1908,8 @@ int rchecksum()
sum^=((u_int *)reg)[i];
return sum;
}
-void rlist()
+
+static void rlist(void)
{
int i;
printf("TRACE: ");
@@ -1875,12 +1918,12 @@ void rlist()
printf("\n");
}
-void enabletrace()
+static void enabletrace(void)
{
tracedebug=1;
}
-void memdebug(int i)
+static void memdebug(int i)
{
//printf("TRACE: count=%d next=%d (checksum %x) lo=%8x%8x\n",Count,next_interupt,mchecksum(),(int)(reg[LOREG]>>32),(int)reg[LOREG]);
//printf("TRACE: count=%d next=%d (rchecksum %x)\n",Count,next_interupt,rchecksum());
@@ -1905,6 +1948,7 @@ void memdebug(int i)
}
//printf("TRACE: %x\n",(&i)[-1]);
}
+#endif
void alu_assemble(int i,struct regstat *i_regs)
{
@@ -7016,7 +7060,7 @@ static int new_dynarec_test(void)
// clear the state completely, instead of just marking
// things invalid like invalidate_all_pages() does
-void new_dynarec_clear_full()
+void new_dynarec_clear_full(void)
{
int n;
out=(u_char *)BASE_ADDR;
@@ -7037,45 +7081,57 @@ void new_dynarec_clear_full()
for(n=0;n<4096;n++) ll_clear(jump_dirty+n);
}
-void new_dynarec_init()
+void new_dynarec_init(void)
{
SysPrintf("Init new dynarec\n");
+#ifdef _3DS
+ check_rosalina();
+#endif
+
// allocate/prepare a buffer for translation cache
// see assem_arm.h for some explanation
#if defined(BASE_ADDR_FIXED)
if (mmap (translation_cache, 1 << TARGET_SIZE_2,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_ANONYMOUS,
- -1, 0) != translation_cache) {
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1, 0) != translation_cache)
+ {
SysPrintf("mmap() failed: %s\n", strerror(errno));
SysPrintf("disable BASE_ADDR_FIXED and recompile\n");
abort();
}
#elif defined(BASE_ADDR_DYNAMIC)
- #ifdef VITA
- sceBlock = sceKernelAllocMemBlockForVM("code", 1 << TARGET_SIZE_2);
+#ifdef VITA
+ sceBlock = getVMBlock();//sceKernelAllocMemBlockForVM("code", 1 << TARGET_SIZE_2);
if (sceBlock < 0)
SysPrintf("sceKernelAllocMemBlockForVM failed\n");
int ret = sceKernelGetMemBlockBase(sceBlock, (void **)&translation_cache);
if (ret < 0)
SysPrintf("sceKernelGetMemBlockBase failed\n");
- #else
+
+ sceKernelOpenVMDomain();
+ sceClibPrintf("translation_cache = 0x%08X \n ", translation_cache);
+#elif defined(_MSC_VER)
+ base_addr = VirtualAlloc(NULL, 1<<TARGET_SIZE_2, MEM_COMMIT | MEM_RESERVE,
+ PAGE_EXECUTE_READWRITE);
+#else
translation_cache = mmap (NULL, 1 << TARGET_SIZE_2,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (translation_cache == MAP_FAILED) {
SysPrintf("mmap() failed: %s\n", strerror(errno));
abort();
}
- #endif
+#endif
#else
- #ifndef NO_WRITE_EXEC
+#ifndef NO_WRITE_EXEC
// not all systems allow execute in data segment by default
if (mprotect((void *)BASE_ADDR, 1<<TARGET_SIZE_2, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
SysPrintf("mprotect() failed: %s\n", strerror(errno));
- #endif
#endif
+#endif
+
out=(u_char *)BASE_ADDR;
cycle_multiplier=200;
new_dynarec_clear_full();
@@ -7092,24 +7148,28 @@ void new_dynarec_init()
SysPrintf("warning: RAM is not directly mapped, performance will suffer\n");
}
-void new_dynarec_cleanup()
+void new_dynarec_cleanup(void)
{
int n;
#if defined(BASE_ADDR_FIXED) || defined(BASE_ADDR_DYNAMIC)
- #ifdef VITA
- sceKernelFreeMemBlock(sceBlock);
- sceBlock = -1;
- #else
+#ifndef VITA
+#if defined(_MSC_VER)
+ VirtualFree(base_addr, 0, MEM_RELEASE);
+#else
if (munmap ((void *)BASE_ADDR, 1<<TARGET_SIZE_2) < 0)
SysPrintf("munmap() failed\n");
- #endif
#endif
- for(n=0;n<4096;n++) ll_clear(jump_in+n);
- for(n=0;n<4096;n++) ll_clear(jump_out+n);
- for(n=0;n<4096;n++) ll_clear(jump_dirty+n);
- #ifdef ROM_COPY
+#endif
+#endif
+ for(n=0;n<4096;n++)
+ ll_clear(jump_in+n);
+ for(n=0;n<4096;n++)
+ ll_clear(jump_out+n);
+ for(n=0;n<4096;n++)
+ ll_clear(jump_dirty+n);
+#ifdef ROM_COPY
if (munmap (ROM_COPY, 67108864) < 0) {SysPrintf("munmap() failed\n");}
- #endif
+#endif
}
static u_int *get_source_start(u_int addr, u_int *limit)
diff --git a/libpcsxcore/new_dynarec/new_dynarec.h b/libpcsxcore/new_dynarec/new_dynarec.h
index ddc84a5..d196f59 100644
--- a/libpcsxcore/new_dynarec/new_dynarec.h
+++ b/libpcsxcore/new_dynarec/new_dynarec.h
@@ -1,4 +1,4 @@
-#define NEW_DYNAREC 1
+/* #define NEW_DYNAREC 1 */
extern int pcaddr;
extern int pending_exception;
@@ -11,12 +11,12 @@ extern int cycle_multiplier; // 100 for 1.0
#define NDHACK_GTE_NO_FLAGS (1<<2)
extern int new_dynarec_hacks;
-void new_dynarec_init();
-void new_dynarec_cleanup();
-void new_dynarec_clear_full();
-void new_dyna_start();
+void new_dynarec_init(void);
+void new_dynarec_cleanup(void);
+void new_dynarec_clear_full(void);
+void new_dyna_start(void);
int new_dynarec_save_blocks(void *save, int size);
void new_dynarec_load_blocks(const void *save, int size);
-void invalidate_all_pages();
+void invalidate_all_pages(void);
void invalidate_block(unsigned int block);
diff --git a/libpcsxcore/new_dynarec/new_dynarec_config.h b/libpcsxcore/new_dynarec/new_dynarec_config.h
index fbd08ac..d55f128 100644
--- a/libpcsxcore/new_dynarec/new_dynarec_config.h
+++ b/libpcsxcore/new_dynarec/new_dynarec_config.h
@@ -4,7 +4,7 @@
#define USE_MINI_HT 1
//#define REG_PREFETCH 1
-#if defined(__MACH__) || defined(VITA)
+#if defined(__MACH__)
#define NO_WRITE_EXEC 1
#endif
#ifdef VITA
diff --git a/libpcsxcore/plugins.c b/libpcsxcore/plugins.c
index e6d8a11..67fe835 100644
--- a/libpcsxcore/plugins.c
+++ b/libpcsxcore/plugins.c
@@ -1,836 +1,1240 @@
-/***************************************************************************
- * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
- ***************************************************************************/
-
-/*
-* Plugin library callback/access functions.
-*/
-
-#include "plugins.h"
-#include "cdriso.h"
-
-static char IsoFile[MAXPATHLEN] = "";
-static s64 cdOpenCaseTime = 0;
-
-GPUupdateLace GPU_updateLace;
-GPUinit GPU_init;
-GPUshutdown GPU_shutdown;
-GPUconfigure GPU_configure;
-GPUtest GPU_test;
-GPUabout GPU_about;
-GPUopen GPU_open;
-GPUclose GPU_close;
-GPUreadStatus GPU_readStatus;
-GPUreadData GPU_readData;
-GPUreadDataMem GPU_readDataMem;
-GPUwriteStatus GPU_writeStatus;
-GPUwriteData GPU_writeData;
-GPUwriteDataMem GPU_writeDataMem;
-GPUdmaChain GPU_dmaChain;
-GPUkeypressed GPU_keypressed;
-GPUdisplayText GPU_displayText;
-GPUmakeSnapshot GPU_makeSnapshot;
-GPUfreeze GPU_freeze;
-GPUgetScreenPic GPU_getScreenPic;
-GPUshowScreenPic GPU_showScreenPic;
-GPUclearDynarec GPU_clearDynarec;
-GPUvBlank GPU_vBlank;
-
-CDRinit CDR_init;
-CDRshutdown CDR_shutdown;
-CDRopen CDR_open;
-CDRclose CDR_close;
-CDRtest CDR_test;
-CDRgetTN CDR_getTN;
-CDRgetTD CDR_getTD;
-CDRreadTrack CDR_readTrack;
-CDRgetBuffer CDR_getBuffer;
-CDRplay CDR_play;
-CDRstop CDR_stop;
-CDRgetStatus CDR_getStatus;
-CDRgetDriveLetter CDR_getDriveLetter;
-CDRgetBufferSub CDR_getBufferSub;
-CDRconfigure CDR_configure;
-CDRabout CDR_about;
-CDRsetfilename CDR_setfilename;
-CDRreadCDDA CDR_readCDDA;
-CDRgetTE CDR_getTE;
-
-SPUconfigure SPU_configure;
-SPUabout SPU_about;
-SPUinit SPU_init;
-SPUshutdown SPU_shutdown;
-SPUtest SPU_test;
-SPUopen SPU_open;
-SPUclose SPU_close;
-SPUplaySample SPU_playSample;
-SPUwriteRegister SPU_writeRegister;
-SPUreadRegister SPU_readRegister;
-SPUwriteDMA SPU_writeDMA;
-SPUreadDMA SPU_readDMA;
-SPUwriteDMAMem SPU_writeDMAMem;
-SPUreadDMAMem SPU_readDMAMem;
-SPUplayADPCMchannel SPU_playADPCMchannel;
-SPUfreeze SPU_freeze;
-SPUregisterCallback SPU_registerCallback;
-SPUregisterScheduleCb SPU_registerScheduleCb;
-SPUasync SPU_async;
-SPUplayCDDAchannel SPU_playCDDAchannel;
-
-PADconfigure PAD1_configure;
-PADabout PAD1_about;
-PADinit PAD1_init;
-PADshutdown PAD1_shutdown;
-PADtest PAD1_test;
-PADopen PAD1_open;
-PADclose PAD1_close;
-PADquery PAD1_query;
-PADreadPort1 PAD1_readPort1;
-PADkeypressed PAD1_keypressed;
-PADstartPoll PAD1_startPoll;
-PADpoll PAD1_poll;
-PADsetSensitive PAD1_setSensitive;
-
-PADconfigure PAD2_configure;
-PADabout PAD2_about;
-PADinit PAD2_init;
-PADshutdown PAD2_shutdown;
-PADtest PAD2_test;
-PADopen PAD2_open;
-PADclose PAD2_close;
-PADquery PAD2_query;
-PADreadPort2 PAD2_readPort2;
-PADkeypressed PAD2_keypressed;
-PADstartPoll PAD2_startPoll;
-PADpoll PAD2_poll;
-PADsetSensitive PAD2_setSensitive;
-
-NETinit NET_init;
-NETshutdown NET_shutdown;
-NETopen NET_open;
-NETclose NET_close;
-NETtest NET_test;
-NETconfigure NET_configure;
-NETabout NET_about;
-NETpause NET_pause;
-NETresume NET_resume;
-NETqueryPlayer NET_queryPlayer;
-NETsendData NET_sendData;
-NETrecvData NET_recvData;
-NETsendPadData NET_sendPadData;
-NETrecvPadData NET_recvPadData;
-NETsetInfo NET_setInfo;
-NETkeypressed NET_keypressed;
-
-#ifdef ENABLE_SIO1API
-
-SIO1init SIO1_init;
-SIO1shutdown SIO1_shutdown;
-SIO1open SIO1_open;
-SIO1close SIO1_close;
-SIO1test SIO1_test;
-SIO1configure SIO1_configure;
-SIO1about SIO1_about;
-SIO1pause SIO1_pause;
-SIO1resume SIO1_resume;
-SIO1keypressed SIO1_keypressed;
-SIO1writeData8 SIO1_writeData8;
-SIO1writeData16 SIO1_writeData16;
-SIO1writeData32 SIO1_writeData32;
-SIO1writeStat16 SIO1_writeStat16;
-SIO1writeStat32 SIO1_writeStat32;
-SIO1writeMode16 SIO1_writeMode16;
-SIO1writeMode32 SIO1_writeMode32;
-SIO1writeCtrl16 SIO1_writeCtrl16;
-SIO1writeCtrl32 SIO1_writeCtrl32;
-SIO1writeBaud16 SIO1_writeBaud16;
-SIO1writeBaud32 SIO1_writeBaud32;
-SIO1readData8 SIO1_readData8;
-SIO1readData16 SIO1_readData16;
-SIO1readData32 SIO1_readData32;
-SIO1readStat16 SIO1_readStat16;
-SIO1readStat32 SIO1_readStat32;
-SIO1readMode16 SIO1_readMode16;
-SIO1readMode32 SIO1_readMode32;
-SIO1readCtrl16 SIO1_readCtrl16;
-SIO1readCtrl32 SIO1_readCtrl32;
-SIO1readBaud16 SIO1_readBaud16;
-SIO1readBaud32 SIO1_readBaud32;
-SIO1registerCallback SIO1_registerCallback;
-
-#endif
-
-static const char *err;
-
-#define CheckErr(func) { \
- err = SysLibError(); \
- if (err != NULL) { SysMessage(_("Error loading %s: %s"), func, err); return -1; } \
-}
-
-#define LoadSym(dest, src, name, checkerr) { \
- dest = (src)SysLoadSym(drv, name); \
- if (checkerr) { CheckErr(name); } else SysLibError(); \
-}
-
-void *hGPUDriver = NULL;
-
-void CALLBACK GPU__displayText(char *pText) {
- SysPrintf("%s\n", pText);
-}
-
-long CALLBACK GPU__configure(void) { return 0; }
-long CALLBACK GPU__test(void) { return 0; }
-void CALLBACK GPU__about(void) {}
-void CALLBACK GPU__makeSnapshot(void) {}
-void CALLBACK GPU__keypressed(int key) {}
-long CALLBACK GPU__getScreenPic(unsigned char *pMem) { return -1; }
-long CALLBACK GPU__showScreenPic(unsigned char *pMem) { return -1; }
-void CALLBACK GPU__clearDynarec(void (CALLBACK *callback)(void)) {}
-void CALLBACK GPU__vBlank(int val) {}
-
-#define LoadGpuSym1(dest, name) \
- LoadSym(GPU_##dest, GPU##dest, name, TRUE);
-
-#define LoadGpuSym0(dest, name) \
- LoadSym(GPU_##dest, GPU##dest, name, FALSE); \
- if (GPU_##dest == NULL) GPU_##dest = (GPU##dest) GPU__##dest;
-
-#define LoadGpuSymN(dest, name) \
- LoadSym(GPU_##dest, GPU##dest, name, FALSE);
-
-static int LoadGPUplugin(const char *GPUdll) {
- void *drv;
-
- hGPUDriver = SysLoadLibrary(GPUdll);
- if (hGPUDriver == NULL) {
- GPU_configure = NULL;
- SysMessage (_("Could not load GPU plugin %s!"), GPUdll); return -1;
- }
- drv = hGPUDriver;
- LoadGpuSym1(init, "GPUinit");
- LoadGpuSym1(shutdown, "GPUshutdown");
- LoadGpuSym1(open, "GPUopen");
- LoadGpuSym1(close, "GPUclose");
- LoadGpuSym1(readData, "GPUreadData");
- LoadGpuSym1(readDataMem, "GPUreadDataMem");
- LoadGpuSym1(readStatus, "GPUreadStatus");
- LoadGpuSym1(writeData, "GPUwriteData");
- LoadGpuSym1(writeDataMem, "GPUwriteDataMem");
- LoadGpuSym1(writeStatus, "GPUwriteStatus");
- LoadGpuSym1(dmaChain, "GPUdmaChain");
- LoadGpuSym1(updateLace, "GPUupdateLace");
- LoadGpuSym0(keypressed, "GPUkeypressed");
- LoadGpuSym0(displayText, "GPUdisplayText");
- LoadGpuSym0(makeSnapshot, "GPUmakeSnapshot");
- LoadGpuSym1(freeze, "GPUfreeze");
- LoadGpuSym0(getScreenPic, "GPUgetScreenPic");
- LoadGpuSym0(showScreenPic, "GPUshowScreenPic");
- LoadGpuSym0(clearDynarec, "GPUclearDynarec");
- LoadGpuSym0(vBlank, "GPUvBlank");
- LoadGpuSym0(configure, "GPUconfigure");
- LoadGpuSym0(test, "GPUtest");
- LoadGpuSym0(about, "GPUabout");
-
- return 0;
-}
-
-void *hCDRDriver = NULL;
-
-long CALLBACK CDR__play(unsigned char *sector) { return 0; }
-long CALLBACK CDR__stop(void) { return 0; }
-
-long CALLBACK CDR__getStatus(struct CdrStat *stat) {
- if (cdOpenCaseTime < 0 || cdOpenCaseTime > (s64)time(NULL))
- stat->Status = 0x10;
- else
- stat->Status = 0;
-
- return 0;
-}
-
-char* CALLBACK CDR__getDriveLetter(void) { return NULL; }
-long CALLBACK CDR__configure(void) { return 0; }
-long CALLBACK CDR__test(void) { return 0; }
-void CALLBACK CDR__about(void) {}
-long CALLBACK CDR__setfilename(char*filename) { return 0; }
-
-#define LoadCdrSym1(dest, name) \
- LoadSym(CDR_##dest, CDR##dest, name, TRUE);
-
-#define LoadCdrSym0(dest, name) \
- LoadSym(CDR_##dest, CDR##dest, name, FALSE); \
- if (CDR_##dest == NULL) CDR_##dest = (CDR##dest) CDR__##dest;
-
-#define LoadCdrSymN(dest, name) \
- LoadSym(CDR_##dest, CDR##dest, name, FALSE);
-
-static int LoadCDRplugin(const char *CDRdll) {
- void *drv;
-
- if (CDRdll == NULL) {
- cdrIsoInit();
- return 0;
- }
-
- hCDRDriver = SysLoadLibrary(CDRdll);
- if (hCDRDriver == NULL) {
- CDR_configure = NULL;
- SysMessage (_("Could not load CD-ROM plugin %s!"), CDRdll); return -1;
- }
- drv = hCDRDriver;
- LoadCdrSym1(init, "CDRinit");
- LoadCdrSym1(shutdown, "CDRshutdown");
- LoadCdrSym1(open, "CDRopen");
- LoadCdrSym1(close, "CDRclose");
- LoadCdrSym1(getTN, "CDRgetTN");
- LoadCdrSym1(getTD, "CDRgetTD");
- LoadCdrSym1(readTrack, "CDRreadTrack");
- LoadCdrSym1(getBuffer, "CDRgetBuffer");
- LoadCdrSym1(getBufferSub, "CDRgetBufferSub");
- LoadCdrSym0(play, "CDRplay");
- LoadCdrSym0(stop, "CDRstop");
- LoadCdrSym0(getStatus, "CDRgetStatus");
- LoadCdrSym0(getDriveLetter, "CDRgetDriveLetter");
- LoadCdrSym0(configure, "CDRconfigure");
- LoadCdrSym0(test, "CDRtest");
- LoadCdrSym0(about, "CDRabout");
- LoadCdrSym0(setfilename, "CDRsetfilename");
- LoadCdrSymN(readCDDA, "CDRreadCDDA");
- LoadCdrSymN(getTE, "CDRgetTE");
-
- return 0;
-}
-
-void *hSPUDriver = NULL;
-
-long CALLBACK SPU__configure(void) { return 0; }
-void CALLBACK SPU__about(void) {}
-long CALLBACK SPU__test(void) { return 0; }
-void CALLBACK SPU__registerScheduleCb(void (CALLBACK *cb)(unsigned int)) {}
-
-#define LoadSpuSym1(dest, name) \
- LoadSym(SPU_##dest, SPU##dest, name, TRUE);
-
-#define LoadSpuSym0(dest, name) \
- LoadSym(SPU_##dest, SPU##dest, name, FALSE); \
- if (SPU_##dest == NULL) SPU_##dest = (SPU##dest) SPU__##dest;
-
-#define LoadSpuSymN(dest, name) \
- LoadSym(SPU_##dest, SPU##dest, name, FALSE);
-
-static int LoadSPUplugin(const char *SPUdll) {
- void *drv;
-
- hSPUDriver = SysLoadLibrary(SPUdll);
- if (hSPUDriver == NULL) {
- SPU_configure = NULL;
- SysMessage (_("Could not load SPU plugin %s!"), SPUdll); return -1;
- }
- drv = hSPUDriver;
- LoadSpuSym1(init, "SPUinit");
- LoadSpuSym1(shutdown, "SPUshutdown");
- LoadSpuSym1(open, "SPUopen");
- LoadSpuSym1(close, "SPUclose");
- LoadSpuSym0(configure, "SPUconfigure");
- LoadSpuSym0(about, "SPUabout");
- LoadSpuSym0(test, "SPUtest");
- LoadSpuSym1(writeRegister, "SPUwriteRegister");
- LoadSpuSym1(readRegister, "SPUreadRegister");
- LoadSpuSym1(writeDMA, "SPUwriteDMA");
- LoadSpuSym1(readDMA, "SPUreadDMA");
- LoadSpuSym1(writeDMAMem, "SPUwriteDMAMem");
- LoadSpuSym1(readDMAMem, "SPUreadDMAMem");
- LoadSpuSym1(playADPCMchannel, "SPUplayADPCMchannel");
- LoadSpuSym1(freeze, "SPUfreeze");
- LoadSpuSym1(registerCallback, "SPUregisterCallback");
- LoadSpuSym0(registerScheduleCb, "SPUregisterScheduleCb");
- LoadSpuSymN(async, "SPUasync");
- LoadSpuSymN(playCDDAchannel, "SPUplayCDDAchannel");
-
- return 0;
-}
-
-void *hPAD1Driver = NULL;
-void *hPAD2Driver = NULL;
-
-static unsigned char buf[256];
-unsigned char stdpar[10] = { 0x00, 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-unsigned char mousepar[8] = { 0x00, 0x12, 0x5a, 0xff, 0xff, 0xff, 0xff };
-unsigned char analogpar[9] = { 0x00, 0xff, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-static int bufcount, bufc;
-
-PadDataS padd1, padd2;
-
-unsigned char _PADstartPoll(PadDataS *pad) {
- bufc = 0;
-
- switch (pad->controllerType) {
- case PSE_PAD_TYPE_MOUSE:
- mousepar[3] = pad->buttonStatus & 0xff;
- mousepar[4] = pad->buttonStatus >> 8;
- mousepar[5] = pad->moveX;
- mousepar[6] = pad->moveY;
-
- memcpy(buf, mousepar, 7);
- bufcount = 6;
- break;
- case PSE_PAD_TYPE_NEGCON: // npc101/npc104(slph00001/slph00069)
- analogpar[1] = 0x23;
- analogpar[3] = pad->buttonStatus & 0xff;
- analogpar[4] = pad->buttonStatus >> 8;
- analogpar[5] = pad->rightJoyX;
- analogpar[6] = pad->rightJoyY;
- analogpar[7] = pad->leftJoyX;
- analogpar[8] = pad->leftJoyY;
-
- memcpy(buf, analogpar, 9);
- bufcount = 8;
- break;
- case PSE_PAD_TYPE_ANALOGPAD: // scph1150
- analogpar[1] = 0x73;
- analogpar[3] = pad->buttonStatus & 0xff;
- analogpar[4] = pad->buttonStatus >> 8;
- analogpar[5] = pad->rightJoyX;
- analogpar[6] = pad->rightJoyY;
- analogpar[7] = pad->leftJoyX;
- analogpar[8] = pad->leftJoyY;
-
- memcpy(buf, analogpar, 9);
- bufcount = 8;
- break;
- case PSE_PAD_TYPE_ANALOGJOY: // scph1110
- analogpar[1] = 0x53;
- analogpar[3] = pad->buttonStatus & 0xff;
- analogpar[4] = pad->buttonStatus >> 8;
- analogpar[5] = pad->rightJoyX;
- analogpar[6] = pad->rightJoyY;
- analogpar[7] = pad->leftJoyX;
- analogpar[8] = pad->leftJoyY;
-
- memcpy(buf, analogpar, 9);
- bufcount = 8;
- break;
- case PSE_PAD_TYPE_STANDARD:
- default:
- stdpar[3] = pad->buttonStatus & 0xff;
- stdpar[4] = pad->buttonStatus >> 8;
-
- memcpy(buf, stdpar, 5);
- bufcount = 4;
- }
-
- return buf[bufc++];
-}
-
-unsigned char _PADpoll(unsigned char value) {
- if (bufc > bufcount) return 0;
- return buf[bufc++];
-}
-
-unsigned char CALLBACK PAD1__startPoll(int pad) {
- PadDataS padd;
-
- PAD1_readPort1(&padd);
-
- return _PADstartPoll(&padd);
-}
-
-unsigned char CALLBACK PAD1__poll(unsigned char value) {
- return _PADpoll(value);
-}
-
-long CALLBACK PAD1__configure(void) { return 0; }
-void CALLBACK PAD1__about(void) {}
-long CALLBACK PAD1__test(void) { return 0; }
-long CALLBACK PAD1__query(void) { return 3; }
-long CALLBACK PAD1__keypressed() { return 0; }
-
-#define LoadPad1Sym1(dest, name) \
- LoadSym(PAD1_##dest, PAD##dest, name, TRUE);
-
-#define LoadPad1SymN(dest, name) \
- LoadSym(PAD1_##dest, PAD##dest, name, FALSE);
-
-#define LoadPad1Sym0(dest, name) \
- LoadSym(PAD1_##dest, PAD##dest, name, FALSE); \
- if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;
-
-static int LoadPAD1plugin(const char *PAD1dll) {
- void *drv;
-
- hPAD1Driver = SysLoadLibrary(PAD1dll);
- if (hPAD1Driver == NULL) {
- PAD1_configure = NULL;
- SysMessage (_("Could not load Controller 1 plugin %s!"), PAD1dll); return -1;
- }
- drv = hPAD1Driver;
- LoadPad1Sym1(init, "PADinit");
- LoadPad1Sym1(shutdown, "PADshutdown");
- LoadPad1Sym1(open, "PADopen");
- LoadPad1Sym1(close, "PADclose");
- LoadPad1Sym0(query, "PADquery");
- LoadPad1Sym1(readPort1, "PADreadPort1");
- LoadPad1Sym0(configure, "PADconfigure");
- LoadPad1Sym0(test, "PADtest");
- LoadPad1Sym0(about, "PADabout");
- LoadPad1Sym0(keypressed, "PADkeypressed");
- LoadPad1Sym0(startPoll, "PADstartPoll");
- LoadPad1Sym0(poll, "PADpoll");
- LoadPad1SymN(setSensitive, "PADsetSensitive");
-
- return 0;
-}
-
-unsigned char CALLBACK PAD2__startPoll(int pad) {
- PadDataS padd;
-
- PAD2_readPort2(&padd);
-
- return _PADstartPoll(&padd);
-}
-
-unsigned char CALLBACK PAD2__poll(unsigned char value) {
- return _PADpoll(value);
-}
-
-long CALLBACK PAD2__configure(void) { return 0; }
-void CALLBACK PAD2__about(void) {}
-long CALLBACK PAD2__test(void) { return 0; }
-long CALLBACK PAD2__query(void) { return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2; }
-long CALLBACK PAD2__keypressed() { return 0; }
-
-#define LoadPad2Sym1(dest, name) \
- LoadSym(PAD2_##dest, PAD##dest, name, TRUE);
-
-#define LoadPad2Sym0(dest, name) \
- LoadSym(PAD2_##dest, PAD##dest, name, FALSE); \
- if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest;
-
-#define LoadPad2SymN(dest, name) \
- LoadSym(PAD2_##dest, PAD##dest, name, FALSE);
-
-static int LoadPAD2plugin(const char *PAD2dll) {
- void *drv;
-
- hPAD2Driver = SysLoadLibrary(PAD2dll);
- if (hPAD2Driver == NULL) {
- PAD2_configure = NULL;
- SysMessage (_("Could not load Controller 2 plugin %s!"), PAD2dll); return -1;
- }
- drv = hPAD2Driver;
- LoadPad2Sym1(init, "PADinit");
- LoadPad2Sym1(shutdown, "PADshutdown");
- LoadPad2Sym1(open, "PADopen");
- LoadPad2Sym1(close, "PADclose");
- LoadPad2Sym0(query, "PADquery");
- LoadPad2Sym1(readPort2, "PADreadPort2");
- LoadPad2Sym0(configure, "PADconfigure");
- LoadPad2Sym0(test, "PADtest");
- LoadPad2Sym0(about, "PADabout");
- LoadPad2Sym0(keypressed, "PADkeypressed");
- LoadPad2Sym0(startPoll, "PADstartPoll");
- LoadPad2Sym0(poll, "PADpoll");
- LoadPad2SymN(setSensitive, "PADsetSensitive");
-
- return 0;
-}
-
-void *hNETDriver = NULL;
-
-void CALLBACK NET__setInfo(netInfo *info) {}
-void CALLBACK NET__keypressed(int key) {}
-long CALLBACK NET__configure(void) { return 0; }
-long CALLBACK NET__test(void) { return 0; }
-void CALLBACK NET__about(void) {}
-
-#define LoadNetSym1(dest, name) \
- LoadSym(NET_##dest, NET##dest, name, TRUE);
-
-#define LoadNetSymN(dest, name) \
- LoadSym(NET_##dest, NET##dest, name, FALSE);
-
-#define LoadNetSym0(dest, name) \
- LoadSym(NET_##dest, NET##dest, name, FALSE); \
- if (NET_##dest == NULL) NET_##dest = (NET##dest) NET__##dest;
-
-static int LoadNETplugin(const char *NETdll) {
- void *drv;
-
- hNETDriver = SysLoadLibrary(NETdll);
- if (hNETDriver == NULL) {
- SysMessage (_("Could not load NetPlay plugin %s!"), NETdll); return -1;
- }
- drv = hNETDriver;
- LoadNetSym1(init, "NETinit");
- LoadNetSym1(shutdown, "NETshutdown");
- LoadNetSym1(open, "NETopen");
- LoadNetSym1(close, "NETclose");
- LoadNetSymN(sendData, "NETsendData");
- LoadNetSymN(recvData, "NETrecvData");
- LoadNetSym1(sendPadData, "NETsendPadData");
- LoadNetSym1(recvPadData, "NETrecvPadData");
- LoadNetSym1(queryPlayer, "NETqueryPlayer");
- LoadNetSym1(pause, "NETpause");
- LoadNetSym1(resume, "NETresume");
- LoadNetSym0(setInfo, "NETsetInfo");
- LoadNetSym0(keypressed, "NETkeypressed");
- LoadNetSym0(configure, "NETconfigure");
- LoadNetSym0(test, "NETtest");
- LoadNetSym0(about, "NETabout");
-
- return 0;
-}
-
-#ifdef ENABLE_SIO1API
-
-void *hSIO1Driver = NULL;
-
-long CALLBACK SIO1__init(void) { return 0; }
-long CALLBACK SIO1__shutdown(void) { return 0; }
-long CALLBACK SIO1__open(void) { return 0; }
-long CALLBACK SIO1__close(void) { return 0; }
-long CALLBACK SIO1__configure(void) { return 0; }
-long CALLBACK SIO1__test(void) { return 0; }
-void CALLBACK SIO1__about(void) {}
-void CALLBACK SIO1__pause(void) {}
-void CALLBACK SIO1__resume(void) {}
-long CALLBACK SIO1__keypressed(int key) { return 0; }
-void CALLBACK SIO1__writeData8(unsigned char val) {}
-void CALLBACK SIO1__writeData16(unsigned short val) {}
-void CALLBACK SIO1__writeData32(unsigned long val) {}
-void CALLBACK SIO1__writeStat16(unsigned short val) {}
-void CALLBACK SIO1__writeStat32(unsigned long val) {}
-void CALLBACK SIO1__writeMode16(unsigned short val) {}
-void CALLBACK SIO1__writeMode32(unsigned long val) {}
-void CALLBACK SIO1__writeCtrl16(unsigned short val) {}
-void CALLBACK SIO1__writeCtrl32(unsigned long val) {}
-void CALLBACK SIO1__writeBaud16(unsigned short val) {}
-void CALLBACK SIO1__writeBaud32(unsigned long val) {}
-unsigned char CALLBACK SIO1__readData8(void) { return 0; }
-unsigned short CALLBACK SIO1__readData16(void) { return 0; }
-unsigned long CALLBACK SIO1__readData32(void) { return 0; }
-unsigned short CALLBACK SIO1__readStat16(void) { return 0; }
-unsigned long CALLBACK SIO1__readStat32(void) { return 0; }
-unsigned short CALLBACK SIO1__readMode16(void) { return 0; }
-unsigned long CALLBACK SIO1__readMode32(void) { return 0; }
-unsigned short CALLBACK SIO1__readCtrl16(void) { return 0; }
-unsigned long CALLBACK SIO1__readCtrl32(void) { return 0; }
-unsigned short CALLBACK SIO1__readBaud16(void) { return 0; }
-unsigned long CALLBACK SIO1__readBaud32(void) { return 0; }
-void CALLBACK SIO1__registerCallback(void (CALLBACK *callback)(void)) {};
-
-void CALLBACK SIO1irq(void) {
- psxHu32ref(0x1070) |= SWAPu32(0x100);
-}
-
-#define LoadSio1Sym1(dest, name) \
- LoadSym(SIO1_##dest, SIO1##dest, name, TRUE);
-
-#define LoadSio1SymN(dest, name) \
- LoadSym(SIO1_##dest, SIO1##dest, name, FALSE);
-
-#define LoadSio1Sym0(dest, name) \
- LoadSym(SIO1_##dest, SIO1##dest, name, FALSE); \
- if (SIO1_##dest == NULL) SIO1_##dest = (SIO1##dest) SIO1__##dest;
-
-static int LoadSIO1plugin(const char *SIO1dll) {
- void *drv;
-
- hSIO1Driver = SysLoadLibrary(SIO1dll);
- if (hSIO1Driver == NULL) {
- SysMessage (_("Could not load SIO1 plugin %s!"), SIO1dll); return -1;
- }
- drv = hSIO1Driver;
-
- LoadSio1Sym0(init, "SIO1init");
- LoadSio1Sym0(shutdown, "SIO1shutdown");
- LoadSio1Sym0(open, "SIO1open");
- LoadSio1Sym0(close, "SIO1close");
- LoadSio1Sym0(pause, "SIO1pause");
- LoadSio1Sym0(resume, "SIO1resume");
- LoadSio1Sym0(keypressed, "SIO1keypressed");
- LoadSio1Sym0(configure, "SIO1configure");
- LoadSio1Sym0(test, "SIO1test");
- LoadSio1Sym0(about, "SIO1about");
- LoadSio1Sym0(writeData8, "SIO1writeData8");
- LoadSio1Sym0(writeData16, "SIO1writeData16");
- LoadSio1Sym0(writeData32, "SIO1writeData32");
- LoadSio1Sym0(writeStat16, "SIO1writeStat16");
- LoadSio1Sym0(writeStat32, "SIO1writeStat32");
- LoadSio1Sym0(writeMode16, "SIO1writeMode16");
- LoadSio1Sym0(writeMode32, "SIO1writeMode32");
- LoadSio1Sym0(writeCtrl16, "SIO1writeCtrl16");
- LoadSio1Sym0(writeCtrl32, "SIO1writeCtrl32");
- LoadSio1Sym0(writeBaud16, "SIO1writeBaud16");
- LoadSio1Sym0(writeBaud32, "SIO1writeBaud32");
- LoadSio1Sym0(readData16, "SIO1readData16");
- LoadSio1Sym0(readData32, "SIO1readData32");
- LoadSio1Sym0(readStat16, "SIO1readStat16");
- LoadSio1Sym0(readStat32, "SIO1readStat32");
- LoadSio1Sym0(readMode16, "SIO1readMode16");
- LoadSio1Sym0(readMode32, "SIO1readMode32");
- LoadSio1Sym0(readCtrl16, "SIO1readCtrl16");
- LoadSio1Sym0(readCtrl32, "SIO1readCtrl32");
- LoadSio1Sym0(readBaud16, "SIO1readBaud16");
- LoadSio1Sym0(readBaud32, "SIO1readBaud32");
- LoadSio1Sym0(registerCallback, "SIO1registerCallback");
-
- return 0;
-}
-
-#endif
-
-void CALLBACK clearDynarec(void) {
- psxCpu->Reset();
-}
-
-int LoadPlugins() {
- int ret;
- char Plugin[MAXPATHLEN];
-
- ReleasePlugins();
- SysLibError();
-
- if (UsingIso()) {
- LoadCDRplugin(NULL);
- } else {
- sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
- if (LoadCDRplugin(Plugin) == -1) return -1;
- }
-
- sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);
- if (LoadGPUplugin(Plugin) == -1) return -1;
-
- sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);
- if (LoadSPUplugin(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;
-
- if (strcmp("Disabled", Config.Net) == 0 || strcmp("", Config.Net) == 0)
- Config.UseNet = FALSE;
- else {
- Config.UseNet = TRUE;
- sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Net);
- if (LoadNETplugin(Plugin) == -1) Config.UseNet = FALSE;
- }
-
-#ifdef ENABLE_SIO1API
- sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Sio1);
- if (LoadSIO1plugin(Plugin) == -1) return -1;
-#endif
-
- ret = CDR_init();
- if (ret < 0) { SysMessage (_("Error initializing CD-ROM plugin: %d"), ret); return -1; }
- ret = GPU_init();
- if (ret < 0) { SysMessage (_("Error initializing GPU plugin: %d"), ret); return -1; }
- ret = SPU_init();
- if (ret < 0) { SysMessage (_("Error initializing SPU plugin: %d"), ret); return -1; }
- ret = PAD1_init(1);
- if (ret < 0) { SysMessage (_("Error initializing Controller 1 plugin: %d"), ret); return -1; }
- ret = PAD2_init(2);
- if (ret < 0) { SysMessage (_("Error initializing Controller 2 plugin: %d"), ret); return -1; }
-
- if (Config.UseNet) {
- ret = NET_init();
- if (ret < 0) { SysMessage (_("Error initializing NetPlay plugin: %d"), ret); return -1; }
- }
-
-#ifdef ENABLE_SIO1API
- ret = SIO1_init();
- if (ret < 0) { SysMessage (_("Error initializing SIO1 plugin: %d"), ret); return -1; }
-#endif
-
- SysPrintf(_("Plugins loaded.\n"));
- return 0;
-}
-
-void ReleasePlugins() {
- if (Config.UseNet) {
- int ret = NET_close();
- if (ret < 0) Config.UseNet = FALSE;
- }
- NetOpened = FALSE;
-
- if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
- if (hGPUDriver != NULL) GPU_shutdown();
- if (hSPUDriver != NULL) SPU_shutdown();
- if (hPAD1Driver != NULL) PAD1_shutdown();
- if (hPAD2Driver != NULL) PAD2_shutdown();
-
- if (Config.UseNet && hNETDriver != NULL) NET_shutdown();
-
- if (hCDRDriver != NULL) SysCloseLibrary(hCDRDriver); hCDRDriver = NULL;
- if (hGPUDriver != NULL) SysCloseLibrary(hGPUDriver); hGPUDriver = NULL;
- if (hSPUDriver != NULL) SysCloseLibrary(hSPUDriver); hSPUDriver = NULL;
- if (hPAD1Driver != NULL) SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL;
- if (hPAD2Driver != NULL) SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL;
-
- if (Config.UseNet && hNETDriver != NULL) {
- SysCloseLibrary(hNETDriver); hNETDriver = NULL;
- }
-
-#ifdef ENABLE_SIO1API
- if (hSIO1Driver != NULL) {
- SIO1_shutdown();
- SysCloseLibrary(hSIO1Driver);
- hSIO1Driver = NULL;
- }
-#endif
-}
-
-// for CD swap
-int ReloadCdromPlugin()
-{
- if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
- if (hCDRDriver != NULL) SysCloseLibrary(hCDRDriver); hCDRDriver = NULL;
-
- if (UsingIso()) {
- LoadCDRplugin(NULL);
- } else {
- char Plugin[MAXPATHLEN];
- sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
- if (LoadCDRplugin(Plugin) == -1) return -1;
- }
-
- return CDR_init();
-}
-
-void SetIsoFile(const char *filename) {
- if (filename == NULL) {
- IsoFile[0] = '\0';
- return;
- }
- strncpy(IsoFile, filename, MAXPATHLEN);
-}
-
-const char *GetIsoFile(void) {
- return IsoFile;
-}
-
-boolean UsingIso(void) {
- return (IsoFile[0] != '\0');
-}
-
-void SetCdOpenCaseTime(s64 time) {
- cdOpenCaseTime = time;
-}
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+/*
+* Plugin library callback/access functions.
+*/
+
+#include "plugins.h"
+#include "cdriso.h"
+#include "../plugins/dfinput/externals.h"
+
+static char IsoFile[MAXPATHLEN] = "";
+static s64 cdOpenCaseTime = 0;
+
+GPUupdateLace GPU_updateLace;
+GPUinit GPU_init;
+GPUshutdown GPU_shutdown;
+GPUconfigure GPU_configure;
+GPUtest GPU_test;
+GPUabout GPU_about;
+GPUopen GPU_open;
+GPUclose GPU_close;
+GPUreadStatus GPU_readStatus;
+GPUreadData GPU_readData;
+GPUreadDataMem GPU_readDataMem;
+GPUwriteStatus GPU_writeStatus;
+GPUwriteData GPU_writeData;
+GPUwriteDataMem GPU_writeDataMem;
+GPUdmaChain GPU_dmaChain;
+GPUkeypressed GPU_keypressed;
+GPUdisplayText GPU_displayText;
+GPUmakeSnapshot GPU_makeSnapshot;
+GPUfreeze GPU_freeze;
+GPUgetScreenPic GPU_getScreenPic;
+GPUshowScreenPic GPU_showScreenPic;
+GPUclearDynarec GPU_clearDynarec;
+GPUvBlank GPU_vBlank;
+
+CDRinit CDR_init;
+CDRshutdown CDR_shutdown;
+CDRopen CDR_open;
+CDRclose CDR_close;
+CDRtest CDR_test;
+CDRgetTN CDR_getTN;
+CDRgetTD CDR_getTD;
+CDRreadTrack CDR_readTrack;
+CDRgetBuffer CDR_getBuffer;
+CDRplay CDR_play;
+CDRstop CDR_stop;
+CDRgetStatus CDR_getStatus;
+CDRgetDriveLetter CDR_getDriveLetter;
+CDRgetBufferSub CDR_getBufferSub;
+CDRconfigure CDR_configure;
+CDRabout CDR_about;
+CDRsetfilename CDR_setfilename;
+CDRreadCDDA CDR_readCDDA;
+CDRgetTE CDR_getTE;
+
+SPUconfigure SPU_configure;
+SPUabout SPU_about;
+SPUinit SPU_init;
+SPUshutdown SPU_shutdown;
+SPUtest SPU_test;
+SPUopen SPU_open;
+SPUclose SPU_close;
+SPUplaySample SPU_playSample;
+SPUwriteRegister SPU_writeRegister;
+SPUreadRegister SPU_readRegister;
+SPUwriteDMA SPU_writeDMA;
+SPUreadDMA SPU_readDMA;
+SPUwriteDMAMem SPU_writeDMAMem;
+SPUreadDMAMem SPU_readDMAMem;
+SPUplayADPCMchannel SPU_playADPCMchannel;
+SPUfreeze SPU_freeze;
+SPUregisterCallback SPU_registerCallback;
+SPUregisterScheduleCb SPU_registerScheduleCb;
+SPUasync SPU_async;
+SPUplayCDDAchannel SPU_playCDDAchannel;
+
+PADconfigure PAD1_configure;
+PADabout PAD1_about;
+PADinit PAD1_init;
+PADshutdown PAD1_shutdown;
+PADtest PAD1_test;
+PADopen PAD1_open;
+PADclose PAD1_close;
+PADquery PAD1_query;
+PADreadPort1 PAD1_readPort1;
+PADkeypressed PAD1_keypressed;
+PADstartPoll PAD1_startPoll;
+PADpoll PAD1_poll;
+PADsetSensitive PAD1_setSensitive;
+
+PADconfigure PAD2_configure;
+PADabout PAD2_about;
+PADinit PAD2_init;
+PADshutdown PAD2_shutdown;
+PADtest PAD2_test;
+PADopen PAD2_open;
+PADclose PAD2_close;
+PADquery PAD2_query;
+PADreadPort2 PAD2_readPort2;
+PADkeypressed PAD2_keypressed;
+PADstartPoll PAD2_startPoll;
+PADpoll PAD2_poll;
+PADsetSensitive PAD2_setSensitive;
+
+NETinit NET_init;
+NETshutdown NET_shutdown;
+NETopen NET_open;
+NETclose NET_close;
+NETtest NET_test;
+NETconfigure NET_configure;
+NETabout NET_about;
+NETpause NET_pause;
+NETresume NET_resume;
+NETqueryPlayer NET_queryPlayer;
+NETsendData NET_sendData;
+NETrecvData NET_recvData;
+NETsendPadData NET_sendPadData;
+NETrecvPadData NET_recvPadData;
+NETsetInfo NET_setInfo;
+NETkeypressed NET_keypressed;
+
+#ifdef ENABLE_SIO1API
+
+SIO1init SIO1_init;
+SIO1shutdown SIO1_shutdown;
+SIO1open SIO1_open;
+SIO1close SIO1_close;
+SIO1test SIO1_test;
+SIO1configure SIO1_configure;
+SIO1about SIO1_about;
+SIO1pause SIO1_pause;
+SIO1resume SIO1_resume;
+SIO1keypressed SIO1_keypressed;
+SIO1writeData8 SIO1_writeData8;
+SIO1writeData16 SIO1_writeData16;
+SIO1writeData32 SIO1_writeData32;
+SIO1writeStat16 SIO1_writeStat16;
+SIO1writeStat32 SIO1_writeStat32;
+SIO1writeMode16 SIO1_writeMode16;
+SIO1writeMode32 SIO1_writeMode32;
+SIO1writeCtrl16 SIO1_writeCtrl16;
+SIO1writeCtrl32 SIO1_writeCtrl32;
+SIO1writeBaud16 SIO1_writeBaud16;
+SIO1writeBaud32 SIO1_writeBaud32;
+SIO1readData8 SIO1_readData8;
+SIO1readData16 SIO1_readData16;
+SIO1readData32 SIO1_readData32;
+SIO1readStat16 SIO1_readStat16;
+SIO1readStat32 SIO1_readStat32;
+SIO1readMode16 SIO1_readMode16;
+SIO1readMode32 SIO1_readMode32;
+SIO1readCtrl16 SIO1_readCtrl16;
+SIO1readCtrl32 SIO1_readCtrl32;
+SIO1readBaud16 SIO1_readBaud16;
+SIO1readBaud32 SIO1_readBaud32;
+SIO1registerCallback SIO1_registerCallback;
+
+#endif
+
+static const char *err;
+
+#define CheckErr(func) { \
+ err = SysLibError(); \
+ if (err != NULL) { SysMessage(_("Error loading %s: %s"), func, err); return -1; } \
+}
+
+#define LoadSym(dest, src, name, checkerr) { \
+ dest = (src)SysLoadSym(drv, name); \
+ if (checkerr) { CheckErr(name); } else SysLibError(); \
+}
+
+void *hGPUDriver = NULL;
+
+void CALLBACK GPU__displayText(char *pText) {
+ SysPrintf("%s\n", pText);
+}
+
+long CALLBACK GPU__configure(void) { return 0; }
+long CALLBACK GPU__test(void) { return 0; }
+void CALLBACK GPU__about(void) {}
+void CALLBACK GPU__makeSnapshot(void) {}
+void CALLBACK GPU__keypressed(int key) {}
+long CALLBACK GPU__getScreenPic(unsigned char *pMem) { return -1; }
+long CALLBACK GPU__showScreenPic(unsigned char *pMem) { return -1; }
+void CALLBACK GPU__clearDynarec(void (CALLBACK *callback)(void)) {}
+void CALLBACK GPU__vBlank(int val) {}
+
+#define LoadGpuSym1(dest, name) \
+ LoadSym(GPU_##dest, GPU##dest, name, TRUE);
+
+#define LoadGpuSym0(dest, name) \
+ LoadSym(GPU_##dest, GPU##dest, name, FALSE); \
+ if (GPU_##dest == NULL) GPU_##dest = (GPU##dest) GPU__##dest;
+
+#define LoadGpuSymN(dest, name) \
+ LoadSym(GPU_##dest, GPU##dest, name, FALSE);
+
+static int LoadGPUplugin(const char *GPUdll) {
+ void *drv;
+
+ hGPUDriver = SysLoadLibrary(GPUdll);
+ if (hGPUDriver == NULL) {
+ GPU_configure = NULL;
+ SysMessage (_("Could not load GPU plugin %s!"), GPUdll); return -1;
+ }
+ drv = hGPUDriver;
+ LoadGpuSym1(init, "GPUinit");
+ LoadGpuSym1(shutdown, "GPUshutdown");
+ LoadGpuSym1(open, "GPUopen");
+ LoadGpuSym1(close, "GPUclose");
+ LoadGpuSym1(readData, "GPUreadData");
+ LoadGpuSym1(readDataMem, "GPUreadDataMem");
+ LoadGpuSym1(readStatus, "GPUreadStatus");
+ LoadGpuSym1(writeData, "GPUwriteData");
+ LoadGpuSym1(writeDataMem, "GPUwriteDataMem");
+ LoadGpuSym1(writeStatus, "GPUwriteStatus");
+ LoadGpuSym1(dmaChain, "GPUdmaChain");
+ LoadGpuSym1(updateLace, "GPUupdateLace");
+ LoadGpuSym0(keypressed, "GPUkeypressed");
+ LoadGpuSym0(displayText, "GPUdisplayText");
+ LoadGpuSym0(makeSnapshot, "GPUmakeSnapshot");
+ LoadGpuSym1(freeze, "GPUfreeze");
+ LoadGpuSym0(getScreenPic, "GPUgetScreenPic");
+ LoadGpuSym0(showScreenPic, "GPUshowScreenPic");
+ LoadGpuSym0(clearDynarec, "GPUclearDynarec");
+ LoadGpuSym0(vBlank, "GPUvBlank");
+ LoadGpuSym0(configure, "GPUconfigure");
+ LoadGpuSym0(test, "GPUtest");
+ LoadGpuSym0(about, "GPUabout");
+
+ return 0;
+}
+
+void *hCDRDriver = NULL;
+
+long CALLBACK CDR__play(unsigned char *sector) { return 0; }
+long CALLBACK CDR__stop(void) { return 0; }
+
+long CALLBACK CDR__getStatus(struct CdrStat *stat) {
+ if (cdOpenCaseTime < 0 || cdOpenCaseTime > (s64)time(NULL))
+ stat->Status = 0x10;
+ else
+ stat->Status = 0;
+
+ return 0;
+}
+
+char* CALLBACK CDR__getDriveLetter(void) { return NULL; }
+long CALLBACK CDR__configure(void) { return 0; }
+long CALLBACK CDR__test(void) { return 0; }
+void CALLBACK CDR__about(void) {}
+long CALLBACK CDR__setfilename(char*filename) { return 0; }
+
+#define LoadCdrSym1(dest, name) \
+ LoadSym(CDR_##dest, CDR##dest, name, TRUE);
+
+#define LoadCdrSym0(dest, name) \
+ LoadSym(CDR_##dest, CDR##dest, name, FALSE); \
+ if (CDR_##dest == NULL) CDR_##dest = (CDR##dest) CDR__##dest;
+
+#define LoadCdrSymN(dest, name) \
+ LoadSym(CDR_##dest, CDR##dest, name, FALSE);
+
+static int LoadCDRplugin(const char *CDRdll) {
+ void *drv;
+
+ if (CDRdll == NULL) {
+ cdrIsoInit();
+ return 0;
+ }
+
+ hCDRDriver = SysLoadLibrary(CDRdll);
+ if (hCDRDriver == NULL) {
+ CDR_configure = NULL;
+ SysMessage (_("Could not load CD-ROM plugin %s!"), CDRdll); return -1;
+ }
+ drv = hCDRDriver;
+ LoadCdrSym1(init, "CDRinit");
+ LoadCdrSym1(shutdown, "CDRshutdown");
+ LoadCdrSym1(open, "CDRopen");
+ LoadCdrSym1(close, "CDRclose");
+ LoadCdrSym1(getTN, "CDRgetTN");
+ LoadCdrSym1(getTD, "CDRgetTD");
+ LoadCdrSym1(readTrack, "CDRreadTrack");
+ LoadCdrSym1(getBuffer, "CDRgetBuffer");
+ LoadCdrSym1(getBufferSub, "CDRgetBufferSub");
+ LoadCdrSym0(play, "CDRplay");
+ LoadCdrSym0(stop, "CDRstop");
+ LoadCdrSym0(getStatus, "CDRgetStatus");
+ LoadCdrSym0(getDriveLetter, "CDRgetDriveLetter");
+ LoadCdrSym0(configure, "CDRconfigure");
+ LoadCdrSym0(test, "CDRtest");
+ LoadCdrSym0(about, "CDRabout");
+ LoadCdrSym0(setfilename, "CDRsetfilename");
+ LoadCdrSymN(readCDDA, "CDRreadCDDA");
+ LoadCdrSymN(getTE, "CDRgetTE");
+
+ return 0;
+}
+
+void *hSPUDriver = NULL;
+
+long CALLBACK SPU__configure(void) { return 0; }
+void CALLBACK SPU__about(void) {}
+long CALLBACK SPU__test(void) { return 0; }
+void CALLBACK SPU__registerScheduleCb(void (CALLBACK *cb)(unsigned int)) {}
+
+#define LoadSpuSym1(dest, name) \
+ LoadSym(SPU_##dest, SPU##dest, name, TRUE);
+
+#define LoadSpuSym0(dest, name) \
+ LoadSym(SPU_##dest, SPU##dest, name, FALSE); \
+ if (SPU_##dest == NULL) SPU_##dest = (SPU##dest) SPU__##dest;
+
+#define LoadSpuSymN(dest, name) \
+ LoadSym(SPU_##dest, SPU##dest, name, FALSE);
+
+static int LoadSPUplugin(const char *SPUdll) {
+ void *drv;
+
+ hSPUDriver = SysLoadLibrary(SPUdll);
+ if (hSPUDriver == NULL) {
+ SPU_configure = NULL;
+ SysMessage (_("Could not load SPU plugin %s!"), SPUdll); return -1;
+ }
+ drv = hSPUDriver;
+ LoadSpuSym1(init, "SPUinit");
+ LoadSpuSym1(shutdown, "SPUshutdown");
+ LoadSpuSym1(open, "SPUopen");
+ LoadSpuSym1(close, "SPUclose");
+ LoadSpuSym0(configure, "SPUconfigure");
+ LoadSpuSym0(about, "SPUabout");
+ LoadSpuSym0(test, "SPUtest");
+ LoadSpuSym1(writeRegister, "SPUwriteRegister");
+ LoadSpuSym1(readRegister, "SPUreadRegister");
+ LoadSpuSym1(writeDMA, "SPUwriteDMA");
+ LoadSpuSym1(readDMA, "SPUreadDMA");
+ LoadSpuSym1(writeDMAMem, "SPUwriteDMAMem");
+ LoadSpuSym1(readDMAMem, "SPUreadDMAMem");
+ LoadSpuSym1(playADPCMchannel, "SPUplayADPCMchannel");
+ LoadSpuSym1(freeze, "SPUfreeze");
+ LoadSpuSym1(registerCallback, "SPUregisterCallback");
+ LoadSpuSym0(registerScheduleCb, "SPUregisterScheduleCb");
+ LoadSpuSymN(async, "SPUasync");
+ LoadSpuSymN(playCDDAchannel, "SPUplayCDDAchannel");
+
+ return 0;
+}
+
+void *hPAD1Driver = NULL;
+void *hPAD2Driver = NULL;
+
+static int multitap1 = -1;
+static int multitap2 = -1;
+//Pad information, keystate, mode, config mode, vibration
+static PadDataS pad[8];
+
+static int reqPos, respSize, req;
+static int ledStateReq44[8];
+
+static unsigned char buf[256];
+static unsigned char bufMulti[34] = { 0x80, 0x5a,
+ 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+unsigned char stdpar[8] = { 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+unsigned char multitappar[34] = { 0x80, 0x5a,
+ 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+//response for request 44, 45, 46, 47, 4C, 4D
+static unsigned char resp45[8] = {0xF3, 0x5A, 0x01, 0x02, 0x00, 0x02, 0x01, 0x00};
+static unsigned char resp46_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A};
+static unsigned char resp46_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14};
+static unsigned char resp47[8] = {0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00};
+static unsigned char resp4C_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00};
+static unsigned char resp4C_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00};
+static unsigned char resp4D[8] = {0xF3, 0x5A, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF};
+
+//fixed reponse of request number 41, 48, 49, 4A, 4B, 4E, 4F
+static unsigned char resp40[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static unsigned char resp41[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static unsigned char resp43[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static unsigned char resp44[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static unsigned char resp49[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static unsigned char resp4A[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static unsigned char resp4B[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static unsigned char resp4E[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static unsigned char resp4F[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+// Resquest of psx core
+enum {
+ // REQUEST
+ // first call of this request for the pad, the pad is configured as an digital pad.
+ // 0x0X, 0x42, 0x0Y, 0xZZ, 0xAA, 0x00, 0x00, 0x00, 0x00
+ // X pad number (used for the multitap, first request response 0x00, 0x80, 0x5A, (8 bytes pad A), (8 bytes pad B), (8 bytes pad C), (8 bytes pad D)
+ // Y if 1 : psx request the full length response for the multitap, 3 bytes header and 4 block of 8 bytes per pad
+ // Y if 0 : psx request a pad key state
+ // ZZ rumble small motor 00-> OFF, 01 -> ON
+ // AA rumble large motor speed 0x00 -> 0xFF
+ // RESPONSE
+ // header 3 Bytes
+ // 0x00
+ // PadId -> 0x41 for digital pas, 0x73 for analog pad
+ // 0x5A mode has not change (no press on analog button on the center of pad), 0x00 the analog button have been pressed and the mode switch
+ // 6 Bytes for keystates
+ CMD_READ_DATA_AND_VIBRATE = 0x42,
+
+ // REQUEST
+ // Header
+ // 0x0N, 0x43, 0x00, XX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ // XX = 00 -> Normal mode : Seconde bytes of response = padId
+ // XX = 01 -> Configuration mode : Seconde bytes of response = 0xF3
+ // RESPONSE
+ // enter in config mode example :
+ // req : 01 43 00 01 00 00 00 00 00 00
+ // res : 00 41 5A buttons state, analog states
+ // exit config mode :
+ // req : 01 43 00 00 00 00 00 00 00 00
+ // res : 00 F3 5A buttons state, analog states
+ CMD_CONFIG_MODE = 0x43,
+
+ // Set led State
+ // REQUEST
+ // 0x0N, 0x44, 0x00, VAL, SEL, 0x00, 0x00, 0x00, 0x00
+ // If sel = 2 then
+ // VAL = 00 -> OFF
+ // VAL = 01 -> ON
+ // RESPONSE
+ // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ CMD_SET_MODE_AND_LOCK = 0x44,
+
+ // Get Analog Led state
+ // REQUEST
+ // 0x0N, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ // RESPONSE
+ // 0x00, 0xF3, 0x5A, 0x01, 0x02, VAL, 0x02, 0x01, 0x00
+ // VAL = 00 Led OFF
+ // VAL = 01 Led ON
+ CMD_QUERY_MODEL_AND_MODE = 0x45,
+
+ //Get Variable A
+ // REQUEST
+ // 0x0N, 0x46, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
+ // RESPONSE
+ // XX=00
+ // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A
+ // XX=01
+ // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14
+ CMD_QUERY_ACT = 0x46,
+
+ // REQUEST
+ // 0x0N, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ // RESPONSE
+ // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00
+ CMD_QUERY_COMB = 0x47,
+
+ // REQUEST
+ // 0x0N, 0x4C, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
+ // RESPONSE
+ // XX = 0
+ // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00
+ // XX = 1
+ // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00
+ CMD_QUERY_MODE = 0x4C,
+
+ // REQUEST
+ // 0x0N, 0x4D, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
+ // RESPONSE
+ // 0x00, 0xF3, 0x5A, old value or
+ // AA = 01 unlock large motor (and swap VAL1 and VAL2)
+ // BB = 01 unlock large motor (default)
+ // CC, DD, EE, FF = all FF -> unlock small motor
+ //
+ // default repsonse for analog pad with 2 motor : 0x00 0xF3 0x5A 0x00 0x01 0xFF 0xFF 0xFF 0xFF
+ //
+ CMD_VIBRATION_TOGGLE = 0x4D,
+ REQ40 = 0x40,
+ REQ41 = 0x41,
+ REQ49 = 0x49,
+ REQ4A = 0x4A,
+ REQ4B = 0x4B,
+ REQ4E = 0x4E,
+ REQ4F = 0x4F
+};
+
+
+
+
+//NO MULTITAP
+
+void initBufForRequest(int padIndex, char value){
+ switch (value){
+ //Pad keystate already in buffer
+ //case CMD_READ_DATA_AND_VIBRATE :
+ // break;
+ case CMD_CONFIG_MODE :
+ if (pad[padIndex].configMode == 1) {
+ memcpy(buf, resp43, 8);
+ break;
+ }
+ //else, not in config mode, pad keystate return (already in the buffer)
+ break;
+ case CMD_SET_MODE_AND_LOCK :
+ memcpy(buf, resp44, 8);
+ break;
+ case CMD_QUERY_MODEL_AND_MODE :
+ memcpy(buf, resp45, 8);
+ break;
+ case CMD_QUERY_ACT :
+ memcpy(buf, resp46_00, 8);
+ break;
+ case CMD_QUERY_COMB :
+ memcpy(buf, resp47, 8);
+ break;
+ case CMD_QUERY_MODE :
+ memcpy(buf, resp4C_00, 8);
+ break;
+ case CMD_VIBRATION_TOGGLE :
+ memcpy(buf, resp4D, 8);
+ break;
+ case REQ40 :
+ memcpy(buf, resp40, 8);
+ break;
+ case REQ41 :
+ memcpy(buf, resp41, 8);
+ break;
+ case REQ49 :
+ memcpy(buf, resp49, 8);
+ break;
+ case REQ4A :
+ memcpy(buf, resp4A, 8);
+ break;
+ case REQ4B :
+ memcpy(buf, resp4B, 8);
+ break;
+ case REQ4E :
+ memcpy(buf, resp4E, 8);
+ break;
+ case REQ4F :
+ memcpy(buf, resp4F, 8);
+ break;
+ }
+}
+
+
+
+
+void reqIndex2Treatment(int padIndex, char value){
+ switch (req){
+ case CMD_CONFIG_MODE :
+ //0x43
+ if (value == 0) {
+ pad[padIndex].configMode = 0;
+ } else {
+ pad[padIndex].configMode = 1;
+ }
+ break;
+ case CMD_SET_MODE_AND_LOCK :
+ //0x44 store the led state for change mode if the next value = 0x02
+ //0x01 analog ON
+ //0x00 analog OFF
+ ledStateReq44[padIndex] = value;
+ break;
+ case CMD_QUERY_ACT :
+ //0x46
+ if (value == 1) {
+ memcpy(buf, resp46_01, 8);
+ }
+ break;
+ case CMD_QUERY_MODE :
+ if (value == 1) {
+ memcpy(buf, resp4C_01, 8);
+ }
+ break;
+ case CMD_VIBRATION_TOGGLE :
+ //0x4D
+ memcpy(buf, resp4D, 8);
+ break;
+ case CMD_READ_DATA_AND_VIBRATE:
+ //mem the vibration value for small motor;
+ pad[padIndex].Vib[0] = value;
+ break;
+ }
+}
+
+void vibrate(int padIndex){
+ if (pad[padIndex].Vib[0] != pad[padIndex].VibF[0] || pad[padIndex].Vib[1] != pad[padIndex].VibF[1]) {
+ //value is different update Value and call libretro for vibration
+ pad[padIndex].VibF[0] = pad[padIndex].Vib[0];
+ pad[padIndex].VibF[1] = pad[padIndex].Vib[1];
+ plat_trigger_vibrate(padIndex, pad[padIndex].VibF[0], pad[padIndex].VibF[1]);
+ //printf("vibration pad %i", padIndex);
+ }
+}
+
+
+
+
+//Build response for 0x42 request Pad in port
+void _PADstartPoll(PadDataS *pad) {
+ switch (pad->controllerType) {
+ case PSE_PAD_TYPE_MOUSE:
+ stdpar[0] = 0x12;
+ stdpar[2] = pad->buttonStatus & 0xff;
+ stdpar[3] = pad->buttonStatus >> 8;
+ stdpar[4] = pad->moveX;
+ stdpar[5] = pad->moveY;
+ memcpy(buf, stdpar, 6);
+ respSize = 6;
+ break;
+ case PSE_PAD_TYPE_NEGCON: // npc101/npc104(slph00001/slph00069)
+ stdpar[0] = 0x23;
+ stdpar[2] = pad->buttonStatus & 0xff;
+ stdpar[3] = pad->buttonStatus >> 8;
+ stdpar[4] = pad->rightJoyX;
+ stdpar[5] = pad->rightJoyY;
+ stdpar[6] = pad->leftJoyX;
+ stdpar[7] = pad->leftJoyY;
+ memcpy(buf, stdpar, 8);
+ respSize = 8;
+ break;
+ case PSE_PAD_TYPE_GUNCON: // GUNCON - gun controller SLPH-00034 from Namco
+ stdpar[0] = 0x63;
+ stdpar[1] = 0x5a;
+ stdpar[2] = pad->buttonStatus & 0xff;
+ stdpar[3] = pad->buttonStatus >> 8;
+
+ //This code assumes an X resolution of 256 and a Y resolution of 240
+ int xres = 256;
+ int yres = 240;
+
+ //The code wants an input range for x and y of 0-1023 we passed in -32767 -> 32767
+ int absX = (pad->absoluteX / 64) + 512;
+ int absY = (pad->absoluteY / 64) + 512;
+
+ //Keep within limits
+ if (absX > 1023) absX = 1023;
+ if (absX < 0) absX = 0;
+ if (absY > 1023) absY = 1023;
+ if (absY < 0) absY = 0;
+
+ stdpar[4] = 0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10);
+ stdpar[5] = (0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10)) >> 8;
+ stdpar[6] = 0x20 + (yres * absY >> 10);
+ stdpar[7] = (0x20 + (yres * absY >> 10)) >> 8;
+
+ //Offscreen - Point at the side of the screen so PSX thinks you are pointing offscreen
+ //Required as a mouse can't be offscreen
+ //Coordinates X=0001h, Y=000Ah indicates "no light"
+ //This will mean you cannot shoot the very each of the screen
+ //ToDo read offscreen range from settings if useful to change
+ int OffscreenRange = 2;
+ if (absX < (OffscreenRange) || absX > (1023 - OffscreenRange) || absY < (OffscreenRange) || absY > (1023 - OffscreenRange))
+ {
+ stdpar[4] = 0x01;
+ stdpar[5] = 0x00;
+ stdpar[6] = 0x0A;
+ stdpar[7] = 0x00;
+ }
+
+ memcpy(buf, stdpar, 8);
+ respSize = 8;
+ break;
+ case PSE_PAD_TYPE_ANALOGPAD: // scph1150
+ stdpar[0] = 0x73;
+ stdpar[2] = pad->buttonStatus & 0xff;
+ stdpar[3] = pad->buttonStatus >> 8;
+ stdpar[4] = pad->rightJoyX;
+ stdpar[5] = pad->rightJoyY;
+ stdpar[6] = pad->leftJoyX;
+ stdpar[7] = pad->leftJoyY;
+ memcpy(buf, stdpar, 8);
+ respSize = 8;
+ break;
+ case PSE_PAD_TYPE_ANALOGJOY: // scph1110
+ stdpar[0] = 0x53;
+ stdpar[2] = pad->buttonStatus & 0xff;
+ stdpar[3] = pad->buttonStatus >> 8;
+ stdpar[4] = pad->rightJoyX;
+ stdpar[5] = pad->rightJoyY;
+ stdpar[6] = pad->leftJoyX;
+ stdpar[7] = pad->leftJoyY;
+ memcpy(buf, stdpar, 8);
+ respSize = 8;
+ break;
+ case PSE_PAD_TYPE_STANDARD:
+ default:
+ stdpar[0] = 0x41;
+ stdpar[2] = pad->buttonStatus & 0xff;
+ stdpar[3] = pad->buttonStatus >> 8;
+ //avoid analog value in multitap mode if change pad type in game.
+ stdpar[4] = 0xff;
+ stdpar[5] = 0xff;
+ stdpar[6] = 0xff;
+ stdpar[7] = 0xff;
+ memcpy(buf, stdpar, 8);
+ respSize = 8;
+ }
+}
+
+
+//Build response for 0x42 request Multitap in port
+//Response header for multitap : 0x80, 0x5A, (Pad information port 1-2A), (Pad information port 1-2B), (Pad information port 1-2C), (Pad information port 1-2D)
+void _PADstartPollMultitap(PadDataS* padd) {
+ int i, offset;
+ for(i = 0; i < 4; i++) {
+ offset = 2 + (i * 8);
+ _PADstartPoll(&padd[i]);
+ memcpy(multitappar+offset, stdpar, 8);
+ }
+ memcpy(bufMulti, multitappar, 34);
+ respSize = 34;
+}
+
+
+unsigned char _PADpoll(int port, unsigned char value) {
+ if (reqPos == 0) {
+ //mem the request number
+ req = value;
+ //copy the default value of request response in buffer instead of the keystate
+ initBufForRequest(port, value);
+ }
+
+ //if no new request the pad return 0xff, for signaling connected
+ if (reqPos >= respSize) return 0xff;
+
+ switch(reqPos){
+ case 2:
+ reqIndex2Treatment(port, value);
+ break;
+ case 3:
+ switch(req) {
+ case CMD_SET_MODE_AND_LOCK :
+ //change mode on pad
+ break;
+ case CMD_READ_DATA_AND_VIBRATE:
+ //mem the vibration value for Large motor;
+ pad[port].Vib[1] = value;
+ //vibration
+ vibrate(port);
+ break;
+ }
+ break;
+ }
+ return buf[reqPos++];
+}
+
+
+unsigned char _PADpollMultitap(int port, unsigned char value) {
+ if (reqPos >= respSize) return 0xff;
+ return bufMulti[reqPos++];
+}
+
+
+// refresh the button state on port 1.
+// int pad is not needed.
+unsigned char CALLBACK PAD1__startPoll(int pad) {
+ reqPos = 0;
+ // first call the pad provide if a multitap is connected between the psx and himself
+ if (multitap1 == -1) {
+ PadDataS padd;
+ padd.requestPadIndex = 0;
+ PAD1_readPort1(&padd);
+ multitap1 = padd.portMultitap;
+ }
+ // just one pad is on port 1 : NO MULTITAP
+ if (multitap1 == 0) {
+ PadDataS padd;
+ padd.requestPadIndex = 0;
+ PAD1_readPort1(&padd);
+ _PADstartPoll(&padd);
+ } else {
+ // a multitap is plugged : refresh all pad.
+ int i;
+ PadDataS padd[4];
+ for(i = 0; i < 4; i++) {
+ padd[i].requestPadIndex = i;
+ PAD1_readPort1(&padd[i]);
+ }
+ _PADstartPollMultitap(padd);
+ }
+ //printf("\npad 1 : ");
+ return 0x00;
+}
+
+unsigned char CALLBACK PAD1__poll(unsigned char value) {
+ char tmp;
+ if (multitap1 == 1) {
+ tmp = _PADpollMultitap(0, value);
+ } else {
+ tmp = _PADpoll(0, value);
+ }
+ //printf("%2x:%2x, ",value,tmp);
+ return tmp;
+
+}
+
+
+long CALLBACK PAD1__configure(void) { return 0; }
+void CALLBACK PAD1__about(void) {}
+long CALLBACK PAD1__test(void) { return 0; }
+long CALLBACK PAD1__query(void) { return 3; }
+long CALLBACK PAD1__keypressed() { return 0; }
+
+#define LoadPad1Sym1(dest, name) \
+ LoadSym(PAD1_##dest, PAD##dest, name, TRUE);
+
+#define LoadPad1SymN(dest, name) \
+ LoadSym(PAD1_##dest, PAD##dest, name, FALSE);
+
+#define LoadPad1Sym0(dest, name) \
+ LoadSym(PAD1_##dest, PAD##dest, name, FALSE); \
+ if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;
+
+static int LoadPAD1plugin(const char *PAD1dll) {
+ void *drv;
+
+ hPAD1Driver = SysLoadLibrary(PAD1dll);
+ if (hPAD1Driver == NULL) {
+ PAD1_configure = NULL;
+ SysMessage (_("Could not load Controller 1 plugin %s!"), PAD1dll); return -1;
+ }
+ drv = hPAD1Driver;
+ LoadPad1Sym1(init, "PADinit");
+ LoadPad1Sym1(shutdown, "PADshutdown");
+ LoadPad1Sym1(open, "PADopen");
+ LoadPad1Sym1(close, "PADclose");
+ LoadPad1Sym0(query, "PADquery");
+ LoadPad1Sym1(readPort1, "PADreadPort1");
+ LoadPad1Sym0(configure, "PADconfigure");
+ LoadPad1Sym0(test, "PADtest");
+ LoadPad1Sym0(about, "PADabout");
+ LoadPad1Sym0(keypressed, "PADkeypressed");
+ LoadPad1Sym0(startPoll, "PADstartPoll");
+ LoadPad1Sym0(poll, "PADpoll");
+ LoadPad1SymN(setSensitive, "PADsetSensitive");
+
+ return 0;
+}
+
+unsigned char CALLBACK PAD2__startPoll(int pad) {
+ int pad_index;
+
+ reqPos = 0;
+ if (multitap1 == 0 && (multitap2 == 0 || multitap2 == 2)) {
+ pad_index = 1;
+ } else if(multitap1 == 1 && (multitap2 == 0 || multitap2 == 2)) {
+ pad_index = 4;
+ } else {
+ pad_index = 0;
+ }
+
+ //first call the pad provide if a multitap is connected between the psx and himself
+ if (multitap2 == -1) {
+ PadDataS padd;
+ padd.requestPadIndex = pad_index;
+ PAD2_readPort2(&padd);
+ multitap2 = padd.portMultitap;
+ }
+
+ // just one pad is on port 1 : NO MULTITAP
+ if (multitap2 == 0) {
+ PadDataS padd;
+ padd.requestPadIndex = pad_index;
+ PAD2_readPort2(&padd);
+ _PADstartPoll(&padd);
+ } else {
+ // a multitap is plugged : refresh all pad.
+ int i;
+ PadDataS padd[4];
+ for(i = 0; i < 4; i++) {
+ padd[i].requestPadIndex = i+pad_index;
+ PAD2_readPort2(&padd[i]);
+ }
+ _PADstartPollMultitap(padd);
+ }
+ //printf("\npad 2 : ");
+ return 0x00;
+}
+
+unsigned char CALLBACK PAD2__poll(unsigned char value) {
+ char tmp;
+ if (multitap2 == 2) {
+ tmp = _PADpollMultitap(1, value);
+ } else {
+ tmp = _PADpoll(1, value);
+ }
+ //printf("%2x:%2x, ",value,tmp);
+ return tmp;
+}
+
+long CALLBACK PAD2__configure(void) { return 0; }
+void CALLBACK PAD2__about(void) {}
+long CALLBACK PAD2__test(void) { return 0; }
+long CALLBACK PAD2__query(void) { return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2; }
+long CALLBACK PAD2__keypressed() { return 0; }
+
+#define LoadPad2Sym1(dest, name) \
+ LoadSym(PAD2_##dest, PAD##dest, name, TRUE);
+
+#define LoadPad2Sym0(dest, name) \
+ LoadSym(PAD2_##dest, PAD##dest, name, FALSE); \
+ if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest;
+
+#define LoadPad2SymN(dest, name) \
+ LoadSym(PAD2_##dest, PAD##dest, name, FALSE);
+
+static int LoadPAD2plugin(const char *PAD2dll) {
+ void *drv;
+
+ hPAD2Driver = SysLoadLibrary(PAD2dll);
+ if (hPAD2Driver == NULL) {
+ PAD2_configure = NULL;
+ SysMessage (_("Could not load Controller 2 plugin %s!"), PAD2dll); return -1;
+ }
+ drv = hPAD2Driver;
+ LoadPad2Sym1(init, "PADinit");
+ LoadPad2Sym1(shutdown, "PADshutdown");
+ LoadPad2Sym1(open, "PADopen");
+ LoadPad2Sym1(close, "PADclose");
+ LoadPad2Sym0(query, "PADquery");
+ LoadPad2Sym1(readPort2, "PADreadPort2");
+ LoadPad2Sym0(configure, "PADconfigure");
+ LoadPad2Sym0(test, "PADtest");
+ LoadPad2Sym0(about, "PADabout");
+ LoadPad2Sym0(keypressed, "PADkeypressed");
+ LoadPad2Sym0(startPoll, "PADstartPoll");
+ LoadPad2Sym0(poll, "PADpoll");
+ LoadPad2SymN(setSensitive, "PADsetSensitive");
+
+ return 0;
+}
+
+void *hNETDriver = NULL;
+
+void CALLBACK NET__setInfo(netInfo *info) {}
+void CALLBACK NET__keypressed(int key) {}
+long CALLBACK NET__configure(void) { return 0; }
+long CALLBACK NET__test(void) { return 0; }
+void CALLBACK NET__about(void) {}
+
+#define LoadNetSym1(dest, name) \
+ LoadSym(NET_##dest, NET##dest, name, TRUE);
+
+#define LoadNetSymN(dest, name) \
+ LoadSym(NET_##dest, NET##dest, name, FALSE);
+
+#define LoadNetSym0(dest, name) \
+ LoadSym(NET_##dest, NET##dest, name, FALSE); \
+ if (NET_##dest == NULL) NET_##dest = (NET##dest) NET__##dest;
+
+static int LoadNETplugin(const char *NETdll) {
+ void *drv;
+
+ hNETDriver = SysLoadLibrary(NETdll);
+ if (hNETDriver == NULL) {
+ SysMessage (_("Could not load NetPlay plugin %s!"), NETdll); return -1;
+ }
+ drv = hNETDriver;
+ LoadNetSym1(init, "NETinit");
+ LoadNetSym1(shutdown, "NETshutdown");
+ LoadNetSym1(open, "NETopen");
+ LoadNetSym1(close, "NETclose");
+ LoadNetSymN(sendData, "NETsendData");
+ LoadNetSymN(recvData, "NETrecvData");
+ LoadNetSym1(sendPadData, "NETsendPadData");
+ LoadNetSym1(recvPadData, "NETrecvPadData");
+ LoadNetSym1(queryPlayer, "NETqueryPlayer");
+ LoadNetSym1(pause, "NETpause");
+ LoadNetSym1(resume, "NETresume");
+ LoadNetSym0(setInfo, "NETsetInfo");
+ LoadNetSym0(keypressed, "NETkeypressed");
+ LoadNetSym0(configure, "NETconfigure");
+ LoadNetSym0(test, "NETtest");
+ LoadNetSym0(about, "NETabout");
+
+ return 0;
+}
+
+#ifdef ENABLE_SIO1API
+
+void *hSIO1Driver = NULL;
+
+long CALLBACK SIO1__init(void) { return 0; }
+long CALLBACK SIO1__shutdown(void) { return 0; }
+long CALLBACK SIO1__open(void) { return 0; }
+long CALLBACK SIO1__close(void) { return 0; }
+long CALLBACK SIO1__configure(void) { return 0; }
+long CALLBACK SIO1__test(void) { return 0; }
+void CALLBACK SIO1__about(void) {}
+void CALLBACK SIO1__pause(void) {}
+void CALLBACK SIO1__resume(void) {}
+long CALLBACK SIO1__keypressed(int key) { return 0; }
+void CALLBACK SIO1__writeData8(unsigned char val) {}
+void CALLBACK SIO1__writeData16(unsigned short val) {}
+void CALLBACK SIO1__writeData32(unsigned long val) {}
+void CALLBACK SIO1__writeStat16(unsigned short val) {}
+void CALLBACK SIO1__writeStat32(unsigned long val) {}
+void CALLBACK SIO1__writeMode16(unsigned short val) {}
+void CALLBACK SIO1__writeMode32(unsigned long val) {}
+void CALLBACK SIO1__writeCtrl16(unsigned short val) {}
+void CALLBACK SIO1__writeCtrl32(unsigned long val) {}
+void CALLBACK SIO1__writeBaud16(unsigned short val) {}
+void CALLBACK SIO1__writeBaud32(unsigned long val) {}
+unsigned char CALLBACK SIO1__readData8(void) { return 0; }
+unsigned short CALLBACK SIO1__readData16(void) { return 0; }
+unsigned long CALLBACK SIO1__readData32(void) { return 0; }
+unsigned short CALLBACK SIO1__readStat16(void) { return 0; }
+unsigned long CALLBACK SIO1__readStat32(void) { return 0; }
+unsigned short CALLBACK SIO1__readMode16(void) { return 0; }
+unsigned long CALLBACK SIO1__readMode32(void) { return 0; }
+unsigned short CALLBACK SIO1__readCtrl16(void) { return 0; }
+unsigned long CALLBACK SIO1__readCtrl32(void) { return 0; }
+unsigned short CALLBACK SIO1__readBaud16(void) { return 0; }
+unsigned long CALLBACK SIO1__readBaud32(void) { return 0; }
+void CALLBACK SIO1__registerCallback(void (CALLBACK *callback)(void)) {};
+
+void CALLBACK SIO1irq(void) {
+ psxHu32ref(0x1070) |= SWAPu32(0x100);
+}
+
+#define LoadSio1Sym1(dest, name) \
+ LoadSym(SIO1_##dest, SIO1##dest, name, TRUE);
+
+#define LoadSio1SymN(dest, name) \
+ LoadSym(SIO1_##dest, SIO1##dest, name, FALSE);
+
+#define LoadSio1Sym0(dest, name) \
+ LoadSym(SIO1_##dest, SIO1##dest, name, FALSE); \
+ if (SIO1_##dest == NULL) SIO1_##dest = (SIO1##dest) SIO1__##dest;
+
+static int LoadSIO1plugin(const char *SIO1dll) {
+ void *drv;
+
+ hSIO1Driver = SysLoadLibrary(SIO1dll);
+ if (hSIO1Driver == NULL) {
+ SysMessage (_("Could not load SIO1 plugin %s!"), SIO1dll); return -1;
+ }
+ drv = hSIO1Driver;
+
+ LoadSio1Sym0(init, "SIO1init");
+ LoadSio1Sym0(shutdown, "SIO1shutdown");
+ LoadSio1Sym0(open, "SIO1open");
+ LoadSio1Sym0(close, "SIO1close");
+ LoadSio1Sym0(pause, "SIO1pause");
+ LoadSio1Sym0(resume, "SIO1resume");
+ LoadSio1Sym0(keypressed, "SIO1keypressed");
+ LoadSio1Sym0(configure, "SIO1configure");
+ LoadSio1Sym0(test, "SIO1test");
+ LoadSio1Sym0(about, "SIO1about");
+ LoadSio1Sym0(writeData8, "SIO1writeData8");
+ LoadSio1Sym0(writeData16, "SIO1writeData16");
+ LoadSio1Sym0(writeData32, "SIO1writeData32");
+ LoadSio1Sym0(writeStat16, "SIO1writeStat16");
+ LoadSio1Sym0(writeStat32, "SIO1writeStat32");
+ LoadSio1Sym0(writeMode16, "SIO1writeMode16");
+ LoadSio1Sym0(writeMode32, "SIO1writeMode32");
+ LoadSio1Sym0(writeCtrl16, "SIO1writeCtrl16");
+ LoadSio1Sym0(writeCtrl32, "SIO1writeCtrl32");
+ LoadSio1Sym0(writeBaud16, "SIO1writeBaud16");
+ LoadSio1Sym0(writeBaud32, "SIO1writeBaud32");
+ LoadSio1Sym0(readData16, "SIO1readData16");
+ LoadSio1Sym0(readData32, "SIO1readData32");
+ LoadSio1Sym0(readStat16, "SIO1readStat16");
+ LoadSio1Sym0(readStat32, "SIO1readStat32");
+ LoadSio1Sym0(readMode16, "SIO1readMode16");
+ LoadSio1Sym0(readMode32, "SIO1readMode32");
+ LoadSio1Sym0(readCtrl16, "SIO1readCtrl16");
+ LoadSio1Sym0(readCtrl32, "SIO1readCtrl32");
+ LoadSio1Sym0(readBaud16, "SIO1readBaud16");
+ LoadSio1Sym0(readBaud32, "SIO1readBaud32");
+ LoadSio1Sym0(registerCallback, "SIO1registerCallback");
+
+ return 0;
+}
+
+#endif
+
+void CALLBACK clearDynarec(void) {
+ psxCpu->Reset();
+}
+
+int LoadPlugins() {
+ int ret;
+ char Plugin[MAXPATHLEN * 2];
+
+ ReleasePlugins();
+ SysLibError();
+
+ if (UsingIso()) {
+ LoadCDRplugin(NULL);
+ } else {
+ sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
+ if (LoadCDRplugin(Plugin) == -1) return -1;
+ }
+
+ sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);
+ if (LoadGPUplugin(Plugin) == -1) return -1;
+
+ sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);
+ if (LoadSPUplugin(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;
+
+ if (strcmp("Disabled", Config.Net) == 0 || strcmp("", Config.Net) == 0)
+ Config.UseNet = FALSE;
+ else {
+ Config.UseNet = TRUE;
+ sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Net);
+ if (LoadNETplugin(Plugin) == -1) Config.UseNet = FALSE;
+ }
+
+#ifdef ENABLE_SIO1API
+ sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Sio1);
+ if (LoadSIO1plugin(Plugin) == -1) return -1;
+#endif
+
+ ret = CDR_init();
+ if (ret < 0) { SysMessage (_("Error initializing CD-ROM plugin: %d"), ret); return -1; }
+ ret = GPU_init();
+ if (ret < 0) { SysMessage (_("Error initializing GPU plugin: %d"), ret); return -1; }
+ ret = SPU_init();
+ if (ret < 0) { SysMessage (_("Error initializing SPU plugin: %d"), ret); return -1; }
+ ret = PAD1_init(1);
+ if (ret < 0) { SysMessage (_("Error initializing Controller 1 plugin: %d"), ret); return -1; }
+ ret = PAD2_init(2);
+ if (ret < 0) { SysMessage (_("Error initializing Controller 2 plugin: %d"), ret); return -1; }
+
+ if (Config.UseNet) {
+ ret = NET_init();
+ if (ret < 0) { SysMessage (_("Error initializing NetPlay plugin: %d"), ret); return -1; }
+ }
+
+#ifdef ENABLE_SIO1API
+ ret = SIO1_init();
+ if (ret < 0) { SysMessage (_("Error initializing SIO1 plugin: %d"), ret); return -1; }
+#endif
+
+ SysPrintf(_("Plugins loaded.\n"));
+ return 0;
+}
+
+void ReleasePlugins() {
+ if (Config.UseNet) {
+ int ret = NET_close();
+ if (ret < 0) Config.UseNet = FALSE;
+ }
+ NetOpened = FALSE;
+
+ if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
+ if (hGPUDriver != NULL) GPU_shutdown();
+ if (hSPUDriver != NULL) SPU_shutdown();
+ if (hPAD1Driver != NULL) PAD1_shutdown();
+ if (hPAD2Driver != NULL) PAD2_shutdown();
+
+ if (Config.UseNet && hNETDriver != NULL) NET_shutdown();
+
+ if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
+ if (hGPUDriver != NULL) { SysCloseLibrary(hGPUDriver); hGPUDriver = NULL; }
+ if (hSPUDriver != NULL) { SysCloseLibrary(hSPUDriver); hSPUDriver = NULL; }
+ if (hPAD1Driver != NULL) { SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL; }
+ if (hPAD2Driver != NULL) { SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL; }
+
+ if (Config.UseNet && hNETDriver != NULL) {
+ SysCloseLibrary(hNETDriver); hNETDriver = NULL;
+ }
+
+#ifdef ENABLE_SIO1API
+ if (hSIO1Driver != NULL) {
+ SIO1_shutdown();
+ SysCloseLibrary(hSIO1Driver);
+ hSIO1Driver = NULL;
+ }
+#endif
+}
+
+// for CD swap
+int ReloadCdromPlugin()
+{
+ if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
+ if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
+
+ if (UsingIso()) {
+ LoadCDRplugin(NULL);
+ } else {
+ char Plugin[MAXPATHLEN * 2];
+ sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
+ if (LoadCDRplugin(Plugin) == -1) return -1;
+ }
+
+ return CDR_init();
+}
+
+void SetIsoFile(const char *filename) {
+ if (filename == NULL) {
+ IsoFile[0] = '\0';
+ return;
+ }
+ strncpy(IsoFile, filename, MAXPATHLEN - 1);
+}
+
+const char *GetIsoFile(void) {
+ return IsoFile;
+}
+
+boolean UsingIso(void) {
+ return (IsoFile[0] != '\0');
+}
+
+void SetCdOpenCaseTime(s64 time) {
+ cdOpenCaseTime = time;
+}
diff --git a/libpcsxcore/ppf.c b/libpcsxcore/ppf.c
index edebdd0..f6ccfca 100644
--- a/libpcsxcore/ppf.c
+++ b/libpcsxcore/ppf.c
@@ -183,7 +183,7 @@ void BuildPPFCache() {
char method, undo = 0, blockcheck = 0;
int dizlen, dizyn;
unsigned char ppfmem[512];
- char szPPF[MAXPATHLEN];
+ char szPPF[MAXPATHLEN * 2];
int count, seekpos, pos;
u32 anz; // use 32-bit to avoid stupid overflows
s32 ladr, off, anx;
diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c
index ecd4264..6016f7e 100644
--- a/libpcsxcore/psxbios.c
+++ b/libpcsxcore/psxbios.c
@@ -1,6 +1,6 @@
/***************************************************************************
* Copyright (C) 2019 Ryan Schultz, PCSX-df Team, PCSX team, gameblabla, *
- * dmitrysmagin, senquack *
+ * dmitrysmagin, senquack *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
@@ -18,7 +18,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
***************************************************************************/
-/* Gameblabla 2018-2019 :
+/* Gameblabla 2018-2019 :
* Numerous changes to bios calls as well as improvements in order to conform to nocash's findings
* for the PSX bios calls. Thanks senquack for helping out with some of the changes
* and helping to spot issues and refine my patches.
@@ -33,6 +33,7 @@
#include "psxbios.h"
#include "psxhw.h"
#include "gpu.h"
+#include "sio.h"
#include <zlib.h>
#undef SysPrintf
@@ -217,7 +218,7 @@ typedef struct {
u32 func;
} TCB;
-typedef struct {
+typedef struct {
u32 _pc0;
u32 gp0;
u32 t_addr;
@@ -255,7 +256,7 @@ static int pad_buf1len, pad_buf2len;
static int pad_stopped = 0;
static u32 regs[35];
-static EvCB *Event;
+static EvCB *EventCB;
static EvCB *HwEV; // 0xf0
static EvCB *EvEV; // 0xf1
static EvCB *RcEV; // 0xf2
@@ -267,10 +268,10 @@ static u32 *heap_addr = NULL;
static u32 *heap_end = NULL;
static u32 SysIntRP[8];
static int CardState = -1;
-static TCB Thread[8];
+static TCB ThreadCB[8];
static int CurThread = 0;
static FileDesc FDesc[32];
-static u32 card_active_chan;
+static u32 card_active_chan = 0;
boolean hleSoftCall = FALSE;
@@ -299,12 +300,12 @@ static inline void softCall2(u32 pc) {
}
static inline void DeliverEvent(u32 ev, u32 spec) {
- if (Event[ev][spec].status != EvStACTIVE) return;
+ if (EventCB[ev][spec].status != EvStACTIVE) return;
-// Event[ev][spec].status = EvStALREADY;
- if (Event[ev][spec].mode == EvMdINTR) {
- softCall2(Event[ev][spec].fhandler);
- } else Event[ev][spec].status = EvStALREADY;
+// EventCB[ev][spec].status = EvStALREADY;
+ if (EventCB[ev][spec].mode == EvMdINTR) {
+ softCall2(EventCB[ev][spec].fhandler);
+ } else EventCB[ev][spec].status = EvStALREADY;
}
static unsigned interrupt_r26=0x8004E8B0;
@@ -696,7 +697,7 @@ void psxBios_index() { // 0x1c
pc0 = ra;
return;
}
-
+
do {
if (*p == a1) {
v0 = a0 + (p - (char *)Ra0);
@@ -925,7 +926,7 @@ void psxBios_memcmp() { // 0x2d
void psxBios_memchr() { // 0x2e
char *p = (char *)Ra0;
-
+
if (a0 == 0 || a2 > 0x7FFFFFFF)
{
pc0 = ra;
@@ -1424,7 +1425,7 @@ void psxBios_GPU_dw() { // 0x46
} while(--size);
pc0 = ra;
-}
+}
void psxBios_mem2vram() { // 0x47
int size;
@@ -1464,8 +1465,8 @@ void psxBios_GPU_cwb() { // 0x4a
pc0 = ra;
}
-
-void psxBios_GPU_SendPackets() { //4b:
+
+void psxBios_GPU_SendPackets() { //4b:
GPU_writeStatus(0x04000002);
psxHwWrite32(0x1f8010f4,0);
psxHwWrite32(0x1f8010f0,psxHwRead32(0x1f8010f0)|0x800);
@@ -1500,7 +1501,7 @@ void psxBios_LoadExec() { // 51
#endif
s_addr = a1; s_size = a2;
- a1 = 0xf000;
+ a1 = 0xf000;
psxBios_Load();
header->S_addr = s_addr;
@@ -1555,7 +1556,7 @@ void psxBios_SetMem() { // 9f
psxHu32ref(0x1060) = SWAP32(new | 0x300);
psxMu32ref(0x060) = a0;
SysPrintf("Change effective memory : %d MBytes\n",a0);
-
+
default:
SysPrintf("Effective memory must be 2/8 MBytes\n");
break;
@@ -1575,16 +1576,16 @@ void psxBios__card_info() { // ab
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s: %x\n", biosA0n[0xab], a0);
#endif
- u32 ret;
+ u32 ret, port;
card_active_chan = a0;
-
- switch (card_active_chan)
- {
- case 0x00: case 0x01: case 0x02: case 0x03:
- ret = Config.Mcd1[0] ? 0x2 : 0x8;
- break;
- case 0x10: case 0x11: case 0x12: case 0x13:
- ret = Config.Mcd2[0] ? 0x2 : 0x8;
+ port = card_active_chan >> 4;
+
+ switch (port) {
+ case 0x0:
+ case 0x1:
+ ret = 0x2;
+ if (McdDisable[port & 1])
+ ret = 0x8;
break;
default:
#ifdef PSXBIOS_LOG
@@ -1593,8 +1594,12 @@ void psxBios__card_info() { // ab
ret = 0x11;
break;
}
-
- DeliverEvent(0x11, 0x2); // 0xf4000001, 0x0004
+
+ if (McdDisable[0] && McdDisable[1])
+ ret = 0x8;
+
+ DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004
+// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004
DeliverEvent(0x81, ret); // 0xf4000001, 0x0004
v0 = 1; pc0 = ra;
}
@@ -1683,14 +1688,14 @@ void psxBios_ResetRCnt() { // 06
}
-/* gets ev for use with Event */
+/* gets ev for use with EventCB */
#define GetEv() \
ev = (a0 >> 24) & 0xf; \
if (ev == 0xf) ev = 0x5; \
ev*= 32; \
ev+= a0&0x1f;
-/* gets spec for use with Event */
+/* gets spec for use with EventCB */
#define GetSpec() \
spec = 0; \
switch (a1) { \
@@ -1728,9 +1733,9 @@ void psxBios_OpenEvent() { // 08
PSXBIOS_LOG("psxBios_%s %x,%x (class:%x, spec:%x, mode:%x, func:%x)\n", biosB0n[0x08], ev, spec, a0, a1, a2, a3);
#endif
- Event[ev][spec].status = EvStWAIT;
- Event[ev][spec].mode = a2;
- Event[ev][spec].fhandler = a3;
+ EventCB[ev][spec].status = EvStWAIT;
+ EventCB[ev][spec].mode = a2;
+ EventCB[ev][spec].fhandler = a3;
v0 = ev | (spec << 8);
pc0 = ra;
@@ -1746,7 +1751,7 @@ void psxBios_CloseEvent() { // 09
PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x09], ev, spec);
#endif
- Event[ev][spec].status = EvStUNUSED;
+ EventCB[ev][spec].status = EvStUNUSED;
v0 = 1; pc0 = ra;
}
@@ -1759,17 +1764,17 @@ void psxBios_WaitEvent() { // 0a
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0a], ev, spec);
#endif
- if (Event[ev][spec].status == EvStUNUSED)
+ if (EventCB[ev][spec].status == EvStUNUSED)
{
v0 = 0;
- pc0 = ra;
+ pc0 = ra;
return;
}
- if (Event[ev][spec].status == EvStALREADY)
+ if (EventCB[ev][spec].status == EvStALREADY)
{
/* Callback events (mode=EvMdINTR) do never set the ready flag (and thus WaitEvent would hang forever). */
- if (!(Event[ev][spec].mode == EvMdINTR)) Event[ev][spec].status = EvStACTIVE;
+ if (!(EventCB[ev][spec].mode == EvMdINTR)) EventCB[ev][spec].status = EvStACTIVE;
v0 = 1;
pc0 = ra;
return;
@@ -1785,12 +1790,12 @@ void psxBios_TestEvent() { // 0b
ev = a0 & 0xff;
spec = (a0 >> 8) & 0xff;
- if (Event[ev][spec].status == EvStALREADY)
+ if (EventCB[ev][spec].status == EvStALREADY)
{
- if (!(Event[ev][spec].mode == EvMdINTR)) Event[ev][spec].status = EvStACTIVE;
+ if (!(EventCB[ev][spec].mode == EvMdINTR)) EventCB[ev][spec].status = EvStACTIVE;
v0 = 1;
- }
- else
+ }
+ else
{
v0 = 0;
}
@@ -1812,7 +1817,7 @@ void psxBios_EnableEvent() { // 0c
PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0c], ev, spec);
#endif
- Event[ev][spec].status = EvStACTIVE;
+ EventCB[ev][spec].status = EvStACTIVE;
v0 = 1; pc0 = ra;
}
@@ -1827,7 +1832,7 @@ void psxBios_DisableEvent() { // 0d
PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0d], ev, spec);
#endif
- Event[ev][spec].status = EvStWAIT;
+ EventCB[ev][spec].status = EvStWAIT;
v0 = 1; pc0 = ra;
}
@@ -1841,7 +1846,7 @@ void psxBios_OpenTh() { // 0e
for (th=1; th<8; th++)
{
- if (Thread[th].status == 0) break;
+ if (ThreadCB[th].status == 0) break;
}
if (th == 8) {
@@ -1858,10 +1863,10 @@ void psxBios_OpenTh() { // 0e
PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x0e], th);
#endif
- Thread[th].status = 1;
- Thread[th].func = a0;
- Thread[th].reg[29] = a1;
- Thread[th].reg[28] = a2;
+ ThreadCB[th].status = 1;
+ ThreadCB[th].func = a0;
+ ThreadCB[th].reg[29] = a1;
+ ThreadCB[th].reg[28] = a2;
v0 = th; pc0 = ra;
}
@@ -1878,8 +1883,8 @@ void psxBios_CloseTh() { // 0f
#endif
/* The return value is always 1 (even if the handle was already closed). */
v0 = 1;
- if (Thread[th].status != 0) {
- Thread[th].status = 0;
+ if (ThreadCB[th].status != 0) {
+ ThreadCB[th].status = 0;
}
pc0 = ra;
@@ -1897,18 +1902,18 @@ void psxBios_ChangeTh() { // 10
#endif
/* The return value is always 1. */
v0 = 1;
- if (Thread[th].status == 0 || CurThread == th) {
+ if (ThreadCB[th].status == 0 || CurThread == th) {
pc0 = ra;
} else {
- if (Thread[CurThread].status == 2) {
- Thread[CurThread].status = 1;
- Thread[CurThread].func = ra;
- memcpy(Thread[CurThread].reg, psxRegs.GPR.r, 32*4);
+ if (ThreadCB[CurThread].status == 2) {
+ ThreadCB[CurThread].status = 1;
+ ThreadCB[CurThread].func = ra;
+ memcpy(ThreadCB[CurThread].reg, psxRegs.GPR.r, 32*4);
}
- memcpy(psxRegs.GPR.r, Thread[th].reg, 32*4);
- pc0 = Thread[th].func;
- Thread[th].status = 2;
+ memcpy(psxRegs.GPR.r, ThreadCB[th].reg, 32*4);
+ pc0 = ThreadCB[th].func;
+ ThreadCB[th].status = 2;
CurThread = th;
}
}
@@ -2012,26 +2017,27 @@ void psxBios_UnDeliverEvent() { // 0x20
PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x20], ev, spec);
#endif
- if (Event[ev][spec].status == EvStALREADY &&
- Event[ev][spec].mode == EvMdNOINTR)
- Event[ev][spec].status = EvStACTIVE;
+ if (EventCB[ev][spec].status == EvStALREADY &&
+ EventCB[ev][spec].mode == EvMdNOINTR)
+ EventCB[ev][spec].status = EvStACTIVE;
pc0 = ra;
}
char ffile[64], *pfile;
int nfile;
-static void buopen(int mcd, u8 *ptr, u8 *cfg)
+
+static void buopen(int mcd, char *ptr, char *cfg)
{
int i;
- u8 *fptr = ptr;
+ char *mcd_data = ptr;
strcpy(FDesc[1 + mcd].name, Ra0+5);
FDesc[1 + mcd].offset = 0;
FDesc[1 + mcd].mode = a1;
for (i=1; i<16; i++) {
- fptr += 128;
+ const char *fptr = mcd_data + 128 * i;
if ((*fptr & 0xF0) != 0x50) continue;
if (strcmp(FDesc[1 + mcd].name, fptr+0xa)) continue;
FDesc[1 + mcd].mcfile = i;
@@ -2040,12 +2046,11 @@ static void buopen(int mcd, u8 *ptr, u8 *cfg)
break;
}
if (a1 & 0x200 && v0 == -1) { /* FCREAT */
- fptr = ptr;
for (i=1; i<16; i++) {
int j, xor, nblk = a1 >> 16;
- u8 *pptr, *fptr2;
+ char *pptr, *fptr2;
+ char *fptr = mcd_data + 128 * i;
- fptr += 128;
if ((*fptr & 0xF0) != 0xa0) continue;
FDesc[1 + mcd].mcfile = i;
@@ -2060,7 +2065,7 @@ static void buopen(int mcd, u8 *ptr, u8 *cfg)
int k;
for(i++; i<16; i++) {
fptr2 += 128;
-
+
memset(fptr2, 0, 128);
fptr2[0] = j < nblk ? 0x52 : 0x53;
pptr[8] = i - 1;
@@ -2090,8 +2095,6 @@ static void buopen(int mcd, u8 *ptr, u8 *cfg)
*/
void psxBios_open() { // 0x32
- int i;
- char *ptr;
void *pa0 = Ra0;
#ifdef PSXBIOS_LOG
@@ -2160,7 +2163,7 @@ void psxBios_read() { // 0x34
case 3: buread(pa1, 2, a2); break;
}
}
-
+
pc0 = ra;
}
@@ -2226,7 +2229,7 @@ void psxBios_puts() { // 3e/3f
/* To avoid any issues with different behaviour when using the libc's own strlen instead.
* We want to mimic the PSX's behaviour in this case for bufile. */
-static size_t strlen_internal(char* p)
+static size_t strlen_internal(char* p)
{
size_t size_of_array = 0;
while (*p++) size_of_array++;
@@ -2267,7 +2270,7 @@ static size_t strlen_internal(char* p)
/*
* struct DIRENTRY* firstfile(char *name,struct DIRENTRY *dir);
*/
-
+
void psxBios_firstfile() { // 42
struct DIRENTRY *dir = (struct DIRENTRY *)Ra1;
void *pa0 = Ra0;
@@ -2524,7 +2527,7 @@ void psxBios__new_card() { // 0x50
/* According to a user, this allows Final Fantasy Tactics to save/load properly */
void psxBios__get_error(void) // 55
-{
+{
v0 = 0;
pc0 = ra;
}
@@ -2600,7 +2603,7 @@ void psxBios__card_chan() { // 0x58
void psxBios_ChangeClearPad() { // 5b
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x5b], a0);
-#endif
+#endif
pc0 = ra;
}
@@ -2668,11 +2671,11 @@ void psxBios_ChangeClearRCnt() { // 0a
pc0 = ra;
}
-void psxBios_dummy() {
+void psxBios_dummy() {
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("unk %x call: %x\n", pc0 & 0x1fffff, t1);
#endif
- pc0 = ra;
+ pc0 = ra;
}
void (*biosA0[256])();
@@ -2683,7 +2686,7 @@ void (*biosC0[256])();
void psxBiosInit() {
u32 base, size;
- u32 *ptr;
+ u32 *ptr;
int i;
uLongf len;
@@ -2766,7 +2769,7 @@ void psxBiosInit() {
biosA0[0x39] = psxBios_InitHeap;
//biosA0[0x3a] = psxBios__exit;
biosA0[0x3b] = psxBios_getchar;
- biosA0[0x3c] = psxBios_putchar;
+ biosA0[0x3c] = psxBios_putchar;
//biosA0[0x3d] = psxBios_gets;
//biosA0[0x40] = psxBios_sys_a0_40;
//biosA0[0x41] = psxBios_LoadTest;
@@ -2782,7 +2785,7 @@ void psxBiosInit() {
biosA0[0x4b] = psxBios_GPU_SendPackets;
biosA0[0x4c] = psxBios_sys_a0_4c;
biosA0[0x4d] = psxBios_GPU_GetGPUStatus;
- //biosA0[0x4e] = psxBios_GPU_sync;
+ //biosA0[0x4e] = psxBios_GPU_sync;
//biosA0[0x4f] = psxBios_sys_a0_4f;
//biosA0[0x50] = psxBios_sys_a0_50;
biosA0[0x51] = psxBios_LoadExec;
@@ -2834,10 +2837,10 @@ void psxBiosInit() {
//biosA0[0x7f] = psxBios_sys_a0_7f;
//biosA0[0x80] = psxBios_sys_a0_80;
//biosA0[0x81] = psxBios_sys_a0_81;
- //biosA0[0x82] = psxBios_sys_a0_82;
+ //biosA0[0x82] = psxBios_sys_a0_82;
//biosA0[0x83] = psxBios_sys_a0_83;
//biosA0[0x84] = psxBios_sys_a0_84;
- //biosA0[0x85] = psxBios__96_CdStop;
+ //biosA0[0x85] = psxBios__96_CdStop;
//biosA0[0x86] = psxBios_sys_a0_86;
//biosA0[0x87] = psxBios_sys_a0_87;
//biosA0[0x88] = psxBios_sys_a0_88;
@@ -2989,7 +2992,7 @@ void psxBiosInit() {
//biosC0[0x07] = psxBios_InstallExeptionHandler;
//biosC0[0x08] = psxBios_SysInitMemory;
//biosC0[0x09] = psxBios_SysInitKMem;
- biosC0[0x0a] = psxBios_ChangeClearRCnt;
+ biosC0[0x0a] = psxBios_ChangeClearRCnt;
//biosC0[0x0b] = psxBios_SystemError;
//biosC0[0x0c] = psxBios_InitDefInt;
//biosC0[0x0d] = psxBios_sys_c0_0d;
@@ -3012,14 +3015,14 @@ void psxBiosInit() {
/**/
base = 0x1000;
size = sizeof(EvCB) * 32;
- Event = (void *)&psxR[base]; base += size * 6;
- memset(Event, 0, size * 6);
- HwEV = Event;
- EvEV = Event + 32;
- RcEV = Event + 32 * 2;
- UeEV = Event + 32 * 3;
- SwEV = Event + 32 * 4;
- ThEV = Event + 32 * 5;
+ EventCB = (void *)&psxR[base]; base += size * 6;
+ memset(EventCB, 0, size * 6);
+ HwEV = EventCB;
+ EvEV = EventCB + 32;
+ RcEV = EventCB + 32 * 2;
+ UeEV = EventCB + 32 * 3;
+ SwEV = EventCB + 32 * 4;
+ ThEV = EventCB + 32 * 5;
ptr = (u32 *)&psxM[0x0874]; // b0 table
ptr[0] = SWAPu32(0x4c54 - 0x884);
@@ -3028,8 +3031,8 @@ void psxBiosInit() {
ptr[6] = SWAPu32(0xc80);
memset(SysIntRP, 0, sizeof(SysIntRP));
- memset(Thread, 0, sizeof(Thread));
- Thread[0].status = 2; // main thread
+ memset(ThreadCB, 0, sizeof(ThreadCB));
+ ThreadCB[0].status = 2; // main thread
pad_stopped = 1;
jmp_int = NULL;
@@ -3057,7 +3060,7 @@ void psxBiosInit() {
*/
// opcode HLE
psxRu32ref(0x0000) = SWAPu32((0x3b << 26) | 4);
- /* Whatever this does, it actually breaks CTR, even without the uninitiliazed memory patch.
+ /* Whatever this does, it actually breaks CTR, even without the uninitiliazed memory patch.
Normally games shouldn't read from address 0 yet they do. See explanation below in details. */
//psxMu32ref(0x0000) = SWAPu32((0x3b << 26) | 0);
psxMu32ref(0x00a0) = SWAPu32((0x3b << 26) | 1);
@@ -3085,14 +3088,14 @@ void psxBiosInit() {
psxHu32ref(0x1060) = SWAPu32(0x00000b88);
hleSoftCall = FALSE;
-
+
/* Some games like R-Types, CTR, Fade to Black read from adress 0x00000000 due to uninitialized pointers.
See Garbage Area at Address 00000000h in Nocash PSX Specfications for more information.
Here are some examples of games not working with this fix in place :
R-type won't get past the Irem logo if not implemented.
Crash Team Racing will softlock after the Sony logo.
*/
-
+
psxMu32ref(0x0000) = SWAPu32(0x00000003);
/*
But overwritten by 00000003h after soon.
@@ -3273,7 +3276,7 @@ void psxBiosException() {
break;
case 2: // ExitCritical - enable irq's
- psxRegs.CP0.n.Status |= 0x404;
+ psxRegs.CP0.n.Status |= 0x404;
break;
/* Normally this should cover SYS(00h, SYS(04h but they don't do anything relevant so... */
default:
@@ -3332,7 +3335,7 @@ void psxBiosFreeze(int Mode) {
bfreezes(regs);
bfreezes(SysIntRP);
bfreezel(&CardState);
- bfreezes(Thread);
+ bfreezes(ThreadCB);
bfreezel(&CurThread);
bfreezes(FDesc);
bfreezel(&card_active_chan);
diff --git a/libpcsxcore/psxcommon.h b/libpcsxcore/psxcommon.h
index 9f5444e..cb417d4 100644
--- a/libpcsxcore/psxcommon.h
+++ b/libpcsxcore/psxcommon.h
@@ -40,7 +40,9 @@ extern "C" {
#include <math.h>
#include <time.h>
#include <ctype.h>
+#ifndef __SWITCH__
#include <sys/types.h>
+#endif
#include <assert.h>
// Define types
@@ -118,7 +120,9 @@ typedef struct {
boolean Mdec;
boolean PsxAuto;
boolean Cdda;
+ boolean AsyncCD;
boolean HLE;
+ boolean SlowBoot;
boolean Debug;
boolean PsxOut;
boolean SpuIrq;
diff --git a/libpcsxcore/psxcounters.c b/libpcsxcore/psxcounters.c
index 35823da..bebec87 100644
--- a/libpcsxcore/psxcounters.c
+++ b/libpcsxcore/psxcounters.c
@@ -64,7 +64,9 @@ static const u32 HSyncTotal[] = { 263, 313 };
#define VBlankStart 240
#define VERBOSE_LEVEL 0
+#if VERBOSE_LEVEL > 0
static const s32 VerboseLevel = VERBOSE_LEVEL;
+#endif
/******************************************************************************/
diff --git a/libpcsxcore/psxhle.c b/libpcsxcore/psxhle.c
index 83362ec..7507192 100644
--- a/libpcsxcore/psxhle.c
+++ b/libpcsxcore/psxhle.c
@@ -23,6 +23,12 @@
#include "psxhle.h"
+#if 0
+#define PSXHLE_LOG SysPrintf
+#else
+#define PSXHLE_LOG(...)
+#endif
+
static void hleDummy() {
psxRegs.pc = psxRegs.GPR.n.ra;
@@ -54,10 +60,10 @@ static void hleC0() {
}
static void hleBootstrap() { // 0xbfc00000
- SysPrintf("hleBootstrap\n");
+ PSXHLE_LOG("hleBootstrap\n");
CheckCdrom();
LoadCdrom();
- SysPrintf("CdromLabel: \"%s\": PC = %8.8lx (SP = %8.8lx)\n", CdromLabel, psxRegs.pc, psxRegs.GPR.n.sp);
+ PSXHLE_LOG("CdromLabel: \"%s\": PC = %8.8lx (SP = %8.8lx)\n", CdromLabel, psxRegs.pc, psxRegs.GPR.n.sp);
}
typedef struct {
@@ -77,7 +83,7 @@ typedef struct {
static void hleExecRet() {
EXEC *header = (EXEC*)PSXM(psxRegs.GPR.n.s0);
- SysPrintf("ExecRet %x: %x\n", psxRegs.GPR.n.s0, header->ret);
+ PSXHLE_LOG("ExecRet %x: %x\n", psxRegs.GPR.n.s0, header->ret);
psxRegs.GPR.n.ra = header->ret;
psxRegs.GPR.n.sp = header->_sp;
diff --git a/libpcsxcore/psxmem.c b/libpcsxcore/psxmem.c
index a1a641d..11a01ad 100644
--- a/libpcsxcore/psxmem.c
+++ b/libpcsxcore/psxmem.c
@@ -42,7 +42,16 @@ void (*psxUnmapHook)(void *ptr, size_t size, enum psxMapTag tag);
void *psxMap(unsigned long addr, size_t size, int is_fixed,
enum psxMapTag tag)
{
+#ifdef LIGHTREC
+#ifdef MAP_FIXED_NOREPLACE
+ int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE;
+#else
+ int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED;
+#endif
+#else
int flags = MAP_PRIVATE | MAP_ANONYMOUS;
+#endif
+
int try_ = 0;
unsigned long mask;
void *req, *ret;
@@ -135,7 +144,14 @@ int psxMemInit() {
memset(psxMemRLUT, 0, 0x10000 * sizeof(void *));
memset(psxMemWLUT, 0, 0x10000 * sizeof(void *));
+#ifdef LIGHTREC
+ psxM = psxMap(0x30000000, 0x00210000, 1, MAP_TAG_RAM);
+ if (psxM == NULL)
+ psxM = psxMap(0x70000000, 0x00210000, 1, MAP_TAG_RAM);
+
+#else
psxM = psxMap(0x80000000, 0x00210000, 1, MAP_TAG_RAM);
+#endif
#ifndef RAM_FIXED
if (psxM == NULL)
psxM = psxMap(0x77000000, 0x00210000, 0, MAP_TAG_RAM);
@@ -146,8 +162,18 @@ int psxMemInit() {
}
psxP = &psxM[0x200000];
+#ifdef LIGHTREC
+ psxH = psxMap(0x4f800000, 0x10000, 0, MAP_TAG_OTHER);
+ if (psxH == NULL)
+ psxH = psxMap(0x8f800000, 0x10000, 0, MAP_TAG_OTHER);
+
+ psxR = psxMap(0x4fc00000, 0x80000, 0, MAP_TAG_OTHER);
+ if (psxR == NULL)
+ psxR = psxMap(0x8fc00000, 0x80000, 0, MAP_TAG_OTHER);
+#else
psxH = psxMap(0x1f800000, 0x10000, 0, MAP_TAG_OTHER);
psxR = psxMap(0x1fc00000, 0x80000, 0, MAP_TAG_OTHER);
+#endif
if (psxMemRLUT == NULL || psxMemWLUT == NULL ||
psxR == NULL || psxP == NULL || psxH == NULL) {
diff --git a/libpcsxcore/psxmem.h b/libpcsxcore/psxmem.h
index d9fee00..36b4693 100644
--- a/libpcsxcore/psxmem.h
+++ b/libpcsxcore/psxmem.h
@@ -122,9 +122,11 @@ extern u8 **psxMemRLUT;
#define PSXMu32ref(mem) (*(u32 *)PSXM(mem))
-#if !defined(PSXREC) && (defined(__x86_64__) || defined(__i386__) || defined(__ppc__)) && !defined(NOPSXREC)
+#ifndef PSXREC
+#if defined(NEW_DYNAREC) || defined(LIGHTREC)
#define PSXREC
#endif
+#endif
int psxMemInit();
void psxMemReset();
diff --git a/libpcsxcore/r3000a.c b/libpcsxcore/r3000a.c
index 82eb885..1118107 100644
--- a/libpcsxcore/r3000a.c
+++ b/libpcsxcore/r3000a.c
@@ -30,9 +30,9 @@ R3000Acpu *psxCpu = NULL;
psxRegisters psxRegs;
int psxInit() {
- SysPrintf(_("Running PCSX Version %s (%s).\n"), PACKAGE_VERSION, __DATE__);
+ SysPrintf(_("Running PCSX Version %s (%s).\n"), PCSX_VERSION, __DATE__);
-#ifdef PSXREC
+#if defined(NEW_DYNAREC) || defined(LIGHTREC)
if (Config.Cpu == CPU_INTERPRETER) {
psxCpu = &psxInt;
} else psxCpu = &psxRec;
@@ -50,7 +50,7 @@ int psxInit() {
void psxReset() {
psxMemReset();
- memset(&psxRegs, 0, sizeof(psxRegs));
+ memset(&psxRegs, 0x00, sizeof(psxRegs));
psxRegs.pc = 0xbfc00000; // Start in bootstrap
diff --git a/libpcsxcore/sio.c b/libpcsxcore/sio.c
index b3732d2..c2390bf 100644
--- a/libpcsxcore/sio.c
+++ b/libpcsxcore/sio.c
@@ -117,6 +117,20 @@ void sioWrite8(unsigned char value) {
break;
}
}
+ // NegCon - Wipeout 3
+ if( buf[parp] == 0x23 ) {
+ switch (value) {
+ // enter config mode
+ case 0x43:
+ buf[1] = 0x79;
+ break;
+
+ // get status
+ case 0x45:
+ buf[1] = 0xf3;
+ break;
+ }
+ }
}
else padst = 0;
return;
@@ -409,6 +423,12 @@ void LoadMcd(int mcd, char *str) {
}
McdDisable[mcd - 1] = 0;
+#ifdef HAVE_LIBRETRO
+ // memcard1 is handled by libretro
+ if (mcd == 1)
+ return;
+#endif
+
if (str == NULL || strcmp(str, "none") == 0) {
McdDisable[mcd - 1] = 1;
return;
diff --git a/libpcsxcore/sio.h b/libpcsxcore/sio.h
index eff1746..a554c2b 100644
--- a/libpcsxcore/sio.h
+++ b/libpcsxcore/sio.h
@@ -34,6 +34,7 @@ extern "C" {
#define MCD_SIZE (1024 * 8 * 16)
extern char Mcd1Data[MCD_SIZE], Mcd2Data[MCD_SIZE];
+extern char McdDisable[2];
void sioWrite8(unsigned char value);
void sioWriteStat16(unsigned short value);
diff --git a/libpcsxcore/socket.c b/libpcsxcore/socket.c
index 31f82e2..df768e6 100644
--- a/libpcsxcore/socket.c
+++ b/libpcsxcore/socket.c
@@ -15,6 +15,22 @@
* along with this program; if not, see <http://www.gnu.org/licenses>.
*/
+#ifdef NO_SOCKET
+
+int StartServer() { return 0;}
+void StopServer() {}
+void GetClient() {}
+void CloseClient() {}
+int HasClient() { return 0;}
+int ReadSocket(char * buffer, int len) { return 0;}
+int RawReadSocket(char * buffer, int len) { return 0;}
+void WriteSocket(char * buffer, int len) {}
+
+void SetsBlock() {}
+void SetsNonblock() {}
+
+#else // NO_SOCKET
+
#ifdef _WIN32
#include <winsock2.h>
#endif
@@ -119,7 +135,7 @@ void GetClient() {
}
#endif
- sprintf(hello, "000 PCSX Version %s - Debug console\r\n", PACKAGE_VERSION);
+ sprintf(hello, "000 PCSX Version %s - Debug console\r\n", PCSX_VERSION);
WriteSocket(hello, strlen(hello));
ptr = 0;
}
@@ -252,3 +268,4 @@ void SetsNonblock() {
fcntl(server_socket, F_SETFL, flags | O_NONBLOCK);
#endif
}
+#endif // NO_SOCKET
diff --git a/libpcsxcore/system.h b/libpcsxcore/system.h
index c869fdf..cd1814c 100644
--- a/libpcsxcore/system.h
+++ b/libpcsxcore/system.h
@@ -35,6 +35,7 @@ void SysCloseLibrary(void *lib); // Closes Library
void SysUpdate(); // Called on VBlank (to update i.e. pads)
void SysRunGui(); // Returns to the Gui
void SysClose(); // Close mem and plugins
+void SysDLog(const char *fmt, ...); // Prints debug-level logs
#ifdef __cplusplus
}