mirror of https://github.com/PCSX2/pcsx2.git
Couple of fixes, one for Kingdom Hearts 2 Issue 239, others might help textures in the GT games (maybe!)
Also prepared some code to add support for VU looping in MTGS mode, this will require a GS Spec update, so its commented out for now until i can sync an update with Gabest. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1289 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
e384d001da
commit
aa64a21e93
|
@ -265,7 +265,7 @@ protected:
|
||||||
// Processes a GIFtag & packet, and throws out some gsIRQs as needed.
|
// Processes a GIFtag & packet, and throws out some gsIRQs as needed.
|
||||||
// Used to keep interrupts in sync with the EE, while the GS itself
|
// Used to keep interrupts in sync with the EE, while the GS itself
|
||||||
// runs potentially several frames behind.
|
// runs potentially several frames behind.
|
||||||
u32 _gifTransferDummy( GIF_PATH pathidx, const u8 *pMem, u32 size );
|
int _gifTransferDummy( GIF_PATH pathidx, const u8 *pMem, u32 size );
|
||||||
|
|
||||||
// Used internally by SendSimplePacket type functions
|
// Used internally by SendSimplePacket type functions
|
||||||
uint _PrepForSimplePacket();
|
uint _PrepForSimplePacket();
|
||||||
|
|
|
@ -58,8 +58,6 @@ __forceinline void gsInterrupt() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Path3progress == 2) vif1Regs->stat &= ~VIF1_STAT_VGW;
|
|
||||||
|
|
||||||
if (gif->qwc > 0 || gspath3done == 0) {
|
if (gif->qwc > 0 || gspath3done == 0) {
|
||||||
if (!(psHu32(DMAC_CTRL) & 0x1)) {
|
if (!(psHu32(DMAC_CTRL) & 0x1)) {
|
||||||
Console::Notice("gs dma masked, re-scheduling...");
|
Console::Notice("gs dma masked, re-scheduling...");
|
||||||
|
@ -72,12 +70,14 @@ __forceinline void gsInterrupt() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vif1Regs->stat &= ~VIF1_STAT_VGW;
|
||||||
gspath3done = 0;
|
gspath3done = 0;
|
||||||
gscycles = 0;
|
gscycles = 0;
|
||||||
gif->chcr &= ~0x100;
|
gif->chcr &= ~0x100;
|
||||||
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
||||||
GSCSRr |= 0x4000; //FIFO empty
|
GSCSRr |= 0x4000; //FIFO empty
|
||||||
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
|
psHu32(GIF_STAT) &= ~GIF_STAT_P3Q;
|
||||||
|
//psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
|
||||||
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
|
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
|
||||||
hwDmacIrq(DMAC_GIF);
|
hwDmacIrq(DMAC_GIF);
|
||||||
GIF_LOG("GIF DMA end");
|
GIF_LOG("GIF DMA end");
|
||||||
|
@ -86,7 +86,7 @@ __forceinline void gsInterrupt() {
|
||||||
|
|
||||||
static u32 WRITERING_DMA(u32 *pMem, u32 qwc)
|
static u32 WRITERING_DMA(u32 *pMem, u32 qwc)
|
||||||
{
|
{
|
||||||
psHu32(GIF_STAT) |= 0xE00;
|
psHu32(GIF_STAT) |= GIF_STAT_APATH3 | GIF_STAT_OPH;
|
||||||
|
|
||||||
|
|
||||||
if( mtgsThread != NULL )
|
if( mtgsThread != NULL )
|
||||||
|
@ -107,6 +107,7 @@ static u32 WRITERING_DMA(u32 *pMem, u32 qwc)
|
||||||
memcpy_aligned(pgsmem, pMem, sizetoread<<4);
|
memcpy_aligned(pgsmem, pMem, sizetoread<<4);
|
||||||
|
|
||||||
mtgsThread->SendDataPacket();
|
mtgsThread->SendDataPacket();
|
||||||
|
if(Path3progress == 2) psHu32(GIF_STAT)&= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0
|
||||||
return sizetoread;
|
return sizetoread;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -243,6 +244,7 @@ void GIFdma()
|
||||||
|
|
||||||
if(Path3progress == 2/* && gif->qwc != 0*/)
|
if(Path3progress == 2/* && gif->qwc != 0*/)
|
||||||
{
|
{
|
||||||
|
vif1Regs->stat &= ~VIF1_STAT_VGW;
|
||||||
dmaGIFend();
|
dmaGIFend();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -347,8 +349,9 @@ void dmaGIF() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gspath3done = 0; // For some reason this doesnt clear? So when the system starts the thread, we will clear it :)
|
|
||||||
|
|
||||||
|
gspath3done = 0; // For some reason this doesnt clear? So when the system starts the thread, we will clear it :)
|
||||||
|
psHu32(GIF_STAT) |= GIF_STAT_P3Q;
|
||||||
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
||||||
GSCSRr |= 0x8000; //FIFO full
|
GSCSRr |= 0x8000; //FIFO full
|
||||||
psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [used to be 0xE00; // OPH=1 | APATH=3]
|
psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [used to be 0xE00; // OPH=1 | APATH=3]
|
||||||
|
@ -376,7 +379,7 @@ void dmaGIF() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Halflife sets a QWC amount in chain mode, no tadr set.
|
//Halflife sets a QWC amount in chain mode, no tadr set.
|
||||||
if((gif->qwc > 0) && ((gif->chcr & 0x4) == 0x4)) gspath3done = 1;
|
if(gif->qwc > 0) gspath3done = 1;
|
||||||
|
|
||||||
GIFdma();
|
GIFdma();
|
||||||
}
|
}
|
||||||
|
@ -391,7 +394,7 @@ static __forceinline int mfifoGIFrbTransfer() {
|
||||||
if ((gif->madr+mfifoqwc*16) > (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16))
|
if ((gif->madr+mfifoqwc*16) > (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16))
|
||||||
{
|
{
|
||||||
int s1 = ((psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16) - gif->madr) >> 4;
|
int s1 = ((psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16) - gif->madr) >> 4;
|
||||||
|
int s2 = (mfifoqwc - s1);
|
||||||
// fixme - I don't think these should use WRITERING_DMA, since our source
|
// fixme - I don't think these should use WRITERING_DMA, since our source
|
||||||
// isn't the DmaGetAddr(gif->madr) address that WRITERING_DMA expects.
|
// isn't the DmaGetAddr(gif->madr) address that WRITERING_DMA expects.
|
||||||
|
|
||||||
|
@ -400,13 +403,14 @@ static __forceinline int mfifoGIFrbTransfer() {
|
||||||
if (src == NULL) return -1;
|
if (src == NULL) return -1;
|
||||||
s1 = WRITERING_DMA(src, s1);
|
s1 = WRITERING_DMA(src, s1);
|
||||||
|
|
||||||
if(s1 == (((psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16) - gif->madr) >> 4))
|
if(s1 == (mfifoqwc - s2))
|
||||||
{
|
{
|
||||||
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
|
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
|
||||||
src = (u32*)PSM(psHu32(DMAC_RBOR));
|
src = (u32*)PSM(psHu32(DMAC_RBOR));
|
||||||
if (src == NULL) return -1;
|
if (src == NULL) return -1;
|
||||||
mfifoqwc = WRITERING_DMA(src, (mfifoqwc - s1)) + s1;
|
s2 = WRITERING_DMA(src, s2);
|
||||||
}
|
} else s2 = 0;
|
||||||
|
mfifoqwc = s1 + s2;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -579,10 +583,10 @@ void gifMFIFOInterrupt()
|
||||||
if (!gifmfifoirq) gifqwc = 0;
|
if (!gifmfifoirq) gifqwc = 0;
|
||||||
gifstate = GIF_STATE_READY;
|
gifstate = GIF_STATE_READY;
|
||||||
gif->chcr &= ~0x100;
|
gif->chcr &= ~0x100;
|
||||||
|
vif1Regs->stat &= ~VIF1_STAT_VGW;
|
||||||
hwDmacIrq(DMAC_GIF);
|
hwDmacIrq(DMAC_GIF);
|
||||||
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
||||||
GSCSRr |= 0x4000; //FIFO empty
|
GSCSRr |= 0x4000; //FIFO empty
|
||||||
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
|
|
||||||
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
|
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
pcsx2/Hw.h
17
pcsx2/Hw.h
|
@ -288,6 +288,23 @@ enum DMACIrqs
|
||||||
#define VIF_STAT_ER1 (1<<13)
|
#define VIF_STAT_ER1 (1<<13)
|
||||||
#define VIF_STAT_FDR (1<<23)
|
#define VIF_STAT_FDR (1<<23)
|
||||||
|
|
||||||
|
//GIF_STAT
|
||||||
|
|
||||||
|
#define GIF_STAT_M3R (1) //GIF_MODE Mask
|
||||||
|
#define GIF_STAT_M3P (1<<1) //VIF PATH3 Mask
|
||||||
|
#define GIF_STAT_IMT (1<<2) //Intermittent Transfer Mode
|
||||||
|
#define GIF_STAT_PSE (1<<3) //Temporary Transfer Stop
|
||||||
|
#define GIF_STAT_IP3 (1<<5) //Interrupted PATH3
|
||||||
|
#define GIF_STAT_P3Q (1<<6) //PATH3 request Queued
|
||||||
|
#define GIF_STAT_P2Q (1<<7) //PATH2 request Queued
|
||||||
|
#define GIF_STAT_P1Q (1<<8) //PATH1 request Queued
|
||||||
|
#define GIF_STAT_OPH (1<<9) //Output Path (Outputting Data)
|
||||||
|
#define GIF_STAT_APATH1 (1<<10) //Data Transfer Path 1 (In progress)
|
||||||
|
#define GIF_STAT_APATH2 (2<<10) //Data Transfer Path 2 (In progress)
|
||||||
|
#define GIF_STAT_APATH3 (3<<10) //Data Transfer Path 3 (In progress) (Mask too)
|
||||||
|
#define GIF_STAT_DIR (1<<12) //Transfer Direction
|
||||||
|
#define GIF_STAT_FQC (31<<24) //QWC in GIF-FIFO
|
||||||
|
|
||||||
//DMA interrupts & masks
|
//DMA interrupts & masks
|
||||||
enum DMAInter
|
enum DMAInter
|
||||||
{
|
{
|
||||||
|
|
|
@ -259,10 +259,11 @@ void mtgsThreadObject::Reset()
|
||||||
// Used to keep interrupts in sync with the EE, while the GS itself
|
// Used to keep interrupts in sync with the EE, while the GS itself
|
||||||
// runs potentially several frames behind.
|
// runs potentially several frames behind.
|
||||||
// size - size of the packet in simd128's
|
// size - size of the packet in simd128's
|
||||||
__forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u8* pMem, u32 size )
|
__forceinline int mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u8* pMem, u32 size )
|
||||||
{
|
{
|
||||||
GIFPath& path = m_path[pathidx];
|
GIFPath& path = m_path[pathidx];
|
||||||
|
/* bool path1loop = false;
|
||||||
|
int startval = size;*/
|
||||||
#ifdef PCSX2_GSRING_SAMPLING_STATS
|
#ifdef PCSX2_GSRING_SAMPLING_STATS
|
||||||
static uptr profStartPtr = 0;
|
static uptr profStartPtr = 0;
|
||||||
static uptr profEndPtr = 0;
|
static uptr profEndPtr = 0;
|
||||||
|
@ -296,9 +297,24 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u
|
||||||
|
|
||||||
if( pathidx == 0 )
|
if( pathidx == 0 )
|
||||||
{
|
{
|
||||||
|
// int transize = 0;
|
||||||
// hack: if too much data for VU1, just ignore.
|
// hack: if too much data for VU1, just ignore.
|
||||||
|
|
||||||
// The GIF is evil : if nreg is 0, it's really 16. Otherwise it's the value in nreg.
|
// The GIF is evil : if nreg is 0, it's really 16. Otherwise it's the value in nreg.
|
||||||
|
/*const int numregs = path.tag.nreg ? path.tag.nreg : 16;
|
||||||
|
if(path.tag.flg < 2)
|
||||||
|
{
|
||||||
|
transize = (path.tag.nloop * numregs);
|
||||||
|
}
|
||||||
|
else transize = path.tag.nloop;
|
||||||
|
|
||||||
|
if(transize > (path.tag.flg == 1 ? 0x800 : 0x400))
|
||||||
|
{
|
||||||
|
//DevCon::Notice("Too much data");
|
||||||
|
path.tag.nloop = 0;
|
||||||
|
if(path1loop == true)return ++size - 0x400;
|
||||||
|
else return ++size;
|
||||||
|
}*/
|
||||||
const int numregs = ((path.tag.nreg-1)&15)+1;
|
const int numregs = ((path.tag.nreg-1)&15)+1;
|
||||||
|
|
||||||
if((path.tag.nloop * numregs) > (size * ((path.tag.flg == 1) ? 2 : 1)))
|
if((path.tag.nloop * numregs) > (size * ((path.tag.flg == 1) ? 2 : 1)))
|
||||||
|
@ -374,7 +390,22 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pathidx == 0 || pathidx == 2)
|
if(pathidx == 0)
|
||||||
|
{
|
||||||
|
if(path.tag.eop && path.tag.nloop == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*if((path.tag.nloop > 0 || (!path.tag.eop && path.tag.nloop == 0)) && size == 0)
|
||||||
|
{
|
||||||
|
if(path1loop == true) return size - 0x400;
|
||||||
|
//DevCon::Notice("Looping Nloop %x, Eop %x, FLG %x", params path.tag.nloop, path.tag.eop, path.tag.flg);
|
||||||
|
size = 0x400;
|
||||||
|
pMem -= 0x4000;
|
||||||
|
path1loop = true;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
if(pathidx == 2)
|
||||||
{
|
{
|
||||||
if(path.tag.eop && path.tag.nloop == 0)
|
if(path.tag.eop && path.tag.nloop == 0)
|
||||||
{
|
{
|
||||||
|
@ -386,6 +417,11 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u
|
||||||
|
|
||||||
if(pathidx == 0)
|
if(pathidx == 0)
|
||||||
{
|
{
|
||||||
|
//If the XGKick has spun around the VU memory end address, we need to INCREASE the size sent.
|
||||||
|
/*if(path1loop == true)
|
||||||
|
{
|
||||||
|
return (size - 0x400); //This will cause a negative making eg. size(20) - retval(-30) = 50;
|
||||||
|
}*/
|
||||||
if(size == 0 && path.tag.nloop > 0)
|
if(size == 0 && path.tag.nloop > 0)
|
||||||
{
|
{
|
||||||
path.tag.nloop = 0;
|
path.tag.nloop = 0;
|
||||||
|
@ -533,8 +569,8 @@ int mtgsThreadObject::Callback()
|
||||||
const u128* data = m_RingBuffer.GetPtr( m_RingPos+1 );
|
const u128* data = m_RingBuffer.GetPtr( m_RingPos+1 );
|
||||||
|
|
||||||
// make sure that tag>>16 is the MAX size readable
|
// make sure that tag>>16 is the MAX size readable
|
||||||
//GSgifTransfer1(((u32*)data) - 0x1000 + 4*qsize, 0x4000-qsize*16);
|
|
||||||
GSgifTransfer1((u32*)(data - 0x400 + qsize), 0x4000-qsize*16);
|
GSgifTransfer1((u32*)(data - 0x400 + qsize), 0x4000-qsize*16);
|
||||||
|
//GSgifTransfer1((u32*)data, qsize);
|
||||||
ringposinc += qsize;
|
ringposinc += qsize;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -863,6 +899,7 @@ int mtgsThreadObject::PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 s
|
||||||
gif->madr += (size - retval) * 16;
|
gif->madr += (size - retval) * 16;
|
||||||
gif->qwc -= size - retval;
|
gif->qwc -= size - retval;
|
||||||
}
|
}
|
||||||
|
//if(retval < 0) DevCon::Notice("Increasing size from %x to %x path %x", params size, size-retval, pathidx+1);
|
||||||
size = size - retval;
|
size = size - retval;
|
||||||
m_packet_size = size;
|
m_packet_size = size;
|
||||||
size++; // takes into account our command qword.
|
size++; // takes into account our command qword.
|
||||||
|
|
|
@ -2061,7 +2061,33 @@ void _vuXGKICK(VURegs * VU)
|
||||||
ptr = (u32*)GET_VU_MEM(VU, 0);
|
ptr = (u32*)GET_VU_MEM(VU, 0);
|
||||||
memcpy(&tempmem[temp], ptr, ((VU->VI[_Is_].US[0]*16) & 0x3fff));
|
memcpy(&tempmem[temp], ptr, ((VU->VI[_Is_].US[0]*16) & 0x3fff));
|
||||||
GSGIFTRANSFER1((u32*)&tempmem[0], 0);
|
GSGIFTRANSFER1((u32*)&tempmem[0], 0);
|
||||||
} else*/ GSGIFTRANSFER1((u32*)VU->Mem, (VU->VI[_Is_].US[0]*16) & 0x3fff);
|
} else*/
|
||||||
|
//DevCon::Notice("Addr %x", params VU->VI[_Is_].US[0] & 0x3fff);
|
||||||
|
if( mtgsThread != NULL )
|
||||||
|
{
|
||||||
|
u32* data = (u32*)((u8*)VU->Mem + ((VU->VI[_Is_].US[0]*16) & 0x3fff));
|
||||||
|
u32 size;
|
||||||
|
size = mtgsThread->PrepDataPacket( GIF_PATH_1, data, (0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff)) >> 4);
|
||||||
|
{
|
||||||
|
u8* pmem = mtgsThread->GetDataPacketPtr();
|
||||||
|
|
||||||
|
if((size << 4) > (u32)(0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff)))
|
||||||
|
{
|
||||||
|
//DevCon::Notice("addr + Size = 0x%x, transferring %x then doing %x", params ((VU->VI[_Is_].US[0]*16) & 0x3fff) + (size << 4), (0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff)) >> 4, size - (0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff) >> 4));
|
||||||
|
memcpy_aligned(pmem, (u8*)VU->Mem+((VU->VI[_Is_].US[0]*16) & 0x3fff), 0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff));
|
||||||
|
size -= (0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff)) >> 4;
|
||||||
|
//DevCon::Notice("Size left %x", params size);
|
||||||
|
pmem += 0x4000-((VU->VI[_Is_].US[0]*16) & 0x3fff);
|
||||||
|
memcpy_aligned(pmem, (u8*)VU->Mem, size<<4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy_aligned(pmem, (u8*)VU->Mem+((VU->VI[_Is_].US[0]*16) & 0x3fff), size<<4);
|
||||||
|
}
|
||||||
|
mtgsThread->SendDataPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
}else GSGIFTRANSFER1((u32*)VU->Mem, (VU->VI[_Is_].US[0]*16) & 0x3fff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _vuXTOP(VURegs * VU) {
|
void _vuXTOP(VURegs * VU) {
|
||||||
|
|
|
@ -623,8 +623,8 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
|
||||||
if(tempsize > (u32)(VIFdmanum ? 0x4000 : 0x1000))
|
if(tempsize > (u32)(VIFdmanum ? 0x4000 : 0x1000))
|
||||||
{
|
{
|
||||||
|
|
||||||
//DevCon::Notice("VIF%x Unpack ending %x > %x", params VIFdmanum, tempsize, VIFdmanum ? 0x4000 : 0x1000);
|
|
||||||
if(vifRegs->cycle.cl == 1 && ((u32)(VIFdmanum ? 0x4000 : 0x1000) + ((vifRegs->cycle.cl - vifRegs->cycle.wl) * 16)) == tempsize
|
if(((vifRegs->cycle.cl != vifRegs->cycle.wl) && ((u32)(VIFdmanum ? 0x4000 : 0x1000) + ((vifRegs->cycle.cl - vifRegs->cycle.wl) * 16)) == tempsize)
|
||||||
|| tempsize == (u32)(VIFdmanum ? 0x4000 : 0x1000))
|
|| tempsize == (u32)(VIFdmanum ? 0x4000 : 0x1000))
|
||||||
{
|
{
|
||||||
//Its a red herring! so ignore it! SSE unpacks will be much quicker
|
//Its a red herring! so ignore it! SSE unpacks will be much quicker
|
||||||
|
@ -632,6 +632,7 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//DevCon::Notice("VIF%x Unpack ending %x > %x", params VIFdmanum, tempsize, VIFdmanum ? 0x4000 : 0x1000);
|
||||||
tempsize = size;
|
tempsize = size;
|
||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
|
@ -1678,7 +1679,7 @@ static __forceinline void vif1UNPACK(u32 *data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vif1FLUSH();
|
//vif1FLUSH();
|
||||||
|
|
||||||
vl = (vif1.cmd) & 0x3;
|
vl = (vif1.cmd) & 0x3;
|
||||||
vn = (vif1.cmd >> 2) & 0x3;
|
vn = (vif1.cmd >> 2) & 0x3;
|
||||||
|
@ -1890,7 +1891,7 @@ static int __fastcall Vif1TransDirectHL(u32 *data)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
psHu32(GIF_STAT) &= ~0x80;
|
psHu32(GIF_STAT) &= ~GIF_STAT_APATH2;
|
||||||
ret = vif1.tag.size;
|
ret = vif1.tag.size;
|
||||||
vif1.tag.size = 0;
|
vif1.tag.size = 0;
|
||||||
vif1.cmd = 0;
|
vif1.cmd = 0;
|
||||||
|
@ -2057,7 +2058,7 @@ static void Vif1CMDFlush() // FLUSH/E/A
|
||||||
|
|
||||||
if((vif1.cmd & 0x7f) == 0x13)
|
if((vif1.cmd & 0x7f) == 0x13)
|
||||||
{
|
{
|
||||||
if(Path3progress != 2 && gif->chcr & 0x100) // Gif is already transferring so wait for it.
|
if((Path3progress != 2 || !vif1Regs->mskpath3) && gif->chcr & 0x100) // Gif is already transferring so wait for it.
|
||||||
{
|
{
|
||||||
vif1Regs->stat |= VIF1_STAT_VGW;
|
vif1Regs->stat |= VIF1_STAT_VGW;
|
||||||
}
|
}
|
||||||
|
@ -2089,7 +2090,7 @@ static void Vif1CMDSTRowCol() // STROW / STCOL
|
||||||
static void Vif1CMDMPGTransfer() // MPG
|
static void Vif1CMDMPGTransfer() // MPG
|
||||||
{
|
{
|
||||||
int vifNum;
|
int vifNum;
|
||||||
vif1FLUSH();
|
//vif1FLUSH();
|
||||||
vifNum = (u8)(vif1Regs->code >> 16);
|
vifNum = (u8)(vif1Regs->code >> 16);
|
||||||
|
|
||||||
if (vifNum == 0) vifNum = 256;
|
if (vifNum == 0) vifNum = 256;
|
||||||
|
@ -2113,15 +2114,15 @@ static void Vif1CMDDirectHL() // DIRECT/HL
|
||||||
//FIXME: This should have timing in both cases, see note below.
|
//FIXME: This should have timing in both cases, see note below.
|
||||||
if((vif1.cmd & 0x7f) == 0x51)
|
if((vif1.cmd & 0x7f) == 0x51)
|
||||||
{
|
{
|
||||||
if(gif->chcr & 0x100 /*&& Path3progress == 0*/) //PATH3 is in image mode, so wait for end of transfer
|
if(gif->chcr & 0x100 && (!vif1Regs->mskpath3 || Path3progress != 2)) //PATH3 is in image mode, so wait for end of transfer
|
||||||
{
|
{
|
||||||
//DevCon::Notice("DirectHL gif chcr %x gif qwc %x mskpth3 %x", params gif->chcr, gif->qwc, vif1Regs->mskpath3);
|
//DevCon::Notice("DirectHL gif chcr %x gif qwc %x mskpth3 %x", params gif->chcr, gif->qwc, vif1Regs->mskpath3);
|
||||||
if(vif1Regs->mskpath3)vif1Regs->stat |= VIF1_STAT_VGW;
|
/*if(vif1Regs->mskpath3)*/vif1Regs->stat |= VIF1_STAT_VGW;
|
||||||
else while(gif->chcr & 0x100) gsInterrupt(); //Hacky as hell (no timing) but Soul Calibur 3 doesnt want timing :(
|
//else while(gif->chcr & 0x100) gsInterrupt(); //Hacky as hell (no timing) but Soul Calibur 3 doesnt want timing :(
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
psHu32(GIF_STAT) |= 0x80;
|
psHu32(GIF_STAT) |= GIF_STAT_APATH2;
|
||||||
|
|
||||||
}
|
}
|
||||||
static void Vif1CMDNull() // invalid opcode
|
static void Vif1CMDNull() // invalid opcode
|
||||||
|
@ -2193,6 +2194,17 @@ int VIF1transfer(u32 *data, int size, int istag)
|
||||||
|
|
||||||
while (vif1.vifpacketsize > 0)
|
while (vif1.vifpacketsize > 0)
|
||||||
{
|
{
|
||||||
|
if((vif1.cmd & 0x7f) == 0x51)
|
||||||
|
{
|
||||||
|
if(gif->chcr & 0x100 && (!vif1Regs->mskpath3 || Path3progress != 2)) //PATH3 is in image mode, so wait for end of transfer
|
||||||
|
{
|
||||||
|
//DevCon::Notice("DirectHL gif chcr %x gif qwc %x mskpth3 %x", params gif->chcr, gif->qwc, vif1Regs->mskpath3);
|
||||||
|
/*if(vif1Regs->mskpath3)*/vif1Regs->stat |= VIF1_STAT_VGW;
|
||||||
|
//else while(gif->chcr & 0x100) gsInterrupt(); //Hacky as hell (no timing) but Soul Calibur 3 doesnt want timing :(
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(vif1Regs->stat & VIF1_STAT_VGW) break;
|
||||||
if (vif1.cmd)
|
if (vif1.cmd)
|
||||||
{
|
{
|
||||||
vif1Regs->stat |= VIF1_STAT_VPS_T; //Decompression has started
|
vif1Regs->stat |= VIF1_STAT_VPS_T; //Decompression has started
|
||||||
|
@ -2350,7 +2362,7 @@ void vif1TransferFromMemory()
|
||||||
}
|
}
|
||||||
FreezeXMMRegs(0);
|
FreezeXMMRegs(0);
|
||||||
|
|
||||||
if (vif1Regs->mskpath3 == 0)vif1Regs->stat &= ~0x1f000000;
|
|
||||||
g_vifCycles += vif1ch->qwc * 2;
|
g_vifCycles += vif1ch->qwc * 2;
|
||||||
vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes
|
vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes
|
||||||
vif1ch->qwc = 0;
|
vif1ch->qwc = 0;
|
||||||
|
@ -2401,6 +2413,7 @@ __forceinline void vif1SetupTransfer()
|
||||||
case 1: //Normal (From memory)
|
case 1: //Normal (From memory)
|
||||||
vif1.inprogress = 1;
|
vif1.inprogress = 1;
|
||||||
vif1.done = true;
|
vif1.done = true;
|
||||||
|
g_vifCycles = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: //Chain
|
case 2: //Chain
|
||||||
|
@ -2513,7 +2526,12 @@ __forceinline void vif1Interrupt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vif1.inprogress) _VIF1chain();
|
if (vif1.inprogress)
|
||||||
|
{
|
||||||
|
_VIF1chain();
|
||||||
|
CPU_INT(1, g_vifCycles);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((!vif1.done) || (vif1.inprogress & 0x1))
|
if ((!vif1.done) || (vif1.inprogress & 0x1))
|
||||||
{
|
{
|
||||||
|
@ -2543,7 +2561,7 @@ __forceinline void vif1Interrupt()
|
||||||
vif1ch->chcr &= ~0x100;
|
vif1ch->chcr &= ~0x100;
|
||||||
g_vifCycles = 0;
|
g_vifCycles = 0;
|
||||||
hwDmacIrq(DMAC_VIF1);
|
hwDmacIrq(DMAC_VIF1);
|
||||||
vif1Regs->stat &= ~0x1F000000; // FQC=0
|
if(vif1ch->chcr & 0x1)vif1Regs->stat &= ~0x1F000000; // FQC=0
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmaVIF1()
|
void dmaVIF1()
|
||||||
|
@ -2557,7 +2575,6 @@ void dmaVIF1()
|
||||||
g_vifCycles = 0;
|
g_vifCycles = 0;
|
||||||
vif1.inprogress = 0;
|
vif1.inprogress = 0;
|
||||||
|
|
||||||
vif1Regs->stat |= 0x10000000; // FQC=16
|
|
||||||
|
|
||||||
if (((psHu32(DMAC_CTRL) & 0xC) == 0x8)) // VIF MFIFO
|
if (((psHu32(DMAC_CTRL) & 0xC) == 0x8)) // VIF MFIFO
|
||||||
{
|
{
|
||||||
|
@ -2591,6 +2608,9 @@ void dmaVIF1()
|
||||||
vif1.dmamode = 2;
|
vif1.dmamode = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(vif1.dmamode != 1)vif1Regs->stat |= 0x10000000; // FQC=16
|
||||||
|
else vif1Regs->stat |= min((u16)16, vif1ch->qwc) << 24; // FQC=16
|
||||||
|
|
||||||
// Chain Mode
|
// Chain Mode
|
||||||
vif1.done = false;
|
vif1.done = false;
|
||||||
vif1Interrupt();
|
vif1Interrupt();
|
||||||
|
@ -2705,7 +2725,7 @@ void vif1Write32(u32 mem, u32 value)
|
||||||
vif1Regs->stat = (vif1Regs->stat & ~VIF1_STAT_FDR) | (value & VIF1_STAT_FDR);
|
vif1Regs->stat = (vif1Regs->stat & ~VIF1_STAT_FDR) | (value & VIF1_STAT_FDR);
|
||||||
if (vif1Regs->stat & VIF1_STAT_FDR)
|
if (vif1Regs->stat & VIF1_STAT_FDR)
|
||||||
{
|
{
|
||||||
vif1Regs->stat |= 0x01000000;
|
vif1Regs->stat |= 0x01000000; // FQC=1 - hack but it checks this is true before tranfer? (fatal frame)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1989,7 +1989,20 @@ void VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr)
|
||||||
//if( size > 0 )
|
//if( size > 0 )
|
||||||
{
|
{
|
||||||
u8* pmem = mtgsThread->GetDataPacketPtr();
|
u8* pmem = mtgsThread->GetDataPacketPtr();
|
||||||
memcpy_aligned(pmem, (u8*)pMem+addr, size<<4);
|
|
||||||
|
/* if((size << 4) > (0x4000-(addr&0x3fff)))
|
||||||
|
{
|
||||||
|
//DevCon::Notice("addr + Size = 0x%x, transferring %x then doing %x", params (addr&0x3fff) + (size << 4), (0x4000-(addr&0x3fff)) >> 4, size - ((0x4000-(addr&0x3fff)) >> 4));
|
||||||
|
memcpy_aligned(pmem, (u8*)pMem+addr, 0x4000-(addr&0x3fff));
|
||||||
|
size -= (0x4000-(addr&0x3fff)) >> 4;
|
||||||
|
//DevCon::Notice("Size left %x", params size);
|
||||||
|
pmem += 0x4000-(addr&0x3fff);
|
||||||
|
memcpy_aligned(pmem, (u8*)pMem, size<<4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{*/
|
||||||
|
memcpy_aligned(pmem, (u8*)pMem+addr, size<<4);
|
||||||
|
// }
|
||||||
mtgsThread->SendDataPacket();
|
mtgsThread->SendDataPacket();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1103,7 +1103,22 @@ void __fastcall mVU_XGKICK_(u32 addr) {
|
||||||
u32 *data = (u32*)(microVU1.regs->Mem + addr);
|
u32 *data = (u32*)(microVU1.regs->Mem + addr);
|
||||||
u32 size = mtgsThread->PrepDataPacket(GIF_PATH_1, data, (0x4000-addr) >> 4);
|
u32 size = mtgsThread->PrepDataPacket(GIF_PATH_1, data, (0x4000-addr) >> 4);
|
||||||
u8 *pDest = mtgsThread->GetDataPacketPtr();
|
u8 *pDest = mtgsThread->GetDataPacketPtr();
|
||||||
memcpy_aligned(pDest, microVU1.regs->Mem + addr, size<<4);
|
/*
|
||||||
|
if((size << 4) > (0x4000-(addr&0x3fff)))
|
||||||
|
{
|
||||||
|
//DevCon::Notice("addr + Size = 0x%x, transferring %x then doing %x", params (addr&0x3fff) + (size << 4), (0x4000-(addr&0x3fff)) >> 4, size - ((0x4000-(addr&0x3fff)) >> 4));
|
||||||
|
memcpy_aligned(pDest, microVU1.regs->Mem + addr, 0x4000-(addr&0x3fff));
|
||||||
|
size -= (0x4000-(addr&0x3fff)) >> 4;
|
||||||
|
//DevCon::Notice("Size left %x", params size);
|
||||||
|
pDest += 0x4000-(addr&0x3fff);
|
||||||
|
memcpy_aligned(pDest, microVU1.regs->Mem, size<<4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*/
|
||||||
|
memcpy_aligned(pDest, microVU1.regs->Mem + addr, size<<4);
|
||||||
|
// }
|
||||||
|
|
||||||
mtgsThread->SendDataPacket();
|
mtgsThread->SendDataPacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue