aboutsummaryrefslogtreecommitdiff
path: root/libpcsxcore
diff options
context:
space:
mode:
Diffstat (limited to 'libpcsxcore')
-rw-r--r--libpcsxcore/cdriso.c43
-rw-r--r--libpcsxcore/cdrom.c170
-rw-r--r--libpcsxcore/cdrom.h4
-rw-r--r--libpcsxcore/coff.h6
-rw-r--r--libpcsxcore/gte.c9
-rw-r--r--libpcsxcore/mdec.c25
-rw-r--r--libpcsxcore/misc.c51
-rw-r--r--libpcsxcore/new_dynarec/emu_if.c8
-rw-r--r--libpcsxcore/psxcounters.c107
-rw-r--r--libpcsxcore/psxmem.c15
-rw-r--r--libpcsxcore/r3000a.h14
11 files changed, 271 insertions, 181 deletions
diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c
index 0089cfe..c9d94f2 100644
--- a/libpcsxcore/cdriso.c
+++ b/libpcsxcore/cdriso.c
@@ -59,8 +59,11 @@ static pthread_t threadid;
static unsigned int initial_offset = 0;
static boolean playing = FALSE;
static boolean cddaBigEndian = FALSE;
+// offsets of cddaHandle file
static unsigned int cdda_cur_sector;
-static unsigned int cdda_start_sector;
+static unsigned int cdda_first_sector;
+// toc_sector - file_sector
+static unsigned int cdda_toc_delta;
/* Frame offset into CD image where pregap data would be found if it was there.
* If a game seeks there we must *not* return subchannel data since it's
* not in the CD image, so that cdrom code can fake subchannel data instead.
@@ -181,17 +184,13 @@ static void *playthread(void *param)
if (d < CD_FRAMESIZE_RAW)
break;
+ if (cdda_cur_sector < cdda_first_sector)
+ memset(sndbuffer + s, 0, CD_FRAMESIZE_RAW);
+
s += d;
cdda_cur_sector++;
}
- if (subHandle != NULL) {
- fseek(subHandle, cdda_cur_sector * SUB_FRAMESIZE, SEEK_SET);
- fread(subbuffer, 1, SUB_FRAMESIZE, subHandle);
-
- if (subChanRaw) DecodeRawSubData();
- }
-
if (s == 0) {
playing = FALSE;
initial_offset = 0;
@@ -1230,7 +1229,7 @@ static long CALLBACK ISOopen(void) {
if (numtracks > 1 && ti[1].handle == NULL) {
ti[1].handle = fopen(GetIsoFile(), "rb");
}
- cdda_cur_sector = cdda_start_sector = 0;
+ cdda_cur_sector = cdda_toc_delta = 0;
return 0;
}
@@ -1377,19 +1376,22 @@ static long CALLBACK ISOreadTrack(unsigned char *time) {
// sector: byte 0 - minute; byte 1 - second; byte 2 - frame
// does NOT uses bcd format
static long CALLBACK ISOplay(unsigned char *time) {
- unsigned int i, abs_sect;
- int file_sect;
+ unsigned int i, abs_sect, start_sect = 0;
+ int track_offset, file_sect;
if (numtracks <= 1)
return 0;
// find the track
abs_sect = msf2sec((char *)time);
- for (i = numtracks; i > 1; i--)
- if (msf2sec(ti[i].start) <= abs_sect + 2 * 75)
+ for (i = numtracks; i > 1; i--) {
+ start_sect = msf2sec(ti[i].start);
+ if (start_sect <= abs_sect + 2 * 75)
break;
+ }
- file_sect = ti[i].start_offset + (abs_sect - msf2sec(ti[i].start));
+ track_offset = abs_sect - start_sect;
+ file_sect = ti[i].start_offset + track_offset;
if (file_sect < 0)
file_sect = 0;
@@ -1398,13 +1400,12 @@ static long CALLBACK ISOplay(unsigned char *time) {
if (ti[i].handle != NULL)
break;
- cdda_start_sector = abs_sect - file_sect;
- cddaHandle = ti[i].handle;
+ cdda_first_sector = 0;
+ if (i == 1)
+ cdda_first_sector = file_sect - track_offset;
- if (pregapOffset && (unsigned int)(pregapOffset - file_sect) < 2 * 75) {
- // get out of the missing pregap to avoid noise
- file_sect = pregapOffset;
- }
+ cdda_toc_delta = abs_sect - file_sect;
+ cddaHandle = ti[i].handle;
if (SPU_playCDDAchannel != NULL) {
startCDDA(file_sect);
@@ -1440,7 +1441,7 @@ static long CALLBACK ISOgetStatus(struct CdrStat *stat) {
stat->Type = 0x01;
}
- sec = cdda_start_sector + cdda_cur_sector;
+ sec = cdda_cur_sector + cdda_toc_delta;
sec2msf(sec, (char *)stat->Time);
return 0;
diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c
index 297c8ae..60f03e7 100644
--- a/libpcsxcore/cdrom.c
+++ b/libpcsxcore/cdrom.c
@@ -26,6 +26,7 @@
#include "psxdma.h"
cdrStruct cdr;
+static unsigned char *pTransfer;
/* CD-ROM magic numbers */
#define CdlSync 0
@@ -119,13 +120,20 @@ unsigned char Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 };
// so (PSXCLK / 75) = cdr read time (linuzappz)
#define cdReadTime (PSXCLK / 75)
+// for cdr.Seeked
+enum seeked_state {
+ SEEK_PENDING = 0,
+ SEEK_DONE = 1,
+ SEEK_DOING_CMD = 2,
+};
+
static struct CdrStat stat;
-static unsigned int msf2sec(char *msf) {
+static unsigned int msf2sec(u8 *msf) {
return ((msf[0] * 60 + msf[1]) * 75) + msf[2];
}
-static void sec2msf(unsigned int s, char *msf) {
+static void sec2msf(unsigned int s, u8 *msf) {
msf[0] = s / 75 / 60;
s = s - msf[0] * 75 * 60;
msf[1] = s / 75;
@@ -133,7 +141,7 @@ static void sec2msf(unsigned int s, char *msf) {
msf[2] = s;
}
-
+// cdrInterrupt
#define CDR_INT(eCycle) { \
psxRegs.interrupt |= (1 << PSXINT_CDR); \
psxRegs.intCycle[PSXINT_CDR].cycle = eCycle; \
@@ -141,6 +149,7 @@ static void sec2msf(unsigned int s, char *msf) {
new_dyna_set_event(PSXINT_CDR, eCycle); \
}
+// cdrReadInterrupt
#define CDREAD_INT(eCycle) { \
psxRegs.interrupt |= (1 << PSXINT_CDREAD); \
psxRegs.intCycle[PSXINT_CDREAD].cycle = eCycle; \
@@ -148,6 +157,7 @@ static void sec2msf(unsigned int s, char *msf) {
new_dyna_set_event(PSXINT_CDREAD, eCycle); \
}
+// cdrLidSeekInterrupt
#define CDRLID_INT(eCycle) { \
psxRegs.interrupt |= (1 << PSXINT_CDRLID); \
psxRegs.intCycle[PSXINT_CDRLID].cycle = eCycle; \
@@ -155,7 +165,8 @@ static void sec2msf(unsigned int s, char *msf) {
new_dyna_set_event(PSXINT_CDRLID, eCycle); \
}
-#define CDRPLAY_INT(eCycle) { \
+// cdrPlayInterrupt
+#define CDRMISC_INT(eCycle) { \
psxRegs.interrupt |= (1 << PSXINT_CDRPLAY); \
psxRegs.intCycle[PSXINT_CDRPLAY].cycle = eCycle; \
psxRegs.intCycle[PSXINT_CDRPLAY].sCycle = psxRegs.cycle; \
@@ -251,7 +262,6 @@ void cdrLidSeekInterrupt()
}
}
-
static void Check_Shell( int Irq )
{
// check case open/close
@@ -410,12 +420,13 @@ static void ReadTrack( u8 *time ) {
}
-void AddIrqQueue(unsigned char irq, unsigned long ecycle) {
+static void AddIrqQueue(unsigned char irq, unsigned long ecycle) {
+ //if (cdr.Irq != 0 && cdr.Irq != 0xff)
+ // printf("cdr: override cmd %02x -> %02x\n", cdr.Irq, irq);
+
cdr.Irq = irq;
cdr.eCycle = ecycle;
- // Doom: Force rescheduling
- // - Fixes boot
CDR_INT(ecycle);
}
@@ -541,6 +552,9 @@ static void cdrPlayInterrupt_Autopause()
struct SubQ *subq = (struct SubQ *)CDR_getBufferSub();
int track_changed = 0;
if (subq != NULL ) {
+ // update subq
+ ReadTrack( cdr.SetSectorPlay );
+
#ifdef CDR_LOG
CDR_LOG( "CDDA SUB - %X:%X:%X\n",
subq->AbsoluteAddress[0], subq->AbsoluteAddress[1], subq->AbsoluteAddress[2] );
@@ -553,7 +567,9 @@ static void cdrPlayInterrupt_Autopause()
Tomb Raider 1 ($7)
*/
- if( cdr.CurTrack < btoi( subq->TrackNumber ) )
+ // .. + 1 is probably wrong, but deals with corrupted subq + good checksum
+ // (how does real thing handle those?)
+ if( cdr.CurTrack + 1 == btoi( subq->TrackNumber ) )
track_changed = 1;
} else {
Create_Fake_Subq();
@@ -582,13 +598,14 @@ static void cdrPlayInterrupt_Autopause()
StopCdda();
}
- if (cdr.Mode & MODE_REPORT) {
+ else if (cdr.Mode & MODE_REPORT) {
if (subq != NULL) {
#ifdef CDR_LOG
CDR_LOG( "REPPLAY SUB - %X:%X:%X\n",
subq->AbsoluteAddress[0], subq->AbsoluteAddress[1], subq->AbsoluteAddress[2] );
#endif
- cdr.CurTrack = btoi( subq->TrackNumber );
+ // breaks when .sub doesn't have index 0 for some reason (bad rip?)
+ //cdr.CurTrack = btoi( subq->TrackNumber );
if (subq->AbsoluteAddress[2] & 0xf)
return;
@@ -629,15 +646,40 @@ static void cdrPlayInterrupt_Autopause()
}
}
+// also handles seek
void cdrPlayInterrupt()
{
- if( !cdr.Play ) return;
+ if (cdr.Seeked == SEEK_DOING_CMD) {
+ SetResultSize(1);
+ cdr.StatP |= STATUS_ROTATING;
+ cdr.StatP &= ~STATUS_SEEK;
+ cdr.Result[0] = cdr.StatP;
+ if (cdr.Irq == 0 || cdr.Irq == 0xff) {
+ cdr.Stat = Complete;
+ if (cdr.Stat != NoIntr)
+ psxHu32ref(0x1070) |= SWAP32(0x4);
+ }
+
+ cdr.Seeked = SEEK_PENDING;
+ CDRMISC_INT(cdReadTime * 20); // ???
+ return;
+ }
+ else if (cdr.Seeked == SEEK_PENDING) {
+ cdr.Seeked = SEEK_DONE;
+ if (!cdr.Play && !cdr.Reading) {
+ memcpy(cdr.SetSectorPlay, cdr.SetSector, 4);
+ Find_CurTrack();
+ ReadTrack(cdr.SetSector);
+ }
+ }
+
+ if (!cdr.Play) return;
#ifdef CDR_LOG
CDR_LOG( "CDDA - %d:%d:%d\n",
cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2] );
#endif
- CDRPLAY_INT( cdReadTime );
+ CDRMISC_INT( cdReadTime );
if (!cdr.Irq && !cdr.Stat && (cdr.Mode & MODE_CDDA) && (cdr.Mode & (MODE_AUTOPAUSE|MODE_REPORT)))
cdrPlayInterrupt_Autopause();
@@ -696,9 +738,10 @@ void cdrInterrupt() {
case CdlPlay:
fake_subq_change = 0;
- if( cdr.Seeked == FALSE ) {
+ if (cdr.Seeked == SEEK_PENDING) {
+ // XXX: wrong, should seek instead..
memcpy( cdr.SetSectorPlay, cdr.SetSector, 4 );
- cdr.Seeked = TRUE;
+ cdr.Seeked = SEEK_DONE;
}
/*
@@ -779,7 +822,7 @@ void cdrInterrupt() {
cdr.SetSectorPlay[2] = cdr.ResultTD[0];
// reset data
- Set_Track();
+ //Set_Track();
Find_CurTrack();
ReadTrack( cdr.SetSectorPlay );
@@ -807,7 +850,7 @@ void cdrInterrupt() {
// BIOS player - set flag again
cdr.Play = TRUE;
- CDRPLAY_INT( cdReadTime );
+ CDRMISC_INT( cdReadTime );
break;
case CdlForward:
@@ -958,6 +1001,10 @@ void cdrInterrupt() {
subq = (struct SubQ *)CDR_getBufferSub();
if (subq != NULL) {
+ if( cdr.Play && (cdr.Mode & MODE_CDDA) && !(cdr.Mode & (MODE_AUTOPAUSE|MODE_REPORT)) )
+ // update subq
+ ReadTrack( cdr.SetSectorPlay );
+
cdr.Result[0] = subq->TrackNumber;
cdr.Result[1] = subq->IndexNumber;
memcpy(cdr.Result + 2, subq->TrackRelativeAddress, 3);
@@ -1036,6 +1083,7 @@ void cdrInterrupt() {
break;
case CdlSeekL:
+ case CdlSeekP:
SetResultSize(1);
cdr.StatP |= STATUS_ROTATING;
cdr.Result[0] = cdr.StatP;
@@ -1055,45 +1103,8 @@ void cdrInterrupt() {
Rockman X5 = 0.5-4x
- fix capcom logo
*/
- AddIrqQueue(CdlSeekL + 0x20, cdReadTime * 4);
- break;
-
- case CdlSeekL + 0x20:
- SetResultSize(1);
- cdr.StatP |= STATUS_ROTATING;
- cdr.StatP &= ~STATUS_SEEK;
- cdr.Result[0] = cdr.StatP;
- cdr.Seeked = TRUE;
- cdr.Stat = Complete;
-
-
- // Mega Man Legends 2: must update read cursor for getlocp
- ReadTrack( cdr.SetSector );
- break;
-
- case CdlSeekP:
- SetResultSize(1);
- cdr.StatP |= STATUS_ROTATING;
- cdr.Result[0] = cdr.StatP;
- cdr.StatP |= STATUS_SEEK;
- cdr.Stat = Acknowledge;
- AddIrqQueue(CdlSeekP + 0x20, cdReadTime * 1);
- break;
-
- case CdlSeekP + 0x20:
- SetResultSize(1);
- cdr.StatP |= STATUS_ROTATING;
- cdr.StatP &= ~STATUS_SEEK;
- cdr.Result[0] = cdr.StatP;
- cdr.Stat = Complete;
- cdr.Seeked = TRUE;
-
- // GameShark Music Player
- memcpy( cdr.SetSectorPlay, cdr.SetSector, 4 );
-
- // Tomb Raider 2: must update read cursor for getlocp
- Find_CurTrack();
- ReadTrack( cdr.SetSectorPlay );
+ CDRMISC_INT(cdr.Seeked == SEEK_DONE ? 0x800 : cdReadTime * 4);
+ cdr.Seeked = SEEK_DOING_CMD;
break;
case CdlTest:
@@ -1222,17 +1233,14 @@ void cdrInterrupt() {
if (buf != NULL)
memcpy(cdr.Transfer, buf, 8);
}
-
-
+
/*
Duke Nukem: Land of the Babes - seek then delay read for one frame
- fixes cutscenes
C-12 - Final Resistance - doesn't like seek
*/
- if (!cdr.Seeked) {
- cdr.Seeked = TRUE;
-
+ if (cdr.Seeked != SEEK_DONE) {
cdr.StatP |= STATUS_SEEK;
cdr.StatP &= ~STATUS_READ;
@@ -1272,7 +1280,10 @@ void cdrInterrupt() {
}
#ifdef CDR_LOG
- CDR_LOG("cdrInterrupt() Log: CDR Interrupt IRQ %x\n", Irq);
+ printf("cdrInterrupt() Log: CDR Interrupt IRQ %x: ", Irq);
+ for (i = 0; i < cdr.ResultC; i++)
+ printf("%02x ", cdr.Result[i]);
+ printf("\n");
#endif
}
@@ -1296,6 +1307,7 @@ void cdrReadInterrupt() {
cdr.StatP |= STATUS_READ|STATUS_ROTATING;
cdr.StatP &= ~STATUS_SEEK;
cdr.Result[0] = cdr.StatP;
+ cdr.Seeked = SEEK_DONE;
ReadTrack( cdr.SetSector );
@@ -1473,7 +1485,7 @@ unsigned char cdrRead1(void) {
}
void cdrWrite1(unsigned char rt) {
- char set_loc[3];
+ u8 set_loc[3];
int i;
#ifdef CDR_LOG
@@ -1526,17 +1538,14 @@ void cdrWrite1(unsigned char rt) {
StopReading();
for (i = 0; i < 3; i++)
set_loc[i] = btoi(cdr.Param[i]);
+
i = abs(msf2sec(cdr.SetSector) - msf2sec(set_loc));
if (i > 16)
- cdr.Seeked = FALSE;
+ cdr.Seeked = SEEK_PENDING;
+
memcpy(cdr.SetSector, set_loc, 3);
cdr.SetSector[3] = 0;
- /*
- if ((cdr.SetSector[0] | cdr.SetSector[1] | cdr.SetSector[2]) == 0) {
- *(u32 *)cdr.SetSector = *(u32 *)cdr.SetSectorSeek;
- }*/
-
cdr.Ctrl |= 0x80;
cdr.Stat = NoIntr;
AddIrqQueue(cdr.Cmd, 0x800);
@@ -1652,6 +1661,7 @@ void cdrWrite1(unsigned char rt) {
case CdlReset:
case CdlInit:
+ cdr.Seeked = SEEK_DONE;
StopCdda();
StopReading();
cdr.Ctrl |= 0x80;
@@ -1826,7 +1836,7 @@ unsigned char cdrRead2(void) {
if (cdr.Readed == 0) {
ret = 0;
} else {
- ret = *cdr.pTransfer++;
+ ret = *pTransfer++;
}
#ifdef CDR_LOG
@@ -1942,16 +1952,16 @@ void cdrWrite3(unsigned char rt) {
if (rt == 0x80 && !(cdr.Ctrl & 0x3) && cdr.Readed == 0) {
cdr.Readed = 1;
- cdr.pTransfer = cdr.Transfer;
+ pTransfer = cdr.Transfer;
switch (cdr.Mode & 0x30) {
case MODE_SIZE_2328:
case 0x00:
- cdr.pTransfer += 12;
+ pTransfer += 12;
break;
case MODE_SIZE_2340:
- cdr.pTransfer += 0;
+ pTransfer += 0;
break;
default:
@@ -2007,16 +2017,16 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
- CdlPlay
- Spams DMA3 and gets buffer overrun
*/
- size = CD_FRAMESIZE_RAW - (cdr.pTransfer - cdr.Transfer);
+ size = CD_FRAMESIZE_RAW - (pTransfer - cdr.Transfer);
if (size > cdsize)
size = cdsize;
if (size > 0)
{
- memcpy(ptr, cdr.pTransfer, size);
+ memcpy(ptr, pTransfer, size);
}
psxCpu->Clear(madr, cdsize / 4);
- cdr.pTransfer += cdsize;
+ pTransfer += cdsize;
// burst vs normal
@@ -2053,6 +2063,7 @@ void cdrReset() {
cdr.CurTrack = 1;
cdr.File = 1;
cdr.Channel = 1;
+ pTransfer = cdr.Transfer;
// BIOS player - default values
cdr.AttenuatorLeft[0] = 0x80;
@@ -2062,8 +2073,7 @@ void cdrReset() {
}
int cdrFreeze(gzFile f, int Mode) {
- uintptr_t tmp;
-
+ u32 tmp;
if( Mode == 0 ) {
StopCdda();
@@ -2072,12 +2082,12 @@ int cdrFreeze(gzFile f, int Mode) {
gzfreeze(&cdr, sizeof(cdr));
if (Mode == 1)
- tmp = cdr.pTransfer - cdr.Transfer;
+ tmp = pTransfer - cdr.Transfer;
gzfreeze(&tmp, sizeof(tmp));
if (Mode == 0) {
- cdr.pTransfer = cdr.Transfer + tmp;
+ pTransfer = cdr.Transfer + tmp;
if (cdr.Play && !Config.Cdda)
CDR_play(cdr.SetSectorPlay);
diff --git a/libpcsxcore/cdrom.h b/libpcsxcore/cdrom.h
index 772e3ca..ab22ccd 100644
--- a/libpcsxcore/cdrom.h
+++ b/libpcsxcore/cdrom.h
@@ -52,7 +52,7 @@ typedef struct {
unsigned char StatP;
unsigned char Transfer[CD_FRAMESIZE_RAW];
- unsigned char *pTransfer;
+ unsigned int pad1;
unsigned char Prev[4];
unsigned char Param[8];
@@ -87,7 +87,7 @@ typedef struct {
unsigned char Irq;
u32 eCycle;
- boolean Seeked;
+ u8 Seeked;
u8 LidCheck;
u8 FastForward;
diff --git a/libpcsxcore/coff.h b/libpcsxcore/coff.h
index 1d084d2..b472e1d 100644
--- a/libpcsxcore/coff.h
+++ b/libpcsxcore/coff.h
@@ -25,9 +25,9 @@
struct external_filehdr {
unsigned short f_magic; /* magic number */
unsigned short f_nscns; /* number of sections */
- unsigned long f_timdat; /* time & date stamp */
- unsigned long f_symptr; /* file pointer to symtab */
- unsigned long f_nsyms; /* number of symtab entries */
+ unsigned int f_timdat; /* time & date stamp */
+ unsigned int f_symptr; /* file pointer to symtab */
+ unsigned int f_nsyms; /* number of symtab entries */
unsigned short f_opthdr; /* sizeof(optional hdr) */
unsigned short f_flags; /* flags */
};
diff --git a/libpcsxcore/gte.c b/libpcsxcore/gte.c
index dc56b7f..62fc7f3 100644
--- a/libpcsxcore/gte.c
+++ b/libpcsxcore/gte.c
@@ -26,11 +26,6 @@
#include "gte.h"
#include "psxmem.h"
-typedef struct psxCP2Regs {
- psxCP2Data CP2D; /* Cop2 data registers */
- psxCP2Ctrl CP2C; /* Cop2 control registers */
-} psxCP2Regs;
-
#define VX(n) (n < 3 ? regs->CP2D.p[n << 1].sw.l : regs->CP2D.p[9].sw.l)
#define VY(n) (n < 3 ? regs->CP2D.p[n << 1].sw.h : regs->CP2D.p[10].sw.l)
#define VZ(n) (n < 3 ? regs->CP2D.p[(n << 1) + 1].sw.l : regs->CP2D.p[11].sw.l)
@@ -264,7 +259,7 @@ static inline u32 limE_(psxCP2Regs *regs, u32 result) {
#ifndef FLAGLESS
static inline u32 MFC2(int reg) {
- psxCP2Regs *regs = (psxCP2Regs *)&psxRegs.CP2D;
+ psxCP2Regs *regs = &psxRegs.CP2;
switch (reg) {
case 1:
case 3:
@@ -299,7 +294,7 @@ static inline u32 MFC2(int reg) {
}
static inline void MTC2(u32 value, int reg) {
- psxCP2Regs *regs = (psxCP2Regs *)&psxRegs.CP2D;
+ psxCP2Regs *regs = &psxRegs.CP2;
switch (reg) {
case 15:
gteSXY0 = gteSXY1;
diff --git a/libpcsxcore/mdec.c b/libpcsxcore/mdec.c
index 6cf2886..cd8d3bf 100644
--- a/libpcsxcore/mdec.c
+++ b/libpcsxcore/mdec.c
@@ -672,7 +672,30 @@ void mdec1Interrupt() {
}
int mdecFreeze(gzFile f, int Mode) {
- gzfreeze(&mdec, sizeof(mdec));
+ u8 *base = (u8 *)&psxM[0x100000];
+ u32 v;
+
+ gzfreeze(&mdec.reg0, sizeof(mdec.reg0));
+ gzfreeze(&mdec.reg1, sizeof(mdec.reg1));
+
+ // old code used to save raw pointers..
+ v = (u8 *)mdec.rl - base;
+ gzfreeze(&v, sizeof(v));
+ mdec.rl = (u16 *)(base + (v & 0xffffe));
+ v = (u8 *)mdec.rl_end - base;
+ gzfreeze(&v, sizeof(v));
+ mdec.rl_end = (u16 *)(base + (v & 0xffffe));
+
+ v = 0;
+ if (mdec.block_buffer_pos)
+ v = mdec.block_buffer_pos - base;
+ gzfreeze(&v, sizeof(v));
+ mdec.block_buffer_pos = 0;
+ if (v)
+ mdec.block_buffer_pos = base + (v & 0xfffff);
+
+ gzfreeze(&mdec.block_buffer, sizeof(mdec.block_buffer));
+ gzfreeze(&mdec.pending_dma1, sizeof(mdec.pending_dma1));
gzfreeze(iq_y, sizeof(iq_y));
gzfreeze(iq_uv, sizeof(iq_uv));
diff --git a/libpcsxcore/misc.c b/libpcsxcore/misc.c
index 2fe5600..ad2e5d5 100644
--- a/libpcsxcore/misc.c
+++ b/libpcsxcore/misc.c
@@ -93,8 +93,9 @@ void mmssdd( char *b, char *p )
#define READTRACK() \
if (CDR_readTrack(time) == -1) return -1; \
- buf = CDR_getBuffer(); \
- if (buf == NULL) return -1; else CheckPPFCache(buf, time[0], time[1], time[2]);
+ buf = (void *)CDR_getBuffer(); \
+ if (buf == NULL) return -1; \
+ else CheckPPFCache((u8 *)buf, time[0], time[1], time[2]);
#define READDIR(_dir) \
READTRACK(); \
@@ -104,9 +105,9 @@ void mmssdd( char *b, char *p )
READTRACK(); \
memcpy(_dir + 2048, buf + 12, 2048);
-int GetCdromFile(u8 *mdir, u8 *time, s8 *filename) {
+int GetCdromFile(u8 *mdir, u8 *time, char *filename) {
struct iso_directory_record *dir;
- char ddir[4096];
+ u8 ddir[4096];
u8 *buf;
int i;
@@ -169,7 +170,7 @@ int LoadCdrom() {
struct iso_directory_record *dir;
u8 time[4], *buf;
u8 mdir[4096];
- s8 exename[256];
+ char exename[256];
// not the best place to do it, but since BIOS boot logo killer
// is just below, do it here
@@ -207,7 +208,7 @@ int LoadCdrom() {
if (GetCdromFile(mdir, time, exename) == -1) {
sscanf((char *)buf + 12, "BOOT = cdrom:%256s", exename);
if (GetCdromFile(mdir, time, exename) == -1) {
- char *ptr = strstr(buf + 12, "cdrom:");
+ char *ptr = strstr((char *)buf + 12, "cdrom:");
if (ptr != NULL) {
ptr += 6;
while (*ptr == '\\' || *ptr == '/') ptr++;
@@ -258,8 +259,10 @@ int LoadCdrom() {
int LoadCdromFile(const char *filename, EXE_HEADER *head) {
struct iso_directory_record *dir;
u8 time[4],*buf;
- u8 mdir[4096], exename[256];
+ u8 mdir[4096];
+ char exename[256];
u32 size, addr;
+ void *mem;
sscanf(filename, "cdrom:\\%256s", exename);
@@ -288,7 +291,9 @@ int LoadCdromFile(const char *filename, EXE_HEADER *head) {
incTime();
READTRACK();
- memcpy((void *)PSXM(addr), buf + 12, 2048);
+ mem = PSXM(addr);
+ if (mem)
+ memcpy(mem, buf + 12, 2048);
size -= 2048;
addr += 2048;
@@ -299,7 +304,8 @@ int LoadCdromFile(const char *filename, EXE_HEADER *head) {
int CheckCdrom() {
struct iso_directory_record *dir;
- unsigned char time[4], *buf;
+ unsigned char time[4];
+ char *buf;
unsigned char mdir[4096];
char exename[256];
int i, c;
@@ -327,9 +333,9 @@ int CheckCdrom() {
if (GetCdromFile(mdir, time, "SYSTEM.CNF;1") != -1) {
READTRACK();
- sscanf((char *)buf + 12, "BOOT = cdrom:\\%256s", exename);
+ sscanf(buf + 12, "BOOT = cdrom:\\%256s", exename);
if (GetCdromFile(mdir, time, exename) == -1) {
- sscanf((char *)buf + 12, "BOOT = cdrom:%256s", exename);
+ sscanf(buf + 12, "BOOT = cdrom:%256s", exename);
if (GetCdromFile(mdir, time, exename) == -1) {
char *ptr = strstr(buf + 12, "cdrom:"); // possibly the executable is in some subdir
if (ptr != NULL) {
@@ -364,6 +370,9 @@ int CheckCdrom() {
}
}
+ if (CdromId[0] == '\0')
+ strcpy(CdromId, "SLUS99999");
+
if (Config.PsxAuto) { // autodetect system (pal or ntsc)
if (CdromId[2] == 'e' || CdromId[2] == 'E')
Config.PsxType = PSX_TYPE_PAL; // pal
@@ -406,6 +415,22 @@ static int PSXGetFileType(FILE *f) {
return INVALID_EXE;
}
+// temporary pandora workaround..
+// FIXME: remove
+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);
+ memcpy(ptr, tmp, size * nmemb);
+ free(tmp);
+ }
+ return ret;
+}
+
int Load(const char *ExePath) {
FILE *tmpFile;
EXE_HEADER tmpHead;
@@ -432,7 +457,7 @@ int Load(const char *ExePath) {
mem = PSXM(section_address);
if (mem != NULL) {
fseek(tmpFile, 0x800, SEEK_SET);
- fread(mem, section_size, 1, tmpFile);
+ fread_to_ram(mem, section_size, 1, tmpFile);
psxCpu->Clear(section_address, section_size / 4);
}
fclose(tmpFile);
@@ -458,7 +483,7 @@ int Load(const char *ExePath) {
#endif
mem = PSXM(section_address);
if (mem != NULL) {
- fread(mem, section_size, 1, tmpFile);
+ fread_to_ram(mem, section_size, 1, tmpFile);
psxCpu->Clear(section_address, section_size / 4);
}
break;
diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/emu_if.c
index 85ec174..588bc63 100644
--- a/libpcsxcore/new_dynarec/emu_if.c
+++ b/libpcsxcore/new_dynarec/emu_if.c
@@ -299,7 +299,6 @@ static void ari64_reset()
pending_exception = 1;
}
-#ifdef __arm__
// execute until predefined leave points
// (HLE softcall exit and BIOS fastboot end)
static void ari64_execute_until()
@@ -322,7 +321,6 @@ static void ari64_execute()
evprintf("drc left @%08x\n", psxRegs.pc);
}
}
-#endif
static void ari64_clear(u32 addr, u32 size)
{
@@ -360,7 +358,7 @@ extern void intExecuteBlockT();
R3000Acpu psxRec = {
ari64_init,
ari64_reset,
-#if defined(__arm__)
+#ifndef DRC_DISABLE
ari64_execute,
ari64_execute_until,
#else
@@ -377,7 +375,7 @@ void do_insn_trace() {}
void do_insn_cmp() {}
#endif
-#if defined(__x86_64__) || defined(__i386__)
+#ifdef DRC_DISABLE
unsigned int address;
int pending_exception, stop;
unsigned int next_interupt;
@@ -387,7 +385,7 @@ int new_dynarec_hacks;
void *psxH_ptr;
void *zeromem_ptr;
u8 zero_mem[0x1000];
-void new_dynarec_init() {}
+void new_dynarec_init() { (void)ari64_execute; }
void new_dyna_start() {}
void new_dynarec_cleanup() {}
void new_dynarec_clear_full() {}
diff --git a/libpcsxcore/psxcounters.c b/libpcsxcore/psxcounters.c
index 8fc33b4..3e6d417 100644
--- a/libpcsxcore/psxcounters.c
+++ b/libpcsxcore/psxcounters.c
@@ -152,6 +152,52 @@ u32 _psxRcntRcount( u32 index )
return count;
}
+static
+void _psxRcntWmode( u32 index, u32 value )
+{
+ rcnts[index].mode = value;
+
+ switch( index )
+ {
+ case 0:
+ if( value & Rc0PixelClock )
+ {
+ rcnts[index].rate = 5;
+ }
+ else
+ {
+ rcnts[index].rate = 1;
+ }
+ break;
+ case 1:
+ if( value & Rc1HSyncClock )
+ {
+ rcnts[index].rate = (PSXCLK / (FrameRate[Config.PsxType] * HSyncTotal[Config.PsxType]));
+ }
+ else
+ {
+ rcnts[index].rate = 1;
+ }
+ break;
+ case 2:
+ if( value & Rc2OneEighthClock )
+ {
+ rcnts[index].rate = 8;
+ }
+ else
+ {
+ rcnts[index].rate = 1;
+ }
+
+ // TODO: wcount must work.
+ if( value & Rc2Disable )
+ {
+ rcnts[index].rate = 0xffffffff;
+ }
+ break;
+ }
+}
+
/******************************************************************************/
static
@@ -357,50 +403,10 @@ void psxRcntWmode( u32 index, u32 value )
{
verboseLog( 1, "[RCNT %i] wmode: %x\n", index, value );
- rcnts[index].mode = value;
- rcnts[index].irqState = 0;
-
- switch( index )
- {
- case 0:
- if( value & Rc0PixelClock )
- {
- rcnts[index].rate = 5;
- }
- else
- {
- rcnts[index].rate = 1;
- }
- break;
- case 1:
- if( value & Rc1HSyncClock )
- {
- rcnts[index].rate = (PSXCLK / (FrameRate[Config.PsxType] * HSyncTotal[Config.PsxType]));
- }
- else
- {
- rcnts[index].rate = 1;
- }
- break;
- case 2:
- if( value & Rc2OneEighthClock )
- {
- rcnts[index].rate = 8;
- }
- else
- {
- rcnts[index].rate = 1;
- }
-
- // TODO: wcount must work.
- if( value & Rc2Disable )
- {
- rcnts[index].rate = 0xffffffff;
- }
- break;
- }
-
+ _psxRcntWmode( index, value );
_psxRcntWcount( index, 0 );
+
+ rcnts[index].irqState = 0;
psxRcntSet();
}
@@ -497,6 +503,9 @@ void psxRcntInit()
s32 psxRcntFreeze( gzFile f, s32 Mode )
{
+ u32 count;
+ s32 i;
+
gzfreeze( &rcnts, sizeof(rcnts) );
gzfreeze( &hSyncCount, sizeof(hSyncCount) );
gzfreeze( &spuSyncCount, sizeof(spuSyncCount) );
@@ -504,9 +513,19 @@ s32 psxRcntFreeze( gzFile f, s32 Mode )
gzfreeze( &psxNextsCounter, sizeof(psxNextsCounter) );
if (Mode == 0)
+ {
+ // don't trust things from a savestate
+ for( i = 0; i < CounterQuantity; ++i )
+ {
+ _psxRcntWmode( i, rcnts[i].mode );
+ count = (psxRegs.cycle - rcnts[i].cycleStart) / rcnts[i].rate;
+ _psxRcntWcount( i, count );
+ }
hsync_steps = (psxRegs.cycle - rcnts[3].cycleStart) / rcnts[3].target;
+ psxRcntSet();
- base_cycle = 0;
+ base_cycle = 0;
+ }
return 0;
}
diff --git a/libpcsxcore/psxmem.c b/libpcsxcore/psxmem.c
index 1cabd53..ddcd05b 100644
--- a/libpcsxcore/psxmem.c
+++ b/libpcsxcore/psxmem.c
@@ -60,6 +60,16 @@ u8 **psxMemRLUT = NULL;
0xbfc0_0000-0xbfc7_ffff BIOS Mirror (512K) Uncached
*/
+#if 1
+void *plat_mmap(unsigned long addr, size_t size, int need_exec, int is_fixed);
+void plat_munmap(void *ptr, size_t size);
+#else
+#define plat_mmap(addr, size, need_exec, is_fixed) \
+ mmap((void *)addr, size, PROT_WRITE | PROT_READ, \
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0)
+#define plat_munmap munmap
+#endif
+
int psxMemInit() {
int i;
@@ -68,8 +78,7 @@ int psxMemInit() {
memset(psxMemRLUT, 0, 0x10000 * sizeof(void *));
memset(psxMemWLUT, 0, 0x10000 * sizeof(void *));
- psxM = mmap((void *)0x80000000, 0x00210000,
- PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+ psxM = plat_mmap(0x80000000, 0x00210000, 0, 1);
#ifndef RAM_FIXED
if (psxM == MAP_FAILED)
psxM = mmap((void *)0x70000000, 0x00210000,
@@ -144,7 +153,7 @@ void psxMemReset() {
}
void psxMemShutdown() {
- munmap(psxM, 0x00210000);
+ plat_munmap(psxM, 0x00210000);
munmap(psxH, 0x1f800000);
munmap(psxR, 0x80000);
diff --git a/libpcsxcore/r3000a.h b/libpcsxcore/r3000a.h
index 76f42bc..13aaa59 100644
--- a/libpcsxcore/r3000a.h
+++ b/libpcsxcore/r3000a.h
@@ -163,11 +163,21 @@ enum {
PSXINT_COUNT
};
+typedef struct psxCP2Regs {
+ psxCP2Data CP2D; /* Cop2 data registers */
+ psxCP2Ctrl CP2C; /* Cop2 control registers */
+} psxCP2Regs;
+
typedef struct {
psxGPRRegs GPR; /* General Purpose Registers */
psxCP0Regs CP0; /* Coprocessor0 Registers */
- psxCP2Data CP2D; /* Cop2 data registers */
- psxCP2Ctrl CP2C; /* Cop2 control registers */
+ union {
+ struct {
+ psxCP2Data CP2D; /* Cop2 data registers */
+ psxCP2Ctrl CP2C; /* Cop2 control registers */
+ };
+ psxCP2Regs CP2;
+ };
u32 pc; /* Program counter */
u32 code; /* The instruction */
u32 cycle;