Add a more detailed comment about SPR_WPAR's BNE bit
This commit is contained in:
parent
c06f203e98
commit
97412553f9
|
@ -56,9 +56,23 @@ void Init()
|
||||||
memset(s_gather_pipe, 0, sizeof(s_gather_pipe));
|
memset(s_gather_pipe, 0, sizeof(s_gather_pipe));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsEmpty()
|
bool IsBNE()
|
||||||
{
|
{
|
||||||
return GetGatherPipeCount() == 0;
|
// TODO: It's not clear exactly when the BNE (buffer not empty) bit is set.
|
||||||
|
// The PPC 750cl manual says in section 2.1.2.12 "Write Pipe Address Register (WPAR)" (page 78):
|
||||||
|
// "A mfspr WPAR is used to read the BNE bit to check for any outstanding data transfers."
|
||||||
|
// In section 9.4.2 "Write Gather Pipe Operation" (page 327) it says:
|
||||||
|
// "Software can check WPAR[BNE] to determine if the buffer is empty or not."
|
||||||
|
// On page 327, it also says "The only way for software to flush out a partially full 32 byte
|
||||||
|
// block is to fill up the block with dummy data,."
|
||||||
|
// On page 328, it says: "Before disabling the write gather pipe, the WPAR[BNE] bit should be
|
||||||
|
// tested to insure that all outstanding transfers from the buffer to the bus have completed."
|
||||||
|
//
|
||||||
|
// GXRedirectWriteGatherPipe and GXRestoreWriteGatherPipe (used for display lists) wait for
|
||||||
|
// the bit to be 0 before continuing, so it can't be a case of any data existing in the FIFO;
|
||||||
|
// it might be a case of over 32 bytes being stored pending transfer to memory? For now, always
|
||||||
|
// return false since that prevents hangs in games that use display lists.
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetGatherPipe()
|
void ResetGatherPipe()
|
||||||
|
|
|
@ -26,7 +26,7 @@ void UpdateGatherPipe();
|
||||||
void CheckGatherPipe();
|
void CheckGatherPipe();
|
||||||
void FastCheckGatherPipe();
|
void FastCheckGatherPipe();
|
||||||
|
|
||||||
bool IsEmpty();
|
bool IsBNE();
|
||||||
|
|
||||||
// Write
|
// Write
|
||||||
void Write8(u8 value);
|
void Write8(u8 value);
|
||||||
|
|
|
@ -238,11 +238,14 @@ void Interpreter::mfspr(UGeckoInstruction inst)
|
||||||
|
|
||||||
case SPR_WPAR:
|
case SPR_WPAR:
|
||||||
{
|
{
|
||||||
// TODO: If wpar_empty ever is false, Paper Mario hangs. Strange.
|
// The bottom, read-only bit checks if the buffer is not empty.
|
||||||
// Maybe WPAR is automatically flushed after a certain amount of time?
|
// GXRedirectWriteGatherPipe and GXRestoreWriteGatherPipe (used for display lists) wait for
|
||||||
bool wpar_empty = true; // GPFifo::IsEmpty();
|
// this bit to be cleared before writing to SPR_WPAR again (with a value of 0x0c00800 (aka
|
||||||
if (!wpar_empty)
|
// GPFifo::GATHER_PIPE_PHYSICAL_ADDRESS)).
|
||||||
rSPR(index) |= 1; // BNE = buffer not empty
|
// Currently, we always treat the buffer as not empty, as the exact behavior is unclear
|
||||||
|
// (and games that use display lists will hang if the bit doesn't eventually become zero).
|
||||||
|
if (GPFifo::IsBNE())
|
||||||
|
rSPR(index) |= 1;
|
||||||
else
|
else
|
||||||
rSPR(index) &= ~1;
|
rSPR(index) &= ~1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,16 +282,16 @@ static void WriteToHardware(u32 em_address, const u32 data, const u32 size)
|
||||||
wi = translated_addr.wi;
|
wi = translated_addr.wi;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for a gather pipe write.
|
// Check for a gather pipe write (which are not implemented through the MMIO system).
|
||||||
//
|
//
|
||||||
// Note that we must mask the address to correctly emulate certain games; Pac-Man World 3
|
// Note that we must mask the address to correctly emulate certain games; Pac-Man World 3
|
||||||
// in particular is affected by this. (See https://bugs.dolphin-emu.org/issues/8386)
|
// in particular is affected by this. (See https://bugs.dolphin-emu.org/issues/8386)
|
||||||
//
|
//
|
||||||
// Note that the PowerPC 750CL manual says (in section 9.4.2 Write Gather Pipe Operation on page
|
// The PowerPC 750CL manual says (in section 9.4.2 Write Gather Pipe Operation on page 327):
|
||||||
// 327): "A noncacheable store to an address with bits 0-26 matching WPAR[GB_ADDR] but with bits
|
// "A noncacheable store to an address with bits 0-26 matching WPAR[GB_ADDR] but with bits 27-31
|
||||||
// 27-31 not all zero will result in incorrect data in the buffer." So, it's possible that in some
|
// not all zero will result in incorrect data in the buffer." So, it's possible that in some cases
|
||||||
// cases writes which do not exactly match the masking behave differently, but Pac-Man World 3's
|
// writes which do not exactly match the masking behave differently, but Pac-Man World 3's writes
|
||||||
// writes happen to behave correctly.
|
// happen to behave correctly.
|
||||||
if (flag == XCheckTLBFlag::Write &&
|
if (flag == XCheckTLBFlag::Write &&
|
||||||
(em_address & 0xFFFFF000) == GPFifo::GATHER_PIPE_PHYSICAL_ADDRESS)
|
(em_address & 0xFFFFF000) == GPFifo::GATHER_PIPE_PHYSICAL_ADDRESS)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue