Modified my changes from r5392, one small fix and some code movement, thanks to DarkShoelaces for pointing it out.

Also cleaned up the DMA change made in r5393 and added a small comment of explination to why it is now right :P

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5413 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
refraction 2012-09-13 19:55:25 +00:00
parent e06484adb8
commit 3016161920
4 changed files with 67 additions and 97 deletions

View File

@ -204,65 +204,33 @@ static __ri void DmaExec( void (*func)(), u32 mem, u32 value )
{
const uint channel = ChannelNumber(mem);
// The following if ( 0 ) is probably a misunderstanding, broke Katamari videos
if( 0 /*psHu8(DMAC_ENABLER+2) == 1*/) //DMA is suspended so we can allow writes to anything
//As the manual states "Fields other than STR can only be written to when the DMA is stopped"
//Also "The DMA may not stop properly just by writing 0 to STR"
//So the presumption is that STR can be written to (ala force stop the DMA) but nothing else
//If the developer wishes to alter any of the other fields, it must be done AFTER the STR has been written,
//it will not work before or during this event.
if(chcr.STR == 0)
{
//If it stops the DMA, we need to clear any pending interrupts so the DMA doesnt continue.
if(chcr.STR == 0)
//DevCon.Warning(L"32bit Force Stopping %s (Current CHCR %x) while DMA active", ChcrName(mem), reg.chcr._u32, chcr._u32);
reg.chcr.STR = 0;
//We need to clear any existing DMA loops that are in progress else they will continue!
if(channel == 1)
{
//DevCon.Warning(L"32bit %s DMA Stopped on Suspend", ChcrName(mem));
if(channel == 1)
{
cpuClearInt( 10 );
QueuedDMA._u16 &= ~(1 << 10); //Clear any queued DMA requests for this channel
}
else if(channel == 2)
{
cpuClearInt( 11 );
QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel
}
cpuClearInt( channel );
QueuedDMA._u16 &= ~(1 << channel); //Clear any queued DMA requests for this channel
cpuClearInt( 10 );
QueuedDMA._u16 &= ~(1 << 10); //Clear any queued DMA requests for this channel
}
//Sanity Check for possible future bug fix0rs ;p
//Spams on Persona 4 opening.
//if(reg.chcr.TAG != chcr.TAG) DevCon.Warning(L"32bit CHCR Tag on %s changed to %x from %x QWC = %x Channel Active", ChcrName(mem), chcr.TAG, reg.chcr.TAG, reg.qwc);
//Here we update the LOWER CHCR, if a chain is stopped half way through, it can be manipulated in to a different mode
//But we need to preserve the existing tag for now
reg.chcr.set((reg.chcr.TAG << 16) | chcr.lower());
return;
}
else //Else the DMA is running (Not Suspended), so we cant touch it!
{
//As the manual states "Fields other than STR can only be written to when the DMA is stopped"
//Also "The DMA may not stop properly just by writing 0 to STR"
//So the presumption is that STR can be written to (ala force stop the DMA) but nothing else
if(chcr.STR == 0)
else if(channel == 2)
{
//DevCon.Warning(L"32bit Force Stopping %s (Current CHCR %x) while DMA active", ChcrName(mem), reg.chcr._u32, chcr._u32);
reg.chcr.STR = 0;
//We need to clear any existing DMA loops that are in progress else they will continue!
if(channel == 1)
{
cpuClearInt( 10 );
QueuedDMA._u16 &= ~(1 << 10); //Clear any queued DMA requests for this channel
}
else if(channel == 2)
{
cpuClearInt( 11 );
QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel
}
cpuClearInt( channel );
QueuedDMA._u16 &= ~(1 << channel); //Clear any queued DMA requests for this channel
cpuClearInt( 11 );
QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel
}
//else DevCon.Warning(L"32bit Attempted to change %s CHCR (Currently %x) with %x while DMA active, ignoring QWC = %x", ChcrName(mem), reg.chcr._u32, chcr._u32, reg.qwc);
return;
cpuClearInt( channel );
QueuedDMA._u16 &= ~(1 << channel); //Clear any queued DMA requests for this channel
}
//else DevCon.Warning(L"32bit Attempted to change %s CHCR (Currently %x) with %x while DMA active, ignoring QWC = %x", ChcrName(mem), reg.chcr._u32, chcr._u32, reg.qwc);
return;
}
//if(reg.chcr.TAG != chcr.TAG && chcr.MOD == CHAIN_MODE) DevCon.Warning(L"32bit CHCR Tag on %s changed to %x from %x QWC = %x Channel Not Active", ChcrName(mem), chcr.TAG, reg.chcr.TAG, reg.qwc);

View File

@ -142,14 +142,6 @@ void mVUsaveReg(const xmm& reg, xAddressVoid ptr, int xyzw, bool modXYZW)
}
}
static const __aligned16 u32 SSEXYZWMask[4][4] =
{
{0xffffffff, 0xffffffff, 0xffffffff, 0x00000000},
{0xffffffff, 0xffffffff, 0x00000000, 0xffffffff},
{0xffffffff, 0x00000000, 0xffffffff, 0xffffffff},
{0x00000000, 0xffffffff, 0xffffffff, 0xffffffff}
};
// Modifies the Source Reg! (ToDo: Optimize modXYZW = 1 cases)
void mVUmergeRegs(const xmm& dest, const xmm& src, int xyzw, bool modXYZW)
{
@ -215,15 +207,6 @@ void mVUmergeRegs(const xmm& dest, const xmm& src, int xyzw, bool modXYZW)
}
}
}
else if( dest == src )
{
//VIF can sent the temp directory as the source and destination, just need to clear the ones we dont want in which case.
if(!(xyzw & 0x1)) xAND.PS( dest, ptr128[SSEXYZWMask[0]]);
if(!(xyzw & 0x2)) xAND.PS( dest, ptr128[SSEXYZWMask[1]]);
if(!(xyzw & 0x4)) xAND.PS( dest, ptr128[SSEXYZWMask[2]]);
if(!(xyzw & 0x8)) xAND.PS( dest, ptr128[SSEXYZWMask[3]]);
}
}
//------------------------------------------------------------------

View File

@ -291,7 +291,7 @@ _vifT static __ri bool dVifExecuteUnpack(const u8* data, bool isFill)
((nVifrecCall)b->startPtr)((uptr)dest, (uptr)data);
}
else {
DevCon.WriteLn("Running Interpreter Block");
VIF_LOG("Running Interpreter Block");
_nVifUnpack(idx, data, vifRegs.mode, isFill);
}
return true;

View File

@ -22,18 +22,38 @@
#define xMOV64(regX, loc) xMOVUPS(regX, loc)
#define xMOV128(regX, loc) xMOVUPS(regX, loc)
static const __aligned16 u32 SSEXYZWMask[4][4] =
{
{0xffffffff, 0xffffffff, 0xffffffff, 0x00000000},
{0xffffffff, 0xffffffff, 0x00000000, 0xffffffff},
{0xffffffff, 0x00000000, 0xffffffff, 0xffffffff},
{0x00000000, 0xffffffff, 0xffffffff, 0xffffffff}
};
//static __pagealigned u8 nVifUpkExec[__pagesize*4];
static RecompiledCodeReserve* nVifUpkExec = NULL;
// Merges xmm vectors without modifying source reg
void mergeVectors(xRegisterSSE dest, xRegisterSSE src, xRegisterSSE temp, int xyzw) {
if (x86caps.hasStreamingSIMD4Extensions || (xyzw==15)
|| (xyzw==12) || (xyzw==11) || (xyzw==8) || (xyzw==3)) {
mVUmergeRegs(dest, src, xyzw);
if(dest == temp)
{
//VIF can sent the temp directory as the source and destination, just need to clear the ones we dont want in which case.
if(!(xyzw & 0x1)) xAND.PS( dest, ptr128[SSEXYZWMask[0]]);
if(!(xyzw & 0x2)) xAND.PS( dest, ptr128[SSEXYZWMask[1]]);
if(!(xyzw & 0x4)) xAND.PS( dest, ptr128[SSEXYZWMask[2]]);
if(!(xyzw & 0x8)) xAND.PS( dest, ptr128[SSEXYZWMask[3]]);
}
else {
if(temp != src) xMOVAPS(temp, src); //Sometimes we don't care if the source is modified and is temp reg.
mVUmergeRegs(dest, temp, xyzw);
else
{
if (x86caps.hasStreamingSIMD4Extensions || (xyzw==15)
|| (xyzw==12) || (xyzw==11) || (xyzw==8) || (xyzw==3)) {
mVUmergeRegs(dest, src, xyzw);
}
else {
if(temp != src) xMOVAPS(temp, src); //Sometimes we don't care if the source is modified and is temp reg.
mVUmergeRegs(dest, temp, xyzw);
}
}
}
@ -174,26 +194,25 @@ void VifUnpackSSE_Base::xUPK_V2_32() const {
void VifUnpackSSE_Base::xUPK_V2_16() const {
if(UnpkLoopIteration == 0 || !x86caps.hasStreamingSIMD4Extensions)
{
if (x86caps.hasStreamingSIMD4Extensions)
{
xPMOVXX16 (workReg);
}
else
{
xXOR.PD (destReg, destReg);
xMOV64 (workReg, ptr32[srcIndirect]);
xPUNPCK.LWD(workReg, destReg);
//xShiftR (workReg, 16);
}
xPSHUF.D (destReg, workReg, 0x44); //v1v0v1v0
}
else
{
xPSHUF.D (destReg, workReg, 0xEE); //v3v2v3v2
}
if(UnpkLoopIteration == 0)
{
if (x86caps.hasStreamingSIMD4Extensions)
{
xPMOVXX16 (workReg);
}
else
{
xMOV64 (workReg, ptr64[srcIndirect]);
xPUNPCK.LWD(workReg, workReg);
xShiftR (workReg, 16);
}
xPSHUF.D (destReg, workReg, 0x44); //v1v0v1v0
}
else
{
xPSHUF.D (destReg, workReg, 0xEE); //v3v2v3v2
}
}