Skip to content

Commit

Permalink
Update following review
Browse files Browse the repository at this point in the history
 - Improve unit tests
 - Add a mask to handle complex pointer like PSX
  • Loading branch information
Vancleeff committed Apr 28, 2024
1 parent 2fc324b commit 8312f48
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 30 deletions.
18 changes: 14 additions & 4 deletions src/ui/viewmodels/MemoryViewerViewModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -903,12 +903,22 @@ void MemoryViewerViewModel::OnShiftClick(int nX, int nY)

OnClick(nX, nY);

ra::ByteAddress nAddress = pEmulatorContext.ReadMemory(GetAddress(), GetSize());
// We need to create a mask based on the last address of the current console to be able to point to more complexe pointer format
// like on Playstation on which pointers are represented as a 24-bit pointer prefixed by 80.
std::wstring sMaxAddress = ra::data::MemSizeFormat(pConsoleContext.MaxAddress(), MemSize::ThirtyTwoBit, MemFormat::Hex);
std::wstring sMask;

for (wchar_t ch : sMaxAddress)
if (ch != L'0')
sMask.push_back(L'F');

auto nMask = std::stoi(sMask, 0, 16);
ra::ByteAddress nAddress = (pEmulatorContext.ReadMemory(GetAddress(), GetSize())) & nMask;
const auto nConvertedAddress = pConsoleContext.ByteAddressFromRealAddress(nAddress);
if (nConvertedAddress != 0xFFFFFFFF)
nAddress = nConvertedAddress;

SetAddress(nAddress);
{
SetAddress(nConvertedAddress);
}
}

void MemoryViewerViewModel::OnResized(int nWidth, int nHeight)
Expand Down
94 changes: 68 additions & 26 deletions tests/ui/viewmodels/MemoryViewerViewModel_Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1925,19 +1925,17 @@ TEST_CLASS(MemoryViewerViewModel_Tests)

TEST_METHOD(TestOnShiftClickEightBit)
{
ra::data::context::mocks::MockConsoleContext mockConsole(PlayStation, L"Playstation");
ra::data::context::mocks::MockConsoleContext mockConsole(PlayStation, L"PlayStation");

MemoryViewerViewModelHarness viewer;
viewer.InitializeMemory(128); // 8 rows of 16 bytes
viewer.mockEmulatorContext.WriteMemoryByte(0U, 0x20);
viewer.mockEmulatorContext.WriteMemoryByte(1U, 0xff);
viewer.mockEmulatorContext.WriteMemoryByte(2U, 0x0);
viewer.InitializeMemory(0xFFFF);

Assert::AreEqual(MemSize::EightBit, viewer.GetSize());
Assert::AreEqual({ 0U }, viewer.GetAddress());
Assert::AreEqual({ 0U }, viewer.GetSelectedNibble());

// If fixed address, ignore
viewer.mockEmulatorContext.WriteMemoryByte(0U, 0x20);
viewer.SetAddressFixed(true);
viewer.OnShiftClick(10 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0x0U}, viewer.GetAddress());
Expand All @@ -1947,26 +1945,20 @@ TEST_CLASS(MemoryViewerViewModel_Tests)
viewer.OnShiftClick(10 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({ 0x20U }, viewer.GetAddress());

// Shift click on the second byte containing 0xFF should lead to address 0x7F as 0xFF is bigger than the last
// address in memory
viewer.OnShiftClick(13 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0x7FU}, viewer.GetAddress());

// Shift click on the third byte containing 0x0 should lead back to address 0x0
viewer.OnShiftClick(16 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0x0U}, viewer.GetAddress());
// Shift click on the second byte containing 0x0 should do nothing
viewer.SetAddress(0);
viewer.mockEmulatorContext.WriteMemoryByte(1U, 0x0);
viewer.OnShiftClick(15 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0x1U}, viewer.GetAddress());
}

