2009-09-08 12:08:10 +00:00
|
|
|
/* PCSX2 - PS2 Emulator for PCs
|
2010-05-03 14:08:02 +00:00
|
|
|
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
2010-04-25 00:31:27 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
|
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
2009-02-09 21:15:56 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
2009-02-09 21:15:56 +00:00
|
|
|
*/
|
|
|
|
|
2009-09-08 12:08:10 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
#include "PrecompiledHeader.h"
|
|
|
|
#include "Common.h"
|
2009-11-14 12:02:56 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
#include "VUmicro.h"
|
|
|
|
|
|
|
|
extern void _vuFlushAll(VURegs* VU);
|
|
|
|
|
2010-08-24 17:53:27 +00:00
|
|
|
static void _vu0ExecUpper(VURegs* VU, u32 *ptr) {
|
2010-04-25 00:31:27 +00:00
|
|
|
VU->code = ptr[1];
|
2009-02-09 21:15:56 +00:00
|
|
|
IdebugUPPER(VU0);
|
2010-04-25 00:31:27 +00:00
|
|
|
VU0_UPPER_OPCODE[VU->code & 0x3f]();
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
2010-08-24 17:53:27 +00:00
|
|
|
static void _vu0ExecLower(VURegs* VU, u32 *ptr) {
|
2010-04-25 00:31:27 +00:00
|
|
|
VU->code = ptr[0];
|
2009-02-09 21:15:56 +00:00
|
|
|
IdebugLOWER(VU0);
|
2010-04-25 00:31:27 +00:00
|
|
|
VU0_LOWER_OPCODE[VU->code >> 25]();
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int vu0branch = 0;
|
|
|
|
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;
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
ptr = (u32*)&VU->Micro[VU->VI[REG_TPC].UL];
|
2009-02-09 21:15:56 +00:00
|
|
|
VU->VI[REG_TPC].UL+=8;
|
|
|
|
|
|
|
|
if (ptr[1] & 0x40000000) {
|
|
|
|
VU->ebit = 2;
|
|
|
|
}
|
2010-04-25 00:31:27 +00:00
|
|
|
if (ptr[1] & 0x20000000) { /* M flag */
|
2009-02-09 21:15:56 +00:00
|
|
|
VU->flags|= VUFLAG_MFLAGSET;
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
// Console.WriteLn("fixme: M flag set");
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
VU->code = ptr[1];
|
2009-02-09 21:15:56 +00:00
|
|
|
VU0regs_UPPER_OPCODE[VU->code & 0x3f](&uregs);
|
|
|
|
#ifndef INT_VUSTALLHACK
|
|
|
|
_vuTestUpperStalls(VU, &uregs);
|
|
|
|
#endif
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
/* check upper flags */
|
|
|
|
if (ptr[1] & 0x80000000) { /* I flag */
|
2009-02-09 21:15:56 +00:00
|
|
|
_vu0ExecUpper(VU, ptr);
|
|
|
|
|
2010-04-25 00:31:27 +00:00
|
|
|
VU->VI[REG_I].UL = ptr[0];
|
2009-02-09 21:15:56 +00:00
|
|
|
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) {
|
2009-10-29 13:32:40 +00:00
|
|
|
// Console.Warning("*PCSX2*: Warning, VF write to the same reg in both lower/upper cycle");
|
2009-02-09 21:15:56 +00:00
|
|
|
discard = 1;
|
|
|
|
}
|
|
|
|
if (lregs.VFread0 == uregs.VFwrite ||
|
|
|
|
lregs.VFread1 == uregs.VFwrite) {
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
// Console.WriteLn("saving reg %d at pc=%x", i, VU->VI[REG_TPC].UL);
|
2009-02-09 21:15:56 +00:00
|
|
|
_VF = VU->VF[uregs.VFwrite];
|
|
|
|
vfreg = uregs.VFwrite;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (uregs.VIread & (1 << REG_CLIP_FLAG)) {
|
|
|
|
if (lregs.VIwrite & (1 << REG_CLIP_FLAG)) {
|
2009-10-29 13:32:40 +00:00
|
|
|
Console.Warning("*PCSX2*: Warning, VI write to the same reg in both lower/upper cycle");
|
2009-02-09 21:15:56 +00:00
|
|
|
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) {
|
2013-01-28 23:05:18 +00:00
|
|
|
if (VU->branch-- == 1) {
|
2009-02-09 21:15:56 +00:00
|
|
|
VU->VI[REG_TPC].UL = VU->branchpc;
|
2013-01-28 23:05:18 +00:00
|
|
|
if(VU->takedelaybranch == true)
|
2013-01-27 16:56:58 +00:00
|
|
|
{
|
2013-01-28 23:05:18 +00:00
|
|
|
//DevCon.Warning("VU0 - Branch/Jump in Delay Slot");
|
|
|
|
if(VU->firstbranchisjump == 1)
|
|
|
|
{
|
|
|
|
//DevCon.Warning("Jump first, so reading 1 instruction from first branch, then jumping second");
|
2013-01-27 16:56:58 +00:00
|
|
|
|
2013-01-28 23:05:18 +00:00
|
|
|
VU->branch = 1;
|
|
|
|
VU->branchpc = VU->delaybranchpc;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//DevCon.Warning("Branch first, so ignoring second branch");
|
|
|
|
}
|
|
|
|
|
2012-05-30 21:18:31 +00:00
|
|
|
VU->delaybranchpc = 0;
|
|
|
|
VU->takedelaybranch = false;
|
|
|
|
}
|
2013-01-28 23:05:18 +00:00
|
|
|
|
|
|
|
VU->firstbranchisjump = 0;
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( VU->ebit > 0 ) {
|
|
|
|
if( VU->ebit-- == 1 ) {
|
|
|
|
_vuFlushAll(VU);
|
2010-04-25 00:31:27 +00:00
|
|
|
VU0.VI[REG_VPU_STAT].UL&= ~0x1; /* E flag */
|
2010-08-31 05:22:26 +00:00
|
|
|
vif0Regs.stat.VEW = false;
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void vu0Exec(VURegs* VU)
|
|
|
|
{
|
2010-08-27 03:21:16 +00:00
|
|
|
VU0.VI[REG_TPC].UL &= VU0_PROGMASK;
|
|
|
|
_vu0Exec(VU);
|
2009-02-09 21:15:56 +00:00
|
|
|
VU->cycle++;
|
|
|
|
|
Lots of new code maintenance stuffs:
* Completely new assertion macros: pxAssert, pxAssertMsg, and pxFail, pxAssertDev (both which default to using a message). These replace *all* wxASSERT, DevAssert, and jASSUME varieties of macros. New macros borrow the best of all assertion worlds: MSVCRT, wxASSERT, and AtlAssume. :)
* Rewrote the Console namespace as a structure called IConsoleWriter, and created several varieties of ConsoleWriters for handling different states of log and console availability (should help reduce overhead of console logging nicely).
* More improvements to the PersistentThread model, using safely interlocked "Do*" style callbacks for starting and cleaning up threads.
* Fixed console logs so that they're readable in Win32 notepad again (the log writer adds CRs to naked LFs).
* Added AppInit.cpp -- contains constructor, destructor, OnInit, and command line parsing mess.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1950 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-04 08:27:27 +00:00
|
|
|
if (VU->VI[0].UL != 0) DbgCon.Error("VI[0] != 0!!!!\n");
|
|
|
|
if (VU->VF[0].f.x != 0.0f) DbgCon.Error("VF[0].x != 0.0!!!!\n");
|
|
|
|
if (VU->VF[0].f.y != 0.0f) DbgCon.Error("VF[0].y != 0.0!!!!\n");
|
|
|
|
if (VU->VF[0].f.z != 0.0f) DbgCon.Error("VF[0].z != 0.0!!!!\n");
|
|
|
|
if (VU->VF[0].f.w != 1.0f) DbgCon.Error("VF[0].w != 1.0!!!!\n");
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
2009-12-07 14:00:39 +00:00
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
// VU0microInterpreter
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
InterpVU0::InterpVU0()
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2010-02-24 07:20:33 +00:00
|
|
|
m_Idx = 0;
|
2009-12-07 14:00:39 +00:00
|
|
|
IsInterpreter = true;
|
|
|
|
}
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-12-07 14:00:39 +00:00
|
|
|
void InterpVU0::Step()
|
|
|
|
{
|
|
|
|
vu0Exec( &VU0 );
|
|
|
|
}
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2010-02-24 07:20:33 +00:00
|
|
|
void InterpVU0::Execute(u32 cycles)
|
2009-12-07 14:00:39 +00:00
|
|
|
{
|
2010-02-26 03:52:53 +00:00
|
|
|
for (int i = (int)cycles; i > 0 ; i--) {
|
|
|
|
if (!(VU0.VI[REG_VPU_STAT].UL & 0x1)) {
|
|
|
|
if (VU0.branch || VU0.ebit) {
|
|
|
|
vu0Exec(&VU0); // run branch delay slot?
|
2009-12-07 14:00:39 +00:00
|
|
|
}
|
|
|
|
break;
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
2009-12-07 14:00:39 +00:00
|
|
|
vu0Exec(&VU0);
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
2009-12-07 14:00:39 +00:00
|
|
|
}
|
2009-12-03 15:51:39 +00:00
|
|
|
|