psxdma: implement a few more details
authornotaz <notasas@gmail.com>
Sun, 24 Mar 2024 00:46:33 +0000 (02:46 +0200)
committernotaz <notasas@gmail.com>
Sun, 24 Mar 2024 01:14:01 +0000 (03:14 +0200)
notaz/pcsx_rearmed#336

libpcsxcore/psxdma.c
libpcsxcore/psxdma.h
libpcsxcore/psxhw.c

index 25ee2f0..55d2a0a 100644 (file)
@@ -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;
index 5c0ab4e..ce10d9d 100644 (file)
@@ -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();
index 6788112..b96db97 100644 (file)
@@ -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)
 {