spunull: Add missing callback and fix prototypes
[pcsx_rearmed.git] / libpcsxcore / cdrom.c
index 1615e18..4ef0a23 100644 (file)
@@ -111,7 +111,7 @@ static struct {
        u8 AdpcmActive;
        u32 LastReadSeekCycles;
 
        u8 AdpcmActive;
        u32 LastReadSeekCycles;
 
-       u8 unused7;
+       u8 RetryDetected;
 
        u8 DriveState; // enum drive_state
        u8 FastForward;
 
        u8 DriveState; // enum drive_state
        u8 FastForward;
@@ -232,7 +232,7 @@ enum drive_state {
        DRIVESTATE_SEEK,
 };
 
        DRIVESTATE_SEEK,
 };
 
-static struct CdrStat stat;
+static struct CdrStat cdr_stat;
 
 static unsigned int msf2sec(const u8 *msf) {
        return ((msf[0] * 60 + msf[1]) * 75) + msf[2];
 
 static unsigned int msf2sec(const u8 *msf) {
        return ((msf[0] * 60 + msf[1]) * 75) + msf[2];
@@ -327,10 +327,10 @@ void cdrLidSeekInterrupt(void)
                //StopReading();
                SetPlaySeekRead(cdr.StatP, 0);
 
                //StopReading();
                SetPlaySeekRead(cdr.StatP, 0);
 
-               if (CDR_getStatus(&stat) == -1)
+               if (CDR_getStatus(&cdr_stat) == -1)
                        return;
 
                        return;
 
-               if (stat.Status & STATUS_SHELLOPEN)
+               if (cdr_stat.Status & STATUS_SHELLOPEN)
                {
                        memset(cdr.Prev, 0xff, sizeof(cdr.Prev));
                        cdr.DriveState = DRIVESTATE_LID_OPEN;
                {
                        memset(cdr.Prev, 0xff, sizeof(cdr.Prev));
                        cdr.DriveState = DRIVESTATE_LID_OPEN;
@@ -339,8 +339,8 @@ void cdrLidSeekInterrupt(void)
                break;
 
        case DRIVESTATE_LID_OPEN:
                break;
 
        case DRIVESTATE_LID_OPEN:
-               if (CDR_getStatus(&stat) == -1)
-                       stat.Status &= ~STATUS_SHELLOPEN;
+               if (CDR_getStatus(&cdr_stat) == -1)
+                       cdr_stat.Status &= ~STATUS_SHELLOPEN;
 
                // 02, 12, 10
                if (!(cdr.StatP & STATUS_SHELLOPEN)) {
 
                // 02, 12, 10
                if (!(cdr.StatP & STATUS_SHELLOPEN)) {
@@ -367,7 +367,7 @@ void cdrLidSeekInterrupt(void)
                else if (cdr.StatP & STATUS_ROTATING) {
                        cdr.StatP &= ~STATUS_ROTATING;
                }
                else if (cdr.StatP & STATUS_ROTATING) {
                        cdr.StatP &= ~STATUS_ROTATING;
                }
-               else if (!(stat.Status & STATUS_SHELLOPEN)) {
+               else if (!(cdr_stat.Status & STATUS_SHELLOPEN)) {
                        // closed now
                        CheckCdrom();
 
                        // closed now
                        CheckCdrom();
 
@@ -576,6 +576,14 @@ static void cdrPlayInterrupt_Autopause()
                cdr.ReportDelay--;
 }
 
                cdr.ReportDelay--;
 }
 
+static boolean canDoTurbo(void)
+{
+       u32 c = psxRegs.cycle;
+       return Config.TurboCD && !cdr.RetryDetected && !cdr.AdpcmActive
+               //&& c - psxRegs.intCycle[PSXINT_SPUDMA].sCycle > (u32)cdReadTime * 2
+               && c - psxRegs.intCycle[PSXINT_MDECOUTDMA].sCycle > (u32)cdReadTime * 16;
+}
+
 static int cdrSeekTime(unsigned char *target)
 {
        int diff = msf2sec(cdr.SetSectorPlay) - msf2sec(target);
 static int cdrSeekTime(unsigned char *target)
 {
        int diff = msf2sec(cdr.SetSectorPlay) - msf2sec(target);
@@ -654,6 +662,11 @@ static void msfiSub(u8 *msfi, u32 count)
        }
 }
 
        }
 }
 
+static int msfiEq(const u8 *a, const u8 *b)
+{
+       return a[0] == b[0] && a[1] == b[1] && a[2] == b[2];
+}
+
 void cdrPlayReadInterrupt(void)
 {
        int hit = CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2]);
 void cdrPlayReadInterrupt(void)
 {
        int hit = CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1], cdr.SetSectorPlay[2]);
@@ -708,8 +721,8 @@ void cdrPlayReadInterrupt(void)
 
 static void softReset(void)
 {
 
 static void softReset(void)
 {
-       CDR_getStatus(&stat);
-       if (stat.Status & STATUS_SHELLOPEN) {
+       CDR_getStatus(&cdr_stat);
+       if (cdr_stat.Status & STATUS_SHELLOPEN) {
                cdr.DriveState = DRIVESTATE_LID_OPEN;
                cdr.StatP = STATUS_SHELLOPEN;
        }
                cdr.DriveState = DRIVESTATE_LID_OPEN;
                cdr.StatP = STATUS_SHELLOPEN;
        }
@@ -822,6 +835,9 @@ void cdrInterrupt(void) {
                        {
                                for (i = 0; i < 3; i++)
                                        set_loc[i] = btoi(cdr.Param[i]);
                        {
                                for (i = 0; i < 3; i++)
                                        set_loc[i] = btoi(cdr.Param[i]);
+                               cdr.RetryDetected = msfiEq(cdr.SetSector, set_loc)
+                                       && !cdr.SetlocPending;
+                               //cdr.RetryDetected |= msfiEq(cdr.Param, cdr.Transfer);
                                memcpy(cdr.SetSector, set_loc, 3);
                                cdr.SetSector[3] = 0;
                                cdr.SetlocPending = 1;
                                memcpy(cdr.SetSector, set_loc, 3);
                                cdr.SetSector[3] = 0;
                                cdr.SetlocPending = 1;
@@ -971,27 +987,19 @@ void cdrInterrupt(void) {
                        cdr.sectorsRead = 0;
 
                        /*
                        cdr.sectorsRead = 0;
 
                        /*
-                       Gundam Battle Assault 2: much slower (*)
-                       - Fixes boot, gameplay
-
-                       Hokuto no Ken 2: slower
-                       - Fixes intro + subtitles
-
-                       InuYasha - Feudal Fairy Tale: slower
-                       - Fixes battles
+                       Gundam Battle Assault 2
+                       Hokuto no Ken 2
+                       InuYasha - Feudal Fairy Tale
+                       Dance Dance Revolution Konamix
+                       ...
                        */
                        */
-                       /* Gameblabla - Tightening the timings (as taken from Duckstation). 
-                        * The timings from Duckstation are based upon hardware tests.
-                        * Mednafen's timing don't work for Gundam Battle Assault 2 in PAL/50hz mode,
-                        * seems to be timing sensitive as it can depend on the CPU's clock speed.
-                        * */
                        if (!(cdr.StatP & (STATUS_PLAY | STATUS_READ)))
                        {
                                second_resp_time = 7000;
                        }
                        else
                        {
                        if (!(cdr.StatP & (STATUS_PLAY | STATUS_READ)))
                        {
                                second_resp_time = 7000;
                        }
                        else
                        {
-                               second_resp_time = (((cdr.Mode & MODE_SPEED) ? 1 : 2) * 1097107);
+                               second_resp_time = 2 * 1097107;
                        }
                        SetPlaySeekRead(cdr.StatP, 0);
                        DriveStateOld = cdr.DriveState;
                        }
                        SetPlaySeekRead(cdr.StatP, 0);
                        DriveStateOld = cdr.DriveState;
@@ -1111,7 +1119,8 @@ void cdrInterrupt(void) {
                        StopReading();
                        SetPlaySeekRead(cdr.StatP, STATUS_SEEK | STATUS_ROTATING);
 
                        StopReading();
                        SetPlaySeekRead(cdr.StatP, STATUS_SEEK | STATUS_ROTATING);
 
-                       seekTime = cdrSeekTime(cdr.SetSector);
+                       if (!canDoTurbo())
+                               seekTime = cdrSeekTime(cdr.SetSector);
                        memcpy(cdr.SetSectorPlay, cdr.SetSector, 4);
                        cdr.DriveState = DRIVESTATE_SEEK;
                        CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1],
                        memcpy(cdr.SetSectorPlay, cdr.SetSector, 4);
                        cdr.DriveState = DRIVESTATE_SEEK;
                        CDR_prefetch(cdr.SetSectorPlay[0], cdr.SetSectorPlay[1],
@@ -1179,11 +1188,11 @@ void cdrInterrupt(void) {
                        cdr.Result[3] = 0;
 
                        // 0x10 - audio | 0x40 - disk missing | 0x80 - unlicensed
                        cdr.Result[3] = 0;
 
                        // 0x10 - audio | 0x40 - disk missing | 0x80 - unlicensed
-                       if (CDR_getStatus(&stat) == -1 || stat.Type == 0 || stat.Type == 0xff) {
+                       if (CDR_getStatus(&cdr_stat) == -1 || cdr_stat.Type == 0 || cdr_stat.Type == 0xff) {
                                cdr.Result[1] = 0xc0;
                        }
                        else {
                                cdr.Result[1] = 0xc0;
                        }
                        else {
-                               if (stat.Type == 2)
+                               if (cdr_stat.Type == 2)
                                        cdr.Result[1] |= 0x10;
                                if (CdromId[0] == '\0')
                                        cdr.Result[1] |= 0x80;
                                        cdr.Result[1] |= 0x10;
                                if (CdromId[0] == '\0')
                                        cdr.Result[1] |= 0x80;
@@ -1260,6 +1269,8 @@ void cdrInterrupt(void) {
                        cycles += seekTime;
                        if (Config.hacks.cdr_read_timing)
                                cycles = cdrAlignTimingHack(cycles);
                        cycles += seekTime;
                        if (Config.hacks.cdr_read_timing)
                                cycles = cdrAlignTimingHack(cycles);
+                       else if (canDoTurbo())
+                               cycles = cdReadTime / 2;
                        CDRPLAYREAD_INT(cycles, 1);
 
                        SetPlaySeekRead(cdr.StatP, STATUS_SEEK);
                        CDRPLAYREAD_INT(cycles, 1);
 
                        SetPlaySeekRead(cdr.StatP, STATUS_SEEK);
@@ -1451,6 +1462,8 @@ unsigned char cdrRead0(void) {
        cdr.Ctrl |= cdr.AdpcmActive << 2;
        cdr.Ctrl |= cdr.ResultReady << 5;
 
        cdr.Ctrl |= cdr.AdpcmActive << 2;
        cdr.Ctrl |= cdr.ResultReady << 5;
 
+       //cdr.Ctrl &= ~0x40;
+       //if (cdr.FifoOffset != DATA_SIZE)
        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 |= 0x40; // data fifo not empty
 
        // What means the 0x10 and the 0x08 bits? I only saw it used by the bios
@@ -1650,7 +1663,7 @@ void cdrWrite3(unsigned char rt) {
 }
 
 void psxDma3(u32 madr, u32 bcr, u32 chcr) {
 }
 
 void psxDma3(u32 madr, u32 bcr, u32 chcr) {
-       u32 cdsize, max_words;
+       u32 cdsize, max_words, cycles;
        int size;
        u8 *ptr;
 
        int size;
        u8 *ptr;
 
@@ -1696,7 +1709,8 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
                        }
                        psxCpu->Clear(madr, cdsize / 4);
 
                        }
                        psxCpu->Clear(madr, cdsize / 4);
 
-                       set_event(PSXINT_CDRDMA, (cdsize / 4) * 24);
+                       cycles = (cdsize / 4) * 24;
+                       set_event(PSXINT_CDRDMA, cycles);
 
                        HW_DMA3_CHCR &= SWAPu32(~0x10000000);
                        if (chcr & 0x100) {
 
                        HW_DMA3_CHCR &= SWAPu32(~0x10000000);
                        if (chcr & 0x100) {
@@ -1705,8 +1719,10 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
                        }
                        else {
                                // halted
                        }
                        else {
                                // halted
-                               psxRegs.cycle += (cdsize/4) * 24 - 20;
+                               psxRegs.cycle += cycles - 20;
                        }
                        }
+                       if (canDoTurbo() && cdr.Reading && cdr.FifoOffset >= 2048)
+                               CDRPLAYREAD_INT(cycles + 4096, 1);
                        return;
 
                default:
                        return;
 
                default: