X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fcdrom.c;h=3f4057954d3c5eb2830bcda0ffe405658f68896a;hb=b1eb84bc59c07b110e36714bf0222197f298ec09;hp=310ea4f273ae85ea1bf192d2ddc05d651c248e05;hpb=4f329f16f58b969df7ec9081549a7bbd70814f55;p=pcsx_rearmed.git diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index 310ea4f2..3f405795 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,7 +95,8 @@ static struct { xa_decode_t Xa; - u32 FifoOffset; + u16 FifoOffset; + u16 FifoSize; u16 CmdInProgress; u8 Irq1Pending; @@ -294,8 +295,8 @@ static void setIrq(int log_cmd) if (cdr.Stat) { int i; - SysPrintf("CDR IRQ=%d cmd %02x stat %02x: ", - !!(cdr.Stat & cdr.Reg2), log_cmd, cdr.Stat); + SysPrintf("%u cdrom: CDR IRQ=%d cmd %02x stat %02x: ", + psxRegs.cycle, !!(cdr.Stat & cdr.Reg2), log_cmd, cdr.Stat); for (i = 0; i < cdr.ResultC; i++) SysPrintf("%02x ", cdr.Result[i]); SysPrintf("\n"); @@ -544,7 +545,8 @@ static void cdrPlayInterrupt_Autopause() static int cdrSeekTime(unsigned char *target) { - int seekTime = abs(msf2sec(cdr.SetSectorPlay) - msf2sec(target)) * (cdReadTime / 200); + int diff = msf2sec(cdr.SetSectorPlay) - msf2sec(target); + int seekTime = abs(diff) * (cdReadTime / 200); /* * Gameblabla : * It was originally set to 1000000 for Driver, however it is not high enough for Worms Pinball @@ -565,7 +567,10 @@ static int cdrSeekTime(unsigned char *target) return seekTime; } +static void cdrUpdateTransferBuf(const u8 *buf); static void cdrReadInterrupt(void); +static void cdrPrepCdda(s16 *buf, int samples); +static void cdrAttenuate(s16 *buf, int samples, int stereo); void cdrPlaySeekReadInterrupt(void) { @@ -612,6 +617,7 @@ void cdrPlaySeekReadInterrupt(void) cdrPlayInterrupt_Autopause(); if (!cdr.Muted && !Config.Cdda) { + cdrPrepCdda(read_buf, CD_FRAMESIZE_RAW / 4); cdrAttenuate(read_buf, CD_FRAMESIZE_RAW / 4, 1); SPU_playCDDAchannel(read_buf, CD_FRAMESIZE_RAW, psxRegs.cycle, cdr.FirstSector); cdr.FirstSector = 0; @@ -645,7 +651,20 @@ void cdrInterrupt(void) { int i; if (cdr.Stat) { - CDR_LOG_I("cdrom: cmd %02x with irqstat %x\n", cdr.CmdInProgress, cdr.Stat); + CDR_LOG_I("%u cdrom: cmd %02x with irqstat %x\n", + psxRegs.cycle, cdr.CmdInProgress, cdr.Stat); + return; + } + 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; } @@ -1100,7 +1119,8 @@ 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_LOG_I("%u cdrom: cmd %02x came before %02x finished\n", + psxRegs.cycle, cdr.Cmd, Cmd); } setIrq(Cmd); @@ -1116,7 +1136,18 @@ void cdrInterrupt(void) { } while (0) #endif -void cdrAttenuate(s16 *buf, int samples, int stereo) +static void cdrPrepCdda(s16 *buf, int samples) +{ +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + int i; + for (i = 0; i < samples; i++) { + buf[i * 2 + 0] = SWAP16(buf[i * 2 + 0]); + buf[i * 2 + 1] = SWAP16(buf[i * 2 + 1]); + } +#endif +} + +static void cdrAttenuate(s16 *buf, int samples, int stereo) { int i, l, r; int ll = cdr.AttenuatorLeftToLeft; @@ -1176,7 +1207,8 @@ static void cdrUpdateTransferBuf(const u8 *buf) 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; + if (cdr.FifoOffset < 2048 + 12) + CDR_LOG("cdrom: FifoOffset(1) %d/%d\n", cdr.FifoOffset, cdr.FifoSize); } static void cdrReadInterrupt(void) @@ -1252,25 +1284,6 @@ static void cdrReadInterrupt(void) CDRPLAYSEEKREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime, 0); } -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; - } - if (!(psxRegs.interrupt & (1 << PSXINT_CDR)) && cdr.CmdInProgress) - CDR_INT(256); -} - /* cdrRead0: bit 0,1 - mode @@ -1333,7 +1346,7 @@ void cdrWrite1(unsigned char rt) { } #ifdef CDR_LOG_CMD_IRQ - SysPrintf("CD1 write: %x (%s)", rt, CmdName[rt]); + SysPrintf("%u cdrom: CD1 write: %x (%s)", psxRegs.cycle, rt, CmdName[rt]); if (cdr.ParamC) { int i; SysPrintf(" Param[%d] = {", cdr.ParamC); @@ -1354,8 +1367,8 @@ void cdrWrite1(unsigned char rt) { CDR_INT(5000); } else { - CDR_LOG_I("cdr: cmd while busy: %02x, prev %02x, busy %02x\n", - rt, cdr.Cmd, cdr.CmdInProgress); + CDR_LOG_I("%u cdrom: cmd while busy: %02x, prev %02x, busy %02x\n", + psxRegs.cycle, rt, cdr.Cmd, cdr.CmdInProgress); if (cdr.CmdInProgress < 0x100) // no pending 2nd response cdr.CmdInProgress = rt; } @@ -1366,10 +1379,10 @@ void cdrWrite1(unsigned char rt) { unsigned char cdrRead2(void) { unsigned char ret = 0; - if (cdr.Readed && cdr.FifoOffset < DATA_SIZE) + if (cdr.FifoOffset < cdr.FifoSize) ret = cdr.Transfer[cdr.FifoOffset++]; else - CDR_LOG_I("cdrom: read empty fifo\n"); + CDR_LOG_I("cdrom: read empty fifo (%d)\n", cdr.FifoSize); CDR_LOG_IO("cdr r2.dat: %02x\n", ret); return ret; @@ -1415,15 +1428,20 @@ void cdrWrite3(unsigned char rt) { case 0: break; // transfer case 1: + if (cdr.Stat & rt) { #ifdef CDR_LOG_CMD_IRQ - if (cdr.Stat & rt) - SysPrintf("ack %02x\n", cdr.Stat & rt); + SysPrintf("%u cdrom: ack %02x (w %02x)\n", + psxRegs.cycle, cdr.Stat & rt, rt); #endif + // note: Croc vs Discworld Noir + if (!(psxRegs.interrupt & (1 << PSXINT_CDR)) && + (cdr.CmdInProgress || cdr.Irq1Pending)) + CDR_INT(850); // 711-993 + } cdr.Stat &= ~rt; if (rt & 0x40) cdr.ParamC = 0; - doMissedIrqs(); return; case 2: cdr.AttenuatorLeftToRightT = rt; @@ -1438,21 +1456,27 @@ void cdrWrite3(unsigned char rt) { return; } - if ((rt & 0x80) && cdr.Readed == 0) { - cdr.Readed = 1; - + // 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: cdr.FifoOffset = 12; + cdr.FifoSize = 2048 + 12; break; case MODE_SIZE_2340: 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) { @@ -1464,10 +1488,6 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { switch (chcr & 0x71000000) { case 0x11000000: - if (cdr.Readed == 0) { - CDR_LOG_I("psxDma3() Log: *** DMA 3 *** NOT READY\n"); - break; - } ptr = (u8 *)PSXM(madr); if (ptr == NULL) { CDR_LOG_I("psxDma3() Log: *** DMA 3 *** NULL Pointer!\n"); @@ -1491,6 +1511,8 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { cdr.FifoOffset += size; psxCpu->Clear(madr, size / 4); } + if (size < cdsize) + CDR_LOG_I("cdrom: dma3 %d/%d\n", size, cdsize); CDRDMA_INT((cdsize/4) * 24); @@ -1506,7 +1528,7 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) { return; default: - CDR_LOG("psxDma3() Log: Unknown cddma %x\n", chcr); + CDR_LOG_I("psxDma3() Log: Unknown cddma %x\n", chcr); break; } @@ -1575,6 +1597,7 @@ int cdrFreeze(void *f, int Mode) { getCdInfo(); cdr.FifoOffset = tmp; + cdr.FifoSize = (cdr.Mode & 0x20) ? 2340 : 2048 + 12; // read right sub data tmpp[0] = btoi(cdr.Prev[0]);