From f1c4b7d5df81f1c6265c141c4a9976a42ae563f8 Mon Sep 17 00:00:00 2001 From: Akash Date: Thu, 20 Oct 2016 20:09:35 +0530 Subject: [PATCH] PSX-mode: Detect video mode via colorburst Previously the video mode was initialized using the info fetched from SetGsCrt Syscall though unfortunately, it doesn't seem to work with PSX games as they don't use the SetGsCrt syscall. At such cases, we get the video mode info from the SMODE2 colorburst to properly maintain the timing as per the video mode. Might help some cases on PSX games where PAL/NTSC video mode was improperly set to a wrong limit instead of it's actual vertical frequency limit. --- pcsx2/GS.cpp | 18 ++++++++++++++++-- pcsx2/GS.h | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/pcsx2/GS.cpp b/pcsx2/GS.cpp index be2f0bed46..4521e24aa5 100644 --- a/pcsx2/GS.cpp +++ b/pcsx2/GS.cpp @@ -25,6 +25,7 @@ using namespace Threading; using namespace R5900; +static GS_VideoMode s_ColorBurst = GS_VideoMode::Uninitialized; __aligned16 u8 g_RealGSMem[Ps2MemSize::GSregs]; void gsOnModeChanged( Fixed100 framerate, u32 newTickrate ) @@ -35,9 +36,12 @@ void gsOnModeChanged( Fixed100 framerate, u32 newTickrate ) void gsSetVideoMode(GS_VideoMode mode ) { - if( gsVideoMode == mode ) return; + if( gsVideoMode == mode ) + return; - gsVideoMode = mode; + // SetGsCrt doesn't seem to work for PSX games and they're left with the initial bios mode + // At such cases, let's use the colorburst to detect the video mode. + gsVideoMode = (mode == GS_VideoMode::BIOS) ? s_ColorBurst : mode; UpdateVSyncRate(); } @@ -138,6 +142,14 @@ __fi void gsWrite8(u32 mem, u8 value) GIF_LOG("GS write 8 at %8.8lx with data %8.8lx", mem, value); } +static void GetColorBurst(u64 value) +{ + GSRegSMODE1 Register; + Register.SMODE1 = value; + if(Register.CMOD) + s_ColorBurst = (Register.CMOD == 3) ? GS_VideoMode::PAL : GS_VideoMode::NTSC; +} + ////////////////////////////////////////////////////////////////////////// // GS Write 16 bit @@ -201,6 +213,8 @@ void __fastcall gsWrite64_generic( u32 mem, const mem64_t* value ) void __fastcall gsWrite64_page_00( u32 mem, const mem64_t* value ) { + if (mem == GS_SMODE1) + GetColorBurst(*value); gsWrite64_generic( mem, value ); } diff --git a/pcsx2/GS.h b/pcsx2/GS.h index 57615946c4..0b9a55560e 100644 --- a/pcsx2/GS.h +++ b/pcsx2/GS.h @@ -198,6 +198,41 @@ union tGS_IMR bool masked() const { return (SIGMSK || FINISHMSK || HSMSK || VSMSK || EDWMSK); } }; +// -------------------------------------------------------------------------------------- +// GSRegSMODE1 +// -------------------------------------------------------------------------------------- +// Currently it's only used to get the CMOD bit from the SMODE1 register value. +union GSRegSMODE1 +{ + struct + { + u32 RC : 3; + u32 LC : 7; + u32 T1248 : 2; + u32 SLCK : 1; + u32 CMOD : 2; + u32 EX : 1; + u32 PRST : 1; + u32 SINT : 1; + u32 XPCK : 1; + u32 PCK2 : 2; + u32 SPML : 4; + u32 GCONT : 1; + u32 PHS : 1; + u32 PVS : 1; + u32 PEHS : 1; + u32 PEVS : 1; + u32 CLKSEL : 2; + u32 NVCK : 1; + u32 SLCK2 : 1; + u32 VCKSEL : 2; + u32 VHP : 1; + u32 _PAD1 : 27; + }; + + u64 SMODE1; +}; + // -------------------------------------------------------------------------------------- // GSRegSIGBLID // --------------------------------------------------------------------------------------