From 407b6e547c9f0ed6e9dbc8d682d83ceb9b8cb9a5 Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Tue, 2 Apr 2024 22:16:31 -0400 Subject: [PATCH] Fixed stutter caused by saving by adding a sleep in the saving loop, fixed bug with timers not resuming due to a negative remaining duration --- patches/patches.h | 4 ++ patches/save_patches.c | 86 ++++++++++++++++++++++++++++++++++++++++++ patches/syms.ld | 4 ++ ultramodern/timer.cpp | 3 +- 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 patches/save_patches.c diff --git a/patches/patches.h b/patches/patches.h index c3a0c5b..2ac4219 100644 --- a/patches/patches.h +++ b/patches/patches.h @@ -6,8 +6,12 @@ #define osRecvMesg osRecvMesg_recomp #define osSendMesg osSendMesg_recomp #define osViGetCurrentFramebuffer osViGetCurrentFramebuffer_recomp +#define osFlashWriteArray osFlashWriteArray_recomp +#define osFlashWriteBuffer osFlashWriteBuffer_recomp +#define osWritebackDCache osWritebackDCache_recomp #define sinf __sinf_recomp #define cosf __cosf_recomp +#define bzero bzero_recomp #define gRandFloat sRandFloat #include "global.h" #include "rt64_extended_gbi.h" diff --git a/patches/save_patches.c b/patches/save_patches.c new file mode 100644 index 0000000..fac569f --- /dev/null +++ b/patches/save_patches.c @@ -0,0 +1,86 @@ +#include "patches.h" +#include "sys_flashrom.h" +#include "PR/os_internal_flash.h" +#include "fault.h" + +extern OSMesgQueue sFlashromMesgQueue; +s32 SysFlashrom_IsInit(void); +void Sleep_Msec(u32 ms); + +// @recomp Patched to not wait a hardcoded amount of time for the save to complete. +void Sram_UpdateWriteToFlashDefault(SramContext* sramCtx) { + if (sramCtx->status == 2) { + if (SysFlashrom_IsBusy() != 0) { // if task running + if (SysFlashrom_AwaitResult() == 0) { // wait for task done + // task success + sramCtx->status = 4; + } else { + // task failure + sramCtx->status = 4; + } + } + } else if (sramCtx->status == 4) { + // @recomp Patched to check status instead of using a hardcoded wait. + recomp_printf("Status 4\n"); + sramCtx->status = 0; + } +} + +// @recomp Patched to not wait a hardcoded amount of time for the save to complete. +void Sram_UpdateWriteToFlashOwlSave(SramContext* sramCtx) { + if (sramCtx->status == 7) { + if (SysFlashrom_IsBusy() != 0) { // Is task running + if (SysFlashrom_AwaitResult() == 0) { // Wait for task done + SysFlashrom_WriteDataAsync(sramCtx->saveBuf, sramCtx->curPage + 0x80, sramCtx->numPages); + sramCtx->status = 8; + } else { + SysFlashrom_WriteDataAsync(sramCtx->saveBuf, sramCtx->curPage + 0x80, sramCtx->numPages); + sramCtx->status = 8; + } + } + } else if (sramCtx->status == 8) { + if (SysFlashrom_IsBusy() != 0) { // Is task running + if (SysFlashrom_AwaitResult() == 0) { // Wait for task done + sramCtx->status = 4; + } else { + sramCtx->status = 4; + } + } + } else if (sramCtx->status == 4) { + // @recomp Patched to check status instead of using a hardcoded wait. + sramCtx->status = 0; + bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); + gSaveContext.save.isOwlSave = false; + gSaveContext.save.saveInfo.checksum = 0; + // flash read to buffer then copy to save context + SysFlashrom_ReadData(sramCtx->saveBuf, sramCtx->curPage, sramCtx->numPages); + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, offsetof(SaveContext, fileNum)); + } +} + +// @recomp Patched to add a pause so that other threads can execute in the meantime. +s32 SysFlashrom_ExecWrite(void* addr, u32 pageNum, u32 pageCount) { + OSIoMesg msg; + s32 result; + u32 i; + + if (!SysFlashrom_IsInit()) { + return -1; + } + // Ensure the page is always aligned to a sector boundary. + if ((pageNum % FLASH_BLOCK_SIZE) != 0) { + Fault_AddHungupAndCrash("../sys_flashrom.c", 275); + } + osWritebackDCache(addr, pageCount * FLASH_BLOCK_SIZE); + for (i = 0; i < pageCount; i++) { + // @recomp Pause shortly to allow other threads to work. + Sleep_Msec(5); + osFlashWriteBuffer(&msg, OS_MESG_PRI_NORMAL, (u8*)addr + i * FLASH_BLOCK_SIZE, &sFlashromMesgQueue); + osRecvMesg(&sFlashromMesgQueue, NULL, OS_MESG_BLOCK); + result = osFlashWriteArray(i + pageNum); + if (result != 0) { + return result; + } + } + return 0; +} diff --git a/patches/syms.ld b/patches/syms.ld index e51375e..b1e22c1 100644 --- a/patches/syms.ld +++ b/patches/syms.ld @@ -27,3 +27,7 @@ recomp_set_current_frame_poll_id = 0x8F00004C; recomp_time_us = 0x8F000050; recomp_measure_latency = 0x8F000054; osViGetCurrentFramebuffer_recomp = 0x8F000058; +bzero_recomp = 0x8F00005C; +osFlashWriteArray_recomp = 0x8F000060; +osFlashWriteBuffer_recomp = 0x8F000064; +osWritebackDCache_recomp = 0x8F000068; diff --git a/ultramodern/timer.cpp b/ultramodern/timer.cpp index 06c4e69..d71e068 100644 --- a/ultramodern/timer.cpp +++ b/ultramodern/timer.cpp @@ -112,10 +112,9 @@ void timer_thread(RDRAM_ARG1) { // Determine how long to wait to reach the timer's timestamp auto wait_duration = ticks_to_timepoint(cur_timer->timestamp) - std::chrono::system_clock::now(); - auto wait_us = std::chrono::duration_cast(wait_duration); // Wait for either the duration to complete or a new action to come through - if (timer_context.action_queue.wait_dequeue_timed(cur_action, wait_duration)) { + if (wait_duration.count() >= 0 && timer_context.action_queue.wait_dequeue_timed(cur_action, wait_duration)) { // Timer was interrupted by a new action // Add the current timer back to the queue (done first in case the action is to remove this timer) active_timers.insert(cur_timer_);