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:
refraction 2010-07-06 17:25:02 +00:00
parent 968eed2822
commit b003a3bd47
7 changed files with 58 additions and 8 deletions

View File

@ -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;

View File

@ -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))
{

View File

@ -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()

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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)