From 94f83db2b57458adeb8d4c33fe5e9e80ee30d8e4 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Thu, 9 Apr 2020 21:44:45 +0200 Subject: [PATCH] Adjust s_DIMAR/s_DILENGTH behavior (fixes Baten Kaitos music) https://bugs.dolphin-emu.org/issues/11997 The problem seemed to be that s_DILENGTH would get set to 0 at times when it shouldn't. Simply not changing it in case of NoReply or DTK seems to fix the problem. However, we can actually go one step further in accuracy and use data.size() to change s_DIMAR and s_DILENGTH as partial reads (NoReply commands) complete, instead of jumping directly to 0 when the whole read completes. --- Source/Core/Core/HW/DVD/DVDInterface.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp index 9ecb58dc03..ff4d623fa4 100644 --- a/Source/Core/Core/HW/DVD/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp @@ -1233,8 +1233,17 @@ void SetHighError(u32 high_error) void FinishExecutingCommand(ReplyType reply_type, DIInterruptType interrupt_type, s64 cycles_late, const std::vector& data) { - s_DIMAR += s_DILENGTH; - s_DILENGTH = 0; + // The data parameter contains the requested data iff this was called from DVDThread, and is + // empty otherwise. DVDThread is the only source of ReplyType::NoReply and ReplyType::DTK. + + u32 transfer_size = 0; + if (reply_type == ReplyType::NoReply) + transfer_size = static_cast(data.size()); + else if (reply_type == ReplyType::Interrupt || reply_type == ReplyType::IOS) + transfer_size = s_DILENGTH; + + s_DIMAR += transfer_size; + s_DILENGTH -= transfer_size; switch (reply_type) {