mirror of https://github.com/PCSX2/pcsx2.git
SIGNAL! Area 51 WORKS! Soul Calibur 3 WORKS! probably broke loads! :P But thats the first time Area 51 has worked in years.
Only kidding, it should be awsome now, Also added a debug message incase some Paths are queued on a FINISH, any broken graphics when this shows up (or failure to load) should be reported asap! Thanks to jake for his hard work getting signal and my optimizations working :) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3400 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
968eed2822
commit
b003a3bd47
18
pcsx2/GS.cpp
18
pcsx2/GS.cpp
|
@ -113,12 +113,22 @@ static __forceinline void gsCSRwrite( const tGS_CSR& csr )
|
|||
// SIGNAL : What's not known here is whether or not the SIGID register should be updated
|
||||
// here or when the IMR is cleared (below).
|
||||
|
||||
GIF_LOG("GS SIGNAL (pending) data=%x_%x IMR=%x CSRr=%x\n",SIGNAL_Data_Pending[0], SIGNAL_Data_Pending[1], GSIMR, GSCSRr);
|
||||
GSSIGLBLID.SIGID = (GSSIGLBLID.SIGID&~SIGNAL_Data_Pending[1])|(SIGNAL_Data_Pending[0]&SIGNAL_Data_Pending[1]);
|
||||
if(SIGNAL_IMR_Pending == true)
|
||||
{
|
||||
//DevCon.Warning("Firing pending signal");
|
||||
GIF_LOG("GS SIGNAL (pending) data=%x_%x IMR=%x CSRr=%x\n",SIGNAL_Data_Pending[0], SIGNAL_Data_Pending[1], GSIMR, GSCSRr);
|
||||
GSSIGLBLID.SIGID = (GSSIGLBLID.SIGID&~SIGNAL_Data_Pending[1])|(SIGNAL_Data_Pending[0]&SIGNAL_Data_Pending[1]);
|
||||
|
||||
CSRreg.SIGNAL = false;
|
||||
if (!(GSIMR&0x100))
|
||||
gsIrq();
|
||||
|
||||
CSRreg.SIGNAL = true; //Just to be sure :P
|
||||
}
|
||||
else CSRreg.SIGNAL = false;
|
||||
|
||||
// [TODO] (SIGNAL) : Re-enable GIFpath DMAs here!
|
||||
SIGNAL_IMR_Pending = false;
|
||||
|
||||
if(gifRegs->stat.P1Q && gifRegs->stat.APATH <= GIF_APATH1) gsPath1Interrupt();
|
||||
}
|
||||
|
||||
if(csr.FINISH) CSRreg.FINISH = false;
|
||||
|
|
|
@ -89,10 +89,20 @@ void gsPath1Interrupt()
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
extern bool SIGNAL_IMR_Pending;
|
||||
|
||||
__forceinline void gsInterrupt()
|
||||
{
|
||||
GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle);
|
||||
|
||||
if(SIGNAL_IMR_Pending == true)
|
||||
{
|
||||
//DevCon.Warning("Path 3 Paused");
|
||||
CPU_INT(DMAC_GIF, 128);
|
||||
return;
|
||||
}
|
||||
|
||||
if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE && gifRegs->stat.APATH == GIF_APATH3 )
|
||||
{
|
||||
gifRegs->stat.OPH = false;
|
||||
|
@ -100,6 +110,7 @@ __forceinline void gsInterrupt()
|
|||
gifRegs->stat.APATH = GIF_APATH_IDLE;
|
||||
if(gifRegs->stat.P1Q) gsPath1Interrupt();
|
||||
}
|
||||
|
||||
|
||||
if (!(gif->chcr.STR))
|
||||
{
|
||||
|
|
|
@ -255,6 +255,8 @@ __forceinline void vif1SetupTransfer()
|
|||
}
|
||||
}
|
||||
|
||||
extern bool SIGNAL_IMR_Pending;
|
||||
|
||||
bool CheckPath2GIF(int channel)
|
||||
{
|
||||
if ((vif1Regs->stat.VGW))
|
||||
|
@ -327,6 +329,12 @@ bool CheckPath2GIF(int channel)
|
|||
}
|
||||
}
|
||||
}
|
||||
if(SIGNAL_IMR_Pending == true && (vif1.cmd & 0x7e) == 0x50)
|
||||
{
|
||||
//DevCon.Warning("Path 2 Paused");
|
||||
CPU_INT(channel, 128);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
__forceinline void vif1Interrupt()
|
||||
|
|
|
@ -114,6 +114,8 @@ vifOp(vifCode_Base) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
extern bool SIGNAL_IMR_Pending;
|
||||
|
||||
template<int idx> _f int _vifCode_Direct(int pass, u8* data, bool isDirectHL) {
|
||||
pass1 {
|
||||
vif1Only();
|
||||
|
@ -150,13 +152,21 @@ template<int idx> _f int _vifCode_Direct(int pass, u8* data, bool isDirectHL) {
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
if(SIGNAL_IMR_Pending == true)
|
||||
{
|
||||
DevCon.Warning("Path 2 Paused (At start)");
|
||||
vif1.vifstalled = true;
|
||||
return 0;
|
||||
}
|
||||
if (gifRegs->stat.PSE) // temporarily stop
|
||||
{
|
||||
Console.WriteLn("Gif dma temp paused? VIF DIRECT");
|
||||
vif1.GifWaitState = 3;
|
||||
vif1.vifstalled = true;
|
||||
vif1Regs->stat.VGW = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gifRegs->stat.clear_flags(GIF_STAT_P2Q);
|
||||
|
|
|
@ -147,7 +147,7 @@ static void __fastcall RegHandlerSIGNAL(const u32* data)
|
|||
// Time to ignore all subsequent drawing operations. (which is not yet supported)
|
||||
if (!SIGNAL_IMR_Pending)
|
||||
{
|
||||
DevCon.WriteLn( Color_StrongOrange, "GS SIGNAL double throw encountered!" );
|
||||
//DevCon.WriteLn( Color_StrongOrange, "GS SIGNAL double throw encountered!" );
|
||||
SIGNAL_IMR_Pending = true;
|
||||
SIGNAL_Data_Pending[0] = data[0];
|
||||
SIGNAL_Data_Pending[1] = data[1];
|
||||
|
@ -572,7 +572,7 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size)
|
|||
gsHandler(pMem);
|
||||
}
|
||||
incTag(16, 1);
|
||||
} while(StepReg() && size > 0);
|
||||
} while(StepReg() && size > 0 && SIGNAL_IMR_Pending == false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -680,6 +680,7 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size)
|
|||
// FINISH is *not* a per-path register, and it seems to pretty clearly indicate that all active
|
||||
// drawing *and* image transfer actions must be finished before the IRQ raises.
|
||||
|
||||
if(gifRegs->stat.P1Q || gifRegs->stat.P2Q || gifRegs->stat.P3Q) DevCon.Warning("Early FINISH signal! P1 %x P2 %x P3 %x", gifRegs->stat.P1Q, gifRegs->stat.P2Q, gifRegs->stat.P3Q);
|
||||
if (!(GSIMR&0x200) && !s_gifPath.path[0].IsActive() && !s_gifPath.path[1].IsActive() && !s_gifPath.path[2].IsActive())
|
||||
{
|
||||
gsIrq();
|
||||
|
@ -687,6 +688,11 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size)
|
|||
}
|
||||
break;
|
||||
}
|
||||
if(SIGNAL_IMR_Pending == true)
|
||||
{
|
||||
//DevCon.Warning("Path %x", pathidx + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size = (startSize - size);
|
||||
|
|
|
@ -1101,7 +1101,10 @@ mVUop(mVU_XITOP) {
|
|||
//------------------------------------------------------------------
|
||||
// XGkick
|
||||
//------------------------------------------------------------------
|
||||
|
||||
extern void gsPath1Interrupt();
|
||||
extern bool SIGNAL_IMR_Pending;
|
||||
|
||||
void __fastcall mVU_XGKICK_(u32 addr) {
|
||||
addr &= 0x3ff;
|
||||
u8* data = microVU1.regs->Mem + (addr*16);
|
||||
|
@ -1109,7 +1112,7 @@ void __fastcall mVU_XGKICK_(u32 addr) {
|
|||
u32 size;
|
||||
u8* pDest;
|
||||
|
||||
if(gifRegs->stat.APATH <= GIF_APATH1 || (gifRegs->stat.APATH == GIF_APATH3 && gifRegs->stat.IP3 == true))
|
||||
if(gifRegs->stat.APATH <= GIF_APATH1 || (gifRegs->stat.APATH == GIF_APATH3 && gifRegs->stat.IP3 == true) && SIGNAL_IMR_Pending == false)
|
||||
{
|
||||
|
||||
if(Path1WritePos != 0)
|
||||
|
|
|
@ -1970,6 +1970,8 @@ void recVUMI_XTOP( VURegs *VU, int info )
|
|||
//------------------------------------------------------------------
|
||||
// VU1XGKICK_MTGSTransfer() - Called by ivuZerorec.cpp
|
||||
//------------------------------------------------------------------
|
||||
extern bool SIGNAL_IMR_Pending;
|
||||
|
||||
void __fastcall VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr)
|
||||
{
|
||||
addr &= 0x3fff;
|
||||
|
@ -1978,7 +1980,7 @@ void __fastcall VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr)
|
|||
u32 size;
|
||||
u8* pDest;
|
||||
|
||||
if(gifRegs->stat.APATH <= GIF_APATH1 || (gifRegs->stat.APATH == GIF_APATH3 && gifRegs->stat.IP3 == true))
|
||||
if(gifRegs->stat.APATH <= GIF_APATH1 || (gifRegs->stat.APATH == GIF_APATH3 && gifRegs->stat.IP3 == true) && SIGNAL_IMR_Pending == false)
|
||||
{
|
||||
|
||||
if(Path1WritePos != 0)
|
||||
|
|
Loading…
Reference in New Issue