mirror of
https://github.com/N64Recomp/N64Recomp.git
synced 2025-05-28 22:33:15 +00:00
Created solution for testing output
This commit is contained in:
parent
5d9ea96abc
commit
b94fe6f5fb
24 changed files with 9225 additions and 2 deletions
17
test/src/ai.cpp
Normal file
17
test/src/ai.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "recomp.h"
|
||||
|
||||
extern "C" void osAiSetFrequency_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osAiSetNextBuffer_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osAiGetLength_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osAiGetStatus_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
25
test/src/cont.cpp
Normal file
25
test/src/cont.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include "recomp.h"
|
||||
|
||||
extern "C" void osContInit_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osContStartReadData_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osContGetReadData_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osMotorInit_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osMotorStart_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osMotorStop_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
5
test/src/dp.cpp
Normal file
5
test/src/dp.cpp
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include "recomp.h"
|
||||
|
||||
extern "C" void osDpSetNextBuffer_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
21
test/src/eep.cpp
Normal file
21
test/src/eep.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include "recomp.h"
|
||||
|
||||
extern "C" void osEepromProbe_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osEepromWrite_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osEepromLongWrite_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osEepromRead_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osEepromLongRead_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
65
test/src/misc_ultra.cpp
Normal file
65
test/src/misc_ultra.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include "recomp.h"
|
||||
|
||||
extern uint64_t start_time;
|
||||
|
||||
|
||||
extern "C" void osVirtualToPhysical_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
uint32_t virtual_addr = ctx->r4;
|
||||
// TODO handle TLB mappings
|
||||
ctx->r2 = virtual_addr - 0x80000000;
|
||||
}
|
||||
|
||||
extern "C" void osInvalDCache_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osInvalICache_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osWritebackDCache_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osWritebackDCacheAll_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void __osDisableInt_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void __osRestoreInt_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
48
test/src/pi.cpp
Normal file
48
test/src/pi.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
#include <memory>
|
||||
#include "recomp.h"
|
||||
#include "../portultra/ultra64.h"
|
||||
|
||||
extern std::unique_ptr<uint8_t[]> rom;
|
||||
extern size_t rom_size;
|
||||
|
||||
extern "C" void osCartRomInit_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osCreatePiManager_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
constexpr uint32_t rom_base = 0xB0000000;
|
||||
|
||||
extern "C" void osPiStartDma_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
uint32_t mb = ctx->r4;
|
||||
uint32_t pri = ctx->r5;
|
||||
uint32_t direction = ctx->r6;
|
||||
uint32_t devAddr = ctx->r7;
|
||||
uint32_t dramAddr = MEM_W(0x10, ctx->r29);
|
||||
uint32_t size = MEM_W(0x14, ctx->r29);
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
// Send a message to the mq to indicate that the transfer completed
|
||||
osSendMesg(rdram, mq_, 0, OS_MESG_NOBLOCK);
|
||||
}
|
||||
|
||||
extern "C" void osEPiStartDma_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osPiGetStatus_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
ctx->r2 = 0;
|
||||
}
|
||||
|
||||
extern "C" void osPiRawStartDma_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
;
|
||||
}
|
41
test/src/portultra_translation.cpp
Normal file
41
test/src/portultra_translation.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include "../portultra/ultra64.h"
|
||||
#include "recomp.h"
|
||||
|
||||
extern "C" void osInitialize_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
osInitialize();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
extern "C" void osSetThreadPri_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
osSetThreadPri(rdram, (uint32_t)ctx->r4, (OSPri)ctx->r5);
|
||||
}
|
||||
|
||||
extern "C" void osCreateMesgQueue_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
osCreateMesgQueue(rdram, (uint32_t)ctx->r4, (uint32_t)ctx->r5, (s32)ctx->r6);
|
||||
}
|
||||
|
||||
extern "C" void osRecvMesg_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
ctx->r2 = osRecvMesg(rdram, (uint32_t)ctx->r4, (uint32_t)ctx->r5, (s32)ctx->r6);
|
||||
}
|
||||
|
||||
extern "C" void osSendMesg_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
ctx->r2 = osSendMesg(rdram, (uint32_t)ctx->r4, (OSMesg)ctx->r5, (s32)ctx->r6);
|
||||
}
|
||||
|
||||
extern "C" void osJamMesg_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
ctx->r2 = osJamMesg(rdram, (uint32_t)ctx->r4, (OSMesg)ctx->r5, (s32)ctx->r6);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
169
test/src/recomp.cpp
Normal file
169
test/src/recomp.cpp
Normal file
|
@ -0,0 +1,169 @@
|
|||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <cmath>
|
||||
#include <unordered_map>
|
||||
#include <fstream>
|
||||
#include "recomp.h"
|
||||
#include "../portultra/multilibultra.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
inline uint32_t byteswap(uint32_t val) {
|
||||
return _byteswap_ulong(val);
|
||||
}
|
||||
#else
|
||||
constexpr uint32_t byteswap(uint32_t val) {
|
||||
return __builtin_bswap32(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;
|
||||
|
||||
std::unordered_map<uint32_t, recomp_func_t*> func_map{};
|
||||
|
||||
extern "C" recomp_func_t* get_function(uint32_t addr) {
|
||||
auto func_find = func_map.find(addr);
|
||||
if (func_find == func_map.end()) {
|
||||
fprintf(stderr, "Failed to find function at 0x%08X\n", addr);
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
return func_find->second;
|
||||
}
|
||||
|
||||
extern "C" void bzero(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
uint32_t start_addr = ctx->r4;
|
||||
uint32_t size = ctx->r5;
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
MEM_B(start_addr, i) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void switch_error(const char* func, uint32_t vram, uint32_t jtbl) {
|
||||
printf("Switch-case out of bounds in %s at 0x%08X for jump table at 0x%08X\n", func, vram, jtbl);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
extern "C" void do_break(uint32_t vram) {
|
||||
printf("Encountered break at original vram 0x%08X\n", vram);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void run_thread_function(uint8_t* rdram, uint32_t addr, uint32_t sp, uint32_t arg) {
|
||||
recomp_context ctx{};
|
||||
ctx.r29 = sp;
|
||||
recomp_func_t* func = get_function(addr);
|
||||
func(rdram, &ctx);
|
||||
}
|
||||
|
||||
extern "C" void game_init(uint8_t* restrict rdram, recomp_context* restrict ctx);
|
||||
|
||||
std::unique_ptr<uint8_t[]> rom;
|
||||
size_t rom_size;
|
||||
|
||||
uint64_t start_time;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s [baserom]\n", argv[0]);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
{
|
||||
std::basic_ifstream<uint8_t> rom_file{ argv[1], std::ios::binary };
|
||||
|
||||
size_t iobuf_size = 0x100000;
|
||||
std::unique_ptr<uint8_t[]> iobuf = std::make_unique<uint8_t[]>(iobuf_size);
|
||||
rom_file.rdbuf()->pubsetbuf(iobuf.get(), iobuf_size);
|
||||
|
||||
if (!rom_file) {
|
||||
fprintf(stderr, "Failed to open rom: %s\n", argv[1]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
rom_file.seekg(0, std::ios::end);
|
||||
rom_size = rom_file.tellg();
|
||||
rom_file.seekg(0, std::ios::beg);
|
||||
|
||||
rom = std::make_unique<uint8_t[]>(rom_size);
|
||||
|
||||
rom_file.read(rom.get(), rom_size);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Get entrypoint from ROM
|
||||
// TODO fix this for other IPL3 versions
|
||||
uint32_t entrypoint = *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);
|
||||
std::memset(rdram_buffer.get(), 0, 8 * 1024 * 1024);
|
||||
recomp_context context{};
|
||||
|
||||
// Initial 1MB DMA
|
||||
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++) {
|
||||
func_map[funcs[i].first] = funcs[i].second;
|
||||
}
|
||||
|
||||
// TODO move this to a more appropriate place
|
||||
#ifdef _WIN32
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
|
||||
start_time = ((uint64_t)ft.dwHighDateTime << 32) + ft.dwLowDateTime;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set up stack pointer
|
||||
context.r29 = 0x803FFFF0u;
|
||||
|
||||
// Initialize variables normally set by IPL3
|
||||
constexpr uint32_t osTvType = 0x80000300;
|
||||
constexpr uint32_t osRomType = 0x80000304;
|
||||
constexpr uint32_t osRomBase = 0x80000308;
|
||||
constexpr uint32_t osResetType = 0x8000030c;
|
||||
constexpr uint32_t osCicId = 0x80000310;
|
||||
constexpr uint32_t osVersion = 0x80000314;
|
||||
constexpr uint32_t osMemSize = 0x80000318;
|
||||
constexpr uint32_t osAppNMIBuffer = 0x8000031c;
|
||||
uint8_t *rdram = rdram_buffer.get();
|
||||
MEM_W(osTvType, 0) = 1; // NTSC
|
||||
MEM_W(osRomBase, 0) = 0xB0000000u; // standard rom base
|
||||
MEM_W(osResetType, 0) = 0; // cold reset
|
||||
MEM_W(osMemSize, 0) = 8 * 1024 * 1024; // 8MB
|
||||
|
||||
// Clear bss
|
||||
// TODO run the entrypoint instead
|
||||
memset(rdram_buffer.get() + 0XAF860, 0, 0xC00A0u - 0XAF860);
|
||||
|
||||
printf("[Recomp] Starting\n");
|
||||
|
||||
Multilibultra::set_main_thread();
|
||||
|
||||
game_init(rdram_buffer.get(), &context);
|
||||
|
||||
printf("[Recomp] Quitting\n");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
22
test/src/sp.cpp
Normal file
22
test/src/sp.cpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include <cstdio>
|
||||
#include "recomp.h"
|
||||
|
||||
extern "C" void osSpTaskLoad_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osSpTaskStartGo_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
printf("[sp] osSpTaskStartGo(0x%08X)\n", (uint32_t)ctx->r4);
|
||||
}
|
||||
|
||||
extern "C" void osSpTaskYield_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osSpTaskYielded_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void __osSpSetPc_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
33
test/src/vi.cpp
Normal file
33
test/src/vi.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "recomp.h"
|
||||
|
||||
extern "C" void osCreateViManager_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osViBlack_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osViSetSpecialFeatures_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osViGetCurrentFramebuffer_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osViGetNextFramebuffer_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osViSwapBuffer_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
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