drc: something works on arm64
[pcsx_rearmed.git] / libpcsxcore / mdec.c
index b25b961..61ed5ea 100644 (file)
  * 320x240x16@60Hz => 9.216 MB/s
  * so 2.0 to 4.0 should be fine.
  */
-#define MDEC_BIAS 2.0f
+/* Was set to 2 before but it would cause issues in R-types and Vandal Hearts videos. 
+ * Setting it to 6 as dmitrysmagin did fix those... except for Galerians.
+ * Galerians needs this to be set to 10 (!!) before it looks properly.
+ * I've tried this with a few other games (including R-Types) and so far, this
+ * has not backfired.
+ * */
+#define MDEC_BIAS 10
 
 #define DSIZE                  8
 #define DSIZE2                 (DSIZE * DSIZE)
@@ -531,8 +538,11 @@ void psxDma0(u32 adr, u32 bcr, u32 chcr) {
 
 void mdec0Interrupt()
 {
-       HW_DMA0_CHCR &= SWAP32(~0x01000000);
-       DMA_INTERRUPT(0);
+       if (HW_DMA0_CHCR & SWAP32(0x01000000))
+       {
+               HW_DMA0_CHCR &= SWAP32(~0x01000000);
+               DMA_INTERRUPT(0);
+       }
 }
 
 #define SIZE_OF_24B_BLOCK (16*16*3)
@@ -542,15 +552,13 @@ void psxDma1(u32 adr, u32 bcr, u32 chcr) {
        int blk[DSIZE2 * 6];
        u8 * image;
        int size;
-       int dmacnt;
+       u32 words;
 
        if (chcr != 0x01000200) return;
 
-       size = (bcr >> 16) * (bcr & 0xffff);
+       words = (bcr >> 16) * (bcr & 0xffff);
        /* size in byte */
-       size *= 4;
-       /* I guess the memory speed is limitating */
-       dmacnt = size;
+       size = words * 4;
 
        if (!(mdec.reg1 & MDEC1_BUSY)) {
                /* add to pending */
@@ -622,7 +630,7 @@ void psxDma1(u32 adr, u32 bcr, u32 chcr) {
        }
        
        /* define the power of mdec */
-       MDECOUTDMA_INT((int) ((dmacnt* MDEC_BIAS)));
+       MDECOUTDMA_INT(words * MDEC_BIAS);
        }
 }
 
@@ -651,26 +659,48 @@ void mdec1Interrupt() {
         *
         */
 
-       /* this else if avoid to read outside memory */
-       if(mdec.rl >= mdec.rl_end) {
-               mdec.reg1 &= ~MDEC1_STP;
-               HW_DMA0_CHCR &= SWAP32(~0x01000000);
-               DMA_INTERRUPT(0);
-               mdec.reg1 &= ~MDEC1_BUSY;
-       } else if (SWAP16(*(mdec.rl)) == MDEC_END_OF_DATA) {
-               mdec.reg1 &= ~MDEC1_STP;
-               HW_DMA0_CHCR &= SWAP32(~0x01000000);
-               DMA_INTERRUPT(0);
-               mdec.reg1 &= ~MDEC1_BUSY;
+       /* MDEC_END_OF_DATA avoids read outside memory */
+       if (mdec.rl >= mdec.rl_end || SWAP16(*(mdec.rl)) == MDEC_END_OF_DATA) {
+               mdec.reg1 &= ~(MDEC1_STP|MDEC1_BUSY);
+               if (HW_DMA0_CHCR & SWAP32(0x01000000))
+               {
+                       HW_DMA0_CHCR &= SWAP32(~0x01000000);
+                       DMA_INTERRUPT(0);
+               }
        }
 
-       HW_DMA1_CHCR &= SWAP32(~0x01000000);
-       DMA_INTERRUPT(1);
-       return;
+       if (HW_DMA1_CHCR & SWAP32(0x01000000))
+       {
+               HW_DMA1_CHCR &= SWAP32(~0x01000000);
+               DMA_INTERRUPT(1);
+       }
 }
 
-int mdecFreeze(gzFile f, int Mode) {
-       gzfreeze(&mdec, sizeof(mdec));
+int mdecFreeze(void *f, int Mode) {
+       u8 *base = (u8 *)&psxM[0x100000];
+       u32 v;
+
+       gzfreeze(&mdec.reg0, sizeof(mdec.reg0));
+       gzfreeze(&mdec.reg1, sizeof(mdec.reg1));
+
+       // old code used to save raw pointers..
+       v = (u8 *)mdec.rl - base;
+       gzfreeze(&v, sizeof(v));
+       mdec.rl = (u16 *)(base + (v & 0xffffe));
+       v = (u8 *)mdec.rl_end - base;
+       gzfreeze(&v, sizeof(v));
+       mdec.rl_end = (u16 *)(base + (v & 0xffffe));
+
+       v = 0;
+       if (mdec.block_buffer_pos)
+               v = mdec.block_buffer_pos - base;
+       gzfreeze(&v, sizeof(v));
+       mdec.block_buffer_pos = 0;
+       if (v)
+               mdec.block_buffer_pos = base + (v & 0xfffff);
+
+       gzfreeze(&mdec.block_buffer, sizeof(mdec.block_buffer));
+       gzfreeze(&mdec.pending_dma1, sizeof(mdec.pending_dma1));
        gzfreeze(iq_y, sizeof(iq_y));
        gzfreeze(iq_uv, sizeof(iq_uv));