dma: try more accurate timings
authornotaz <notasas@gmail.com>
Thu, 8 Sep 2022 15:17:06 +0000 (18:17 +0300)
committernotaz <notasas@gmail.com>
Thu, 8 Sep 2022 21:13:59 +0000 (00:13 +0300)
seems to help Legend of Mana

libpcsxcore/cdrom.c
libpcsxcore/mdec.c
libpcsxcore/psxdma.c

index 000e548..310ea4f 100644 (file)
@@ -1462,9 +1462,8 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
 
        CDR_LOG("psxDma3() Log: *** DMA 3 *** %x addr = %x size = %x\n", chcr, madr, bcr);
 
-       switch (chcr) {
+       switch (chcr & 0x71000000) {
                case 0x11000000:
-               case 0x11400100:
                        if (cdr.Readed == 0) {
                                CDR_LOG_I("psxDma3() Log: *** DMA 3 *** NOT READY\n");
                                break;
@@ -1493,15 +1492,16 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
                                psxCpu->Clear(madr, size / 4);
                        }
 
-                       if( chcr == 0x11400100 ) {
+                       CDRDMA_INT((cdsize/4) * 24);
+
+                       HW_DMA3_CHCR &= SWAPu32(~0x10000000);
+                       if (chcr & 0x100) {
                                HW_DMA3_MADR = SWAPu32(madr + cdsize);
-                               CDRDMA_INT( (cdsize/4) / 4 );
+                               HW_DMA3_BCR &= SWAPu32(0xffff0000);
                        }
-                       else if( chcr == 0x11000000 ) {
-                               // CDRDMA_INT( (cdsize/4) * 1 );
+                       else {
                                // halted
-                               psxRegs.cycle += (cdsize/4) * 24/2;
-                               CDRDMA_INT(16);
+                               psxRegs.cycle += (cdsize/4) * 24 - 20;
                        }
                        return;
 
index 61ed5ea..4b93ffa 100644 (file)
  * so 2.0 to 4.0 should be fine.
  */
  
-/* 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.
- * */
+/*
+ * >= 10 for Galerians
+ * <= 18 for "Disney's Treasure Planet"
+ */
 #define MDEC_BIAS 10
 
 #define DSIZE                  8
@@ -487,7 +485,7 @@ void psxDma0(u32 adr, u32 bcr, u32 chcr) {
        size = (bcr >> 16) * (bcr & 0xffff);
 
        switch (cmd >> 28) {
-               case 0x3: // decode
+               case 0x3: // decode 15/24bpp
                        mdec.rl = (u16 *) PSXM(adr);
                        /* now the mdec is busy till all data are decoded */
                        mdec.reg1 |= MDEC1_BUSY;
@@ -495,10 +493,8 @@ void psxDma0(u32 adr, u32 bcr, u32 chcr) {
                        mdec.rl_end = mdec.rl + (size * 2);
 
                        /* sanity check */
-                       if(mdec.rl_end <= mdec.rl) {
-                               MDECINDMA_INT( size / 4 );
-                               return;
-                       }
+                       if(mdec.rl_end <= mdec.rl)
+                               break;
 
                        /* process the pending dma1 */
                        if(mdec.pending_dma1.adr){
@@ -517,23 +513,18 @@ void psxDma0(u32 adr, u32 bcr, u32 chcr) {
                                iqtab_init(iq_y, p);
                                iqtab_init(iq_uv, p + 64);
                        }
-
-                       MDECINDMA_INT( size / 4 );
-      return;
+                       break;
 
                case 0x6: // cosine table
                        // printf("mdec cosine table\n");
-
-                       MDECINDMA_INT( size / 4 );
-      return;
+                       break;
 
                default:
                        // printf("mdec unknown command\n");
                        break;
        }
 
-       HW_DMA0_CHCR &= SWAP32(~0x01000000);
-       DMA_INTERRUPT(0);
+       MDECINDMA_INT(size);
 }
 
 void mdec0Interrupt()
@@ -629,8 +620,10 @@ void psxDma1(u32 adr, u32 bcr, u32 chcr) {
                }
        }
        
-       /* define the power of mdec */
-       MDECOUTDMA_INT(words * MDEC_BIAS);
+               /* define the power of mdec */
+               MDECOUTDMA_INT(words * MDEC_BIAS);
+               /* some CPU stalling */
+               psxRegs.cycle += words;
        }
 }
 
index d3b8572..e6f68fc 100644 (file)
@@ -54,7 +54,7 @@ void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU
                        words = (bcr >> 16) * (bcr & 0xffff);
                        SPU_writeDMAMem(ptr, words * 2, psxRegs.cycle);
                        HW_DMA4_MADR = SWAPu32(madr + words * 4);
-                       SPUDMA_INT(words / 2);
+                       SPUDMA_INT(words * 4);
                        return;
 
                case 0x01000200: //spu to cpu transfer
@@ -73,7 +73,7 @@ void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU
                        psxCpu->Clear(madr, words);
 
                        HW_DMA4_MADR = SWAPu32(madr + words * 4);
-                       SPUDMA_INT(words / 2);
+                       SPUDMA_INT(words * 4);
                        return;
 
 #ifdef PSXDMA_LOG