Implement RTC flag, which is counter-intuitively disc drive related
This commit is contained in:
parent
77189e74cd
commit
11bd132650
|
@ -19,6 +19,7 @@
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/HLE/HLE.h"
|
#include "Core/HLE/HLE.h"
|
||||||
|
#include "Core/HW/DVD/DVDInterface.h"
|
||||||
#include "Core/HW/EXI/EXI_DeviceIPL.h"
|
#include "Core/HW/EXI/EXI_DeviceIPL.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/IOS/ES/ES.h"
|
#include "Core/IOS/ES/ES.h"
|
||||||
|
@ -390,6 +391,9 @@ bool CBoot::EmulatedBS2_Wii(const DiscIO::VolumeDisc& volume)
|
||||||
state->discstate = 0x01;
|
state->discstate = 0x01;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// The system menu clears the RTC flags
|
||||||
|
ExpansionInterface::g_rtc_flags.m_hex = 0;
|
||||||
|
|
||||||
// While reading a disc, the system menu reads the first partition table
|
// While reading a disc, the system menu reads the first partition table
|
||||||
// (0x20 bytes from 0x00040020) and stores a pointer to the data partition entry.
|
// (0x20 bytes from 0x00040020) and stores a pointer to the data partition entry.
|
||||||
// When launching the disc game, it copies the partition type and offset to 0x3194
|
// When launching the disc game, it copies the partition type and offset to 0x3194
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "Core/HW/AudioInterface.h"
|
#include "Core/HW/AudioInterface.h"
|
||||||
#include "Core/HW/DVD/DVDMath.h"
|
#include "Core/HW/DVD/DVDMath.h"
|
||||||
#include "Core/HW/DVD/DVDThread.h"
|
#include "Core/HW/DVD/DVDThread.h"
|
||||||
|
#include "Core/HW/EXI/EXI_DeviceIPL.h"
|
||||||
#include "Core/HW/MMIO.h"
|
#include "Core/HW/MMIO.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/HW/ProcessorInterface.h"
|
#include "Core/HW/ProcessorInterface.h"
|
||||||
|
@ -473,7 +474,9 @@ void Shutdown()
|
||||||
void SetDisc(std::unique_ptr<DiscIO::VolumeDisc> disc,
|
void SetDisc(std::unique_ptr<DiscIO::VolumeDisc> disc,
|
||||||
std::optional<std::vector<std::string>> auto_disc_change_paths = {})
|
std::optional<std::vector<std::string>> auto_disc_change_paths = {})
|
||||||
{
|
{
|
||||||
if (disc)
|
bool had_disc = IsDiscInside();
|
||||||
|
bool has_disc = static_cast<bool>(disc);
|
||||||
|
if (has_disc)
|
||||||
s_current_partition = disc->GetGamePartition();
|
s_current_partition = disc->GetGamePartition();
|
||||||
|
|
||||||
if (auto_disc_change_paths)
|
if (auto_disc_change_paths)
|
||||||
|
@ -485,6 +488,10 @@ void SetDisc(std::unique_ptr<DiscIO::VolumeDisc> disc,
|
||||||
s_auto_disc_change_index = 0;
|
s_auto_disc_change_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assume that inserting a disc requires having an empty disc before
|
||||||
|
if (had_disc != has_disc)
|
||||||
|
ExpansionInterface::g_rtc_flags[ExpansionInterface::RTCFlag::DiscChanged] = true;
|
||||||
|
|
||||||
DVDThread::SetDisc(std::move(disc));
|
DVDThread::SetDisc(std::move(disc));
|
||||||
SetLidOpen();
|
SetLidOpen();
|
||||||
}
|
}
|
||||||
|
@ -517,9 +524,11 @@ static void InsertDiscCallback(u64 userdata, s64 cyclesLate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must only be called on the CPU thread
|
// Must only be called on the CPU thread
|
||||||
void EjectDisc()
|
void EjectDisc(EjectCause cause)
|
||||||
{
|
{
|
||||||
CoreTiming::ScheduleEvent(0, s_eject_disc);
|
CoreTiming::ScheduleEvent(0, s_eject_disc);
|
||||||
|
if (cause == EjectCause::User)
|
||||||
|
ExpansionInterface::g_rtc_flags[ExpansionInterface::RTCFlag::EjectButton] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must only be called on the CPU thread
|
// Must only be called on the CPU thread
|
||||||
|
@ -545,7 +554,7 @@ void ChangeDisc(const std::string& new_path)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EjectDisc();
|
EjectDisc(EjectCause::User);
|
||||||
|
|
||||||
s_disc_path_to_insert = new_path;
|
s_disc_path_to_insert = new_path;
|
||||||
CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), s_insert_disc);
|
CoreTiming::ScheduleEvent(SystemTimers::GetTicksPerSecond(), s_insert_disc);
|
||||||
|
@ -1072,7 +1081,7 @@ void ExecuteCommand(u32 command_0, u32 command_1, u32 command_2, u32 output_addr
|
||||||
}
|
}
|
||||||
else if (force_eject)
|
else if (force_eject)
|
||||||
{
|
{
|
||||||
EjectDiscCallback(0, 0);
|
EjectDisc(EjectCause::Software);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,12 @@ enum class ReplyType : u32
|
||||||
DTK
|
DTK
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class EjectCause
|
||||||
|
{
|
||||||
|
User,
|
||||||
|
Software,
|
||||||
|
};
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void Reset();
|
void Reset();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
@ -84,7 +90,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
||||||
void SetDisc(std::unique_ptr<DiscIO::VolumeDisc> disc,
|
void SetDisc(std::unique_ptr<DiscIO::VolumeDisc> disc,
|
||||||
std::optional<std::vector<std::string>> auto_disc_change_paths);
|
std::optional<std::vector<std::string>> auto_disc_change_paths);
|
||||||
bool IsDiscInside();
|
bool IsDiscInside();
|
||||||
void EjectDisc(); // Must only be called on the CPU thread
|
void EjectDisc(EjectCause cause); // Must only be called on the CPU thread
|
||||||
void ChangeDisc(const std::vector<std::string>& paths); // Must only be called on the CPU thread
|
void ChangeDisc(const std::vector<std::string>& paths); // Must only be called on the CPU thread
|
||||||
void ChangeDisc(const std::string& new_path); // Must only be called on the CPU thread
|
void ChangeDisc(const std::string& new_path); // Must only be called on the CPU thread
|
||||||
bool AutoChangeDisc(); // Must only be called on the CPU thread
|
bool AutoChangeDisc(); // Must only be called on the CPU thread
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "Core/HW/EXI/EXI_DeviceIPL.h"
|
#include "Core/HW/EXI/EXI_DeviceIPL.h"
|
||||||
|
#include "Core/HW/DVD/DVDInterface.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -43,6 +44,8 @@ static const char iplverPAL[0x100] = "(C) 1999-2001 Nintendo. All rights reserv
|
||||||
static const char iplverNTSC[0x100] = "(C) 1999-2001 Nintendo. All rights reserved."
|
static const char iplverNTSC[0x100] = "(C) 1999-2001 Nintendo. All rights reserved."
|
||||||
"(C) 1999 ArtX Inc. All rights reserved.";
|
"(C) 1999 ArtX Inc. All rights reserved.";
|
||||||
|
|
||||||
|
Common::Flags<RTCFlag> g_rtc_flags;
|
||||||
|
|
||||||
// bootrom descrambler reversed by segher
|
// bootrom descrambler reversed by segher
|
||||||
// Copyright 2008 Segher Boessenkool <segher@kernel.crashing.org>
|
// Copyright 2008 Segher Boessenkool <segher@kernel.crashing.org>
|
||||||
void CEXIIPL::Descrambler(u8* data, u32 size)
|
void CEXIIPL::Descrambler(u8* data, u32 size)
|
||||||
|
@ -149,6 +152,7 @@ CEXIIPL::~CEXIIPL()
|
||||||
void CEXIIPL::DoState(PointerWrap& p)
|
void CEXIIPL::DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
p.Do(g_SRAM.rtc);
|
p.Do(g_SRAM.rtc);
|
||||||
|
p.Do(g_rtc_flags);
|
||||||
p.Do(m_command);
|
p.Do(m_command);
|
||||||
p.Do(m_command_bytes_received);
|
p.Do(m_command_bytes_received);
|
||||||
p.Do(m_cursor);
|
p.Do(m_cursor);
|
||||||
|
@ -361,10 +365,12 @@ void CEXIIPL::TransferByte(u8& data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IN_RANGE(WII_RTC))
|
else if (IN_RANGE(WII_RTC) && DEV_ADDR(WII_RTC) == 0x20)
|
||||||
{
|
{
|
||||||
// Wii only RTC flags... afaik only the Wii Menu initializes it
|
if (m_command.is_write())
|
||||||
// Seems to be 4bytes at dev_addr 0x20
|
g_rtc_flags.m_hex = data;
|
||||||
|
else
|
||||||
|
data = g_rtc_flags.m_hex;
|
||||||
}
|
}
|
||||||
else if (IN_RANGE(EUART))
|
else if (IN_RANGE(EUART))
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "Common/BitUtils.h"
|
||||||
#include "Core/HW/EXI/EXI_Device.h"
|
#include "Core/HW/EXI/EXI_Device.h"
|
||||||
|
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
|
@ -78,4 +79,17 @@ private:
|
||||||
|
|
||||||
static std::string FindIPLDump(const std::string& path_prefix);
|
static std::string FindIPLDump(const std::string& path_prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Used to indicate disc changes on the Wii, as insane as that sounds.
|
||||||
|
// However, the name is definitely RTCFlag, as the code that gets it is __OSGetRTCFlags and
|
||||||
|
// __OSClearRTCFlags in OSRtc.o (based on symbols from Kirby's Dream Collection)
|
||||||
|
// This may simply be a single byte that gets repeated 4 times by some EXI quirk,
|
||||||
|
// as reading it gives the value repeated 4 times but code only checks the first bit.
|
||||||
|
enum class RTCFlag : u32
|
||||||
|
{
|
||||||
|
EjectButton = 0x01010101,
|
||||||
|
DiscChanged = 0x02020202,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Common::Flags<RTCFlag> g_rtc_flags;
|
||||||
} // namespace ExpansionInterface
|
} // namespace ExpansionInterface
|
||||||
|
|
|
@ -194,7 +194,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
if (g_gpio_out[GPIO::DO_EJECT])
|
if (g_gpio_out[GPIO::DO_EJECT])
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC, "Ejecting disc due to GPIO write");
|
INFO_LOG(WII_IPC, "Ejecting disc due to GPIO write");
|
||||||
DVDInterface::EjectDisc();
|
DVDInterface::EjectDisc(DVDInterface::EjectCause::Software);
|
||||||
}
|
}
|
||||||
// SENSOR_BAR is checked by WiimoteEmu::CameraLogic
|
// SENSOR_BAR is checked by WiimoteEmu::CameraLogic
|
||||||
// TODO: AVE, SLOT_LED
|
// TODO: AVE, SLOT_LED
|
||||||
|
|
|
@ -686,7 +686,7 @@ void MainWindow::ChangeDisc()
|
||||||
|
|
||||||
void MainWindow::EjectDisc()
|
void MainWindow::EjectDisc()
|
||||||
{
|
{
|
||||||
Core::RunAsCPUThread(DVDInterface::EjectDisc);
|
Core::RunAsCPUThread([] { DVDInterface::EjectDisc(DVDInterface::EjectCause::User); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::Open()
|
void MainWindow::Open()
|
||||||
|
|
Loading…
Reference in New Issue