From 2ebeffee891211ee95bbd85a9e6b07cf2a9fcc6a Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Mon, 6 Feb 2023 18:17:31 -0500 Subject: [PATCH] Implemented sram saving --- test/portultra/multilibultra.hpp | 1 + test/portultra/ultrainit.cpp | 1 + test/src/pi.cpp | 54 ++++++++++++++++++++++++++------ 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/test/portultra/multilibultra.hpp b/test/portultra/multilibultra.hpp index e782159..767562b 100644 --- a/test/portultra/multilibultra.hpp +++ b/test/portultra/multilibultra.hpp @@ -18,6 +18,7 @@ struct UltraThreadContext { namespace Multilibultra { void preinit(uint8_t* rdram, uint8_t* rom); +void save_init(); void native_init(); void init_scheduler(); void init_events(uint8_t* rdram, uint8_t* rom); diff --git a/test/portultra/ultrainit.cpp b/test/portultra/ultrainit.cpp index 2668ab6..4b4d825 100644 --- a/test/portultra/ultrainit.cpp +++ b/test/portultra/ultrainit.cpp @@ -5,6 +5,7 @@ void Multilibultra::preinit(uint8_t* rdram, uint8_t* rom) { Multilibultra::set_main_thread(); Multilibultra::init_events(rdram, rom); Multilibultra::init_timers(rdram); + Multilibultra::save_init(); } extern "C" void osInitialize() { diff --git a/test/src/pi.cpp b/test/src/pi.cpp index d069ae4..01b73ef 100644 --- a/test/src/pi.cpp +++ b/test/src/pi.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include "recomp.h" #include "../portultra/ultra64.h" #include "../portultra/multilibultra.hpp" @@ -78,36 +80,70 @@ void do_rom_read(uint8_t* rdram, gpr ram_address, uint32_t physical_addr, size_t } } +std::array save_buffer; +const char save_filename[] = "save.bin"; + +void save_write(uint8_t* restrict rdram, gpr rdram_address, uint32_t offset, uint32_t count) { + for (uint32_t i = 0; i < count; i++) { + save_buffer[offset + i] = MEM_B(i, rdram_address); + } + std::ofstream save_file{ save_filename, std::ios_base::binary }; + + if (save_file.good()) { + save_file.write(save_buffer.data(), save_buffer.size()); + } else { + fprintf(stderr, "Failed to save!\n"); + std::exit(EXIT_FAILURE); + } +} + +void save_read(uint8_t* restrict rdram, gpr rdram_address, uint32_t offset, uint32_t count) { + for (size_t i = 0; i < count; i++) { + MEM_B(i, rdram_address) = save_buffer[offset + i]; + } +} + +void Multilibultra::save_init() { + std::ifstream save_file{ save_filename, std::ios_base::binary }; + + if (save_file.good()) { + save_file.read(save_buffer.data(), save_buffer.size()); + } else { + save_buffer.fill(0); + } +} + void do_dma(uint8_t* restrict rdram, PTR(OSMesgQueue) mq, gpr rdram_address, uint32_t physical_addr, uint32_t size, uint32_t direction) { // TODO asynchronous transfer // TODO implement unaligned DMA correctly if (direction == 0) { - if (physical_addr > rom_base) { + if (physical_addr >= rom_base) { // read cart rom 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 { + } else if (physical_addr >= sram_base) { // read sram - printf("[WARN] SRAM read unimplemented, returning zeroes\n"); - for (uint32_t i = 0; i < size; i++) { - MEM_B(i, rdram_address) = 0; - } + save_read(rdram, rdram_address, physical_addr - sram_base, size); // Send a message to the mq to indicate that the transfer completed osSendMesg(rdram, mq, 0, OS_MESG_NOBLOCK); + } else { + 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 >= rom_base) { // write cart rom throw std::runtime_error("ROM DMA write unimplemented"); - } else { + } else if (physical_addr >= sram_base) { // write sram - printf("[WARN] SRAM write unimplemented, ignoring data\n"); + save_write(rdram, rdram_address, physical_addr - sram_base, size); // Send a message to the mq to indicate that the transfer completed osSendMesg(rdram, mq, 0, OS_MESG_NOBLOCK); + } else { + fprintf(stderr, "[WARN] PI DMA write to unknown region, phys address 0x%08X\n", physical_addr); } } }