From d95c9dcb57f71bf0b8b7bff8579763080c7a10af Mon Sep 17 00:00:00 2001 From: gameblabla Date: Thu, 18 Jul 2019 02:02:48 +0200 Subject: [PATCH] psxbios: Improve WaitEvent behaviour according to documentation Nocash says it should return 0 if Event is unused, which it already does so it might be safe to remove the warning about it. (see why below) Then, it says that it should return 1 if event is ready (EvStALREADY). When that happens, it should also set it to ready (EvStACTIVE), unless event mode is EvMdINTR. (aka Callback Events) If it is a callback event, then documentation says it should be stuck in a loop forever. It also says that it can sometime return 0 (a BUG according to nocash), especially if it switched from EvStALREADY to EvStACTIVE. Said return value was previously set to 1, for some reasons. Now that we are covering all the corner cases, we should be returning 0 instead by default to cover the BUG. This should cover how most games expects it to behave now and should make it more robust. --- libpcsxcore/psxbios.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c index fc28ff86..139c8a5d 100644 --- a/libpcsxcore/psxbios.c +++ b/libpcsxcore/psxbios.c @@ -1562,14 +1562,28 @@ void psxBios_WaitEvent() { // 0a ev = a0 & 0xff; spec = (a0 >> 8) & 0xff; - #ifdef PSXBIOS_LOG PSXBIOS_LOG("psxBios_%s %x,%x\n", biosB0n[0x0a], ev, spec); #endif + if (Event[ev][spec].status == EvStUNUSED) + { + v0 = 0; + pc0 = ra; + return; + } - Event[ev][spec].status = EvStACTIVE; + if (Event[ev][spec].status == EvStALREADY) + { + /* Callback events (mode=EvMdINTR) do never set the ready flag (and thus WaitEvent would hang forever). */ + if (!(Event[ev][spec].mode == EvMdINTR)) Event[ev][spec].status = EvStACTIVE; + v0 = 1; + pc0 = ra; + return; + } - v0 = 1; pc0 = ra; + v0 = 0; + pc0 = ra; + ResetIoCycle(); } void psxBios_TestEvent() { // 0b -- 2.39.2