mirror of
https://github.com/N64Recomp/N64ModernRuntime.git
synced 2025-12-29 11:12:32 +00:00
62 lines
1.9 KiB
C++
62 lines
1.9 KiB
C++
#include <cassert>
|
|
#include <cstring>
|
|
#include <cinttypes>
|
|
|
|
#include "rsp.hpp"
|
|
|
|
static recomp::rsp::callbacks_t rsp_callbacks {};
|
|
|
|
void recomp::rsp::set_callbacks(const callbacks_t& callbacks) {
|
|
rsp_callbacks = callbacks;
|
|
}
|
|
|
|
uint8_t dmem[0x1000];
|
|
uint16_t rspReciprocals[512];
|
|
uint16_t rspInverseSquareRoots[512];
|
|
|
|
// From Ares emulator. For license details, see rsp_vu.h
|
|
void recomp::rsp::constants_init() {
|
|
rspReciprocals[0] = u16(~0);
|
|
for (u16 index = 1; index < 512; index++) {
|
|
u64 a = index + 512;
|
|
u64 b = (u64(1) << 34) / a;
|
|
rspReciprocals[index] = u16((b + 1) >> 8);
|
|
}
|
|
|
|
for (u16 index = 0; index < 512; index++) {
|
|
u64 a = (index + 512) >> ((index % 2 == 1) ? 1 : 0);
|
|
u64 b = 1 << 17;
|
|
//find the largest b where b < 1.0 / sqrt(a)
|
|
while (a * (b + 1) * (b + 1) < (u64(1) << 44)) b++;
|
|
rspInverseSquareRoots[index] = u16(b >> 1);
|
|
}
|
|
}
|
|
|
|
// Runs a recompiled RSP microcode
|
|
bool recomp::rsp::run_task(uint8_t* rdram, const OSTask* task) {
|
|
assert(rsp_callbacks.get_rsp_microcode != nullptr);
|
|
RspUcodeFunc* ucode_func = rsp_callbacks.get_rsp_microcode(task);
|
|
|
|
if (ucode_func == nullptr) {
|
|
fprintf(stderr, "No registered RSP ucode for %" PRIu32 " (returned `nullptr`)\n", task->t.type);
|
|
return false;
|
|
}
|
|
|
|
// Load the OSTask into DMEM
|
|
memcpy(&dmem[0xFC0], task, sizeof(OSTask));
|
|
|
|
// Load the ucode data into DMEM
|
|
dma_rdram_to_dmem(rdram, 0x0000, task->t.ucode_data, 0xF80 - 1);
|
|
|
|
// Run the ucode
|
|
RspExitReason exit_reason = ucode_func(rdram, task->t.ucode);
|
|
|
|
// Ensure that the ucode exited correctly
|
|
if (exit_reason != RspExitReason::Broke) {
|
|
fprintf(stderr, "RSP ucode %" PRIu32 " exited unexpectedly. exit_reason: %i\n", task->t.type, static_cast<int>(exit_reason));
|
|
assert(exit_reason == RspExitReason::Broke);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|