diff options
| author | SND\shalma_cp <SND\shalma_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-09-28 14:07:40 +0000 |
|---|---|---|
| committer | SND\shalma_cp <SND\shalma_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-09-28 14:07:40 +0000 |
| commit | da14cf2c433e99eaa9ae14c7a1e589c20c93073b (patch) | |
| tree | 0aa0c5022860b52c5b7b20d844e1dc970f79797a /libpcsxcore | |
| parent | f90c726e013a832cea1ce213e5251b9a013ad8a1 (diff) | |
| download | pcsxr-da14cf2c433e99eaa9ae14c7a1e589c20c93073b.tar.gz | |
Rayman, BIOS Music Player, GameShark Music Players
- cdriso.c: Forward + Backward (rewind) support, Data track wiping during audio play, GetStatus (time) fixes
- cdrom.c: CdlForward, CdlBackward, CdlID (auto boot Music CDs with BIOS), CdlStop, CdlPause, CdlPlay (support BIOS play + pause / resume), CdlGetlocP (timing, output results), REPPLAY (report play times - Rayman, BIOS) now work
- cdrom.h: Forward, Backward states; Larger result buffer
NOTE:
Must use iso images with subchannel data for Rayman and Music Players to work. And use latest PCSX-r PEOPS DSound plugin.
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@57823 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'libpcsxcore')
| -rw-r--r-- | libpcsxcore/cdriso.c | 85 | ||||
| -rw-r--r-- | libpcsxcore/cdrom.c | 543 | ||||
| -rw-r--r-- | libpcsxcore/cdrom.h | 4 |
3 files changed, 438 insertions, 194 deletions
diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c index fbdb9eb1..cb6527d7 100644 --- a/libpcsxcore/cdriso.c +++ b/libpcsxcore/cdriso.c @@ -66,8 +66,8 @@ extern void *hCDRDriver; struct trackinfo { enum {DATA, CDDA} type; - char start[3]; // MSF-format - char length[3]; // MSF-format + u8 start[3]; // MSF-format + u8 length[3]; // MSF-format }; #define MAXTRACKS 100 /* How many tracks can a CD hold? */ @@ -161,8 +161,6 @@ static void *playthread(void *param) t = GetTickCount() + CDDA_FRAMETIME; - sec = cddaCurOffset / CD_FRAMESIZE_RAW;
-
if (subChanMixed) { s = 0; @@ -181,6 +179,8 @@ static void *playthread(void *param) else { s = fread(sndbuffer, 1, sizeof(sndbuffer), cddaHandle); + sec = cddaCurOffset / CD_FRAMESIZE_RAW;
+
if (subHandle != NULL) { fseek(subHandle, sec * SUB_FRAMESIZE, SEEK_SET); fread(subbuffer, 1, SUB_FRAMESIZE, subHandle); @@ -204,10 +204,53 @@ static void *playthread(void *param) } } + // wipe data track
+ if( subHandle || subChanInterleaved ) {
+ if( ti[ ((struct SubQ *) subbuffer)->TrackNumber ].type == DATA )
+ memset( sndbuffer, 0, s );
+ }
+
SPU_playCDDAchannel((short *)sndbuffer, s); } cddaCurOffset += s; +
+
+ // BIOS CD Player: Fast forward / reverse seek
+ if( cdr.FastForward ) {
+ // ~+0.25 sec
+ cddaCurOffset += CD_FRAMESIZE_RAW * 75/4;
+
+#if 0
+ // Bad idea: too much static
+ if( subChanInterleaved )
+ fseek( cddaHandle, s * (CD_FRAMESIZE_RAW + SUB_FRAMESIZE), SEEK_SET );
+ else
+ fseek( cddaHandle, s * CD_FRAMESIZE_RAW, SEEK_SET );
+#endif
+ }
+ else if( cdr.FastBackward ) {
+ // ~-0.25 sec
+ cddaCurOffset -= CD_FRAMESIZE_RAW * 75/4;
+ if( cddaCurOffset & 0x80000000 ) {
+ cddaCurOffset = 0;
+ cdr.FastBackward = 0;
+
+ playing = 0;
+ fclose(cddaHandle);
+ cddaHandle = NULL;
+ initial_offset = 0;
+ break;
+ }
+
+#if 0
+ // Bad idea: too much static
+ if( subChanInterleaved )
+ fseek( cddaHandle, s * (CD_FRAMESIZE_RAW + SUB_FRAMESIZE), SEEK_SET );
+ else
+ fseek( cddaHandle, s * CD_FRAMESIZE_RAW, SEEK_SET );
+#endif
+ }
} #ifdef _WIN32 @@ -862,21 +905,25 @@ static unsigned char* CALLBACK ISOgetBufferSub(void) { } static long CALLBACK ISOgetStatus(struct CdrStat *stat) { - int sec; - - CDR__getStatus(stat); - - if (playing) { - stat->Type = 0x02; - stat->Status |= 0x80; - sec = cddaCurOffset / CD_FRAMESIZE_RAW; - sec2msf(sec, (char *)stat->Time); - } - else { - stat->Type = 0x01; - } - - return 0; + u32 sect;
+
+ CDR__getStatus(stat);
+
+ if (playing) {
+ stat->Status |= 0x80;
+ }
+
+ // relative -> absolute time
+ sect = cddaCurOffset / CD_FRAMESIZE_RAW + 150;
+ sec2msf(sect, (u8 *)stat->Time);
+
+ if (subHandle != NULL || subChanInterleaved) {
+ stat->Type = ti[ ((struct SubQ *) subbuffer)->TrackNumber ].type;
+ }
+ else
+ stat->Type = ti[ cdr.CurTrack ].type;
+
+ return 0;
} void cdrIsoInit(void) { diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index a6e40834..2924461b 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -122,7 +122,9 @@ static struct SubQ *subq; if (cdr.Play) { \ if (!Config.Cdda) CDR_stop(); \ cdr.StatP &= ~0x80; \ - cdr.Play = FALSE; \ + cdr.Play = FALSE; \
+ cdr.FastForward = 0; \
+ cdr.FastBackward = 0; \
} \ } @@ -132,6 +134,37 @@ static struct SubQ *subq; cdr.ResultReady = 1; \ } +void Find_CurTrack() {
+ cdr.CurTrack = 0;
+
+ if (CDR_getTN(cdr.ResultTN) != -1) {
+ int lcv;
+
+ for( lcv = 1; lcv < cdr.ResultTN[1]; lcv++ ) {
+ if (CDR_getTD((u8)(lcv), cdr.ResultTD) != -1) {
+ u32 sect1, sect2;
+
+#ifdef CDR_LOG___0
+ CDR_LOG( "curtrack %d %d %d | %d %d %d | %d\n",
+ cdr.SetSector[0], cdr.SetSector[1], cdr.SetSector[2],
+ cdr.ResultTD[0], cdr.ResultTD[1], cdr.ResultTD[2],
+ cdr.CurTrack );
+#endif
+
+ // find next track boundary
+ sect1 = cdr.SetSector[0] * 60 * 75 + cdr.SetSector[1] * 75 + cdr.SetSector[2];
+ sect2 = cdr.ResultTD[2] * 60 * 75 + cdr.ResultTD[1] * 75 + cdr.ResultTD[0];
+ if( sect1 >= sect2 ) {
+ cdr.CurTrack++;
+ continue;
+ }
+ }
+
+ break;
+ }
+ }
+}
+
static void ReadTrack() { cdr.Prev[0] = itob(cdr.SetSector[0]); cdr.Prev[1] = itob(cdr.SetSector[1]); @@ -209,16 +242,30 @@ void cdrInterrupt() { cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP |= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Complete; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; +
+
+ // GameShark CD Player: Calls 2x + Play 2x
+ if( cdr.FastForward == 0 ) cdr.FastForward = 2;
+ else cdr.FastForward++;
+
+ cdr.FastBackward = 0;
break; case CdlBackward: cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP |= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = Complete; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete;
+
+
+ // GameShark CD Player: Calls 2x + Play 2x
+ if( cdr.FastBackward == 0 ) cdr.FastBackward = 2;
+ else cdr.FastBackward++;
+
+ cdr.FastForward = 0;
break; case CdlStandby: @@ -322,15 +369,22 @@ void cdrInterrupt() { break; case CdlGetlocP: - SetResultSize(8); + SetResultSize(17);
+ memset( cdr.Result, 0, 17 );
+
subq = (struct SubQ *)CDR_getBufferSub(); - // DATA + AUDIO has subchannel data if (subq != NULL) { - cdr.Result[0] = subq->TrackNumber; - cdr.Result[1] = subq->IndexNumber; - memcpy(cdr.Result + 2, subq->TrackRelativeAddress, 3); - memcpy(cdr.Result + 5, subq->AbsoluteAddress, 3); + // Subchannel block #1
+ cdr.Result[0] = subq->TrackNumber;
+ cdr.Result[1] = subq->IndexNumber;
+ memcpy(cdr.Result+2, subq->TrackRelativeAddress, 3);
+ memcpy(cdr.Result+5, subq->AbsoluteAddress, 3);
+
+
+ // GameShark CDX CD Player: Subchannel block #2
+ cdr.Result[16] = subq->TrackNumber;
+
// subQ integrity check if (calcCrc((u8 *)subq + 12, 10) != (((u16)subq->CRC[0] << 8) | subq->CRC[1])) { @@ -357,6 +411,55 @@ void cdrInterrupt() { memcpy(cdr.Result + 5, cdr.Prev, 3); } +#if 1
+ // FIXME!!!
+ if( cdr.LidCheck ) {
+ memset( cdr.Result, 0, 17 );
+
+ // each state needs ~50 tries
+ if( cdr.LidCheck < 130 )
+ cdr.LidCheck++;
+ else
+ cdr.LidCheck = 0;
+
+ i = stat.Status;
+ if (CDR_getStatus(&stat) != -1) {
+ // Hack: Fake CDROM seek / spin time
+ static int seek_time = 0;
+
+ if (stat.Type == 0xff) {
+ }
+ else if (stat.Status & 0x10) {
+ // unknown #1 - status?
+ // unknown #2 - case open?
+
+ cdr.Result[0] = 0x11;
+ cdr.Result[1] = 0x80;
+ }
+ else if ( i & 0x10 ) {
+ cdr.Result[0] = 0x13;
+ cdr.Result[1] = 0x80;
+
+ // minimum tries for GS CDX 3.3
+ seek_time = 120;
+ }
+ else if ( seek_time > 60 ) {
+ cdr.Result[0] = 0x13;
+ cdr.Result[1] = 0x80;
+
+ seek_time--;
+ }
+ else if( seek_time ) {
+ // GameShark CDX swap
+ cdr.Result[0] = 0x01;
+ cdr.Result[1] = 0x00;
+
+ seek_time--;
+ }
+ }
+ }
+#endif
+
cdr.Stat = Acknowledge; break; @@ -457,21 +560,26 @@ void cdrInterrupt() { break; case CdlID + 0x20: - SetResultSize(8); - if (CDR_getStatus(&stat) == -1) { - cdr.Result[0] = 0x00; // 0x08 and cdr.Result[1]|0x10 : audio cd, enters cd player - cdr.Result[1] = 0x00; // 0x80 leads to the menu in the bios, else loads CD - } - else { - if (stat.Type == 2) { - cdr.Result[0] = 0x08; - cdr.Result[1] = 0x10; - } - else { - cdr.Result[0] = 0x00; - cdr.Result[1] = 0x00; - } - } + SetResultSize(8);
+ if (CDR_getStatus(&stat) == -1) {
+ cdr.Result[0] = 0x00; // 0x08 and cdr.Result[1]|0x10 : audio cd, enters cd player
+ cdr.Result[1] = 0x00; // 0x80 leads to the menu in the bios, else loads CD
+ }
+ else {
+ if (stat.Type == 2) {
+ // Music CD
+ cdr.Result[0] = 0x08;
+ cdr.Result[1] = 0x10;
+
+ cdr.Result[1] |= 0x80;
+ }
+ else {
+ // Data CD
+ cdr.Result[0] = 0x08;
+ cdr.Result[1] = 0x00;
+ }
+ }
+
cdr.Result[1] |= 0x80; cdr.Result[2] = 0x00; cdr.Result[3] = 0x00; @@ -539,26 +647,67 @@ void cdrInterrupt() { break; case REPPLAY: - if ((cdr.Mode & 5) != 5) break; - if (CDR_getStatus(&stat) == -1) { - cdr.Result[0] = 0; - cdr.Result[1] = 0; - cdr.Result[2] = 0; - cdr.Result[3] = 0; - cdr.Result[4] = 0; - cdr.Result[5] = 0; - cdr.Result[6] = 0; - cdr.Result[7] = 0; - } - else - // FIXME!! - //memcpy(cdr.Result, &stat.Track, 8); - 0; - - cdr.Stat = 1; - SetResultSize(8); - AddIrqQueue(REPPLAY_ACK, cdReadTime); - break; + if ((cdr.Mode & 5) != 5) break;
+
+ memset( cdr.Result, 0, 8 );
+ if( CDR_getStatus(&stat) != -1) {
+ // HACK: Switch between local / absolute times
+ static u8 report_time = 1;
+
+
+ subq = (struct SubQ *)CDR_getBufferSub();
+
+ if (subq != NULL ) {
+ /*
+ skip subQ integrity check (audio playback)
+ mainly useful for DATA LibCrypt checking
+ */
+ //if( SWAP16(subq->CRC) != calcCrc((unsigned char *)subq + 12, 10) )
+
+ cdr.Result[0] = cdr.StatP;
+
+
+ // Rayman: audio pregap flag / track change
+ // - not all CDs will use PREGAPs, so we track it manually
+ if( cdr.CurTrack < btoi( subq->TrackNumber ) ) {
+ cdr.Result[0] |= 0x10;
+
+ cdr.CurTrack = btoi( subq->TrackNumber );
+ }
+
+
+ // BIOS CD Player: data already BCD format
+ cdr.Result[1] = subq->TrackNumber;
+ cdr.Result[2] = subq->IndexNumber;
+
+
+ // BIOS CD Player: switch between local / absolute times
+ if( report_time == 0 ) {
+ cdr.Result[3] = subq->AbsoluteAddress[0];
+ cdr.Result[4] = subq->AbsoluteAddress[1];
+ cdr.Result[5] = subq->AbsoluteAddress[2];
+
+ report_time = 1;
+ }
+ else {
+ cdr.Result[3] = subq->TrackRelativeAddress[0];
+ cdr.Result[4] = subq->TrackRelativeAddress[1];
+ cdr.Result[5] = subq->TrackRelativeAddress[2];
+
+ cdr.Result[4] |= 0x80;
+
+ report_time = 0;
+ }
+ }
+ }
+
+ // Rayman: Logo freeze
+ cdr.ResultReady = 1;
+
+ cdr.Stat = 1;
+ SetResultSize(8);
+ AddIrqQueue(REPPLAY_ACK, cdReadTime);
+ break;
case 0xff: return; @@ -569,7 +718,8 @@ void cdrInterrupt() { } // check case open/close - if (cdr.LidCheck > 0) { + if( cdr.LidCheck > 0 && Irq != CdlGetlocP ) {
+ // if (cdr.LidCheck > 0) { cdr.LidCheck--; i = stat.Status; @@ -815,55 +965,119 @@ void cdrWrite1(unsigned char rt) { break; case CdlSetloc: - StopReading(); - cdr.Seeked = FALSE; - for (i = 0; i < 3; i++) - cdr.SetSector[i] = btoi(cdr.Param[i]); - 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; + StopReading(); + cdr.Seeked = FALSE; + for (i = 0; i < 3; i++) + cdr.SetSector[i] = btoi(cdr.Param[i]); + cdr.SetSector[3] = 0; +
+#ifdef DVD5_HACK
+ // PS1 DVD5 hack (shalma's disc combining kits)
+ dvd5_mode = cdr.Param[2] & 0x80;
+
+ if( CDR__setDVD5 ) {
+ if( cdr.Param[2] & 0x80 )
+ CDR__setDVD5(1);
+ else if( cdr.Param[1] & 0x80 )
+ CDR__setDVD5(2);
+ else
+ CDR__setDVD5(0);
+ }
+
+ cdr.Param[1] &= 0x7f;
+ cdr.Param[2] &= 0x7f;
+#endif
+
+ /*
+ 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, 0x1000); - break; + break; case CdlPlay: - if (!cdr.SetSector[0] & !cdr.SetSector[1] & !cdr.SetSector[2]) { - if (CDR_getTN(cdr.ResultTN) != -1) { - if (cdr.CurTrack > cdr.ResultTN[1]) - cdr.CurTrack = cdr.ResultTN[1]; - if (CDR_getTD((unsigned char)(cdr.CurTrack), cdr.ResultTD) != -1) { - int tmp = cdr.ResultTD[2]; - cdr.ResultTD[2] = cdr.ResultTD[0]; - cdr.ResultTD[0] = tmp; - if (!Config.Cdda) CDR_play(cdr.ResultTD); - } - } - } else if (!Config.Cdda) { - CDR_play(cdr.SetSector); - } - cdr.Play = TRUE; - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x1000); - break; + // Rayman: detect track changes
+ Find_CurTrack();
+
+
+ // GameShark CD Player: Calls 2x + Play 2x
+ if( cdr.FastBackward || cdr.FastForward ) {
+ if( cdr.FastForward ) cdr.FastForward--;
+ if( cdr.FastBackward ) cdr.FastBackward--;
+
+ if( cdr.FastBackward == 0 && cdr.FastForward == 0 ) {
+ if( CDR_getStatus(&stat) != -1 ) {
+ cdr.SetSector[0] = stat.Time[0];
+ cdr.SetSector[1] = stat.Time[1];
+ cdr.SetSector[2] = stat.Time[2];
+ }
+ }
+ }
+
+
+ if (!Config.Cdda) {
+ // BIOS CD Player
+ // - Pause player, hit Track 01/02/../xx (Setloc issued!!)
+
+ // GameShark CD Player: Resume play
+ if( cdr.ParamC == 0 ) {
+ CDR_play( cdr.SetSector );
+ }
+ else
+ {
+ // BIOS CD Player: Resume play
+ if( cdr.Param[0] == 0 ) {
+ CDR_play( cdr.SetSector );
+ }
+
+ else {
+ // BIOS CD Player: Allow track replaying
+ StopCdda();
+
+
+ cdr.CurTrack = btoi( cdr.Param[0] );
+
+ if (CDR_getTN(cdr.ResultTN) != -1) {
+ // check last track
+ if (cdr.CurTrack > cdr.ResultTN[1])
+ cdr.CurTrack = cdr.ResultTN[1];
+
+ if (CDR_getTD((u8)(cdr.CurTrack), cdr.ResultTD) != -1) {
+ cdr.SetSector[0] = cdr.ResultTD[2];
+ cdr.SetSector[1] = cdr.ResultTD[1];
+ cdr.SetSector[2] = cdr.ResultTD[0];
+
+ CDR_play(cdr.SetSector);
+ }
+ }
+ }
+ }
+ }
+
+ cdr.Play = TRUE;
+ cdr.Ctrl |= 0x80;
+ cdr.Stat = NoIntr;
+ AddIrqQueue(cdr.Cmd, 0x1000);
+ break;
case CdlForward: - if (cdr.CurTrack < 0xaa) - cdr.CurTrack++; - cdr.Ctrl |= 0x80; + //if (cdr.CurTrack < 0xaa) + // cdr.CurTrack++; + cdr.Ctrl |= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x1000); - break; + break; case CdlBackward: - if (cdr.CurTrack > 1) - cdr.CurTrack--; - cdr.Ctrl |= 0x80; + //if (cdr.CurTrack > 1) + //cdr.CurTrack--; + cdr.Ctrl |= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x1000); - break; + break; case CdlReadN: cdr.Irq = 0; @@ -882,20 +1096,45 @@ void cdrWrite1(unsigned char rt) { break; case CdlStop: - StopCdda(); - StopReading(); - cdr.Ctrl |= 0x80; + // GameShark CD Player: Reset CDDA to track start
+ if( CDR_getStatus(&stat) != -1 ) {
+ cdr.SetSector[0] = stat.Time[0];
+ cdr.SetSector[1] = stat.Time[1];
+ cdr.SetSector[2] = stat.Time[2];
+
+ Find_CurTrack();
+
+
+ // grab time for current track
+ CDR_getTD((u8)(cdr.CurTrack), cdr.ResultTD);
+
+ cdr.SetSector[0] = cdr.ResultTD[2];
+ cdr.SetSector[1] = cdr.ResultTD[1];
+ cdr.SetSector[2] = cdr.ResultTD[0];
+ }
+
+ StopCdda();
+ StopReading();
+
+ cdr.Ctrl |= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x1000); - break; + break; case CdlPause: - StopCdda(); - StopReading(); - cdr.Ctrl |= 0x80; + // GameShark CD Player: save time for resume
+ if( CDR_getStatus(&stat) != -1 ) {
+ cdr.SetSector[0] = stat.Time[0];
+ cdr.SetSector[1] = stat.Time[1];
+ cdr.SetSector[2] = stat.Time[2];
+ }
+
+ StopCdda();
+ StopReading();
+ cdr.Ctrl |= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x80000); - break; + break; case CdlReset: case CdlInit: @@ -951,16 +1190,23 @@ void cdrWrite1(unsigned char rt) { break; case CdlGetlocP: - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x1000); - break; + cdr.Ctrl |= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x1000); +
+ // GameShark CDX / Lite Player: pretty narrow time window
+ // - doesn't always work due to time inprecision
+ //AddIrqQueue(cdr.Cmd, 0x28);
+ break; case CdlGetTN: - cdr.Ctrl |= 0x80; + cdr.Ctrl |= 0x80; cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x1000); - break; + //AddIrqQueue(cdr.Cmd, 0x1000); +
+ // GameShark CDX CD Player: very long time
+ AddIrqQueue(cdr.Cmd, 0x100000);
+ break; case CdlGetTD: cdr.Ctrl |= 0x80; @@ -1075,21 +1321,39 @@ unsigned char cdrRead3(void) { void cdrWrite3(unsigned char rt) { #ifdef CDR_LOG CDR_LOG("cdrWrite3() Log: CD3 write: %x\n", rt); -#endif - if (rt == 0x07 && cdr.Ctrl & 0x1) { +#endif
+ + // GameShark CDX CD Player: Irq timing mania
+ if( rt == 0 &&
+ cdr.Irq != 0 && cdr.Irq != 0xff &&
+ cdr.ResultReady == 0 ) {
+
+ // GS CDX: ~0x28 cycle timing - way too precise
+ if( cdr.Irq == CdlGetlocP ) {
+ cdrInterrupt();
+
+ psxRegs.interrupt &= ~(1 << PSXINT_CDR);
+ }
+ }
+
+
+ if (rt == 0x07 && cdr.Ctrl & 0x1) { cdr.Stat = 0; if (cdr.Irq == 0xff) { cdr.Irq = 0; return; - } + }
+ if (cdr.Irq) - CDR_INT(cdr.eCycle); + CDR_INT(cdr.eCycle);
+ if (cdr.Reading && !cdr.ResultReady) CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); return; - } + }
+ if (rt == 0x80 && !(cdr.Ctrl & 0x1) && cdr.Readed == 0) { cdr.Readed = 1; cdr.pTransfer = cdr.Transfer; @@ -1103,75 +1367,6 @@ void cdrWrite3(unsigned char rt) { break; } } - - /* - GameShark CDX 3.3 - - TODO: Can we relax the rules? - */ - if (rt == 0 && cdr.Ctrl == 0xd8 && cdr.Readed == 1) { - u32 i; - - - // low-level status access - SetResultSize(15); - - - i = stat.Status; - if (CDR_getStatus(&stat) != -1) { - // Hack: Fake CDROM seek / spin time - static int seek_time = 0; - - if (stat.Type == 0xff) { - } - else if (stat.Status & 0x10) { - // unknown #1 - status? - // unknown #2 - case open? - - cdr.Result[0] = 0x11; - cdr.Result[1] = 0x80; - } - else if ( i & 0x10 ) { - cdr.Result[0] = 0x13; - cdr.Result[1] = 0x80; - - // minimum 50 tries for GS CDX 3.3 - seek_time = 50; - } - else if ( seek_time ) { - cdr.Result[0] = 0x13; - cdr.Result[1] = 0x80; - - seek_time--; - } - else - { - cdr.Result[0] = 0x01; - cdr.Result[1] = 0x00; - } - - // unknown #3 - cdr.Result[2] = 0; - - // unknown #4 - error? - cdr.Result[3] = 0; - - // unknown #5-14 - cdr.Result[4] = 0; - cdr.Result[5] = 0; - cdr.Result[6] = 0; - cdr.Result[7] = 0; - cdr.Result[8] = 0; - cdr.Result[9] = 0; - cdr.Result[10] = 0; - cdr.Result[11] = 0; - cdr.Result[12] = 0; - cdr.Result[13] = 0; - - // unknown #15 - error? - cdr.Result[14] = 0; - } - } } void psxDma3(u32 madr, u32 bcr, u32 chcr) { diff --git a/libpcsxcore/cdrom.h b/libpcsxcore/cdrom.h index 9e4c6fa7..da4fe108 100644 --- a/libpcsxcore/cdrom.h +++ b/libpcsxcore/cdrom.h @@ -56,7 +56,7 @@ typedef struct { unsigned char Prev[4]; unsigned char Param[8]; - unsigned char Result[15]; + unsigned char Result[16]; unsigned char ParamC; unsigned char ParamP; @@ -89,6 +89,8 @@ typedef struct { boolean Seeked; u8 LidCheck; + u8 FastForward;
+ u8 FastBackward;
} cdrStruct; extern cdrStruct cdr; |
