X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fpsxhw.c;h=8be775bca0c8cf2307e1b73123510c511282528d;hb=9a0a61d27586bfb93aa443cc59d9588d2b9cf992;hp=8397f3914e210b810c80ca4c70086444c262e082;hpb=6fb444d65d471c40872f7b559c7fe2520bf5ef47;p=pcsx_rearmed.git diff --git a/libpcsxcore/psxhw.c b/libpcsxcore/psxhw.c index 8397f391..8be775bc 100644 --- a/libpcsxcore/psxhw.c +++ b/libpcsxcore/psxhw.c @@ -22,6 +22,7 @@ */ #include "psxhw.h" +#include "psxevents.h" #include "mdec.h" #include "cdrom.h" #include "gpu.h" @@ -32,6 +33,8 @@ #define PAD_LOG(...) #endif +static u32 (*psxHwReadGpuSRptr)(void) = psxHwReadGpuSR; + void psxHwReset() { memset(psxH, 0, 0x10000); @@ -39,6 +42,8 @@ void psxHwReset() { cdrReset(); psxRcntInit(); HW_GPU_STATUS = SWAP32(0x14802000); + psxHwReadGpuSRptr = Config.hacks.gpu_busy_hack + ? psxHwReadGpuSRbusyHack : psxHwReadGpuSR; } void psxHwWriteIstat(u32 value) @@ -58,7 +63,7 @@ void psxHwWriteImask(u32 value) if (stat & value) { //if ((psxRegs.CP0.n.SR & 0x401) == 0x401) // log_unhandled("irq on unmask @%08x\n", psxRegs.pc); - new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1); + set_event(PSXINT_NEWDRC_CHECK, 1); } psxRegs.CP0.n.Cause &= ~0x400; if (stat & value) @@ -78,6 +83,39 @@ void psxHwWriteDmaIcr32(u32 value) HW_DMA_ICR = SWAPu32(tmp); } +void psxHwWriteGpuSR(u32 value) +{ + GPU_writeStatus(value); + gpuSyncPluginSR(); +} + +u32 psxHwReadGpuSR(void) +{ + u32 v; + + // meh2, syncing for img bit, might want to avoid it.. + gpuSyncPluginSR(); + v = SWAP32(HW_GPU_STATUS); + + // XXX: because of large timeslices can't use hSyncCount, using rough + // approximization instead. Perhaps better use hcounter code here or something. + if (hSyncCount < 240 && (v & PSXGPU_ILACE_BITS) != PSXGPU_ILACE_BITS) + v |= PSXGPU_LCF & (psxRegs.cycle << 20); + return v; +} + +// a hack due to poor timing of gpu idle bit +// to get rid of this, GPU draw times, DMAs, cpu timing has to fall within +// certain timing window or else games like "ToHeart" softlock +u32 psxHwReadGpuSRbusyHack(void) +{ + u32 v = psxHwReadGpuSR(); + static u32 hack; + if (!(hack++ & 3)) + v &= ~PSXGPU_nBUSY; + return v; +} + u8 psxHwRead8(u32 add) { unsigned char hard; @@ -120,8 +158,11 @@ u8 psxHwRead8(u32 add) { log_unhandled("unhandled r8 %08x @%08x\n", add, psxRegs.pc); // falthrough default: - if (0x1f801c00 <= add && add < 0x1f802000) - log_unhandled("spu r8 %02x @%08x\n", add, psxRegs.pc); + if (0x1f801c00 <= add && add < 0x1f802000) { + u16 val = SPU_readRegister(add & ~1, psxRegs.cycle); + hard = (add & 1) ? val >> 8 : val; + break; + } hard = psxHu8(add); #ifdef PSXHW_LOG PSXHW_LOG("*Unkwnown 8bit read at address %x\n", add); @@ -175,7 +216,7 @@ u16 psxHwRead16(u32 add) { return 0x80; case 0x1f801100: - hard = psxRcntRcount(0); + hard = psxRcntRcount0(); #ifdef PSXHW_LOG PSXHW_LOG("T0 count read16: %x\n", hard); #endif @@ -193,7 +234,7 @@ u16 psxHwRead16(u32 add) { #endif return hard; case 0x1f801110: - hard = psxRcntRcount(1); + hard = psxRcntRcount1(); #ifdef PSXHW_LOG PSXHW_LOG("T1 count read16: %x\n", hard); #endif @@ -211,7 +252,7 @@ u16 psxHwRead16(u32 add) { #endif return hard; case 0x1f801120: - hard = psxRcntRcount(2); + hard = psxRcntRcount2(); #ifdef PSXHW_LOG PSXHW_LOG("T2 count read16: %x\n", hard); #endif @@ -253,7 +294,7 @@ u16 psxHwRead16(u32 add) { // falthrough default: if (0x1f801c00 <= add && add < 0x1f802000) - return SPU_readRegister(add); + return SPU_readRegister(add, psxRegs.cycle); hard = psxHu16(add); #ifdef PSXHW_LOG PSXHW_LOG("*Unkwnown 16bit read at address %x\n", add); @@ -299,10 +340,7 @@ u32 psxHwRead32(u32 add) { #endif return hard; case 0x1f801814: - gpuSyncPluginSR(); - hard = SWAP32(HW_GPU_STATUS); - if (hSyncCount < 240 && (hard & PSXGPU_ILACE_BITS) != PSXGPU_ILACE_BITS) - hard |= PSXGPU_LCF & (psxRegs.cycle << 20); + hard = psxHwReadGpuSRptr(); #ifdef PSXHW_LOG PSXHW_LOG("GPU STATUS 32bit read %x\n", hard); #endif @@ -346,7 +384,7 @@ u32 psxHwRead32(u32 add) { // time for rootcounters :) case 0x1f801100: - hard = psxRcntRcount(0); + hard = psxRcntRcount0(); #ifdef PSXHW_LOG PSXHW_LOG("T0 count read32: %x\n", hard); #endif @@ -364,7 +402,7 @@ u32 psxHwRead32(u32 add) { #endif return hard; case 0x1f801110: - hard = psxRcntRcount(1); + hard = psxRcntRcount1(); #ifdef PSXHW_LOG PSXHW_LOG("T1 count read32: %x\n", hard); #endif @@ -382,7 +420,7 @@ u32 psxHwRead32(u32 add) { #endif return hard; case 0x1f801120: - hard = psxRcntRcount(2); + hard = psxRcntRcount2(); #ifdef PSXHW_LOG PSXHW_LOG("T2 count read32: %x\n", hard); #endif @@ -411,8 +449,8 @@ u32 psxHwRead32(u32 add) { // falthrough default: if (0x1f801c00 <= add && add < 0x1f802000) { - hard = SPU_readRegister(add); - hard |= SPU_readRegister(add + 2) << 16; + hard = SPU_readRegister(add, psxRegs.cycle); + hard |= SPU_readRegister(add + 2, psxRegs.cycle) << 16; return hard; } hard = psxHu32(add); @@ -768,8 +806,7 @@ void psxHwWrite32(u32 add, u32 value) { #ifdef PSXHW_LOG PSXHW_LOG("GPU STATUS 32bit write %x\n", value); #endif - GPU_writeStatus(value); - gpuSyncPluginSR(); + psxHwWriteGpuSR(value); return; case 0x1f801820: