mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-07-11 01:34:17 +02:00
Patch: Add unit tests
This commit is contained in:
Vendored
+8
-27
@@ -1,38 +1,19 @@
|
||||
# We need to use a custom CMakeLists for GoogleTest, because we can't compile with exceptions on.
|
||||
|
||||
add_library(gtest
|
||||
googletest/src/gtest.cc
|
||||
googletest/src/gtest-assertion-result.cc
|
||||
googletest/src/gtest-death-test.cc
|
||||
googletest/src/gtest-filepath.cc
|
||||
googletest/src/gtest-matchers.cc
|
||||
googletest/src/gtest-port.cc
|
||||
googletest/src/gtest-printers.cc
|
||||
googletest/src/gtest-test-part.cc
|
||||
googletest/src/gtest-typed-test.cc
|
||||
googletest/src/gtest-all.cc
|
||||
googlemock/src/gmock-all.cc
|
||||
googlemock/src/gmock_main.cc
|
||||
)
|
||||
target_include_directories(gtest PUBLIC
|
||||
googletest/include
|
||||
googlemock/include
|
||||
)
|
||||
target_include_directories(gtest PRIVATE
|
||||
googletest
|
||||
googletest/include
|
||||
)
|
||||
target_include_directories(gtest INTERFACE
|
||||
googletest/include
|
||||
googlemock
|
||||
)
|
||||
target_link_libraries(gtest Threads::Threads)
|
||||
set_property(TARGET gtest PROPERTY CXX_STANDARD 17)
|
||||
set_property(TARGET gtest PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
add_library(gtest_main
|
||||
googletest/src/gtest_main.cc
|
||||
)
|
||||
target_include_directories(gtest_main PRIVATE
|
||||
googletest
|
||||
googletest/include
|
||||
)
|
||||
target_include_directories(gtest_main INTERFACE
|
||||
googletest/include
|
||||
)
|
||||
target_link_libraries(gtest_main Threads::Threads)
|
||||
set_property(TARGET gtest_main PROPERTY CXX_STANDARD 17)
|
||||
set_property(TARGET gtest_main PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
|
||||
+32
-80
@@ -7,7 +7,6 @@
|
||||
#include "common/ByteSwap.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/Path.h"
|
||||
#include "common/SmallString.h"
|
||||
#include "common/StringUtil.h"
|
||||
#include "common/ZipHelpers.h"
|
||||
|
||||
@@ -33,30 +32,6 @@
|
||||
|
||||
namespace Patch
|
||||
{
|
||||
enum patch_cpu_type : u8
|
||||
{
|
||||
CPU_EE,
|
||||
CPU_IOP
|
||||
};
|
||||
|
||||
enum patch_data_type : u8
|
||||
{
|
||||
BYTE_T,
|
||||
SHORT_T,
|
||||
WORD_T,
|
||||
DOUBLE_T,
|
||||
EXTENDED_T,
|
||||
SHORT_BE_T,
|
||||
WORD_BE_T,
|
||||
DOUBLE_BE_T,
|
||||
BYTES_T
|
||||
};
|
||||
|
||||
static constexpr std::array<const char*, 4> s_place_to_string = {{"0", "1", "2", "3"}};
|
||||
static constexpr std::array<const char*, 2> s_cpu_to_string = {{"EE", "IOP"}};
|
||||
static constexpr std::array<const char*, 9> s_type_to_string = {
|
||||
{"byte", "short", "word", "double", "extended", "beshort", "beword", "bedouble", "bytes"}};
|
||||
|
||||
template <typename EnumType, class ArrayType>
|
||||
static inline std::optional<EnumType> LookupEnumName(const std::string_view val, const ArrayType& arr)
|
||||
{
|
||||
@@ -68,48 +43,6 @@ namespace Patch
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
struct PatchCommand
|
||||
{
|
||||
patch_place_type placetopatch;
|
||||
patch_cpu_type cpu;
|
||||
patch_data_type type;
|
||||
u32 addr;
|
||||
u64 data;
|
||||
u8* data_ptr;
|
||||
|
||||
// needed because of the pointer
|
||||
PatchCommand() { std::memset(static_cast<void*>(this), 0, sizeof(*this)); }
|
||||
PatchCommand(const PatchCommand& p) = delete;
|
||||
PatchCommand(PatchCommand&& p)
|
||||
{
|
||||
std::memcpy(static_cast<void*>(this), &p, sizeof(*this));
|
||||
p.data_ptr = nullptr;
|
||||
}
|
||||
~PatchCommand()
|
||||
{
|
||||
if (data_ptr)
|
||||
std::free(data_ptr);
|
||||
}
|
||||
|
||||
PatchCommand& operator=(const PatchCommand& p) = delete;
|
||||
PatchCommand& operator=(PatchCommand&& p)
|
||||
{
|
||||
std::memcpy(static_cast<void*>(this), &p, sizeof(*this));
|
||||
p.data_ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const PatchCommand& p) const { return std::memcmp(this, &p, sizeof(*this)) == 0; }
|
||||
bool operator!=(const PatchCommand& p) const { return std::memcmp(this, &p, sizeof(*this)) != 0; }
|
||||
|
||||
SmallString ToString() const
|
||||
{
|
||||
return SmallString::from_format("{},{},{},{:08x},{:x}", s_place_to_string[static_cast<u8>(placetopatch)],
|
||||
s_cpu_to_string[static_cast<u8>(cpu)], s_type_to_string[static_cast<u8>(type)], addr, data);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(PatchCommand) == 24, "IniPatch has no padding");
|
||||
|
||||
struct PatchGroup
|
||||
{
|
||||
std::string name;
|
||||
@@ -157,7 +90,9 @@ namespace Patch
|
||||
static u32 EnablePatches(const std::vector<PatchGroup>* patches, const std::vector<std::string>& enable_list, const std::vector<std::string>* enable_immediately_list);
|
||||
|
||||
template <typename EEMemory, typename IOPMemory>
|
||||
static void ApplyPatch(const PatchCommand* p, EEMemory& ee, IOPMemory& iop);
|
||||
requires std::is_base_of_v<MemoryInterface, EEMemory> &&
|
||||
std::is_base_of_v<MemoryInterface, IOPMemory>
|
||||
void ApplyPatch(const PatchCommand* p, EEMemory& ee, IOPMemory& iop);
|
||||
static void ApplyDynaPatch(const DynamicPatch& patch, u32 address);
|
||||
template <typename Memory>
|
||||
requires std::is_base_of_v<MemoryInterface, Memory>
|
||||
@@ -1149,26 +1084,41 @@ void Patch::PatchFunc::dpatch(PatchGroup* group, const std::string_view cmd, con
|
||||
|
||||
void Patch::ApplyBootPatches()
|
||||
{
|
||||
ApplyLoadedPatches(PPT_ONCE_ON_LOAD);
|
||||
ApplyLoadedPatches(PPT_COMBINED_0_1);
|
||||
ApplyLoadedPatches(PPT_ON_LOAD_OR_WHEN_ENABLED);
|
||||
EEMemoryInterface ee;
|
||||
IOPMemoryInterface iop;
|
||||
ApplyPatches(s_active_patches, PPT_ONCE_ON_LOAD, ee, iop);
|
||||
ApplyPatches(s_active_patches, PPT_COMBINED_0_1, ee, iop);
|
||||
ApplyPatches(s_active_patches, PPT_ON_LOAD_OR_WHEN_ENABLED, ee, iop);
|
||||
}
|
||||
|
||||
void Patch::ApplyVsyncPatches()
|
||||
{
|
||||
ApplyLoadedPatches(PPT_CONTINUOUSLY);
|
||||
ApplyLoadedPatches(PPT_COMBINED_0_1);
|
||||
}
|
||||
|
||||
void Patch::ApplyLoadedPatches(patch_place_type place)
|
||||
{
|
||||
EEMemoryInterface ee;
|
||||
IOPMemoryInterface iop;
|
||||
for (const PatchCommand* i : s_active_patches)
|
||||
{
|
||||
ApplyPatches(s_active_patches, PPT_CONTINUOUSLY, ee, iop);
|
||||
ApplyPatches(s_active_patches, PPT_COMBINED_0_1, ee, iop);
|
||||
}
|
||||
|
||||
void Patch::ApplyPatches(
|
||||
const std::vector<const PatchCommand*>& patches,
|
||||
patch_place_type place,
|
||||
EEMemoryInterface& ee,
|
||||
IOPMemoryInterface& iop)
|
||||
{
|
||||
for (const PatchCommand* i : patches)
|
||||
if (i->placetopatch == place)
|
||||
ApplyPatch(i, ee, iop);
|
||||
}
|
||||
|
||||
void Patch::ApplyPatches(
|
||||
const std::vector<const PatchCommand*>& patches,
|
||||
patch_place_type place,
|
||||
MemoryInterface& ee,
|
||||
MemoryInterface& iop)
|
||||
{
|
||||
for (const PatchCommand* i : patches)
|
||||
if (i->placetopatch == place)
|
||||
ApplyPatch(i, ee, iop);
|
||||
}
|
||||
}
|
||||
|
||||
u32 Patch::GetActiveGameDBPatchesCount()
|
||||
@@ -1703,6 +1653,8 @@ void Patch::handle_extended_t(const PatchCommand* p, Memory& memory)
|
||||
}
|
||||
|
||||
template <typename EEMemory, typename IOPMemory>
|
||||
requires std::is_base_of_v<MemoryInterface, EEMemory> &&
|
||||
std::is_base_of_v<MemoryInterface, IOPMemory>
|
||||
void Patch::ApplyPatch(const PatchCommand* p, EEMemory& ee, IOPMemory& iop)
|
||||
{
|
||||
u64 ledata = 0;
|
||||
|
||||
+98
-23
@@ -18,11 +18,15 @@
|
||||
#include "Config.h"
|
||||
|
||||
#include "common/MemoryInterface.h"
|
||||
#include "common/SmallString.h"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
class EEMemoryInterface;
|
||||
class IOPMemoryInterface;
|
||||
|
||||
namespace Patch
|
||||
{
|
||||
// "place" is the first number at a pnach line (patch=<place>,...), e.g.:
|
||||
@@ -51,6 +55,84 @@ namespace Patch
|
||||
PPT_END_MARKER
|
||||
};
|
||||
|
||||
enum patch_cpu_type : u8
|
||||
{
|
||||
CPU_EE,
|
||||
CPU_IOP
|
||||
};
|
||||
|
||||
enum patch_data_type : u8
|
||||
{
|
||||
BYTE_T,
|
||||
SHORT_T,
|
||||
WORD_T,
|
||||
DOUBLE_T,
|
||||
EXTENDED_T,
|
||||
SHORT_BE_T,
|
||||
WORD_BE_T,
|
||||
DOUBLE_BE_T,
|
||||
BYTES_T
|
||||
};
|
||||
|
||||
static constexpr std::array<const char*, 4> s_place_to_string = {{"0", "1", "2", "3"}};
|
||||
static constexpr std::array<const char*, 2> s_cpu_to_string = {{"EE", "IOP"}};
|
||||
static constexpr std::array<const char*, 9> s_type_to_string = {
|
||||
{"byte", "short", "word", "double", "extended", "beshort", "beword", "bedouble", "bytes"}};
|
||||
|
||||
struct PatchCommand
|
||||
{
|
||||
patch_place_type placetopatch;
|
||||
patch_cpu_type cpu;
|
||||
patch_data_type type;
|
||||
u32 addr;
|
||||
u64 data;
|
||||
u8* data_ptr;
|
||||
|
||||
// needed because of the pointer
|
||||
PatchCommand() { std::memset(static_cast<void*>(this), 0, sizeof(*this)); }
|
||||
PatchCommand(const PatchCommand& p) = delete;
|
||||
PatchCommand(PatchCommand&& p)
|
||||
{
|
||||
std::memcpy(static_cast<void*>(this), &p, sizeof(*this));
|
||||
p.data_ptr = nullptr;
|
||||
}
|
||||
~PatchCommand()
|
||||
{
|
||||
if (data_ptr)
|
||||
std::free(data_ptr);
|
||||
}
|
||||
|
||||
PatchCommand& operator=(const PatchCommand& p) = delete;
|
||||
PatchCommand& operator=(PatchCommand&& p)
|
||||
{
|
||||
std::memcpy(static_cast<void*>(this), &p, sizeof(*this));
|
||||
p.data_ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const PatchCommand& p) const { return std::memcmp(this, &p, sizeof(*this)) == 0; }
|
||||
bool operator!=(const PatchCommand& p) const { return std::memcmp(this, &p, sizeof(*this)) != 0; }
|
||||
|
||||
SmallString ToString() const
|
||||
{
|
||||
return SmallString::from_format("{},{},{},{:08x},{:x}", s_place_to_string[static_cast<u8>(placetopatch)],
|
||||
s_cpu_to_string[static_cast<u8>(cpu)], s_type_to_string[static_cast<u8>(type)], addr, data);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(PatchCommand) == 24, "PatchCommand has extra padding");
|
||||
|
||||
struct DynamicPatchEntry
|
||||
{
|
||||
u32 offset;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
struct DynamicPatch
|
||||
{
|
||||
std::vector<DynamicPatchEntry> pattern;
|
||||
std::vector<DynamicPatchEntry> replacement;
|
||||
};
|
||||
|
||||
struct PatchInfo
|
||||
{
|
||||
std::string name;
|
||||
@@ -65,18 +147,6 @@ namespace Patch
|
||||
std::string_view GetNameParentPart() const;
|
||||
};
|
||||
|
||||
struct DynamicPatchEntry
|
||||
{
|
||||
u32 offset;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
struct DynamicPatch
|
||||
{
|
||||
std::vector<DynamicPatchEntry> pattern;
|
||||
std::vector<DynamicPatchEntry> replacement;
|
||||
};
|
||||
|
||||
// Config sections/keys to use to enable patches.
|
||||
extern const char* PATCHES_CONFIG_SECTION;
|
||||
extern const char* CHEATS_CONFIG_SECTION;
|
||||
@@ -96,24 +166,29 @@ namespace Patch
|
||||
extern bool ReloadPatchAffectingOptions();
|
||||
extern void UnloadPatches();
|
||||
|
||||
// Functions for Dynamic EE patching.
|
||||
/// Functions for Dynamic EE patching.
|
||||
extern void LoadDynamicPatches(const std::vector<DynamicPatch>& patches);
|
||||
extern void ApplyDynamicPatches(u32 pc);
|
||||
|
||||
// Apply all loaded patches that should be applied when the entry point is
|
||||
// being recompiled.
|
||||
/// Apply all loaded patches that should be applied when the entry point is
|
||||
/// being recompiled.
|
||||
extern void ApplyBootPatches();
|
||||
|
||||
// Apply all loaded patches that should be applied during vsync.
|
||||
/// Apply all loaded patches that should be applied during vsync.
|
||||
extern void ApplyVsyncPatches();
|
||||
|
||||
// Patches the emulation memory by applying all the loaded patches with a specific place value.
|
||||
// Note: unless you know better, there's no need to check whether or not different patch sources
|
||||
// are enabled (e.g. ws patches, auto game fixes, etc) before calling ApplyLoadedPatches,
|
||||
// because on boot or on any configuration change --> all the loaded patches are invalidated,
|
||||
// and then it loads only the ones which are enabled according to the current config
|
||||
// (this happens at AppCoreThread::ApplySettings(...) )
|
||||
extern void ApplyLoadedPatches(patch_place_type place);
|
||||
/// Apply the patches from the provided list which have place values that
|
||||
/// match the one specified.
|
||||
extern void ApplyPatches(
|
||||
const std::vector<const PatchCommand*>& patches,
|
||||
patch_place_type place,
|
||||
EEMemoryInterface& ee,
|
||||
IOPMemoryInterface& iop);
|
||||
extern void ApplyPatches(
|
||||
const std::vector<const PatchCommand*>& patches,
|
||||
patch_place_type place,
|
||||
MemoryInterface& ee,
|
||||
MemoryInterface& iop);
|
||||
|
||||
// Get the total counts of the active game patches.
|
||||
extern u32 GetActiveGameDBPatchesCount();
|
||||
|
||||
@@ -4,7 +4,7 @@ add_custom_command(TARGET unittests POST_BUILD COMMAND ${CMAKE_CTEST_COMMAND} --
|
||||
|
||||
macro(add_pcsx2_test target)
|
||||
add_executable(${target} EXCLUDE_FROM_ALL ${ARGN})
|
||||
target_link_libraries(${target} PRIVATE gtest gtest_main)
|
||||
target_link_libraries(${target} PRIVATE gtest)
|
||||
if(APPLE)
|
||||
# For some reason this doesn't get pulled in implicitly...
|
||||
target_link_libraries(${target} PRIVATE
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
add_pcsx2_test(core_test
|
||||
patch_tests.cpp
|
||||
MockMemoryInterface.h
|
||||
StubHost.cpp
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "common/MemoryInterface.h"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
class MockMemoryInterface : public MemoryInterface
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD(u8, Read8, (u32 address, bool* valid), (override));
|
||||
MOCK_METHOD(u16, Read16, (u32 address, bool* valid), (override));
|
||||
MOCK_METHOD(u32, Read32, (u32 address, bool* valid), (override));
|
||||
MOCK_METHOD(u64, Read64, (u32 address, bool* valid), (override));
|
||||
MOCK_METHOD(u128, Read128, (u32 address, bool* valid), (override));
|
||||
MOCK_METHOD(bool, ReadBytes, (u32 address, void* dest, u32 size), (override));
|
||||
|
||||
MOCK_METHOD(bool, Write8, (u32 address, u8 value), (override));
|
||||
MOCK_METHOD(bool, Write16, (u32 address, u16 value), (override));
|
||||
MOCK_METHOD(bool, Write32, (u32 address, u32 value), (override));
|
||||
MOCK_METHOD(bool, Write64, (u32 address, u64 value), (override));
|
||||
MOCK_METHOD(bool, Write128, (u32 address, u128 value), (override));
|
||||
MOCK_METHOD(bool, WriteBytes, (u32 address, void* src, u32 size), (override));
|
||||
|
||||
MOCK_METHOD(bool, CompareBytes, (u32 address, void* src, u32 size), (override));
|
||||
|
||||
struct SetValidOutParameterAction
|
||||
{
|
||||
template <typename... Args>
|
||||
void operator()(const Args&... args) const
|
||||
{
|
||||
if (std::get<1>(std::tie(args...)))
|
||||
*std::get<1>(std::tie(args...)) = true;
|
||||
}
|
||||
};
|
||||
|
||||
#define DEFINE_EXPECT_CALL_FUNCTIONS(size) \
|
||||
void ExpectRead##size(u32 address, u##size return_value) \
|
||||
{ \
|
||||
auto actions = testing::DoAll(SetValidOutParameterAction{}, testing::Return(return_value)); \
|
||||
EXPECT_CALL(*this, Read##size(address, testing::_)).Times(1).WillOnce(std::move(actions)); \
|
||||
} \
|
||||
void ExpectWrite##size(u32 address, u##size expected_value) \
|
||||
{ \
|
||||
EXPECT_CALL(*this, Write##size(address, expected_value)).Times(1).WillOnce(testing::Return(true)); \
|
||||
} \
|
||||
void ExpectIdempotentWrite##size(u32 address, u##size old_value, u##size new_value) \
|
||||
{ \
|
||||
ExpectRead##size(address, old_value); \
|
||||
if (old_value != new_value) \
|
||||
ExpectWrite##size(address, new_value); \
|
||||
}
|
||||
DEFINE_EXPECT_CALL_FUNCTIONS(8)
|
||||
DEFINE_EXPECT_CALL_FUNCTIONS(16)
|
||||
DEFINE_EXPECT_CALL_FUNCTIONS(32)
|
||||
DEFINE_EXPECT_CALL_FUNCTIONS(64)
|
||||
DEFINE_EXPECT_CALL_FUNCTIONS(128)
|
||||
#undef DEFINE_EXPECT_CALL_FUNCTIONS
|
||||
};
|
||||
@@ -0,0 +1,522 @@
|
||||
// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "Patch.h"
|
||||
|
||||
#include "MockMemoryInterface.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// Create a test that makes sure applying a given list of patch commands results
|
||||
// in a certain sequence of memory reads/writes.
|
||||
#define PATCH_TEST(name, ...) \
|
||||
static void patch_test_setup_expected_calls_##name(MockMemoryInterface& ee, MockMemoryInterface& iop); \
|
||||
TEST(Patch, name) \
|
||||
{ \
|
||||
testing::StrictMock<MockMemoryInterface> ee; \
|
||||
testing::StrictMock<MockMemoryInterface> iop; \
|
||||
{ \
|
||||
testing::InSequence seq; \
|
||||
patch_test_setup_expected_calls_##name(ee, iop); \
|
||||
} \
|
||||
Patch::PatchCommand commands[]{__VA_ARGS__}; \
|
||||
std::vector<const Patch::PatchCommand*> pointers; \
|
||||
pointers.reserve(std::size(commands)); \
|
||||
for (Patch::PatchCommand& command : commands) \
|
||||
pointers.push_back(&command); \
|
||||
Patch::ApplyPatches(pointers, Patch::PPT_ONCE_ON_LOAD, ee, iop); \
|
||||
Patch::ApplyPatches(pointers, Patch::PPT_CONTINUOUSLY, ee, iop); \
|
||||
Patch::ApplyPatches(pointers, Patch::PPT_COMBINED_0_1, ee, iop); \
|
||||
Patch::ApplyPatches(pointers, Patch::PPT_ON_LOAD_OR_WHEN_ENABLED, ee, iop); \
|
||||
} \
|
||||
static void patch_test_setup_expected_calls_##name(MockMemoryInterface& ee, MockMemoryInterface& iop)
|
||||
|
||||
static Patch::PatchCommand BuildPatchCommand(
|
||||
Patch::patch_place_type place,
|
||||
Patch::patch_cpu_type cpu,
|
||||
u32 address,
|
||||
Patch::patch_data_type type,
|
||||
u64 data)
|
||||
{
|
||||
Patch::PatchCommand command;
|
||||
command.placetopatch = place;
|
||||
command.cpu = cpu;
|
||||
command.addr = address;
|
||||
command.type = type;
|
||||
command.data = data;
|
||||
return command;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// Writes
|
||||
// *****************************************************************************
|
||||
|
||||
PATCH_TEST(Byte,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00100000, Patch::BYTE_T, 0x12))
|
||||
{
|
||||
ee.ExpectIdempotentWrite8(0x00100000, 0, 0x12);
|
||||
}
|
||||
|
||||
PATCH_TEST(Short,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00100000, Patch::SHORT_T, 0x1234))
|
||||
{
|
||||
ee.ExpectIdempotentWrite16(0x00100000, 0, 0x1234);
|
||||
}
|
||||
|
||||
PATCH_TEST(Word,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00100000, Patch::WORD_T, 0x12345678))
|
||||
{
|
||||
ee.ExpectIdempotentWrite32(0x00100000, 0, 0x12345678);
|
||||
}
|
||||
|
||||
PATCH_TEST(Double,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00100000, Patch::DOUBLE_T, 0x123456789acdef12))
|
||||
{
|
||||
ee.ExpectIdempotentWrite64(0x00100000, 0, 0x123456789acdef12);
|
||||
}
|
||||
|
||||
PATCH_TEST(BigEndianShort,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00100000, Patch::SHORT_BE_T, 0x1234))
|
||||
{
|
||||
ee.ExpectIdempotentWrite16(0x00100000, 0, 0x3412);
|
||||
}
|
||||
|
||||
PATCH_TEST(BigEndianWord,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00100000, Patch::WORD_BE_T, 0x12345678))
|
||||
{
|
||||
ee.ExpectIdempotentWrite32(0x00100000, 0, 0x78563412);
|
||||
}
|
||||
|
||||
PATCH_TEST(BigEndianDouble,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00100000, Patch::DOUBLE_BE_T, 0xabcdef0123456789))
|
||||
{
|
||||
ee.ExpectIdempotentWrite64(0x00100000, 0, 0x8967452301efcdab);
|
||||
}
|
||||
|
||||
PATCH_TEST(IOPByte,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_IOP, 0x00100000, Patch::BYTE_T, 0x12))
|
||||
{
|
||||
iop.ExpectIdempotentWrite8(0x00100000, 0, 0x12);
|
||||
}
|
||||
|
||||
PATCH_TEST(IOPShort,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_IOP, 0x00100000, Patch::SHORT_T, 0x1234))
|
||||
{
|
||||
iop.ExpectIdempotentWrite16(0x00100000, 0, 0x1234);
|
||||
}
|
||||
|
||||
PATCH_TEST(IOPWord,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_IOP, 0x00100000, Patch::WORD_T, 0x12345678))
|
||||
{
|
||||
iop.ExpectIdempotentWrite32(0x00100000, 0, 0x12345678);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// Writes (Extended)
|
||||
// *****************************************************************************
|
||||
|
||||
PATCH_TEST(Extended8BitWrite,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00100000, Patch::EXTENDED_T, 0x00000012))
|
||||
{
|
||||
ee.ExpectWrite8(0x00100000, 0x12);
|
||||
}
|
||||
|
||||
PATCH_TEST(Extended16BitWrite,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x10100000, Patch::EXTENDED_T, 0x00001234))
|
||||
{
|
||||
ee.ExpectWrite16(0x00100000, 0x1234);
|
||||
}
|
||||
|
||||
PATCH_TEST(Extended32BitWrite,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x20100000, Patch::EXTENDED_T, 0x12345678))
|
||||
{
|
||||
ee.ExpectWrite32(0x00100000, 0x12345678);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// Increments/Decrements (Extended)
|
||||
// *****************************************************************************
|
||||
|
||||
PATCH_TEST(Extended8BitIncrement,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30000012, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30000012, Patch::EXTENDED_T, 0x00100000))
|
||||
{
|
||||
ee.ExpectRead8(0x00100000, 0x00);
|
||||
ee.ExpectWrite8(0x00100000, 0x12);
|
||||
ee.ExpectRead8(0x00100000, 0x12);
|
||||
ee.ExpectWrite8(0x00100000, 0x24);
|
||||
}
|
||||
|
||||
PATCH_TEST(Extended8BitIncrementWrapping,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30000012, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30000012, Patch::EXTENDED_T, 0x00100000))
|
||||
{
|
||||
ee.ExpectRead8(0x00100000, 0xee);
|
||||
ee.ExpectWrite8(0x00100000, 0x00);
|
||||
ee.ExpectRead8(0x00100000, 0x00);
|
||||
ee.ExpectWrite8(0x00100000, 0x12);
|
||||
}
|
||||
|
||||
PATCH_TEST(Extended8BitDecrement,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30100012, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30100012, Patch::EXTENDED_T, 0x00100000))
|
||||
{
|
||||
ee.ExpectRead8(0x00100000, 0x24);
|
||||
ee.ExpectWrite8(0x00100000, 0x12);
|
||||
ee.ExpectRead8(0x00100000, 0x12);
|
||||
ee.ExpectWrite8(0x00100000, 0x00);
|
||||
}
|
||||
|
||||
PATCH_TEST(Extended8BitDecrementWrapping,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30100012, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30100012, Patch::EXTENDED_T, 0x00100000))
|
||||
{
|
||||
ee.ExpectRead8(0x00100000, 0x12);
|
||||
ee.ExpectWrite8(0x00100000, 0x00);
|
||||
ee.ExpectRead8(0x00100000, 0x00);
|
||||
ee.ExpectWrite8(0x00100000, 0xee);
|
||||
}
|
||||
|
||||
PATCH_TEST(Extended16BitIncrement,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30201234, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30201234, Patch::EXTENDED_T, 0x00100000))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x0000);
|
||||
ee.ExpectWrite16(0x00100000, 0x1234);
|
||||
ee.ExpectRead16(0x00100000, 0x1234);
|
||||
ee.ExpectWrite16(0x00100000, 0x2468);
|
||||
}
|
||||
|
||||
PATCH_TEST(Extended16BitIncrementWrapping,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30201234, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30201234, Patch::EXTENDED_T, 0x00100000))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0xedcc);
|
||||
ee.ExpectWrite16(0x00100000, 0x0000);
|
||||
ee.ExpectRead16(0x00100000, 0x0000);
|
||||
ee.ExpectWrite16(0x00100000, 0x1234);
|
||||
}
|
||||
|
||||
PATCH_TEST(Extended16BitDecrement,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30301234, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30301234, Patch::EXTENDED_T, 0x00100000))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x2468);
|
||||
ee.ExpectWrite16(0x00100000, 0x1234);
|
||||
ee.ExpectRead16(0x00100000, 0x1234);
|
||||
ee.ExpectWrite16(0x00100000, 0x0000);
|
||||
}
|
||||
|
||||
PATCH_TEST(Extended16BitDecrementWrapping,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30301234, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30301234, Patch::EXTENDED_T, 0x00100000))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x1234);
|
||||
ee.ExpectWrite16(0x00100000, 0x0000);
|
||||
ee.ExpectRead16(0x00100000, 0x0000);
|
||||
ee.ExpectWrite16(0x00100000, 0xedcc);
|
||||
}
|
||||
|
||||
PATCH_TEST(Extended32BitIncrement,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30400000, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x12345678, Patch::EXTENDED_T, 0x00000000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30400000, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x12345678, Patch::EXTENDED_T, 0x00000000))
|
||||
{
|
||||
ee.ExpectRead32(0x00100000, 0x00000000);
|
||||
ee.ExpectWrite32(0x00100000, 0x12345678);
|
||||
ee.ExpectRead32(0x00100000, 0x12345678);
|
||||
ee.ExpectWrite32(0x00100000, 0x2468acf0);
|
||||
}
|
||||
|
||||
PATCH_TEST(Extended32BitIncrementWrapping,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30400000, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x12345678, Patch::EXTENDED_T, 0x00000000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30400000, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x12345678, Patch::EXTENDED_T, 0x00000000))
|
||||
{
|
||||
ee.ExpectRead32(0x00100000, 0xedcba988);
|
||||
ee.ExpectWrite32(0x00100000, 0x00000000);
|
||||
ee.ExpectRead32(0x00100000, 0x00000000);
|
||||
ee.ExpectWrite32(0x00100000, 0x12345678);
|
||||
}
|
||||
|
||||
PATCH_TEST(Extended32BitDecrement,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30500000, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x12345678, Patch::EXTENDED_T, 0x00000000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30500000, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x12345678, Patch::EXTENDED_T, 0x00000000))
|
||||
{
|
||||
ee.ExpectRead32(0x00100000, 0x2468acf0);
|
||||
ee.ExpectWrite32(0x00100000, 0x12345678);
|
||||
ee.ExpectRead32(0x00100000, 0x12345678);
|
||||
ee.ExpectWrite32(0x00100000, 0x00000000);
|
||||
}
|
||||
|
||||
PATCH_TEST(Extended32BitDecrementWrapping,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30500000, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x12345678, Patch::EXTENDED_T, 0x00000000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x30500000, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x12345678, Patch::EXTENDED_T, 0x00000000))
|
||||
{
|
||||
ee.ExpectRead32(0x00100000, 0x12345678);
|
||||
ee.ExpectWrite32(0x00100000, 0x00000000);
|
||||
ee.ExpectRead32(0x00100000, 0x00000000);
|
||||
ee.ExpectWrite32(0x00100000, 0xedcba988);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// Serial Write (Extended)
|
||||
// *****************************************************************************
|
||||
|
||||
PATCH_TEST(ExtendedSerialWriteZero,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x40100000, Patch::EXTENDED_T, 0x00000000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00000000, Patch::EXTENDED_T, 0x00000000))
|
||||
{
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedSerialWriteOnce,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x40100000, Patch::EXTENDED_T, 0x00010000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x12345678, Patch::EXTENDED_T, 0x11111111))
|
||||
{
|
||||
ee.ExpectWrite32(0x00100000, 0x12345678);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedSerialWriteContiguous,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x40100000, Patch::EXTENDED_T, 0x00020001),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x12345678, Patch::EXTENDED_T, 0x11111111))
|
||||
{
|
||||
ee.ExpectWrite32(0x00100000, 0x12345678);
|
||||
ee.ExpectWrite32(0x00100004, 0x23456789);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedSerialWriteStrided,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x40100000, Patch::EXTENDED_T, 0x00020002),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x12345678, Patch::EXTENDED_T, 0x11111111))
|
||||
{
|
||||
ee.ExpectWrite32(0x00100000, 0x12345678);
|
||||
ee.ExpectWrite32(0x00100008, 0x23456789);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// Copy bytes (Extended)
|
||||
// *****************************************************************************
|
||||
|
||||
PATCH_TEST(ExtendedCopyBytes0,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x50100000, Patch::EXTENDED_T, 0x00000000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00200000, Patch::EXTENDED_T, 0x00000000))
|
||||
{
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedCopyBytes2,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x50100000, Patch::EXTENDED_T, 0x00000002),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00200000, Patch::EXTENDED_T, 0x00000000))
|
||||
{
|
||||
ee.ExpectRead8(0x00100000, 0x12);
|
||||
ee.ExpectWrite8(0x00200000, 0x12);
|
||||
ee.ExpectRead8(0x00100001, 0x12);
|
||||
ee.ExpectWrite8(0x00200001, 0x12);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// Pointer write (Extended)
|
||||
// *****************************************************************************
|
||||
|
||||
PATCH_TEST(ExtendedPointerWrite8,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x60100000, Patch::EXTENDED_T, 0x00000012),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00000001, Patch::EXTENDED_T, 0x00000004))
|
||||
{
|
||||
ee.ExpectRead32(0x00100000, 0x00200000);
|
||||
ee.ExpectWrite8(0x00200004, 0x12);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedPointerWrite16,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x60100000, Patch::EXTENDED_T, 0x00001234),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00010001, Patch::EXTENDED_T, 0x00000004))
|
||||
{
|
||||
ee.ExpectRead32(0x00100000, 0x00200000);
|
||||
ee.ExpectWrite16(0x00200004, 0x1234);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedPointerWrite32,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x60100000, Patch::EXTENDED_T, 0x12345678),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00020001, Patch::EXTENDED_T, 0x00000004))
|
||||
{
|
||||
ee.ExpectRead32(0x00100000, 0x00200000);
|
||||
ee.ExpectWrite32(0x00200004, 0x12345678);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedPointerWriteMultiEven,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x60100000, Patch::EXTENDED_T, 0x12345678),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00020002, Patch::EXTENDED_T, 0x00000004),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00000008, Patch::EXTENDED_T, 0x00000000))
|
||||
{
|
||||
ee.ExpectRead32(0x00100000, 0x00200000);
|
||||
ee.ExpectRead32(0x00200004, 0x00300000);
|
||||
ee.ExpectWrite32(0x00300008, 0x12345678);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedPointerWriteMultiOdd,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x60100000, Patch::EXTENDED_T, 0x12345678),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00020003, Patch::EXTENDED_T, 0x00000004),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00000008, Patch::EXTENDED_T, 0x0000000c))
|
||||
{
|
||||
ee.ExpectRead32(0x00100000, 0x00200000);
|
||||
ee.ExpectRead32(0x00200004, 0x00300000);
|
||||
ee.ExpectRead32(0x00300008, 0x00400000);
|
||||
ee.ExpectWrite32(0x0040000c, 0x12345678);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedPointerWriteFirstNull,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x60100000, Patch::EXTENDED_T, 0x12345678),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00020000, Patch::EXTENDED_T, 0x00000004))
|
||||
{
|
||||
ee.ExpectRead32(0x00100000, 0x00000000);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedPointerWriteLastNull,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x60100000, Patch::EXTENDED_T, 0x12345678),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00020003, Patch::EXTENDED_T, 0x00000004),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00000008, Patch::EXTENDED_T, 0x0000000c))
|
||||
{
|
||||
ee.ExpectRead32(0x00100000, 0x00200000);
|
||||
ee.ExpectRead32(0x00200004, 0x00300000);
|
||||
ee.ExpectRead32(0x00300008, 0x00000000);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// Boolean operation (Extended)
|
||||
// *****************************************************************************
|
||||
|
||||
PATCH_TEST(ExtendedBooleanOr8,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x70100000, Patch::EXTENDED_T, 0x00000012))
|
||||
{
|
||||
ee.ExpectRead8(0x00100000, 0x78);
|
||||
ee.ExpectWrite8(0x00100000, 0x7a);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedBooleanOr16,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x70100000, Patch::EXTENDED_T, 0x00101234))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x89ab);
|
||||
ee.ExpectWrite16(0x00100000, 0x9bbf);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedBooleanAnd8,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x70100000, Patch::EXTENDED_T, 0x00200012))
|
||||
{
|
||||
ee.ExpectRead8(0x00100000, 0x34);
|
||||
ee.ExpectWrite8(0x00100000, 0x10);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedBooleanAnd16,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x70100000, Patch::EXTENDED_T, 0x00301234))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x5678);
|
||||
ee.ExpectWrite16(0x00100000, 0x1230);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedBooleanXor8,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x70100000, Patch::EXTENDED_T, 0x00400012))
|
||||
{
|
||||
ee.ExpectRead8(0x00100000, 0x89);
|
||||
ee.ExpectWrite8(0x00100000, 0x9b);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedBooleanXor16,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x70100000, Patch::EXTENDED_T, 0x00501234))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x89ab);
|
||||
ee.ExpectWrite16(0x00100000, 0x9b9f);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// Do multi-lines if conditional (Extended)
|
||||
// *****************************************************************************
|
||||
|
||||
PATCH_TEST(ExtendedConditional8BitEqualTrue,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0xd0100000, Patch::EXTENDED_T, 0x01010012),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00200000, Patch::EXTENDED_T, 0x00000012),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00300000, Patch::EXTENDED_T, 0x00000012))
|
||||
{
|
||||
ee.ExpectRead8(0x00100000, 0x12);
|
||||
ee.ExpectWrite8(0x00200000, 0x12);
|
||||
ee.ExpectWrite8(0x00300000, 0x12);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedConditional8BitEqualFalse,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0xd0100000, Patch::EXTENDED_T, 0x01010012),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00200000, Patch::EXTENDED_T, 0x00000012),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00300000, Patch::EXTENDED_T, 0x00000012))
|
||||
{
|
||||
ee.ExpectRead8(0x00100000, 0x21);
|
||||
ee.ExpectWrite8(0x00300000, 0x12);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedConditionalEqualTrue,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0xd0100000, Patch::EXTENDED_T, 0x01001234),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00200000, Patch::EXTENDED_T, 0x00000012),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00300000, Patch::EXTENDED_T, 0x00000012))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x1234);
|
||||
ee.ExpectWrite8(0x00200000, 0x12);
|
||||
ee.ExpectWrite8(0x00300000, 0x12);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedConditionalEqualFalse,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0xd0100000, Patch::EXTENDED_T, 0x01001234),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00200000, Patch::EXTENDED_T, 0x00000012),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00300000, Patch::EXTENDED_T, 0x00000012))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x4321);
|
||||
ee.ExpectWrite8(0x00300000, 0x12);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedConditionalNotEqualTrue,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0xd0100000, Patch::EXTENDED_T, 0x01101234),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00200000, Patch::EXTENDED_T, 0x00000012))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x4321);
|
||||
ee.ExpectWrite8(0x00200000, 0x12);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedConditionalNotEqualFalse,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0xd0100000, Patch::EXTENDED_T, 0x01101234),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00200000, Patch::EXTENDED_T, 0x00000012))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x1234);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedConditionalLessThanTrue,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0xd0100000, Patch::EXTENDED_T, 0x01101234),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00200000, Patch::EXTENDED_T, 0x00000012))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x4321);
|
||||
ee.ExpectWrite8(0x00200000, 0x12);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedConditionalLessThanFalse,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0xd0100000, Patch::EXTENDED_T, 0x01101234),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00200000, Patch::EXTENDED_T, 0x00000012))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x1234);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedConditionalECodeEqualTrue,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0xe0011234, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00200000, Patch::EXTENDED_T, 0x00000012),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00300000, Patch::EXTENDED_T, 0x00000012))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x1234);
|
||||
ee.ExpectWrite8(0x00200000, 0x12);
|
||||
ee.ExpectWrite8(0x00300000, 0x12);
|
||||
}
|
||||
|
||||
PATCH_TEST(ExtendedConditionalECodeEqualFalse,
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0xe0011234, Patch::EXTENDED_T, 0x00100000),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00200000, Patch::EXTENDED_T, 0x00000012),
|
||||
BuildPatchCommand(Patch::PPT_ONCE_ON_LOAD, Patch::CPU_EE, 0x00300000, Patch::EXTENDED_T, 0x00000012))
|
||||
{
|
||||
ee.ExpectRead16(0x00100000, 0x4321);
|
||||
ee.ExpectWrite8(0x00300000, 0x12);
|
||||
}
|
||||
Reference in New Issue
Block a user