X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fcdrom.c;h=eebd8edcb6e744d78a46ddec34c571b05fbfc8e1;hp=61e1e7adb98c53d9d0dcd374b7288f5fb4bc0b93;hb=94c118c3c7a031500d0d1b2ede9d85124239b323;hpb=f9ccca15495c5d2ac9ca098ec171d76907a7bccc diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index 61e1e7ad..eebd8edc 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -25,6 +25,24 @@ #include "ppf.h" #include "psxdma.h" +/* logging */ +#if 0 +#define CDR_LOG SysPrintf +#else +#define CDR_LOG(...) +#endif +#if 0 +#define CDR_LOG_I SysPrintf +#else +#define CDR_LOG_I(...) +#endif +#if 0 +#define CDR_LOG_IO SysPrintf +#else +#define CDR_LOG_IO(...) +#endif +//#define CDR_LOG_CMD_IRQ + cdrStruct cdr; static unsigned char *pTransfer; @@ -60,12 +78,6 @@ static unsigned char *pTransfer; #define CdlReset 28 #define CdlReadToc 30 -#define AUTOPAUSE 249 -#define READ_ACK 250 -#define READ 251 -#define REPPLAY_ACK 252 -#define REPPLAY 253 -#define ASYNC 254 /* don't set 255, it's reserved */ char *CmdName[0x100]= { @@ -173,13 +185,6 @@ static void sec2msf(unsigned int s, u8 *msf) { new_dyna_set_event(PSXINT_CDRPLAY, eCycle); \ } -#define StartReading(type, eCycle) { \ - cdr.Reading = type; \ - cdr.FirstSector = 1; \ - cdr.Readed = 0xff; \ - AddIrqQueue(READ_ACK, eCycle); \ -} - #define StopReading() { \ if (cdr.Reading) { \ cdr.Reading = 0; \ @@ -200,11 +205,16 @@ static void sec2msf(unsigned int s, u8 *msf) { } #define SetResultSize(size) { \ - cdr.ResultP = 0; \ + cdr.ResultP = 0; \ cdr.ResultC = size; \ cdr.ResultReady = 1; \ } +static void setIrq(void) +{ + if (cdr.Stat & cdr.Reg2) + psxHu32ref(0x1070) |= SWAP32((u32)0x4); +} void cdrLidSeekInterrupt() { @@ -267,9 +277,7 @@ static void Check_Shell( int Irq ) // check case open/close if (cdr.LidCheck > 0) { -#ifdef CDR_LOG CDR_LOG( "LidCheck\n" ); -#endif // $20 = check lid state if( cdr.LidCheck == 0x20 ) @@ -325,8 +333,7 @@ static void Check_Shell( int Irq ) if( cdr.Stat == NoIntr ) cdr.Stat = Acknowledge; - psxHu32ref(0x1070) |= SWAP32((u32)0x4); - + setIrq(); // begin close-seek-ready cycle CDRLID_INT( cdReadTime * 3 ); @@ -366,12 +373,11 @@ static void Check_Shell( int Irq ) if( cdr.Stat == NoIntr ) cdr.Stat = Acknowledge; - psxHu32ref(0x1070) |= SWAP32((u32)0x4); + setIrq(); } } } - void Find_CurTrack() { cdr.CurTrack = 0; @@ -382,12 +388,10 @@ void Find_CurTrack() { 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.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2], cdr.ResultTD[2], cdr.ResultTD[1], cdr.ResultTD[0], cdr.CurTrack ); -#endif // find next track boundary - only need m:s accuracy sect1 = cdr.SetSectorPlay[0] * 60 * 75 + cdr.SetSectorPlay[1] * 75; @@ -413,16 +417,14 @@ static void ReadTrack( u8 *time ) { cdr.Prev[1] = itob( time[1] ); cdr.Prev[2] = itob( time[2] ); -#ifdef CDR_LOG CDR_LOG("ReadTrack() Log: KEY *** %x:%x:%x\n", cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]); -#endif cdr.RErr = CDR_readTrack(cdr.Prev); } static void AddIrqQueue(unsigned char irq, unsigned long ecycle) { - //if (cdr.Irq != 0 && cdr.Irq != 0xff) - // printf("cdr: override cmd %02x -> %02x\n", cdr.Irq, irq); + if (cdr.Irq != 0 && cdr.Irq != 0xff) + CDR_LOG_I("cdr: override cmd %02x -> %02x\n", cdr.Irq, irq); cdr.Irq = irq; cdr.eCycle = ecycle; @@ -438,12 +440,10 @@ void Set_Track() for( lcv = 1; lcv < cdr.ResultTN[1]; lcv++ ) { if (CDR_getTD((u8)(lcv), cdr.ResultTD) != -1) { -#ifdef CDR_LOG___0 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 ); -#endif // check if time matches track start (only need min, sec accuracy) // - m:s:f vs f:s:m @@ -524,12 +524,10 @@ static void Create_Fake_Subq() 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 @@ -555,10 +553,8 @@ static void cdrPlayInterrupt_Autopause() // update subq ReadTrack( cdr.SetSectorPlay ); -#ifdef CDR_LOG CDR_LOG( "CDDA SUB - %X:%X:%X\n", subq->AbsoluteAddress[0], subq->AbsoluteAddress[1], subq->AbsoluteAddress[2] ); -#endif /* CDDA Autopause @@ -573,19 +569,15 @@ static void cdrPlayInterrupt_Autopause() track_changed = 1; } else { Create_Fake_Subq(); -#ifdef CDR_LOG___0 CDR_LOG( "CDDA FAKE SUB - %d:%d:%d\n", fake_subq_real[0], fake_subq_real[1], fake_subq_real[2] ); -#endif track_changed = fake_subq_change; fake_subq_change = 0; } if ((cdr.Mode & MODE_AUTOPAUSE) && track_changed) { -#ifdef CDR_LOG CDR_LOG( "CDDA STOP\n" ); -#endif // Magic the Gathering // - looping territory cdda @@ -594,16 +586,15 @@ static void cdrPlayInterrupt_Autopause() //cdr.ResultReady = 1; //cdr.Stat = DataReady; cdr.Stat = DataEnd; - psxHu32ref(0x1070) |= SWAP32((u32)0x4); + setIrq(); StopCdda(); } else if (cdr.Mode & MODE_REPORT) { if (subq != NULL) { -#ifdef CDR_LOG CDR_LOG( "REPPLAY SUB - %X:%X:%X\n", subq->AbsoluteAddress[0], subq->AbsoluteAddress[1], subq->AbsoluteAddress[2] ); -#endif + // breaks when .sub doesn't have index 0 for some reason (bad rip?) //cdr.CurTrack = btoi( subq->TrackNumber ); @@ -619,10 +610,8 @@ static void cdrPlayInterrupt_Autopause() cdr.Result[4] = subq->AbsoluteAddress[1]; cdr.Result[5] = subq->AbsoluteAddress[2]; } else { -#ifdef CDR_LOG___0 CDR_LOG( "REPPLAY FAKE - %d:%d:%d\n", fake_subq_real[0], fake_subq_real[1], fake_subq_real[2] ); -#endif if (fake_subq_real[2] & 0xf) return; @@ -642,7 +631,7 @@ static void cdrPlayInterrupt_Autopause() cdr.Stat = DataReady; SetResultSize(8); - psxHu32ref(0x1070) |= SWAP32((u32)0x4); + setIrq(); } } @@ -650,14 +639,18 @@ static void cdrPlayInterrupt_Autopause() void cdrPlayInterrupt() { if (cdr.Seeked == SEEK_DOING_CMD) { + if (cdr.Stat) { + CDR_LOG_I("cdrom: seek stat hack\n"); + CDRMISC_INT(0x1000); + return; + } SetResultSize(1); cdr.StatP |= STATUS_ROTATING; cdr.StatP &= ~STATUS_SEEK; cdr.Result[0] = cdr.StatP; if (cdr.Irq == 0 || cdr.Irq == 0xff) { cdr.Stat = Complete; - if (cdr.Reg2 != 0x18) - psxHu32ref(0x1070) |= SWAP32(0x4); + setIrq(); } cdr.Seeked = SEEK_PENDING; @@ -675,10 +668,9 @@ 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 + CDRMISC_INT( cdReadTime ); if (!cdr.Irq && !cdr.Stat && (cdr.Mode & MODE_CDDA) && (cdr.Mode & (MODE_AUTOPAUSE|MODE_REPORT))) @@ -704,7 +696,8 @@ void cdrInterrupt() { // Reschedule IRQ if (cdr.Stat) { - CDR_INT( 0x100 ); + CDR_LOG_I("cdrom: stat hack: %02x %x\n", cdr.Irq, cdr.Stat); + CDR_INT(0x1000); return; } @@ -781,10 +774,8 @@ void cdrInterrupt() { // GameShark CD Player: Resume play if( cdr.ParamC == 0 ) { -#ifdef CDR_LOG___0 CDR_LOG( "PLAY Resume @ %d:%d:%d\n", cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2] ); -#endif //CDR_play( cdr.SetSectorPlay ); } @@ -792,18 +783,14 @@ void cdrInterrupt() { { // BIOS CD Player: Resume play if( cdr.Param[0] == 0 ) { -#ifdef CDR_LOG___0 CDR_LOG( "PLAY Resume T0 @ %d:%d:%d\n", cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2] ); -#endif //CDR_play( cdr.SetSectorPlay ); } else { -#ifdef CDR_LOG___0 CDR_LOG( "PLAY Resume Td @ %d:%d:%d\n", cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2] ); -#endif // BIOS CD Player: Allow track replaying StopCdda(); @@ -1204,20 +1191,8 @@ void cdrInterrupt() { cdr.Stat = Complete; break; - case AUTOPAUSE: - cdr.OCUP = 0; -/* SetResultSize(1); - StopCdda(); - StopReading(); - cdr.OCUP = 0; - cdr.StatP&=~0x20; - cdr.StatP|= 0x2; - cdr.Result[0] = cdr.StatP; - cdr.Stat = DataEnd; -*/ AddIrqQueue(CdlPause, 0x800); - break; - - case READ_ACK: + case CdlReadN: + case CdlReadS: if (!cdr.Reading) return; @@ -1272,18 +1247,16 @@ void cdrInterrupt() { Check_Shell( Irq ); - cdr.ParamP = 0; cdr.ParamC = 0; - if (cdr.Stat != NoIntr && cdr.Reg2 != 0x18) { - psxHu32ref(0x1070) |= SWAP32((u32)0x4); - } + setIrq(); -#ifdef CDR_LOG - printf("cdrInterrupt() Log: CDR Interrupt IRQ %x: ", Irq); +#ifdef CDR_LOG_CMD_IRQ + SysPrintf("cdrInterrupt() Log: CDR Interrupt IRQ %d %02x: ", + cdr.Stat != NoIntr && cdr.Reg2 != 0x18, Irq); for (i = 0; i < cdr.ResultC; i++) - printf("%02x ", cdr.Result[i]); - printf("\n"); + SysPrintf("%02x ", cdr.Result[i]); + SysPrintf("\n"); #endif } @@ -1294,14 +1267,11 @@ void cdrReadInterrupt() { return; if (cdr.Irq || cdr.Stat) { - CDREAD_INT(0x100); + CDR_LOG_I("cdrom: read stat hack %02x %x\n", cdr.Irq, cdr.Stat); + CDREAD_INT(0x1000); return; } -#ifdef CDR_LOG - CDR_LOG("cdrReadInterrupt() Log: KEY END"); -#endif - cdr.OCUP = 1; SetResultSize(1); cdr.StatP |= STATUS_READ|STATUS_ROTATING; @@ -1316,9 +1286,7 @@ void cdrReadInterrupt() { cdr.RErr = -1; if (cdr.RErr == -1) { -#ifdef CDR_LOG - fprintf(emuLog, "cdrReadInterrupt() Log: err\n"); -#endif + CDR_LOG_I("cdrReadInterrupt() Log: err\n"); memset(cdr.Transfer, 0, DATA_SIZE); cdr.Stat = DiskError; cdr.Result[0] |= STATUS_ERROR; @@ -1330,9 +1298,7 @@ void cdrReadInterrupt() { CheckPPFCache(cdr.Transfer, cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]); -#ifdef CDR_LOG - fprintf(emuLog, "cdrReadInterrupt() Log: cdr.Transfer %x:%x:%x\n", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); -#endif + CDR_LOG("cdrReadInterrupt() Log: cdr.Transfer %x:%x:%x\n", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); if ((!cdr.Muted) && (cdr.Mode & MODE_STRSND) && (!Config.Xa) && (cdr.FirstSector != -1)) { // CD-XA // Firemen 2: Multi-XA files - briefings, cutscenes @@ -1373,7 +1339,7 @@ void cdrReadInterrupt() { // - don't do here // signal ADPCM data ready - psxHu32ref(0x1070) |= SWAP32((u32)0x200); + setIrq(); #endif } else cdr.FirstSector = -1; @@ -1395,10 +1361,9 @@ void cdrReadInterrupt() { // 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 -#ifdef CDR_LOG + CDR_LOG("cdrReadInterrupt() Log: Autopausing read\n"); -#endif -// AddIrqQueue(AUTOPAUSE, 0x2000); + AddIrqQueue(CdlPause, 0x2000); } else { @@ -1418,15 +1383,14 @@ void cdrReadInterrupt() { // Rockman X5 - no music restart problem cdr.Stat = NoIntr; } - psxHu32ref(0x1070) |= SWAP32((u32)0x4); + setIrq(); Check_Shell(0); } /* cdrRead0: - bit 0 - 0 REG1 command send / 1 REG1 data read - bit 1 - 0 data transfer finish / 1 data transfer ready/in progress + bit 0,1 - mode bit 2 - unknown bit 3 - unknown bit 4 - unknown @@ -1449,38 +1413,28 @@ unsigned char cdrRead0(void) { // What means the 0x10 and the 0x08 bits? I only saw it used by the bios cdr.Ctrl |= 0x18; -#ifdef CDR_LOG - CDR_LOG("cdrRead0() Log: CD0 Read: %x\n", cdr.Ctrl); -#endif + CDR_LOG_IO("cdr r0: %02x\n", cdr.Ctrl); return psxHu8(0x1800) = cdr.Ctrl; } -/* -cdrWrite0: - 0 - to send a command / 1 - to get the result -*/ - void cdrWrite0(unsigned char rt) { -#ifdef CDR_LOG - CDR_LOG("cdrWrite0() Log: CD0 write: %x\n", rt); -#endif + CDR_LOG_IO("cdr w0: %02x\n", rt); + cdr.Ctrl = (rt & 3) | (cdr.Ctrl & ~3); } unsigned char cdrRead1(void) { - if (cdr.ResultReady) { // && cdr.Ctrl & 0x1) { - // GameShark CDX CD Player: uses 17 bytes output (wraps around) + if ((cdr.ResultP & 0xf) < cdr.ResultC) psxHu8(0x1801) = cdr.Result[cdr.ResultP & 0xf]; - cdr.ResultP++; - if (cdr.ResultP == cdr.ResultC) - cdr.ResultReady = 0; - } else { + else psxHu8(0x1801) = 0; - } -#ifdef CDR_LOG - CDR_LOG("cdrRead1() Log: CD1 Read: %x\n", psxHu8(0x1801)); -#endif + cdr.ResultP++; + if (cdr.ResultP == cdr.ResultC) + cdr.ResultReady = 0; + + CDR_LOG_IO("cdr r1: %02x\n", psxHu8(0x1801)); + return psxHu8(0x1801); } @@ -1488,22 +1442,22 @@ void cdrWrite1(unsigned char rt) { u8 set_loc[3]; int i; -#ifdef CDR_LOG - CDR_LOG("cdrWrite1() Log: CD1 write: %x (%s)\n", rt, CmdName[rt]); -#endif - + CDR_LOG_IO("cdr w1: %02x\n", rt); - // Tekken: CDXA fade-out - if( (cdr.Ctrl & 3) == 3 ) { - cdr.AttenuatorRight[0] = rt; + switch (cdr.Ctrl & 3) { + case 0: + break; + case 3: + cdr.AttenuatorRight[1] = rt; + return; + default: + return; } - -// psxHu8(0x1801) = rt; cdr.Cmd = rt; cdr.OCUP = 0; -#ifdef CDRCMD_DEBUG +#ifdef CDR_LOG_CMD_IRQ SysPrintf("cdrWrite1() Log: CD1 write: %x (%s)", rt, CmdName[rt]); if (cdr.ParamC) { SysPrintf(" Param[%d] = {", cdr.ParamC); @@ -1515,43 +1469,40 @@ void cdrWrite1(unsigned char rt) { } #endif - if (cdr.Ctrl & 0x3) return; - cdr.ResultReady = 0; + cdr.Ctrl |= 0x80; + // cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); switch (cdr.Cmd) { - case CdlSync: - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlNop: - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - - // Twisted Metal 3 - fix music - AddIrqQueue(cdr.Cmd, 0x800); - break; + case CdlSync: + case CdlNop: + case CdlForward: + case CdlBackward: + case CdlReadT: + case CdlTest: + case CdlID: + case CdlReadToc: + case CdlGetmode: + case CdlGetlocL: + case CdlGetlocP: + case CdlGetTD: + break; - case CdlSetloc: + case CdlSetloc: StopReading(); for (i = 0; i < 3; i++) set_loc[i] = btoi(cdr.Param[i]); i = abs(msf2sec(cdr.SetSector) - msf2sec(set_loc)); if (i > 16) - cdr.Seeked = SEEK_PENDING; + cdr.Seeked = SEEK_PENDING; memcpy(cdr.SetSector, set_loc, 3); - cdr.SetSector[3] = 0; - - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; + cdr.SetSector[3] = 0; + break; - case CdlPlay: + case CdlPlay: // Vib Ribbon: try same track again StopCdda(); @@ -1575,50 +1526,25 @@ void cdrWrite1(unsigned char rt) { //TODO? //CDRDBUF_INT( PSXCLK / 44100 * 0x100 ); - cdr.Play = TRUE; cdr.StatP |= STATUS_SEEK; cdr.StatP &= ~STATUS_ROTATING; + break; - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlForward: - //if (cdr.CurTrack < 0xaa) - // cdr.CurTrack++; - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlBackward: - //if (cdr.CurTrack > 1) - //cdr.CurTrack--; - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlReadN: - cdr.Irq = 0; + case CdlReadN: StopReading(); - cdr.Ctrl|= 0x80; - cdr.Stat = NoIntr; - StartReading(1, 0x800); + cdr.Reading = 1; + cdr.FirstSector = 1; + cdr.Readed = 0xff; break; - case CdlStandby: + case CdlStandby: StopCdda(); StopReading(); - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; + break; - case CdlStop: + case CdlStop: // GameShark CD Player: Reset CDDA to track start if( cdr.Play && CDR_getStatus(&stat) != -1 ) { cdr.SetSectorPlay[0] = stat.Time[0]; @@ -1627,7 +1553,6 @@ void cdrWrite1(unsigned char rt) { Find_CurTrack(); - // grab time for current track CDR_getTD((u8)(cdr.CurTrack), cdr.ResultTD); @@ -1638,13 +1563,9 @@ void cdrWrite1(unsigned char rt) { StopCdda(); StopReading(); + break; - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlPause: + case CdlPause: /* GameShark CD Player: save time for resume @@ -1653,62 +1574,41 @@ void cdrWrite1(unsigned char rt) { StopCdda(); StopReading(); - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - - AddIrqQueue(cdr.Cmd, 0x800); break; case CdlReset: - case CdlInit: + case CdlInit: cdr.Seeked = SEEK_DONE; StopCdda(); StopReading(); - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlMute: - cdr.Muted = TRUE; - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); + break; + case CdlMute: + cdr.Muted = TRUE; // Duke Nukem - Time to Kill // - do not directly set cd-xa volume //SPU_writeRegister( H_CDLeft, 0x0000 ); //SPU_writeRegister( H_CDRight, 0x0000 ); - break; + break; - case CdlDemute: - cdr.Muted = FALSE; - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); + case CdlDemute: + cdr.Muted = FALSE; // Duke Nukem - Time to Kill // - do not directly set cd-xa volume //SPU_writeRegister( H_CDLeft, 0x7f00 ); //SPU_writeRegister( H_CDRight, 0x7f00 ); - break; + break; case CdlSetfilter: cdr.File = cdr.Param[0]; cdr.Channel = cdr.Param[1]; - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); break; case CdlSetmode: -#ifdef CDR_LOG CDR_LOG("cdrWrite1() Log: Setmode %x\n", cdr.Param[0]); -#endif + cdr.Mode = cdr.Param[0]; - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); // Squaresoft on PlayStation 1998 Collector's CD Vol. 1 // - fixes choppy movie sound @@ -1716,118 +1616,32 @@ void cdrWrite1(unsigned char rt) { StopCdda(); break; - case CdlGetmode: - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlGetlocL: - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - - // Crusaders of Might and Magic - cutscene speech - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlGetlocP: - cdr.Ctrl |= 0x80; - 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, 0x40); - - // rearmed: the above works in pcsxr-svn, but breaks here - // (TOCA world touring cars), perhaps some other code is not merged yet - AddIrqQueue(cdr.Cmd, 0x1000); - break; - case CdlGetTN: - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; //AddIrqQueue(cdr.Cmd, 0x800); // GameShark CDX CD Player: very long time AddIrqQueue(cdr.Cmd, 0x100000); break; - case CdlGetTD: - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - case CdlSeekL: -// ((u32 *)cdr.SetSectorSeek)[0] = ((u32 *)cdr.SetSector)[0]; - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - - 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(); - - AddIrqQueue(cdr.Cmd, 0x800); - break; - - // Destruction Derby: read TOC? GetTD after this - case CdlReadT: - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); break; - case CdlTest: - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - case CdlID: - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - case CdlReadS: - cdr.Irq = 0; StopReading(); - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - StartReading(2, 0x800); + cdr.Reading = 2; + cdr.FirstSector = 1; + cdr.Readed = 0xff; break; - case CdlReadToc: - cdr.Ctrl |= 0x80; - cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - break; - - default: - cdr.ParamP = 0; + default: cdr.ParamC = 0; -#ifdef CDR_LOG - CDR_LOG("cdrWrite1() Log: Unknown command: %x\n", cdr.Cmd); -#endif + CDR_LOG_I("cdrWrite1() Log: Unknown command: %x\n", cdr.Cmd); return; } - if (cdr.Stat != NoIntr) { - psxHu32ref(0x1070) |= SWAP32((u32)0x4); - } } unsigned char cdrRead2(void) { @@ -1839,95 +1653,66 @@ unsigned char cdrRead2(void) { ret = *pTransfer++; } -#ifdef CDR_LOG - CDR_LOG("cdrRead2() Log: CD2 Read: %x\n", ret); -#endif + CDR_LOG_IO("cdr r2: %02x\n", ret); return ret; } void cdrWrite2(unsigned char rt) { -#ifdef CDR_LOG - CDR_LOG("cdrWrite2() Log: CD2 write: %x\n", rt); -#endif + CDR_LOG_IO("cdr w2: %02x\n", rt); - // Tekken: CDXA fade-out - if( (cdr.Ctrl & 3) == 2 ) { + switch (cdr.Ctrl & 3) { + case 0: + if (cdr.ParamC < 8) // FIXME: size and wrapping + cdr.Param[cdr.ParamC++] = rt; + return; + case 1: + cdr.Reg2 = rt; + setIrq(); + return; + case 2: cdr.AttenuatorLeft[0] = rt; - } - else if( (cdr.Ctrl & 3) == 3 ) { - cdr.AttenuatorRight[1] = rt; - } - - - if (cdr.Ctrl & 0x1) { - switch (rt) { - case 0x07: - cdr.ParamP = 0; - cdr.ParamC = 0; - cdr.ResultReady = 1; //0; - cdr.Ctrl &= ~3; //cdr.Ctrl = 0; - break; - - default: - cdr.Reg2 = rt; - break; - } - } else if (!(cdr.Ctrl & 0x3) && cdr.ParamP < 8) { - cdr.Param[cdr.ParamP++] = rt; - cdr.ParamC++; + return; + case 3: + cdr.AttenuatorRight[0] = rt; + return; } } unsigned char cdrRead3(void) { - if (cdr.Stat) { - if (cdr.Ctrl & 0x1) - psxHu8(0x1803) = cdr.Stat | 0xE0; - else - psxHu8(0x1803) = 0xff; - } else { - psxHu8(0x1803) = 0; - } -#ifdef CDR_LOG - CDR_LOG("cdrRead3() Log: CD3 Read: %x\n", psxHu8(0x1803)); -#endif + if (cdr.Ctrl & 0x1) + psxHu8(0x1803) = cdr.Stat | 0xE0; + else + psxHu8(0x1803) = cdr.Reg2 | 0xE0; + + CDR_LOG_IO("cdr r3: %02x\n", psxHu8(0x1803)); return psxHu8(0x1803); } 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_LOG_IO("cdr w3: %02x\n", rt); + + switch (cdr.Ctrl & 3) { + case 0: + goto transfer; + case 1: + break; // irq + case 2: cdr.AttenuatorLeft[1] = rt; - } - else if( (cdr.Ctrl & 3) == 3 && rt == 0x20 ) { -#ifdef CDR_LOG + return; + case 3: + if (rt == 0x20) CDR_LOG( "CD-XA Volume: %X %X | %X %X\n", cdr.AttenuatorLeft[0], cdr.AttenuatorLeft[1], cdr.AttenuatorRight[0], cdr.AttenuatorRight[1] ); -#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); - } + return; } + cdr.Stat &= ~rt; - if (rt == 0x07 && (cdr.Ctrl & 3) == 1) { - cdr.Stat = 0; + if (rt & 0x40) + cdr.ParamC = 0; + if (rt == 0x07) { if (cdr.Irq == 0xff) { cdr.Irq = 0; return; @@ -1942,15 +1727,15 @@ void cdrWrite3(unsigned char rt) { 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); + CDR_LOG_I("-- resched %d -> %d\n", left, time); CDREAD_INT(time); } } - - return; } + return; - if (rt == 0x80 && !(cdr.Ctrl & 0x3) && cdr.Readed == 0) { +transfer: + if ((rt & 0x80) && cdr.Readed == 0) { cdr.Readed = 1; pTransfer = cdr.Transfer; @@ -1975,17 +1760,13 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { int size; u8 *ptr; -#ifdef CDR_LOG CDR_LOG("psxDma3() Log: *** DMA 3 *** %x addr = %x size = %x\n", chcr, madr, bcr); -#endif switch (chcr) { case 0x11000000: case 0x11400100: if (cdr.Readed == 0) { -#ifdef CDR_LOG CDR_LOG("psxDma3() Log: *** DMA 3 *** NOT READY\n"); -#endif break; } @@ -2005,9 +1786,7 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { ptr = (u8 *)PSXM(madr); if (ptr == NULL) { -#ifdef CPU_LOG CDR_LOG("psxDma3() Log: *** DMA 3 *** NULL Pointer!\n"); -#endif break; } @@ -2039,9 +1818,7 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { return; default: -#ifdef CDR_LOG CDR_LOG("psxDma3() Log: Unknown cddma %x\n", chcr); -#endif break; } @@ -2068,8 +1845,8 @@ void cdrReset() { // BIOS player - default values cdr.AttenuatorLeft[0] = 0x80; cdr.AttenuatorLeft[1] = 0x00; - cdr.AttenuatorRight[0] = 0x80; - cdr.AttenuatorRight[1] = 0x00; + cdr.AttenuatorRight[0] = 0x00; + cdr.AttenuatorRight[1] = 0x80; } int cdrFreeze(void *f, int Mode) { @@ -2081,8 +1858,10 @@ int cdrFreeze(void *f, int Mode) { gzfreeze(&cdr, sizeof(cdr)); - if (Mode == 1) + if (Mode == 1) { + cdr.ParamP = cdr.ParamC; tmp = pTransfer - cdr.Transfer; + } gzfreeze(&tmp, sizeof(tmp));