Skip to content
Permalink
Browse files
Merge pull request #8394 from Pokechu22/misc-di-gpio
Various DI improvements
  • Loading branch information
JosJuice committed Jan 13, 2020
2 parents ae6d3be + 3b5d20e commit 966e1b3
Show file tree
Hide file tree
Showing 20 changed files with 1,551 additions and 514 deletions.
@@ -8,6 +8,7 @@
#include <climits>
#include <cstddef>
#include <cstring>
#include <initializer_list>
#include <type_traits>

namespace Common
@@ -299,4 +300,44 @@ void SetBit(T& value, size_t bit_number, bool bit_value)
value &= ~(T{1} << bit_number);
}

template <typename T>
class FlagBit
{
public:
FlagBit(std::underlying_type_t<T>& bits, T bit) : m_bits(bits), m_bit(bit) {}
explicit operator bool() const
{
return (m_bits & static_cast<std::underlying_type_t<T>>(m_bit)) != 0;
}
FlagBit& operator=(const bool rhs)
{
if (rhs)
m_bits |= static_cast<std::underlying_type_t<T>>(m_bit);
else
m_bits &= ~static_cast<std::underlying_type_t<T>>(m_bit);
return *this;
}

private:
std::underlying_type_t<T>& m_bits;
T m_bit;
};

template <typename T>
class Flags
{
public:
constexpr Flags() = default;
constexpr Flags(std::initializer_list<T> bits)
{
for (auto bit : bits)
{
m_hex |= static_cast<std::underlying_type_t<T>>(bit);
}
}
FlagBit<T> operator[](T bit) { return FlagBit(m_hex, bit); }

std::underlying_type_t<T> m_hex = 0;
};

} // namespace Common
@@ -19,6 +19,7 @@
#include <deque>
#include <list>
#include <map>
#include <optional>
#include <set>
#include <string>
#include <type_traits>
@@ -144,6 +145,36 @@ class PointerWrap
Do(x.second);
}

template <typename T>
void Do(std::optional<T>& x)
{
bool present = x.has_value();
Do(present);

switch (mode)
{
case MODE_READ:
if (present)
{
x = std::make_optional<T>();
Do(x.value());
}
else
{
x = std::nullopt;
}
break;

case MODE_WRITE:
case MODE_MEASURE:
case MODE_VERIFY:
if (present)
Do(x.value());

break;
}
}

template <typename T, std::size_t N>
void DoArray(std::array<T, N>& x)
{
@@ -132,9 +132,16 @@ void DolphinAnalytics::ReportGameStart()
}

// Keep in sync with enum class GameQuirk definition.
constexpr std::array<const char*, 2> GAME_QUIRKS_NAMES{
constexpr std::array<const char*, 9> GAME_QUIRKS_NAMES{
"icache-matters",
"directly-reads-wiimote-input",
"uses-DVDLowStopLaser",
"uses-DVDLowOffset",
"uses-DVDLowReadDiskBca",
"uses-DVDLowRequestDiscStatus",
"uses-DVDLowRequestRetryNumber",
"uses-DVDLowSerMeasControl",
"uses-different-partition-command",
};
static_assert(GAME_QUIRKS_NAMES.size() == static_cast<u32>(GameQuirk::COUNT),
"Game quirks names and enum definition are out of sync.");
@@ -29,6 +29,18 @@ enum class GameQuirk
// "read" extension or IR data. This would break our current TAS/NetPlay implementation.
DIRECTLY_READS_WIIMOTE_INPUT,

// Several Wii DI commands that are rarely/never used and not implemented by Dolphin
USES_DVD_LOW_STOP_LASER,
USES_DVD_LOW_OFFSET,
USES_DVD_LOW_READ_DISK_BCA, // NSMBW known to use this
USES_DVD_LOW_REQUEST_DISC_STATUS,
USES_DVD_LOW_REQUEST_RETRY_NUMBER,
USES_DVD_LOW_SER_MEAS_CONTROL,

// Dolphin only implements the simple DVDLowOpenPartition, not any of the variants where some
// already-read data is provided
USES_DIFFERENT_PARTITION_COMMAND,

COUNT,
};

@@ -244,6 +244,17 @@ bool CBoot::DVDRead(const DiscIO::VolumeDisc& disc, u64 dvd_offset, u32 output_a
return true;
}

bool CBoot::DVDReadDiscID(const DiscIO::VolumeDisc& disc, u32 output_address)
{
std::array<u8, 0x20> buffer;
if (!disc.Read(0, buffer.size(), buffer.data(), DiscIO::PARTITION_NONE))
return false;
Memory::CopyToEmu(output_address, buffer.data(), buffer.size());
// Clear ERROR_NO_DISKID_L, probably should check if that's currently set
DVDInterface::SetLowError(DVDInterface::ERROR_READY);
return true;
}

void CBoot::UpdateDebugger_MapLoaded()
{
Host_NotifyMapLoaded();
@@ -104,6 +104,7 @@ class CBoot
private:
static bool DVDRead(const DiscIO::VolumeDisc& disc, u64 dvd_offset, u32 output_address,
u32 length, const DiscIO::Partition& partition);
static bool DVDReadDiscID(const DiscIO::VolumeDisc& disc, u32 output_address);
static void RunFunction(u32 address);

static void UpdateDebugger_MapLoaded();
@@ -19,8 +19,10 @@
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/HLE/HLE.h"
#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/EXI/EXI_DeviceIPL.h"
#include "Core/HW/Memmap.h"
#include "Core/IOS/DI/DI.h"
#include "Core/IOS/ES/ES.h"
#include "Core/IOS/ES/Formats.h"
#include "Core/IOS/FS/FileSystem.h"
@@ -209,7 +211,22 @@ bool CBoot::EmulatedBS2_GC(const DiscIO::VolumeDisc& volume)

SetupGCMemory();

DVDRead(volume, /*offset*/ 0x00000000, /*address*/ 0x00000000, 0x20, DiscIO::PARTITION_NONE);
DVDReadDiscID(volume, 0x00000000);

bool streaming = Memory::Read_U8(0x80000008);
if (streaming)
{
u8 streaming_size = Memory::Read_U8(0x80000009);
// If the streaming buffer size is 0, then BS2 uses a default size of 10 instead.
// No known game uses a size other than the default.
if (streaming_size == 0)
streaming_size = 10;
DVDInterface::AudioBufferConfig(true, streaming_size);
}
else
{
DVDInterface::AudioBufferConfig(false, 0);
}

const bool ntsc = DiscIO::IsNTSC(SConfig::GetInstance().m_region);

@@ -390,6 +407,9 @@ bool CBoot::EmulatedBS2_Wii(const DiscIO::VolumeDisc& volume)
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
// (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
@@ -402,7 +422,13 @@ bool CBoot::EmulatedBS2_Wii(const DiscIO::VolumeDisc& volume)
if (!SetupWiiMemory(console_type) || !IOS::HLE::GetIOS()->BootIOS(tmd.GetIOSId()))
return false;

DVDRead(volume, 0x00000000, 0x00000000, 0x20, DiscIO::PARTITION_NONE); // Game Code
auto di = std::static_pointer_cast<IOS::HLE::Device::DI>(
IOS::HLE::GetIOS()->GetDeviceByName("/dev/di"));

di->InitializeIfFirstTime();
di->ChangePartition(data_partition);

DVDReadDiscID(volume, 0x00000000);

// This is some kind of consistency check that is compared to the 0x00
// values as the game boots. This location keeps the 4 byte ID for as long

0 comments on commit 966e1b3

Please sign in to comment.