Made some minor tweaks to SIF to test some theories and fix some broken-looking code -- please report any regressions. Also commented some of SIF and IPU stuff. :)

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3812 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-09-20 12:47:17 +00:00
parent d06838c4a5
commit 5fd2cf97d3
8 changed files with 69 additions and 65 deletions

View File

@ -161,7 +161,7 @@ union u128
bool operator!=( const u128& right ) const bool operator!=( const u128& right ) const
{ {
return (lo != right.lo) && (hi != right.hi); return (lo != right.lo) || (hi != right.hi);
} }
// In order for the following ToString() and WriteTo methods to be available, you must // In order for the following ToString() and WriteTo methods to be available, you must
@ -206,7 +206,7 @@ struct s128
bool operator!=( const s128& right ) const bool operator!=( const s128& right ) const
{ {
return (lo != right.lo) && (hi != right.hi); return (lo != right.lo) || (hi != right.hi);
} }
}; };

View File

@ -92,6 +92,8 @@ union tDMA_TAG {
}; };
u32 _u32; u32 _u32;
tDMA_TAG() {}
tDMA_TAG(u32 val) { _u32 = val; } tDMA_TAG(u32 val) { _u32 = val; }
u16 upper() const { return (_u32 >> 16); } u16 upper() const { return (_u32 >> 16); }
u16 lower() const { return (u16)_u32; } u16 lower() const { return (u16)_u32; }

View File

@ -448,6 +448,14 @@ static bool __fastcall ipuVDEC(u32 val)
jNO_DEFAULT jNO_DEFAULT
} }
// HACK ATTACK! This code OR's the MPEG decoder's bitstream position into the upper
// 16 bits of DATA; which really doesn't make sense since (a) we already rewound the bits
// back into the IPU internal buffer above, and (b) the IPU doesn't have an MPEG internal
// 32-bit decoder buffer of its own anyway. Furthermore, setting the upper 16 bits to
// any value other than zero appears to work fine. When set to zero, however, FMVs run
// very choppy (basically only decoding/updating every 30th frame or so). So yeah,
// someone with knowledge on the subject please feel free to explain this one. :) --air
ipuRegs.cmd.DATA &= 0xFFFF; ipuRegs.cmd.DATA &= 0xFFFF;
ipuRegs.cmd.DATA |= 0x10000; ipuRegs.cmd.DATA |= 0x10000;
@ -466,6 +474,7 @@ static bool __fastcall ipuVDEC(u32 val)
IPU_LOG("VDEC command data 0x%x(0x%x). Skip 0x%X bits/Table=%d (%s), pct %d", IPU_LOG("VDEC command data 0x%x(0x%x). Skip 0x%X bits/Table=%d (%s), pct %d",
ipuRegs.cmd.DATA, ipuRegs.cmd.DATA >> 16, val & 0x3f, (val >> 26) & 3, (val >> 26) & 1 ? ipuRegs.cmd.DATA, ipuRegs.cmd.DATA >> 16, val & 0x3f, (val >> 26) & 3, (val >> 26) & 1 ?
((val >> 26) & 2 ? "DMV" : "MBT") : (((val >> 26) & 2 ? "MC" : "MBAI")), ipuRegs.ctrl.PCT); ((val >> 26) & 2 ? "DMV" : "MBT") : (((val >> 26) & 2 ? "MC" : "MBAI")), ipuRegs.ctrl.PCT);
return true; return true;
jNO_DEFAULT jNO_DEFAULT
@ -488,8 +497,6 @@ static __fi bool ipuFDEC(u32 val)
static bool ipuSETIQ(u32 val) static bool ipuSETIQ(u32 val)
{ {
int i;
if ((val >> 27) & 1) if ((val >> 27) & 1)
{ {
u8 (&niq)[64] = decoder.niq; u8 (&niq)[64] = decoder.niq;
@ -500,7 +507,7 @@ static bool ipuSETIQ(u32 val)
} }
IPU_LOG("Read non-intra quantization matrix from FIFO."); IPU_LOG("Read non-intra quantization matrix from FIFO.");
for (i = 0; i < 8; i++) for (uint i = 0; i < 8; i++)
{ {
IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X", IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X",
niq[i * 8 + 0], niq[i * 8 + 1], niq[i * 8 + 2], niq[i * 8 + 3], niq[i * 8 + 0], niq[i * 8 + 1], niq[i * 8 + 2], niq[i * 8 + 3],
@ -517,7 +524,7 @@ static bool ipuSETIQ(u32 val)
} }
IPU_LOG("Read intra quantization matrix from FIFO."); IPU_LOG("Read intra quantization matrix from FIFO.");
for (i = 0; i < 8; i++) for (uint i = 0; i < 8; i++)
{ {
IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X", IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X",
iq[i * 8 + 0], iq[i * 8 + 1], iq[i * 8 + 2], iq[i *8 + 3], iq[i * 8 + 0], iq[i * 8 + 1], iq[i * 8 + 2], iq[i *8 + 3],

View File

@ -195,14 +195,8 @@ void psxDma9(u32 madr, u32 bcr, u32 chcr)
SIF_LOG("IOP: dmaSIF0 chcr = %lx, madr = %lx, bcr = %lx, tadr = %lx", chcr, madr, bcr, HW_DMA9_TADR); SIF_LOG("IOP: dmaSIF0 chcr = %lx, madr = %lx, bcr = %lx, tadr = %lx", chcr, madr, bcr, HW_DMA9_TADR);
sif0.iop.busy = true; sif0.iop.busy = true;
psHu32(SBUS_F240) |= 0x2000;
/*if (sif0.ee.busy)
{*/
SIF0Dma(); SIF0Dma();
psHu32(SBUS_F240) &= ~0x20;
psHu32(SBUS_F240) &= ~0x2000;
//}
} }
void psxDma10(u32 madr, u32 bcr, u32 chcr) void psxDma10(u32 madr, u32 bcr, u32 chcr)
@ -210,15 +204,8 @@ void psxDma10(u32 madr, u32 bcr, u32 chcr)
SIF_LOG("IOP: dmaSIF1 chcr = %lx, madr = %lx, bcr = %lx", chcr, madr, bcr); SIF_LOG("IOP: dmaSIF1 chcr = %lx, madr = %lx, bcr = %lx", chcr, madr, bcr);
sif1.iop.busy = true; sif1.iop.busy = true;
psHu32(SBUS_F240) |= 0x4000;
/*if (sif1.ee.busy)
{*/
SIF1Dma(); SIF1Dma();
psHu32(SBUS_F240) &= ~0x40;
psHu32(SBUS_F240) &= ~0x100;
psHu32(SBUS_F240) &= ~0x4000;
//}
} }
/* psxDma11 & psxDma 12 are in IopSio2.cpp, along with the appropriate interrupt functions. */ /* psxDma11 & psxDma 12 are in IopSio2.cpp, along with the appropriate interrupt functions. */

View File

@ -22,13 +22,17 @@ static DMACh& sif0dma = (DMACh&)eeHw[0xc000];
static DMACh& sif1dma = (DMACh&)eeHw[0xc400]; static DMACh& sif1dma = (DMACh&)eeHw[0xc400];
static DMACh& sif2dma = (DMACh&)eeHw[0xc800]; static DMACh& sif2dma = (DMACh&)eeHw[0xc800];
// Despite its name, this is actually the IOP's DMAtag, which itself also contains
// the EE's DMAtag in its upper 64 bits. Note that only the lower 24 bits of 'data' is
// the IOP's chain transfer address (loaded into MADR). Bits 30 and 31 are transfer stop
// bits of some sort.
struct sifData struct sifData
{ {
s32 data; s32 data;
s32 words; s32 words;
s32 count; // I think this is unused.
s32 addr; // This too. tDMA_TAG tag_lo; // EE DMA tag
tDMA_TAG tag_hi; // EE DMA tag
}; };
struct sifFifo struct sifFifo
@ -100,6 +104,7 @@ struct sif_ee
s32 cycles; s32 cycles;
}; };
struct sif_iop struct sif_iop
{ {
bool end; bool end;
@ -110,6 +115,7 @@ struct sif_iop
s32 counter; // Used to keep track of how much is left in IOP. s32 counter; // Used to keep track of how much is left in IOP.
struct sifData data; // Only used in IOP. struct sifData data; // Only used in IOP.
}; };
struct _sif struct _sif
{ {
sifFifo fifo; // Used in both. sifFifo fifo; // Used in both.

View File

@ -69,8 +69,8 @@ static __fi bool WriteIOPtoFifo()
SIF_LOG("Write IOP to Fifo: +++++++++++ %lX of %lX", writeSize, sif0.iop.counter); SIF_LOG("Write IOP to Fifo: +++++++++++ %lX of %lX", writeSize, sif0.iop.counter);
sif0.fifo.write((u32*)iopPhysMem(hw_dma(9).madr), writeSize); sif0.fifo.write((u32*)iopPhysMem(hw_dma9.madr), writeSize);
hw_dma(9).madr += writeSize << 2; hw_dma9.madr += writeSize << 2;
// iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords). // iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords).
sif0.iop.cycles += (writeSize >> 2)/* * BIAS*/; // fixme : should be >> 4 sif0.iop.cycles += (writeSize >> 2)/* * BIAS*/; // fixme : should be >> 4
@ -83,13 +83,13 @@ static __fi bool WriteIOPtoFifo()
static __fi bool ProcessEETag() static __fi bool ProcessEETag()
{ {
static __aligned16 u32 tag[4]; 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], 4); // Tag
SIF_LOG("SIF0 EE read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]); SIF_LOG("SIF0 EE read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]);
sif0dma.unsafeTransfer(((tDMA_TAG*)(tag))); sif0dma.unsafeTransfer(&ptag);
sif0dma.madr = tag[1]; sif0dma.madr = tag[1];
tDMA_TAG ptag(tag[0]);
SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)", SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)",
sif0dma.madr, sif0dma.qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]); sif0dma.madr, sif0dma.qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]);
@ -102,13 +102,9 @@ static __fi bool ProcessEETag()
switch (ptag.ID) switch (ptag.ID)
{ {
case TAG_REFE: case TAG_CNT: break;
sif0.ee.end = true;
if (dmacRegs.ctrl.STS != NO_STS)
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
break;
case TAG_REFS: case TAG_CNTS:
if (dmacRegs.ctrl.STS != NO_STS) if (dmacRegs.ctrl.STS != NO_STS)
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16); dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
break; break;
@ -120,22 +116,29 @@ static __fi bool ProcessEETag()
return true; return true;
} }
// Read Fifo into an iop tag, and transfer it to hw_dma(9). And presumably process it. // Read Fifo into an iop tag, and transfer it to hw_dma9. And presumably process it.
static __fi bool ProcessIOPTag() static __fi bool ProcessIOPTag()
{ {
// Process DMA tag at hw_dma(9).tadr // Process DMA tag at hw_dma9.tadr
sif0.iop.data = *(sifData *)iopPhysMem(hw_dma(9).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 + 3) & 0xfffffffc; // Round up to nearest 4.
sif0.fifo.write((u32*)iopPhysMem(hw_dma(9).tadr + 8), 4);
hw_dma(9).tadr += 16; ///hw_dma(9).madr + 16 + sif0.sifData.words << 2; // send the EE's side of the DMAtag. The tag is only 64 bits, with the upper 64 bits
// ignored by the EE.
// We're only copying the first 24 bits. sif0.fifo.write((u32*)iopPhysMem(hw_dma9.tadr + 8), 2);
hw_dma(9).madr = sif0data & 0xFFFFFF; 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;
sif0.iop.counter = sif0words; sif0.iop.counter = sif0words;
// IOP tags have an IRQ bit and an End of Transfer bit:
if (sif0tag.IRQ || (sif0tag.ID & 4)) sif0.iop.end = true; if (sif0tag.IRQ || (sif0tag.ID & 4)) sif0.iop.end = true;
SIF_LOG("SIF0 IOP Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)", hw_dma(9).madr, hw_dma(9).tadr, sif0.iop.counter, sif0words, sif0data); SIF_LOG("SIF0 IOP Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)", hw_dma9.madr, hw_dma9.tadr, sif0.iop.counter, sif0words, sif0data);
return true; return true;
} }
@ -265,7 +268,7 @@ static __fi void HandleIOPTransfer()
} }
else else
{ {
// Read Fifo into an iop tag, and transfer it to hw_dma(9). // Read Fifo into an iop tag, and transfer it to hw_dma9.
// And presumably process it. // And presumably process it.
ProcessIOPTag(); ProcessIOPTag();
} }
@ -282,6 +285,9 @@ static __fi void HandleIOPTransfer()
static __fi void Sif0End() static __fi void Sif0End()
{ {
psHu32(SBUS_F240) &= ~0x20;
psHu32(SBUS_F240) &= ~0x2000;
SIF_LOG("SIF0 DMA end..."); SIF_LOG("SIF0 DMA end...");
} }
@ -351,8 +357,5 @@ __fi void dmaSIF0()
{ {
//hwIntcIrq(INTC_SBUS); // not sure, so let's not //hwIntcIrq(INTC_SBUS); // not sure, so let's not
SIF0Dma(); SIF0Dma();
// Do we really want to mess with the SIF flags like that? Nah.
//psHu32(SBUS_F240) &= ~0x20;
//psHu32(SBUS_F240) &= ~0x2000;
} }
} }

