mirror of
https://github.com/N64Recomp/N64ModernRuntime.git
synced 2026-05-10 19:01:53 +00:00
Made rdram size an argument in recomp::start, reorganized some PI address constants
This commit is contained in:
parent
71cd05807f
commit
cc2d991972
6 changed files with 48 additions and 35 deletions
21
librecomp/include/librecomp/addresses.hpp
Normal file
21
librecomp/include/librecomp/addresses.hpp
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef __RECOMP_ADDRESSES_HPP__
|
||||
#define __RECOMP_ADDRESSES_HPP__
|
||||
|
||||
#include <cstdint>
|
||||
#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
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
#include <cassert>
|
||||
#include <ultramodern/ultra64.h>
|
||||
#include <ultramodern/ultramodern.hpp>
|
||||
#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<char, page_size> 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) {
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@
|
|||
#include <cstring>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#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 <ultramodern/ultra64.h>
|
||||
#include <ultramodern/ultramodern.hpp>
|
||||
|
||||
|
|
@ -20,13 +21,6 @@ void recomp::set_rom_contents(std::vector<uint8_t>&& 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 {
|
||||
|
|
|
|||
|
|
@ -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<uint8_t[]> rdram_buffer = std::make_unique<uint8_t[]>(ultramodern::rdram_size);
|
||||
std::memset(rdram_buffer.get(), 0, ultramodern::rdram_size);
|
||||
std::unique_ptr<uint8_t[]> rdram_buffer = std::make_unique<uint8_t[]>(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");
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue