feat(agc): implement sceAgcGetPacketSize
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
bc24783e5b
commit
40c191029d
|
|
@ -83,6 +83,19 @@ if(BUILD_TESTING)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
add_test_executable(agc_packet_info_tests EXCLUDE_FROM_ALL tests/PacketInfo.cpp)
|
||||
target_include_directories(agc_packet_info_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(agc_packet_info_tests PRIVATE libSceAgc libc)
|
||||
configure_windows_unwind(agc_packet_info_tests)
|
||||
if(BUILD_TESTING)
|
||||
set_target_properties(agc_packet_info_tests PROPERTIES EXCLUDE_FROM_ALL FALSE)
|
||||
add_test(NAME agc_packet_info_tests COMMAND agc_packet_info_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(agc_packet_info_tests PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_test_executable(agc_register_command_tests EXCLUDE_FROM_ALL
|
||||
tests/RegisterCommands.cpp
|
||||
Command/src/Packet.cpp
|
||||
|
|
|
|||
|
|
@ -9,9 +9,12 @@
|
|||
extern "C" {
|
||||
|
||||
uint32_t APS5_VABI sceAgcGetPacketSize(uint32_t* packet) {
|
||||
(void)packet;
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
Agc::Command::CheckAddress(reinterpret_cast<std::uintptr_t>(packet), alignof(uint32_t), __func__);
|
||||
Agc::Command::Require((packet[0] & 0xc0000000u) == 0xc0000000u, __func__, "source pointer is not a PM4 packet");
|
||||
if ((packet[0] & 0x3fffff00u) == 0x3fff1000u) {
|
||||
return 1;
|
||||
}
|
||||
return ((packet[0] >> 16u) & 0x3fffu) + 2u;
|
||||
}
|
||||
|
||||
APS5_EXPORT("V++UgBtQhn0", sceAgcGetDataPacketPayloadAddressUnk);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include "prx/libc/include/Shutdown.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
extern "C" std::uint32_t APS5_VABI sceAgcGetPacketSize(std::uint32_t* packet);
|
||||
|
||||
namespace {
|
||||
|
||||
void check(bool condition, const char* message) {
|
||||
if (!condition) throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
template <typename TAction>
|
||||
void expectFailure(TAction action) {
|
||||
try {
|
||||
action();
|
||||
} catch (const std::runtime_error& error) {
|
||||
check(error.what()[0] != '\0', "empty exception message");
|
||||
return;
|
||||
}
|
||||
throw std::runtime_error("expected an exception");
|
||||
}
|
||||
|
||||
void testPacketSize() {
|
||||
const std::array<std::pair<std::uint32_t, std::uint32_t>, 7> sizes{{
|
||||
{0xc0047600u, 6}, {0xc0001000u, 2}, {0xfffe1000u, 0x4000}, {0xffff7600u, 0x4001},
|
||||
{0xffff1000u, 1}, {0xffff1001u, 1}, {0xffff10fcu, 1}}};
|
||||
for (const auto& [header, size] : sizes) {
|
||||
std::array<std::uint32_t, 2> words{header, 0xffff1000u};
|
||||
check(sceAgcGetPacketSize(words.data()) == size, "packet size mismatch");
|
||||
check(words[0] == header && words[1] == 0xffff1000u, "packet size query modified the packet");
|
||||
}
|
||||
}
|
||||
|
||||
void testRejections() {
|
||||
for (const auto header : {0x80000000u, 0x3fff1000u, 0x40001000u, 0x00047600u}) {
|
||||
std::uint32_t word = header;
|
||||
expectFailure([&] { sceAgcGetPacketSize(&word); });
|
||||
}
|
||||
expectFailure([] { sceAgcGetPacketSize(nullptr); });
|
||||
std::array<std::uint32_t, 2> words{0x00100000u, 0x000000c0u};
|
||||
auto* misaligned = reinterpret_cast<std::uint32_t*>(reinterpret_cast<unsigned char*>(words.data()) + 1);
|
||||
expectFailure([&] { sceAgcGetPacketSize(misaligned); });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
try {
|
||||
testPacketSize();
|
||||
testRejections();
|
||||
LibcRunShutdown_nid_postfix();
|
||||
std::puts("AGC packet info tests passed");
|
||||
return 0;
|
||||
} catch (const std::exception& error) {
|
||||
std::fprintf(stderr, "%s\n", error.what());
|
||||
try { LibcRunShutdown_nid_postfix(); }
|
||||
catch (const std::exception& shutdown) { std::fprintf(stderr, "shutdown: %s\n", shutdown.what()); }
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue