X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fcdrom.c;h=1e8f950aa2fe8b6ffb1bc2ec183623c4ccd17c82;hb=1f035e278151a3e29b3d2077f7242787fc541216;hp=ca7f9f7b1d53c4b85c11847e636b0453b5643ec0;hpb=030bd76a17021cb6e56aad5ae5d0320d7d43133b;p=pcsx_rearmed.git diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index ca7f9f7b..1e8f950a 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -14,16 +14,17 @@ * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ -/* +/* * Handles all CD-ROM registers and functions. */ #include "cdrom.h" #include "ppf.h" #include "psxdma.h" +#include "arm_features.h" /* logging */ #if 0 @@ -47,7 +48,7 @@ cdrStruct cdr; static unsigned char *pTransfer; /* CD-ROM magic numbers */ -#define CdlSync 0 +#define CdlSync 0 /* nocash documentation : "Uh, actually, returns error code 40h = Invalid Command...?" */ #define CdlNop 1 #define CdlSetloc 2 #define CdlPlay 3 @@ -126,7 +127,7 @@ unsigned char Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 }; #define STATUS_ERROR (1<<0) // 0x01 /* Errors */ -#define ERROR_NOT_READY (1<<7) // 0x80 +#define ERROR_NOTREADY (1<<7) // 0x80 #define ERROR_INVALIDCMD (1<<6) // 0x40 #define ERROR_INVALIDARG (1<<5) // 0x20 @@ -205,7 +206,7 @@ static void sec2msf(unsigned int s, u8 *msf) { cdr.Reading = 0; \ psxRegs.interrupt &= ~(1 << PSXINT_CDREAD); \ } \ - cdr.StatP &= ~STATUS_READ;\ + cdr.StatP &= ~(STATUS_READ|STATUS_SEEK);\ } #define StopCdda() { \ @@ -492,7 +493,11 @@ void cdrPlayInterrupt() setIrq(); } - memcpy(cdr.SetSectorPlay, cdr.SetSector, 4); + if (cdr.SetlocPending) { + memcpy(cdr.SetSectorPlay, cdr.SetSector, 4); + cdr.SetlocPending = 0; + cdr.m_locationChanged = TRUE; + } Find_CurTrack(cdr.SetSectorPlay); ReadTrack(cdr.SetSectorPlay); cdr.TrackChanged = FALSE; @@ -523,7 +528,15 @@ void cdrPlayInterrupt() } } - CDRMISC_INT(cdReadTime); + if (cdr.m_locationChanged) + { + CDRMISC_INT(cdReadTime * 30); + cdr.m_locationChanged = FALSE; + } + else + { + CDRMISC_INT(cdReadTime); + } // update for CdlGetlocP/autopause generate_subq(cdr.SetSectorPlay); @@ -535,6 +548,7 @@ void cdrInterrupt() { int start_rotating = 0; int error = 0; int delay; + unsigned int seekTime = 0; // Reschedule IRQ if (cdr.Stat) { @@ -561,10 +575,6 @@ void cdrInterrupt() { cdr.Irq = 0; switch (Irq) { - case CdlSync: - // TOOD: sometimes/always return error? - break; - case CdlNop: if (cdr.DriveState != DRIVESTATE_LID_OPEN) cdr.StatP &= ~STATUS_SHELLOPEN; @@ -574,13 +584,18 @@ void cdrInterrupt() { case CdlSetloc: break; + do_CdlPlay: case CdlPlay: StopCdda(); if (cdr.Seeked == SEEK_PENDING) { // XXX: wrong, should seek instead.. - memcpy( cdr.SetSectorPlay, cdr.SetSector, 4 ); cdr.Seeked = SEEK_DONE; } + if (cdr.SetlocPending) { + memcpy(cdr.SetSectorPlay, cdr.SetSector, 4); + cdr.SetlocPending = 0; + cdr.m_locationChanged = TRUE; + } // BIOS CD Player // - Pause player, hit Track 01/02/../xx (Setloc issued!!) @@ -900,13 +915,25 @@ void cdrInterrupt() { case CdlReadN: case CdlReadS: + if (cdr.SetlocPending) { + seekTime = abs(msf2sec(cdr.SetSectorPlay) - msf2sec(cdr.SetSector)) * (cdReadTime / 200); + if(seekTime > 1000000) seekTime = 1000000; + memcpy(cdr.SetSectorPlay, cdr.SetSector, 4); + cdr.SetlocPending = 0; + cdr.m_locationChanged = TRUE; + } + Find_CurTrack(cdr.SetSectorPlay); + + if ((cdr.Mode & MODE_CDDA) && cdr.CurTrack > 1) + // Read* acts as play for cdda tracks in cdda mode + goto do_CdlPlay; + cdr.Reading = 1; cdr.FirstSector = 1; // Fighting Force 2 - update subq time immediately // - fixes new game - Find_CurTrack(cdr.SetSector); - ReadTrack(cdr.SetSector); + ReadTrack(cdr.SetSectorPlay); // Crusaders of Might and Magic - update getlocl now @@ -931,7 +958,7 @@ void cdrInterrupt() { // - fix cutscene speech (startup) // ??? - use more accurate seek time later - CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime * 1); + CDREAD_INT(((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime * 1) + seekTime); } else { cdr.StatP |= STATUS_READ; cdr.StatP &= ~STATUS_SEEK; @@ -942,7 +969,7 @@ void cdrInterrupt() { cdr.Result[0] = cdr.StatP; start_rotating = 1; break; - + case CdlSync: default: CDR_LOG_I("Invalid command: %02x\n", Irq); error = ERROR_INVALIDCMD; @@ -968,7 +995,7 @@ void cdrInterrupt() { case DRIVESTATE_PREPARE_CD: SetResultSize(2); cdr.Result[0] = cdr.StatP | STATUS_ERROR; - cdr.Result[1] = ERROR_NOT_READY; + cdr.Result[1] = ERROR_NOTREADY; cdr.Stat = DiskError; break; } @@ -990,7 +1017,7 @@ finish: #endif } -#ifdef __ARM_ARCH_7A__ +#ifdef HAVE_ARMV7 #define ssat32_to_16(v) \ asm("ssat %0,#16,%1" : "=r" (v) : "r" (v)) #else @@ -1057,7 +1084,7 @@ void cdrReadInterrupt() { cdr.Result[0] = cdr.StatP; cdr.Seeked = SEEK_DONE; - ReadTrack(cdr.SetSector); + ReadTrack(cdr.SetSectorPlay); buf = CDR_getBuffer(); if (buf == NULL) @@ -1085,9 +1112,14 @@ void cdrReadInterrupt() { cdr.Channel = cdr.Transfer[4 + 1]; } + /* Gameblabla + * Skips playing on channel 255. + * Fixes missing audio in Blue's Clues : Blue's Big Musical. (Should also fix Taxi 2) + * TODO : Check if this is the proper behaviour. + * */ if((cdr.Transfer[4 + 2] & 0x4) && (cdr.Transfer[4 + 1] == cdr.Channel) && - (cdr.Transfer[4 + 0] == cdr.File)) { + (cdr.Transfer[4 + 0] == cdr.File) && cdr.Channel != 255) { int ret = xa_decode_sector(&cdr.Xa, cdr.Transfer+4, cdr.FirstSector); if (!ret) { cdrAttenuate(cdr.Xa.pcm, cdr.Xa.nsamples, cdr.Xa.stereo); @@ -1098,19 +1130,25 @@ void cdrReadInterrupt() { } } - cdr.SetSector[2]++; - if (cdr.SetSector[2] == 75) { - cdr.SetSector[2] = 0; - cdr.SetSector[1]++; - if (cdr.SetSector[1] == 60) { - cdr.SetSector[1] = 0; - cdr.SetSector[0]++; + 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]++; } } cdr.Readed = 0; - CDREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime); + uint32_t delay = (cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime; + if (cdr.m_locationChanged) { + CDREAD_INT(delay * 30); + cdr.m_locationChanged = FALSE; + } else { + CDREAD_INT(delay); + } /* Croc 2: $40 - only FORM1 (*) @@ -1124,7 +1162,7 @@ void cdrReadInterrupt() { } // update for CdlGetlocP - ReadTrack(cdr.SetSector); + ReadTrack(cdr.SetSectorPlay); } /* @@ -1218,18 +1256,14 @@ void cdrWrite1(unsigned char rt) { for (i = 0; i < 3; i++) set_loc[i] = btoi(cdr.Param[i]); - // 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 = msf2sec(cdr.SetSectorPlay); i = abs(i - msf2sec(set_loc)); if (i > 16) cdr.Seeked = SEEK_PENDING; memcpy(cdr.SetSector, set_loc, 3); cdr.SetSector[3] = 0; + cdr.SetlocPending = 1; break; case CdlReadN: @@ -1401,13 +1435,15 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { psxCpu->Clear(madr, cdsize / 4); pTransfer += cdsize; - - // burst vs normal if( chcr == 0x11400100 ) { + HW_DMA3_MADR = SWAPu32(madr + cdsize); CDRDMA_INT( (cdsize/4) / 4 ); } else if( chcr == 0x11000000 ) { - CDRDMA_INT( (cdsize/4) * 1 ); + // CDRDMA_INT( (cdsize/4) * 1 ); + // halted + psxRegs.cycle += (cdsize/4) * 24/2; + CDRDMA_INT(16); } return; @@ -1448,7 +1484,10 @@ void cdrReset() { cdr.Reg2 = 0x1f; cdr.Stat = NoIntr; cdr.DriveState = DRIVESTATE_STANDBY; + cdr.StatP = STATUS_ROTATING; pTransfer = cdr.Transfer; + cdr.SetlocPending = 0; + cdr.m_locationChanged = FALSE; // BIOS player - default values cdr.AttenuatorLeftToLeft = 0x80; @@ -1466,7 +1505,7 @@ int cdrFreeze(void *f, int Mode) { if (Mode == 0 && !Config.Cdda) CDR_stop(); - cdr.freeze_ver = 0x63647201; + cdr.freeze_ver = 0x63647202; gzfreeze(&cdr, sizeof(cdr)); if (Mode == 1) { @@ -1482,11 +1521,16 @@ int cdrFreeze(void *f, int Mode) { pTransfer = cdr.Transfer + tmp; // read right sub data - memcpy(tmpp, cdr.Prev, 3); + tmpp[0] = btoi(cdr.Prev[0]); + tmpp[1] = btoi(cdr.Prev[1]); + tmpp[2] = btoi(cdr.Prev[2]); cdr.Prev[0]++; ReadTrack(tmpp); if (cdr.Play) { + if (cdr.freeze_ver < 0x63647202) + memcpy(cdr.SetSectorPlay, cdr.SetSector, 3); + Find_CurTrack(cdr.SetSectorPlay); if (!Config.Cdda) CDR_play(cdr.SetSectorPlay); @@ -1498,6 +1542,12 @@ int cdrFreeze(void *f, int Mode) { SysPrintf("cdrom: fixing up old savestate\n"); cdr.Reg2 = 7; } + // also did not save Attenuator.. + if ((cdr.AttenuatorLeftToLeft | cdr.AttenuatorLeftToRight + | cdr.AttenuatorRightToLeft | cdr.AttenuatorRightToRight) == 0) + { + cdr.AttenuatorLeftToLeft = cdr.AttenuatorRightToRight = 0x80; + } } }