X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fpsxhw.c;h=c90f8c73d5bfb9c50b61766c9f3e2b1661c83c5a;hb=refs%2Fheads%2Fmaster;hp=0a468753aefad86b1bbaf6fbd57a25802197644a;hpb=0c2126b9446fea1eb2a4e4c84fcb5ac1f364e81c;p=pcsx_rearmed.git diff --git a/libpcsxcore/psxhw.c b/libpcsxcore/psxhw.c index 0a468753..1afa9c61 100644 --- a/libpcsxcore/psxhw.c +++ b/libpcsxcore/psxhw.c @@ -26,6 +26,7 @@ #include "mdec.h" #include "cdrom.h" #include "gpu.h" +#include "../include/compiler_features.h" void psxHwReset() { memset(psxH, 0, 0x10000); @@ -60,22 +61,56 @@ 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 (HW_DMA_PCR & SWAPu32(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 psxHwWriteDmaPcr32(u32 value) +{ + // todo: can this also pause/stop live dma? + u32 on = (SWAPu32(HW_DMA_PCR) ^ value) & value & 0x08888888; + u32 chcr; + HW_DMA_PCR = SWAPu32(value); + if (likely(!on)) + return; + #define DO(n) \ + chcr = SWAPu32(HW_DMA##n##_CHCR); \ + if ((on & (8u << 4*n)) && (chcr & 0x01000000)) \ + psxDma##n(SWAPu32(HW_DMA##n##_MADR), SWAPu32(HW_DMA##n##_BCR), chcr) + DO(0); + DO(1); + // breaks Kyuutenkai. Probably needs better timing or + // proper gpu side dma enable handling + //DO(2); + if ((on & (8u << 4*2)) && (SWAPu32(HW_DMA2_CHCR) & 0x01000000)) + log_unhandled("dma2 pcr write ignored\n"); + DO(3); + DO(4); + DO(6); + #undef DO +} void psxHwWriteDmaIcr32(u32 value) { @@ -117,6 +152,12 @@ u32 psxHwReadGpuSR(void) return v; } +u32 sio1ReadStat16(void) +{ + // Armored Core, F1 Link cable misdetection + return 0xa0; +} + u8 psxHwRead8(u32 add) { u8 hard; @@ -180,7 +221,7 @@ u16 psxHwRead16(u32 add) { case 0x1048: hard = sioReadMode16(); break; case 0x104a: hard = sioReadCtrl16(); break; case 0x104e: hard = sioReadBaud16(); break; - case 0x1054: hard = 0x80; break; // Armored Core Link cable misdetection + case 0x1054: hard = sio1ReadStat16(); break; case 0x1100: hard = psxRcntRcount0(); break; case 0x1104: hard = psxRcntRmode(0); break; case 0x1108: hard = psxRcntRtarget(0); break; @@ -321,6 +362,7 @@ void psxHwWrite16(u32 add, u32 value) { case 0x10cc: psxHwWriteChcr4(value); return; case 0x10e8: // DMA6 chcr (OT clear) case 0x10ec: psxHwWriteChcr6(value); return; + case 0x10f0: psxHwWriteDmaPcr32(value); return; case 0x10f4: psxHwWriteDmaIcr32(value); return; // forced write32 with no immediate effect: @@ -333,7 +375,6 @@ void psxHwWrite16(u32 add, u32 value) { case 0x10c0: case 0x10d0: case 0x10e0: - case 0x10f0: psxHu32ref(add) = SWAPu32(value); return; @@ -379,6 +420,7 @@ void psxHwWrite32(u32 add, u32 value) { case 0x10cc: psxHwWriteChcr4(value); return; case 0x10e8: // DMA6 chcr (OT clear) case 0x10ec: psxHwWriteChcr6(value); return; + case 0x10f0: psxHwWriteDmaPcr32(value); return; case 0x10f4: psxHwWriteDmaIcr32(value); return; case 0x1810: GPU_writeData(value); return;