X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fcdrom.c;h=3c016dfd2be1c8fd7c2fc35f3b1e77cb14a085bb;hb=f5450cfbaf8651524f23579832ddb5bc08fe545a;hp=5dfa658dc7d96b70899ec37f493ed601878737c3;hpb=f522e63c1182d8a7f1ca7de3b5c06c47a5d22bbb;p=pcsx_rearmed.git diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index 5dfa658d..3c016dfd 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -45,10 +45,11 @@ //#define CDR_LOG_CMD_IRQ static struct { - unsigned char OCUP; - unsigned char Reg1Mode; + // unused members maintain savesate compatibility + unsigned char unused0; + unsigned char unused1; unsigned char Reg2; - unsigned char CmdProcess; + unsigned char unused2; unsigned char Ctrl; unsigned char Stat; @@ -62,7 +63,7 @@ static struct { unsigned char Absolute[3]; } subq; unsigned char TrackChanged; - unsigned char pad1[3]; + unsigned char unused3[3]; unsigned int freeze_ver; unsigned char Prev[4]; @@ -94,18 +95,19 @@ static struct { xa_decode_t Xa; - int Init; + u32 unused4; - u16 Irq; - u8 IrqRepeated; - u32 eCycle; + u16 CmdInProgress; + u8 Irq1Pending; + u8 unused5; + u32 unused6; - u8 pad2; + u8 unused7; u8 DriveState; u8 FastForward; u8 FastBackward; - u8 pad; + u8 unused8; u8 AttenuatorLeftToLeft, AttenuatorLeftToRight; u8 AttenuatorRightToRight, AttenuatorRightToLeft; @@ -241,12 +243,16 @@ static void sec2msf(unsigned int s, u8 *msf) { new_dyna_set_event(PSXINT_CDR, eCycle); \ } -// cdrReadInterrupt -#define CDREAD_INT(eCycle) { \ +// cdrPlaySeekReadInterrupt +#define CDRPLAYSEEKREAD_INT(eCycle, isFirst) { \ + u32 e_ = eCycle; \ psxRegs.interrupt |= (1 << PSXINT_CDREAD); \ - psxRegs.intCycle[PSXINT_CDREAD].cycle = eCycle; \ - psxRegs.intCycle[PSXINT_CDREAD].sCycle = psxRegs.cycle; \ - new_dyna_set_event(PSXINT_CDREAD, eCycle); \ + if (isFirst) \ + psxRegs.intCycle[PSXINT_CDREAD].sCycle = psxRegs.cycle; \ + else \ + psxRegs.intCycle[PSXINT_CDREAD].sCycle += psxRegs.intCycle[PSXINT_CDREAD].cycle; \ + psxRegs.intCycle[PSXINT_CDREAD].cycle = e_; \ + new_dyna_set_event_abs(PSXINT_CDREAD, psxRegs.intCycle[PSXINT_CDREAD].sCycle + e_); \ } // cdrLidSeekInterrupt @@ -257,14 +263,6 @@ static void sec2msf(unsigned int s, u8 *msf) { new_dyna_set_event(PSXINT_CDRLID, eCycle); \ } -// cdrPlayInterrupt -#define CDRSEEKPLAY_INT(eCycle) { \ - psxRegs.interrupt |= (1 << PSXINT_CDRPLAY); \ - psxRegs.intCycle[PSXINT_CDRPLAY].cycle = eCycle; \ - psxRegs.intCycle[PSXINT_CDRPLAY].sCycle = psxRegs.cycle; \ - new_dyna_set_event(PSXINT_CDRPLAY, eCycle); \ -} - #define StopReading() { \ cdr.Reading = 0; \ psxRegs.interrupt &= ~(1 << PSXINT_CDREAD); \ @@ -294,6 +292,7 @@ static void setIrq(int log_cmd) psxHu32ref(0x1070) |= SWAP32((u32)0x4); #ifdef CDR_LOG_CMD_IRQ + if (cdr.Stat) { int i; SysPrintf("CDR IRQ=%d cmd %02x stat %02x: ", @@ -307,7 +306,7 @@ static void setIrq(int log_cmd) // timing used in this function was taken from tests on real hardware // (yes it's slow, but you probably don't want to modify it) -void cdrLidSeekInterrupt() +void cdrLidSeekInterrupt(void) { switch (cdr.DriveState) { default: @@ -485,23 +484,6 @@ static void ReadTrack(const u8 *time) { cdr.subq.Absolute[0], cdr.subq.Absolute[1], cdr.subq.Absolute[2]); } -static void AddIrqQueue(unsigned short irq, unsigned long ecycle) { - if (cdr.Irq != 0) { - if (irq == cdr.Irq || irq + 0x100 == cdr.Irq) { - cdr.IrqRepeated = 1; - CDR_INT(ecycle); - return; - } - - CDR_LOG_I("cdr: override cmd %02x -> %02x\n", cdr.Irq, irq); - } - - cdr.Irq = irq; - cdr.eCycle = ecycle; - - CDR_INT(ecycle); -} - static void cdrPlayInterrupt_Autopause() { u32 abs_lev_max = 0; @@ -584,27 +566,32 @@ static int cdrSeekTime(unsigned char *target) return seekTime; } -// also handles seek -void cdrPlayInterrupt() +static void cdrReadInterrupt(void); + +void cdrPlaySeekReadInterrupt(void) { - if (cdr.StatP & STATUS_SEEK) { + if (cdr.Reading) { + cdrReadInterrupt(); + return; + } + + if (!cdr.Play && (cdr.StatP & STATUS_SEEK)) { if (cdr.Stat) { CDR_LOG_I("cdrom: seek stat hack\n"); - CDRSEEKPLAY_INT(0x1000); + CDRPLAYSEEKREAD_INT(0x1000, 1); return; } SetResultSize(1); cdr.StatP |= STATUS_ROTATING; - SetPlaySeekRead(cdr.StatP, cdr.Play ? STATUS_PLAY : 0); + SetPlaySeekRead(cdr.StatP, 0); cdr.Result[0] = cdr.StatP; - if (cdr.Irq == 0) { - cdr.Stat = Complete; - setIrq(0x202); - } + cdr.Stat = Complete; + setIrq(0x202); Find_CurTrack(cdr.SetSectorPlay); ReadTrack(cdr.SetSectorPlay); cdr.TrackChanged = FALSE; + return; } if (!cdr.Play) return; @@ -612,6 +599,7 @@ void cdrPlayInterrupt() CDR_LOG( "CDDA - %d:%d:%d\n", cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2] ); + SetPlaySeekRead(cdr.StatP, STATUS_PLAY); if (memcmp(cdr.SetSectorPlay, cdr.SetSectorEnd, 3) == 0) { StopCdda(); SetPlaySeekRead(cdr.StatP, 0); @@ -621,13 +609,13 @@ void cdrPlayInterrupt() CDR_readCDDA(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2], (u8 *)read_buf); } - if (!cdr.Irq && !cdr.Stat && (cdr.Mode & (MODE_AUTOPAUSE|MODE_REPORT))) + if (!cdr.Stat && (cdr.Mode & (MODE_AUTOPAUSE|MODE_REPORT))) cdrPlayInterrupt_Autopause(); - if (CDR_readCDDA && !cdr.Muted && !Config.Cdda) { + if (!cdr.Muted && !Config.Cdda) { cdrAttenuate(read_buf, CD_FRAMESIZE_RAW / 4, 1); - if (SPU_playCDDAchannel) - SPU_playCDDAchannel(read_buf, CD_FRAMESIZE_RAW); + SPU_playCDDAchannel(read_buf, CD_FRAMESIZE_RAW, psxRegs.cycle, cdr.FirstSector); + cdr.FirstSector = 0; } cdr.SetSectorPlay[2]++; @@ -640,26 +628,25 @@ void cdrPlayInterrupt() } } - CDRSEEKPLAY_INT(cdReadTime); - // update for CdlGetlocP/autopause generate_subq(cdr.SetSectorPlay); + + CDRPLAYSEEKREAD_INT(cdReadTime, 0); } -void cdrInterrupt() { - u16 Irq = cdr.Irq; +void cdrInterrupt(void) { int no_busy_error = 0; int start_rotating = 0; int error = 0; - int delay; unsigned int seekTime = 0; + u32 second_resp_time = 0; + u8 ParamC; u8 set_loc[3]; + u16 Cmd; int i; - // Reschedule IRQ if (cdr.Stat) { - CDR_LOG_I("cdrom: stat hack: %02x %x\n", cdr.Irq, cdr.Stat); - CDR_INT(0x1000); + CDR_LOG_I("cdrom: cmd %02x with irqstat %x\n", cdr.CmdInProgress, cdr.Stat); return; } @@ -670,17 +657,16 @@ void cdrInterrupt() { cdr.Result[0] = cdr.StatP; cdr.Stat = Acknowledge; - if (cdr.IrqRepeated) { - cdr.IrqRepeated = 0; - if (cdr.eCycle > psxRegs.cycle) { - CDR_INT(cdr.eCycle); - goto finish; - } - } + Cmd = cdr.CmdInProgress; + cdr.CmdInProgress = 0; + ParamC = cdr.ParamC; - cdr.Irq = 0; + if (Cmd < 0x100) { + cdr.Cmd = 0; + cdr.ParamC = 0; + } - switch (Irq) { + switch (Cmd) { case CdlNop: if (cdr.DriveState != DRIVESTATE_LID_OPEN) cdr.StatP &= ~STATUS_SHELLOPEN; @@ -718,7 +704,7 @@ void cdrInterrupt() { // BIOS CD Player // - Pause player, hit Track 01/02/../xx (Setloc issued!!) - if (cdr.ParamC != 0 && cdr.Param[0] != 0) { + if (ParamC != 0 && cdr.Param[0] != 0) { int track = btoi( cdr.Param[0] ); if (track <= cdr.ResultTN[1]) @@ -756,6 +742,7 @@ void cdrInterrupt() { Find_CurTrack(cdr.SetSectorPlay); ReadTrack(cdr.SetSectorPlay); cdr.TrackChanged = FALSE; + cdr.FirstSector = 1; if (!Config.Cdda) CDR_play(cdr.SetSectorPlay); @@ -765,7 +752,7 @@ void cdrInterrupt() { // BIOS player - set flag again cdr.Play = TRUE; - CDRSEEKPLAY_INT(cdReadTime + seekTime); + CDRPLAYSEEKREAD_INT(cdReadTime + seekTime, 1); start_rotating = 1; break; @@ -791,7 +778,7 @@ void cdrInterrupt() { error = ERROR_INVALIDARG; goto set_error; } - AddIrqQueue(CdlStandby + 0x100, cdReadTime * 125 / 2); + second_resp_time = cdReadTime * 125 / 2; start_rotating = 1; break; @@ -814,12 +801,11 @@ void cdrInterrupt() { SetPlaySeekRead(cdr.StatP, 0); cdr.StatP &= ~STATUS_ROTATING; - delay = 0x800; + second_resp_time = 0x800; if (cdr.DriveState == DRIVESTATE_STANDBY) - delay = cdReadTime * 30 / 2; + second_resp_time = cdReadTime * 30 / 2; cdr.DriveState = DRIVESTATE_STOPPED; - AddIrqQueue(CdlStop + 0x100, delay); break; case CdlStop + 0x100: @@ -846,13 +832,12 @@ void cdrInterrupt() { * */ if (!(cdr.StatP & (STATUS_PLAY | STATUS_READ))) { - delay = 7000; + second_resp_time = 7000; } else { - delay = (((cdr.Mode & MODE_SPEED) ? 2 : 1) * (1000000)); + second_resp_time = (((cdr.Mode & MODE_SPEED) ? 2 : 1) * 1000000); } - AddIrqQueue(CdlPause + 0x100, delay); SetPlaySeekRead(cdr.StatP, 0); cdr.Ctrl |= 0x80; break; @@ -867,7 +852,7 @@ void cdrInterrupt() { SetPlaySeekRead(cdr.StatP, 0); cdr.Muted = FALSE; cdr.Mode = 0x20; /* This fixes This is Football 2, Pooh's Party lockups */ - AddIrqQueue(CdlReset + 0x100, 4100000); + second_resp_time = 4100000; no_busy_error = 1; start_rotating = 1; break; @@ -890,6 +875,8 @@ void cdrInterrupt() { break; case CdlSetmode: + CDR_LOG("cdrWrite1() Log: Setmode %x\n", cdr.Param[0]); + cdr.Mode = cdr.Param[0]; no_busy_error = 1; break; @@ -915,7 +902,7 @@ void cdrInterrupt() { case CdlReadT: // SetSession? // really long - AddIrqQueue(CdlReadT + 0x100, cdReadTime * 290 / 4); + second_resp_time = cdReadTime * 290 / 4; start_rotating = 1; break; @@ -973,7 +960,7 @@ void cdrInterrupt() { Rockman X5 = 0.5-4x - fix capcom logo */ - CDRSEEKPLAY_INT(cdReadTime + seekTime); + CDRPLAYSEEKREAD_INT(cdReadTime + seekTime, 1); start_rotating = 1; break; @@ -996,7 +983,7 @@ void cdrInterrupt() { break; case CdlID: - AddIrqQueue(CdlID + 0x100, 20480); + second_resp_time = 20480; break; case CdlID + 0x100: @@ -1018,7 +1005,8 @@ void cdrInterrupt() { } cdr.Result[0] |= (cdr.Result[1] >> 4) & 0x08; - strncpy((char *)&cdr.Result[4], "PCSX", 4); + /* This adds the string "PCSX" in Playstation bios boot screen */ + memcpy((char *)&cdr.Result[4], "PCSX", 4); cdr.Stat = Complete; break; @@ -1039,7 +1027,7 @@ void cdrInterrupt() { break; case CdlReadToc: - AddIrqQueue(CdlReadToc + 0x100, cdReadTime * 180 / 4); + second_resp_time = cdReadTime * 180 / 4; no_busy_error = 1; start_rotating = 1; break; @@ -1070,47 +1058,14 @@ void cdrInterrupt() { // - fixes new game ReadTrack(cdr.SetSectorPlay); - - // Crusaders of Might and Magic - update getlocl now - // - fixes cutscene speech - { - u8 *buf = CDR_getBuffer(); - 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 - */ - - /* - By nicolasnoble from PCSX Redux : - "It LOOKS like this logic is wrong, therefore disabling it with `&& false` for now. - For "PoPoLoCrois Monogatari II", the game logic will soft lock and will never issue GetLocP to detect - the end of its XA streams, as it seems to assume ReadS will not return a status byte with the SEEK - flag set. I think the reasonning is that since it's invalid to call GetLocP while seeking, the game - tries to protect itself against errors by preventing from issuing a GetLocP while it knows the - last status was "seek". But this makes the logic just softlock as it'll never get a notification - about the fact the drive is done seeking and the read actually started. - - In other words, this state machine here is probably wrong in assuming the response to ReadS/ReadN is - done right away. It's rather when it's done seeking, and the read has actually started. This probably - requires a bit more work to make sure seek delays are processed properly. - Checked with a few games, this seems to work fine." - - Gameblabla additional notes : - This still needs the "+ seekTime" that PCSX Redux doesn't have for the Driver "retry" mission error. - */ - CDREAD_INT(((cdr.Mode & 0x80) ? (cdReadTime) : cdReadTime * 2) + seekTime); + CDRPLAYSEEKREAD_INT(((cdr.Mode & 0x80) ? (cdReadTime) : cdReadTime * 2) + seekTime, 1); SetPlaySeekRead(cdr.StatP, STATUS_SEEK); start_rotating = 1; break; case CdlSync: default: - CDR_LOG_I("Invalid command: %02x\n", Irq); + CDR_LOG_I("Invalid command: %02x\n", Cmd); error = ERROR_INVALIDCMD; // FALLTHROUGH @@ -1140,9 +1095,16 @@ void cdrInterrupt() { } } -finish: - setIrq(Irq); - cdr.ParamC = 0; + if (second_resp_time) { + cdr.CmdInProgress = Cmd | 0x100; + CDR_INT(second_resp_time); + } + else if (cdr.Cmd && cdr.Cmd != (Cmd & 0xff)) { + cdr.CmdInProgress = cdr.Cmd; + CDR_LOG_I("cdrom: cmd %02x came before %02x finished\n", cdr.Cmd, Cmd); + } + + setIrq(Cmd); } #ifdef HAVE_ARMV7 @@ -1193,49 +1155,59 @@ void cdrAttenuate(s16 *buf, int samples, int stereo) } } -void cdrReadInterrupt() { - u8 *buf; - - if (!cdr.Reading) +static void cdrReadInterruptSetResult(unsigned char result) +{ + if (cdr.Stat) { + CDR_LOG_I("cdrom: %d:%02d:%02d irq miss, cmd=%02x irqstat=%02x\n", + cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2], + cdr.CmdInProgress, cdr.Stat); + cdr.Irq1Pending = result; return; + } + SetResultSize(1); + cdr.Result[0] = result; + cdr.Stat = (result & STATUS_ERROR) ? DiskError : DataReady; + setIrq(0x203); +} - if (cdr.Irq || cdr.Stat) { - CDR_LOG_I("cdrom: read stat hack %02x %x\n", cdr.Irq, cdr.Stat); - CDREAD_INT(2048); +static void cdrUpdateTransferBuf(const u8 *buf) +{ + if (!buf) return; - } + memcpy(cdr.Transfer, buf, DATA_SIZE); + CheckPPFCache(cdr.Transfer, cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]); + CDR_LOG("cdr.Transfer %x:%x:%x\n", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); + cdr.Readed = 0; +} + +static void cdrReadInterrupt(void) +{ + u8 *buf = NULL, *hdr; - cdr.OCUP = 1; - SetResultSize(1); SetPlaySeekRead(cdr.StatP, STATUS_READ | STATUS_ROTATING); - cdr.Result[0] = cdr.StatP; ReadTrack(cdr.SetSectorPlay); - - buf = CDR_getBuffer(); + if (cdr.NoErr) + buf = CDR_getBuffer(); if (buf == NULL) cdr.NoErr = 0; if (!cdr.NoErr) { CDR_LOG_I("cdrReadInterrupt() Log: err\n"); memset(cdr.Transfer, 0, DATA_SIZE); - cdr.Stat = DiskError; - cdr.Result[0] |= STATUS_ERROR; - CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); + cdrReadInterruptSetResult(cdr.StatP | STATUS_ERROR); return; } - memcpy(cdr.Transfer, buf, DATA_SIZE); - CheckPPFCache(cdr.Transfer, cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]); - - - CDR_LOG("cdrReadInterrupt() Log: cdr.Transfer %x:%x:%x\n", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); + if (!cdr.Irq1Pending) + cdrUpdateTransferBuf(buf); if ((!cdr.Muted) && (cdr.Mode & MODE_STRSND) && (!Config.Xa) && (cdr.FirstSector != -1)) { // CD-XA + hdr = buf + 4; // 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]; + cdr.File = hdr[0]; + cdr.Channel = hdr[1]; } /* Gameblabla @@ -1243,19 +1215,26 @@ void cdrReadInterrupt() { * 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.Channel != 255) { - int ret = xa_decode_sector(&cdr.Xa, cdr.Transfer+4, cdr.FirstSector); + if ((hdr[2] & 0x4) && hdr[0] == cdr.File && hdr[1] == cdr.Channel && cdr.Channel != 255) { + int ret = xa_decode_sector(&cdr.Xa, buf + 4, cdr.FirstSector); if (!ret) { cdrAttenuate(cdr.Xa.pcm, cdr.Xa.nsamples, cdr.Xa.stereo); - SPU_playADPCMchannel(&cdr.Xa); + SPU_playADPCMchannel(&cdr.Xa, psxRegs.cycle, cdr.FirstSector); cdr.FirstSector = 0; } else cdr.FirstSector = -1; } } + /* + Croc 2: $40 - only FORM1 (*) + Judge Dredd: $C8 - only FORM1 (*) + Sim Theme Park - no adpcm at all (zero) + */ + + if (!(cdr.Mode & MODE_STRSND) || !(buf[4+2] & 0x4)) + cdrReadInterruptSetResult(cdr.StatP); + cdr.SetSectorPlay[2]++; if (cdr.SetSectorPlay[2] == 75) { cdr.SetSectorPlay[2] = 0; @@ -1266,23 +1245,31 @@ void cdrReadInterrupt() { } } - cdr.Readed = 0; - - CDREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime); + if (!cdr.Irq1Pending) { + // update for CdlGetlocP + ReadTrack(cdr.SetSectorPlay); + } - /* - Croc 2: $40 - only FORM1 (*) - Judge Dredd: $C8 - only FORM1 (*) - Sim Theme Park - no adpcm at all (zero) - */ + CDRPLAYSEEKREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime, 0); +} - if (!(cdr.Mode & MODE_STRSND) || !(cdr.Transfer[4+2] & 0x4)) { - cdr.Stat = DataReady; - setIrq(0x203); +static void doMissedIrqs(void) +{ + if (cdr.Irq1Pending) + { + // hand out the "newest" sector, according to nocash + cdrUpdateTransferBuf(CDR_getBuffer()); + CDR_LOG_I("cdrom: %x:%02x:%02x loaded on ack\n", + cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); + SetResultSize(1); + cdr.Result[0] = cdr.Irq1Pending; + cdr.Stat = (cdr.Irq1Pending & STATUS_ERROR) ? DiskError : DataReady; + cdr.Irq1Pending = 0; + setIrq(0x205); + return; } - - // update for CdlGetlocP - ReadTrack(cdr.SetSectorPlay); + if (!(psxRegs.interrupt & (1 << PSXINT_CDR)) && cdr.CmdInProgress) + CDR_INT(256); } /* @@ -1302,10 +1289,7 @@ unsigned char cdrRead0(void) { else cdr.Ctrl &= ~0x20; - if (cdr.OCUP) - cdr.Ctrl |= 0x40; -// else -// cdr.Ctrl &= ~0x40; + cdr.Ctrl |= 0x40; // data fifo not empty // What means the 0x10 and the 0x08 bits? I only saw it used by the bios cdr.Ctrl |= 0x18; @@ -1349,9 +1333,6 @@ void cdrWrite1(unsigned char rt) { return; } - cdr.Cmd = rt; - cdr.OCUP = 0; - #ifdef CDR_LOG_CMD_IRQ SysPrintf("CD1 write: %x (%s)", rt, CmdName[rt]); if (cdr.ParamC) { @@ -1367,16 +1348,20 @@ void cdrWrite1(unsigned char rt) { cdr.ResultReady = 0; cdr.Ctrl |= 0x80; - // cdr.Stat = NoIntr; - AddIrqQueue(cdr.Cmd, 0x800); - - switch (cdr.Cmd) { - case CdlSetmode: - CDR_LOG("cdrWrite1() Log: Setmode %x\n", cdr.Param[0]); - cdr.Mode = cdr.Param[0]; - break; + if (!cdr.CmdInProgress) { + cdr.CmdInProgress = rt; + // should be something like 12k + controller delays + CDR_INT(5000); } + else { + CDR_LOG_I("cdr: cmd while busy: %02x, prev %02x, busy %02x\n", + rt, cdr.Cmd, cdr.CmdInProgress); + if (cdr.CmdInProgress < 0x100) // no pending 2nd response + cdr.CmdInProgress = rt; + } + + cdr.Cmd = rt; } unsigned char cdrRead2(void) { @@ -1432,10 +1417,15 @@ void cdrWrite3(unsigned char rt) { case 0: break; // transfer case 1: +#ifdef CDR_LOG_CMD_IRQ + if (cdr.Stat & rt) + SysPrintf("ack %02x\n", cdr.Stat & rt); +#endif cdr.Stat &= ~rt; if (rt & 0x40) cdr.ParamC = 0; + doMissedIrqs(); return; case 2: cdr.AttenuatorLeftToRightT = rt; @@ -1443,7 +1433,7 @@ void cdrWrite3(unsigned char rt) { case 3: if (rt & 0x20) { memcpy(&cdr.AttenuatorLeftToLeft, &cdr.AttenuatorLeftToLeftT, 4); - CDR_LOG_I("CD-XA Volume: %02x %02x | %02x %02x\n", + CDR_LOG("CD-XA Volume: %02x %02x | %02x %02x\n", cdr.AttenuatorLeftToLeft, cdr.AttenuatorLeftToRight, cdr.AttenuatorRightToLeft, cdr.AttenuatorRightToRight); } @@ -1481,7 +1471,7 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { case 0x11000000: case 0x11400100: if (cdr.Readed == 0) { - CDR_LOG("psxDma3() Log: *** DMA 3 *** NOT READY\n"); + CDR_LOG_I("psxDma3() Log: *** DMA 3 *** NOT READY\n"); break; } @@ -1544,7 +1534,7 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { DMA_INTERRUPT(3); } -void cdrDmaInterrupt() +void cdrDmaInterrupt(void) { if (HW_DMA3_CHCR & SWAP32(0x01000000)) { @@ -1620,6 +1610,8 @@ int cdrFreeze(void *f, int Mode) { Find_CurTrack(cdr.SetSectorPlay); if (!Config.Cdda) CDR_play(cdr.SetSectorPlay); + if (psxRegs.interrupt & (1 << PSXINT_CDRPLAY_OLD)) + CDRPLAYSEEKREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime, 1); } if ((cdr.freeze_ver & 0xffffff00) != 0x63647200) { @@ -1640,7 +1632,7 @@ int cdrFreeze(void *f, int Mode) { return 0; } -void LidInterrupt() { +void LidInterrupt(void) { getCdInfo(); cdrLidSeekInterrupt(); }