From 7babd24bd13c81eed33908ccd8d114eef78f5c4f Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Wed, 15 Feb 2023 17:59:25 -0500 Subject: [PATCH] Implemented audio ucode recomp and audio interface, removed restrict usage due to issues with release builds --- RSPRecomp/src/rsp_recomp.cpp | 76 ++++++++----- recomp.h | 3 +- src/main.cpp | 6 +- src/recompilation.cpp | 2 +- test/RecompFuncs/RecompFuncs.vcxproj | 7 ++ test/RecompTest.vcxproj | 22 +++- test/RecompTest.vcxproj.filters | 6 + test/portultra/audio.cpp | 142 +++++++++++++++++++++++ test/portultra/events.cpp | 3 +- test/portultra/multilibultra.hpp | 4 + test/portultra/ultrainit.cpp | 1 + test/rsp/.gitignore | 1 + test/src/ai.cpp | 29 +++-- test/src/cont.cpp | 20 ++-- test/src/dp.cpp | 2 +- test/src/eep.cpp | 10 +- test/src/math_routines.cpp | 18 +-- test/src/pak.cpp | 14 +-- test/src/pi.cpp | 20 ++-- test/src/portultra_translation.cpp | 60 +++++----- test/src/print.cpp | 38 +++---- test/src/recomp.cpp | 6 +- test/src/rsp_vu.h | 164 +++++++++++++-------------- test/src/sp.cpp | 10 +- test/src/vi.cpp | 18 +-- 25 files changed, 447 insertions(+), 235 deletions(-) create mode 100644 test/portultra/audio.cpp diff --git a/RSPRecomp/src/rsp_recomp.cpp b/RSPRecomp/src/rsp_recomp.cpp index e6dfdb3..c43f476 100644 --- a/RSPRecomp/src/rsp_recomp.cpp +++ b/RSPRecomp/src/rsp_recomp.cpp @@ -11,6 +11,7 @@ using InstrId = rabbitizer::InstrId::UniqueId; using Cop0Reg = rabbitizer::Registers::Rsp::Cop0; constexpr size_t instr_size = sizeof(uint32_t); +constexpr uint32_t rsp_mem_mask = 0x1FFF; // Can't use rabbitizer's operand types because we need to be able to provide a register reference or a register index enum class RspOperand { @@ -126,6 +127,8 @@ uint32_t expected_c0_reg_value(int cop0_reg) { return 0; // Pretend DMAs complete instantly case Cop0Reg::RSP_COP0_SP_SEMAPHORE: return 0; // Always acquire the semaphore + case Cop0Reg::RSP_COP0_DPC_STATUS: + return 0; // Good enough for the microcodes that would be recompiled (i.e. non-graphics ones) } fmt::print(stderr, "Unhandled mfc0: {}\n", cop0_reg); assert(false); @@ -175,7 +178,7 @@ BranchTargets get_branch_targets(const std::vector& BranchTargets ret; for (const auto& instr : instrs) { if (instr.isJumpWithAddress() || instr.isBranch()) { - ret.direct_targets.insert(instr.getBranchVramGeneric()); + ret.direct_targets.insert(instr.getBranchVramGeneric() & rsp_mem_mask); } if (instr.doesLink()) { ret.indirect_targets.insert(instr.getVram() + 2 * instr_size); @@ -184,22 +187,27 @@ BranchTargets get_branch_targets(const std::vector& return ret; } -bool process_instruction(size_t instr_index, const std::vector& instructions, std::ofstream& output_file, const BranchTargets& branch_targets, bool indent) { +bool process_instruction(size_t instr_index, const std::vector& instructions, std::ofstream& output_file, const BranchTargets& branch_targets, bool indent, bool in_delay_slot) { const auto& instr = instructions[instr_index]; uint32_t instr_vram = instr.getVram(); InstrId instr_id = instr.getUniqueId(); - // Print a label if one exists here - if (branch_targets.direct_targets.contains(instr_vram) || branch_targets.indirect_targets.contains(instr_vram)) { - fmt::print(output_file, "L_{:08X}:\n", instr_vram); + // Skip labels if we're duplicating an instruction into a delay slot + if (!in_delay_slot) { + // Print a label if one exists here + if (branch_targets.direct_targets.contains(instr_vram) || branch_targets.indirect_targets.contains(instr_vram)) { + fmt::print(output_file, "L_{:04X}:\n", instr_vram); + } } + uint16_t branch_target = instr.getBranchVramGeneric() & rsp_mem_mask; + // Output a comment with the original instruction if (instr.isBranch() || instr_id == InstrId::rsp_j) { - fmt::print(output_file, " // {}\n", instr.disassemble(0, fmt::format("L_{:08X}", (uint32_t)instr.getBranchVramGeneric()))); + fmt::print(output_file, " // {}\n", instr.disassemble(0, fmt::format("L_{:04X}", branch_target))); } else if (instr_id == InstrId::rsp_jal) { - fmt::print(output_file, " // {}\n", instr.disassemble(0, fmt::format("0x{:08X}", (uint32_t)instr.getBranchVramGeneric()))); + fmt::print(output_file, " // {}\n", instr.disassemble(0, fmt::format("0x{:04X}", branch_target))); } else { fmt::print(output_file, " // {}\n", instr.disassemble(0)); } @@ -222,7 +230,7 @@ bool process_instruction(size_t instr_index, const std::vector(fmt::format_string fmt_str, Ts ...args) { if (instr_index < instructions.size() - 1) { uint32_t next_vram = instr_vram + 4; - process_instruction(instr_index + 1, instructions, output_file, branch_targets, false); + process_instruction(instr_index + 1, instructions, output_file, branch_targets, false, true); } print_indent(); fmt::print(output_file, fmt_str, args...); @@ -233,7 +241,7 @@ bool process_instruction(size_t instr_index, const std::vector= 0)", ctx_gpr_prefix(rs), rs); - print_branch("goto L_{:08X}", (uint32_t)instr.getBranchVramGeneric()); + print_branch("goto L_{:04X}", branch_target); break; case InstrId::rsp_bgtz: print_indent(); print_branch_condition("if (RSP_SIGNED({}{}) > 0)", ctx_gpr_prefix(rs), rs); - print_branch("goto L_{:08X}", (uint32_t)instr.getBranchVramGeneric()); + print_branch("goto L_{:04X}", branch_target); break; case InstrId::rsp_blez: print_indent(); print_branch_condition("if (RSP_SIGNED({}{}) <= 0)", ctx_gpr_prefix(rs), rs); - print_branch("goto L_{:08X}", (uint32_t)instr.getBranchVramGeneric()); + print_branch("goto L_{:04X}", branch_target); break; case InstrId::rsp_bltz: print_indent(); print_branch_condition("if (RSP_SIGNED({}{}) < 0)", ctx_gpr_prefix(rs), rs); - print_branch("goto L_{:08X}", (uint32_t)instr.getBranchVramGeneric()); + print_branch("goto L_{:04X}", branch_target); break; case InstrId::rsp_break: print_line("return RspExitReason::Broke", instr_vram); @@ -492,9 +500,9 @@ bool process_instruction(size_t instr_index, const std::vector extra_indirect_branch_targets{}; + +constexpr size_t rsp_text_offset = 0xB89260; +constexpr size_t rsp_text_size = 0xFB0; +constexpr size_t rsp_text_address = 0x04001000; std::string rom_file_path = "../test/oot_mq_debug.z64"; -std::string output_file_path = "../test/rsp/njpgdspMain.cpp"; -std::string output_function_name = "njpgdspMain"; +std::string output_file_path = "../test/rsp/aspMain.cpp"; +std::string output_function_name = "aspMain"; +const std::vector extra_indirect_branch_targets{ 0x1F68, 0x1230, 0x114C, 0x1F18, 0x1E2C, 0x14F4, 0x1E9C, 0x1CB0, 0x117C, 0x17CC, 0x11E8, 0x1AA4, 0x1B34, 0x1190, 0x1C5C, 0x1220, 0x1784, 0x1830, 0x1A20, 0x1884, 0x1A84, 0x1A94, 0x1A48, 0x1BA0 }; #ifdef _MSC_VER inline uint32_t byteswap(uint32_t val) { @@ -544,7 +561,7 @@ int main() { // Decode the instruction words into instructions std::vector instrs{}; instrs.reserve(instr_words.size()); - uint32_t vram = rsp_text_address; + uint32_t vram = rsp_text_address & rsp_mem_mask; for (uint32_t instr_word : instr_words) { const rabbitizer::InstructionRsp& instr = instrs.emplace_back(byteswap(instr_word), vram); vram += instr_size; @@ -553,6 +570,11 @@ int main() { // Collect indirect jump targets (return addresses for linked jumps) BranchTargets branch_targets = get_branch_targets(instrs); + // Add any additional indirect branch targets that may not be found directly in the code (e.g. from a jump table) + for (uint32_t target : extra_indirect_branch_targets) { + branch_targets.indirect_targets.insert(target); + } + // Open output file and write beginning std::ofstream output_file(output_file_path); fmt::print(output_file, @@ -568,7 +590,7 @@ int main() { " r1 = 0xFC0;\n", output_function_name); // Write each instruction for (size_t instr_index = 0; instr_index < instrs.size(); instr_index++) { - process_instruction(instr_index, instrs, output_file, branch_targets, false); + process_instruction(instr_index, instrs, output_file, branch_targets, false, false); } // Terminate instruction code with a return to indicate that the microcode has run past its end diff --git a/recomp.h b/recomp.h index 9db6594..2b17d41 100644 --- a/recomp.h +++ b/recomp.h @@ -173,14 +173,13 @@ typedef struct { } recomp_context; #ifdef __cplusplus -#define restrict __restrict extern "C" { #endif void switch_error(const char* func, uint32_t vram, uint32_t jtbl); void do_break(uint32_t vram); -typedef void (recomp_func_t)(uint8_t* restrict rdram, recomp_context* restrict ctx); +typedef void (recomp_func_t)(uint8_t* rdram, recomp_context* ctx); recomp_func_t* get_function(int32_t vram); diff --git a/src/main.cpp b/src/main.cpp index 76da17d..cfb43dc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -992,7 +992,7 @@ int main(int argc, char** argv) { if (!func.ignored && func.words.size() != 0) { fmt::print(func_header_file, - "void {}(uint8_t* restrict rdram, recomp_context* restrict ctx);\n", func.name); + "void {}(uint8_t* rdram, recomp_context* ctx);\n", func.name); //fmt::print(lookup_file, // " {{ 0x{:08X}u, {} }},\n", func.vram, func.name); if (RecompPort::recompile_function(context, func, output_dir + func.name + ".c", static_funcs_by_section) == false) { @@ -1002,7 +1002,7 @@ int main(int argc, char** argv) { } } else if (func.reimplemented) { fmt::print(func_header_file, - "void {}(uint8_t* restrict rdram, recomp_context* restrict ctx);\n", func.name); + "void {}(uint8_t* rdram, recomp_context* ctx);\n", func.name); //fmt::print(lookup_file, // " {{ 0x{:08X}u, {} }},\n", func.vram, func.name); } @@ -1058,7 +1058,7 @@ int main(int argc, char** argv) { }; fmt::print(func_header_file, - "void {}(uint8_t* restrict rdram, recomp_context* restrict ctx);\n", func.name); + "void {}(uint8_t* rdram, recomp_context* ctx);\n", func.name); //fmt::print(lookup_file, // " {{ 0x{:08X}u, {} }},\n", func.vram, func.name); if (RecompPort::recompile_function(context, func, output_dir + func.name + ".c", static_funcs_by_section) == false) { diff --git a/src/recompilation.cpp b/src/recompilation.cpp index 0cb5bba..bca1e8f 100644 --- a/src/recompilation.cpp +++ b/src/recompilation.cpp @@ -978,7 +978,7 @@ bool RecompPort::recompile_function(const RecompPort::Context& context, const Re "#include \"recomp.h\"\n" "#include \"disable_warnings.h\"\n" "\n" - "void {}(uint8_t* restrict rdram, recomp_context* restrict ctx) {{\n" + "void {}(uint8_t* rdram, recomp_context* ctx) {{\n" // these variables shouldn't need to be preserved across function boundaries, so make them local for more efficient output " uint64_t hi = 0, lo = 0, result = 0;\n" " int c1cs = 0; \n", // cop1 conditional signal diff --git a/test/RecompFuncs/RecompFuncs.vcxproj b/test/RecompFuncs/RecompFuncs.vcxproj index a3d947e..0cf8357 100644 --- a/test/RecompFuncs/RecompFuncs.vcxproj +++ b/test/RecompFuncs/RecompFuncs.vcxproj @@ -93,6 +93,10 @@ $(SolutionDir).. true + Disabled + + + EnableFastChecks @@ -134,6 +138,8 @@ $(SolutionDir).. true + Disabled + EnableFastChecks @@ -155,6 +161,7 @@ $(SolutionDir).. true + false diff --git a/test/RecompTest.vcxproj b/test/RecompTest.vcxproj index 9dee895..3171e2e 100644 --- a/test/RecompTest.vcxproj +++ b/test/RecompTest.vcxproj @@ -153,6 +153,11 @@ XCOPY "$(ProjectDir)Lib\SDL2-2.24.0\lib\$(Platform)\SDL2.dll" "$(TargetDir)" /S + + MaxSpeed + MaxSpeed + Default + @@ -162,7 +167,22 @@ XCOPY "$(ProjectDir)Lib\SDL2-2.24.0\lib\$(Platform)\SDL2.dll" "$(TargetDir)" /S - + + MaxSpeed + MaxSpeed + Default + false + AnySuitable + AnySuitable + + + MaxSpeed + MaxSpeed + Default + false + AnySuitable + AnySuitable + diff --git a/test/RecompTest.vcxproj.filters b/test/RecompTest.vcxproj.filters index 7f0a312..e40ba5f 100644 --- a/test/RecompTest.vcxproj.filters +++ b/test/RecompTest.vcxproj.filters @@ -30237,6 +30237,12 @@ Source Files + + Source Files + + + Source Files + diff --git a/test/portultra/audio.cpp b/test/portultra/audio.cpp new file mode 100644 index 0000000..c884138 --- /dev/null +++ b/test/portultra/audio.cpp @@ -0,0 +1,142 @@ +#include "ultra64.h" +#include "multilibultra.hpp" +#include "SDL.h" +#include "SDL_audio.h" +#include + +static SDL_AudioDeviceID audio_device = 0; + +void Multilibultra::init_audio() { + // Initialize SDL audio. + SDL_InitSubSystem(SDL_INIT_AUDIO); + // Pick an initial dummy sample rate; this will be set by the game later to the true sample rate. + set_audio_frequency(48000); +} + +void SDLCALL feed_audio(void* userdata, Uint8* stream, int len); + +void Multilibultra::set_audio_frequency(uint32_t freq) { + if (audio_device != 0) { + SDL_CloseAudioDevice(audio_device); + } + SDL_AudioSpec spec_desired{ + .freq = (int)freq, + .format = AUDIO_S16, + .channels = 2, + .silence = 0, // calculated + .samples = 0x100, // Fairly small sample count to reduce the latency of internal buffering + .padding = 0, // unused + .size = 0, // calculated + .callback = feed_audio, // Use a callback as QueueAudio causes popping + .userdata = nullptr + }; + + audio_device = SDL_OpenAudioDevice(nullptr, false, &spec_desired, nullptr, 0); + if (audio_device == 0) { + printf("SDL Error: %s\n", SDL_GetError()); + fflush(stdout); + assert(false); + } + SDL_PauseAudioDevice(audio_device, 0); +} + +// Struct representing a queued audio buffer. +struct AudioBuffer { + // All samples in the buffer, including those that have already been sent. + std::vector samples; + // The count of samples that have already been sent to the audio device. + size_t used_samples = 0; + + // Helper methods. + size_t remaining_samples() const { return samples.size() - used_samples; }; + size_t remaining_bytes() const { return remaining_samples() * sizeof(samples[0]); }; + int16_t* first_unused_sample() { return &samples[used_samples]; } + bool empty() { return used_samples == samples.size(); } +}; + +// Mutex for locking the queued audio buffer list. +std::mutex audio_buffers_mutex; +// The queued audio buffer list, holds a list of buffers that have been queued by the game. +std::vector audio_buffers; + +void SDLCALL feed_audio(void* userdata, Uint8* stream, int byte_count) { + // Ensure that the byte count is an integer multiple of samples. + assert((byte_count & 1) == 0); + + // Calculate the sample count from the byte count. + size_t remaining_samples = byte_count / sizeof(int16_t); + + // Lock the queued audio buffer list. + std::lock_guard lock{ audio_buffers_mutex }; + + // Empty the audio buffers until we've sent all the required samples + // or until there are no samples left in the audio buffers. + while (!audio_buffers.empty() && remaining_samples > 0) { + auto& cur_buffer = audio_buffers.front(); + // Prevent overrunning either the input or output buffer. + size_t to_copy = std::min(remaining_samples, cur_buffer.remaining_samples()); + // Copy samples from the input buffer to the output one. + memcpy(stream, cur_buffer.first_unused_sample(), to_copy * sizeof(int16_t)); + // Advance the output buffer by the copied byte count. + stream += to_copy * sizeof(int16_t); + // Advance the input buffer by the copied sample count. + cur_buffer.used_samples += to_copy; + // Updated the remaining sample count. + remaining_samples -= to_copy; + + // If the input buffer was emptied, remove it from the list of queued buffers. + if (cur_buffer.empty()) { + audio_buffers.erase(audio_buffers.begin()); + } + } + + // Zero out any remaining audio data to lessen audio issues during lag + memset(stream, 0, remaining_samples * sizeof(int16_t)); +} + +void Multilibultra::queue_audio_buffer(RDRAM_ARG PTR(s16) audio_data_, uint32_t byte_count) { + // Ensure that the byte count is an integer multiple of samples. + assert((byte_count & 1) == 0); + + s16* audio_data = TO_PTR(s16, audio_data_); + // Calculate the number of samples from the number of bytes. + uint32_t sample_count = byte_count / sizeof(s16); + + // Lock the queued audio buffer list. + std::lock_guard lock{ audio_buffers_mutex }; + + // Set up a new queued audio buffer. + AudioBuffer& new_buf = audio_buffers.emplace_back(); + new_buf.samples.resize(sample_count); + new_buf.used_samples = 0; + + // Copy the data into the new buffer. + // Swap the audio channels to correct for the address xor caused by endianness handling. + for (size_t i = 0; i < sample_count; i += 2) { + new_buf.samples[i + 0] = audio_data[i + 1]; + new_buf.samples[i + 1] = audio_data[i + 0]; + } +} + +// If there's ever any audio popping, check here first. Some games are very sensitive to +// the remaining sample count and reporting a number that's too high here can lead to issues. +// Reporting a number that's too low can lead to audio lag in some games. +uint32_t Multilibultra::get_remaining_audio_bytes() { + // Calculate the number of samples still in the queued audio buffers + size_t buffered_byte_count = 0; + { + // Lock the queued audio buffer list. + std::lock_guard lock{ audio_buffers_mutex }; + + // Gather the remaining byte count of the next buffer, if any exists. + if (!audio_buffers.empty()) { + buffered_byte_count = audio_buffers.front().remaining_bytes(); + } + } + // Add the number of remaining bytes in the audio data that's been sent to the device. + buffered_byte_count += SDL_GetQueuedAudioSize(audio_device); + + // Add a slight positive scaling bias, which helps audio respond quicker. Remove the bias + // if games have popping issues. + return buffered_byte_count + (buffered_byte_count / 10); +} diff --git a/test/portultra/events.cpp b/test/portultra/events.cpp index e57af26..a82be86 100644 --- a/test/portultra/events.cpp +++ b/test/portultra/events.cpp @@ -210,6 +210,7 @@ uint16_t rspInverseSquareRoots[512]; using RspUcodeFunc = RspExitReason(uint8_t* rdram); extern RspUcodeFunc njpgdspMain; +extern RspUcodeFunc aspMain; // From Ares emulator. For license details, see rsp_vu.h void rsp_constants_init() { @@ -269,7 +270,7 @@ void event_thread_func(uint8_t* rdram, uint8_t* rom) { sp_complete(); dp_complete(); } else if (task_action->task.t.type == M_AUDTASK) { - sp_complete(); + run_rsp_microcode(rdram, &task_action->task, aspMain); } else if (task_action->task.t.type == M_NJPEGTASK) { run_rsp_microcode(rdram, &task_action->task, njpgdspMain); } else { diff --git a/test/portultra/multilibultra.hpp b/test/portultra/multilibultra.hpp index 767562b..7845eb2 100644 --- a/test/portultra/multilibultra.hpp +++ b/test/portultra/multilibultra.hpp @@ -47,6 +47,10 @@ void send_si_message(); uint32_t get_speed_multiplier(); std::chrono::system_clock::time_point get_start(); std::chrono::system_clock::duration time_since_start(); +void init_audio(); +void set_audio_frequency(uint32_t freq); +void queue_audio_buffer(RDRAM_ARG PTR(s16) audio_data, uint32_t byte_count); +uint32_t get_remaining_audio_bytes(); class preemption_guard { public: diff --git a/test/portultra/ultrainit.cpp b/test/portultra/ultrainit.cpp index 4b4d825..a95c06c 100644 --- a/test/portultra/ultrainit.cpp +++ b/test/portultra/ultrainit.cpp @@ -5,6 +5,7 @@ void Multilibultra::preinit(uint8_t* rdram, uint8_t* rom) { Multilibultra::set_main_thread(); Multilibultra::init_events(rdram, rom); Multilibultra::init_timers(rdram); + Multilibultra::init_audio(); Multilibultra::save_init(); } diff --git a/test/rsp/.gitignore b/test/rsp/.gitignore index 06fee25..8341830 100644 --- a/test/rsp/.gitignore +++ b/test/rsp/.gitignore @@ -1 +1,2 @@ njpgdspMain.cpp +aspMain.cpp diff --git a/test/src/ai.cpp b/test/src/ai.cpp index 65954b2..835bb01 100644 --- a/test/src/ai.cpp +++ b/test/src/ai.cpp @@ -1,20 +1,29 @@ #include "recomp.h" +#include +#include +#include "../portultra/ultra64.h" +#include "../portultra/multilibultra.hpp" -extern "C" void osAiSetFrequency_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { - ctx->r2 = ctx->r4; +#define VI_NTSC_CLOCK 48681812 + +extern "C" void osAiSetFrequency_recomp(uint8_t* rdram, recomp_context* ctx) { + uint32_t freq = ctx->r4; + // This makes actual audio frequency more accurate to console, but may not be desirable + //uint32_t dacRate = (uint32_t)(((float)VI_NTSC_CLOCK / freq) + 0.5f); + //freq = VI_NTSC_CLOCK / dacRate; + ctx->r2 = freq; + Multilibultra::set_audio_frequency(freq); } -static uint32_t ai_length = 0; - -extern "C" void osAiSetNextBuffer_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { - ai_length = (uint32_t)ctx->r5; +extern "C" void osAiSetNextBuffer_recomp(uint8_t* rdram, recomp_context* ctx) { + Multilibultra::queue_audio_buffer(rdram, ctx->r4, ctx->r5); ctx->r2 = 0; } -extern "C" void osAiGetLength_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { - ctx->r2 = ai_length; +extern "C" void osAiGetLength_recomp(uint8_t* rdram, recomp_context* ctx) { + ctx->r2 = Multilibultra::get_remaining_audio_bytes(); } -extern "C" void osAiGetStatus_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { - ctx->r2 = 0x80000000; +extern "C" void osAiGetStatus_recomp(uint8_t* rdram, recomp_context* ctx) { + ctx->r2 = 0x00000000; // Pretend the audio DMAs finish instantly } diff --git a/test/src/cont.cpp b/test/src/cont.cpp index c167d04..52283a2 100644 --- a/test/src/cont.cpp +++ b/test/src/cont.cpp @@ -3,7 +3,7 @@ static int max_controllers = 0; -extern "C" void osContInit_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osContInit_recomp(uint8_t* rdram, recomp_context* ctx) { gpr bitpattern = ctx->r5; gpr status = ctx->r6; @@ -26,7 +26,7 @@ extern "C" void osContInit_recomp(uint8_t* restrict rdram, recomp_context* restr ctx->r2 = 0; } -extern "C" void osContStartReadData_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osContStartReadData_recomp(uint8_t* rdram, recomp_context* ctx) { Multilibultra::send_si_message(); } @@ -49,7 +49,7 @@ void release_button(int button) { } -extern "C" void osContGetReadData_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osContGetReadData_recomp(uint8_t* rdram, recomp_context* ctx) { int32_t pad = (int32_t)ctx->r4; if (max_controllers > 0) { @@ -67,11 +67,11 @@ extern "C" void osContGetReadData_recomp(uint8_t* restrict rdram, recomp_context } } -extern "C" void osContStartQuery_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osContStartQuery_recomp(uint8_t * rdram, recomp_context * ctx) { Multilibultra::send_si_message(); } -extern "C" void osContGetQuery_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osContGetQuery_recomp(uint8_t * rdram, recomp_context * ctx) { gpr status = ctx->r4; // Mark controller 0 as present @@ -86,23 +86,23 @@ extern "C" void osContGetQuery_recomp(uint8_t * restrict rdram, recomp_context * } } -extern "C" void osContSetCh_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osContSetCh_recomp(uint8_t* rdram, recomp_context* ctx) { max_controllers = std::min((unsigned int)ctx->r4, 4u); ctx->r2 = 0; } -extern "C" void __osMotorAccess_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void __osMotorAccess_recomp(uint8_t* rdram, recomp_context* ctx) { } -extern "C" void osMotorInit_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osMotorInit_recomp(uint8_t* rdram, recomp_context* ctx) { ; } -extern "C" void osMotorStart_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osMotorStart_recomp(uint8_t* rdram, recomp_context* ctx) { ; } -extern "C" void osMotorStop_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osMotorStop_recomp(uint8_t* rdram, recomp_context* ctx) { ; } diff --git a/test/src/dp.cpp b/test/src/dp.cpp index bb7bb1d..3cf8e43 100644 --- a/test/src/dp.cpp +++ b/test/src/dp.cpp @@ -1,5 +1,5 @@ #include "recomp.h" -extern "C" void osDpSetNextBuffer_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osDpSetNextBuffer_recomp(uint8_t* rdram, recomp_context* ctx) { ; } diff --git a/test/src/eep.cpp b/test/src/eep.cpp index 7c509da..b6b04f9 100644 --- a/test/src/eep.cpp +++ b/test/src/eep.cpp @@ -1,21 +1,21 @@ #include "recomp.h" -extern "C" void osEepromProbe_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osEepromProbe_recomp(uint8_t* rdram, recomp_context* ctx) { ; } -extern "C" void osEepromWrite_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osEepromWrite_recomp(uint8_t* rdram, recomp_context* ctx) { ; } -extern "C" void osEepromLongWrite_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osEepromLongWrite_recomp(uint8_t* rdram, recomp_context* ctx) { ; } -extern "C" void osEepromRead_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osEepromRead_recomp(uint8_t* rdram, recomp_context* ctx) { ; } -extern "C" void osEepromLongRead_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osEepromLongRead_recomp(uint8_t* rdram, recomp_context* ctx) { ; } diff --git a/test/src/math_routines.cpp b/test/src/math_routines.cpp index 1f8b4dc..e0f82aa 100644 --- a/test/src/math_routines.cpp +++ b/test/src/math_routines.cpp @@ -2,7 +2,7 @@ #include "recomp.h" -extern "C" void __udivdi3_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __udivdi3_recomp(uint8_t * rdram, recomp_context * ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); uint64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); uint64_t ret = a / b; @@ -11,7 +11,7 @@ extern "C" void __udivdi3_recomp(uint8_t * restrict rdram, recomp_context * rest ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __divdi3_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __divdi3_recomp(uint8_t * rdram, recomp_context * ctx) { int64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); int64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); int64_t ret = a / b; @@ -20,7 +20,7 @@ extern "C" void __divdi3_recomp(uint8_t * restrict rdram, recomp_context * restr ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __umoddi3_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __umoddi3_recomp(uint8_t * rdram, recomp_context * ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); uint64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); uint64_t ret = a % b; @@ -29,7 +29,7 @@ extern "C" void __umoddi3_recomp(uint8_t * restrict rdram, recomp_context * rest ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __ull_div_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __ull_div_recomp(uint8_t * rdram, recomp_context * ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); uint64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); uint64_t ret = a / b; @@ -38,7 +38,7 @@ extern "C" void __ull_div_recomp(uint8_t * restrict rdram, recomp_context * rest ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __ll_div_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __ll_div_recomp(uint8_t * rdram, recomp_context * ctx) { int64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); int64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); int64_t ret = a / b; @@ -47,7 +47,7 @@ extern "C" void __ll_div_recomp(uint8_t * restrict rdram, recomp_context * restr ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __ll_mul_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __ll_mul_recomp(uint8_t * rdram, recomp_context * ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); uint64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); uint64_t ret = a * b; @@ -56,7 +56,7 @@ extern "C" void __ll_mul_recomp(uint8_t * restrict rdram, recomp_context * restr ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __ull_rem_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __ull_rem_recomp(uint8_t * rdram, recomp_context * ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); uint64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); uint64_t ret = a % b; @@ -65,14 +65,14 @@ extern "C" void __ull_rem_recomp(uint8_t * restrict rdram, recomp_context * rest ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __ull_to_d_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __ull_to_d_recomp(uint8_t * rdram, recomp_context * ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); double ret = (double)a; ctx->f0.d = ret; } -extern "C" void __ull_to_f_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __ull_to_f_recomp(uint8_t * rdram, recomp_context * ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); float ret = (float)a; diff --git a/test/src/pak.cpp b/test/src/pak.cpp index 677dede..777ece6 100644 --- a/test/src/pak.cpp +++ b/test/src/pak.cpp @@ -2,30 +2,30 @@ #include "../portultra/ultra64.h" #include "../portultra/multilibultra.hpp" -extern "C" void osPfsInitPak_recomp(uint8_t * restrict rdram, recomp_context* restrict ctx) { +extern "C" void osPfsInitPak_recomp(uint8_t * rdram, recomp_context* ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } -extern "C" void osPfsFreeBlocks_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osPfsFreeBlocks_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } -extern "C" void osPfsAllocateFile_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osPfsAllocateFile_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } -extern "C" void osPfsDeleteFile_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osPfsDeleteFile_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } -extern "C" void osPfsFileState_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osPfsFileState_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } -extern "C" void osPfsFindFile_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osPfsFindFile_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } -extern "C" void osPfsReadWriteFile_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osPfsReadWriteFile_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } diff --git a/test/src/pi.cpp b/test/src/pi.cpp index 01b73ef..ca1807f 100644 --- a/test/src/pi.cpp +++ b/test/src/pi.cpp @@ -58,7 +58,7 @@ constexpr int32_t cart_handle = 0x80800000; extern std::unique_ptr rom; extern size_t rom_size; -extern "C" void osCartRomInit_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osCartRomInit_recomp(uint8_t* rdram, recomp_context* ctx) { OSPiHandle* handle = TO_PTR(OSPiHandle, cart_handle); handle->type = 0; // cart handle->baseAddress = phys_to_k1(rom_base); @@ -67,7 +67,7 @@ extern "C" void osCartRomInit_recomp(uint8_t* restrict rdram, recomp_context* re ctx->r2 = (gpr)cart_handle; } -extern "C" void osCreatePiManager_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osCreatePiManager_recomp(uint8_t* rdram, recomp_context* ctx) { ; } @@ -83,7 +83,7 @@ void do_rom_read(uint8_t* rdram, gpr ram_address, uint32_t physical_addr, size_t std::array save_buffer; const char save_filename[] = "save.bin"; -void save_write(uint8_t* restrict rdram, gpr rdram_address, uint32_t offset, uint32_t count) { +void save_write(uint8_t* rdram, gpr rdram_address, uint32_t offset, uint32_t count) { for (uint32_t i = 0; i < count; i++) { save_buffer[offset + i] = MEM_B(i, rdram_address); } @@ -97,7 +97,7 @@ void save_write(uint8_t* restrict rdram, gpr rdram_address, uint32_t offset, uin } } -void save_read(uint8_t* restrict rdram, gpr rdram_address, uint32_t offset, uint32_t count) { +void save_read(uint8_t* rdram, gpr rdram_address, uint32_t offset, uint32_t count) { for (size_t i = 0; i < count; i++) { MEM_B(i, rdram_address) = save_buffer[offset + i]; } @@ -113,7 +113,7 @@ void Multilibultra::save_init() { } } -void do_dma(uint8_t* restrict rdram, PTR(OSMesgQueue) mq, gpr rdram_address, uint32_t physical_addr, uint32_t size, uint32_t direction) { +void do_dma(uint8_t* rdram, PTR(OSMesgQueue) mq, gpr rdram_address, uint32_t physical_addr, uint32_t size, uint32_t direction) { // TODO asynchronous transfer // TODO implement unaligned DMA correctly if (direction == 0) { @@ -148,7 +148,7 @@ void do_dma(uint8_t* restrict rdram, PTR(OSMesgQueue) mq, gpr rdram_address, uin } } -extern "C" void osPiStartDma_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osPiStartDma_recomp(uint8_t* rdram, recomp_context* ctx) { uint32_t mb = ctx->r4; uint32_t pri = ctx->r5; uint32_t direction = ctx->r6; @@ -165,7 +165,7 @@ extern "C" void osPiStartDma_recomp(uint8_t* restrict rdram, recomp_context* res ctx->r2 = 0; } -extern "C" void osEPiStartDma_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osEPiStartDma_recomp(uint8_t* rdram, recomp_context* ctx) { OSPiHandle* handle = TO_PTR(OSPiHandle, ctx->r4); OSIoMesg* mb = TO_PTR(OSIoMesg, ctx->r5); uint32_t direction = ctx->r6; @@ -182,7 +182,7 @@ extern "C" void osEPiStartDma_recomp(uint8_t* restrict rdram, recomp_context* re ctx->r2 = 0; } -extern "C" void osEPiReadIo_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osEPiReadIo_recomp(uint8_t * rdram, recomp_context * ctx) { OSPiHandle* handle = TO_PTR(OSPiHandle, ctx->r4); uint32_t devAddr = handle->baseAddress | ctx->r5; gpr dramAddr = ctx->r6; @@ -199,10 +199,10 @@ extern "C" void osEPiReadIo_recomp(uint8_t * restrict rdram, recomp_context * re ctx->r2 = 0; } -extern "C" void osPiGetStatus_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osPiGetStatus_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 0; } -extern "C" void osPiRawStartDma_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osPiRawStartDma_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 0; } diff --git a/test/src/portultra_translation.cpp b/test/src/portultra_translation.cpp index ca2bc33..f2f9df2 100644 --- a/test/src/portultra_translation.cpp +++ b/test/src/portultra_translation.cpp @@ -3,125 +3,125 @@ #include "../portultra/multilibultra.hpp" #include "recomp.h" -extern "C" void osInitialize_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osInitialize_recomp(uint8_t * rdram, recomp_context * ctx) { osInitialize(); } -extern "C" void __osInitialize_common_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __osInitialize_common_recomp(uint8_t * rdram, recomp_context * ctx) { osInitialize(); } -extern "C" void osCreateThread_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osCreateThread_recomp(uint8_t* rdram, recomp_context* ctx) { osCreateThread(rdram, (int32_t)ctx->r4, (OSId)ctx->r5, (int32_t)ctx->r6, (int32_t)ctx->r7, (int32_t)MEM_W(0x10, ctx->r29), (OSPri)MEM_W(0x14, ctx->r29)); } -extern "C" void osStartThread_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osStartThread_recomp(uint8_t* rdram, recomp_context* ctx) { osStartThread(rdram, (int32_t)ctx->r4); } -extern "C" void osStopThread_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osStopThread_recomp(uint8_t * rdram, recomp_context * ctx) { osStopThread(rdram, (int32_t)ctx->r4); } -extern "C" void osDestroyThread_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osDestroyThread_recomp(uint8_t * rdram, recomp_context * ctx) { osDestroyThread(rdram, (int32_t)ctx->r4); } -extern "C" void osSetThreadPri_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osSetThreadPri_recomp(uint8_t* rdram, recomp_context* ctx) { osSetThreadPri(rdram, (int32_t)ctx->r4, (OSPri)ctx->r5); } -extern "C" void osGetThreadPri_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osGetThreadPri_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = osGetThreadPri(rdram, (int32_t)ctx->r4); } -extern "C" void osGetThreadId_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osGetThreadId_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = osGetThreadId(rdram, (int32_t)ctx->r4); } -extern "C" void osCreateMesgQueue_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osCreateMesgQueue_recomp(uint8_t* rdram, recomp_context* ctx) { osCreateMesgQueue(rdram, (int32_t)ctx->r4, (int32_t)ctx->r5, (s32)ctx->r6); } -extern "C" void osRecvMesg_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osRecvMesg_recomp(uint8_t* rdram, recomp_context* ctx) { ctx->r2 = osRecvMesg(rdram, (int32_t)ctx->r4, (int32_t)ctx->r5, (s32)ctx->r6); } -extern "C" void osSendMesg_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osSendMesg_recomp(uint8_t* rdram, recomp_context* ctx) { ctx->r2 = osSendMesg(rdram, (int32_t)ctx->r4, (OSMesg)ctx->r5, (s32)ctx->r6); } -extern "C" void osJamMesg_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osJamMesg_recomp(uint8_t* rdram, recomp_context* ctx) { ctx->r2 = osJamMesg(rdram, (int32_t)ctx->r4, (OSMesg)ctx->r5, (s32)ctx->r6); } -extern "C" void osSetEventMesg_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osSetEventMesg_recomp(uint8_t* rdram, recomp_context* ctx) { osSetEventMesg(rdram, (OSEvent)ctx->r4, (int32_t)ctx->r5, (OSMesg)ctx->r6); } -extern "C" void osViSetEvent_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osViSetEvent_recomp(uint8_t * rdram, recomp_context * ctx) { osViSetEvent(rdram, (int32_t)ctx->r4, (OSMesg)ctx->r5, (u32)ctx->r6); } -extern "C" void osGetCount_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osGetCount_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = osGetCount(); } -extern "C" void osGetTime_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osGetTime_recomp(uint8_t * rdram, recomp_context * ctx) { uint64_t total_count = osGetTime(); ctx->r2 = (int32_t)(total_count >> 32); ctx->r3 = (int32_t)(total_count >> 0); } -extern "C" void osSetTimer_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osSetTimer_recomp(uint8_t * rdram, recomp_context * ctx) { uint64_t countdown = ((uint64_t)(ctx->r6) << 32) | ((ctx->r7) & 0xFFFFFFFFu); uint64_t interval = load_doubleword(rdram, ctx->r29, 0x10); ctx->r2 = osSetTimer(rdram, (int32_t)ctx->r4, countdown, interval, (int32_t)MEM_W(0x18, ctx->r29), (OSMesg)MEM_W(0x1C, ctx->r29)); } -extern "C" void osStopTimer_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osStopTimer_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = osStopTimer(rdram, (int32_t)ctx->r4); } -extern "C" void osVirtualToPhysical_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osVirtualToPhysical_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = osVirtualToPhysical((int32_t)ctx->r2); } -extern "C" void osInvalDCache_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osInvalDCache_recomp(uint8_t * rdram, recomp_context * ctx) { ; } -extern "C" void osInvalICache_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osInvalICache_recomp(uint8_t * rdram, recomp_context * ctx) { ; } -extern "C" void osWritebackDCache_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osWritebackDCache_recomp(uint8_t * rdram, recomp_context * ctx) { ; } -extern "C" void osWritebackDCacheAll_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osWritebackDCacheAll_recomp(uint8_t * rdram, recomp_context * ctx) { ; } -extern "C" void osSetIntMask_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osSetIntMask_recomp(uint8_t * rdram, recomp_context * ctx) { ; } -extern "C" void __osDisableInt_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __osDisableInt_recomp(uint8_t * rdram, recomp_context * ctx) { ; } -extern "C" void __osRestoreInt_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __osRestoreInt_recomp(uint8_t * rdram, recomp_context * ctx) { ; } -extern "C" void __osSetFpcCsr_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __osSetFpcCsr_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 0; } // For the Mario Party games (not working) -//extern "C" void longjmp_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +//extern "C" void longjmp_recomp(uint8_t * rdram, recomp_context * ctx) { // RecompJmpBuf* buf = TO_PTR(RecompJmpBuf, ctx->r4); // // // Check if this is a buffer that was set up with setjmp @@ -148,7 +148,7 @@ extern "C" void __osSetFpcCsr_recomp(uint8_t * restrict rdram, recomp_context * //} // //#undef setjmp_recomp -//extern "C" void setjmp_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +//extern "C" void setjmp_recomp(uint8_t * rdram, recomp_context * ctx) { // fprintf(stderr, "Program called setjmp_recomp\n"); // std::quick_exit(EXIT_FAILURE); //} diff --git a/test/src/print.cpp b/test/src/print.cpp index d271d64..c6e227b 100644 --- a/test/src/print.cpp +++ b/test/src/print.cpp @@ -3,31 +3,31 @@ #include "recomp.h" #include "euc-jp.h" -extern "C" void __checkHardware_msp_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __checkHardware_msp_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 0; } -extern "C" void __checkHardware_kmc_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __checkHardware_kmc_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 0; } -extern "C" void __checkHardware_isv_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __checkHardware_isv_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 0; } -extern "C" void __osInitialize_msp_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __osInitialize_msp_recomp(uint8_t * rdram, recomp_context * ctx) { } -extern "C" void __osInitialize_kmc_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __osInitialize_kmc_recomp(uint8_t * rdram, recomp_context * ctx) { } -extern "C" void __osInitialize_isv_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __osInitialize_isv_recomp(uint8_t * rdram, recomp_context * ctx) { } -extern "C" void isPrintfInit_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void isPrintfInit_recomp(uint8_t * rdram, recomp_context * ctx) { } -extern "C" void __osRdbSend_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void __osRdbSend_recomp(uint8_t * rdram, recomp_context * ctx) { gpr buf = ctx->r4; size_t size = ctx->r5; u32 type = (u32)ctx->r6; @@ -43,7 +43,7 @@ extern "C" void __osRdbSend_recomp(uint8_t * restrict rdram, recomp_context * re ctx->r2 = size; } -extern "C" void is_proutSyncPrintf_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void is_proutSyncPrintf_recomp(uint8_t * rdram, recomp_context * ctx) { // Buffering to speed up print performance static std::vector print_buffer; @@ -51,17 +51,17 @@ extern "C" void is_proutSyncPrintf_recomp(uint8_t * restrict rdram, recomp_conte size_t size = ctx->r6; for (size_t i = 0; i < size; i++) { - // Add the new character to the buffer - char cur_char = MEM_B(i, buf); + // Add the new character to the buffer + char cur_char = MEM_B(i, buf); - // If the new character is a newline, flush the buffer - if (cur_char == '\n') { - std::string utf8_str = Encoding::decode_eucjp(std::string_view{ print_buffer.data(), print_buffer.size() }); - puts(utf8_str.c_str()); - print_buffer.clear(); - } else { - print_buffer.push_back(cur_char); - } + // If the new character is a newline, flush the buffer + if (cur_char == '\n') { + std::string utf8_str = Encoding::decode_eucjp(std::string_view{ print_buffer.data(), print_buffer.size() }); + puts(utf8_str.c_str()); + print_buffer.clear(); + } else { + print_buffer.push_back(cur_char); + } } //fwrite(to_print.get(), size, 1, stdout); diff --git a/test/src/recomp.cpp b/test/src/recomp.cpp index 8d57579..957311c 100644 --- a/test/src/recomp.cpp +++ b/test/src/recomp.cpp @@ -21,7 +21,7 @@ constexpr uint32_t byteswap(uint32_t val) { } #endif -extern "C" void _bzero(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void _bzero(uint8_t* rdram, recomp_context* ctx) { gpr start_addr = ctx->r4; gpr size = ctx->r5; @@ -30,7 +30,7 @@ extern "C" void _bzero(uint8_t* restrict rdram, recomp_context* restrict ctx) { } } -extern "C" void osGetMemSize_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) { +extern "C" void osGetMemSize_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 8 * 1024 * 1024; } @@ -58,7 +58,7 @@ std::unique_ptr rom; size_t rom_size; // Recomp generation functions -extern "C" void recomp_entrypoint(uint8_t * restrict rdram, recomp_context * restrict ctx); +extern "C" void recomp_entrypoint(uint8_t * rdram, recomp_context * ctx); gpr get_entrypoint_address(); const char* get_rom_name(); void init_overlays(); diff --git a/test/src/rsp_vu.h b/test/src/rsp_vu.h index 8ec9b3b..d60e62f 100644 --- a/test/src/rsp_vu.h +++ b/test/src/rsp_vu.h @@ -91,7 +91,7 @@ struct RSP { auto set(u32 index, bool value) -> bool { return u16(index) = 0 - value, value; } //vu-registers.cpp - auto operator()(u32 index) const -> r128; + inline auto operator()(u32 index) const -> r128; }; using cr128 = const r128; @@ -109,91 +109,91 @@ struct RSP { static constexpr r128 zero{0}; static constexpr r128 invert{(uint64_t)-1, (uint64_t)-1}; - auto accumulatorGet(u32 index) const -> u64; - auto accumulatorSet(u32 index, u64 value) -> void; - auto accumulatorSaturate(u32 index, bool slice, u16 negative, u16 positive) const -> u16; + inline auto accumulatorGet(u32 index) const -> u64; + inline auto accumulatorSet(u32 index, u64 value) -> void; + inline auto accumulatorSaturate(u32 index, bool slice, u16 negative, u16 positive) const -> u16; - auto CFC2(r32& rt, u8 rd) -> void; - auto CTC2(cr32& rt, u8 rd) -> void; - template auto LBV(r128& vt, cr32& rs, s8 imm) -> void; - template auto LDV(r128& vt, cr32& rs, s8 imm) -> void; - template auto LFV(r128& vt, cr32& rs, s8 imm) -> void; - template auto LHV(r128& vt, cr32& rs, s8 imm) -> void; - template auto LLV(r128& vt, cr32& rs, s8 imm) -> void; - template auto LPV(r128& vt, cr32& rs, s8 imm) -> void; - template auto LQV(r128& vt, cr32& rs, s8 imm) -> void; - template auto LRV(r128& vt, cr32& rs, s8 imm) -> void; - template auto LSV(r128& vt, cr32& rs, s8 imm) -> void; - template auto LTV(u8 vt, cr32& rs, s8 imm) -> void; - template auto LUV(r128& vt, cr32& rs, s8 imm) -> void; - template auto LWV(r128& vt, cr32& rs, s8 imm) -> void; - template auto MFC2(r32& rt, cr128& vs) -> void; - template auto MTC2(cr32& rt, r128& vs) -> void; - template auto SBV(cr128& vt, cr32& rs, s8 imm) -> void; - template auto SDV(cr128& vt, cr32& rs, s8 imm) -> void; - template auto SFV(cr128& vt, cr32& rs, s8 imm) -> void; - template auto SHV(cr128& vt, cr32& rs, s8 imm) -> void; - template auto SLV(cr128& vt, cr32& rs, s8 imm) -> void; - template auto SPV(cr128& vt, cr32& rs, s8 imm) -> void; - template auto SQV(cr128& vt, cr32& rs, s8 imm) -> void; - template auto SRV(cr128& vt, cr32& rs, s8 imm) -> void; - template auto SSV(cr128& vt, cr32& rs, s8 imm) -> void; - template auto STV(u8 vt, cr32& rs, s8 imm) -> void; - template auto SUV(cr128& vt, cr32& rs, s8 imm) -> void; - template auto SWV(cr128& vt, cr32& rs, s8 imm) -> void; - template auto VABS(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VADD(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VADDC(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VAND(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VCH(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VCL(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VCR(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VEQ(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VGE(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VLT(r128& vd, cr128& vs, cr128& vt) -> void; + inline auto CFC2(r32& rt, u8 rd) -> void; + inline auto CTC2(cr32& rt, u8 rd) -> void; + template inline auto LBV(r128& vt, cr32& rs, s8 imm) -> void; + template inline auto LDV(r128& vt, cr32& rs, s8 imm) -> void; + template inline auto LFV(r128& vt, cr32& rs, s8 imm) -> void; + template inline auto LHV(r128& vt, cr32& rs, s8 imm) -> void; + template inline auto LLV(r128& vt, cr32& rs, s8 imm) -> void; + template inline auto LPV(r128& vt, cr32& rs, s8 imm) -> void; + template inline auto LQV(r128& vt, cr32& rs, s8 imm) -> void; + template inline auto LRV(r128& vt, cr32& rs, s8 imm) -> void; + template inline auto LSV(r128& vt, cr32& rs, s8 imm) -> void; + template inline auto LTV(u8 vt, cr32& rs, s8 imm) -> void; + template inline auto LUV(r128& vt, cr32& rs, s8 imm) -> void; + template inline auto LWV(r128& vt, cr32& rs, s8 imm) -> void; + template inline auto MFC2(r32& rt, cr128& vs) -> void; + template inline auto MTC2(cr32& rt, r128& vs) -> void; + template inline auto SBV(cr128& vt, cr32& rs, s8 imm) -> void; + template inline auto SDV(cr128& vt, cr32& rs, s8 imm) -> void; + template inline auto SFV(cr128& vt, cr32& rs, s8 imm) -> void; + template inline auto SHV(cr128& vt, cr32& rs, s8 imm) -> void; + template inline auto SLV(cr128& vt, cr32& rs, s8 imm) -> void; + template inline auto SPV(cr128& vt, cr32& rs, s8 imm) -> void; + template inline auto SQV(cr128& vt, cr32& rs, s8 imm) -> void; + template inline auto SRV(cr128& vt, cr32& rs, s8 imm) -> void; + template inline auto SSV(cr128& vt, cr32& rs, s8 imm) -> void; + template inline auto STV(u8 vt, cr32& rs, s8 imm) -> void; + template inline auto SUV(cr128& vt, cr32& rs, s8 imm) -> void; + template inline auto SWV(cr128& vt, cr32& rs, s8 imm) -> void; + template inline auto VABS(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VADD(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VADDC(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VAND(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VCH(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VCL(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VCR(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VEQ(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VGE(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VLT(r128& vd, cr128& vs, cr128& vt) -> void; template - auto VMACF(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VMACF(r128& vd, cr128& vs, cr128& vt) -> void { VMACF<0, e>(vd, vs, vt); } - template auto VMACU(r128& vd, cr128& vs, cr128& vt) -> void { VMACF<1, e>(vd, vs, vt); } - auto VMACQ(r128& vd) -> void; - template auto VMADH(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VMADL(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VMADM(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VMADN(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VMOV(r128& vd, u8 de, cr128& vt) -> void; - template auto VMRG(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VMUDH(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VMUDL(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VMUDM(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VMUDN(r128& vd, cr128& vs, cr128& vt) -> void; + inline auto VMACF(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VMACF(r128& vd, cr128& vs, cr128& vt) -> void { VMACF<0, e>(vd, vs, vt); } + template inline auto VMACU(r128& vd, cr128& vs, cr128& vt) -> void { VMACF<1, e>(vd, vs, vt); } + inline auto VMACQ(r128& vd) -> void; + template inline auto VMADH(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VMADL(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VMADM(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VMADN(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VMOV(r128& vd, u8 de, cr128& vt) -> void; + template inline auto VMRG(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VMUDH(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VMUDL(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VMUDM(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VMUDN(r128& vd, cr128& vs, cr128& vt) -> void; template - auto VMULF(r128& rd, cr128& vs, cr128& vt) -> void; - template auto VMULF(r128& rd, cr128& vs, cr128& vt) -> void { VMULF<0, e>(rd, vs, vt); } - template auto VMULU(r128& rd, cr128& vs, cr128& vt) -> void { VMULF<1, e>(rd, vs, vt); } - template auto VMULQ(r128& rd, cr128& vs, cr128& vt) -> void; - template auto VNAND(r128& rd, cr128& vs, cr128& vt) -> void; - template auto VNE(r128& vd, cr128& vs, cr128& vt) -> void; - auto VNOP() -> void; - template auto VNOR(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VNXOR(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VOR(r128& vd, cr128& vs, cr128& vt) -> void; + inline auto VMULF(r128& rd, cr128& vs, cr128& vt) -> void; + template inline auto VMULF(r128& rd, cr128& vs, cr128& vt) -> void { VMULF<0, e>(rd, vs, vt); } + template inline auto VMULU(r128& rd, cr128& vs, cr128& vt) -> void { VMULF<1, e>(rd, vs, vt); } + template inline auto VMULQ(r128& rd, cr128& vs, cr128& vt) -> void; + template inline auto VNAND(r128& rd, cr128& vs, cr128& vt) -> void; + template inline auto VNE(r128& vd, cr128& vs, cr128& vt) -> void; + inline auto VNOP() -> void; + template inline auto VNOR(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VNXOR(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VOR(r128& vd, cr128& vs, cr128& vt) -> void; template - auto VRCP(r128& vd, u8 de, cr128& vt) -> void; - template auto VRCP(r128& vd, u8 de, cr128& vt) -> void { VRCP<0, e>(vd, de, vt); } - template auto VRCPL(r128& vd, u8 de, cr128& vt) -> void { VRCP<1, e>(vd, de, vt); } - template auto VRCPH(r128& vd, u8 de, cr128& vt) -> void; + inline auto VRCP(r128& vd, u8 de, cr128& vt) -> void; + template inline auto VRCP(r128& vd, u8 de, cr128& vt) -> void { VRCP<0, e>(vd, de, vt); } + template inline auto VRCPL(r128& vd, u8 de, cr128& vt) -> void { VRCP<1, e>(vd, de, vt); } + template inline auto VRCPH(r128& vd, u8 de, cr128& vt) -> void; template - auto VRND(r128& vd, u8 vs, cr128& vt) -> void; - template auto VRNDN(r128& vd, u8 vs, cr128& vt) -> void { VRND<0, e>(vd, vs, vt); } - template auto VRNDP(r128& vd, u8 vs, cr128& vt) -> void { VRND<1, e>(vd, vs, vt); } + inline auto VRND(r128& vd, u8 vs, cr128& vt) -> void; + template inline auto VRNDN(r128& vd, u8 vs, cr128& vt) -> void { VRND<0, e>(vd, vs, vt); } + template inline auto VRNDP(r128& vd, u8 vs, cr128& vt) -> void { VRND<1, e>(vd, vs, vt); } template - auto VRSQ(r128& vd, u8 de, cr128& vt) -> void; - template auto VRSQ(r128& vd, u8 de, cr128& vt) -> void { VRSQ<0, e>(vd, de, vt); } - template auto VRSQL(r128& vd, u8 de, cr128& vt) -> void { VRSQ<1, e>(vd, de, vt); } - template auto VRSQH(r128& vd, u8 de, cr128& vt) -> void; - template auto VSAR(r128& vd, cr128& vs) -> void; - template auto VSUB(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VSUBC(r128& vd, cr128& vs, cr128& vt) -> void; - template auto VXOR(r128& rd, cr128& vs, cr128& vt) -> void; - template auto VZERO(r128& rd, cr128& vs, cr128& vt) -> void; + inline auto VRSQ(r128& vd, u8 de, cr128& vt) -> void; + template inline auto VRSQ(r128& vd, u8 de, cr128& vt) -> void { VRSQ<0, e>(vd, de, vt); } + template inline auto VRSQL(r128& vd, u8 de, cr128& vt) -> void { VRSQ<1, e>(vd, de, vt); } + template inline auto VRSQH(r128& vd, u8 de, cr128& vt) -> void; + template inline auto VSAR(r128& vd, cr128& vs) -> void; + template inline auto VSUB(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VSUBC(r128& vd, cr128& vs, cr128& vt) -> void; + template inline auto VXOR(r128& rd, cr128& vs, cr128& vt) -> void; + template inline auto VZERO(r128& rd, cr128& vs, cr128& vt) -> void; }; diff --git a/test/src/sp.cpp b/test/src/sp.cpp index 3289667..d443948 100644 --- a/test/src/sp.cpp +++ b/test/src/sp.cpp @@ -3,13 +3,13 @@ #include "../portultra/multilibultra.hpp" #include "recomp.h" -extern "C" void osSpTaskLoad_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osSpTaskLoad_recomp(uint8_t* rdram, recomp_context* ctx) { // Nothing to do here } bool dump_frame = false; -extern "C" void osSpTaskStartGo_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osSpTaskStartGo_recomp(uint8_t* rdram, recomp_context* ctx) { //printf("[sp] osSpTaskStartGo(0x%08X)\n", (uint32_t)ctx->r4); OSTask* task = TO_PTR(OSTask, ctx->r4); if (task->t.type == M_GFXTASK) { @@ -35,15 +35,15 @@ extern "C" void osSpTaskStartGo_recomp(uint8_t* restrict rdram, recomp_context* Multilibultra::submit_rsp_task(rdram, ctx->r4); } -extern "C" void osSpTaskYield_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osSpTaskYield_recomp(uint8_t* rdram, recomp_context* ctx) { // Ignore yield requests (acts as if the task completed before it received the yield request) } -extern "C" void osSpTaskYielded_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osSpTaskYielded_recomp(uint8_t* rdram, recomp_context* ctx) { // Task yield requests are ignored, so always return 0 as tasks will never be yielded ctx->r2 = 0; } -extern "C" void __osSpSetPc_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void __osSpSetPc_recomp(uint8_t* rdram, recomp_context* ctx) { assert(false); } diff --git a/test/src/vi.cpp b/test/src/vi.cpp index 979b0ce..0b1f714 100644 --- a/test/src/vi.cpp +++ b/test/src/vi.cpp @@ -1,38 +1,38 @@ #include "../portultra/multilibultra.hpp" #include "recomp.h" -extern "C" void osViSetYScale_recomp(uint8_t* restrict rdram, recomp_context * restrict ctx) { +extern "C" void osViSetYScale_recomp(uint8_t* rdram, recomp_context * ctx) { ; } -extern "C" void osViSetXScale_recomp(uint8_t* restrict rdram, recomp_context * restrict ctx) { +extern "C" void osViSetXScale_recomp(uint8_t* rdram, recomp_context * ctx) { ; } -extern "C" void osCreateViManager_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osCreateViManager_recomp(uint8_t* rdram, recomp_context* ctx) { ; } -extern "C" void osViBlack_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osViBlack_recomp(uint8_t* rdram, recomp_context* ctx) { ; } -extern "C" void osViSetSpecialFeatures_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osViSetSpecialFeatures_recomp(uint8_t* rdram, recomp_context* ctx) { ; } -extern "C" void osViGetCurrentFramebuffer_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osViGetCurrentFramebuffer_recomp(uint8_t* rdram, recomp_context* ctx) { ctx->r2 = (gpr)(int32_t)osViGetCurrentFramebuffer(); } -extern "C" void osViGetNextFramebuffer_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osViGetNextFramebuffer_recomp(uint8_t* rdram, recomp_context* ctx) { ctx->r2 = (gpr)(int32_t)osViGetNextFramebuffer(); } -extern "C" void osViSwapBuffer_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osViSwapBuffer_recomp(uint8_t* rdram, recomp_context* ctx) { osViSwapBuffer(rdram, (int32_t)ctx->r4); } -extern "C" void osViSetMode_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) { +extern "C" void osViSetMode_recomp(uint8_t* rdram, recomp_context* ctx) { ; }