void __fastcall ReadFIFO_VIF1(mem128_t* out) { if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) ) DevCon.Warning( "Reading from vif1 fifo when stalled" ); ZeroQWC(out); // Clear first in case no data gets written... pxAssertRel(vif1Regs.stat.FQC != 0, "FQC = 0 on VIF FIFO READ!"); if (vif1Regs.stat.FDR) { if (vif1Regs.stat.FQC > vif1.GSLastDownloadSize) { DevCon.Warning("Warning! GS Download size < FIFO count!"); } if (vif1Regs.stat.FQC > 0) { GetMTGS().WaitGS(); if (GSinitReadFIFO) { GetMTGS().SendPointerPacket(GS_RINGTYPE_INIT_READ_FIFO1, 0, out); GetMTGS().WaitGS(false); // wait without reg sync } GSreadFIFO((u64*)out); vif1.GSLastDownloadSize--; GUNIT_LOG("ReadFIFO_VIF1"); if (vif1.GSLastDownloadSize <= 16) gifRegs.stat.OPH = false; vif1Regs.stat.FQC = std::min((u32)16, vif1.GSLastDownloadSize); } } VIF_LOG("ReadFIFO/VIF1 -> %ls", WX_STR(out->ToString())); }
void SysCoreThread::GameStartingInThread() { GetMTGS().SendGameCRC(ElfCRC); if (EmuConfig.EnablePatches) ApplyPatch(0); if (EmuConfig.EnableCheats) ApplyCheat(0); }
void Sys_RecordingToggle() { ScopedCoreThreadPause paused_core; paused_core.AllowResume(); g_Pcsx2Recording ^= 1; GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start. if (g_Pcsx2Recording) { // start recording if (GSsetupRecording) { // GSsetupRecording can be aborted/canceled by the user. Don't go on to record the audio if that happens. if (GSsetupRecording(g_Pcsx2Recording, NULL)) { if (SPU2setupRecording) SPU2setupRecording(g_Pcsx2Recording, NULL); } else { // recording dialog canceled by the user. align our state g_Pcsx2Recording ^= 1; } } else { // the GS doesn't support recording. if (SPU2setupRecording) SPU2setupRecording(g_Pcsx2Recording, NULL); } } else { // stop recording if (GSsetupRecording) GSsetupRecording(g_Pcsx2Recording, NULL); if (SPU2setupRecording) SPU2setupRecording(g_Pcsx2Recording, NULL); } }
void vif1TransferToMemory() { u128* pMem = (u128*)dmaGetAddr(vif1ch.madr, false); // VIF from gsMemory if (pMem == NULL) { // Is vif0ptag empty? Console.WriteLn("Vif1 Tag BUSERR"); dmacRegs.stat.BEIS = true; // Bus Error vif1Regs.stat.FQC = 0; vif1ch.qwc = 0; vif1.done = true; CPU_INT(DMAC_VIF1, 0); return; // An error has occurred. } // MTGS concerns: The MTGS is inherently disagreeable with the idea of downloading // stuff from the GS. The *only* way to handle this case safely is to flush the GS // completely and execute the transfer there-after. //Console.Warning("Real QWC %x", vif1ch.qwc); const u32 size = min(vif1.GSLastDownloadSize, (u32)vif1ch.qwc); const u128* pMemEnd = vif1.GSLastDownloadSize + pMem; if (size) { // Checking if any crazy game does a partial // gs primitive and then does a gs download... Gif_Path& p1 = gifUnit.gifPath[GIF_PATH_1]; Gif_Path& p2 = gifUnit.gifPath[GIF_PATH_2]; Gif_Path& p3 = gifUnit.gifPath[GIF_PATH_3]; pxAssert(p1.isDone() || !p1.gifTag.isValid); pxAssert(p2.isDone() || !p2.gifTag.isValid); pxAssert(p3.isDone() || !p3.gifTag.isValid); } GetMTGS().WaitGS(); GSreadFIFO2((u64*)pMem, size); pMem += size; if(pMem < pMemEnd) { //DevCon.Warning("GS Transfer < VIF QWC, Clearing end of space"); __m128 zeroreg = _mm_setzero_ps(); do { _mm_store_ps((float*)pMem, zeroreg); } while (++pMem < pMemEnd); } g_vif1Cycles += vif1ch.qwc * 2; vif1ch.madr += vif1ch.qwc * 16; // mgs3 scene changes if (vif1.GSLastDownloadSize >= vif1ch.qwc) { vif1.GSLastDownloadSize -= vif1ch.qwc; vif1Regs.stat.FQC = min((u32)16, vif1.GSLastDownloadSize); } else { vif1Regs.stat.FQC = 0; vif1.GSLastDownloadSize = 0; } vif1ch.qwc = 0; }
void __fastcall ReadFIFO_VIF1(mem128_t* out) { if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS) ) DevCon.Warning( "Reading from vif1 fifo when stalled" ); pxAssertRel(vif1Regs.stat.FQC != 0, "FQC = 0 on VIF FIFO READ!"); if (vif1Regs.stat.FDR) { if(vif1Regs.stat.FQC > vif1.GSLastDownloadSize) { DevCon.Warning("Warning! GS Download size < FIFO count!"); } if (vif1Regs.stat.FQC > 0) { GetMTGS().WaitGS(); GSreadFIFO((u64*)out); vif1.GSLastDownloadSize--; if (vif1.GSLastDownloadSize <= 16) gifRegs.stat.OPH = false; vif1Regs.stat.FQC = min((u32)16, vif1.GSLastDownloadSize); } } VIF_LOG("ReadFIFO/VIF1 -> %ls", out->ToString().c_str()); }
void __fastcall WriteFIFO_GIF(const mem128_t *value) { GIF_LOG("WriteFIFO/GIF <- %ls", value->ToString().c_str()); //CopyQWC(&psHu128(GIF_FIFO), value); //CopyQWC(&nloop0_packet, value); GetMTGS().PrepDataPacket(GIF_PATH_3, 1); GIFPath_CopyTag( GIF_PATH_3, value, 1 ); GetMTGS().SendDataPacket(); if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH3 ) { if(gifRegs.stat.DIR == 0)gifRegs.stat.OPH = false; gifRegs.stat.APATH = GIF_APATH_IDLE; if(gifRegs.stat.P1Q) gsPath1Interrupt(); } }
void Sys_RecordingToggle() { ScopedCoreThreadPause paused_core; paused_core.AllowResume(); g_Pcsx2Recording ^= 1; GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start. if( GSsetupRecording != NULL ) GSsetupRecording(g_Pcsx2Recording, NULL); if( SPU2setupRecording != NULL ) SPU2setupRecording(g_Pcsx2Recording, NULL); }
bool SysCoreThread::StateCheckInThread() { GetMTGS().RethrowException(); return _parent::StateCheckInThread() && (_reset_stuff_as_needed(), true); }
// -------------------------------------------------------------------------------------- // SysCoreThread *Worker* Implementations // (Called from the context of this thread only) // -------------------------------------------------------------------------------------- bool SysCoreThread::HasPendingStateChangeRequest() const { return !m_hasActiveMachine || GetMTGS().HasPendingException() || _parent::HasPendingStateChangeRequest(); }