diff options
| author | SND\dario86_cp <SND\dario86_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-03-12 18:54:28 +0000 |
|---|---|---|
| committer | SND\dario86_cp <SND\dario86_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-03-12 18:54:28 +0000 |
| commit | a58cfdac407bc1d8fedc11acd924b275ba28cc51 (patch) | |
| tree | b4c2e08c34ef1bfe0ba947ef8eed931c9a43fc0e /libpcsxcore/cdrom.c | |
| parent | 9bdd06684bcc627c06ddcf4c406f6b48f0dfe389 (diff) | |
Commited patch in issue #8171 (by darktjm).
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@64524 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'libpcsxcore/cdrom.c')
| -rw-r--r-- | libpcsxcore/cdrom.c | 1509 |
1 files changed, 751 insertions, 758 deletions
diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index b49d0358..4be39d22 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -22,8 +22,10 @@ */ #include "cdrom.h" +#include "cdriso.h" #include "ppf.h" #include "psxdma.h" +#include "spu.h" cdrStruct cdr; @@ -91,29 +93,29 @@ unsigned char Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 }; #define Acknowledge 3 #define DataEnd 4 #define DiskError 5 -
-/* Modes flags */
-#define MODE_SPEED (1<<7) // 0x80
-#define MODE_STRSND (1<<6) // 0x40 ADPCM on/off
-#define MODE_SIZE_2340 (1<<5) // 0x20
-#define MODE_SIZE_2328 (1<<4) // 0x10
-#define MODE_SIZE_2048 (0<<4) // 0x00
-#define MODE_SF (1<<3) // 0x08 channel on/off
-#define MODE_REPORT (1<<2) // 0x04
-#define MODE_AUTOPAUSE (1<<1) // 0x02
-#define MODE_CDDA (1<<0) // 0x01
-
-/* Status flags */
-#define STATUS_PLAY (1<<7) // 0x80
-#define STATUS_SEEK (1<<6) // 0x40
-#define STATUS_READ (1<<5) // 0x20
-#define STATUS_SHELLOPEN (1<<4) // 0x10
-#define STATUS_UNKNOWN3 (1<<3) // 0x08
-#define STATUS_UNKNOWN2 (1<<2) // 0x04
-#define STATUS_ROTATING (1<<1) // 0x02
-#define STATUS_ERROR (1<<0) // 0x01
-
-
+ +/* Modes flags */ +#define MODE_SPEED (1<<7) // 0x80 +#define MODE_STRSND (1<<6) // 0x40 ADPCM on/off +#define MODE_SIZE_2340 (1<<5) // 0x20 +#define MODE_SIZE_2328 (1<<4) // 0x10 +#define MODE_SIZE_2048 (0<<4) // 0x00 +#define MODE_SF (1<<3) // 0x08 channel on/off +#define MODE_REPORT (1<<2) // 0x04 +#define MODE_AUTOPAUSE (1<<1) // 0x02 +#define MODE_CDDA (1<<0) // 0x01 + +/* Status flags */ +#define STATUS_PLAY (1<<7) // 0x80 +#define STATUS_SEEK (1<<6) // 0x40 +#define STATUS_READ (1<<5) // 0x20 +#define STATUS_SHELLOPEN (1<<4) // 0x10 +#define STATUS_UNKNOWN3 (1<<3) // 0x08 +#define STATUS_UNKNOWN2 (1<<2) // 0x04 +#define STATUS_ROTATING (1<<1) // 0x02 +#define STATUS_ERROR (1<<0) // 0x01 + + // 1x = 75 sectors per second // PSXCLK = 1 sec in the ps @@ -122,21 +124,12 @@ unsigned char Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 }; static struct CdrStat stat; static struct SubQ *subq; -
-
-extern unsigned int msf2sec(char *msf);
-extern void sec2msf(unsigned int s, char *msf);
- - -extern u16 *iso_play_cdbuf; -extern u16 iso_play_bufptr; -extern long CALLBACK ISOinit(void); -extern void CALLBACK SPUirq(void); -extern SPUregisterCallback SPU_registerCallback; +#ifndef H_SPUirqAddr #define H_SPUirqAddr 0x1f801da4 #define H_SPUaddr 0x1f801da6 #define H_SPUctrl 0x1f801daa +#endif #define H_CDLeft 0x1f801db0 #define H_CDRight 0x1f801db2 @@ -165,12 +158,12 @@ extern SPUregisterCallback SPU_registerCallback; psxRegs.intCycle[PSXINT_CDRLID].sCycle = psxRegs.cycle; \ } -#define CDRPLAY_INT(eCycle) { \
- psxRegs.interrupt |= (1 << PSXINT_CDRPLAY); \
- psxRegs.intCycle[PSXINT_CDRPLAY].cycle = eCycle; \
- psxRegs.intCycle[PSXINT_CDRPLAY].sCycle = psxRegs.cycle; \
-}
-
+#define CDRPLAY_INT(eCycle) { \ + psxRegs.interrupt |= (1 << PSXINT_CDRPLAY); \ + psxRegs.intCycle[PSXINT_CDRPLAY].cycle = eCycle; \ + psxRegs.intCycle[PSXINT_CDRPLAY].sCycle = psxRegs.cycle; \ +} + #define StartReading(type, eCycle) { \ cdr.Reading = type; \ cdr.FirstSector = 1; \ @@ -193,7 +186,7 @@ extern SPUregisterCallback SPU_registerCallback; cdr.Play = FALSE; \ cdr.FastForward = 0; \ cdr.FastBackward = 0; \ - SPU_registerCallback( SPUirq ); \
+ SPU_registerCallback( SPUirq ); \ } \ } @@ -206,11 +199,11 @@ extern SPUregisterCallback SPU_registerCallback; void cdrDecodedBufferInterrupt() { - u16 buf_ptr[0x400], lcv;
-
-#if 0
- return;
-#endif
+ u16 buf_ptr[0x400], lcv; + +#if 0 + return; +#endif // ISO reader only @@ -329,7 +322,7 @@ void cdrLidSeekInterrupt() } -void Check_Shell( int Irq ) +static void Check_Shell( int Irq ) { // check case open/close if (cdr.LidCheck > 0) @@ -346,7 +339,7 @@ void Check_Shell( int Irq ) i = stat.Status; if (CDR_getStatus(&stat) != -1) { - // BIOS hangs + BIOS error messages
+ // BIOS hangs + BIOS error messages //if (stat.Type == 0xff) //cdr.Stat = DiskError; @@ -439,7 +432,7 @@ void Check_Shell( int Irq ) } -void Find_CurTrack() { +static void Find_CurTrack() { cdr.CurTrack = 0; if (CDR_getTN(cdr.ResultTN) != -1) { @@ -459,11 +452,11 @@ void Find_CurTrack() { // find next track boundary - only need m:s accuracy sect1 = cdr.SetSectorPlay[0] * 60 * 75 + cdr.SetSectorPlay[1] * 75; sect2 = cdr.ResultTD[2] * 60 * 75 + cdr.ResultTD[1] * 75; -
- // Twisted Metal 4 - psx cdda pregap (2-sec)
- // - fix in-game music
- sect2 -= 75 * 2;
-
+ + // Twisted Metal 4 - psx cdda pregap (2-sec) + // - fix in-game music + sect2 -= 75 * 2; + if( sect1 >= sect2 ) { cdr.CurTrack++; continue; @@ -486,50 +479,50 @@ static void ReadTrack( u8 *time ) { cdr.RErr = CDR_readTrack(cdr.Prev); } -
-void CDXA_Attenuation( s16 *buf, int size, int stereo )
-{
- s16 *spsound;
- s32 lc,rc;
- int i;
-
- spsound = buf;
-
-#if 0
- // mono xa attenuation
- // - Tales of Phantasia (voice meter)
- if( stereo == 0 ) {
- s16 temp[32768];
- int dst;
-
- dst = 0;
- for( i = 0; i < size; i++, dst+=2 ) {
- temp[dst+0] = spsound[i];
- temp[dst+1] = spsound[i];
- }
-
- size *= 2*2;
- memcpy( spsound, temp, size );
- }
-#endif
-
- for( i = 0; i < size / 2; i += 2 )
- {
- lc = (spsound[i+0] * cdr.AttenuatorLeft[0] + spsound[i+1] * cdr.AttenuatorRight[1]) / 128;
- rc = (spsound[i+1] * cdr.AttenuatorRight[0] + spsound[i+0] * cdr.AttenuatorLeft[1]) / 128;
-
- if( lc < -32768 ) lc = -32768;
- if( rc < -32768 ) rc = -32768;
- if( lc > 32767 ) lc = 32767;
- if( rc > 32767 ) rc = 32767;
-
- spsound[i + 0] = lc;
- spsound[i + 1] = rc;
- }
-}
-
-
-void AddIrqQueue(unsigned char irq, unsigned long ecycle) { + +static void CDXA_Attenuation( s16 *buf, int size, int stereo ) +{ + s16 *spsound; + s32 lc,rc; + int i; + + spsound = buf; + +#if 0 + // mono xa attenuation + // - Tales of Phantasia (voice meter) + if( stereo == 0 ) { + s16 temp[32768]; + int dst; + + dst = 0; + for( i = 0; i < size; i++, dst+=2 ) { + temp[dst+0] = spsound[i]; + temp[dst+1] = spsound[i]; + } + + size *= 2*2; + memcpy( spsound, temp, size ); + } +#endif + + for( i = 0; i < size / 2; i += 2 ) + { + lc = (spsound[i+0] * cdr.AttenuatorLeft[0] + spsound[i+1] * cdr.AttenuatorRight[1]) / 128; + rc = (spsound[i+1] * cdr.AttenuatorRight[0] + spsound[i+0] * cdr.AttenuatorLeft[1]) / 128; + + if( lc < -32768 ) lc = -32768; + if( rc < -32768 ) rc = -32768; + if( lc > 32767 ) lc = 32767; + if( rc > 32767 ) rc = 32767; + + spsound[i + 0] = lc; + spsound[i + 1] = rc; + } +} + + +static void AddIrqQueue(unsigned char irq, unsigned long ecycle) { cdr.Irq = irq; cdr.eCycle = ecycle; @@ -539,7 +532,7 @@ void AddIrqQueue(unsigned char irq, unsigned long ecycle) { } -void Set_Track() +static void Set_Track() { if (CDR_getTN(cdr.ResultTN) != -1) { int lcv; @@ -571,374 +564,374 @@ void Set_Track() } -static u8 fake_subq_local[3], fake_subq_real[3], fake_subq_index, fake_subq_change;
-void Create_Fake_Subq()
-{
- u8 temp_cur[3], temp_next[3], temp_start[3], pregap;
- int diff;
-
- if (CDR_getTN(cdr.ResultTN) == -1) return;
- if( cdr.CurTrack+1 <= cdr.ResultTN[1] ) {
- pregap = 150;
- if( CDR_getTD(cdr.CurTrack+1, cdr.ResultTD) == -1 ) return;
- } else {
- // last track - cd size
- pregap = 0;
- if( CDR_getTD(0, cdr.ResultTD) == -1 ) return;
- }
-
- if( cdr.Play == TRUE ) {
- temp_cur[0] = cdr.SetSectorPlay[0];
- temp_cur[1] = cdr.SetSectorPlay[1];
- temp_cur[2] = cdr.SetSectorPlay[2];
- } else {
- temp_cur[0] = btoi( cdr.Prev[0] );
- temp_cur[1] = btoi( cdr.Prev[1] );
- temp_cur[2] = btoi( cdr.Prev[2] );
- }
-
- fake_subq_real[0] = temp_cur[0];
- fake_subq_real[1] = temp_cur[1];
- fake_subq_real[2] = temp_cur[2];
-
- temp_next[0] = cdr.ResultTD[2];
- temp_next[1] = cdr.ResultTD[1];
- temp_next[2] = cdr.ResultTD[0];
-
-
- // flag- next track
- if( msf2sec(temp_cur) >= msf2sec( temp_next )-pregap ) {
- fake_subq_change = 1;
-
- cdr.CurTrack++;
-
- // end cd
- if( pregap == 0 ) StopCdda();
- }
-
- //////////////////////////////////////////////////
- //////////////////////////////////////////////////
-
- // repair
- if( cdr.CurTrack <= cdr.ResultTN[1] ) {
- if( CDR_getTD(cdr.CurTrack, cdr.ResultTD) == -1 ) return;
- } else {
- // last track - cd size
- if( CDR_getTD(0, cdr.ResultTD) == -1 ) return;
- }
-
- temp_start[0] = cdr.ResultTD[2];
- temp_start[1] = cdr.ResultTD[1];
- temp_start[2] = cdr.ResultTD[0];
-
-
-#ifdef CDR_LOG
- CDR_LOG( "CDDA FAKE SUB - %d:%d:%d / %d:%d:%d / %d:%d:%d\n",
- temp_cur[0], temp_cur[1], temp_cur[2],
- temp_start[0], temp_start[1], temp_start[2],
- temp_next[0], temp_next[1], temp_next[2]);
-#endif
-
-
-
- // local time - pregap / real
- diff = msf2sec(temp_cur) - msf2sec( temp_start );
- if( diff < 0 ) {
- fake_subq_index = 0;
-
- sec2msf( -diff, fake_subq_local );
- } else {
- fake_subq_index = 1;
-
- sec2msf( diff, fake_subq_local );
- }
-}
-
-
-void cdrPlayInterrupt_Autopause()
-{
- if ((cdr.Mode & (MODE_AUTOPAUSE|MODE_CDDA)) != (MODE_AUTOPAUSE|MODE_CDDA)) return;
-
- // Reschedule IRQ
- if ( cdr.Irq || cdr.Stat ) {
-#ifdef CDR_LOG
- CDR_LOG("=== BUSY === cdrPlayInterrupt\n");
-#endif
-
- //CDRPLAY_INT( 0x800 );
- return;
- }
-
-
- if( CDR_getStatus(&stat) == -1) return;
-
- subq = (struct SubQ *)CDR_getBufferSub();
-
- if (subq != NULL ) {
-#ifdef CDR_LOG
- CDR_LOG( "CDDA SUB - %X:%X:%X\n",
- subq->AbsoluteAddress[0], subq->AbsoluteAddress[1], subq->AbsoluteAddress[2] );
-#endif
-
- /*
- CDDA Autopause
-
- Silhouette Mirage ($3)
- Tomb Raider 1 ($7)
- */
-
- if( cdr.CurTrack < btoi( subq->TrackNumber ) ) {
-#ifdef CDR_LOG
- CDR_LOG( "CDDA STOP\n" );
-#endif
-
- // Magic the Gathering
- // - looping territory cdda
-
- // ...?
- //cdr.ResultReady = 1;
- //cdr.Stat = DataReady;
- cdr.Stat = DataEnd;
- psxHu32ref(0x1070) |= SWAP32((u32)0x4);
-
-
- StopCdda();
- }
- } else {
-#ifdef CDR_LOG___0
- CDR_LOG( "CDDA FAKE SUB - %d:%d:%d\n",
- temp_cur[0], temp_cur[1], temp_cur[2] );
-#endif
-
- //if( msf2sec(temp_cur) >= msf2sec( temp_next ) ) {
- if( fake_subq_change ) {
-#ifdef CDR_LOG
- CDR_LOG( "CDDA STOP\n" );
-#endif
-
- // Magic the Gathering
- // - looping territory cdda
-
- // ...?
- //cdr.ResultReady = 1;
- //cdr.Stat = DataReady;
- cdr.Stat = DataEnd;
- psxHu32ref(0x1070) |= SWAP32((u32)0x4);
-
-
- StopCdda();
-
- fake_subq_change = 0;
- }
- }
-}
-
-
-void cdrPlayInterrupt_Repplay()
-{
- // BIOS - HACK: Switch between local / absolute times
- static u8 report_time = 1;
-
-
- if ((cdr.Mode & (MODE_REPORT|MODE_CDDA)) != (MODE_REPORT|MODE_CDDA)) return;
-
-#ifdef CDR_LOG
- CDR_LOG("cdrRepplayInterrupt() Log: KEY END\n");
-#endif
-
- // Doom - no more cdda playing
- // - fixes boot with irq cmd reschedule
-
- // Reschedule IRQ
- if ( cdr.Irq || cdr.Stat ) {
-#ifdef CDR_LOG
- CDR_LOG("=== BUSY === cdrRepplayInterrupt\n");
-#endif
-
- //CDREPPLAY_INT( 0x800 );
- return;
- }
-
-
- memset( cdr.Result, 0, 8 );
- if( CDR_getStatus(&stat) == -1) return;
-
- cdr.Result[0] = cdr.StatP;
-
-
- subq = (struct SubQ *)CDR_getBufferSub();
- if (subq != NULL ) {
-#ifdef CDR_LOG
- CDR_LOG( "REPPLAY SUB - %X:%X:%X\n",
- subq->AbsoluteAddress[0], subq->AbsoluteAddress[1], subq->AbsoluteAddress[2] );
-#endif
-
-
- /*
- skip subQ integrity check (audio playback)
- - mainly useful for DATA LibCrypt checking
- */
- //if( SWAP16(subq->CRC) != calcCrc((unsigned char *)subq + 12, 10) )
-
- // 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;
- }
- } else {
-#ifdef CDR_LOG___0
- CDR_LOG( "REPPLAY FAKE - %d:%d:%d\n",
- temp_cur[0], temp_cur[1], temp_cur[2] );
-#endif
-
- // Rayman: check track change
- //if( msf2sec(temp_cur) >= msf2sec( temp_next ) ) {
- if( fake_subq_change ) {
-#ifdef CDR_LOG___0
- CDR_LOG( "TRACK CHANGE %d - %d %d %d ==> %d %d %d\n",
- cdr.CurTrack,
- temp_cur[0], temp_cur[1], temp_cur[2],
- temp_next[0], temp_next[1], temp_next[2] );
-#endif
-
- cdr.Result[0] |= 0x10;
-
- fake_subq_change = 0;
- }
-
-
- // track # / index #
- cdr.Result[1] = itob(cdr.CurTrack);
- cdr.Result[2] = itob(fake_subq_index);
-
- if( report_time == 0 ) {
- // absolute
- cdr.Result[3] = itob( fake_subq_real[0] );
- cdr.Result[4] = itob( fake_subq_real[1] );
- cdr.Result[5] = itob( fake_subq_real[2] );
-
- report_time = 1;
- } else {
- // local
- cdr.Result[3] = itob( fake_subq_local[0] );
- cdr.Result[4] = itob( fake_subq_local[1] );
- cdr.Result[5] = itob( fake_subq_local[2] );
-
- cdr.Result[4] |= 0x80;
-
- report_time = 0;
- }
-
- cdr.Result[6] = 0;
- cdr.Result[7] = 0;
- }
-
-
- // Rayman: Logo freeze (resultready + dataready)
- cdr.ResultReady = 1;
- cdr.Stat = DataReady;
-
- SetResultSize(8);
- psxHu32ref(0x1070) |= SWAP32((u32)0x4);
-}
-
-
-void cdrPlayInterrupt()
-{
- if( !cdr.Play ) return;
-
- //////////////////////////////////////////
- //////////////////////////////////////////
-
-#ifdef CDR_LOG
- CDR_LOG( "CDDA - %d:%d:%d\n",
- cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2] );
-#endif
-
-
- {
- u8 temp[3];
-
- temp[0] = itob(cdr.SetSectorPlay[0]);
- temp[1] = itob(cdr.SetSectorPlay[1]);
- temp[2] = itob(cdr.SetSectorPlay[2]);
-
- // get subq
- CDR_readTrack( temp );
- }
-
- if( CDR_readCDDA ) {
- CDR_readCDDA( cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2], cdr.Transfer );
-
- CDXA_Attenuation( (short *) cdr.Transfer, 2352, 1 );
- }
-
-
-
- // mute data track
- if( (Config.Cdda) ||
- (CDR_getStatus(&stat) != -1 && stat.Type == 1 && cdr.CurTrack == 1) )
- memset( cdr.Transfer, 0, CD_FRAMESIZE_RAW );
-
-
- if( SPU_playCDDAchannel)
- SPU_playCDDAchannel((short *)cdr.Transfer, CD_FRAMESIZE_RAW);
-
- CDRPLAY_INT( cdReadTime );
-
- //////////////////////////////////////////
- //////////////////////////////////////////
-
- subq = (struct SubQ *)CDR_getBufferSub();
- if (subq == NULL )
- Create_Fake_Subq();
-
- cdrPlayInterrupt_Autopause();
- cdrPlayInterrupt_Repplay();
-
- //////////////////////////////////////////
- //////////////////////////////////////////
-
- cdr.SetSectorPlay[2]++;
- if (cdr.SetSectorPlay[2] == 75) {
- cdr.SetSectorPlay[2] = 0;
- cdr.SetSectorPlay[1]++;
- if (cdr.SetSectorPlay[1] == 60) {
- cdr.SetSectorPlay[1] = 0;
- cdr.SetSectorPlay[0]++;
- }
- }
-
-
- Check_Shell(0);
-}
-
-
+static u8 fake_subq_local[3], fake_subq_real[3], fake_subq_index, fake_subq_change; +static void Create_Fake_Subq() +{ + u8 temp_cur[3], temp_next[3], temp_start[3], pregap; + int diff; + + if (CDR_getTN(cdr.ResultTN) == -1) return; + if( cdr.CurTrack+1 <= cdr.ResultTN[1] ) { + pregap = 150; + if( CDR_getTD(cdr.CurTrack+1, cdr.ResultTD) == -1 ) return; + } else { + // last track - cd size + pregap = 0; + if( CDR_getTD(0, cdr.ResultTD) == -1 ) return; + } + + if( cdr.Play == TRUE ) { + temp_cur[0] = cdr.SetSectorPlay[0]; + temp_cur[1] = cdr.SetSectorPlay[1]; + temp_cur[2] = cdr.SetSectorPlay[2]; + } else { + temp_cur[0] = btoi( cdr.Prev[0] ); + temp_cur[1] = btoi( cdr.Prev[1] ); + temp_cur[2] = btoi( cdr.Prev[2] ); + } + + fake_subq_real[0] = temp_cur[0]; + fake_subq_real[1] = temp_cur[1]; + fake_subq_real[2] = temp_cur[2]; + + temp_next[0] = cdr.ResultTD[2]; + temp_next[1] = cdr.ResultTD[1]; + temp_next[2] = cdr.ResultTD[0]; + + + // flag- next track + if( msf2sec(temp_cur) >= msf2sec( temp_next )-pregap ) { + fake_subq_change = 1; + + cdr.CurTrack++; + + // end cd + if( pregap == 0 ) StopCdda(); + } + + ////////////////////////////////////////////////// + ////////////////////////////////////////////////// + + // repair + if( cdr.CurTrack <= cdr.ResultTN[1] ) { + if( CDR_getTD(cdr.CurTrack, cdr.ResultTD) == -1 ) return; + } else { + // last track - cd size + if( CDR_getTD(0, cdr.ResultTD) == -1 ) return; + } + + temp_start[0] = cdr.ResultTD[2]; + temp_start[1] = cdr.ResultTD[1]; + temp_start[2] = cdr.ResultTD[0]; + + +#ifdef CDR_LOG + CDR_LOG( "CDDA FAKE SUB - %d:%d:%d / %d:%d:%d / %d:%d:%d\n", + temp_cur[0], temp_cur[1], temp_cur[2], + temp_start[0], temp_start[1], temp_start[2], + temp_next[0], temp_next[1], temp_next[2]); +#endif + + + + // local time - pregap / real + diff = msf2sec(temp_cur) - msf2sec( temp_start ); + if( diff < 0 ) { + fake_subq_index = 0; + + sec2msf( -diff, fake_subq_local ); + } else { + fake_subq_index = 1; + + sec2msf( diff, fake_subq_local ); + } +} + + +static void cdrPlayInterrupt_Autopause() +{ + if ((cdr.Mode & (MODE_AUTOPAUSE|MODE_CDDA)) != (MODE_AUTOPAUSE|MODE_CDDA)) return; + + // Reschedule IRQ + if ( cdr.Irq || cdr.Stat ) { +#ifdef CDR_LOG + CDR_LOG("=== BUSY === cdrPlayInterrupt\n"); +#endif + + //CDRPLAY_INT( 0x800 ); + return; + } + + + if( CDR_getStatus(&stat) == -1) return; + + subq = (struct SubQ *)CDR_getBufferSub(); + + if (subq != NULL ) { +#ifdef CDR_LOG + CDR_LOG( "CDDA SUB - %X:%X:%X\n", + subq->AbsoluteAddress[0], subq->AbsoluteAddress[1], subq->AbsoluteAddress[2] ); +#endif + + /* + CDDA Autopause + + Silhouette Mirage ($3) + Tomb Raider 1 ($7) + */ + + if( cdr.CurTrack < btoi( subq->TrackNumber ) ) { +#ifdef CDR_LOG + CDR_LOG( "CDDA STOP\n" ); +#endif + + // Magic the Gathering + // - looping territory cdda + + // ...? + //cdr.ResultReady = 1; + //cdr.Stat = DataReady; + cdr.Stat = DataEnd; + psxHu32ref(0x1070) |= SWAP32((u32)0x4); + + + StopCdda(); + } + } else { +#ifdef CDR_LOG___0 + CDR_LOG( "CDDA FAKE SUB - %d:%d:%d\n", + temp_cur[0], temp_cur[1], temp_cur[2] ); +#endif + + //if( msf2sec(temp_cur) >= msf2sec( temp_next ) ) { + if( fake_subq_change ) { +#ifdef CDR_LOG + CDR_LOG( "CDDA STOP\n" ); +#endif + + // Magic the Gathering + // - looping territory cdda + + // ...? + //cdr.ResultReady = 1; + //cdr.Stat = DataReady; + cdr.Stat = DataEnd; + psxHu32ref(0x1070) |= SWAP32((u32)0x4); + + + StopCdda(); + + fake_subq_change = 0; + } + } +} + + +static void cdrPlayInterrupt_Repplay() +{ + // BIOS - HACK: Switch between local / absolute times + static u8 report_time = 1; + + + if ((cdr.Mode & (MODE_REPORT|MODE_CDDA)) != (MODE_REPORT|MODE_CDDA)) return; + +#ifdef CDR_LOG + CDR_LOG("cdrRepplayInterrupt() Log: KEY END\n"); +#endif + + // Doom - no more cdda playing + // - fixes boot with irq cmd reschedule + + // Reschedule IRQ + if ( cdr.Irq || cdr.Stat ) { +#ifdef CDR_LOG + CDR_LOG("=== BUSY === cdrRepplayInterrupt\n"); +#endif + + //CDREPPLAY_INT( 0x800 ); + return; + } + + + memset( cdr.Result, 0, 8 ); + if( CDR_getStatus(&stat) == -1) return; + + cdr.Result[0] = cdr.StatP; + + + subq = (struct SubQ *)CDR_getBufferSub(); + if (subq != NULL ) { +#ifdef CDR_LOG + CDR_LOG( "REPPLAY SUB - %X:%X:%X\n", + subq->AbsoluteAddress[0], subq->AbsoluteAddress[1], subq->AbsoluteAddress[2] ); +#endif + + + /* + skip subQ integrity check (audio playback) + - mainly useful for DATA LibCrypt checking + */ + //if( SWAP16(subq->CRC) != calcCrc((unsigned char *)subq + 12, 10) ) + + // 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; + } + } else { +#ifdef CDR_LOG___0 + CDR_LOG( "REPPLAY FAKE - %d:%d:%d\n", + temp_cur[0], temp_cur[1], temp_cur[2] ); +#endif + + // Rayman: check track change + //if( msf2sec(temp_cur) >= msf2sec( temp_next ) ) { + if( fake_subq_change ) { +#ifdef CDR_LOG___0 + CDR_LOG( "TRACK CHANGE %d - %d %d %d ==> %d %d %d\n", + cdr.CurTrack, + temp_cur[0], temp_cur[1], temp_cur[2], + temp_next[0], temp_next[1], temp_next[2] ); +#endif + + cdr.Result[0] |= 0x10; + + fake_subq_change = 0; + } + + + // track # / index # + cdr.Result[1] = itob(cdr.CurTrack); + cdr.Result[2] = itob(fake_subq_index); + + if( report_time == 0 ) { + // absolute + cdr.Result[3] = itob( fake_subq_real[0] ); + cdr.Result[4] = itob( fake_subq_real[1] ); + cdr.Result[5] = itob( fake_subq_real[2] ); + + report_time = 1; + } else { + // local + cdr.Result[3] = itob( fake_subq_local[0] ); + cdr.Result[4] = itob( fake_subq_local[1] ); + cdr.Result[5] = itob( fake_subq_local[2] ); + + cdr.Result[4] |= 0x80; + + report_time = 0; + } + + cdr.Result[6] = 0; + cdr.Result[7] = 0; + } + + + // Rayman: Logo freeze (resultready + dataready) + cdr.ResultReady = 1; + cdr.Stat = DataReady; + + SetResultSize(8); + psxHu32ref(0x1070) |= SWAP32((u32)0x4); +} + + +void cdrPlayInterrupt() +{ + if( !cdr.Play ) return; + + ////////////////////////////////////////// + ////////////////////////////////////////// + +#ifdef CDR_LOG + CDR_LOG( "CDDA - %d:%d:%d\n", + cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2] ); +#endif + + + { + u8 temp[3]; + + temp[0] = itob(cdr.SetSectorPlay[0]); + temp[1] = itob(cdr.SetSectorPlay[1]); + temp[2] = itob(cdr.SetSectorPlay[2]); + + // get subq + CDR_readTrack( temp ); + } + + if( CDR_readCDDA ) { + CDR_readCDDA( cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2], cdr.Transfer ); + + CDXA_Attenuation( (short *) cdr.Transfer, 2352, 1 ); + } + + + + // mute data track + if( (Config.Cdda) || + (CDR_getStatus(&stat) != -1 && stat.Type == 1 && cdr.CurTrack == 1) ) + memset( cdr.Transfer, 0, CD_FRAMESIZE_RAW ); + + + if( SPU_playCDDAchannel) + SPU_playCDDAchannel((short *)cdr.Transfer, CD_FRAMESIZE_RAW); + + CDRPLAY_INT( cdReadTime ); + + ////////////////////////////////////////// + ////////////////////////////////////////// + + subq = (struct SubQ *)CDR_getBufferSub(); + if (subq == NULL ) + Create_Fake_Subq(); + + cdrPlayInterrupt_Autopause(); + cdrPlayInterrupt_Repplay(); + + ////////////////////////////////////////// + ////////////////////////////////////////// + + cdr.SetSectorPlay[2]++; + if (cdr.SetSectorPlay[2] == 75) { + cdr.SetSectorPlay[2] = 0; + cdr.SetSectorPlay[1]++; + if (cdr.SetSectorPlay[1] == 60) { + cdr.SetSectorPlay[1] = 0; + cdr.SetSectorPlay[0]++; + } + } + + + Check_Shell(0); +} + + void cdrInterrupt() { int i; unsigned char Irq = cdr.Irq; @@ -977,13 +970,13 @@ void cdrInterrupt() { break; case CdlPlay: - fake_subq_change = 0;
-
- if( cdr.Seeked == FALSE ) {
- memcpy( cdr.SetSectorPlay, cdr.SetSector, 4 );
- cdr.Seeked = TRUE;
- }
-
+ fake_subq_change = 0; + + if( cdr.Seeked == FALSE ) { + memcpy( cdr.SetSectorPlay, cdr.SetSector, 4 ); + cdr.Seeked = TRUE; + } + /* Rayman: detect track changes - fixes logo freeze @@ -1060,11 +1053,11 @@ void cdrInterrupt() { cdr.SetSectorPlay[1] = cdr.ResultTD[1]; cdr.SetSectorPlay[2] = cdr.ResultTD[0]; - // reset data
- Set_Track();
- Find_CurTrack();
- ReadTrack( cdr.SetSectorPlay );
-
+ // reset data + Set_Track(); + Find_CurTrack(); + ReadTrack( cdr.SetSectorPlay ); + //CDR_play(cdr.SetSectorPlay); } } @@ -1084,12 +1077,12 @@ void cdrInterrupt() { cdr.Stat = Acknowledge; cdr.StatP |= STATUS_PLAY; -
-
- // BIOS player - set flag again
- cdr.Play = TRUE;
- CDRPLAY_INT( cdReadTime );
+ + // BIOS player - set flag again + cdr.Play = TRUE; + + CDRPLAY_INT( cdReadTime ); break; case CdlForward: @@ -1251,30 +1244,30 @@ void cdrInterrupt() { memset(cdr.Result + 2, 0, 3 + 3); // CRC wrong, wipe out time data } } - } else {
- if( cdr.Play == FALSE ) Create_Fake_Subq();
-
-
- // track # / index #
- cdr.Result[0] = itob(cdr.CurTrack);
- cdr.Result[1] = itob(fake_subq_index);
-
- // local
- cdr.Result[2] = itob( fake_subq_local[0] );
- cdr.Result[3] = itob( fake_subq_local[1] );
- cdr.Result[4] = itob( fake_subq_local[2] );
-
- // absolute
- cdr.Result[5] = itob( fake_subq_real[0] );
- cdr.Result[6] = itob( fake_subq_real[1] );
- cdr.Result[7] = itob( fake_subq_real[2] );
- }
- - // redump.org - wipe time
- if( !cdr.Play && CheckSBI(cdr.Result+5) ) {
- memset( cdr.Result+2, 0, 6 );
- }
-
+ } else { + if( cdr.Play == FALSE ) Create_Fake_Subq(); + + + // track # / index # + cdr.Result[0] = itob(cdr.CurTrack); + cdr.Result[1] = itob(fake_subq_index); + + // local + cdr.Result[2] = itob( fake_subq_local[0] ); + cdr.Result[3] = itob( fake_subq_local[1] ); + cdr.Result[4] = itob( fake_subq_local[2] ); + + // absolute + cdr.Result[5] = itob( fake_subq_real[0] ); + cdr.Result[6] = itob( fake_subq_real[1] ); + cdr.Result[7] = itob( fake_subq_real[2] ); + } + + // redump.org - wipe time + if( !cdr.Play && CheckSBI(cdr.Result+5) ) { + memset( cdr.Result+2, 0, 6 ); + } + cdr.Stat = Acknowledge; break; @@ -1320,21 +1313,21 @@ void cdrInterrupt() { cdr.StatP |= STATUS_ROTATING; cdr.Result[0] = cdr.StatP; cdr.StatP |= STATUS_SEEK; - cdr.Stat = Acknowledge;
-
- /*
- Crusaders of Might and Magic = 0.5x-4x
- - fix cutscene speech start
-
- Eggs of Steel = 2x-?
- - fix new game
-
- Medievil = ?-4x
- - fix cutscene speech
-
- Rockman X5 = 0.5-4x
- - fix capcom logo
- */
+ cdr.Stat = Acknowledge; + + /* + Crusaders of Might and Magic = 0.5x-4x + - fix cutscene speech start + + Eggs of Steel = 2x-? + - fix new game + + Medievil = ?-4x + - fix cutscene speech + + Rockman X5 = 0.5-4x + - fix capcom logo + */ AddIrqQueue(CdlSeekL + 0x20, cdReadTime * 4); break; @@ -1345,10 +1338,10 @@ void cdrInterrupt() { cdr.Result[0] = cdr.StatP; cdr.Seeked = TRUE; cdr.Stat = Complete; -
-
- // Mega Man Legends 2: must update read cursor for getlocp
- ReadTrack( cdr.SetSector );
+ + + // Mega Man Legends 2: must update read cursor for getlocp + ReadTrack( cdr.SetSector ); break; case CdlSeekP: @@ -1357,7 +1350,7 @@ void cdrInterrupt() { cdr.Result[0] = cdr.StatP; cdr.StatP |= STATUS_SEEK; cdr.Stat = Acknowledge; - AddIrqQueue(CdlSeekP + 0x20, cdReadTime * 1);
+ AddIrqQueue(CdlSeekP + 0x20, cdReadTime * 1); break; case CdlSeekP + 0x20: @@ -1368,12 +1361,12 @@ void cdrInterrupt() { 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 );
+ // GameShark Music Player + memcpy( cdr.SetSectorPlay, cdr.SetSector, 4 ); + + // Tomb Raider 2: must update read cursor for getlocp + Find_CurTrack(); + ReadTrack( cdr.SetSectorPlay ); break; case CdlTest: @@ -1489,43 +1482,43 @@ void cdrInterrupt() { case READ_ACK: if (!cdr.Reading) return; -
- // Fighting Force 2 - update subq time immediately
- // - fixes new game
- ReadTrack( cdr.SetSector );
-
-
- // Crusaders of Might and Magic - update getlocl now
- // - fixes cutscene speech
- {
- u8 *buf = CDR_getBuffer();
- memcpy(cdr.Transfer, buf, 8);
- }
-
-
- /*
- Duke Nukem: Land of the Babes - seek then delay read for one frame
- - fixes cutscenes
- */
-
+ + // Fighting Force 2 - update subq time immediately + // - fixes new game + ReadTrack( cdr.SetSector ); + + + // Crusaders of Might and Magic - update getlocl now + // - fixes cutscene speech + { + u8 *buf = CDR_getBuffer(); + memcpy(cdr.Transfer, buf, 8); + } + + + /* + Duke Nukem: Land of the Babes - seek then delay read for one frame + - fixes cutscenes + */ + if (!cdr.Seeked) { cdr.Seeked = TRUE; cdr.StatP |= STATUS_SEEK; - cdr.StatP &= ~STATUS_READ;
-
- // Crusaders of Might and Magic - use short time
- // - fix cutscene speech (startup)
-
- // ??? - use more accurate seek time later
- CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime * 1);
- } else {
- cdr.StatP |= STATUS_READ;
- cdr.StatP &= ~STATUS_SEEK;
-
- CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime * 1);
- }
-
+ cdr.StatP &= ~STATUS_READ; + + // Crusaders of Might and Magic - use short time + // - fix cutscene speech (startup) + + // ??? - use more accurate seek time later + CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime * 1); + } else { + cdr.StatP |= STATUS_READ; + cdr.StatP &= ~STATUS_SEEK; + + CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime * 1); + } + SetResultSize(1); cdr.StatP |= STATUS_ROTATING; cdr.Result[0] = cdr.StatP; @@ -1599,52 +1592,52 @@ void cdrReadInterrupt() { if ((!cdr.Muted) && (cdr.Mode & MODE_STRSND) && (!Config.Xa) && (cdr.FirstSector != -1)) { // CD-XA // Firemen 2: Multi-XA files - briefings, cutscenes - if( cdr.FirstSector == 1 && (cdr.Mode & MODE_SF)==0 ) {
- cdr.File = cdr.Transfer[4 + 0];
- cdr.Channel = cdr.Transfer[4 + 1];
- }
-
- if((cdr.Transfer[4 + 2] & 0x4) &&
- (cdr.Transfer[4 + 1] == cdr.Channel) &&
- (cdr.Transfer[4 + 0] == cdr.File)) {
- int ret = xa_decode_sector(&cdr.Xa, cdr.Transfer+4, cdr.FirstSector);
- - if (!ret) {
- int xa_type;
-
-#if 0
- // save - set only for FirstSector
- xa_type = cdr.Xa.stereo;
-
-
- // Duke Nukem - Time to Kill - speech, music volume control
- // Tekken 3 - post-match fade out
- if( cdr.Xa.stereo == 0 )
- CDXA_Attenuation( cdr.Xa.pcm, cdr.Xa.nsamples * 2, cdr.Xa.stereo );
- else
- CDXA_Attenuation( cdr.Xa.pcm, cdr.Xa.nsamples * 4, cdr.Xa.stereo );
-
-
- // fix mono xa attenuation
- if( cdr.Xa.stereo == 0 ) cdr.Xa.stereo = 1;
-#endif
+ if( cdr.FirstSector == 1 && (cdr.Mode & MODE_SF)==0 ) { + cdr.File = cdr.Transfer[4 + 0]; + cdr.Channel = cdr.Transfer[4 + 1]; + } + + if((cdr.Transfer[4 + 2] & 0x4) && + (cdr.Transfer[4 + 1] == cdr.Channel) && + (cdr.Transfer[4 + 0] == cdr.File)) { + int ret = xa_decode_sector(&cdr.Xa, cdr.Transfer+4, cdr.FirstSector); + + if (!ret) { +#if 0 + int xa_type; + + // save - set only for FirstSector + xa_type = cdr.Xa.stereo; + + + // Duke Nukem - Time to Kill - speech, music volume control + // Tekken 3 - post-match fade out + if( cdr.Xa.stereo == 0 ) + CDXA_Attenuation( cdr.Xa.pcm, cdr.Xa.nsamples * 2, cdr.Xa.stereo ); + else + CDXA_Attenuation( cdr.Xa.pcm, cdr.Xa.nsamples * 4, cdr.Xa.stereo ); + + + // fix mono xa attenuation + if( cdr.Xa.stereo == 0 ) cdr.Xa.stereo = 1; +#endif SPU_playADPCMchannel(&cdr.Xa); cdr.FirstSector = 0; -
-
-#if 0
- cdr.Xa.stereo = xa_type;
-#endif
-
+ +#if 0 + cdr.Xa.stereo = xa_type; +#endif + + #if 0 - // Crash Team Racing: music, speech
- // - done using cdda decoded buffer (spu irq)
+ // Crash Team Racing: music, speech + // - done using cdda decoded buffer (spu irq) // - don't do here // signal ADPCM data ready - psxHu32ref(0x1070) |= SWAP32((u32)0x200);
+ psxHu32ref(0x1070) |= SWAP32((u32)0x200); #endif } else cdr.FirstSector = -1; @@ -1677,9 +1670,9 @@ void cdrReadInterrupt() { } /* - Croc 2: $40 - only FORM1 (*)
- Judge Dredd: $C8 - only FORM1 (*)
- Sim Theme Park - no adpcm at all (zero)
+ Croc 2: $40 - only FORM1 (*) + Judge Dredd: $C8 - only FORM1 (*) + Sim Theme Park - no adpcm at all (zero) */ if( (cdr.Mode & MODE_STRSND) == 0 || (cdr.Transfer[4+2] & 0x4) != 0x4 ) { @@ -1689,7 +1682,7 @@ void cdrReadInterrupt() { // Rockman X5 - no music restart problem cdr.Stat = NoIntr; } - psxHu32ref(0x1070) |= SWAP32((u32)0x4);
+ psxHu32ref(0x1070) |= SWAP32((u32)0x4); Check_Shell(0); } @@ -1746,13 +1739,13 @@ void cdrWrite0(unsigned char rt) { // Tekken: CDXA fade-out else if( rt == 2 ) { - //cdr.AttenuatorLeft[0] = 0;
- //cdr.AttenuatorLeft[1] = 0;
+ //cdr.AttenuatorLeft[0] = 0; + //cdr.AttenuatorLeft[1] = 0; } else if( rt == 3 ) { - // Tekken 3 - character menu (don't do this!)
- //cdr.AttenuatorRight[0] = 0;
- //cdr.AttenuatorRight[1] = 0;
+ // Tekken 3 - character menu (don't do this!) + //cdr.AttenuatorRight[0] = 0; + //cdr.AttenuatorRight[1] = 0; } } @@ -1782,7 +1775,7 @@ void cdrWrite1(unsigned char rt) { // Tekken: CDXA fade-out if( (cdr.Ctrl & 3) == 3 ) { - cdr.AttenuatorRight[0] = rt;
+ cdr.AttenuatorRight[0] = rt; } @@ -1813,8 +1806,8 @@ void cdrWrite1(unsigned char rt) { case CdlNop: cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr;
-
+ cdr.Stat = NoIntr; + // Twisted Metal 3 - fix music AddIrqQueue(cdr.Cmd, 0x800); break; @@ -1934,7 +1927,7 @@ void cdrWrite1(unsigned char rt) { /* GameShark CD Player: save time for resume - Twisted Metal - World Tour: don't mix Setloc / CdlPlay cursors
+ Twisted Metal - World Tour: don't mix Setloc / CdlPlay cursors */ StopCdda(); @@ -1959,8 +1952,8 @@ void cdrWrite1(unsigned char rt) { cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); - // Duke Nukem - Time to Kill
- // - do not directly set cd-xa volume
+ // Duke Nukem - Time to Kill + // - do not directly set cd-xa volume //SPU_writeRegister( H_CDLeft, 0x0000 ); //SPU_writeRegister( H_CDRight, 0x0000 ); break; @@ -1971,8 +1964,8 @@ void cdrWrite1(unsigned char rt) { cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); - // Duke Nukem - Time to Kill
- // - do not directly set cd-xa volume
+ // Duke Nukem - Time to Kill + // - do not directly set cd-xa volume //SPU_writeRegister( H_CDLeft, 0x7f00 ); //SPU_writeRegister( H_CDRight, 0x7f00 ); break; @@ -2016,13 +2009,13 @@ void cdrWrite1(unsigned char rt) { case CdlGetlocP: cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr;
+ cdr.Stat = NoIntr; // GameShark CDX / Lite Player: pretty narrow time window // - doesn't always work due to time inprecision - //AddIrqQueue(cdr.Cmd, 0x28);
-
- // Tomb Raider 2 - cdda
+ //AddIrqQueue(cdr.Cmd, 0x28); + + // Tomb Raider 2 - cdda AddIrqQueue(cdr.Cmd, 0x40); break; @@ -2046,21 +2039,21 @@ void cdrWrite1(unsigned char rt) { cdr.Ctrl |= 0x80; cdr.Stat = NoIntr; AddIrqQueue(cdr.Cmd, 0x800); -
- StopCdda();
- StopReading();
-
+ + StopCdda(); + StopReading(); + break; case CdlSeekP: // ((u32 *)cdr.SetSectorSeek)[0] = ((u32 *)cdr.SetSector)[0]; cdr.Ctrl |= 0x80; cdr.Stat = NoIntr; -
- // Tomb Raider 2 - reset cdda
- StopCdda();
- StopReading();
-
+ + // Tomb Raider 2 - reset cdda + StopCdda(); + StopReading(); + AddIrqQueue(cdr.Cmd, 0x800); break; @@ -2131,10 +2124,10 @@ void cdrWrite2(unsigned char rt) { // Tekken: CDXA fade-out if( (cdr.Ctrl & 3) == 2 ) { - cdr.AttenuatorLeft[0] = rt;
+ cdr.AttenuatorLeft[0] = rt; } else if( (cdr.Ctrl & 3) == 3 ) { - cdr.AttenuatorRight[1] = rt;
+ cdr.AttenuatorRight[1] = rt; } @@ -2180,14 +2173,14 @@ void cdrWrite3(unsigned char rt) { // Tekken: CDXA fade-out if( (cdr.Ctrl & 3) == 2 ) { - cdr.AttenuatorLeft[1] = rt;
+ cdr.AttenuatorLeft[1] = rt; } else if( (cdr.Ctrl & 3) == 3 && rt == 0x20 ) { -#ifdef CDR_LOG
- CDR_LOG( "CD-XA Volume: %X %X | %X %X\n",
- cdr.AttenuatorLeft[0], cdr.AttenuatorLeft[1],
- cdr.AttenuatorRight[0], cdr.AttenuatorRight[1] );
-#endif
+#ifdef CDR_LOG + CDR_LOG( "CD-XA Volume: %X %X | %X %X\n", + cdr.AttenuatorLeft[0], cdr.AttenuatorLeft[1], + cdr.AttenuatorRight[0], cdr.AttenuatorRight[1] ); +#endif } @@ -2212,23 +2205,23 @@ void cdrWrite3(unsigned char rt) { cdr.Irq = 0; return; } -
+ #if 1 - if (cdr.Reading && !cdr.ResultReady) {
- CDREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime);
- }
-#else
- // XA streaming - incorrect timing because of this reschedule
- // - Final Fantasy Tactics
- // - various other games
-
- /*
- if (cdr.Reading && !cdr.ResultReady) {
- CDREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime);
- }
- */
-#endif
-
+ if (cdr.Reading && !cdr.ResultReady) { + CDREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime); + } +#else + // XA streaming - incorrect timing because of this reschedule + // - Final Fantasy Tactics + // - various other games + + /* + if (cdr.Reading && !cdr.ResultReady) { + CDREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime); + } + */ +#endif + return; } @@ -2236,9 +2229,9 @@ void cdrWrite3(unsigned char rt) { cdr.Readed = 1; cdr.pTransfer = cdr.Transfer; - switch (cdr.Mode & (MODE_SIZE_2340|MODE_SIZE_2328)) {
- case MODE_SIZE_2328:
- case MODE_SIZE_2048:
+ switch (cdr.Mode & (MODE_SIZE_2340|MODE_SIZE_2328)) { + case MODE_SIZE_2328: + case MODE_SIZE_2048: cdr.pTransfer += 12; break; @@ -2254,7 +2247,7 @@ void cdrWrite3(unsigned char rt) { void psxDma3(u32 madr, u32 bcr, u32 chcr) { u32 cdsize; - u8 *ptr, *cdwrap_ptr;
+ u8 *ptr; #ifdef CDR_LOG CDR_LOG("psxDma3() Log: *** DMA 3 *** %x addr = %x size = %x\n", chcr, madr, bcr); @@ -2272,18 +2265,18 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { cdsize = (bcr & 0xffff) * 4; - // Ape Escape: bcr = 0001 / 0000
- // - fix boot
- if( cdsize == 0 )
- {
- switch (cdr.Mode & (MODE_SIZE_2340|MODE_SIZE_2328)) {
- case MODE_SIZE_2340: cdsize = 2340; break;
- case MODE_SIZE_2328: cdsize = 2328; break;
- case MODE_SIZE_2048: cdsize = 2048; break;
- }
- }
-
-
+ // Ape Escape: bcr = 0001 / 0000 + // - fix boot + if( cdsize == 0 ) + { + switch (cdr.Mode & (MODE_SIZE_2340|MODE_SIZE_2328)) { + case MODE_SIZE_2340: cdsize = 2340; break; + case MODE_SIZE_2328: cdsize = 2328; break; + case MODE_SIZE_2048: cdsize = 2048; break; + } + } + + ptr = (u8 *)PSXM(madr); if (ptr == NULL) { #ifdef CPU_LOG @@ -2292,8 +2285,8 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { break; } -
-#if 1
+ +#if 1 /* GS CDX: Enhancement CD crash - Setloc 0:0:0 @@ -2313,70 +2306,70 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { psxCpu->Clear(madr, cdsize / 4); cdr.pTransfer += cdsize; -#else
- cdwrap_ptr = cdr.Transfer;
- switch (cdr.Mode & (MODE_SIZE_2340|MODE_SIZE_2328)) {
- case MODE_SIZE_2340: cdwrap_ptr += 2340; break;
- case MODE_SIZE_2328: cdwrap_ptr += 12 + 2328; break;
- case MODE_SIZE_2048: cdwrap_ptr += 12 + 2048; break;
- }
-
-
- // fast copy - no wrap
- if( cdr.pTransfer + cdsize <= cdwrap_ptr ) {
- memcpy(ptr, cdr.pTransfer, cdsize);
-
- psxCpu->Clear(madr, cdsize / 4);
- cdr.pTransfer += cdsize;
- } else {
- int lcv;
-
- /*
- CDROM wrapping
-
- Ape Escape - used several times
- Gameshark Lite - opening movie
-
- Gameshark CDX: enhancement CD patcher
- - calls CdlPlay @ 0:2:0
- - spams DMA3 and overruns buffer
- */
-
- for( lcv = 0; lcv < cdsize; lcv++ )
- {
- // wrap cdrom ptr
- if( cdr.pTransfer == cdwrap_ptr ) {
- switch (cdr.Mode & (MODE_SIZE_2340|MODE_SIZE_2328)) {
- case MODE_SIZE_2328:
- case MODE_SIZE_2048:
- cdr.pTransfer = cdr.Transfer + 12;
- break;
-
- case MODE_SIZE_2340:
- cdr.pTransfer = cdr.Transfer + 0;
- break;
- }
- }
-
-
- *(ptr+lcv) = *cdr.pTransfer;
-
- cdr.pTransfer++;
- }
-
-
- psxCpu->Clear(madr, cdsize / 4);
- }
-#endif
+#else + u8 *cdwrap_ptr = cdr.Transfer; + switch (cdr.Mode & (MODE_SIZE_2340|MODE_SIZE_2328)) { + case MODE_SIZE_2340: cdwrap_ptr += 2340; break; + case MODE_SIZE_2328: cdwrap_ptr += 12 + 2328; break; + case MODE_SIZE_2048: cdwrap_ptr += 12 + 2048; break; + } + + + // fast copy - no wrap + if( cdr.pTransfer + cdsize <= cdwrap_ptr ) { + memcpy(ptr, cdr.pTransfer, cdsize); + + psxCpu->Clear(madr, cdsize / 4); + cdr.pTransfer += cdsize; + } else { + int lcv; + + /* + CDROM wrapping + + Ape Escape - used several times + Gameshark Lite - opening movie + + Gameshark CDX: enhancement CD patcher + - calls CdlPlay @ 0:2:0 + - spams DMA3 and overruns buffer + */ + + for( lcv = 0; lcv < cdsize; lcv++ ) + { + // wrap cdrom ptr + if( cdr.pTransfer == cdwrap_ptr ) { + switch (cdr.Mode & (MODE_SIZE_2340|MODE_SIZE_2328)) { + case MODE_SIZE_2328: + case MODE_SIZE_2048: + cdr.pTransfer = cdr.Transfer + 12; + break; + + case MODE_SIZE_2340: + cdr.pTransfer = cdr.Transfer + 0; + break; + } + } + + + *(ptr+lcv) = *cdr.pTransfer; + + cdr.pTransfer++; + } + + + psxCpu->Clear(madr, cdsize / 4); + } +#endif // burst vs normal - if( chcr == 0x11400100 ) {
+ if( chcr == 0x11400100 ) { #if 1 - CDRDMA_INT( (cdsize/4) / 4 );
-#else
- // Experimental burst dma transfer (0.333x max)
- CDRDMA_INT( (cdsize/4) / 3 );
+ CDRDMA_INT( (cdsize/4) / 4 ); +#else + // Experimental burst dma transfer (0.333x max) + CDRDMA_INT( (cdsize/4) / 3 ); #endif } else if( chcr == 0x11000000 ) { @@ -2405,30 +2398,30 @@ void cdrReset() { memset(&cdr, 0, sizeof(cdr)); cdr.CurTrack = 1; cdr.File = 1; - cdr.Channel = 1;
-
-#if 0
- // BIOS player - default values
- cdr.AttenuatorLeft[0] = 0x80;
- cdr.AttenuatorLeft[1] = 0x00;
- cdr.AttenuatorRight[0] = 0x80;
- cdr.AttenuatorRight[1] = 0x00;
-#endif
+ cdr.Channel = 1; + +#if 0 + // BIOS player - default values + cdr.AttenuatorLeft[0] = 0x80; + cdr.AttenuatorLeft[1] = 0x00; + cdr.AttenuatorRight[0] = 0x80; + cdr.AttenuatorRight[1] = 0x00; +#endif } int cdrFreeze(gzFile f, int Mode) { uintptr_t tmp; -
-
- if( Mode == 0 ) {
- StopCdda();
- }
-
-
+ + + if( Mode == 0 ) { + StopCdda(); + } + + gzfreeze(&cdr, sizeof(cdr)); -
-
+ + if (Mode == 1) tmp = cdr.pTransfer - cdr.Transfer; @@ -2442,9 +2435,9 @@ int cdrFreeze(gzFile f, int Mode) { void LidInterrupt() { cdr.LidCheck = 0x20; // start checker -
- CDRLID_INT( cdReadTime * 3 );
-
+ + CDRLID_INT( cdReadTime * 3 ); + // generate interrupt if none active - open or close if (cdr.Irq == 0 || cdr.Irq == 0xff) { cdr.Ctrl |= 0x80; |
