From 0abf875a3f05719412b0adfe2691d40e9dcd1c63 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 30 Jan 2016 18:35:19 +0100 Subject: [PATCH 1/7] DVDInterface: Call SetDiscInside when setting volume SetDiscInside is an implementation detail that callers shouldn't have to call on their own. --- Source/Core/Core/Boot/Boot.cpp | 7 ------- Source/Core/Core/HW/DVDInterface.cpp | 8 ++++++-- Source/Core/Core/HW/DVDInterface.h | 10 +++++----- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 6e0ffebba6..f7dd454484 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -267,7 +267,6 @@ bool CBoot::BootUp() case SConfig::BOOT_ISO: { DVDInterface::SetVolumeName(_StartupPara.m_strFilename); - DVDInterface::SetDiscInside(DVDInterface::VolumeIsValid()); if (!DVDInterface::VolumeIsValid()) return false; @@ -353,8 +352,6 @@ bool CBoot::BootUp() BS2Success = EmulatedBS2(dolWii); } - DVDInterface::SetDiscInside(DVDInterface::VolumeIsValid()); - if (!BS2Success) { // Set up MSR and the BAT SPR registers. @@ -414,8 +411,6 @@ bool CBoot::BootUp() DVDInterface::SetVolumeDirectory(_StartupPara.m_strFilename, _StartupPara.bWii); } - DVDInterface::SetDiscInside(DVDInterface::VolumeIsValid()); - // Poor man's bootup if (_StartupPara.bWii) { @@ -450,13 +445,11 @@ bool CBoot::BootUp() else if (!_StartupPara.m_strDefaultISO.empty()) DVDInterface::SetVolumeName(_StartupPara.m_strDefaultISO); - DVDInterface::SetDiscInside(DVDInterface::VolumeIsValid()); break; // Bootstrap 2 (AKA: Initial Program Loader, "BIOS") case SConfig::BOOT_BS2: { - DVDInterface::SetDiscInside(DVDInterface::VolumeIsValid()); if (Load_BS2(_StartupPara.m_strBootROM)) { if (LoadMapFromFilename()) diff --git a/Source/Core/Core/HW/DVDInterface.cpp b/Source/Core/Core/HW/DVDInterface.cpp index bcf3bba2ac..c333627b8a 100644 --- a/Source/Core/Core/HW/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVDInterface.cpp @@ -264,7 +264,8 @@ static void EjectDiscCallback(u64 userdata, s64 cyclesLate); static void InsertDiscCallback(u64 userdata, s64 cyclesLate); static void FinishExecutingCommandCallback(u64 userdata, s64 cycles_late); -void SetLidOpen(bool _bOpen); +void SetDiscInside(bool disc_inside); +void SetLidOpen(bool open); void UpdateInterrupts(); void GenerateDIInterrupt(DIInterruptType _DVDInterrupt); @@ -418,6 +419,8 @@ static void DTKStreamingCallback(const std::vector& audio_data, s64 cycles_l void Init() { + _assert_(!VolumeIsValid()); + DVDThread::Start(); Reset(); @@ -483,6 +486,7 @@ bool SetVolumeName(const std::string& disc_path) { DVDThread::WaitUntilIdle(); s_inserted_volume = DiscIO::CreateVolumeFromFilename(disc_path); + SetDiscInside(VolumeIsValid()); return VolumeIsValid(); } @@ -492,6 +496,7 @@ bool SetVolumeDirectory(const std::string& full_path, bool is_wii, DVDThread::WaitUntilIdle(); s_inserted_volume = DiscIO::CreateVolumeFromDirectory(full_path, is_wii, apploader_path, DOL_path); + SetDiscInside(VolumeIsValid()); return VolumeIsValid(); } @@ -534,7 +539,6 @@ static void InsertDiscCallback(u64 userdata, s64 cyclesLate) SetVolumeName(old_path); PanicAlertT("The disc that was about to be inserted couldn't be found."); } - SetDiscInside(VolumeIsValid()); s_disc_path_to_insert.clear(); } diff --git a/Source/Core/Core/HW/DVDInterface.h b/Source/Core/Core/HW/DVDInterface.h index 410aee8f3e..fb6c97aea5 100644 --- a/Source/Core/Core/HW/DVDInterface.h +++ b/Source/Core/Core/HW/DVDInterface.h @@ -108,23 +108,23 @@ void DoState(PointerWrap& p); void RegisterMMIO(MMIO::Mapping* mmio, u32 base); -// Direct disc access +// Disc access (don't call GetVolume unless you know that VolumeIsValid() == true) const DiscIO::IVolume& GetVolume(); bool SetVolumeName(const std::string& disc_path); bool SetVolumeDirectory(const std::string& disc_path, bool is_wii, const std::string& apploader_path = "", const std::string& DOL_path = ""); bool VolumeIsValid(); - -// Disc detection and swapping -void SetDiscInside(bool _DiscInside); bool IsDiscInside(); void ChangeDiscAsHost(const std::string& new_path); // Can only be called by the host thread void ChangeDiscAsCPU(const std::string& new_path); // Can only be called by the CPU thread -// DVD Access Functions +// Direct access to DI for IOS HLE (simpler to implement than how real IOS accesses DI, +// and lets us skip encrypting/decrypting in some cases) bool ChangePartition(u64 offset); void ExecuteCommand(u32 command_0, u32 command_1, u32 command_2, u32 output_address, u32 output_length, bool reply_to_ios); + +// Used by DVDThread void FinishExecutingCommand(ReplyType reply_type, DIInterruptType interrupt_type, s64 cycles_late, const std::vector& data = std::vector()); From 740e4d09920021de7693381326969f15c210e034 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 30 Jan 2016 18:42:32 +0100 Subject: [PATCH 2/7] DVDInterface: Move a check from SetDiscInside to SetLidOpen --- Source/Core/Core/HW/DVDInterface.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/HW/DVDInterface.cpp b/Source/Core/Core/HW/DVDInterface.cpp index c333627b8a..0478f7a9a8 100644 --- a/Source/Core/Core/HW/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVDInterface.cpp @@ -507,9 +507,7 @@ bool VolumeIsValid() void SetDiscInside(bool disc_inside) { - if (s_disc_inside != disc_inside) - SetLidOpen(!disc_inside); - + SetLidOpen(!disc_inside); s_disc_inside = disc_inside; } @@ -572,9 +570,10 @@ void ChangeDiscAsCPU(const std::string& new_path) void SetLidOpen(bool open) { + u32 old_value = s_DICVR.CVR; s_DICVR.CVR = open ? 1 : 0; - - GenerateDIInterrupt(INT_CVRINT); + if (s_DICVR.CVR != old_value) + GenerateDIInterrupt(INT_CVRINT); } bool ChangePartition(u64 offset) From 900793ef1d8ecca51b91276947da4b9db36ae356 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 30 Jan 2016 18:50:12 +0100 Subject: [PATCH 3/7] DVDInterface: Remove s_disc_inside There's no point in having a variable for whether there is a disc when it's simpler to just directly check whether there is a disc. --- Source/Core/Core/HW/DVDInterface.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/Source/Core/Core/HW/DVDInterface.cpp b/Source/Core/Core/HW/DVDInterface.cpp index 0478f7a9a8..9a12876e57 100644 --- a/Source/Core/Core/HW/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVDInterface.cpp @@ -244,7 +244,6 @@ static u32 s_pending_samples; // Disc drive state static u32 s_error_code = 0; -static bool s_disc_inside = false; // Disc drive timing static u64 s_read_buffer_start_time; @@ -283,6 +282,8 @@ u64 CalculateRawDiscReadTime(u64 offset, u64 length); void DoState(PointerWrap& p) { + bool disc_inside = IsDiscInside(); + p.DoPOD(s_DISR); p.DoPOD(s_DICVR); p.DoArray(s_DICMDBUF); @@ -302,7 +303,7 @@ void DoState(PointerWrap& p) p.Do(s_pending_samples); p.Do(s_error_code); - p.Do(s_disc_inside); + p.Do(disc_inside); p.Do(s_read_buffer_start_time); p.Do(s_read_buffer_end_time); @@ -314,13 +315,13 @@ void DoState(PointerWrap& p) DVDThread::DoState(p); // s_inserted_volume isn't savestated (because it points to - // files on the local system). Instead, we check that - // s_disc_inside matches the status of s_inserted_volume. - // This won't catch cases of having the wrong disc inserted, though. + // files on the local system). Instead, we check that the + // savestated disc_inside matches our IsDiscInside(). This + // won't catch cases of having the wrong disc inserted, though. // TODO: Check the game ID, disc number, revision? - if (s_disc_inside != (s_inserted_volume != nullptr)) + if (disc_inside != IsDiscInside()) { - if (s_disc_inside) + if (disc_inside) PanicAlertT("An inserted disc was expected but not found."); else s_inserted_volume.reset(); @@ -425,7 +426,6 @@ void Init() Reset(); s_DICVR.Hex = 1; // Disc Channel relies on cover being open when no disc is inserted - s_disc_inside = false; s_eject_disc = CoreTiming::RegisterEvent("EjectDisc", EjectDiscCallback); s_insert_disc = CoreTiming::RegisterEvent("InsertDisc", InsertDiscCallback); @@ -508,12 +508,11 @@ bool VolumeIsValid() void SetDiscInside(bool disc_inside) { SetLidOpen(!disc_inside); - s_disc_inside = disc_inside; } bool IsDiscInside() { - return s_disc_inside; + return s_inserted_volume != nullptr; } // Take care of all logic of "swapping discs" @@ -702,7 +701,7 @@ void WriteImmediate(u32 value, u32 output_address, bool reply_to_ios) bool ExecuteReadCommand(u64 DVD_offset, u32 output_address, u32 DVD_length, u32 output_length, bool decrypt, ReplyType reply_type, DIInterruptType* interrupt_type) { - if (!s_disc_inside) + if (!IsDiscInside()) { // Disc read fails s_error_code = ERROR_NO_DISK | ERROR_COVER_H; @@ -817,8 +816,8 @@ void ExecuteCommand(u32 command_0, u32 command_1, u32 command_2, u32 output_addr // Probably only used by Wii case DVDLowGetCoverStatus: - WriteImmediate(s_disc_inside ? 2 : 1, output_address, reply_to_ios); - INFO_LOG(DVDINTERFACE, "DVDLowGetCoverStatus: Disc %sInserted", s_disc_inside ? "" : "Not "); + WriteImmediate(IsDiscInside() ? 2 : 1, output_address, reply_to_ios); + INFO_LOG(DVDINTERFACE, "DVDLowGetCoverStatus: Disc %sInserted", IsDiscInside() ? "" : "Not "); break; // Probably only used by Wii From 167d16ded6230210d038aad8cda2d298d5be37a5 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 30 Jan 2016 18:55:28 +0100 Subject: [PATCH 4/7] DVDInterface: Remove the SetLidOpen parameter The lid must always be consistent with whether a disc is inserted. Callers shouldn't be able to set inconsistent states. --- Source/Core/Core/HW/DVDInterface.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/HW/DVDInterface.cpp b/Source/Core/Core/HW/DVDInterface.cpp index 9a12876e57..797db5de3d 100644 --- a/Source/Core/Core/HW/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVDInterface.cpp @@ -264,7 +264,7 @@ static void InsertDiscCallback(u64 userdata, s64 cyclesLate); static void FinishExecutingCommandCallback(u64 userdata, s64 cycles_late); void SetDiscInside(bool disc_inside); -void SetLidOpen(bool open); +void SetLidOpen(); void UpdateInterrupts(); void GenerateDIInterrupt(DIInterruptType _DVDInterrupt); @@ -507,7 +507,7 @@ bool VolumeIsValid() void SetDiscInside(bool disc_inside) { - SetLidOpen(!disc_inside); + SetLidOpen(); } bool IsDiscInside() @@ -567,10 +567,10 @@ void ChangeDiscAsCPU(const std::string& new_path) Movie::SignalDiscChange(new_path); } -void SetLidOpen(bool open) +void SetLidOpen() { u32 old_value = s_DICVR.CVR; - s_DICVR.CVR = open ? 1 : 0; + s_DICVR.CVR = IsDiscInside() ? 0 : 1; if (s_DICVR.CVR != old_value) GenerateDIInterrupt(INT_CVRINT); } From 3b632f5990c0f18fbcb2edcbca3ab7035e069ce4 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 30 Jan 2016 18:57:20 +0100 Subject: [PATCH 5/7] DVDInterface: Remove SetDiscInside It's only a call to SetLidOpen now. --- Source/Core/Core/HW/DVDInterface.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/Source/Core/Core/HW/DVDInterface.cpp b/Source/Core/Core/HW/DVDInterface.cpp index 797db5de3d..95835b722f 100644 --- a/Source/Core/Core/HW/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVDInterface.cpp @@ -263,7 +263,6 @@ static void EjectDiscCallback(u64 userdata, s64 cyclesLate); static void InsertDiscCallback(u64 userdata, s64 cyclesLate); static void FinishExecutingCommandCallback(u64 userdata, s64 cycles_late); -void SetDiscInside(bool disc_inside); void SetLidOpen(); void UpdateInterrupts(); @@ -486,7 +485,7 @@ bool SetVolumeName(const std::string& disc_path) { DVDThread::WaitUntilIdle(); s_inserted_volume = DiscIO::CreateVolumeFromFilename(disc_path); - SetDiscInside(VolumeIsValid()); + SetLidOpen(); return VolumeIsValid(); } @@ -496,7 +495,7 @@ bool SetVolumeDirectory(const std::string& full_path, bool is_wii, DVDThread::WaitUntilIdle(); s_inserted_volume = DiscIO::CreateVolumeFromDirectory(full_path, is_wii, apploader_path, DOL_path); - SetDiscInside(VolumeIsValid()); + SetLidOpen(); return VolumeIsValid(); } @@ -505,11 +504,6 @@ bool VolumeIsValid() return s_inserted_volume != nullptr; } -void SetDiscInside(bool disc_inside) -{ - SetLidOpen(); -} - bool IsDiscInside() { return s_inserted_volume != nullptr; @@ -523,7 +517,7 @@ static void EjectDiscCallback(u64 userdata, s64 cyclesLate) { DVDThread::WaitUntilIdle(); s_inserted_volume.reset(); - SetDiscInside(false); + SetLidOpen(); } static void InsertDiscCallback(u64 userdata, s64 cyclesLate) From a176bf02299eb4aff0d987ad86570f33c396c83f Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 30 Jan 2016 19:03:59 +0100 Subject: [PATCH 6/7] DVDInterface: Remove VolumeIsValid It's the same as IsDiscInside. --- Source/Core/Core/Boot/Boot.cpp | 6 +++--- Source/Core/Core/Boot/Boot_BS2Emu.cpp | 8 ++++---- Source/Core/Core/HW/DVDInterface.cpp | 11 +++-------- Source/Core/Core/HW/DVDInterface.h | 3 +-- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index f7dd454484..53718ab03c 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -50,7 +50,7 @@ bool CBoot::DVDRead(u64 dvd_offset, u32 output_address, u32 length, bool decrypt void CBoot::Load_FST(bool _bIsWii) { - if (!DVDInterface::VolumeIsValid()) + if (!DVDInterface::IsDiscInside()) return; const DiscIO::IVolume& volume = DVDInterface::GetVolume(); @@ -267,7 +267,7 @@ bool CBoot::BootUp() case SConfig::BOOT_ISO: { DVDInterface::SetVolumeName(_StartupPara.m_strFilename); - if (!DVDInterface::VolumeIsValid()) + if (!DVDInterface::IsDiscInside()) return false; const DiscIO::IVolume& pVolume = DVDInterface::GetVolume(); @@ -336,7 +336,7 @@ bool CBoot::BootUp() { BS2Success = EmulatedBS2(dolWii); } - else if ((!DVDInterface::VolumeIsValid() || + else if ((!DVDInterface::IsDiscInside() || DVDInterface::GetVolume().GetVolumeType() != DiscIO::Platform::WII_DISC) && !_StartupPara.m_strDefaultISO.empty()) { diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index e320d93e71..cd5742b56f 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -67,7 +67,7 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader) // to 0x80000000 according to YAGCD 4.2. // It's possible to boot DOL and ELF files without a disc inserted - if (DVDInterface::VolumeIsValid()) + if (DVDInterface::IsDiscInside()) DVDRead(/*offset*/ 0x00000000, /*address*/ 0x00000000, 0x20, false); // write disc info PowerPC::HostWrite_U32(0x0D15EA5E, @@ -100,7 +100,7 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader) HLE::Patch(0x81300000, "OSReport"); // HLE OSReport for Apploader - if (!DVDInterface::VolumeIsValid()) + if (!DVDInterface::IsDiscInside()) return false; // Load Apploader to Memory - The apploader is hardcoded to begin at 0x2440 on the disc, @@ -255,7 +255,7 @@ bool CBoot::SetupWiiMemory(u64 ios_title_id) */ // When booting a WAD or the system menu, there will probably not be a disc inserted - if (DVDInterface::VolumeIsValid()) + if (DVDInterface::IsDiscInside()) DVDRead(0x00000000, 0x00000000, 0x20, false); // Game Code Memory::Write_U32(0x0D15EA5E, 0x00000020); // Another magic word @@ -306,7 +306,7 @@ bool CBoot::SetupWiiMemory(u64 ios_title_id) bool CBoot::EmulatedBS2_Wii() { INFO_LOG(BOOT, "Faking Wii BS2..."); - if (!DVDInterface::VolumeIsValid()) + if (!DVDInterface::IsDiscInside()) return false; if (DVDInterface::GetVolume().GetVolumeType() != DiscIO::Platform::WII_DISC) diff --git a/Source/Core/Core/HW/DVDInterface.cpp b/Source/Core/Core/HW/DVDInterface.cpp index 95835b722f..679ac51cf9 100644 --- a/Source/Core/Core/HW/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVDInterface.cpp @@ -419,7 +419,7 @@ static void DTKStreamingCallback(const std::vector& audio_data, s64 cycles_l void Init() { - _assert_(!VolumeIsValid()); + _assert_(!IsDiscInside()); DVDThread::Start(); @@ -486,7 +486,7 @@ bool SetVolumeName(const std::string& disc_path) DVDThread::WaitUntilIdle(); s_inserted_volume = DiscIO::CreateVolumeFromFilename(disc_path); SetLidOpen(); - return VolumeIsValid(); + return IsDiscInside(); } bool SetVolumeDirectory(const std::string& full_path, bool is_wii, @@ -496,12 +496,7 @@ bool SetVolumeDirectory(const std::string& full_path, bool is_wii, s_inserted_volume = DiscIO::CreateVolumeFromDirectory(full_path, is_wii, apploader_path, DOL_path); SetLidOpen(); - return VolumeIsValid(); -} - -bool VolumeIsValid() -{ - return s_inserted_volume != nullptr; + return IsDiscInside(); } bool IsDiscInside() diff --git a/Source/Core/Core/HW/DVDInterface.h b/Source/Core/Core/HW/DVDInterface.h index fb6c97aea5..64c4bc1efb 100644 --- a/Source/Core/Core/HW/DVDInterface.h +++ b/Source/Core/Core/HW/DVDInterface.h @@ -108,12 +108,11 @@ void DoState(PointerWrap& p); void RegisterMMIO(MMIO::Mapping* mmio, u32 base); -// Disc access (don't call GetVolume unless you know that VolumeIsValid() == true) +// Disc access (don't call GetVolume unless you know that IsDiscInside() == true) const DiscIO::IVolume& GetVolume(); bool SetVolumeName(const std::string& disc_path); bool SetVolumeDirectory(const std::string& disc_path, bool is_wii, const std::string& apploader_path = "", const std::string& DOL_path = ""); -bool VolumeIsValid(); bool IsDiscInside(); void ChangeDiscAsHost(const std::string& new_path); // Can only be called by the host thread void ChangeDiscAsCPU(const std::string& new_path); // Can only be called by the CPU thread From ac3bf7ad0bdc4c600ac4ca1538e4b46e177cb207 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 4 Feb 2017 10:11:36 +0100 Subject: [PATCH 7/7] DVDInterface: Assert IsDiscInside() in GetVolume() --- Source/Core/Core/HW/DVDInterface.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Core/Core/HW/DVDInterface.cpp b/Source/Core/Core/HW/DVDInterface.cpp index 679ac51cf9..fd3092309f 100644 --- a/Source/Core/Core/HW/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVDInterface.cpp @@ -478,6 +478,7 @@ void Shutdown() const DiscIO::IVolume& GetVolume() { + _assert_(IsDiscInside()); return *s_inserted_volume; }