Core/MMU: Add HostTryWrite*() functions.

This commit is contained in:
Admiral H. Curtiss 2021-02-27 16:07:41 +01:00
parent b59fcae70a
commit c292351faa
2 changed files with 91 additions and 0 deletions

View File

@ -721,6 +721,63 @@ void HostWrite_F64(const double var, const u32 address)
HostWrite_U64(integral, address);
}
template <typename T>
static TryWriteResult HostTryWriteUX(const T var, const u32 address, RequestedAddressSpace space)
{
if (!HostIsRAMAddress(address, space))
return TryWriteResult();
switch (space)
{
case RequestedAddressSpace::Effective:
WriteToHardware<XCheckTLBFlag::NoException, T>(address, var);
return TryWriteResult(!!MSR.DR);
case RequestedAddressSpace::Physical:
WriteToHardware<XCheckTLBFlag::NoException, T, true>(address, var);
return TryWriteResult(false);
case RequestedAddressSpace::Virtual:
if (!MSR.DR)
return TryWriteResult();
WriteToHardware<XCheckTLBFlag::NoException, T>(address, var);
return TryWriteResult(true);
}
assert(0);
return TryWriteResult();
}
TryWriteResult HostTryWriteU8(const u8 var, const u32 address, RequestedAddressSpace space)
{
return HostTryWriteUX<u8>(var, address, space);
}
TryWriteResult HostTryWriteU16(const u16 var, const u32 address, RequestedAddressSpace space)
{
return HostTryWriteUX<u16>(var, address, space);
}
TryWriteResult HostTryWriteU32(const u32 var, const u32 address, RequestedAddressSpace space)
{
return HostTryWriteUX<u32>(var, address, space);
}
TryWriteResult HostTryWriteU64(const u64 var, const u32 address, RequestedAddressSpace space)
{
return HostTryWriteUX<u64>(var, address, space);
}
TryWriteResult HostTryWriteF32(const float var, const u32 address, RequestedAddressSpace space)
{
const u32 integral = Common::BitCast<u32>(var);
return HostTryWriteU32(integral, address, space);
}
TryWriteResult HostTryWriteF64(const double var, const u32 address, RequestedAddressSpace space)
{
const u64 integral = Common::BitCast<u64>(var);
return HostTryWriteU64(integral, address, space);
}
std::string HostGetString(u32 address, size_t size)
{
std::string s;

View File

@ -83,6 +83,9 @@ TryReadResult<std::string>
HostTryReadString(u32 address, size_t size = 0,
RequestedAddressSpace space = RequestedAddressSpace::Effective);
// Writes a value to emulated memory using the currently active MMU settings.
// If the write fails (eg. address does not correspond to a mapped address in the current address
// space), a PanicAlert will be shown to the user.
void HostWrite_U8(u8 var, u32 address);
void HostWrite_U16(u16 var, u32 address);
void HostWrite_U32(u32 var, u32 address);
@ -90,6 +93,37 @@ void HostWrite_U64(u64 var, u32 address);
void HostWrite_F32(float var, u32 address);
void HostWrite_F64(double var, u32 address);
struct TryWriteResult
{
// 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
// address was treated as physical)
bool translated;
TryWriteResult() : success(false) {}
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.
// 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
// user-visible alert on failure.
TryWriteResult HostTryWriteU8(u8 var, const u32 address,
RequestedAddressSpace space = RequestedAddressSpace::Effective);
TryWriteResult HostTryWriteU16(u16 var, const u32 address,
RequestedAddressSpace space = RequestedAddressSpace::Effective);
TryWriteResult HostTryWriteU32(u32 var, const u32 address,
RequestedAddressSpace space = RequestedAddressSpace::Effective);
TryWriteResult HostTryWriteU64(u64 var, const u32 address,
RequestedAddressSpace space = RequestedAddressSpace::Effective);
TryWriteResult HostTryWriteF32(float var, const u32 address,
RequestedAddressSpace space = RequestedAddressSpace::Effective);
TryWriteResult HostTryWriteF64(double var, const u32 address,
RequestedAddressSpace space = RequestedAddressSpace::Effective);
// Returns whether a read or write to the given address will resolve to a RAM access in the given
// address space.
bool HostIsRAMAddress(u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective);