mirror of https://github.com/PCSX2/pcsx2.git
SIF: Transfer SIF0 junk for partial QW transfers from IOP
Fixes True Crime: Streets of LA
This commit is contained in:
parent
435b7dcd2b
commit
1a3b532530
22
pcsx2/Sif.h
22
pcsx2/Sif.h
|
@ -37,6 +37,7 @@ struct sifData
|
|||
struct sifFifo
|
||||
{
|
||||
u32 data[FIFO_SIF_W];
|
||||
u32 junk[4];
|
||||
s32 readPos;
|
||||
s32 writePos;
|
||||
s32 size;
|
||||
|
@ -52,7 +53,10 @@ struct sifFifo
|
|||
{
|
||||
const int wP0 = std::min((FIFO_SIF_W - writePos), words);
|
||||
const int wP1 = words - wP0;
|
||||
|
||||
if (size < 4)
|
||||
{
|
||||
memcpy(&junk[size], from, (4 - size) << 2);
|
||||
}
|
||||
memcpy(&data[writePos], from, wP0 << 2);
|
||||
memcpy(&data[0], &from[wP0], wP1 << 2);
|
||||
|
||||
|
@ -62,6 +66,22 @@ struct sifFifo
|
|||
SIF_LOG(" SIF + %d = %d (pos=%d)", words, size, writePos);
|
||||
}
|
||||
|
||||
void writeJunk(int words)
|
||||
{
|
||||
if (words > 0)
|
||||
{
|
||||
const int wP0 = std::min((FIFO_SIF_W - writePos), words);
|
||||
const int wP1 = words - wP0;
|
||||
|
||||
memcpy(&data[writePos], &junk[4-words], wP0 << 2);
|
||||
memcpy(&data[0], &junk[(4 - words)+wP0], wP1 << 2);
|
||||
|
||||
writePos = (writePos + words) & (FIFO_SIF_W - 1);
|
||||
size += words;
|
||||
}
|
||||
SIF_LOG(" SIF + %d = %d (pos=%d)", words, size, writePos);
|
||||
}
|
||||
|
||||
void read(u32 *to, int words)
|
||||
{
|
||||
if (words > 0)
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
_sif sif0;
|
||||
|
||||
static bool done = false;
|
||||
static int writeJunk = 0;
|
||||
|
||||
static __fi void Sif0Init()
|
||||
{
|
||||
|
@ -83,6 +84,12 @@ static __fi bool WriteIOPtoFifo()
|
|||
sif0.iop.cycles += (writeSize >> 2)/* * BIAS*/; // fixme : should be >> 4
|
||||
sif0.iop.counter -= writeSize;
|
||||
|
||||
if (sif0.iop.counter == 0 && writeJunk)
|
||||
{
|
||||
SIF_LOG("Writing Junk %d", writeJunk);
|
||||
sif0.fifo.writeJunk(writeJunk);
|
||||
writeJunk = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -92,7 +99,7 @@ static __fi bool ProcessEETag()
|
|||
static __aligned16 u32 tag[4];
|
||||
tDMA_TAG& ptag(*(tDMA_TAG*)tag);
|
||||
|
||||
sif0.fifo.read((u32*)&tag[0], 4); // Tag
|
||||
sif0.fifo.read((u32*)&tag[0], 2); // Tag
|
||||
SIF_LOG("SIF0 EE read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]);
|
||||
|
||||
sif0ch.unsafeTransfer(&ptag);
|
||||
|
@ -128,26 +135,27 @@ static __fi bool ProcessIOPTag()
|
|||
{
|
||||
// Process DMA tag at hw_dma9.tadr
|
||||
sif0.iop.data = *(sifData *)iopPhysMem(hw_dma9.tadr);
|
||||
sif0.iop.data.words = (sif0.iop.data.words + 3) & 0xfffffffc; // Round up to nearest 4.
|
||||
sif0.iop.data.words = sif0.iop.data.words;
|
||||
|
||||
// send the EE's side of the DMAtag. The tag is only 64 bits, with the upper 64 bits
|
||||
// ignored by the EE.
|
||||
|
||||
sif0.fifo.write((u32*)iopPhysMem(hw_dma9.tadr + 8), 2);
|
||||
sif0.fifo.writePos = (sif0.fifo.writePos + 2) & (FIFO_SIF_W - 1); // iggy on the upper 64.
|
||||
sif0.fifo.size += 2;
|
||||
//sif0.fifo.writePos = (sif0.fifo.writePos + 2) & (FIFO_SIF_W - 1); // iggy on the upper 64.
|
||||
//sif0.fifo.size += 2;
|
||||
|
||||
hw_dma9.tadr += 16; ///hw_dma9.madr + 16 + sif0.sifData.words << 2;
|
||||
|
||||
// We're only copying the first 24 bits. Bits 30 and 31 (checked below) are Stop/IRQ bits.
|
||||
hw_dma9.madr = sif0data & 0xFFFFFF;
|
||||
if (sif0words > 0xFFFFC) DevCon.Warning("SIF0 Overrun %x", sif0words);
|
||||
if (sif0words > 0xFFFFF) DevCon.Warning("SIF0 Overrun %x", sif0words);
|
||||
//Maximum transfer amount 1mb-16 also masking out top part which is a "Mode" cache stuff, we don't care :)
|
||||
sif0.iop.counter = sif0words & 0xFFFFC;
|
||||
sif0.iop.counter = sif0words & 0xFFFFF;
|
||||
|
||||
writeJunk = (sif0.iop.counter & 0x3) ? (4 - sif0.iop.counter & 0x3) : 0;
|
||||
// IOP tags have an IRQ bit and an End of Transfer bit:
|
||||
if (sif0tag.IRQ || (sif0tag.ID & 4)) sif0.iop.end = true;
|
||||
SIF_LOG("SIF0 IOP Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)", hw_dma9.madr, hw_dma9.tadr, sif0.iop.counter, sif0words, sif0data);
|
||||
SIF_LOG("SIF0 IOP Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X) Junk %d", hw_dma9.madr, hw_dma9.tadr, sif0.iop.counter, sif0words, sif0data, writeJunk);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue