// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team // SPDX-License-Identifier: GPL-3.0+ #include "MemoryInterface.h" template Value MemoryInterface::Read(u32 address, bool* valid) { if constexpr (std::is_same_v || std::is_same_v) return static_cast(Read8(address, valid)); else if constexpr (std::is_same_v || std::is_same_v) return static_cast(Read16(address, valid)); else if constexpr (std::is_same_v || std::is_same_v) return static_cast(Read32(address, valid)); else if constexpr (std::is_same_v || std::is_same_v) return static_cast(Read64(address, valid)); else if constexpr (std::is_same_v) return Read128(address, valid); else if constexpr (std::is_same_v) { u128 value = Read128(address, valid); return s128{ .lo = static_cast(value.lo), .hi = static_cast(value.hi), }; } else return Value(0); } template bool MemoryInterface::Write(u32 address, Value value) { if constexpr (std::is_same_v || std::is_same_v) return Write8(address, static_cast(value)); else if constexpr (std::is_same_v || std::is_same_v) return Write16(address, static_cast(value)); else if constexpr (std::is_same_v || std::is_same_v) return Write32(address, static_cast(value)); else if constexpr (std::is_same_v || std::is_same_v) return Write64(address, static_cast(value)); else if constexpr (std::is_same_v) return Write128(address, value); else if constexpr (std::is_same_v) { u128 unsigned_value; unsigned_value.lo = static_cast(value.lo); unsigned_value.hi = static_cast(value.hi); return Write128(address, unsigned_value); } else return false; } bool MemoryInterface::IdempotentWrite8(u32 address, u8 value) { bool valid; u8 existing_value = Read8(address, &valid); if (!valid || existing_value == value) return valid; return Write8(address, value); } bool MemoryInterface::IdempotentWrite16(u32 address, u16 value) { bool valid; u16 existing_value = Read16(address, &valid); if (!valid || existing_value == value) return valid; return Write16(address, value); } bool MemoryInterface::IdempotentWrite32(u32 address, u32 value) { bool valid; u32 existing_value = Read32(address, &valid); if (!valid || existing_value == value) return valid; return Write32(address, value); } bool MemoryInterface::IdempotentWrite64(u32 address, u64 value) { bool valid; u64 existing_value = Read64(address, &valid); if (!valid || existing_value == value) return valid; return Write64(address, value); } bool MemoryInterface::IdempotentWrite128(u32 address, u128 value) { bool valid; u128 existing_value = Read128(address, &valid); if (!valid || existing_value == value) return valid; return Write128(address, value); } bool MemoryInterface::IdempotentWriteBytes(u32 address, void* src, u32 size) { if (CompareBytes(address, src, size)) return true; return WriteBytes(address, src, size); } template bool MemoryInterface::IdempotentWrite(u32 address, Value value) { bool valid; Value existing_value = Read(address, &valid); if (!valid || existing_value == value) return valid; return Write(address, value); } #define EXPLICITLY_INSTANTIATE_TEMPLATES(type) \ template type MemoryInterface::Read(u32 addres, bool* valid); \ template bool MemoryInterface::Write(u32 address, type value); \ template bool MemoryInterface::IdempotentWrite(u32 address, type value); EXPLICITLY_INSTANTIATE_TEMPLATES(u8) EXPLICITLY_INSTANTIATE_TEMPLATES(s8) EXPLICITLY_INSTANTIATE_TEMPLATES(u16) EXPLICITLY_INSTANTIATE_TEMPLATES(s16) EXPLICITLY_INSTANTIATE_TEMPLATES(u32) EXPLICITLY_INSTANTIATE_TEMPLATES(s32) EXPLICITLY_INSTANTIATE_TEMPLATES(u64) EXPLICITLY_INSTANTIATE_TEMPLATES(s64) EXPLICITLY_INSTANTIATE_TEMPLATES(u128) EXPLICITLY_INSTANTIATE_TEMPLATES(s128) #undef EXPLICITLY_INSTANTIATE_TEMPLATES