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 // SIGNAL : What's not known here is whether or not the SIGID register should be updated
// here or when the IMR is cleared (below). // 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); if(SIGNAL_IMR_Pending == true)
GSSIGLBLID.SIGID = (GSSIGLBLID.SIGID&~SIGNAL_Data_Pending[1])|(SIGNAL_Data_Pending[0]&SIGNAL_Data_Pending[1]); {
//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; if(csr.FINISH) CSRreg.FINISH = false;

View File

@ -89,10 +89,20 @@ void gsPath1Interrupt()
} }
} }
extern bool SIGNAL_IMR_Pending;
__forceinline void gsInterrupt() __forceinline void gsInterrupt()
{ {
GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle); 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 ) if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE && gifRegs->stat.APATH == GIF_APATH3 )
{ {
gifRegs->stat.OPH = false; gifRegs->stat.OPH = false;
@ -100,6 +110,7 @@ __forceinline void gsInterrupt()
gifRegs->stat.APATH = GIF_APATH_IDLE; gifRegs->stat.APATH = GIF_APATH_IDLE;
if(gifRegs->stat.P1Q) gsPath1Interrupt(); if(gifRegs->stat.P1Q) gsPath1Interrupt();
} }
if (!(gif->chcr.STR)) if (!(gif->chcr.STR))
{ {

View File

@ -255,6 +255,8 @@ __forceinline void vif1SetupTransfer()
} }
} }
extern bool SIGNAL_IMR_Pending;
bool CheckPath2GIF(int channel) bool CheckPath2GIF(int channel)
{ {
if ((vif1Regs->stat.VGW)) 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; return true;
} }
__forceinline void vif1Interrupt() __forceinline void vif1Interrupt()

View File

@ -114,6 +114,8 @@ vifOp(vifCode_Base) {
return 0; return 0;
} }
extern bool SIGNAL_IMR_Pending;
template<int idx> _f int _vifCode_Direct(int pass, u8* data, bool isDirectHL) { template<int idx> _f int _vifCode_Direct(int pass, u8* data, bool isDirectHL) {
pass1 { pass1 {
vif1Only(); vif1Only();
@ -150,13 +152,21 @@ template<int idx> _f int _vifCode_Direct(int pass, u8* data, bool isDirectHL) {
return 0; 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 if (gifRegs->stat.PSE) // temporarily stop
{ {
Console.WriteLn("Gif dma temp paused? VIF DIRECT"); Console.WriteLn("Gif dma temp paused? VIF DIRECT");
vif1.GifWaitState = 3; vif1.GifWaitState = 3;
vif1.vifstalled = true;
vif1Regs->stat.VGW = true; vif1Regs->stat.VGW = true;
return 0; return 0;
} }
gifRegs->stat.clear_flags(GIF_STAT_P2Q); 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) // Time to ignore all subsequent drawing operations. (which is not yet supported)
if (!SIGNAL_IMR_Pending) 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_IMR_Pending = true;
SIGNAL_Data_Pending[0] = data[0]; SIGNAL_Data_Pending[0] = data[0];
SIGNAL_Data_Pending[1] = data[1]; SIGNAL_Data_Pending[1] = data[1];
@ -572,7 +572,7 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size)
gsHandler(pMem); gsHandler(pMem);
} }
incTag(16, 1); incTag(16, 1);
} while(StepReg() && size > 0); } while(StepReg() && size > 0 && SIGNAL_IMR_Pending == false);
} }
else 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 // 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. // 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()) if (!(GSIMR&0x200) && !s_gifPath.path[0].IsActive() && !s_gifPath.path[1].IsActive() && !s_gifPath.path[2].IsActive())
{ {
gsIrq(); gsIrq();
@ -687,6 +688,11 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size)
} }
break; break;
} }
if(SIGNAL_IMR_Pending == true)
{
//DevCon.Warning("Path %x", pathidx + 1);
break;
}
} }
size = (startSize - size); size = (startSize - size);

View File

@ -1101,7 +1101,10 @@ mVUop(mVU_XITOP) {
//------------------------------------------------------------------ //------------------------------------------------------------------
// XGkick // XGkick
//------------------------------------------------------------------ //------------------------------------------------------------------
extern void gsPath1Interrupt(); extern void gsPath1Interrupt();
extern bool SIGNAL_IMR_Pending;
void __fastcall mVU_XGKICK_(u32 addr) { void __fastcall mVU_XGKICK_(u32 addr) {
addr &= 0x3ff; addr &= 0x3ff;
u8* data = microVU1.regs->Mem + (addr*16); u8* data = microVU1.regs->Mem + (addr*16);
@ -1109,7 +1112,7 @@ void __fastcall mVU_XGKICK_(u32 addr) {
u32 size; u32 size;
u8* pDest; 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) if(Path1WritePos != 0)

View File

@ -1970,6 +1970,8 @@ void recVUMI_XTOP( VURegs *VU, int info )
//------------------------------------------------------------------ //------------------------------------------------------------------
// VU1XGKICK_MTGSTransfer() - Called by ivuZerorec.cpp // VU1XGKICK_MTGSTransfer() - Called by ivuZerorec.cpp
//------------------------------------------------------------------ //------------------------------------------------------------------
extern bool SIGNAL_IMR_Pending;
void __fastcall VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr) void __fastcall VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr)
{ {
addr &= 0x3fff; addr &= 0x3fff;
@ -1978,7 +1980,7 @@ void __fastcall VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr)
u32 size; u32 size;
u8* pDest; 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) if(Path1WritePos != 0)