X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fcdrom.c;h=921e3daa7d652a4528295fe62a5bd0f8063fd065;hb=32ac4c7454b8ba1edcd11b424f03f37ce3688349;hp=145ca32ebe051fb8c73ec4b7a084aa76ed9bc421;hpb=752c1c850b35ff0239abc4d55be091542f52bae4;p=pcsx_rearmed.git diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index 145ca32e..921e3daa 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -325,6 +325,7 @@ void cdrLidSeekInterrupt(void) if (stat.Status & STATUS_SHELLOPEN) { + memset(cdr.Prev, 0xff, sizeof(cdr.Prev)); cdr.DriveState = DRIVESTATE_LID_OPEN; CDRLID_INT(0x800); } @@ -597,8 +598,14 @@ static u32 cdrAlignTimingHack(u32 cycles) * active), but before the game's handler loop reads I_STAT. The time * window for this is quite small (~1k cycles of so). Apparently this * somehow happens naturally on the real hardware. + * + * Note: always enforcing this breaks other games like Crash PAL version + * (inputs get dropped because bios handler doesn't see interrupts). */ - u32 vint_rel = rcnts[3].cycleStart + 63000 - psxRegs.cycle; + u32 vint_rel; + if (psxRegs.cycle - rcnts[3].cycleStart > 250000) + return cycles; + vint_rel = rcnts[3].cycleStart + 63000 - psxRegs.cycle; vint_rel += PSXCLK / 60; while ((s32)(vint_rel - cycles) < 0) vint_rel += PSXCLK / 60; @@ -921,7 +928,7 @@ void cdrInterrupt(void) { SetPlaySeekRead(cdr.StatP, 0); cdr.LocL[0] = LOCL_INVALID; cdr.Muted = FALSE; - cdr.Mode = 0x20; /* This fixes This is Football 2, Pooh's Party lockups */ + cdr.Mode = MODE_SIZE_2340; /* This fixes This is Football 2, Pooh's Party lockups */ second_resp_time = not_ready ? 70000 : 4100000; start_rotating = 1; break; @@ -1152,9 +1159,10 @@ void cdrInterrupt(void) { cdr.LocL[0] = LOCL_INVALID; cdr.SubqForwardSectors = 1; - cycles = (cdr.Mode & 0x80) ? cdReadTime : cdReadTime * 2; + cycles = (cdr.Mode & MODE_SPEED) ? cdReadTime : cdReadTime * 2; cycles += seekTime; - cycles = cdrAlignTimingHack(cycles); + if (Config.hacks.cdr_read_timing) + cycles = cdrAlignTimingHack(cycles); CDRPLAYREAD_INT(cycles, 1); SetPlaySeekRead(cdr.StatP, STATUS_SEEK); @@ -1284,8 +1292,6 @@ static void cdrReadInterrupt(void) u8 subqPos[3]; int read_ok; - SetPlaySeekRead(cdr.StatP, STATUS_READ | STATUS_ROTATING); - memcpy(subqPos, cdr.SetSectorPlay, sizeof(subqPos)); msfiAdd(subqPos, cdr.SubqForwardSectors); UpdateSubq(subqPos); @@ -1295,6 +1301,9 @@ static void cdrReadInterrupt(void) return; } + // note: CdlGetlocL should work as soon as STATUS_READ is indicated + SetPlaySeekRead(cdr.StatP, STATUS_READ | STATUS_ROTATING); + read_ok = ReadTrack(cdr.SetSectorPlay); if (read_ok) buf = CDR_getBuffer(); @@ -1494,14 +1503,22 @@ void cdrWrite3(unsigned char rt) { break; // transfer case 1: if (cdr.Stat & rt) { + u32 nextCycle = psxRegs.intCycle[PSXINT_CDR].sCycle + + psxRegs.intCycle[PSXINT_CDR].cycle; #ifdef CDR_LOG_CMD_IRQ - SysPrintf("%u cdrom: ack %02x (w %02x)\n", - psxRegs.cycle, cdr.Stat & rt, rt); + SysPrintf("%u cdrom: ack %02x (w=%02x p=%d,%d)\n", + psxRegs.cycle, cdr.Stat & rt, rt, + !!(psxRegs.interrupt & (1 << PSXINT_CDR)), + nextCycle - psxRegs.cycle); #endif - // note: Croc vs Discworld Noir + // note: Croc, Shadow Tower (more) vs Discworld Noir (<993) if (!(psxRegs.interrupt & (1 << PSXINT_CDR)) && (cdr.CmdInProgress || cdr.Irq1Pending)) - CDR_INT(850); // 711-993 + { + s32 c = 2048 - (psxRegs.cycle - nextCycle); + c = MAX_VALUE(c, 512); + CDR_INT(c); + } } cdr.Stat &= ~rt; @@ -1526,7 +1543,7 @@ void cdrWrite3(unsigned char rt) { CDR_LOG("cdrom: FifoOffset(2) %d/%d\n", cdr.FifoOffset, cdr.FifoSize); } else if (rt & 0x80) { - switch (cdr.Mode & 0x30) { + switch (cdr.Mode & (MODE_SIZE_2328|MODE_SIZE_2340)) { case MODE_SIZE_2328: case 0x00: cdr.FifoOffset = 12; @@ -1670,7 +1687,7 @@ int cdrFreeze(void *f, int Mode) { getCdInfo(); cdr.FifoOffset = tmp < DATA_SIZE ? tmp : DATA_SIZE; - cdr.FifoSize = (cdr.Mode & 0x20) ? 2340 : 2048 + 12; + cdr.FifoSize = (cdr.Mode & MODE_SIZE_2340) ? 2340 : 2048 + 12; if (cdr.SubqForwardSectors > SUBQ_FORWARD_SECTORS) cdr.SubqForwardSectors = SUBQ_FORWARD_SECTORS; @@ -1689,7 +1706,7 @@ int cdrFreeze(void *f, int Mode) { if (!Config.Cdda) CDR_play(cdr.SetSectorPlay); if (psxRegs.interrupt & (1 << PSXINT_CDRPLAY_OLD)) - CDRPLAYREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime, 1); + CDRPLAYREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime, 1); } if ((cdr.freeze_ver & 0xffffff00) != 0x63647200) {