X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fpsxhw.c;h=8be775bca0c8cf2307e1b73123510c511282528d;hb=7da5c7ad699ce52d0ef8361709b420751f4e42e0;hp=ecb8eaf9f148c242ea43a88af71edc26e256278b;hpb=d358733b8461f6fa182b33d29f0676c2df505854;p=pcsx_rearmed.git diff --git a/libpcsxcore/psxhw.c b/libpcsxcore/psxhw.c index ecb8eaf9..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); @@ -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 @@ -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: