X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fcdrom.c;h=3fafc1985d68f740709c125513e13778a5bb765f;hb=6c9db47c7c54b925e00a96b17faa05e17d6af262;hp=772e76f036e2a65f18f2ba505c03271fb10779c6;hpb=7f2576b26c2372738c528741d7cf8c307736e623;p=pcsx_rearmed.git diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index 772e76f0..3fafc198 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -35,7 +35,7 @@ #if 0 #define CDR_LOG_I SysPrintf #else -#define CDR_LOG_I(...) +#define CDR_LOG_I log_unhandled #endif #if 0 #define CDR_LOG_IO SysPrintf @@ -76,7 +76,7 @@ static struct { unsigned char ResultP; unsigned char ResultReady; unsigned char Cmd; - unsigned char Readed; + unsigned char unused4; unsigned char SetlocPending; u32 Reading; @@ -95,10 +95,12 @@ static struct { xa_decode_t Xa; - u32 unused4; + u16 FifoOffset; + u16 FifoSize; u16 CmdInProgress; - u16 unused5; + u8 Irq1Pending; + u8 unused5; u32 unused6; u8 unused7; @@ -113,7 +115,6 @@ static struct { u8 AttenuatorLeftToLeftT, AttenuatorLeftToRightT; u8 AttenuatorRightToRightT, AttenuatorRightToLeftT; } cdr; -static unsigned char *pTransfer; static s16 read_buf[CD_FRAMESIZE_RAW/2]; /* CD-ROM magic numbers */ @@ -584,10 +585,8 @@ void cdrPlaySeekReadInterrupt(void) cdr.StatP |= STATUS_ROTATING; SetPlaySeekRead(cdr.StatP, 0); cdr.Result[0] = cdr.StatP; - if (cdr.Stat == 0) { - cdr.Stat = Complete; - setIrq(0x202); - } + cdr.Stat = Complete; + setIrq(0x202); Find_CurTrack(cdr.SetSectorPlay); ReadTrack(cdr.SetSectorPlay); @@ -629,10 +628,10 @@ void cdrPlaySeekReadInterrupt(void) } } - CDRPLAYSEEKREAD_INT(cdReadTime, 0); - // update for CdlGetlocP/autopause generate_subq(cdr.SetSectorPlay); + + CDRPLAYSEEKREAD_INT(cdReadTime, 0); } void cdrInterrupt(void) { @@ -646,10 +645,8 @@ void cdrInterrupt(void) { u16 Cmd; int i; - // Reschedule IRQ if (cdr.Stat) { CDR_LOG_I("cdrom: cmd %02x with irqstat %x\n", cdr.CmdInProgress, cdr.Stat); - CDR_INT(1000); return; } @@ -1105,7 +1102,6 @@ void cdrInterrupt(void) { 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); - CDR_INT(256); } setIrq(Cmd); @@ -1159,46 +1155,60 @@ void cdrAttenuate(s16 *buf, int samples, int stereo) } } -static void cdrReadInterrupt(void) +static void cdrReadInterruptSetResult(unsigned char result) { - u8 *buf; - if (cdr.Stat) { - CDR_LOG_I("cdrom: read stat hack %02x %02x\n", cdr.Cmd, cdr.Stat); - CDRPLAYSEEKREAD_INT(2048, 1); + 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); +} + +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]); + if (cdr.FifoOffset < 2048 + 12) + CDR_LOG("cdrom: FifoOffset(1) %d/%d\n", cdr.FifoOffset, cdr.FifoSize); +} + +static void cdrReadInterrupt(void) +{ + u8 *buf = NULL, *hdr; + 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; - setIrq(0x205); + 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 @@ -1206,10 +1216,8 @@ static void cdrReadInterrupt(void) * 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, psxRegs.cycle, cdr.FirstSector); @@ -1219,6 +1227,15 @@ static void cdrReadInterrupt(void) } } + /* + 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; @@ -1229,23 +1246,31 @@ static void cdrReadInterrupt(void) } } - cdr.Readed = 0; + if (!cdr.Irq1Pending) { + // update for CdlGetlocP + ReadTrack(cdr.SetSectorPlay); + } CDRPLAYSEEKREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime, 0); +} - /* - Croc 2: $40 - only FORM1 (*) - Judge Dredd: $C8 - only FORM1 (*) - Sim Theme Park - no adpcm at all (zero) - */ - - 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); } /* @@ -1341,13 +1366,12 @@ void cdrWrite1(unsigned char rt) { } unsigned char cdrRead2(void) { - unsigned char ret; + unsigned char ret = 0; - if (cdr.Readed == 0) { - ret = 0; - } else { - ret = *pTransfer++; - } + if (cdr.FifoOffset < cdr.FifoSize) + ret = cdr.Transfer[cdr.FifoOffset++]; + else + CDR_LOG_I("cdrom: read empty fifo (%d)\n", cdr.FifoSize); CDR_LOG_IO("cdr r2.dat: %02x\n", ret); return ret; @@ -1401,6 +1425,7 @@ void cdrWrite3(unsigned char rt) { if (rt & 0x40) cdr.ParamC = 0; + doMissedIrqs(); return; case 2: cdr.AttenuatorLeftToRightT = rt; @@ -1415,24 +1440,27 @@ void cdrWrite3(unsigned char rt) { return; } - if ((rt & 0x80) && cdr.Readed == 0) { - cdr.Readed = 1; - pTransfer = cdr.Transfer; - + // test: Viewpoint + if ((rt & 0x80) && cdr.FifoOffset < cdr.FifoSize) { + CDR_LOG("cdrom: FifoOffset(2) %d/%d\n", cdr.FifoOffset, cdr.FifoSize); + } + else if (rt & 0x80) { switch (cdr.Mode & 0x30) { case MODE_SIZE_2328: case 0x00: - pTransfer += 12; + cdr.FifoOffset = 12; + cdr.FifoSize = 2048 + 12; break; case MODE_SIZE_2340: - pTransfer += 0; - break; - default: + cdr.FifoOffset = 0; + cdr.FifoSize = 2340; break; } } + else if (!(rt & 0xc0)) + cdr.FifoOffset = DATA_SIZE; // fifo empty } void psxDma3(u32 madr, u32 bcr, u32 chcr) { @@ -1442,66 +1470,49 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { CDR_LOG("psxDma3() Log: *** DMA 3 *** %x addr = %x size = %x\n", chcr, madr, bcr); - switch (chcr) { + switch (chcr & 0x71000000) { case 0x11000000: - case 0x11400100: - if (cdr.Readed == 0) { - CDR_LOG("psxDma3() Log: *** DMA 3 *** NOT READY\n"); - break; - } - - cdsize = (bcr & 0xffff) * 4; - - // Ape Escape: bcr = 0001 / 0000 - // - fix boot - if( cdsize == 0 ) - { - switch (cdr.Mode & (MODE_SIZE_2340|MODE_SIZE_2328)) { - case MODE_SIZE_2340: cdsize = 2340; break; - case MODE_SIZE_2328: cdsize = 2328; break; - default: - case MODE_SIZE_2048: cdsize = 2048; break; - } - } - - ptr = (u8 *)PSXM(madr); if (ptr == NULL) { - CDR_LOG("psxDma3() Log: *** DMA 3 *** NULL Pointer!\n"); + CDR_LOG_I("psxDma3() Log: *** DMA 3 *** NULL Pointer!\n"); break; } + cdsize = (((bcr - 1) & 0xffff) + 1) * 4; + /* GS CDX: Enhancement CD crash - Setloc 0:0:0 - CdlPlay - Spams DMA3 and gets buffer overrun */ - size = CD_FRAMESIZE_RAW - (pTransfer - cdr.Transfer); + size = DATA_SIZE - cdr.FifoOffset; if (size > cdsize) size = cdsize; if (size > 0) { - memcpy(ptr, pTransfer, size); + memcpy(ptr, cdr.Transfer + cdr.FifoOffset, size); + cdr.FifoOffset += size; + psxCpu->Clear(madr, size / 4); } + if (size < cdsize) + CDR_LOG_I("cdrom: dma3 %d/%d\n", size, cdsize); - psxCpu->Clear(madr, cdsize / 4); - pTransfer += cdsize; + CDRDMA_INT((cdsize/4) * 24); - if( chcr == 0x11400100 ) { + HW_DMA3_CHCR &= SWAPu32(~0x10000000); + if (chcr & 0x100) { HW_DMA3_MADR = SWAPu32(madr + cdsize); - CDRDMA_INT( (cdsize/4) / 4 ); + HW_DMA3_BCR &= SWAPu32(0xffff0000); } - else if( chcr == 0x11000000 ) { - // CDRDMA_INT( (cdsize/4) * 1 ); + else { // halted - psxRegs.cycle += (cdsize/4) * 24/2; - CDRDMA_INT(16); + psxRegs.cycle += (cdsize/4) * 24 - 20; } return; default: - CDR_LOG("psxDma3() Log: Unknown cddma %x\n", chcr); + CDR_LOG_I("psxDma3() Log: Unknown cddma %x\n", chcr); break; } @@ -1538,7 +1549,7 @@ void cdrReset() { cdr.Stat = NoIntr; cdr.DriveState = DRIVESTATE_STANDBY; cdr.StatP = STATUS_ROTATING; - pTransfer = cdr.Transfer; + cdr.FifoOffset = DATA_SIZE; // fifo empty // BIOS player - default values cdr.AttenuatorLeftToLeft = 0x80; @@ -1561,7 +1572,7 @@ int cdrFreeze(void *f, int Mode) { if (Mode == 1) { cdr.ParamP = cdr.ParamC; - tmp = pTransfer - cdr.Transfer; + tmp = cdr.FifoOffset; } gzfreeze(&tmp, sizeof(tmp)); @@ -1569,7 +1580,8 @@ int cdrFreeze(void *f, int Mode) { if (Mode == 0) { getCdInfo(); - pTransfer = cdr.Transfer + tmp; + cdr.FifoOffset = tmp; + cdr.FifoSize = (cdr.Mode & 0x20) ? 2340 : 2048 + 12; // read right sub data tmpp[0] = btoi(cdr.Prev[0]);