X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fcdrom.c;h=878559859473ff083ff36f2e9ab975783f454d87;hp=142c1e205df0c7ac2023d88be26e689f6021a51e;hb=50b13be9826da8433b39bd7d02cce2422f91cf0c;hpb=2f24625423d65f64e835905223b61352233bd111 diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index 142c1e20..87855985 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -539,6 +539,7 @@ static void Create_Fake_Subq() static void cdrPlayInterrupt_Autopause() { struct SubQ *subq = (struct SubQ *)CDR_getBufferSub(); + int track_changed = 0; if (subq != NULL ) { #ifdef CDR_LOG CDR_LOG( "CDDA SUB - %X:%X:%X\n", @@ -552,8 +553,8 @@ static void cdrPlayInterrupt_Autopause() Tomb Raider 1 ($7) */ - if( cdr.CurTrack >= btoi( subq->TrackNumber ) ) - return; + if( cdr.CurTrack < btoi( subq->TrackNumber ) ) + track_changed = 1; } else { Create_Fake_Subq(); #ifdef CDR_LOG___0 @@ -561,13 +562,11 @@ static void cdrPlayInterrupt_Autopause() fake_subq_real[0], fake_subq_real[1], fake_subq_real[2] ); #endif - if( !fake_subq_change ) - return; - + track_changed = fake_subq_change; fake_subq_change = 0; } - if (cdr.Mode & MODE_AUTOPAUSE) { + if ((cdr.Mode & MODE_AUTOPAUSE) && track_changed) { #ifdef CDR_LOG CDR_LOG( "CDDA STOP\n" ); #endif @@ -584,11 +583,6 @@ static void cdrPlayInterrupt_Autopause() StopCdda(); } if (cdr.Mode & MODE_REPORT) { - // rearmed note: PCSX-Reloaded does this for every sector, - // but we try to get away with only track change here. - memset( cdr.Result, 0, 8 ); - cdr.Result[0] |= 0x10; - if (subq != NULL) { #ifdef CDR_LOG CDR_LOG( "REPPLAY SUB - %X:%X:%X\n", @@ -596,6 +590,10 @@ static void cdrPlayInterrupt_Autopause() #endif cdr.CurTrack = btoi( subq->TrackNumber ); + if (subq->AbsoluteAddress[2] & 0xf) + return; + + cdr.Result[0] = cdr.StatP; // BIOS CD Player: data already BCD format cdr.Result[1] = subq->TrackNumber; cdr.Result[2] = subq->IndexNumber; @@ -609,6 +607,10 @@ static void cdrPlayInterrupt_Autopause() fake_subq_real[0], fake_subq_real[1], fake_subq_real[2] ); #endif + if (fake_subq_real[2] & 0xf) + return; + + cdr.Result[0] = cdr.StatP; // track # / index # cdr.Result[1] = itob(cdr.CurTrack); cdr.Result[2] = itob(fake_subq_index); @@ -709,11 +711,12 @@ void cdrInterrupt() { Wild 9: skip PREGAP + starting accurate SubQ - plays tracks without retry play */ + /* unneeded with correct cdriso? Set_Track(); + */ Find_CurTrack(); ReadTrack( cdr.SetSectorPlay ); - // GameShark CD Player: Calls 2x + Play 2x if( cdr.FastBackward || cdr.FastForward ) { if( cdr.FastForward ) cdr.FastForward--; @@ -1216,13 +1219,15 @@ void cdrInterrupt() { // - fixes cutscene speech { u8 *buf = CDR_getBuffer(); - memcpy(cdr.Transfer, buf, 8); + 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) { @@ -1327,6 +1332,23 @@ void cdrReadInterrupt() { int ret = xa_decode_sector(&cdr.Xa, cdr.Transfer+4, cdr.FirstSector); if (!ret) { + // only handle attenuator basic channel switch for now + if (cdr.Xa.stereo) { + int i; + if ((cdr.AttenuatorLeft[0] | cdr.AttenuatorLeft[1]) + && !(cdr.AttenuatorRight[0] | cdr.AttenuatorRight[1])) + { + for (i = 0; i < cdr.Xa.nsamples; i++) + cdr.Xa.pcm[i*2 + 1] = cdr.Xa.pcm[i*2]; + } + else if (!(cdr.AttenuatorLeft[0] | cdr.AttenuatorLeft[1]) + && (cdr.AttenuatorRight[0] | cdr.AttenuatorRight[1])) + { + for (i = 0; i < cdr.Xa.nsamples; i++) + cdr.Xa.pcm[i*2] = cdr.Xa.pcm[i*2 + 1]; + } + } + SPU_playADPCMchannel(&cdr.Xa); cdr.FirstSector = 0; @@ -1428,7 +1450,7 @@ void cdrWrite0(unsigned char rt) { #ifdef CDR_LOG CDR_LOG("cdrWrite0() Log: CD0 write: %x\n", rt); #endif - cdr.Ctrl = rt | (cdr.Ctrl & ~0x3); + cdr.Ctrl = (rt & 3) | (cdr.Ctrl & ~3); if (rt == 0) { cdr.ParamP = 0; @@ -1454,6 +1476,7 @@ unsigned char cdrRead1(void) { } void cdrWrite1(unsigned char rt) { + char set_loc[3]; int i; #ifdef CDR_LOG @@ -1463,7 +1486,7 @@ void cdrWrite1(unsigned char rt) { // Tekken: CDXA fade-out if( (cdr.Ctrl & 3) == 3 ) { - //cdr.AttenuatorRight[0] = rt; + cdr.AttenuatorRight[0] = rt; } @@ -1483,7 +1506,7 @@ void cdrWrite1(unsigned char rt) { } #endif - if (cdr.Ctrl & 0x1) return; + if (cdr.Ctrl & 0x3) return; switch (cdr.Cmd) { case CdlSync: @@ -1502,9 +1525,12 @@ void cdrWrite1(unsigned char rt) { case CdlSetloc: StopReading(); - cdr.Seeked = FALSE; for (i = 0; i < 3; i++) - cdr.SetSector[i] = btoi(cdr.Param[i]); + set_loc[i] = btoi(cdr.Param[i]); + i = abs(msf2sec(cdr.SetSector) - msf2sec(set_loc)); + if (i > 16) + cdr.Seeked = FALSE; + memcpy(cdr.SetSector, set_loc, 3); cdr.SetSector[3] = 0; /* @@ -1815,10 +1841,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; } @@ -1835,7 +1861,7 @@ void cdrWrite2(unsigned char rt) { cdr.Reg2 = rt; break; } - } else if (!(cdr.Ctrl & 0x1) && cdr.ParamP < 8) { + } else if (!(cdr.Ctrl & 0x3) && cdr.ParamP < 8) { cdr.Param[cdr.ParamP++] = rt; cdr.ParamC++; } @@ -1860,7 +1886,7 @@ void cdrWrite3(unsigned char rt) { #ifdef CDR_LOG CDR_LOG("cdrWrite3() Log: CD3 write: %x\n", rt); #endif -/* + // Tekken: CDXA fade-out if( (cdr.Ctrl & 3) == 2 ) { cdr.AttenuatorLeft[1] = rt; @@ -1872,7 +1898,7 @@ void cdrWrite3(unsigned char rt) { cdr.AttenuatorRight[0], cdr.AttenuatorRight[1] ); #endif } -*/ + // GameShark CDX CD Player: Irq timing mania if( rt == 0 && @@ -1888,7 +1914,7 @@ void cdrWrite3(unsigned char rt) { } - if (rt == 0x07 && cdr.Ctrl & 0x1) { + if (rt == 0x07 && (cdr.Ctrl & 3) == 1) { cdr.Stat = 0; if (cdr.Irq == 0xff) { @@ -1900,15 +1926,20 @@ void cdrWrite3(unsigned char rt) { // - Final Fantasy Tactics // - various other games - if (cdr.Irq) // rearmed guesswork hack if (cdr.Reading && !cdr.ResultReady) { - CDREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime); + int left = psxRegs.intCycle[PSXINT_CDREAD].sCycle + psxRegs.intCycle[PSXINT_CDREAD].cycle - psxRegs.cycle; + int time = (cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime; + if (Config.CdrReschedule != 2) + if (left < time / 2 || Config.CdrReschedule) { // rearmed guesswork hack + //printf("-- resched %d -> %d\n", left, time); + CDREAD_INT(time); + } } return; } - if (rt == 0x80 && !(cdr.Ctrl & 0x1) && cdr.Readed == 0) { + if (rt == 0x80 && !(cdr.Ctrl & 0x3) && cdr.Readed == 0) { cdr.Readed = 1; cdr.pTransfer = cdr.Transfer; @@ -1930,6 +1961,7 @@ void cdrWrite3(unsigned char rt) { void psxDma3(u32 madr, u32 bcr, u32 chcr) { u32 cdsize; + int size; u8 *ptr; #ifdef CDR_LOG @@ -1974,15 +2006,12 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { - CdlPlay - Spams DMA3 and gets buffer overrun */ - - if( (cdr.pTransfer-cdr.Transfer) + cdsize > 2352 ) - { - // avoid crash - probably should wrap here - //memcpy(ptr, cdr.pTransfer, cdsize); - } - else + size = CD_FRAMESIZE_RAW - (cdr.pTransfer - cdr.Transfer); + if (size > cdsize) + size = cdsize; + if (size > 0) { - memcpy(ptr, cdr.pTransfer, cdsize); + memcpy(ptr, cdr.pTransfer, size); } psxCpu->Clear(madr, cdsize / 4); @@ -2011,8 +2040,11 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { void cdrDmaInterrupt() { - HW_DMA3_CHCR &= SWAP32(~0x01000000); - DMA_INTERRUPT(3); + if (HW_DMA3_CHCR & SWAP32(0x01000000)) + { + HW_DMA3_CHCR &= SWAP32(~0x01000000); + DMA_INTERRUPT(3); + } } void cdrReset() { @@ -2020,6 +2052,12 @@ void cdrReset() { cdr.CurTrack = 1; cdr.File = 1; cdr.Channel = 1; + + // BIOS player - default values + cdr.AttenuatorLeft[0] = 0x80; + cdr.AttenuatorLeft[1] = 0x00; + cdr.AttenuatorRight[0] = 0x80; + cdr.AttenuatorRight[1] = 0x00; } int cdrFreeze(gzFile f, int Mode) { @@ -2037,9 +2075,13 @@ int cdrFreeze(gzFile f, int Mode) { gzfreeze(&tmp, sizeof(tmp)); - if (Mode == 0) + if (Mode == 0) { cdr.pTransfer = cdr.Transfer + tmp; + if (cdr.Play && !Config.Cdda) + CDR_play(cdr.SetSectorPlay); + } + return 0; }