From ac0a180a14093d60e36e55e35d6755dfe1d735c6 Mon Sep 17 00:00:00 2001 From: SlaveOfIDO Date: Thu, 22 Oct 2026 22:32:29 +0200 Subject: [PATCH 1/2] implement proper mips interrupt handling --- ultramodern/include/ultramodern/renderer_context.hpp | 11 +++++++++++ ultramodern/src/events.cpp | 5 +++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ultramodern/include/ultramodern/renderer_context.hpp b/ultramodern/include/ultramodern/renderer_context.hpp index d60c4ecb..50385912 100644 --- a/ultramodern/include/ultramodern/renderer_context.hpp +++ b/ultramodern/include/ultramodern/renderer_context.hpp @@ -72,6 +72,11 @@ namespace ultramodern { GraphicsDeviceNotFound }; + struct MipsInterrupts { + bool dp = false; + bool sp = false; + }; + class RendererContext { public: virtual ~RendererContext() = default; @@ -79,6 +84,11 @@ namespace ultramodern { virtual bool valid() = 0; virtual SetupResult get_setup_result() const { return setup_result; } virtual GraphicsApi get_chosen_api() const { return chosen_api; } + virtual MipsInterrupts get_and_clear_mips_interrupts() { + MipsInterrupts result = mips_interrupts; + mips_interrupts = {}; + return result; + } virtual bool update_config(const GraphicsConfig& old_config, const GraphicsConfig& new_config) = 0; @@ -93,6 +103,7 @@ namespace ultramodern { protected: SetupResult setup_result; GraphicsApi chosen_api; + MipsInterrupts mips_interrupts; }; struct callbacks_t { diff --git a/ultramodern/src/events.cpp b/ultramodern/src/events.cpp index 17d7a47c..548ccc52 100644 --- a/ultramodern/src/events.cpp +++ b/ultramodern/src/events.cpp @@ -368,7 +368,6 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re // start another graphics task until the RDP is also complete. Games usually preserve the RSP inputs until the RDP // is finished as well, so sending this early shouldn't be an issue in most cases. // If this causes issues then the logic can be replaced with responding to yield requests. - sp_complete(); ultramodern::measure_input_latency(); PTR(u64) displaylist = task_action->task.t.data_ptr; @@ -378,7 +377,9 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re renderer_context->send_dl(&task_action->task); [[maybe_unused]] auto renderer_end = std::chrono::high_resolution_clock::now(); - dp_complete(); + ultramodern::renderer::MipsInterrupts interrupts = renderer_context->get_and_clear_mips_interrupts(); + if (interrupts.sp) sp_complete(); + if (interrupts.dp) dp_complete(); // TODO hook the parsed event up to the actual parsing point when a callback is added to RT64. ultramodern::extensions::on_displaylist_parsed(displaylist); ultramodern::extensions::on_displaylist_completed(displaylist); From 0c06735f628a289f2bb60aed785e683386705ad0 Mon Sep 17 00:00:00 2001 From: SlaveOfIDO Date: Thu, 22 Oct 2026 22:33:31 +0200 Subject: [PATCH 2/2] align physical address --- librecomp/src/pi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librecomp/src/pi.cpp b/librecomp/src/pi.cpp index 43509ba0..f3a38ba0 100644 --- a/librecomp/src/pi.cpp +++ b/librecomp/src/pi.cpp @@ -65,7 +65,7 @@ void recomp::do_rom_read(uint8_t* rdram, gpr ram_address, uint32_t physical_addr // TODO use word copies when possible // TODO handle misaligned DMA - assert((physical_addr & 0x1) == 0 && "Only PI DMA from aligned ROM addresses is currently supported"); + physical_addr &= ~1; assert((ram_address & 0x7) == 0 && "Only PI DMA to aligned RDRAM addresses is currently supported"); uint8_t* rom_addr = rom.data() + physical_addr - recomp::rom_base; for (size_t i = 0; i < num_bytes; i++) {