View File

@ -68,9 +68,9 @@ static __fi bool WriteFifoToIOP()
SIF_LOG("Sif 1 IOP doing transfer %04X to %08X", readSize, HW_DMA10_MADR); SIF_LOG("Sif 1 IOP doing transfer %04X to %08X", readSize, HW_DMA10_MADR);
sif1.fifo.read((u32*)iopPhysMem(hw_dma(10).madr), readSize); sif1.fifo.read((u32*)iopPhysMem(hw_dma10.madr), readSize);
psxCpu->Clear(hw_dma(10).madr, readSize); psxCpu->Clear(hw_dma10.madr, readSize);
hw_dma(10).madr += readSize << 2; hw_dma10.madr += readSize << 2;
sif1.iop.cycles += readSize >> 2; // fixme: should be >> 4 sif1.iop.cycles += readSize >> 2; // fixme: should be >> 4
sif1.iop.counter -= readSize; sif1.iop.counter -= readSize;
@ -151,7 +151,7 @@ static __fi bool SIFIOPReadTag()
sif1data & 0xffffff, sif1words, sif1tag.ID, sif1tag.IRQ); sif1data & 0xffffff, sif1words, sif1tag.ID, sif1tag.IRQ);
// Only use the first 24 bits. // Only use the first 24 bits.
hw_dma(10).madr = sif1data & 0xffffff; hw_dma10.madr = sif1data & 0xffffff;
sif1.iop.counter = sif1words; sif1.iop.counter = sif1words;
if (sif1tag.IRQ || (sif1tag.ID & 4)) sif1.iop.end = true; if (sif1tag.IRQ || (sif1tag.ID & 4)) sif1.iop.end = true;
@ -276,6 +276,9 @@ static __fi void HandleIOPTransfer()
static __fi void Sif1End() static __fi void Sif1End()
{ {
psHu32(SBUS_F240) &= ~0x40;
psHu32(SBUS_F240) &= ~0x4000;
SIF_LOG("SIF1 DMA end..."); SIF_LOG("SIF1 DMA end...");
} }
@ -349,9 +352,5 @@ __fi void dmaSIF1()
if (sif1.iop.busy) if (sif1.iop.busy)
{ {
SIF1Dma(); SIF1Dma();
// Do we really want to mess with the SIF flags like that? Nah.
//psHu32(SBUS_F240) &= ~0x40;
//psHu32(SBUS_F240) &= ~0x100;
//psHu32(SBUS_F240) &= ~0x4000;
} }
} }

View File

@ -17,20 +17,20 @@ s32 PrepareEERead()
{ {
static __aligned16 u32 tag[4]; static __aligned16 u32 tag[4];
// Process DMA tag at hw_dma(9).tadr // Process DMA tag at hw_dma9.tadr
sif0.iop.data = *(sifData *)iopPhysMem(hw_dma(9).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 + 3) & 0xfffffffc; // Round up to nearest 4.
memcpy(tag, (u32*)iopPhysMem(hw_dma(9).tadr + 8), 16); memcpy(tag, (u32*)iopPhysMem(hw_dma9.tadr + 8), 16);
hw_dma(9).tadr += 16; ///hw_dma(9).madr + 16 + sif0.sifData.words << 2; hw_dma9.tadr += 16; ///hw_dma9.madr + 16 + sif0.sifData.words << 2;
// We're only copying the first 24 bits. // We're only copying the first 24 bits.
hw_dma(9).madr = sif0data & 0xFFFFFF; hw_dma9.madr = sif0data & 0xFFFFFF;
sif0.iop.counter = sif0words; sif0.iop.counter = sif0words;
if (sif0tag.IRQ || (sif0tag.ID & 4)) sif0.iop.end = true; if (sif0tag.IRQ || (sif0tag.ID & 4)) sif0.iop.end = true;
SIF_LOG("SIF0 IOP to EE Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)" SIF_LOG("SIF0 IOP to EE Tag: madr=%lx, tadr=%lx, counter=%lx (%08X_%08X)"
"\n\tread tag: %x %x %x %x", hw_dma(9).madr, hw_dma(9).tadr, sif0.iop.counter, sif0words, sif0data, "\n\tread tag: %x %x %x %x", hw_dma9.madr, hw_dma9.tadr, sif0.iop.counter, sif0words, sif0data,
tag[0], tag[1], tag[2], tag[3]); tag[0], tag[1], tag[2], tag[3]);
sif0dma.unsafeTransfer(((tDMA_TAG*)(tag))); sif0dma.unsafeTransfer(((tDMA_TAG*)(tag)));
@ -98,7 +98,7 @@ s32 DoSifRead(u32 iopAvailable)
return false; return false;
} }
memcpy((u32*)ptag, (u32*)iopPhysMem(hw_dma(9).madr), transferSizeBytes); memcpy((u32*)ptag, (u32*)iopPhysMem(hw_dma9.madr), transferSizeBytes);
// Clearing handled by vtlb memory protection and manual blocks. // Clearing handled by vtlb memory protection and manual blocks.
//Cpu->Clear(sif0dma.madr, readSize*4); //Cpu->Clear(sif0dma.madr, readSize*4);