From a0314c9847d84c74235fd428c64ce09ce3084341 Mon Sep 17 00:00:00 2001 From: Ran-j Date: Thu, 29 May 2025 16:21:00 -0300 Subject: [PATCH] feat: placeholder for exec VU0Microprogram --- ps2xRecomp/src/code_generator.cpp | 39 ++++++++++++++++++++++++++++--- ps2xRuntime/include/ps2_runtime.h | 1 + ps2xRuntime/src/ps2_runtime.cpp | 11 +++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/ps2xRecomp/src/code_generator.cpp b/ps2xRecomp/src/code_generator.cpp index cd0d73d..f47f523 100644 --- a/ps2xRecomp/src/code_generator.cpp +++ b/ps2xRecomp/src/code_generator.cpp @@ -1976,17 +1976,50 @@ namespace ps2recomp std::string CodeGenerator::translateVU_VCALLMS(const Instruction &inst) { - return fmt::format("// Calls VU0 microprogram at address {} - not implemented in recompiled code", inst.immediate); + // VCALLMS calls a VU0 microprogram at the specified immediate address. + // VU0 micro memory is 4KB = 512 instructions (8 bytes each). Index is 0-511. + uint16_t instr_index = inst.immediate & 0x1FF; // Mask to 9 bits for VU0 + uint32_t target_byte_addr = (uint32_t)instr_index << 3; // Convert instruction index to byte address + + return fmt::format( + "{{ " + " ctx->vu0_tpc = 0x{:X}; " // Set target program counter + " runtime->executeVU0Microprogram(rdram, ctx, 0x{:X}); " + "}}", + target_byte_addr, target_byte_addr); } std::string CodeGenerator::translateVU_VCALLMSR(const Instruction &inst) { - return fmt::format("// Calls VU0 microprogram at address {} - not implemented in recompiled code", inst.immediate); + // VCALLMSR calls a VU0 microprogram at address stored in integer register + uint8_t vis_reg_idx = inst.rs; // Source integer register + + return fmt::format( + "{{ " + " uint16_t instr_index = ctx->vi[{}] & 0x1FF; " // Get instruction index from VI[IS], mask to 9 bits + " uint32_t target_byte_addr = (uint32_t)instr_index << 3; " // Convert to byte address + " ctx->vu0_pc = target_byte_addr; " + " runtime->vu0StartMicroProgram(rdram, ctx, target_byte_addr); " + "}}", + vis_reg_idx); } std::string CodeGenerator::translateVU_VRNEXT(const Instruction &inst) { - return fmt::format("// Unhandled VU0 VRNEXT instruction: 0x{:X}", inst.function); + return fmt::format( + "{{ " + " uint32_t r_vals[4]; " + " _mm_storeu_si128((__m128i*)r_vals, (__m128i)ctx->vu0_r); " + " " + " // Simple LFSR-based random number generation (PS2-like behavior) " + " uint32_t feedback = r_vals[0] ^ (r_vals[0] << 13) ^ (r_vals[1] >> 19) ^ (r_vals[2] << 7); " + " r_vals[0] = r_vals[1]; " + " r_vals[1] = r_vals[2]; " + " r_vals[2] = r_vals[3]; " + " r_vals[3] = feedback; " + " " + " ctx->vu0_r = _mm_loadu_si128((__m128i*)r_vals); " + "}}"); } std::string CodeGenerator::translateVU_VMADD_Field(const Instruction &inst) diff --git a/ps2xRuntime/include/ps2_runtime.h b/ps2xRuntime/include/ps2_runtime.h index bc059f2..de4d33e 100644 --- a/ps2xRuntime/include/ps2_runtime.h +++ b/ps2xRuntime/include/ps2_runtime.h @@ -389,6 +389,7 @@ public: RecompiledFunction lookupFunction(uint32_t address); void SignalException(R5900Context* ctx, PS2Exception exception); + void executeVU0Microprogram(uint8_t* rdram, R5900Context* ctx, uint32_t address); private: void HandleIntegerOverflow(R5900Context* ctx); diff --git a/ps2xRuntime/src/ps2_runtime.cpp b/ps2xRuntime/src/ps2_runtime.cpp index e18f9bb..d3ab501 100644 --- a/ps2xRuntime/src/ps2_runtime.cpp +++ b/ps2xRuntime/src/ps2_runtime.cpp @@ -180,6 +180,17 @@ void PS2Runtime::SignalException(R5900Context *ctx, PS2Exception exception) } } +void PS2Runtime::executeVU0Microprogram(uint8_t *rdram, R5900Context *ctx, uint32_t address) +{ + std::cout << "VU0 microprogram call to address 0x" << std::hex << address + << " - not implemented" << std::dec << std::endl; + + // mayve implement like this or a vu0_interpreter + // Placeholder for VU0 microprogram execution + // auto microprog = findCompiledMicroprogram(address); + // if (microprog) microprog(rdram, ctx); +} + void PS2Runtime::HandleIntegerOverflow(R5900Context *ctx) { std::cerr << "Integer overflow exception at PC: 0x" << std::hex << ctx->pc << std::dec << std::endl;