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
{
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
@ -206,7 +206,7 @@ struct s128
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;
tDMA_TAG() {}
tDMA_TAG(u32 val) { _u32 = val; }
u16 upper() const { return (_u32 >> 16); }
u16 lower() const { return (u16)_u32; }

View File

@ -206,7 +206,7 @@ __fi u32 ipuRead32(u32 mem)
if (!ipuRegs.ctrl.BUSY)
IPU_LOG("read32: IPU_CTRL=0x%08X", ipuRegs.ctrl._u32);
return ipuRegs.ctrl._u32;
return ipuRegs.ctrl._u32;
}
ipucase(IPU_BP): // IPU_BP
@ -218,7 +218,7 @@ __fi u32 ipuRead32(u32 mem)
ipuRegs.ipubp |= g_BP.FP << 16;
IPU_LOG("read32: IPU_BP=0x%08X", ipuRegs.ipubp);
return ipuRegs.ipubp;
return ipuRegs.ipubp;
}
default:
@ -448,6 +448,14 @@ static bool __fastcall ipuVDEC(u32 val)
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 |= 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",
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);
return true;
jNO_DEFAULT
@ -488,8 +497,6 @@ static __fi bool ipuFDEC(u32 val)
static bool ipuSETIQ(u32 val)
{
int i;
if ((val >> 27) & 1)
{
u8 (&niq)[64] = decoder.niq;
@ -500,7 +507,7 @@ static bool ipuSETIQ(u32 val)
}
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",
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.");
for (i = 0; i < 8; i++)
for (uint i = 0; i < 8; i++)
{
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],
@ -539,7 +546,7 @@ static bool ipuSETVQ(u32 val)
"%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d\n"
"%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d\n"
"%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d\n"
"%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d",
"%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d",
vqclut[0] >> 10, (vqclut[0] >> 5) & 0x1F, vqclut[0] & 0x1F,
vqclut[1] >> 10, (vqclut[1] >> 5) & 0x1F, vqclut[1] & 0x1F,
vqclut[2] >> 10, (vqclut[2] >> 5) & 0x1F, vqclut[2] & 0x1F,

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);
sif0.iop.busy = true;
psHu32(SBUS_F240) |= 0x2000;
/*if (sif0.ee.busy)
{*/
SIF0Dma();
psHu32(SBUS_F240) &= ~0x20;
psHu32(SBUS_F240) &= ~0x2000;
//}
SIF0Dma();
}
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);
sif1.iop.busy = true;
psHu32(SBUS_F240) |= 0x4000;
/*if (sif1.ee.busy)
{*/
SIF1Dma();
psHu32(SBUS_F240) &= ~0x40;
psHu32(SBUS_F240) &= ~0x100;
psHu32(SBUS_F240) &= ~0x4000;
//}
SIF1Dma();
}
/* 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& 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
{
s32 data;
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
@ -100,6 +104,7 @@ struct sif_ee
s32 cycles;
};
struct sif_iop
{
bool end;
@ -110,6 +115,7 @@ struct sif_iop
s32 counter; // Used to keep track of how much is left in IOP.
struct sifData data; // Only used in IOP.
};
struct _sif
{
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);
sif0.fifo.write((u32*)iopPhysMem(hw_dma(9).madr), writeSize);
hw_dma(9).madr += writeSize << 2;
sif0.fifo.write((u32*)iopPhysMem(hw_dma9.madr), writeSize);
hw_dma9.madr += writeSize << 2;
// 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
@ -83,13 +83,13 @@ static __fi bool WriteIOPtoFifo()
static __fi bool ProcessEETag()
{
static __aligned16 u32 tag[4];
tDMA_TAG& ptag(*(tDMA_TAG*)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]);
sif0dma.unsafeTransfer(((tDMA_TAG*)(tag)));
sif0dma.unsafeTransfer(&ptag);
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)",
sif0dma.madr, sif0dma.qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]);
@ -102,16 +102,12 @@ static __fi bool ProcessEETag()
switch (ptag.ID)
{
case TAG_REFE:
sif0.ee.end = true;
if (dmacRegs.ctrl.STS != NO_STS)
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
break;
case TAG_CNT: break;
case TAG_REFS:
case TAG_CNTS:
if (dmacRegs.ctrl.STS != NO_STS)
dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16);
break;
break;
case TAG_END:
sif0.ee.end = true;
@ -120,22 +116,29 @@ static __fi bool ProcessEETag()
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()
{
// Process DMA tag at hw_dma(9).tadr
sif0.iop.data = *(sifData *)iopPhysMem(hw_dma(9).tadr);
// 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.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.
hw_dma(9).madr = sif0data & 0xFFFFFF;
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;
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;
// 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_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;
}
@ -265,7 +268,7 @@ static __fi void HandleIOPTransfer()
}
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.
ProcessIOPTag();
}
@ -282,6 +285,9 @@ static __fi void HandleIOPTransfer()
static __fi void Sif0End()
{
psHu32(SBUS_F240) &= ~0x20;
psHu32(SBUS_F240) &= ~0x2000;
SIF_LOG("SIF0 DMA end...");
}
@ -351,8 +357,5 @@ __fi void dmaSIF0()
{
//hwIntcIrq(INTC_SBUS); // not sure, so let's not
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);
sif1.fifo.read((u32*)iopPhysMem(hw_dma(10).madr), readSize);
psxCpu->Clear(hw_dma(10).madr, readSize);
hw_dma(10).madr += readSize << 2;
sif1.fifo.read((u32*)iopPhysMem(hw_dma10.madr), readSize);
psxCpu->Clear(hw_dma10.madr, readSize);
hw_dma10.madr += readSize << 2;
sif1.iop.cycles += readSize >> 2; // fixme: should be >> 4
sif1.iop.counter -= readSize;
@ -151,7 +151,7 @@ static __fi bool SIFIOPReadTag()
sif1data & 0xffffff, sif1words, sif1tag.ID, sif1tag.IRQ);
// Only use the first 24 bits.
hw_dma(10).madr = sif1data & 0xffffff;
hw_dma10.madr = sif1data & 0xffffff;
sif1.iop.counter = sif1words;
if (sif1tag.IRQ || (sif1tag.ID & 4)) sif1.iop.end = true;
@ -276,6 +276,9 @@ static __fi void HandleIOPTransfer()
static __fi void Sif1End()
{
psHu32(SBUS_F240) &= ~0x40;
psHu32(SBUS_F240) &= ~0x4000;
SIF_LOG("SIF1 DMA end...");
}
@ -349,9 +352,5 @@ __fi void dmaSIF1()
if (sif1.iop.busy)
{
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];
// Process DMA tag at hw_dma(9).tadr
sif0.iop.data = *(sifData *)iopPhysMem(hw_dma(9).tadr);
// 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.
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.
hw_dma(9).madr = sif0data & 0xFFFFFF;
hw_dma9.madr = sif0data & 0xFFFFFF;
sif0.iop.counter = sif0words;
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)"
"\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]);
sif0dma.unsafeTransfer(((tDMA_TAG*)(tag)));
@ -98,7 +98,7 @@ s32 DoSifRead(u32 iopAvailable)
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.
//Cpu->Clear(sif0dma.madr, readSize*4);