Implemented SP, DP, and SI events

Inject a thread pause into infinite loops to allow the idle thread to
yield for event processing
Removed all preemption usage from the scheduler
This commit is contained in:
Mr-Wiseguy 2022-11-18 16:12:39 -05:00
parent b94fe6f5fb
commit 39b67c8468
20 changed files with 449 additions and 113 deletions

View file

@ -1,3 +1,4 @@
#include "../portultra/multilibultra.hpp"
#include "recomp.h"
extern "C" void osContInit_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
@ -5,7 +6,7 @@ extern "C" void osContInit_recomp(uint8_t* restrict rdram, recomp_context* restr
}
extern "C" void osContStartReadData_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
;
Multilibultra::send_si_message();
}
extern "C" void osContGetReadData_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {

View file

@ -30,28 +30,6 @@ extern "C" void osWritebackDCacheAll_recomp(uint8_t* restrict rdram, recomp_cont
;
}
// Ticks per second
constexpr uint32_t counter_rate = 46'875'000;
extern "C" void osGetCount_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
// TODO move this to a more appropriate place
int32_t count = 0;
#ifdef _WIN32
SYSTEMTIME st;
FILETIME ft;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &ft);
uint64_t cur_time = ((uint64_t)ft.dwHighDateTime << 32) + ft.dwLowDateTime;
uint64_t delta_100ns = cur_time - start_time;
count = (delta_100ns * counter_rate) / (1'000'000'000 / 100);
#endif
ctx->r2 = count;
;
}
extern "C" void osSetIntMask_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
;
}

View file

@ -1,6 +1,7 @@
#include <memory>
#include "recomp.h"
#include "../portultra/ultra64.h"
#include "../portultra/multilibultra.hpp"
extern std::unique_ptr<uint8_t[]> rom;
extern size_t rom_size;
@ -15,6 +16,15 @@ extern "C" void osCreatePiManager_recomp(uint8_t* restrict rdram, recomp_context
constexpr uint32_t rom_base = 0xB0000000;
void do_rom_read(uint8_t* rdram, uint32_t ram_address, uint32_t dev_address, size_t num_bytes) {
// TODO use word copies when possible
uint8_t* rom_addr = rom.get() + (dev_address | rom_base) - rom_base;
for (size_t i = 0; i < num_bytes; i++) {
MEM_B(i, ram_address) = *rom_addr;
rom_addr++;
}
}
extern "C" void osPiStartDma_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
uint32_t mb = ctx->r4;
uint32_t pri = ctx->r5;
@ -25,11 +35,13 @@ extern "C" void osPiStartDma_recomp(uint8_t* restrict rdram, recomp_context* res
uint32_t mq_ = MEM_W(0x18, ctx->r29);
OSMesgQueue* mq = TO_PTR(OSMesgQueue, mq_);
printf("[pi] DMA from 0x%08X into 0x%08X of size 0x%08X\n", devAddr, dramAddr, size);
debug_printf("[pi] DMA from 0x%08X into 0x%08X of size 0x%08X\n", devAddr, dramAddr, size);
// TODO asynchronous transfer (will require preemption in the scheduler)
// TODO this won't handle unaligned DMA
memcpy(rdram + (dramAddr & 0x3FFFFFF), rom.get() + (devAddr | rom_base) - rom_base, size);
do_rom_read(rdram, dramAddr, devAddr, size);
//memcpy(rdram + (dramAddr & 0x3FFFFFF), rom.get() + (devAddr | rom_base) - rom_base, num_bytes);
// Send a message to the mq to indicate that the transfer completed
osSendMesg(rdram, mq_, 0, OS_MESG_NOBLOCK);

View file

@ -6,13 +6,11 @@ extern "C" void osInitialize_recomp(uint8_t * restrict rdram, recomp_context * r
}
extern "C" void osCreateThread_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
//printf("Creating thread 0x%08X\n", (uint32_t)ctx->r4);
osCreateThread(rdram, (uint32_t)ctx->r4, (OSId)ctx->r5, (uint32_t)ctx->r6, (uint32_t)ctx->r7,
(uint32_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) {
//printf("Starting thread 0x%08X\n", (uint32_t)ctx->r4);
osStartThread(rdram, (uint32_t)ctx->r4);
}
@ -39,3 +37,17 @@ extern "C" void osJamMesg_recomp(uint8_t* restrict rdram, recomp_context* restri
extern "C" void osSetEventMesg_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
osSetEventMesg(rdram, (OSEvent)ctx->r4, (uint32_t)ctx->r5, (OSMesg)ctx->r6);
}
extern "C" void osViSetEvent_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
osViSetEvent(rdram, (uint32_t)ctx->r4, (OSMesg)ctx->r5, (u32)ctx->r6);
}
extern "C" void osGetCount_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
ctx->r2 = osGetCount();
}
extern "C" void osGetTime_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
uint64_t total_count = osGetTime();
ctx->r2 = (uint32_t)(total_count >> 32);
ctx->r3 = (int32_t)(total_count >> 0);
}

View file

@ -20,11 +20,6 @@ constexpr uint32_t byteswap(uint32_t val) {
}
#endif
void test_func(uint8_t* restrict rdram, recomp_context* restrict ctx) {
printf("in test_func\n");
exit(EXIT_FAILURE);
}
extern std::pair<uint32_t, recomp_func_t*> funcs[];
extern const size_t num_funcs;
@ -61,11 +56,13 @@ extern "C" void do_break(uint32_t vram) {
void run_thread_function(uint8_t* rdram, uint32_t addr, uint32_t sp, uint32_t arg) {
recomp_context ctx{};
ctx.r29 = sp;
ctx.r4 = arg;
recomp_func_t* func = get_function(addr);
func(rdram, &ctx);
}
extern "C" void game_init(uint8_t* restrict rdram, recomp_context* restrict ctx);
void do_rom_read(uint8_t* rdram, uint32_t ram_address, uint32_t dev_address, size_t num_bytes);
std::unique_ptr<uint8_t[]> rom;
size_t rom_size;
@ -100,15 +97,15 @@ int main(int argc, char **argv) {
}
// Byteswap the rom
for (size_t rom_addr = 0; rom_addr < rom_size; rom_addr += 4) {
uint32_t word = *reinterpret_cast<uint32_t*>(rom.get() + rom_addr);
word = byteswap(word);
*reinterpret_cast<uint32_t*>(rom.get() + rom_addr) = word;
}
//for (size_t rom_addr = 0; rom_addr < rom_size; rom_addr += 4) {
// uint32_t word = *reinterpret_cast<uint32_t*>(rom.get() + rom_addr);
// word = byteswap(word);
// *reinterpret_cast<uint32_t*>(rom.get() + rom_addr) = word;
//}
// Get entrypoint from ROM
// TODO fix this for other IPL3 versions
uint32_t entrypoint = *reinterpret_cast<uint32_t*>(rom.get() + 0x8);
uint32_t entrypoint = byteswap(*reinterpret_cast<uint32_t*>(rom.get() + 0x8));
// Allocate rdram_buffer
std::unique_ptr<uint8_t[]> rdram_buffer = std::make_unique<uint8_t[]>(8 * 1024 * 1024);
@ -116,7 +113,8 @@ int main(int argc, char **argv) {
recomp_context context{};
// Initial 1MB DMA
std::copy_n(rom.get() + 0x1000, 0x100000, rdram_buffer.get() + entrypoint - 0x80000000);
do_rom_read(rdram_buffer.get(), entrypoint, 0x1000, 0x100000);
//std::copy_n(rom.get() + 0x1000, 0x100000, rdram_buffer.get() + entrypoint - 0x80000000);
// Initialize function address map
for (size_t i = 0; i < num_funcs; i++) {
@ -157,13 +155,13 @@ int main(int argc, char **argv) {
// TODO run the entrypoint instead
memset(rdram_buffer.get() + 0XAF860, 0, 0xC00A0u - 0XAF860);
printf("[Recomp] Starting\n");
debug_printf("[Recomp] Starting\n");
Multilibultra::set_main_thread();
Multilibultra::preinit(rdram_buffer.get());
game_init(rdram_buffer.get(), &context);
printf("[Recomp] Quitting\n");
debug_printf("[Recomp] Quitting\n");
return EXIT_SUCCESS;
}

View file

@ -1,4 +1,5 @@
#include <cstdio>
#include "../portultra/multilibultra.hpp"
#include "recomp.h"
extern "C" void osSpTaskLoad_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
@ -6,7 +7,14 @@ extern "C" void osSpTaskLoad_recomp(uint8_t* restrict rdram, recomp_context* res
}
extern "C" void osSpTaskStartGo_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
printf("[sp] osSpTaskStartGo(0x%08X)\n", (uint32_t)ctx->r4);
//printf("[sp] osSpTaskStartGo(0x%08X)\n", (uint32_t)ctx->r4);
OSTask* task = TO_PTR(OSTask, ctx->r4);
if (task->t.type == M_GFXTASK) {
printf("[sp] Gfx task: %08X\n", (uint32_t)ctx->r4);
} else if (task->t.type == M_AUDTASK) {
printf("[sp] Audio task: %08X\n", (uint32_t)ctx->r4);
}
Multilibultra::submit_rsp_task(rdram, ctx->r4);
}
extern "C" void osSpTaskYield_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {

View file

@ -27,7 +27,3 @@ extern "C" void osViSwapBuffer_recomp(uint8_t* restrict rdram, recomp_context* r
extern "C" void osViSetMode_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
;
}
extern "C" void osViSetEvent_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
;
}