TEST_METHOD(TestOnShiftClickSixTeenBit)
TEST_METHOD(TestOnShiftClickSixteenBit)
{
ra::data::context::mocks::MockConsoleContext mockConsole(PlayStation, L"Playstation");
ra::data::context::mocks::MockConsoleContext mockConsole(PlayStation, L"PlayStation");

MemoryViewerViewModelHarness viewer;
viewer.InitializeMemory(512); // 32 rows of 16 bytes
viewer.InitializeMemory(0xFFFF);
viewer.SetSize(MemSize::SixteenBit);
viewer.mockEmulatorContext.WriteMemory(0U, MemSize::SixteenBit, 0x20);
viewer.mockEmulatorContext.WriteMemory(2U, MemSize::SixteenBit, 0xff);
viewer.mockEmulatorContext.WriteMemory(4U, MemSize::SixteenBit, 0xffff);

Assert::AreEqual(MemSize::SixteenBit, viewer.GetSize());
Assert::AreEqual({0U}, viewer.GetAddress());
Expand All @@ -1978,18 +1970,68 @@ TEST_CLASS(MemoryViewerViewModel_Tests)
Assert::AreEqual({0x0U}, viewer.GetAddress());

// If not fixed address and Shift click on the first word containing 0x20 should lead to address 0x20
viewer.SetAddress(0);
viewer.SetAddressFixed(false);
viewer.mockEmulatorContext.WriteMemory(0U, MemSize::SixteenBit, 0x0020);
viewer.OnShiftClick(10 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0x20U}, viewer.GetAddress());

// Shift click on the second word containing 0x40 should lead to address 0xFF
viewer.OnShiftClick(15 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0xFFU}, viewer.GetAddress());
// Shift click on the first word containing 0x0140 should lead to address 0x0140
viewer.SetAddress(0);
viewer.mockEmulatorContext.WriteMemory(0U, MemSize::SixteenBit, 0x0140);
viewer.OnShiftClick(10 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0x0140U}, viewer.GetAddress());

// Shift click on the second word containing 0x0 should do nothing
viewer.SetAddress(0x4);
viewer.mockEmulatorContext.WriteMemory(4U, MemSize::SixteenBit, 0x0);
viewer.OnShiftClick(22 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0x4U}, viewer.GetAddress());
}

TEST_METHOD(TestOnShiftClickThirtyTwoBit)
{
ra::data::context::mocks::MockConsoleContext mockConsole(PlayStation, L"Playstation");

MemoryViewerViewModelHarness viewer;
viewer.InitializeMemory(0x1FFFFF); // PSX full memory
viewer.SetSize(MemSize::ThirtyTwoBit);

Assert::AreEqual(MemSize::ThirtyTwoBit, viewer.GetSize());
Assert::AreEqual({0U}, viewer.GetAddress());
Assert::AreEqual({0U}, viewer.GetSelectedNibble());

// Shift click on the third word containing 0xFFFF should lead to address 0x1FF as 0xFFFF is bigger than the
// last address in memory
viewer.OnShiftClick(19 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0x1FFU}, viewer.GetAddress());
// If fixed address, ignore
viewer.SetAddressFixed(true);
viewer.OnShiftClick(10 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0x0U}, viewer.GetAddress());

// If not fixed address and Shift click on the first dword containing 0x1234 should lead to address 0x1234
viewer.SetAddress(0);
viewer.SetAddressFixed(false);
viewer.mockEmulatorContext.WriteMemory(0U, MemSize::ThirtyTwoBit, 0x1234);
viewer.OnShiftClick(10 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0x1234U}, viewer.GetAddress());

// Shift click on the first dword containing 0x80012345 should lead to address 0x00012345 as the conversion keeps
// only the same number of nibbles as the Max address from console context (PSX : 1FFFFF)
viewer.SetAddress(0);
viewer.mockEmulatorContext.WriteMemory(0U, MemSize::ThirtyTwoBit, 0x00012345);
viewer.OnShiftClick(10 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0x00012345}, viewer.GetAddress());

// Shift click on the second dword containing 0x0 should do nothing
viewer.SetAddress(0x8);
viewer.mockEmulatorContext.WriteMemory(8U, MemSize::ThirtyTwoBit, 0x0);
viewer.OnShiftClick(28 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0x8U}, viewer.GetAddress());

// Shift click on the first dword containing 0x005FFFFF should do nothing as 0x005FFFFF exceed the
// last address in the current console context (PSX : 0x1FFFFF) and can't be converted to real address
viewer.SetAddress(0);
viewer.mockEmulatorContext.WriteMemory(0U, MemSize::ThirtyTwoBit, 0x005FFFFF);
viewer.OnShiftClick(10 * CHAR_WIDTH, CHAR_HEIGHT + 4);
Assert::AreEqual({0x0}, viewer.GetAddress());
}
};

Expand Down

0 comments on commit 8312f48

Please sign in to comment.