X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fcdrom.c;h=5ea0e3d4487b77ae5b52eaf7ab7b98f360cb5b69;hp=eebd8edcb6e744d78a46ddec34c571b05fbfc8e1;hb=2d5ca6c0ed5b30a57a7eebc263ea0a624c33df57;hpb=94c118c3c7a031500d0d1b2ede9d85124239b323 diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index eebd8edc..5ea0e3d4 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -78,8 +78,6 @@ static unsigned char *pTransfer; #define CdlReset 28 #define CdlReadToc 30 -/* don't set 255, it's reserved */ - char *CmdName[0x100]= { "CdlSync", "CdlNop", "CdlSetloc", "CdlPlay", "CdlForward", "CdlBackward", "CdlReadN", "CdlStandby", @@ -136,7 +134,6 @@ unsigned char Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 }; enum seeked_state { SEEK_PENDING = 0, SEEK_DONE = 1, - SEEK_DOING_CMD = 2, }; static struct CdrStat stat; @@ -423,7 +420,7 @@ static void ReadTrack( u8 *time ) { static void AddIrqQueue(unsigned char irq, unsigned long ecycle) { - if (cdr.Irq != 0 && cdr.Irq != 0xff) + if (cdr.Irq != 0) CDR_LOG_I("cdr: override cmd %02x -> %02x\n", cdr.Irq, irq); cdr.Irq = irq; @@ -432,37 +429,6 @@ static void AddIrqQueue(unsigned char irq, unsigned long ecycle) { CDR_INT(ecycle); } - -void Set_Track() -{ - if (CDR_getTN(cdr.ResultTN) != -1) { - int lcv; - - for( lcv = 1; lcv < cdr.ResultTN[1]; lcv++ ) { - if (CDR_getTD((u8)(lcv), cdr.ResultTD) != -1) { - CDR_LOG( "settrack %d %d %d | %d %d %d | %d\n", - cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2], - cdr.ResultTD[2], cdr.ResultTD[1], cdr.ResultTD[0], - cdr.CurTrack ); - - // check if time matches track start (only need min, sec accuracy) - // - m:s:f vs f:s:m - if( cdr.SetSectorPlay[0] == cdr.ResultTD[2] && - cdr.SetSectorPlay[1] == cdr.ResultTD[1] ) { - // skip pregap frames - if( cdr.SetSectorPlay[2] < cdr.ResultTD[0] ) - cdr.SetSectorPlay[2] = cdr.ResultTD[0]; - - break; - } - else if( cdr.SetSectorPlay[0] < cdr.ResultTD[2] ) - break; - } - } - } -} - - static u8 fake_subq_local[3], fake_subq_real[3], fake_subq_index, fake_subq_change; static void Create_Fake_Subq() { @@ -550,12 +516,6 @@ static void cdrPlayInterrupt_Autopause() struct SubQ *subq = (struct SubQ *)CDR_getBufferSub(); int track_changed = 0; if (subq != NULL ) { - // update subq - ReadTrack( cdr.SetSectorPlay ); - - CDR_LOG( "CDDA SUB - %X:%X:%X\n", - subq->AbsoluteAddress[0], subq->AbsoluteAddress[1], subq->AbsoluteAddress[2] ); - /* CDDA Autopause @@ -568,10 +528,6 @@ static void cdrPlayInterrupt_Autopause() if( cdr.CurTrack + 1 == btoi( subq->TrackNumber ) ) track_changed = 1; } else { - Create_Fake_Subq(); - CDR_LOG( "CDDA FAKE SUB - %d:%d:%d\n", - fake_subq_real[0], fake_subq_real[1], fake_subq_real[2] ); - track_changed = fake_subq_change; fake_subq_change = 0; } @@ -638,7 +594,7 @@ static void cdrPlayInterrupt_Autopause() // also handles seek void cdrPlayInterrupt() { - if (cdr.Seeked == SEEK_DOING_CMD) { + if (cdr.Seeked == SEEK_PENDING) { if (cdr.Stat) { CDR_LOG_I("cdrom: seek stat hack\n"); CDRMISC_INT(0x1000); @@ -648,24 +604,25 @@ void cdrPlayInterrupt() cdr.StatP |= STATUS_ROTATING; cdr.StatP &= ~STATUS_SEEK; cdr.Result[0] = cdr.StatP; - if (cdr.Irq == 0 || cdr.Irq == 0xff) { + cdr.Seeked = SEEK_DONE; + if (cdr.Irq == 0) { cdr.Stat = Complete; setIrq(); } - 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); - } + memcpy(cdr.SetSectorPlay, cdr.SetSector, 4); + Find_CurTrack(); + ReadTrack(cdr.SetSectorPlay); } + // update for CdlGetlocP/autopause + struct SubQ *subq = (struct SubQ *)CDR_getBufferSub(); + if (subq != NULL) + // update subq + ReadTrack(cdr.SetSectorPlay); + else + Create_Fake_Subq(); + if (!cdr.Play) return; CDR_LOG( "CDDA - %d:%d:%d\n", @@ -673,7 +630,7 @@ void cdrPlayInterrupt() CDRMISC_INT( cdReadTime ); - if (!cdr.Irq && !cdr.Stat && (cdr.Mode & MODE_CDDA) && (cdr.Mode & (MODE_AUTOPAUSE|MODE_REPORT))) + if (!cdr.Irq && !cdr.Stat && (cdr.Mode & (MODE_AUTOPAUSE|MODE_REPORT))) cdrPlayInterrupt_Autopause(); cdr.SetSectorPlay[2]++; @@ -701,7 +658,7 @@ void cdrInterrupt() { return; } - cdr.Irq = 0xff; + cdr.Irq = 0; cdr.Ctrl &= ~0x80; switch (Irq) { @@ -737,6 +694,29 @@ void cdrInterrupt() { cdr.Seeked = SEEK_DONE; } + // BIOS CD Player + // - Pause player, hit Track 01/02/../xx (Setloc issued!!) + + if (cdr.ParamC == 0 || cdr.Param[0] == 0) { + CDR_LOG("PLAY Resume @ %d:%d:%d\n", + cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2]); + } + else + { + int track = btoi( cdr.Param[0] ); + + if (track <= cdr.ResultTN[1]) + cdr.CurTrack = track; + + CDR_LOG("PLAY track %d\n", cdr.CurTrack); + + if (CDR_getTD((u8)cdr.CurTrack, cdr.ResultTD) != -1) { + cdr.SetSectorPlay[0] = cdr.ResultTD[2]; + cdr.SetSectorPlay[1] = cdr.ResultTD[1]; + cdr.SetSectorPlay[2] = cdr.ResultTD[0]; + } + } + /* Rayman: detect track changes - fixes logo freeze @@ -747,84 +727,15 @@ 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--; - if( cdr.FastBackward ) cdr.FastBackward--; - - if( cdr.FastBackward == 0 && cdr.FastForward == 0 ) { - if( cdr.Play && CDR_getStatus(&stat) != -1 ) { - cdr.SetSectorPlay[0] = stat.Time[0]; - cdr.SetSectorPlay[1] = stat.Time[1]; - cdr.SetSectorPlay[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_LOG( "PLAY Resume @ %d:%d:%d\n", - cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2] ); - - //CDR_play( cdr.SetSectorPlay ); - } - else - { - // BIOS CD Player: Resume play - if( cdr.Param[0] == 0 ) { - CDR_LOG( "PLAY Resume T0 @ %d:%d:%d\n", - cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2] ); - - //CDR_play( cdr.SetSectorPlay ); - } - else { - CDR_LOG( "PLAY Resume Td @ %d:%d:%d\n", - cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2] ); - - // 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.SetSectorPlay[0] = cdr.ResultTD[2]; - cdr.SetSectorPlay[1] = cdr.ResultTD[1]; - cdr.SetSectorPlay[2] = cdr.ResultTD[0]; - - // reset data - //Set_Track(); - Find_CurTrack(); - ReadTrack( cdr.SetSectorPlay ); - - //CDR_play(cdr.SetSectorPlay); - } - } - } - } - } + ReadTrack(cdr.SetSectorPlay); + if (!Config.Cdda) + CDR_play(cdr.SetSectorPlay); // Vib Ribbon: gameplay checks flag cdr.StatP &= ~STATUS_SEEK; - cdr.CmdProcess = 0; SetResultSize(1); cdr.StatP |= STATUS_ROTATING; @@ -988,9 +899,8 @@ 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 ); + // update subq + ReadTrack( cdr.SetSector ); cdr.Result[0] = subq->TrackNumber; cdr.Result[1] = subq->IndexNumber; @@ -1005,10 +915,9 @@ void cdrInterrupt() { } } } else { - if( cdr.Play == FALSE || !(cdr.Mode & MODE_CDDA) || !(cdr.Mode & (MODE_AUTOPAUSE|MODE_REPORT)) ) + if (cdr.Play == FALSE) Create_Fake_Subq(); - // track # / index # cdr.Result[0] = itob(cdr.CurTrack); cdr.Result[1] = itob(fake_subq_index); @@ -1024,6 +933,9 @@ void cdrInterrupt() { cdr.Result[7] = itob( fake_subq_real[2] ); } + if (!cdr.Play && !cdr.Reading) + cdr.Result[1] = 0; // HACK? + // redump.org - wipe time if( !cdr.Play && CheckSBI(cdr.Result+5) ) { memset( cdr.Result+2, 0, 6 ); @@ -1091,7 +1003,7 @@ void cdrInterrupt() { - fix capcom logo */ CDRMISC_INT(cdr.Seeked == SEEK_DONE ? 0x800 : cdReadTime * 4); - cdr.Seeked = SEEK_DOING_CMD; + cdr.Seeked = SEEK_PENDING; break; case CdlTest: @@ -1358,17 +1270,7 @@ void cdrReadInterrupt() { cdr.Readed = 0; - // G-Police: Don't autopause ADPCM even if mode set (music) - if ((cdr.Transfer[4 + 2] & 0x80) && (cdr.Mode & MODE_AUTOPAUSE) && - (cdr.Transfer[4 + 2] & 0x4) != 0x4 ) { // EOF - - CDR_LOG("cdrReadInterrupt() Log: Autopausing read\n"); - - AddIrqQueue(CdlPause, 0x2000); - } - else { - CDREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime); - } + CDREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime); /* Croc 2: $40 - only FORM1 (*) @@ -1376,14 +1278,10 @@ void cdrReadInterrupt() { Sim Theme Park - no adpcm at all (zero) */ - if( (cdr.Mode & MODE_STRSND) == 0 || (cdr.Transfer[4+2] & 0x4) != 0x4 ) { + if (!(cdr.Mode & MODE_STRSND) || !(cdr.Transfer[4+2] & 0x4)) { cdr.Stat = DataReady; - } else { - // Breath of Fire 3 - fix inn sleeping - // Rockman X5 - no music restart problem - cdr.Stat = NoIntr; + setIrq(); } - setIrq(); Check_Shell(0); } @@ -1494,7 +1392,13 @@ void cdrWrite1(unsigned char rt) { for (i = 0; i < 3; i++) set_loc[i] = btoi(cdr.Param[i]); - i = abs(msf2sec(cdr.SetSector) - msf2sec(set_loc)); + // FIXME: clean up this SetSector/SetSectorPlay mess, + // there should be single var tracking current sector pos + if (cdr.Play) + i = msf2sec(cdr.SetSectorPlay); + else + i = msf2sec(cdr.SetSector); + i = abs(i - msf2sec(set_loc)); if (i > 16) cdr.Seeked = SEEK_PENDING; @@ -1506,6 +1410,7 @@ void cdrWrite1(unsigned char rt) { // Vib Ribbon: try same track again StopCdda(); +#if 0 if (!cdr.SetSector[0] & !cdr.SetSector[1] & !cdr.SetSector[2]) { if (CDR_getTN(cdr.ResultTN) != -1) { if (cdr.CurTrack > cdr.ResultTN[1]) @@ -1517,10 +1422,8 @@ void cdrWrite1(unsigned char rt) { if (!Config.Cdda) CDR_play(cdr.ResultTD); } } - } else if (!Config.Cdda) { - CDR_play(cdr.SetSector); } - +#endif // Vib Ribbon - decoded buffer IRQ for CDDA reading // - fixes ribbon timing + music CD mode //TODO? @@ -1546,11 +1449,7 @@ void cdrWrite1(unsigned char rt) { case CdlStop: // GameShark CD Player: Reset CDDA to track start - if( cdr.Play && CDR_getStatus(&stat) != -1 ) { - cdr.SetSectorPlay[0] = stat.Time[0]; - cdr.SetSectorPlay[1] = stat.Time[1]; - cdr.SetSectorPlay[2] = stat.Time[2]; - + if (cdr.Play) { Find_CurTrack(); // grab time for current track @@ -1693,9 +1592,13 @@ void cdrWrite3(unsigned char rt) { switch (cdr.Ctrl & 3) { case 0: - goto transfer; + break; // transfer case 1: - break; // irq + cdr.Stat &= ~rt; + + if (rt & 0x40) + cdr.ParamC = 0; + return; case 2: cdr.AttenuatorLeft[1] = rt; return; @@ -1707,34 +1610,6 @@ void cdrWrite3(unsigned char rt) { return; } - cdr.Stat &= ~rt; - - if (rt & 0x40) - cdr.ParamC = 0; - - if (rt == 0x07) { - if (cdr.Irq == 0xff) { - cdr.Irq = 0; - return; - } - - // XA streaming - incorrect timing because of this reschedule - // - Final Fantasy Tactics - // - various other games - - if (cdr.Reading && !cdr.ResultReady) { - 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 - CDR_LOG_I("-- resched %d -> %d\n", left, time); - CDREAD_INT(time); - } - } - } - return; - -transfer: if ((rt & 0x80) && cdr.Readed == 0) { cdr.Readed = 1; pTransfer = cdr.Transfer; @@ -1879,7 +1754,7 @@ void LidInterrupt() { cdr.LidCheck = 0x20; // start checker CDRLID_INT( cdReadTime * 3 ); - + // generate interrupt if none active - open or close if (cdr.Irq == 0 || cdr.Irq == 0xff) { cdr.Ctrl |= 0x80;