MMU: Replace TryReadResult and TryWriteResult with std::optional
This commit is contained in:
parent
673f886a7e
commit
525e6b2194
|
@ -101,87 +101,87 @@ std::vector<u8> Cheats::GetValueAsByteVector(const Cheats::SearchValue& value)
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static PowerPC::TryReadResult<T>
|
static std::optional<PowerPC::ReadResult<T>>
|
||||||
TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space);
|
TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space);
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
PowerPC::TryReadResult<u8> TryReadValueFromEmulatedMemory(u32 addr,
|
std::optional<PowerPC::ReadResult<u8>>
|
||||||
PowerPC::RequestedAddressSpace space)
|
TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
return PowerPC::HostTryReadU8(addr, space);
|
return PowerPC::HostTryReadU8(addr, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
PowerPC::TryReadResult<u16> TryReadValueFromEmulatedMemory(u32 addr,
|
std::optional<PowerPC::ReadResult<u16>>
|
||||||
PowerPC::RequestedAddressSpace space)
|
TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
return PowerPC::HostTryReadU16(addr, space);
|
return PowerPC::HostTryReadU16(addr, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
PowerPC::TryReadResult<u32> TryReadValueFromEmulatedMemory(u32 addr,
|
std::optional<PowerPC::ReadResult<u32>>
|
||||||
PowerPC::RequestedAddressSpace space)
|
TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
return PowerPC::HostTryReadU32(addr, space);
|
return PowerPC::HostTryReadU32(addr, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
PowerPC::TryReadResult<u64> TryReadValueFromEmulatedMemory(u32 addr,
|
std::optional<PowerPC::ReadResult<u64>>
|
||||||
PowerPC::RequestedAddressSpace space)
|
TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
return PowerPC::HostTryReadU64(addr, space);
|
return PowerPC::HostTryReadU64(addr, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
PowerPC::TryReadResult<s8> TryReadValueFromEmulatedMemory(u32 addr,
|
std::optional<PowerPC::ReadResult<s8>>
|
||||||
PowerPC::RequestedAddressSpace space)
|
TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
auto tmp = PowerPC::HostTryReadU8(addr, space);
|
auto tmp = PowerPC::HostTryReadU8(addr, space);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return PowerPC::TryReadResult<s8>();
|
return std::nullopt;
|
||||||
return PowerPC::TryReadResult<s8>(tmp.translated, Common::BitCast<s8>(tmp.value));
|
return PowerPC::ReadResult<s8>(tmp->translated, Common::BitCast<s8>(tmp->value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
PowerPC::TryReadResult<s16> TryReadValueFromEmulatedMemory(u32 addr,
|
std::optional<PowerPC::ReadResult<s16>>
|
||||||
PowerPC::RequestedAddressSpace space)
|
TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
auto tmp = PowerPC::HostTryReadU16(addr, space);
|
auto tmp = PowerPC::HostTryReadU16(addr, space);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return PowerPC::TryReadResult<s16>();
|
return std::nullopt;
|
||||||
return PowerPC::TryReadResult<s16>(tmp.translated, Common::BitCast<s16>(tmp.value));
|
return PowerPC::ReadResult<s16>(tmp->translated, Common::BitCast<s16>(tmp->value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
PowerPC::TryReadResult<s32> TryReadValueFromEmulatedMemory(u32 addr,
|
std::optional<PowerPC::ReadResult<s32>>
|
||||||
PowerPC::RequestedAddressSpace space)
|
TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
auto tmp = PowerPC::HostTryReadU32(addr, space);
|
auto tmp = PowerPC::HostTryReadU32(addr, space);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return PowerPC::TryReadResult<s32>();
|
return std::nullopt;
|
||||||
return PowerPC::TryReadResult<s32>(tmp.translated, Common::BitCast<s32>(tmp.value));
|
return PowerPC::ReadResult<s32>(tmp->translated, Common::BitCast<s32>(tmp->value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
PowerPC::TryReadResult<s64> TryReadValueFromEmulatedMemory(u32 addr,
|
std::optional<PowerPC::ReadResult<s64>>
|
||||||
PowerPC::RequestedAddressSpace space)
|
TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
auto tmp = PowerPC::HostTryReadU64(addr, space);
|
auto tmp = PowerPC::HostTryReadU64(addr, space);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return PowerPC::TryReadResult<s64>();
|
return std::nullopt;
|
||||||
return PowerPC::TryReadResult<s64>(tmp.translated, Common::BitCast<s64>(tmp.value));
|
return PowerPC::ReadResult<s64>(tmp->translated, Common::BitCast<s64>(tmp->value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
PowerPC::TryReadResult<float> TryReadValueFromEmulatedMemory(u32 addr,
|
std::optional<PowerPC::ReadResult<float>>
|
||||||
PowerPC::RequestedAddressSpace space)
|
TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
return PowerPC::HostTryReadF32(addr, space);
|
return PowerPC::HostTryReadF32(addr, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
PowerPC::TryReadResult<double> TryReadValueFromEmulatedMemory(u32 addr,
|
std::optional<PowerPC::ReadResult<double>>
|
||||||
PowerPC::RequestedAddressSpace space)
|
TryReadValueFromEmulatedMemory(u32 addr, PowerPC::RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
return PowerPC::HostTryReadF64(addr, space);
|
return PowerPC::HostTryReadF64(addr, space);
|
||||||
}
|
}
|
||||||
|
@ -230,11 +230,11 @@ Cheats::NewSearch(const std::vector<Cheats::MemoryRange>& memory_ranges,
|
||||||
if (!current_value)
|
if (!current_value)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (validator(current_value.value))
|
if (validator(current_value->value))
|
||||||
{
|
{
|
||||||
auto& r = results.emplace_back();
|
auto& r = results.emplace_back();
|
||||||
r.m_value = current_value.value;
|
r.m_value = current_value->value;
|
||||||
r.m_value_state = current_value.translated ?
|
r.m_value_state = current_value->translated ?
|
||||||
Cheats::SearchResultValueState::ValueFromVirtualMemory :
|
Cheats::SearchResultValueState::ValueFromVirtualMemory :
|
||||||
Cheats::SearchResultValueState::ValueFromPhysicalMemory;
|
Cheats::SearchResultValueState::ValueFromPhysicalMemory;
|
||||||
r.m_address = addr;
|
r.m_address = addr;
|
||||||
|
@ -284,11 +284,11 @@ Cheats::NextSearch(const std::vector<Cheats::SearchResult<T>>& previous_results,
|
||||||
// if the previous state was invalid we always update the value to avoid getting stuck in an
|
// if the previous state was invalid we always update the value to avoid getting stuck in an
|
||||||
// invalid state
|
// invalid state
|
||||||
if (!previous_result.IsValueValid() ||
|
if (!previous_result.IsValueValid() ||
|
||||||
validator(current_value.value, previous_result.m_value))
|
validator(current_value->value, previous_result.m_value))
|
||||||
{
|
{
|
||||||
auto& r = results.emplace_back();
|
auto& r = results.emplace_back();
|
||||||
r.m_value = current_value.value;
|
r.m_value = current_value->value;
|
||||||
r.m_value_state = current_value.translated ?
|
r.m_value_state = current_value->translated ?
|
||||||
Cheats::SearchResultValueState::ValueFromVirtualMemory :
|
Cheats::SearchResultValueState::ValueFromVirtualMemory :
|
||||||
Cheats::SearchResultValueState::ValueFromPhysicalMemory;
|
Cheats::SearchResultValueState::ValueFromPhysicalMemory;
|
||||||
r.m_address = addr;
|
r.m_address = addr;
|
||||||
|
|
|
@ -468,34 +468,35 @@ u32 HostRead_Instruction(const u32 address)
|
||||||
return ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
|
return ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
TryReadResult<u32> HostTryReadInstruction(const u32 address, RequestedAddressSpace space)
|
std::optional<ReadResult<u32>> HostTryReadInstruction(const u32 address,
|
||||||
|
RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
if (!HostIsInstructionRAMAddress(address, space))
|
if (!HostIsInstructionRAMAddress(address, space))
|
||||||
return TryReadResult<u32>();
|
return std::nullopt;
|
||||||
|
|
||||||
switch (space)
|
switch (space)
|
||||||
{
|
{
|
||||||
case RequestedAddressSpace::Effective:
|
case RequestedAddressSpace::Effective:
|
||||||
{
|
{
|
||||||
const u32 value = ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
|
const u32 value = ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
|
||||||
return TryReadResult<u32>(!!MSR.DR, value);
|
return ReadResult<u32>(!!MSR.DR, value);
|
||||||
}
|
}
|
||||||
case RequestedAddressSpace::Physical:
|
case RequestedAddressSpace::Physical:
|
||||||
{
|
{
|
||||||
const u32 value = ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32, true>(address);
|
const u32 value = ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32, true>(address);
|
||||||
return TryReadResult<u32>(false, value);
|
return ReadResult<u32>(false, value);
|
||||||
}
|
}
|
||||||
case RequestedAddressSpace::Virtual:
|
case RequestedAddressSpace::Virtual:
|
||||||
{
|
{
|
||||||
if (!MSR.DR)
|
if (!MSR.DR)
|
||||||
return TryReadResult<u32>();
|
return std::nullopt;
|
||||||
const u32 value = ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
|
const u32 value = ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
|
||||||
return TryReadResult<u32>(true, value);
|
return ReadResult<u32>(true, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
return TryReadResult<u32>();
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Memcheck(u32 address, u64 var, bool write, size_t size)
|
static void Memcheck(u32 address, u64 var, bool write, size_t size)
|
||||||
|
@ -574,70 +575,70 @@ float Read_F32(const u32 address)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static TryReadResult<T> HostTryReadUX(const u32 address, RequestedAddressSpace space)
|
static std::optional<ReadResult<T>> HostTryReadUX(const u32 address, RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
if (!HostIsRAMAddress(address, space))
|
if (!HostIsRAMAddress(address, space))
|
||||||
return TryReadResult<T>();
|
return std::nullopt;
|
||||||
|
|
||||||
switch (space)
|
switch (space)
|
||||||
{
|
{
|
||||||
case RequestedAddressSpace::Effective:
|
case RequestedAddressSpace::Effective:
|
||||||
{
|
{
|
||||||
T value = ReadFromHardware<XCheckTLBFlag::NoException, T>(address);
|
T value = ReadFromHardware<XCheckTLBFlag::NoException, T>(address);
|
||||||
return TryReadResult<T>(!!MSR.DR, std::move(value));
|
return ReadResult<T>(!!MSR.DR, std::move(value));
|
||||||
}
|
}
|
||||||
case RequestedAddressSpace::Physical:
|
case RequestedAddressSpace::Physical:
|
||||||
{
|
{
|
||||||
T value = ReadFromHardware<XCheckTLBFlag::NoException, T, true>(address);
|
T value = ReadFromHardware<XCheckTLBFlag::NoException, T, true>(address);
|
||||||
return TryReadResult<T>(false, std::move(value));
|
return ReadResult<T>(false, std::move(value));
|
||||||
}
|
}
|
||||||
case RequestedAddressSpace::Virtual:
|
case RequestedAddressSpace::Virtual:
|
||||||
{
|
{
|
||||||
if (!MSR.DR)
|
if (!MSR.DR)
|
||||||
return TryReadResult<T>();
|
return std::nullopt;
|
||||||
T value = ReadFromHardware<XCheckTLBFlag::NoException, T>(address);
|
T value = ReadFromHardware<XCheckTLBFlag::NoException, T>(address);
|
||||||
return TryReadResult<T>(true, std::move(value));
|
return ReadResult<T>(true, std::move(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
return TryReadResult<T>();
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
TryReadResult<u8> HostTryReadU8(u32 address, RequestedAddressSpace space)
|
std::optional<ReadResult<u8>> HostTryReadU8(u32 address, RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
return HostTryReadUX<u8>(address, space);
|
return HostTryReadUX<u8>(address, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
TryReadResult<u16> HostTryReadU16(u32 address, RequestedAddressSpace space)
|
std::optional<ReadResult<u16>> HostTryReadU16(u32 address, RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
return HostTryReadUX<u16>(address, space);
|
return HostTryReadUX<u16>(address, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
TryReadResult<u32> HostTryReadU32(u32 address, RequestedAddressSpace space)
|
std::optional<ReadResult<u32>> HostTryReadU32(u32 address, RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
return HostTryReadUX<u32>(address, space);
|
return HostTryReadUX<u32>(address, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
TryReadResult<u64> HostTryReadU64(u32 address, RequestedAddressSpace space)
|
std::optional<ReadResult<u64>> HostTryReadU64(u32 address, RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
return HostTryReadUX<u64>(address, space);
|
return HostTryReadUX<u64>(address, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
TryReadResult<float> HostTryReadF32(u32 address, RequestedAddressSpace space)
|
std::optional<ReadResult<float>> HostTryReadF32(u32 address, RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
const auto result = HostTryReadUX<u32>(address, space);
|
const auto result = HostTryReadUX<u32>(address, space);
|
||||||
if (!result)
|
if (!result)
|
||||||
return TryReadResult<float>();
|
return std::nullopt;
|
||||||
return TryReadResult<float>(result.translated, Common::BitCast<float>(result.value));
|
return ReadResult<float>(result->translated, Common::BitCast<float>(result->value));
|
||||||
}
|
}
|
||||||
|
|
||||||
TryReadResult<double> HostTryReadF64(u32 address, RequestedAddressSpace space)
|
std::optional<ReadResult<double>> HostTryReadF64(u32 address, RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
const auto result = HostTryReadUX<u64>(address, space);
|
const auto result = HostTryReadUX<u64>(address, space);
|
||||||
if (!result)
|
if (!result)
|
||||||
return TryReadResult<double>();
|
return std::nullopt;
|
||||||
return TryReadResult<double>(result.translated, Common::BitCast<double>(result.value));
|
return ReadResult<double>(result->translated, Common::BitCast<double>(result->value));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Read_U8_ZX(const u32 address)
|
u32 Read_U8_ZX(const u32 address)
|
||||||
|
@ -763,62 +764,68 @@ void HostWrite_F64(const double var, const u32 address)
|
||||||
HostWrite_U64(integral, address);
|
HostWrite_U64(integral, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TryWriteResult HostTryWriteUX(const u32 var, const u32 address, const u32 size,
|
static std::optional<WriteResult> HostTryWriteUX(const u32 var, const u32 address, const u32 size,
|
||||||
RequestedAddressSpace space)
|
RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
if (!HostIsRAMAddress(address, space))
|
if (!HostIsRAMAddress(address, space))
|
||||||
return TryWriteResult();
|
return std::nullopt;
|
||||||
|
|
||||||
switch (space)
|
switch (space)
|
||||||
{
|
{
|
||||||
case RequestedAddressSpace::Effective:
|
case RequestedAddressSpace::Effective:
|
||||||
WriteToHardware<XCheckTLBFlag::NoException>(address, var, size);
|
WriteToHardware<XCheckTLBFlag::NoException>(address, var, size);
|
||||||
return TryWriteResult(!!MSR.DR);
|
return WriteResult(!!MSR.DR);
|
||||||
case RequestedAddressSpace::Physical:
|
case RequestedAddressSpace::Physical:
|
||||||
WriteToHardware<XCheckTLBFlag::NoException, true>(address, var, size);
|
WriteToHardware<XCheckTLBFlag::NoException, true>(address, var, size);
|
||||||
return TryWriteResult(false);
|
return WriteResult(false);
|
||||||
case RequestedAddressSpace::Virtual:
|
case RequestedAddressSpace::Virtual:
|
||||||
if (!MSR.DR)
|
if (!MSR.DR)
|
||||||
return TryWriteResult();
|
return std::nullopt;
|
||||||
WriteToHardware<XCheckTLBFlag::NoException>(address, var, size);
|
WriteToHardware<XCheckTLBFlag::NoException>(address, var, size);
|
||||||
return TryWriteResult(true);
|
return WriteResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
return TryWriteResult();
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
TryWriteResult HostTryWriteU8(const u32 var, const u32 address, RequestedAddressSpace space)
|
std::optional<WriteResult> HostTryWriteU8(const u32 var, const u32 address,
|
||||||
|
RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
return HostTryWriteUX(var, address, 1, space);
|
return HostTryWriteUX(var, address, 1, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
TryWriteResult HostTryWriteU16(const u32 var, const u32 address, RequestedAddressSpace space)
|
std::optional<WriteResult> HostTryWriteU16(const u32 var, const u32 address,
|
||||||
|
RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
return HostTryWriteUX(var, address, 2, space);
|
return HostTryWriteUX(var, address, 2, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
TryWriteResult HostTryWriteU32(const u32 var, const u32 address, RequestedAddressSpace space)
|
std::optional<WriteResult> HostTryWriteU32(const u32 var, const u32 address,
|
||||||
|
RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
return HostTryWriteUX(var, address, 4, space);
|
return HostTryWriteUX(var, address, 4, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
TryWriteResult HostTryWriteU64(const u64 var, const u32 address, RequestedAddressSpace space)
|
std::optional<WriteResult> HostTryWriteU64(const u64 var, const u32 address,
|
||||||
|
RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
const TryWriteResult result = HostTryWriteUX(static_cast<u32>(var >> 32), address, 4, space);
|
const auto result = HostTryWriteUX(static_cast<u32>(var >> 32), address, 4, space);
|
||||||
if (!result)
|
if (!result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
return HostTryWriteUX(static_cast<u32>(var), address + 4, 4, space);
|
return HostTryWriteUX(static_cast<u32>(var), address + 4, 4, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
TryWriteResult HostTryWriteF32(const float var, const u32 address, RequestedAddressSpace space)
|
std::optional<WriteResult> HostTryWriteF32(const float var, const u32 address,
|
||||||
|
RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
const u32 integral = Common::BitCast<u32>(var);
|
const u32 integral = Common::BitCast<u32>(var);
|
||||||
return HostTryWriteU32(integral, address, space);
|
return HostTryWriteU32(integral, address, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
TryWriteResult HostTryWriteF64(const double var, const u32 address, RequestedAddressSpace space)
|
std::optional<WriteResult> HostTryWriteF64(const double var, const u32 address,
|
||||||
|
RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
const u64 integral = Common::BitCast<u64>(var);
|
const u64 integral = Common::BitCast<u64>(var);
|
||||||
return HostTryWriteU64(integral, address, space);
|
return HostTryWriteU64(integral, address, space);
|
||||||
|
@ -840,25 +847,26 @@ std::string HostGetString(u32 address, size_t size)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
TryReadResult<std::string> HostTryReadString(u32 address, size_t size, RequestedAddressSpace space)
|
std::optional<ReadResult<std::string>> HostTryReadString(u32 address, size_t size,
|
||||||
|
RequestedAddressSpace space)
|
||||||
{
|
{
|
||||||
auto c = HostTryReadU8(address, space);
|
auto c = HostTryReadU8(address, space);
|
||||||
if (!c)
|
if (!c)
|
||||||
return TryReadResult<std::string>();
|
return std::nullopt;
|
||||||
if (c.value == 0)
|
if (c->value == 0)
|
||||||
return TryReadResult<std::string>(c.translated, "");
|
return ReadResult<std::string>(c->translated, "");
|
||||||
|
|
||||||
std::string s;
|
std::string s;
|
||||||
s += static_cast<char>(c.value);
|
s += static_cast<char>(c->value);
|
||||||
while (size == 0 || s.length() < size)
|
while (size == 0 || s.length() < size)
|
||||||
{
|
{
|
||||||
++address;
|
++address;
|
||||||
const auto res = HostTryReadU8(address, space);
|
const auto res = HostTryReadU8(address, space);
|
||||||
if (!res || res.value == 0)
|
if (!res || res->value == 0)
|
||||||
break;
|
break;
|
||||||
s += static_cast<char>(res.value);
|
s += static_cast<char>(res->value);
|
||||||
}
|
}
|
||||||
return TryReadResult<std::string>(c.translated, std::move(s));
|
return ReadResult<std::string>(c->translated, std::move(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsOptimizableRAMAddress(const u32 address)
|
bool IsOptimizableRAMAddress(const u32 address)
|
||||||
|
|
|
@ -37,11 +37,8 @@ u32 HostRead_Instruction(u32 address);
|
||||||
std::string HostGetString(u32 address, size_t size = 0);
|
std::string HostGetString(u32 address, size_t size = 0);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct TryReadResult
|
struct ReadResult
|
||||||
{
|
{
|
||||||
// whether the read succeeded; if false, the other fields should not be touched
|
|
||||||
bool success;
|
|
||||||
|
|
||||||
// whether the address had to be translated (given address was treated as virtual) or not (given
|
// whether the address had to be translated (given address was treated as virtual) or not (given
|
||||||
// address was treated as physical)
|
// address was treated as physical)
|
||||||
bool translated;
|
bool translated;
|
||||||
|
@ -49,37 +46,31 @@ struct TryReadResult
|
||||||
// the actual value that was read
|
// the actual value that was read
|
||||||
T value;
|
T value;
|
||||||
|
|
||||||
TryReadResult() : success(false) {}
|
ReadResult(bool translated_, T&& value_) : translated(translated_), value(std::forward<T>(value_))
|
||||||
TryReadResult(bool translated_, T&& value_)
|
|
||||||
: success(true), translated(translated_), value(std::move(value_))
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
TryReadResult(bool translated_, const T& value_)
|
ReadResult(bool translated_, const T& value_) : translated(translated_), value(value_) {}
|
||||||
: success(true), translated(translated_), value(value_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
explicit operator bool() const { return success; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Try to read a value from emulated memory at the given address in the given memory space.
|
// Try to read a value from emulated memory at the given address in the given memory space.
|
||||||
// If the read succeeds, the returned TryReadResult contains the read value and information on
|
// If the read succeeds, the returned value will be present and the ReadResult contains the read
|
||||||
// whether the given address had to be translated or not. Unlike the HostRead functions, this does
|
// value and information on whether the given address had to be translated or not. Unlike the
|
||||||
// not raise a user-visible alert on failure.
|
// HostRead functions, this does not raise a user-visible alert on failure.
|
||||||
TryReadResult<u8> HostTryReadU8(u32 address,
|
std::optional<ReadResult<u8>>
|
||||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
HostTryReadU8(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
TryReadResult<u16> HostTryReadU16(u32 address,
|
std::optional<ReadResult<u16>>
|
||||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
HostTryReadU16(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
TryReadResult<u32> HostTryReadU32(u32 address,
|
std::optional<ReadResult<u32>>
|
||||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
HostTryReadU32(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
TryReadResult<u64> HostTryReadU64(u32 address,
|
std::optional<ReadResult<u64>>
|
||||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
HostTryReadU64(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
TryReadResult<float> HostTryReadF32(u32 address,
|
std::optional<ReadResult<float>>
|
||||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
HostTryReadF32(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
TryReadResult<double>
|
std::optional<ReadResult<double>>
|
||||||
HostTryReadF64(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
HostTryReadF64(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
TryReadResult<u32>
|
std::optional<ReadResult<u32>>
|
||||||
HostTryReadInstruction(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
HostTryReadInstruction(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
TryReadResult<std::string>
|
std::optional<ReadResult<std::string>>
|
||||||
HostTryReadString(u32 address, size_t size = 0,
|
HostTryReadString(u32 address, size_t size = 0,
|
||||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
|
|
||||||
|
@ -93,35 +84,36 @@ void HostWrite_U64(u64 var, u32 address);
|
||||||
void HostWrite_F32(float var, u32 address);
|
void HostWrite_F32(float var, u32 address);
|
||||||
void HostWrite_F64(double var, u32 address);
|
void HostWrite_F64(double var, u32 address);
|
||||||
|
|
||||||
struct TryWriteResult
|
struct WriteResult
|
||||||
{
|
{
|
||||||
// whether the write succeeded; if false, the other fields should not be touched
|
|
||||||
bool success;
|
|
||||||
|
|
||||||
// whether the address had to be translated (given address was treated as virtual) or not (given
|
// whether the address had to be translated (given address was treated as virtual) or not (given
|
||||||
// address was treated as physical)
|
// address was treated as physical)
|
||||||
bool translated;
|
bool translated;
|
||||||
|
|
||||||
TryWriteResult() : success(false) {}
|
explicit WriteResult(bool translated_) : translated(translated_) {}
|
||||||
TryWriteResult(bool translated_) : success(true), translated(translated_) {}
|
|
||||||
explicit operator bool() const { return success; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Try to a write a value to memory at the given address in the given memory space.
|
// Try to a write a value to memory at the given address in the given memory space.
|
||||||
// If the write succeeds, the returned TryWriteResult contains information on whether the given
|
// If the write succeeds, the returned TryWriteResult contains information on whether the given
|
||||||
// address had to be translated or not. Unlike the HostWrite functions, this does not raise a
|
// address had to be translated or not. Unlike the HostWrite functions, this does not raise a
|
||||||
// user-visible alert on failure.
|
// user-visible alert on failure.
|
||||||
TryWriteResult HostTryWriteU8(u32 var, const u32 address,
|
std::optional<WriteResult>
|
||||||
|
HostTryWriteU8(u32 var, const u32 address,
|
||||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
TryWriteResult HostTryWriteU16(u32 var, const u32 address,
|
std::optional<WriteResult>
|
||||||
|
HostTryWriteU16(u32 var, const u32 address,
|
||||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
TryWriteResult HostTryWriteU32(u32 var, const u32 address,
|
std::optional<WriteResult>
|
||||||
|
HostTryWriteU32(u32 var, const u32 address,
|
||||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
TryWriteResult HostTryWriteU64(u64 var, const u32 address,
|
std::optional<WriteResult>
|
||||||
|
HostTryWriteU64(u64 var, const u32 address,
|
||||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
TryWriteResult HostTryWriteF32(float var, const u32 address,
|
std::optional<WriteResult>
|
||||||
|
HostTryWriteF32(float var, const u32 address,
|
||||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
TryWriteResult HostTryWriteF64(double var, const u32 address,
|
std::optional<WriteResult>
|
||||||
|
HostTryWriteF64(double var, const u32 address,
|
||||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||||
|
|
||||||
// Returns whether a read or write to the given address will resolve to a RAM access in the given
|
// Returns whether a read or write to the given address will resolve to a RAM access in the given
|
||||||
|
|
Loading…
Reference in New Issue