CHD support from libretro's fork. (#188)
[pcsx_rearmed.git] / libpcsxcore / cdrom.c
index 7b5cdf2..a725efa 100644 (file)
@@ -24,6 +24,7 @@
 #include "cdrom.h"
 #include "ppf.h"
 #include "psxdma.h"
+#include "arm_features.h"
 
 /* logging */
 #if 0
@@ -126,7 +127,7 @@ unsigned char Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 };
 #define STATUS_ERROR     (1<<0) // 0x01
 
 /* Errors */
-#define ERROR_NOT_READY  (1<<7) // 0x80
+#define ERROR_NOTREADY   (1<<7) // 0x80
 #define ERROR_INVALIDCMD (1<<6) // 0x40
 #define ERROR_INVALIDARG (1<<5) // 0x20
 
@@ -205,7 +206,7 @@ static void sec2msf(unsigned int s, u8 *msf) {
                cdr.Reading = 0; \
                psxRegs.interrupt &= ~(1 << PSXINT_CDREAD); \
        } \
-       cdr.StatP &= ~STATUS_READ;\
+       cdr.StatP &= ~(STATUS_READ|STATUS_SEEK);\
 }
 
 #define StopCdda() { \
@@ -538,6 +539,7 @@ void cdrInterrupt() {
        int start_rotating = 0;
        int error = 0;
        int delay;
+       unsigned int seekTime = 0;
 
        // Reschedule IRQ
        if (cdr.Stat) {
@@ -908,6 +910,8 @@ void cdrInterrupt() {
                case CdlReadN:
                case CdlReadS:
                        if (cdr.SetlocPending) {
+                               seekTime = abs(msf2sec(cdr.SetSectorPlay) - msf2sec(cdr.SetSector)) * (cdReadTime / 200);
+                               if(seekTime > 1000000) seekTime = 1000000;
                                memcpy(cdr.SetSectorPlay, cdr.SetSector, 4);
                                cdr.SetlocPending = 0;
                        }
@@ -947,7 +951,7 @@ void cdrInterrupt() {
                                // - fix cutscene speech (startup)
 
                                // ??? - use more accurate seek time later
-                               CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime * 1);
+                               CDREAD_INT(((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime * 1) + seekTime);
                        } else {
                                cdr.StatP |= STATUS_READ;
                                cdr.StatP &= ~STATUS_SEEK;
@@ -984,7 +988,7 @@ void cdrInterrupt() {
                case DRIVESTATE_PREPARE_CD:
                        SetResultSize(2);
                        cdr.Result[0] = cdr.StatP | STATUS_ERROR;
-                       cdr.Result[1] = ERROR_NOT_READY;
+                       cdr.Result[1] = ERROR_NOTREADY;
                        cdr.Stat = DiskError;
                        break;
                }
@@ -1006,7 +1010,7 @@ finish:
 #endif
 }
 
-#ifdef __ARM_ARCH_7A__
+#ifdef HAVE_ARMV7
  #define ssat32_to_16(v) \
   asm("ssat %0,#16,%1" : "=r" (v) : "r" (v))
 #else
@@ -1413,13 +1417,15 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
                        psxCpu->Clear(madr, cdsize / 4);
                        pTransfer += cdsize;
 
-
-                       // burst vs normal
                        if( chcr == 0x11400100 ) {
+                               HW_DMA3_MADR = SWAPu32(madr + cdsize);
                                CDRDMA_INT( (cdsize/4) / 4 );
                        }
                        else if( chcr == 0x11000000 ) {
-                               CDRDMA_INT( (cdsize/4) * 1 );
+                               // CDRDMA_INT( (cdsize/4) * 1 );
+                               // halted
+                               psxRegs.cycle += (cdsize/4) * 24/2;
+                               CDRDMA_INT(16);
                        }
                        return;
 
@@ -1495,7 +1501,9 @@ int cdrFreeze(void *f, int Mode) {
                pTransfer = cdr.Transfer + tmp;
 
                // read right sub data
-               memcpy(tmpp, cdr.Prev, 3);
+               tmpp[0] = btoi(cdr.Prev[0]);
+               tmpp[1] = btoi(cdr.Prev[1]);
+               tmpp[2] = btoi(cdr.Prev[2]);
                cdr.Prev[0]++;
                ReadTrack(tmpp);
 
@@ -1514,6 +1522,12 @@ int cdrFreeze(void *f, int Mode) {
                                SysPrintf("cdrom: fixing up old savestate\n");
                                cdr.Reg2 = 7;
                        }
+                       // also did not save Attenuator..
+                       if ((cdr.AttenuatorLeftToLeft | cdr.AttenuatorLeftToRight
+                            | cdr.AttenuatorRightToLeft | cdr.AttenuatorRightToRight) == 0)
+                       {
+                               cdr.AttenuatorLeftToLeft = cdr.AttenuatorRightToRight = 0x80;
+                       }
                }
        }