diff options
Diffstat (limited to 'libpcsxcore')
-rw-r--r-- | libpcsxcore/cdriso.c | 43 | ||||
-rw-r--r-- | libpcsxcore/cdrom.c | 170 | ||||
-rw-r--r-- | libpcsxcore/cdrom.h | 4 | ||||
-rw-r--r-- | libpcsxcore/coff.h | 6 | ||||
-rw-r--r-- | libpcsxcore/gte.c | 9 | ||||
-rw-r--r-- | libpcsxcore/mdec.c | 25 | ||||
-rw-r--r-- | libpcsxcore/misc.c | 51 | ||||
-rw-r--r-- | libpcsxcore/new_dynarec/emu_if.c | 8 | ||||
-rw-r--r-- | libpcsxcore/psxcounters.c | 107 | ||||
-rw-r--r-- | libpcsxcore/psxmem.c | 15 | ||||
-rw-r--r-- | libpcsxcore/r3000a.h | 14 |
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; |