Feature/added execution guess gs psmt (#104)

* fix: CRITICAL fix on code gen on generating BEQ translation, I added a small yeld because goto could spin forever and monopolize guest execution

* feat: add scratchpad alias base and improve scratchpad address handling

* feat: added debug logging on GifArbiter for submit and drain operations

* feat: add interrupt and thread management syscall implementations
fix: change some IDs calls to match ps2sdk

* feat: added vif1 logs

* feat: added logs on gs gpu
feat: added performLocalToLocalTransfer to GS emulation path for TRXDIR = 2. (emulates the PS2 GS “copy this rectangle from one place in VRAM to another”)

* feat: added PSMT8 and refactor PSMT4

* feat: some identation on vu1
feat: added some logs on vu1

* feat: added GuestExecutionScope to temporarily stop owning guest execution, then restore it exactly as it was.
feat: added vsync wizardry
feat: added some regression test

* fix: fix gs logger

* feat: remove extra logs I think they will help no one
feat: move join all threads to prevent the app to get stuck on close, but now it random crash on closing
feat: one more small test on psmt4 to try fix ghosting on re code veronica

* feat: added a small case for exporter from ghidra for metal slug 3

* feat: added ugly code to pass on test
This commit is contained in:
Ranieri
2026-03-18 19:14:40 -03:00
committed by GitHub
parent 7ca6a866c9
commit cad1ca0bb5
32 changed files with 3942 additions and 685 deletions
+60
View File
@@ -100,6 +100,22 @@ void register_ps2_memory_tests()
t.Equals(mem.translateAddress(0xA0005678u), 0x00005678u, "KSEG1 should map directly to physical");
t.Equals(mem.translateAddress(0x20001234u), 0x00001234u, "0x2000 uncached alias should map to RAM");
t.Equals(mem.translateAddress(0x30105678u), 0x00105678u, "0x3010 accelerated alias should map to RAM");
t.Equals(mem.translateAddress(PS2_SCRATCHPAD_BASE + 0x123u), 0x123u, "scratchpad base should translate to local offset");
t.Equals(mem.translateAddress(PS2_SCRATCHPAD_ALIAS_BASE + 0x123u), 0x123u, "0xF000 scratchpad alias should translate to local offset");
});
tc.Run("scratchpad alias accesses the same bytes as base", [](TestCase &t)
{
PS2Memory mem;
t.IsTrue(mem.initialize(), "PS2Memory initialize should succeed");
constexpr uint32_t kOffset = 0x140u;
constexpr uint32_t kScratchAddr = PS2_SCRATCHPAD_BASE + kOffset;
constexpr uint32_t kScratchAliasAddr = PS2_SCRATCHPAD_ALIAS_BASE + kOffset;
mem.write32(kScratchAliasAddr, 0xCAFEBABEu);
t.Equals(mem.read32(kScratchAddr), 0xCAFEBABEu, "writes through 0xF000 scratchpad alias should land in scratchpad");
t.Equals(mem.read32(kScratchAliasAddr), 0xCAFEBABEu, "reads through 0xF000 scratchpad alias should see scratchpad bytes");
});
tc.Run("fast memory helpers wrap safely at RAM boundary", [](TestCase &t)
@@ -792,6 +808,50 @@ void register_ps2_memory_tests()
t.IsTrue(contentOk, "scratchpad GIF DMA packet bytes should match scratchpad source");
});
tc.Run("GIF DMA chain can source tags and payload from 0xF000 scratchpad alias", [](TestCase &t)
{
PS2Memory mem;
t.IsTrue(mem.initialize(), "PS2Memory initialize should succeed");
constexpr uint32_t kGifCh = 0x1000A000u;
constexpr uint32_t kTagAlias = PS2_SCRATCHPAD_ALIAS_BASE + 0x100u;
uint8_t *scratch = mem.getScratchpad();
std::memset(scratch + 0x100u, 0, 32u);
const uint64_t endTag = makeDmaTag(1u, 7u, 0u, false);
std::memcpy(scratch + 0x100u, &endTag, sizeof(endTag));
for (uint32_t i = 0; i < 16u; ++i)
{
scratch[0x110u + i] = static_cast<uint8_t>(0xC0u + i);
}
std::vector<std::vector<uint8_t>> captured;
mem.setGifPacketCallback([&](const uint8_t *data, uint32_t sizeBytes)
{
captured.emplace_back(data, data + sizeBytes);
});
t.IsTrue(mem.writeIORegister(kGifCh + 0x30u, kTagAlias), "write TADR scratchpad alias should succeed");
t.IsTrue(mem.writeIORegister(kGifCh + 0x00u, 0x104u), "write CHCR STR|CHAIN should succeed");
mem.processPendingTransfers();
t.Equals(captured.size(), static_cast<size_t>(1u), "scratchpad alias chain should emit one packet");
t.Equals(captured[0].size(), static_cast<size_t>(16u), "scratchpad alias chain should emit one qword");
bool contentOk = true;
for (uint32_t i = 0; i < 16u; ++i)
{
if (captured[0][i] != static_cast<uint8_t>(0xC0u + i))
{
contentOk = false;
break;
}
}
t.IsTrue(contentOk, "scratchpad alias chain payload should match scratchpad bytes");
});
tc.Run("VIF1 DMA DIRECT forwards payload to GIF callback and clears channel", [](TestCase &t)
{
PS2Memory mem;