From 7b68d92c6224ba23a3250688afbf55c35ab106e4 Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 8 Sep 2022 18:17:06 +0300 Subject: [PATCH] dma: try more accurate timings seems to help Legend of Mana --- libpcsxcore/cdrom.c | 16 ++++++++-------- libpcsxcore/mdec.c | 35 ++++++++++++++--------------------- libpcsxcore/psxdma.c | 4 ++-- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index 1e435152..bd013e3c 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -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; diff --git a/libpcsxcore/mdec.c b/libpcsxcore/mdec.c index 61ed5ea5..4b93ffa5 100644 --- a/libpcsxcore/mdec.c +++ b/libpcsxcore/mdec.c @@ -33,12 +33,10 @@ * 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; } } diff --git a/libpcsxcore/psxdma.c b/libpcsxcore/psxdma.c index c888ecdf..df02b00f 100644 --- a/libpcsxcore/psxdma.c +++ b/libpcsxcore/psxdma.c @@ -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 -- 2.39.5