- if (cdr.SetlocPending) {
- memcpy(cdr.SetSectorPlay, cdr.SetSector, 4);
- cdr.SetlocPending = 0;
- }
- Find_CurTrack(cdr.SetSectorPlay);
- ReadTrack(cdr.SetSectorPlay);
- cdr.TrackChanged = FALSE;
+static u32 cdrAlignTimingHack(u32 cycles)
+{
+ /*
+ * timing hack for T'ai Fu - Wrath of the Tiger:
+ * The game has a bug where it issues some cdc commands from a low priority
+ * vint handler, however there is a higher priority default bios handler
+ * that acks the vint irq and returns, so game's handler is not reached
+ * (see bios irq handler chains at e004 and the game's irq handling func
+ * at 80036810). For the game to work, vint has to arrive after the bios
+ * vint handler rejects some other irq (of which only cd and rcnt2 are
+ * 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.
+ */
+ u32 vint_rel = rcnts[3].cycleStart + 63000 - psxRegs.cycle;
+ vint_rel += PSXCLK / 60;
+ while ((s32)(vint_rel - cycles) < 0)
+ vint_rel += PSXCLK / 60;
+ return vint_rel;
+}
+
+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 cdrPlayReadInterrupt(void)
+{
+ if (cdr.Reading) {
+ cdrReadInterrupt();
+ return;