project64/Source/Project64/UserInterface/Debugger/DebugMMU.h

109 lines
2.6 KiB
C
Raw Normal View History

#pragma once
class CDebugMMU
{
public:
2022-09-26 02:31:54 +00:00
size_t ReadPhysical(uint32_t paddr, size_t length, uint8_t * buffer);
size_t ReadVirtual(uint32_t vaddr, size_t length, uint8_t * buffer);
size_t WritePhysical(uint32_t paddr, size_t length, uint8_t * buffer);
size_t WriteVirtual(uint32_t vaddr, size_t length, uint8_t * buffer);
2019-12-25 00:41:20 +00:00
2022-09-26 02:31:54 +00:00
template <typename T>
bool DebugLoad_PAddr(uint32_t paddr, T & value)
2019-12-25 00:41:20 +00:00
{
2022-09-26 02:31:54 +00:00
union
{
T word;
2019-12-25 00:41:20 +00:00
uint8_t bytes[sizeof(T)];
} buffer;
if (ReadPhysical(paddr, sizeof(buffer), buffer.bytes) == sizeof(buffer))
{
value = ByteSwap<T>(buffer.word);
return true;
}
return false;
}
2022-09-26 02:31:54 +00:00
template <typename T>
bool DebugLoad_VAddr(uint32_t vaddr, T & value)
2019-12-25 00:41:20 +00:00
{
2022-09-26 02:31:54 +00:00
union
{
T word;
2019-12-25 00:41:20 +00:00
uint8_t bytes[sizeof(T)];
} buffer;
if (ReadVirtual(vaddr, sizeof(buffer), buffer.bytes) == sizeof(buffer))
{
value = ByteSwap<T>(buffer.word);
return true;
}
return false;
}
2022-09-26 02:31:54 +00:00
template <typename T>
2019-12-25 00:41:20 +00:00
bool DebugStore_PAddr(uint32_t paddr, T value)
{
2022-09-26 02:31:54 +00:00
union
{
T word;
2019-12-25 00:41:20 +00:00
uint8_t bytes[sizeof(T)];
2022-09-26 02:31:54 +00:00
} buffer = {ByteSwap<T>(value)};
2019-12-25 00:41:20 +00:00
return (WritePhysical(paddr, sizeof(buffer), buffer.bytes) == sizeof(buffer));
}
2022-09-26 02:31:54 +00:00
template <typename T>
2019-12-25 00:41:20 +00:00
bool DebugStore_VAddr(uint32_t vaddr, T value)
{
2022-09-26 02:31:54 +00:00
union
{
T word;
2019-12-25 00:41:20 +00:00
uint8_t bytes[sizeof(T)];
2022-09-26 02:31:54 +00:00
} buffer = {ByteSwap<T>(value)};
2019-12-25 00:41:20 +00:00
return (WriteVirtual(vaddr, sizeof(buffer), buffer.bytes) == sizeof(buffer));
}
private:
2022-09-26 02:31:54 +00:00
uint8_t * GetPhysicalPtr(uint32_t paddr, WORD * flags = nullptr);
bool GetPhysicalByte(uint32_t paddr, uint8_t * value);
bool SetPhysicalByte(uint32_t paddr, uint8_t value);
2019-12-25 00:41:20 +00:00
2022-09-26 02:31:54 +00:00
template <typename T>
2019-12-25 00:41:20 +00:00
T ByteSwap(T value)
{
union
{
2022-09-26 02:31:54 +00:00
T value;
2019-12-25 00:41:20 +00:00
uint16_t u16;
uint32_t u32;
uint64_t u64;
} bytes;
bytes.value = value;
switch (sizeof(T))
{
2022-09-26 02:31:54 +00:00
case sizeof(uint8_t):
2019-12-25 00:41:20 +00:00
break;
2022-09-26 02:31:54 +00:00
case sizeof(uint16_t):
2019-12-25 00:41:20 +00:00
bytes.u16 = _byteswap_ushort(bytes.u16);
break;
2022-09-26 02:31:54 +00:00
case sizeof(uint32_t):
2019-12-25 00:41:20 +00:00
bytes.u32 = _byteswap_ulong(bytes.u32);
break;
2022-09-26 02:31:54 +00:00
case sizeof(uint64_t):
2019-12-25 00:41:20 +00:00
bytes.u64 = _byteswap_uint64(bytes.u64);
break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
}
return bytes.value;
}
};