static void _vu1Exec(VURegs* VU) { _VURegsNum lregs; _VURegsNum uregs; VECTOR _VF; VECTOR _VFc; REG_VI _VI; REG_VI _VIc; u32 *ptr; int vfreg; int vireg; int discard=0; ptr = (u32*)&VU->Micro[VU->VI[REG_TPC].UL]; VU->VI[REG_TPC].UL+=8; if (ptr[1] & 0x40000000) { /* E flag */ VU->ebit = 2; } if (ptr[1] & 0x10000000) { /* D flag */ if (VU0.VI[REG_FBRST].UL & 0x400) { VU0.VI[REG_VPU_STAT].UL|= 0x200; hwIntcIrq(INTC_VU1); VU->ebit = 1; } } if (ptr[1] & 0x08000000) { /* T flag */ if (VU0.VI[REG_FBRST].UL & 0x800) { VU0.VI[REG_VPU_STAT].UL|= 0x400; hwIntcIrq(INTC_VU1); VU->ebit = 1; } } //VUM_LOG("VU->cycle = %d (flags st=%x;mac=%x;clip=%x,q=%f)", VU->cycle, VU->statusflag, VU->macflag, VU->clipflag, VU->q.F); VU->code = ptr[1]; VU1regs_UPPER_OPCODE[VU->code & 0x3f](&uregs); #ifndef INT_VUSTALLHACK _vuTestUpperStalls(VU, &uregs); #endif /* check upper flags */ if (ptr[1] & 0x80000000) { /* I flag */ _vu1ExecUpper(VU, ptr); VU->VI[REG_I].UL = ptr[0]; //Lower not used, set to 0 to fill in the FMAC stall gap //Could probably get away with just running upper stalls, but lets not tempt fate. memset(&lregs, 0, sizeof(lregs)); } else { VU->code = ptr[0]; VU1regs_LOWER_OPCODE[VU->code >> 25](&lregs); #ifndef INT_VUSTALLHACK _vuTestLowerStalls(VU, &lregs); #endif vu1branch = lregs.pipe == VUPIPE_BRANCH; vfreg = 0; vireg = 0; if (uregs.VFwrite) { if (lregs.VFwrite == uregs.VFwrite) { // Console.Warning("*PCSX2*: Warning, VF write to the same reg in both lower/upper cycle"); discard = 1; } if (lregs.VFread0 == uregs.VFwrite || lregs.VFread1 == uregs.VFwrite) { // Console.WriteLn("saving reg %d at pc=%x", i, VU->VI[REG_TPC].UL); _VF = VU->VF[uregs.VFwrite]; vfreg = uregs.VFwrite; } } if (uregs.VIread & (1 << REG_CLIP_FLAG)) { if (lregs.VIwrite & (1 << REG_CLIP_FLAG)) { Console.Warning("*PCSX2*: Warning, VI write to the same reg in both lower/upper cycle"); discard = 1; } if (lregs.VIread & (1 << REG_CLIP_FLAG)) { _VI = VU->VI[REG_CLIP_FLAG]; vireg = REG_CLIP_FLAG; } } _vu1ExecUpper(VU, ptr); if (discard == 0) { if (vfreg) { _VFc = VU->VF[vfreg]; VU->VF[vfreg] = _VF; } if (vireg) { _VIc = VU->VI[vireg]; VU->VI[vireg] = _VI; } _vu1ExecLower(VU, ptr); if (vfreg) { VU->VF[vfreg] = _VFc; } if (vireg) { VU->VI[vireg] = _VIc; } } } _vuAddUpperStalls(VU, &uregs); _vuAddLowerStalls(VU, &lregs); _vuTestPipes(VU); if(VU->VIBackupCycles > 0) VU->VIBackupCycles--; if (VU->branch > 0) { if (VU->branch-- == 1) { VU->VI[REG_TPC].UL = VU->branchpc; if(VU->takedelaybranch) { VU->branch = 2; //DevCon.Warning("VU1 - Branch/Jump in Delay Slot"); VU->branchpc = VU->delaybranchpc; VU->delaybranchpc = 0; VU->takedelaybranch = false; } } } if( VU->ebit > 0 ) { if( VU->ebit-- == 1 ) { VU->VIBackupCycles = 0; _vuFlushAll(VU); VU0.VI[REG_VPU_STAT].UL &= ~0x100; vif1Regs.stat.VEW = false; } } }
static void _vu0Exec(VURegs* VU) { _VURegsNum lregs; _VURegsNum uregs; VECTOR _VF; VECTOR _VFc; REG_VI _VI; REG_VI _VIc; u32 *ptr; int vfreg; int vireg; int discard=0; ptr = (u32*)&VU->Micro[VU->VI[REG_TPC].UL]; VU->VI[REG_TPC].UL+=8; if (ptr[1] & 0x40000000) { VU->ebit = 2; } if (ptr[1] & 0x20000000) { /* M flag */ VU->flags|= VUFLAG_MFLAGSET; // Console.WriteLn("fixme: M flag set"); } if (ptr[1] & 0x10000000) { /* D flag */ if (VU0.VI[REG_FBRST].UL & 0x4) { VU0.VI[REG_VPU_STAT].UL|= 0x2; hwIntcIrq(INTC_VU0); } } if (ptr[1] & 0x08000000) { /* T flag */ if (VU0.VI[REG_FBRST].UL & 0x8) { VU0.VI[REG_VPU_STAT].UL|= 0x4; hwIntcIrq(INTC_VU0); } } VU->code = ptr[1]; VU0regs_UPPER_OPCODE[VU->code & 0x3f](&uregs); #ifndef INT_VUSTALLHACK _vuTestUpperStalls(VU, &uregs); #endif /* check upper flags */ if (ptr[1] & 0x80000000) { /* I flag */ _vu0ExecUpper(VU, ptr); VU->VI[REG_I].UL = ptr[0]; memset(&lregs, 0, sizeof(lregs)); } else { VU->code = ptr[0]; VU0regs_LOWER_OPCODE[VU->code >> 25](&lregs); #ifndef INT_VUSTALLHACK _vuTestLowerStalls(VU, &lregs); #endif vu0branch = lregs.pipe == VUPIPE_BRANCH; vfreg = 0; vireg = 0; if (uregs.VFwrite) { if (lregs.VFwrite == uregs.VFwrite) { // Console.Warning("*PCSX2*: Warning, VF write to the same reg in both lower/upper cycle"); discard = 1; } if (lregs.VFread0 == uregs.VFwrite || lregs.VFread1 == uregs.VFwrite) { // Console.WriteLn("saving reg %d at pc=%x", i, VU->VI[REG_TPC].UL); _VF = VU->VF[uregs.VFwrite]; vfreg = uregs.VFwrite; } } if (uregs.VIread & (1 << REG_CLIP_FLAG)) { if (lregs.VIwrite & (1 << REG_CLIP_FLAG)) { Console.Warning("*PCSX2*: Warning, VI write to the same reg in both lower/upper cycle"); discard = 1; } if (lregs.VIread & (1 << REG_CLIP_FLAG)) { _VI = VU0.VI[REG_CLIP_FLAG]; vireg = REG_CLIP_FLAG; } } _vu0ExecUpper(VU, ptr); if (discard == 0) { if (vfreg) { _VFc = VU->VF[vfreg]; VU->VF[vfreg] = _VF; } if (vireg) { _VIc = VU->VI[vireg]; VU->VI[vireg] = _VI; } _vu0ExecLower(VU, ptr); if (vfreg) { VU->VF[vfreg] = _VFc; } if (vireg) { VU->VI[vireg] = _VIc; } } } _vuAddUpperStalls(VU, &uregs); if (!(ptr[1] & 0x80000000)) _vuAddLowerStalls(VU, &lregs); _vuTestPipes(VU); if (VU->branch > 0) { VU->branch--; if (VU->branch == 0) { VU->VI[REG_TPC].UL = VU->branchpc; } } if( VU->ebit > 0 ) { if( VU->ebit-- == 1 ) { _vuFlushAll(VU); VU0.VI[REG_VPU_STAT].UL&= ~0x1; /* E flag */ vif0Regs.stat.VEW = false; } } }