From 0e067f5504ef81074ecc435b3493e8190c84c0ea Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 24 Mar 2024 02:46:33 +0200 Subject: [PATCH] psxdma: implement a few more details notaz/pcsx_rearmed#336 --- libpcsxcore/psxdma.c | 10 +++++++--- libpcsxcore/psxdma.h | 1 + libpcsxcore/psxhw.c | 31 ++++++++++++++++++++----------- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/libpcsxcore/psxdma.c b/libpcsxcore/psxdma.c index 25ee2f0d..55d2a0a7 100644 --- a/libpcsxcore/psxdma.c +++ b/libpcsxcore/psxdma.c @@ -208,8 +208,8 @@ void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU psxRegs.gpuIdleAfter = psxRegs.cycle + cycles_sum + cycles_last_cmd; set_event(PSXINT_GPUDMA, cycles_sum); - //printf("%u dma2cf: %d,%d %08x\n", psxRegs.cycle, cycles_sum, - // cycles_last_cmd, HW_DMA2_MADR); + //printf("%u dma2cf: %6d,%4d %08x %08x %08x %08x\n", psxRegs.cycle, + // cycles_sum, cycles_last_cmd, madr, bcr, chcr, HW_DMA2_MADR); return; default: @@ -233,7 +233,7 @@ void gpuInterrupt() { cycles_sum += psxRegs.gpuIdleAfter - psxRegs.cycle; psxRegs.gpuIdleAfter = psxRegs.cycle + cycles_sum + cycles_last_cmd; set_event(PSXINT_GPUDMA, cycles_sum); - //printf("%u dma2cn: %d,%d %08x\n", psxRegs.cycle, cycles_sum, + //printf("%u dma2cn: %6d,%4d %08x\n", psxRegs.cycle, cycles_sum, // cycles_last_cmd, HW_DMA2_MADR); return; } @@ -244,6 +244,10 @@ void gpuInterrupt() { } } +void psxAbortDma2() { + psxRegs.gpuIdleAfter = psxRegs.cycle + 32; +} + void psxDma6(u32 madr, u32 bcr, u32 chcr) { u32 words, words_max; u32 *mem; diff --git a/libpcsxcore/psxdma.h b/libpcsxcore/psxdma.h index 5c0ab4e6..ce10d9d3 100644 --- a/libpcsxcore/psxdma.h +++ b/libpcsxcore/psxdma.h @@ -34,6 +34,7 @@ void psxDma2(u32 madr, u32 bcr, u32 chcr); void psxDma3(u32 madr, u32 bcr, u32 chcr); void psxDma4(u32 madr, u32 bcr, u32 chcr); void psxDma6(u32 madr, u32 bcr, u32 chcr); +void psxAbortDma2(); void gpuInterrupt(); void spuInterrupt(); void gpuotcInterrupt(); diff --git a/libpcsxcore/psxhw.c b/libpcsxcore/psxhw.c index 67881124..b96db97a 100644 --- a/libpcsxcore/psxhw.c +++ b/libpcsxcore/psxhw.c @@ -60,22 +60,31 @@ void psxHwWriteImask(u32 value) psxRegs.CP0.n.Cause |= 0x400; } -#define make_dma_func(n) \ +#define make_dma_func(n, abort_func) \ void psxHwWriteChcr##n(u32 value) \ { \ - if (value & SWAPu32(HW_DMA##n##_CHCR) & 0x01000000) \ - log_unhandled("dma" #n " %08x -> %08x\n", HW_DMA##n##_CHCR, value); \ + u32 old = SWAPu32(HW_DMA##n##_CHCR); \ + if (n == 6) { value &= 0x51000002; value |= 2; } \ + else { value &= 0x71770703; } \ + if (value == old) \ + return; \ + if (old & 0x01000000) \ + log_unhandled("%u dma" #n " %08x -> %08x\n", psxRegs.cycle, old, value); \ HW_DMA##n##_CHCR = SWAPu32(value); \ - if (value & 0x01000000 && SWAPu32(HW_DMA_PCR) & (8u << (n * 4))) \ - psxDma##n(SWAPu32(HW_DMA##n##_MADR), SWAPu32(HW_DMA##n##_BCR), value); \ + if ((value ^ old) & 0x01000000) { \ + if (!(value & 0x01000000)) \ + abort_func; \ + else if (SWAPu32(HW_DMA_PCR) & (8u << (n * 4))) \ + psxDma##n(SWAPu32(HW_DMA##n##_MADR), SWAPu32(HW_DMA##n##_BCR), value); \ + } \ } -make_dma_func(0) -make_dma_func(1) -make_dma_func(2) -make_dma_func(3) -make_dma_func(4) -make_dma_func(6) +make_dma_func(0,) +make_dma_func(1,) +make_dma_func(2, psxAbortDma2()) +make_dma_func(3,) +make_dma_func(4,) +make_dma_func(6,) void psxHwWriteDmaIcr32(u32 value) { -- 2.39.5