mirror of
https://github.com/N64Recomp/N64Recomp.git
synced 2025-05-29 06:43:16 +00:00
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:
parent
b94fe6f5fb
commit
39b67c8468
20 changed files with 449 additions and 113 deletions
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue