mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 13:20:27 -06:00
VideoCommon: reset some CP registers during PI_FIFO_RESET
This fixes the shutdown error in SpongeBob Globs of Doom.
This commit is contained in:
@ -175,7 +175,7 @@ ReadHandlingMethod<T>* InvalidRead()
|
|||||||
return ComplexRead<T>([](Core::System&, u32 addr) {
|
return ComplexRead<T>([](Core::System&, u32 addr) {
|
||||||
ERROR_LOG_FMT(MEMMAP, "Trying to read {} bits from an invalid MMIO (addr={:08x})",
|
ERROR_LOG_FMT(MEMMAP, "Trying to read {} bits from an invalid MMIO (addr={:08x})",
|
||||||
8 * sizeof(T), addr);
|
8 * sizeof(T), addr);
|
||||||
return -1;
|
return 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
#include "VideoCommon/AsyncRequests.h"
|
#include "VideoCommon/AsyncRequests.h"
|
||||||
|
#include "VideoCommon/CommandProcessor.h"
|
||||||
#include "VideoCommon/Fifo.h"
|
#include "VideoCommon/Fifo.h"
|
||||||
|
|
||||||
namespace ProcessorInterface
|
namespace ProcessorInterface
|
||||||
@ -96,11 +97,11 @@ void ProcessorInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
|||||||
INFO_LOG_FMT(PROCESSORINTERFACE, "Wrote PI_FIFO_RESET: {:08x}", val);
|
INFO_LOG_FMT(PROCESSORINTERFACE, "Wrote PI_FIFO_RESET: {:08x}", val);
|
||||||
if ((val & 1) != 0)
|
if ((val & 1) != 0)
|
||||||
{
|
{
|
||||||
|
// TODO: Is this still necessary now that we reset the CP registers?
|
||||||
system.GetGPFifo().ResetGatherPipe();
|
system.GetGPFifo().ResetGatherPipe();
|
||||||
|
|
||||||
// Assume that all bytes that made it into the GPU fifo did in fact execute
|
// Reset some CP registers. This may trigger an ad-hoc GPU time slice.
|
||||||
// before this MMIO write takes effect.
|
system.GetCommandProcessor().ResetFifo();
|
||||||
system.GetFifo().SyncGPUForRegisterAccess();
|
|
||||||
|
|
||||||
// Call Fifo::ResetVideoBuffer() from the video thread. Since that function
|
// Call Fifo::ResetVideoBuffer() from the video thread. Since that function
|
||||||
// resets various pointers used by the video thread, we can't call it directly
|
// resets various pointers used by the video thread, we can't call it directly
|
||||||
|
@ -95,7 +95,7 @@ static size_t s_state_writes_in_queue;
|
|||||||
static std::condition_variable s_state_write_queue_is_empty;
|
static std::condition_variable s_state_write_queue_is_empty;
|
||||||
|
|
||||||
// Don't forget to increase this after doing changes on the savestate system
|
// Don't forget to increase this after doing changes on the savestate system
|
||||||
constexpr u32 STATE_VERSION = 173; // Last changed in PR 10084
|
constexpr u32 STATE_VERSION = 174; // Last changed in PR 13342
|
||||||
|
|
||||||
// Increase this if the StateExtendedHeader definition changes
|
// Increase this if the StateExtendedHeader definition changes
|
||||||
constexpr u32 EXTENDED_HEADER_VERSION = 1; // Last changed in PR 12217
|
constexpr u32 EXTENDED_HEADER_VERSION = 1; // Last changed in PR 12217
|
||||||
|
@ -87,6 +87,8 @@ void CommandProcessorManager::DoState(PointerWrap& p)
|
|||||||
p.Do(m_cp_status_reg);
|
p.Do(m_cp_status_reg);
|
||||||
p.Do(m_cp_ctrl_reg);
|
p.Do(m_cp_ctrl_reg);
|
||||||
p.Do(m_cp_clear_reg);
|
p.Do(m_cp_clear_reg);
|
||||||
|
p.Do(m_perf_select);
|
||||||
|
p.Do(m_unk_0a_reg);
|
||||||
m_fifo.DoState(p);
|
m_fifo.DoState(p);
|
||||||
|
|
||||||
p.Do(m_interrupt_set);
|
p.Do(m_interrupt_set);
|
||||||
@ -200,13 +202,13 @@ void CommandProcessorManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
|||||||
mmio->Register(base | CTRL_REGISTER, MMIO::DirectRead<u16>(&m_cp_ctrl_reg.Hex),
|
mmio->Register(base | CTRL_REGISTER, MMIO::DirectRead<u16>(&m_cp_ctrl_reg.Hex),
|
||||||
MMIO::ComplexWrite<u16>([](Core::System& system_, u32, u16 val) {
|
MMIO::ComplexWrite<u16>([](Core::System& system_, u32, u16 val) {
|
||||||
auto& cp = system_.GetCommandProcessor();
|
auto& cp = system_.GetCommandProcessor();
|
||||||
UCPCtrlReg tmp(val);
|
UCPCtrlReg tmp(val & 0x3F);
|
||||||
cp.m_cp_ctrl_reg.Hex = tmp.Hex;
|
cp.m_cp_ctrl_reg.Hex = tmp.Hex;
|
||||||
cp.SetCpControlRegister();
|
cp.SetCpControlRegister();
|
||||||
system_.GetFifo().RunGpu();
|
system_.GetFifo().RunGpu();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
mmio->Register(base | CLEAR_REGISTER, MMIO::DirectRead<u16>(&m_cp_clear_reg.Hex),
|
mmio->Register(base | CLEAR_REGISTER, MMIO::Constant<u16>(0),
|
||||||
MMIO::ComplexWrite<u16>([](Core::System& system_, u32, u16 val) {
|
MMIO::ComplexWrite<u16>([](Core::System& system_, u32, u16 val) {
|
||||||
auto& cp = system_.GetCommandProcessor();
|
auto& cp = system_.GetCommandProcessor();
|
||||||
UCPClearReg tmp(val);
|
UCPClearReg tmp(val);
|
||||||
@ -215,7 +217,14 @@ void CommandProcessorManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
|||||||
system_.GetFifo().RunGpu();
|
system_.GetFifo().RunGpu();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
mmio->Register(base | PERF_SELECT, MMIO::InvalidRead<u16>(), MMIO::Nop<u16>());
|
// TODO: Figure out how this works. Written by GXSetGPMetric. Nicktoons MLB has DWARF v2 with enum
|
||||||
|
// names.
|
||||||
|
mmio->Register(base | PERF_SELECT, MMIO::DirectRead<u16>(&m_perf_select),
|
||||||
|
MMIO::DirectWrite<u16>(&m_perf_select, 0x0007));
|
||||||
|
|
||||||
|
// TODO: Figure out what this is.
|
||||||
|
mmio->Register(base | UNK_0A_REGISTER, MMIO::DirectRead<u16>(&m_unk_0a_reg),
|
||||||
|
MMIO::DirectWrite<u16>(&m_unk_0a_reg, 0x00FF));
|
||||||
|
|
||||||
// Some MMIOs have different handlers for single core vs. dual core mode.
|
// Some MMIOs have different handlers for single core vs. dual core mode.
|
||||||
const bool is_on_thread = IsOnThread(m_system);
|
const bool is_on_thread = IsOnThread(m_system);
|
||||||
@ -565,6 +574,7 @@ void CommandProcessorManager::SetCpStatusRegister()
|
|||||||
|
|
||||||
void CommandProcessorManager::SetCpControlRegister()
|
void CommandProcessorManager::SetCpControlRegister()
|
||||||
{
|
{
|
||||||
|
// Just before disabling reads, give the GPU a chance to catch up.
|
||||||
if (m_fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) && !m_cp_ctrl_reg.GPReadEnable)
|
if (m_fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) && !m_cp_ctrl_reg.GPReadEnable)
|
||||||
{
|
{
|
||||||
m_system.GetFifo().SyncGPUForRegisterAccess();
|
m_system.GetFifo().SyncGPUForRegisterAccess();
|
||||||
@ -591,6 +601,18 @@ void CommandProcessorManager::SetCpClearRegister()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CommandProcessorManager::ResetFifo()
|
||||||
|
{
|
||||||
|
// Link fifos, disable interrupts, disable reads.
|
||||||
|
m_cp_ctrl_reg.Hex = 0x0010;
|
||||||
|
SetCpControlRegister();
|
||||||
|
m_perf_select = 0;
|
||||||
|
m_unk_0a_reg = 0;
|
||||||
|
m_fifo.CPLoWatermark = 0;
|
||||||
|
m_fifo.CPHiWatermark = GetPhysicalAddressMask(m_system.IsWii()) & ~31u;
|
||||||
|
SetCpStatusRegister();
|
||||||
|
}
|
||||||
|
|
||||||
void CommandProcessorManager::HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, bool preprocess)
|
void CommandProcessorManager::HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, bool preprocess)
|
||||||
{
|
{
|
||||||
// Datel software uses 0x01 during startup, and Mario Party 5's Wiggler capsule accidentally uses
|
// Datel software uses 0x01 during startup, and Mario Party 5's Wiggler capsule accidentally uses
|
||||||
|
@ -60,6 +60,7 @@ enum
|
|||||||
CTRL_REGISTER = 0x02,
|
CTRL_REGISTER = 0x02,
|
||||||
CLEAR_REGISTER = 0x04,
|
CLEAR_REGISTER = 0x04,
|
||||||
PERF_SELECT = 0x06,
|
PERF_SELECT = 0x06,
|
||||||
|
UNK_0A_REGISTER = 0x0A,
|
||||||
FIFO_BASE_LO = 0x20,
|
FIFO_BASE_LO = 0x20,
|
||||||
FIFO_BASE_HI = 0x22,
|
FIFO_BASE_HI = 0x22,
|
||||||
FIFO_END_LO = 0x24,
|
FIFO_END_LO = 0x24,
|
||||||
@ -142,7 +143,8 @@ union UCPClearReg
|
|||||||
{
|
{
|
||||||
u16 ClearFifoOverflow : 1;
|
u16 ClearFifoOverflow : 1;
|
||||||
u16 ClearFifoUnderflow : 1;
|
u16 ClearFifoUnderflow : 1;
|
||||||
u16 ClearMetrices : 1;
|
// set by GXClearGPMetric
|
||||||
|
u16 ClearMetrics : 1;
|
||||||
u16 : 13;
|
u16 : 13;
|
||||||
};
|
};
|
||||||
u16 Hex;
|
u16 Hex;
|
||||||
@ -178,6 +180,7 @@ public:
|
|||||||
void SetCpClearRegister();
|
void SetCpClearRegister();
|
||||||
void SetCpControlRegister();
|
void SetCpControlRegister();
|
||||||
void SetCpStatusRegister();
|
void SetCpStatusRegister();
|
||||||
|
void ResetFifo();
|
||||||
|
|
||||||
void HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, bool preprocess);
|
void HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, bool preprocess);
|
||||||
|
|
||||||
@ -194,6 +197,8 @@ private:
|
|||||||
UCPStatusReg m_cp_status_reg;
|
UCPStatusReg m_cp_status_reg;
|
||||||
UCPCtrlReg m_cp_ctrl_reg;
|
UCPCtrlReg m_cp_ctrl_reg;
|
||||||
UCPClearReg m_cp_clear_reg;
|
UCPClearReg m_cp_clear_reg;
|
||||||
|
u16 m_perf_select = 0;
|
||||||
|
u16 m_unk_0a_reg = 0;
|
||||||
|
|
||||||
u16 m_bbox_left = 0;
|
u16 m_bbox_left = 0;
|
||||||
u16 m_bbox_top = 0;
|
u16 m_bbox_top = 0;
|
||||||
|
Reference in New Issue
Block a user