diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 6e0ffebba6..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,8 +267,7 @@ bool CBoot::BootUp() case SConfig::BOOT_ISO: { DVDInterface::SetVolumeName(_StartupPara.m_strFilename); - DVDInterface::SetDiscInside(DVDInterface::VolumeIsValid()); - if (!DVDInterface::VolumeIsValid()) + if (!DVDInterface::IsDiscInside()) return false; const DiscIO::IVolume& pVolume = DVDInterface::GetVolume(); @@ -337,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()) { @@ -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/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 bcf3bba2ac..fd3092309f 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; @@ -264,7 +263,7 @@ 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 SetLidOpen(); void UpdateInterrupts(); void GenerateDIInterrupt(DIInterruptType _DVDInterrupt); @@ -282,6 +281,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); @@ -301,7 +302,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); @@ -313,13 +314,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(); @@ -418,11 +419,12 @@ static void DTKStreamingCallback(const std::vector& audio_data, s64 cycles_l void Init() { + _assert_(!IsDiscInside()); + DVDThread::Start(); 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); @@ -476,6 +478,7 @@ void Shutdown() const DiscIO::IVolume& GetVolume() { + _assert_(IsDiscInside()); return *s_inserted_volume; } @@ -483,7 +486,8 @@ bool SetVolumeName(const std::string& disc_path) { DVDThread::WaitUntilIdle(); s_inserted_volume = DiscIO::CreateVolumeFromFilename(disc_path); - return VolumeIsValid(); + SetLidOpen(); + return IsDiscInside(); } bool SetVolumeDirectory(const std::string& full_path, bool is_wii, @@ -492,25 +496,13 @@ 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); - return VolumeIsValid(); -} - -bool VolumeIsValid() -{ - return s_inserted_volume != nullptr; -} - -void SetDiscInside(bool disc_inside) -{ - if (s_disc_inside != disc_inside) - SetLidOpen(!disc_inside); - - s_disc_inside = disc_inside; + SetLidOpen(); + return IsDiscInside(); } bool IsDiscInside() { - return s_disc_inside; + return s_inserted_volume != nullptr; } // Take care of all logic of "swapping discs" @@ -521,7 +513,7 @@ static void EjectDiscCallback(u64 userdata, s64 cyclesLate) { DVDThread::WaitUntilIdle(); s_inserted_volume.reset(); - SetDiscInside(false); + SetLidOpen(); } static void InsertDiscCallback(u64 userdata, s64 cyclesLate) @@ -534,7 +526,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(); } @@ -566,11 +557,12 @@ void ChangeDiscAsCPU(const std::string& new_path) Movie::SignalDiscChange(new_path); } -void SetLidOpen(bool open) +void SetLidOpen() { - s_DICVR.CVR = open ? 1 : 0; - - GenerateDIInterrupt(INT_CVRINT); + u32 old_value = s_DICVR.CVR; + s_DICVR.CVR = IsDiscInside() ? 0 : 1; + if (s_DICVR.CVR != old_value) + GenerateDIInterrupt(INT_CVRINT); } bool ChangePartition(u64 offset) @@ -699,7 +691,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; @@ -814,8 +806,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 diff --git a/Source/Core/Core/HW/DVDInterface.h b/Source/Core/Core/HW/DVDInterface.h index 410aee8f3e..64c4bc1efb 100644 --- a/Source/Core/Core/HW/DVDInterface.h +++ b/Source/Core/Core/HW/DVDInterface.h @@ -108,23 +108,22 @@ void DoState(PointerWrap& p); void RegisterMMIO(MMIO::Mapping* mmio, u32 base); -// Direct disc access +// 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(); - -// 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());