From cc2d991972b9287b699794045d7f38d30dcf9cf4 Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Fri, 5 Jul 2024 21:27:27 -0400 Subject: [PATCH] Made rdram size an argument in recomp::start, reorganized some PI address constants --- librecomp/include/librecomp/addresses.hpp | 21 +++++++++ librecomp/include/librecomp/game.hpp | 1 + librecomp/src/flash.cpp | 5 +- librecomp/src/pi.cpp | 46 ++++++++----------- librecomp/src/recomp.cpp | 5 +- .../include/ultramodern/ultramodern.hpp | 5 -- 6 files changed, 48 insertions(+), 35 deletions(-) create mode 100644 librecomp/include/librecomp/addresses.hpp diff --git a/librecomp/include/librecomp/addresses.hpp b/librecomp/include/librecomp/addresses.hpp new file mode 100644 index 0000000..6285104 --- /dev/null +++ b/librecomp/include/librecomp/addresses.hpp @@ -0,0 +1,21 @@ +#ifndef __RECOMP_ADDRESSES_HPP__ +#define __RECOMP_ADDRESSES_HPP__ + +#include +#include "ultramodern/ultra64.h" + +namespace recomp { + // We need a place in rdram to hold the PI handles, so pick an address in extended rdram + constexpr int32_t cart_handle = 0x80800000; + constexpr int32_t drive_handle = (int32_t)(cart_handle + sizeof(OSPiHandle)); + constexpr int32_t flash_handle = (int32_t)(drive_handle + sizeof(OSPiHandle)); + + // Flashram occupies the same physical address as sram, but that issue is avoided because libultra exposes + // a high-level interface for flashram. Because that high-level interface is reimplemented, low level accesses + // that involve physical addresses don't need to be handled for flashram. + constexpr uint32_t sram_base = 0x08000000; + constexpr uint32_t rom_base = 0x10000000; + constexpr uint32_t drive_base = 0x06000000; +} + +#endif diff --git a/librecomp/include/librecomp/game.hpp b/librecomp/include/librecomp/game.hpp index 4c2b304..cdb2218 100644 --- a/librecomp/include/librecomp/game.hpp +++ b/librecomp/include/librecomp/game.hpp @@ -49,6 +49,7 @@ namespace recomp { * It must be called only once and it must be called before `ultramodern::preinit`. */ void start( + uint32_t rdram_size, ultramodern::renderer::WindowHandle window_handle, const recomp::rsp::callbacks_t& rsp_callbacks, const ultramodern::renderer::callbacks_t& renderer_callbacks, diff --git a/librecomp/src/flash.cpp b/librecomp/src/flash.cpp index 43407e8..4bbb79e 100644 --- a/librecomp/src/flash.cpp +++ b/librecomp/src/flash.cpp @@ -2,7 +2,8 @@ #include #include #include -#include "recomp.h" +#include "librecomp/recomp.h" +#include "librecomp/addresses.hpp" // TODO move this out into ultramodern code @@ -21,7 +22,7 @@ void save_clear(uint32_t start, uint32_t size, char value); std::array write_buffer; extern "C" void osFlashInit_recomp(uint8_t * rdram, recomp_context * ctx) { - ctx->r2 = ultramodern::flash_handle; + ctx->r2 = recomp::flash_handle; } extern "C" void osFlashReadStatus_recomp(uint8_t * rdram, recomp_context * ctx) { diff --git a/librecomp/src/pi.cpp b/librecomp/src/pi.cpp index 855211c..96e178f 100644 --- a/librecomp/src/pi.cpp +++ b/librecomp/src/pi.cpp @@ -4,9 +4,10 @@ #include #include #include -#include "recomp.h" -#include "game.hpp" -#include "files.hpp" +#include "librecomp/recomp.h" +#include "librecomp/addresses.hpp" +#include "librecomp/game.hpp" +#include "librecomp/files.hpp" #include #include @@ -20,13 +21,6 @@ void recomp::set_rom_contents(std::vector&& new_rom) { rom = std::move(new_rom); } -// Flashram occupies the same physical address as sram, but that issue is avoided because libultra exposes -// a high-level interface for flashram. Because that high-level interface is reimplemented, low level accesses -// that involve physical addresses don't need to be handled for flashram. -constexpr uint32_t sram_base = 0x08000000; -constexpr uint32_t rom_base = 0x10000000; -constexpr uint32_t drive_base = 0x06000000; - constexpr uint32_t k1_to_phys(uint32_t addr) { return addr & 0x1FFFFFFF; } @@ -42,21 +36,21 @@ extern "C" void __osPiRelAccess_recomp(uint8_t* rdram, recomp_context* ctx) { } extern "C" void osCartRomInit_recomp(uint8_t* rdram, recomp_context* ctx) { - OSPiHandle* handle = TO_PTR(OSPiHandle, ultramodern::cart_handle); + OSPiHandle* handle = TO_PTR(OSPiHandle, recomp::cart_handle); handle->type = 0; // cart - handle->baseAddress = phys_to_k1(rom_base); + handle->baseAddress = phys_to_k1(recomp::rom_base); handle->domain = 0; - ctx->r2 = (gpr)ultramodern::cart_handle; + ctx->r2 = (gpr)recomp::cart_handle; } extern "C" void osDriveRomInit_recomp(uint8_t * rdram, recomp_context * ctx) { - OSPiHandle* handle = TO_PTR(OSPiHandle, ultramodern::drive_handle); + OSPiHandle* handle = TO_PTR(OSPiHandle, recomp::drive_handle); handle->type = 1; // bulk - handle->baseAddress = phys_to_k1(drive_base); + handle->baseAddress = phys_to_k1(recomp::drive_base); handle->domain = 0; - ctx->r2 = (gpr)ultramodern::drive_handle; + ctx->r2 = (gpr)recomp::drive_handle; } extern "C" void osCreatePiManager_recomp(uint8_t* rdram, recomp_context* ctx) { @@ -70,7 +64,7 @@ void recomp::do_rom_read(uint8_t* rdram, gpr ram_address, uint32_t physical_addr assert((physical_addr & 0x1) == 0 && "Only PI DMA from aligned ROM addresses is currently supported"); assert((ram_address & 0x7) == 0 && "Only PI DMA to aligned RDRAM addresses is currently supported"); assert((num_bytes & 0x1) == 0 && "Only PI DMA with aligned sizes is currently supported"); - uint8_t* rom_addr = rom.data() + physical_addr - rom_base; + uint8_t* rom_addr = rom.data() + physical_addr - recomp::rom_base; for (size_t i = 0; i < num_bytes; i++) { MEM_B(i, ram_address) = *rom_addr; rom_addr++; @@ -80,7 +74,7 @@ void recomp::do_rom_read(uint8_t* rdram, gpr ram_address, uint32_t physical_addr void recomp::do_rom_pio(uint8_t* rdram, gpr ram_address, uint32_t physical_addr) { assert((physical_addr & 0x3) == 0 && "PIO not 4-byte aligned in device, currently unsupported"); assert((ram_address & 0x3) == 0 && "PIO not 4-byte aligned in RDRAM, currently unsupported"); - uint8_t* rom_addr = rom.data() + physical_addr - rom_base; + uint8_t* rom_addr = rom.data() + physical_addr - recomp::rom_base; MEM_B(0, ram_address) = *rom_addr++; MEM_B(1, ram_address) = *rom_addr++; MEM_B(2, ram_address) = *rom_addr++; @@ -213,15 +207,15 @@ void do_dma(RDRAM_ARG PTR(OSMesgQueue) mq, gpr rdram_address, uint32_t physical_ // TODO asynchronous transfer // TODO implement unaligned DMA correctly if (direction == 0) { - if (physical_addr >= rom_base) { + if (physical_addr >= recomp::rom_base) { // read cart rom recomp::do_rom_read(rdram, rdram_address, physical_addr, size); // Send a message to the mq to indicate that the transfer completed osSendMesg(rdram, mq, 0, OS_MESG_NOBLOCK); - } else if (physical_addr >= sram_base) { + } else if (physical_addr >= recomp::sram_base) { // read sram - save_read(rdram, rdram_address, physical_addr - sram_base, size); + save_read(rdram, rdram_address, physical_addr - recomp::sram_base, size); // Send a message to the mq to indicate that the transfer completed osSendMesg(rdram, mq, 0, OS_MESG_NOBLOCK); @@ -229,12 +223,12 @@ void do_dma(RDRAM_ARG PTR(OSMesgQueue) mq, gpr rdram_address, uint32_t physical_ fprintf(stderr, "[WARN] PI DMA read from unknown region, phys address 0x%08X\n", physical_addr); } } else { - if (physical_addr >= rom_base) { + if (physical_addr >= recomp::rom_base) { // write cart rom throw std::runtime_error("ROM DMA write unimplemented"); - } else if (physical_addr >= sram_base) { + } else if (physical_addr >= recomp::sram_base) { // write sram - save_write(rdram, rdram_address, physical_addr - sram_base, size); + save_write(rdram, rdram_address, physical_addr - recomp::sram_base, size); // Send a message to the mq to indicate that the transfer completed osSendMesg(rdram, mq, 0, OS_MESG_NOBLOCK); @@ -248,7 +242,7 @@ extern "C" void osPiStartDma_recomp(RDRAM_ARG recomp_context* ctx) { uint32_t mb = ctx->r4; uint32_t pri = ctx->r5; uint32_t direction = ctx->r6; - uint32_t devAddr = ctx->r7 | rom_base; + uint32_t devAddr = ctx->r7 | recomp::rom_base; gpr dramAddr = MEM_W(0x10, ctx->r29); uint32_t size = MEM_W(0x14, ctx->r29); PTR(OSMesgQueue) mq = MEM_W(0x18, ctx->r29); @@ -284,7 +278,7 @@ extern "C" void osEPiReadIo_recomp(RDRAM_ARG recomp_context * ctx) { gpr dramAddr = ctx->r6; uint32_t physical_addr = k1_to_phys(devAddr); - if (physical_addr > rom_base) { + if (physical_addr > recomp::rom_base) { // cart rom recomp::do_rom_pio(PASS_RDRAM dramAddr, physical_addr); } else { diff --git a/librecomp/src/recomp.cpp b/librecomp/src/recomp.cpp index 75f8a05..2726894 100644 --- a/librecomp/src/recomp.cpp +++ b/librecomp/src/recomp.cpp @@ -374,6 +374,7 @@ void ultramodern::quit() { } void recomp::start( + uint32_t rdram_size, ultramodern::renderer::WindowHandle window_handle, const recomp::rsp::callbacks_t& rsp_callbacks, const ultramodern::renderer::callbacks_t& renderer_callbacks, @@ -413,8 +414,8 @@ void recomp::start( } // Allocate rdram_buffer - std::unique_ptr rdram_buffer = std::make_unique(ultramodern::rdram_size); - std::memset(rdram_buffer.get(), 0, ultramodern::rdram_size); + std::unique_ptr rdram_buffer = std::make_unique(rdram_size); + std::memset(rdram_buffer.get(), 0, rdram_size); std::thread game_thread{[](ultramodern::renderer::WindowHandle window_handle, uint8_t* rdram) { debug_printf("[Recomp] Starting\n"); diff --git a/ultramodern/include/ultramodern/ultramodern.hpp b/ultramodern/include/ultramodern/ultramodern.hpp index b144eaa..07019d4 100644 --- a/ultramodern/include/ultramodern/ultramodern.hpp +++ b/ultramodern/include/ultramodern/ultramodern.hpp @@ -27,11 +27,6 @@ struct UltraThreadContext { namespace ultramodern { -// We need a place in rdram to hold the PI handles, so pick an address in extended rdram -constexpr uint32_t rdram_size = 1024 * 1024 * 16; // 16MB to give extra room for anything custom -constexpr int32_t cart_handle = 0x80800000; -constexpr int32_t drive_handle = (int32_t)(cart_handle + sizeof(OSPiHandle)); -constexpr int32_t flash_handle = (int32_t)(drive_handle + sizeof(OSPiHandle)); constexpr uint32_t save_size = 1024 * 1024 / 8; // Maximum save size, 1Mbit for flash // Initialization.