mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
e06484adb8
commit
3016161920
|
@ -204,65 +204,33 @@ static __ri void DmaExec( void (*func)(), u32 mem, u32 value )
|
||||||
{
|
{
|
||||||
const uint channel = ChannelNumber(mem);
|
const uint channel = ChannelNumber(mem);
|
||||||
|
|
||||||
// The following if ( 0 ) is probably a misunderstanding, broke Katamari videos
|
//As the manual states "Fields other than STR can only be written to when the DMA is stopped"
|
||||||
if( 0 /*psHu8(DMAC_ENABLER+2) == 1*/) //DMA is suspended so we can allow writes to anything
|
//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.
|
//DevCon.Warning(L"32bit Force Stopping %s (Current CHCR %x) while DMA active", ChcrName(mem), reg.chcr._u32, chcr._u32);
|
||||||
if(chcr.STR == 0)
|
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));
|
cpuClearInt( 10 );
|
||||||
if(channel == 1)
|
QueuedDMA._u16 &= ~(1 << 10); //Clear any queued DMA requests for this channel
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
//Sanity Check for possible future bug fix0rs ;p
|
else if(channel == 2)
|
||||||
//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)
|
|
||||||
{
|
{
|
||||||
//DevCon.Warning(L"32bit Force Stopping %s (Current CHCR %x) while DMA active", ChcrName(mem), reg.chcr._u32, chcr._u32);
|
cpuClearInt( 11 );
|
||||||
reg.chcr.STR = 0;
|
QueuedDMA._u16 &= ~(1 << 11); //Clear any queued DMA requests for this channel
|
||||||
//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
|
|
||||||
}
|
}
|
||||||
//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);
|
//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);
|
||||||
|
|
|
@ -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)
|
// Modifies the Source Reg! (ToDo: Optimize modXYZW = 1 cases)
|
||||||
void mVUmergeRegs(const xmm& dest, const xmm& src, int xyzw, bool modXYZW)
|
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]]);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
|
@ -291,7 +291,7 @@ _vifT static __ri bool dVifExecuteUnpack(const u8* data, bool isFill)
|
||||||
((nVifrecCall)b->startPtr)((uptr)dest, (uptr)data);
|
((nVifrecCall)b->startPtr)((uptr)dest, (uptr)data);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DevCon.WriteLn("Running Interpreter Block");
|
VIF_LOG("Running Interpreter Block");
|
||||||
_nVifUnpack(idx, data, vifRegs.mode, isFill);
|
_nVifUnpack(idx, data, vifRegs.mode, isFill);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -22,18 +22,38 @@
|
||||||
#define xMOV64(regX, loc) xMOVUPS(regX, loc)
|
#define xMOV64(regX, loc) xMOVUPS(regX, loc)
|
||||||
#define xMOV128(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 __pagealigned u8 nVifUpkExec[__pagesize*4];
|
||||||
static RecompiledCodeReserve* nVifUpkExec = NULL;
|
static RecompiledCodeReserve* nVifUpkExec = NULL;
|
||||||
|
|
||||||
// Merges xmm vectors without modifying source reg
|
// Merges xmm vectors without modifying source reg
|
||||||
void mergeVectors(xRegisterSSE dest, xRegisterSSE src, xRegisterSSE temp, int xyzw) {
|
void mergeVectors(xRegisterSSE dest, xRegisterSSE src, xRegisterSSE temp, int xyzw) {
|
||||||
if (x86caps.hasStreamingSIMD4Extensions || (xyzw==15)
|
if(dest == temp)
|
||||||
|| (xyzw==12) || (xyzw==11) || (xyzw==8) || (xyzw==3)) {
|
{
|
||||||
mVUmergeRegs(dest, src, xyzw);
|
//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 {
|
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);
|
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 {
|
void VifUnpackSSE_Base::xUPK_V2_16() const {
|
||||||
|
|
||||||
if(UnpkLoopIteration == 0 || !x86caps.hasStreamingSIMD4Extensions)
|
if(UnpkLoopIteration == 0)
|
||||||
{
|
{
|
||||||
if (x86caps.hasStreamingSIMD4Extensions)
|
if (x86caps.hasStreamingSIMD4Extensions)
|
||||||
{
|
{
|
||||||
xPMOVXX16 (workReg);
|
xPMOVXX16 (workReg);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xXOR.PD (destReg, destReg);
|
xMOV64 (workReg, ptr64[srcIndirect]);
|
||||||
xMOV64 (workReg, ptr32[srcIndirect]);
|
xPUNPCK.LWD(workReg, workReg);
|
||||||
xPUNPCK.LWD(workReg, destReg);
|
xShiftR (workReg, 16);
|
||||||
//xShiftR (workReg, 16);
|
}
|
||||||
}
|
xPSHUF.D (destReg, workReg, 0x44); //v1v0v1v0
|
||||||
xPSHUF.D (destReg, workReg, 0x44); //v1v0v1v0
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
xPSHUF.D (destReg, workReg, 0xEE); //v3v2v3v2
|
||||||
xPSHUF.D (destReg, workReg, 0xEE); //v3v2v3v2
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue