From 73a879caadc91977016b764a2ae0dc2bafa4a7ee Mon Sep 17 00:00:00 2001 From: Akash Date: Wed, 19 Apr 2017 20:53:23 +0530 Subject: [PATCH] PCSX2-Counters: Detect DVD variant videomodes Improved the video mode detection code by also detecting the DVD variant video modes of NTSC & PAL, PSX mode actually make use of these specific variants, as well as the BIOS. Previously, I just had them as a single bios video mode due to laziness. (I know, my bad) After further research, it seems that these DVD variant modes have their own individual VSync timing values similar to the standard NTSC & PAL video modes, dealing with those timer codes might be essential in getting timing accuracy of the PSX mode games. (I kept it to default NTSC/PAL values for now, interested people can mess with it later) I had planned to do this before but there some were concerns that two different video modes make use of 0x73 gate in SetGsCrt, which was rather weird (how the heck could two video modes be used in a single param value?) 0x73- DVDPAL ( 720 x 480 @ ??.???Hz) 0x73- DVD480P ( 720 x 480 @ ??.???Hz) Hence, we had decided to use the CMOD bit from SMODE1 (AKA color subcarrier frequency) to detect whether it's an analog or digital video mode and update the necessary timing values but seems like it's no longer necessary, after further discussions from some PS2 developers, we've come to the conclusion that only DVDPAL is possible via 0x73 in SetGsCrt. (So I assume the DVD480p init possibility was fake info from Blue and those other GSM guys who were reverse engineering the PS2) --- pcsx2/Counters.cpp | 27 +++++++++------- pcsx2/GS.cpp | 14 +-------- pcsx2/GS.h | 66 ++++++++++++++++++++------------------- pcsx2/R5900OpcodeImpl.cpp | 4 +-- 4 files changed, 52 insertions(+), 59 deletions(-) diff --git a/pcsx2/Counters.cpp b/pcsx2/Counters.cpp index f49ae43674..5cc8d5f502 100644 --- a/pcsx2/Counters.cpp +++ b/pcsx2/Counters.cpp @@ -253,16 +253,17 @@ static const char* ReportVideoMode() { switch (gsVideoMode) { - case GS_VideoMode::PAL: return "PAL"; - case GS_VideoMode::NTSC: return "NTSC"; - case GS_VideoMode::VESA: return "VESA"; - case GS_VideoMode::BIOS: return "BIOS"; - case GS_VideoMode::HDTV_480P: return "HDTV 480p"; - case GS_VideoMode::HDTV_576P: return "HDTV 576p"; - case GS_VideoMode::HDTV_720P: return "HDTV 720p"; - case GS_VideoMode::HDTV_1080I: return "HDTV 1080i"; - case GS_VideoMode::HDTV_1080P: return "HDTV 1080p"; - default: return "Unknown"; + case GS_VideoMode::PAL: return "PAL"; + case GS_VideoMode::NTSC: return "NTSC"; + case GS_VideoMode::DVD_NTSC: return "DVD NTSC"; + case GS_VideoMode::DVD_PAL: return "DVD PAL"; + case GS_VideoMode::VESA: return "VESA"; + case GS_VideoMode::HDTV_480P: return "HDTV 480p"; + case GS_VideoMode::HDTV_576P: return "HDTV 576p"; + case GS_VideoMode::HDTV_720P: return "HDTV 720p"; + case GS_VideoMode::HDTV_1080I: return "HDTV 1080i"; + case GS_VideoMode::HDTV_1080P: return "HDTV 1080p"; + default: return "Unknown"; } } @@ -273,8 +274,10 @@ Fixed100 GetVerticalFrequency() case GS_VideoMode::Uninitialized: // SYSCALL instruction hasn't executed yet, give some temporary values. return 60; case GS_VideoMode::PAL: + case GS_VideoMode::DVD_PAL: return EmuConfig.GS.FrameratePAL; case GS_VideoMode::NTSC: + case GS_VideoMode::DVD_NTSC: return EmuConfig.GS.FramerateNTSC; case GS_VideoMode::HDTV_480P: return 59.94; @@ -283,7 +286,6 @@ Fixed100 GetVerticalFrequency() case GS_VideoMode::HDTV_576P: case GS_VideoMode::HDTV_720P: case GS_VideoMode::VESA: - case GS_VideoMode::BIOS: return 60; default: // Pass NTSC vertical frequency value when unknown video mode is detected. @@ -311,12 +313,14 @@ u32 UpdateVSyncRate() break; case GS_VideoMode::PAL: + case GS_VideoMode::DVD_PAL: isCustom = (EmuConfig.GS.FrameratePAL != 50.0); scanlines = SCANLINES_TOTAL_PAL; if (!gsIsInterlaced) scanlines += 3; break; case GS_VideoMode::NTSC: + case GS_VideoMode::DVD_NTSC: isCustom = (EmuConfig.GS.FramerateNTSC != 59.94); scanlines = SCANLINES_TOTAL_NTSC; if (!gsIsInterlaced) scanlines += 1; @@ -328,7 +332,6 @@ u32 UpdateVSyncRate() case GS_VideoMode::HDTV_576P: case GS_VideoMode::HDTV_720P: case GS_VideoMode::VESA: - case GS_VideoMode::BIOS: scanlines = SCANLINES_TOTAL_NTSC; break; diff --git a/pcsx2/GS.cpp b/pcsx2/GS.cpp index 04208f6d96..022c7deb54 100644 --- a/pcsx2/GS.cpp +++ b/pcsx2/GS.cpp @@ -39,9 +39,7 @@ void gsSetVideoMode(GS_VideoMode mode ) if( gsVideoMode == mode ) return; - // 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; + gsVideoMode = mode; UpdateVSyncRate(); } @@ -142,14 +140,6 @@ __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 @@ -213,8 +203,6 @@ 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 6ab029b92e..5056deea60 100644 --- a/pcsx2/GS.h +++ b/pcsx2/GS.h @@ -202,37 +202,38 @@ union tGS_IMR // -------------------------------------------------------------------------------------- // 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; -}; +// Previously, the union was used to get the CMOD bit of the SMODE1 register +// Commenting it out as it's unused right now. (Might potentially be useful in the future) +//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 @@ -264,7 +265,8 @@ enum class GS_VideoMode : int HDTV_720P, HDTV_1080I, HDTV_1080P, - BIOS + DVD_NTSC, + DVD_PAL }; extern GS_VideoMode gsVideoMode; diff --git a/pcsx2/R5900OpcodeImpl.cpp b/pcsx2/R5900OpcodeImpl.cpp index 7d3db0ec4b..ca814c6a88 100644 --- a/pcsx2/R5900OpcodeImpl.cpp +++ b/pcsx2/R5900OpcodeImpl.cpp @@ -932,8 +932,8 @@ void SYSCALL() case 0x53: mode = "HDTV 768x576 @ ??.???"; gsSetVideoMode(GS_VideoMode::HDTV_576P); break; case 0x54: mode = "HDTV 1920x1080 @ ??.???"; gsSetVideoMode(GS_VideoMode::HDTV_1080P); break; - case 0x72: mode = "DVD NTSC 640x448 @ ??.???"; gsSetVideoMode(GS_VideoMode::BIOS); break; - case 0x73: mode = "DVD PAL 720x480 @ ??.???"; gsSetVideoMode(GS_VideoMode::BIOS); break; + case 0x72: mode = "DVD NTSC 640x448 @ ??.???"; gsSetVideoMode(GS_VideoMode::DVD_NTSC); break; + case 0x73: mode = "DVD PAL 720x480 @ ??.???"; gsSetVideoMode(GS_VideoMode::DVD_PAL); break; default: DevCon.Error("Mode %x is not supported. Report me upstream", cpuRegs.GPR.n.a1.UC[0]);