From: notaz Date: Mon, 9 Oct 2023 21:39:57 +0000 (+0300) Subject: add a nasty hack for gpu busy timing X-Git-Tag: r24~121 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=979b861b31ef1f5033db5bd4433b842944300a3e;p=pcsx_rearmed.git add a nasty hack for gpu busy timing with a hope to remove it someday notaz/pcsx_rearmed#225 --- diff --git a/libpcsxcore/database.c b/libpcsxcore/database.c index 9db351c3..5276b92c 100644 --- a/libpcsxcore/database.c +++ b/libpcsxcore/database.c @@ -30,6 +30,12 @@ static const char * const gpu_slow_llist_db[] = "SLES02731", "SLPS02477", "SLPS03198", "SLUS01138", }; +static const char * const gpu_busy_hack_db[] = +{ + /* ToHeart (Japan) */ + "SLPS01919", "SLPS01920", +}; + #define HACK_ENTRY(var, list) \ { #var, &Config.hacks.var, list, ARRAY_SIZE(list) } @@ -44,6 +50,7 @@ hack_db[] = { HACK_ENTRY(cdr_read_timing, cdr_read_hack_db), HACK_ENTRY(gpu_slow_list_walking, gpu_slow_llist_db), + HACK_ENTRY(gpu_busy_hack, gpu_busy_hack_db), }; static const struct diff --git a/libpcsxcore/new_dynarec/pcsxmem.c b/libpcsxcore/new_dynarec/pcsxmem.c index fc19494e..f4b1d90e 100644 --- a/libpcsxcore/new_dynarec/pcsxmem.c +++ b/libpcsxcore/new_dynarec/pcsxmem.c @@ -218,27 +218,6 @@ static void io_spu_write32(u32 value) wfunc(a + 2, value >> 16, psxRegs.cycle); } -static u32 io_gpu_read_status(void) -{ - u32 v; - - // meh2, syncing for img bit, might want to avoid it.. - gpuSyncPluginSR(); - v = 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 && (HW_GPU_STATUS & PSXGPU_ILACE_BITS) != PSXGPU_ILACE_BITS) - v |= PSXGPU_LCF & (psxRegs.cycle << 20); - return v; -} - -static void io_gpu_write_status(u32 value) -{ - GPU_writeStatus(value); - gpuSyncPluginSR(); -} - void new_dyna_pcsx_mem_isolate(int enable) { int i; @@ -385,7 +364,7 @@ void new_dyna_pcsx_mem_init(void) map_item(&mem_iortab[IOMEM32(0x1124)], io_rcnt_read_mode2, 1); map_item(&mem_iortab[IOMEM32(0x1128)], io_rcnt_read_target2, 1); // map_item(&mem_iortab[IOMEM32(0x1810)], GPU_readData, 1); - map_item(&mem_iortab[IOMEM32(0x1814)], io_gpu_read_status, 1); + map_item(&mem_iortab[IOMEM32(0x1814)], psxHwReadGpuSR, 1); map_item(&mem_iortab[IOMEM32(0x1820)], mdecRead0, 1); map_item(&mem_iortab[IOMEM32(0x1824)], mdecRead1, 1); @@ -438,7 +417,7 @@ void new_dyna_pcsx_mem_init(void) map_item(&mem_iowtab[IOMEM32(0x1124)], io_rcnt_write_mode2, 1); map_item(&mem_iowtab[IOMEM32(0x1128)], io_rcnt_write_target2, 1); // map_item(&mem_iowtab[IOMEM32(0x1810)], GPU_writeData, 1); - map_item(&mem_iowtab[IOMEM32(0x1814)], io_gpu_write_status, 1); + map_item(&mem_iowtab[IOMEM32(0x1814)], psxHwWriteGpuSR, 1); map_item(&mem_iowtab[IOMEM32(0x1820)], mdecWrite0, 1); map_item(&mem_iowtab[IOMEM32(0x1824)], mdecWrite1, 1); @@ -489,6 +468,10 @@ void new_dyna_pcsx_mem_reset(void) // plugins might change so update the pointers map_item(&mem_iortab[IOMEM32(0x1810)], GPU_readData, 1); map_item(&mem_iowtab[IOMEM32(0x1810)], GPU_writeData, 1); + if (Config.hacks.gpu_busy_hack) + map_item(&mem_iortab[IOMEM32(0x1814)], psxHwReadGpuSRbusyHack, 1); + else + map_item(&mem_iortab[IOMEM32(0x1814)], psxHwReadGpuSR, 1); } void new_dyna_pcsx_mem_shutdown(void) diff --git a/libpcsxcore/psxcommon.h b/libpcsxcore/psxcommon.h index 4c78255e..f978a583 100644 --- a/libpcsxcore/psxcommon.h +++ b/libpcsxcore/psxcommon.h @@ -150,6 +150,7 @@ typedef struct { struct { boolean cdr_read_timing; boolean gpu_slow_list_walking; + boolean gpu_busy_hack; } hacks; } PcsxConfig; diff --git a/libpcsxcore/psxhw.c b/libpcsxcore/psxhw.c index 60ff6c4c..254693e1 100644 --- a/libpcsxcore/psxhw.c +++ b/libpcsxcore/psxhw.c @@ -32,6 +32,8 @@ #define PAD_LOG(...) #endif +static u32 (*psxHwReadGpuSRptr)(void) = psxHwReadGpuSR; + void psxHwReset() { memset(psxH, 0, 0x10000); @@ -39,6 +41,8 @@ void psxHwReset() { cdrReset(); psxRcntInit(); HW_GPU_STATUS = SWAP32(0x14802000); + psxHwReadGpuSRptr = Config.hacks.gpu_busy_hack + ? psxHwReadGpuSRbusyHack : psxHwReadGpuSR; } void psxHwWriteIstat(u32 value) @@ -78,6 +82,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 = 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 && (HW_GPU_STATUS & 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; @@ -302,10 +339,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 @@ -771,8 +805,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: diff --git a/libpcsxcore/psxhw.h b/libpcsxcore/psxhw.h index 2bde9edc..91256ce3 100644 --- a/libpcsxcore/psxhw.h +++ b/libpcsxcore/psxhw.h @@ -85,6 +85,9 @@ int psxHwFreeze(void *f, int Mode); void psxHwWriteIstat(u32 value); void psxHwWriteImask(u32 value); void psxHwWriteDmaIcr32(u32 value); +void psxHwWriteGpuSR(u32 value); +u32 psxHwReadGpuSR(void); +u32 psxHwReadGpuSRbusyHack(void); #ifdef __cplusplus }