diff --git a/pcsx-redux.nix b/pcsx-redux.nix index 26a62d33..74b72e7c 100644 --- a/pcsx-redux.nix +++ b/pcsx-redux.nix @@ -126,8 +126,8 @@ let ({ owner = "pcsx-redux"; repo = "nugget"; - rev = "4dac78a47eee88c6246856d071769c44ad43f0c9"; - hash = "sha256-6qhjs5dTrtwtW4TByc2kPcYULCrDsOUR11awDXBVaX4="; + rev = "d9e0baca03c5ae6c292b1daf50515d19d370dd33"; + hash = "sha256-8TZG8AQ4wUGz0TegUKThR+rUqaAS9xoy5yKKl2sKgGo="; dest = "src/mips"; }) ({ diff --git a/src/core/cdrom.cc b/src/core/cdrom.cc index 556ce3f1..4dac7e10 100644 --- a/src/core/cdrom.cc +++ b/src/core/cdrom.cc @@ -293,13 +293,15 @@ class CDRomImpl final : public PCSX::CDRom { void scheduleDMA(uint32_t cycles) { PCSX::g_emulator->m_cpu->schedule(PCSX::Schedule::CDRDMA, cycles); } void scheduleDMA(std::chrono::nanoseconds delay) { scheduleDMA(PCSX::psxRegisters::durationToCycles(delay)); } + // An acknowledged response no longer holds its slot: its unread bytes stay readable + // until the next response replaces them. bool maybeEnqueueResponse(QueueElement &response) { if (m_responseFifo[0].valueEmpty() && !m_responseFifo[1].empty()) { m_responseFifo[0] = m_responseFifo[1]; m_responseFifo[1] = response; return true; } - if (m_responseFifo[0].empty()) { + if (m_responseFifo[0].valueEmpty()) { m_responseFifo[0] = response; return true; } else if (m_responseFifo[1].empty()) { diff --git a/src/core/cdrom.h b/src/core/cdrom.h index eea08b09..3ea48b23 100644 --- a/src/core/cdrom.h +++ b/src/core/cdrom.h @@ -221,7 +221,7 @@ class CDRom { QueueElement m_commandFifo; QueueElement m_commandExecuting; QueueElement m_responseFifo[2]; - bool responseFifoFull() { return !m_responseFifo[0].empty() && !m_responseFifo[1].empty(); } + bool responseFifoFull() { return !m_responseFifo[0].valueEmpty() && !m_responseFifo[1].empty(); } private: friend class Widgets::IsoBrowser; diff --git a/src/mips b/src/mips index 4dac78a4..d9e0baca 160000 --- a/src/mips +++ b/src/mips @@ -1 +1 @@ -Subproject commit 4dac78a47eee88c6246856d071769c44ad43f0c9 +Subproject commit d9e0baca03c5ae6c292b1daf50515d19d370dd33 diff --git a/tests/pcsxrunner/cdrom.cc b/tests/pcsxrunner/cdrom.cc index 989fae0c..9af227b7 100644 --- a/tests/pcsxrunner/cdrom.cc +++ b/tests/pcsxrunner/cdrom.cc @@ -32,4 +32,41 @@ TEST(cdrom, Dynarec) { "test.cue", "-loadexe", "src/mips/tests/cdrom/cdrom.ps-exe"); int ret = invoker.invoke(); EXPECT_EQ(ret, 0); -} \ No newline at end of file +} +// Boots the test disc through OpenBIOS's shell and kernel loader, with no -loadexe. Passes once +// the disc's boot executable is in RAM and the CPU is running inside it, fails after 6000 frames. +static const char c_discBoot[] = R"( +local f = assert(io.open('src/mips/monitor/hosts/retail/monitor-retail.ps-exe', 'rb')) +local exe = f:read('*a') +f:close() +local function u32(o) + local a, b, c, d = exe:byte(o + 1, o + 4) + return a + b * 0x100 + c * 0x10000 + d * 0x1000000 +end +local tAddr, tSize = u32(0x18), u32(0x1c) +local text = exe:sub(0x801, 0x800 + tSize) +local frames = 0 +DiscBootListener = PCSX.Events.createEventListener('GPU::Vsync', function() + frames = frames + 1 + local pc = PCSX.getRegisters().pc + if pc >= tAddr and pc < tAddr + tSize then + local ram = ffi.string(PCSX.getMemPtr() + bit.band(tAddr, 0x1fffff), tSize) + if ram == text then PCSX.quit(0) end + end + if frames >= 6000 then PCSX.quit(1) end +end) +)"; + +TEST(cdrom, OpenBIOSBootsDiscInterpreter) { + MainInvoker invoker("-no-ui", "-run", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-interpreter", + "-iso", "test.cue", "-exec", c_discBoot); + int ret = invoker.invoke(); + EXPECT_EQ(ret, 0); +} + +TEST(cdrom, OpenBIOSBootsDiscDynarec) { + MainInvoker invoker("-no-ui", "-run", "-bios", "src/mips/openbios/openbios.bin", "-testmode", "-dynarec", "-iso", + "test.cue", "-exec", c_discBoot); + int ret = invoker.invoke(); + EXPECT_EQ(ret, 0); +}