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.
|
2009-02-09 21:15:56 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* 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-03-01 03:36:52 +00:00
|
|
|
#pragma once
|
2009-02-09 21:15:56 +00:00
|
|
|
#include "Vif.h"
|
|
|
|
|
2009-09-27 00:11:09 +00:00
|
|
|
enum VURegFlags
|
|
|
|
{
|
2021-08-31 19:51:14 +00:00
|
|
|
REG_STATUS_FLAG = 16,
|
|
|
|
REG_MAC_FLAG = 17,
|
|
|
|
REG_CLIP_FLAG = 18,
|
|
|
|
REG_ACC_FLAG = 19, // dummy flag that indicates that VFACC is written/read (nothing to do with VI[19])
|
|
|
|
REG_R = 20,
|
|
|
|
REG_I = 21,
|
|
|
|
REG_Q = 22,
|
|
|
|
REG_P = 23, // only exists in micromode
|
|
|
|
REG_VF0_FLAG = 24, // dummy flag that indicates VF0 is read (nothing to do with VI[24])
|
|
|
|
REG_TPC = 26,
|
|
|
|
REG_CMSAR0 = 27,
|
|
|
|
REG_FBRST = 28,
|
|
|
|
REG_VPU_STAT = 29,
|
|
|
|
REG_CMSAR1 = 31
|
2009-09-27 00:11:09 +00:00
|
|
|
};
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
//interpreter hacks, WIP
|
|
|
|
//#define INT_VUSTALLHACK //some games work without those, big speedup
|
|
|
|
//#define INT_VUDOUBLEHACK
|
|
|
|
|
2021-08-31 19:51:14 +00:00
|
|
|
enum VUStatus
|
|
|
|
{
|
2009-02-09 21:15:56 +00:00
|
|
|
VU_Ready = 0,
|
2021-08-31 19:51:14 +00:00
|
|
|
VU_Run = 1,
|
|
|
|
VU_Stop = 2,
|
2009-02-09 21:15:56 +00:00
|
|
|
};
|
|
|
|
|
2021-08-31 19:51:14 +00:00
|
|
|
union VECTOR
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
float x, y, z, w;
|
2009-02-09 21:15:56 +00:00
|
|
|
} f;
|
2021-08-31 19:51:14 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
u32 x, y, z, w;
|
2009-02-09 21:15:56 +00:00
|
|
|
} i;
|
|
|
|
|
|
|
|
float F[4];
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2010-08-12 11:28:22 +00:00
|
|
|
u128 UQ;
|
|
|
|
s128 SQ;
|
2021-08-31 19:51:14 +00:00
|
|
|
u64 UD[2]; //128 bits
|
2009-02-09 21:15:56 +00:00
|
|
|
s64 SD[2];
|
|
|
|
u32 UL[4];
|
|
|
|
s32 SL[4];
|
|
|
|
u16 US[8];
|
|
|
|
s16 SS[8];
|
2021-08-31 19:51:14 +00:00
|
|
|
u8 UC[16];
|
|
|
|
s8 SC[16];
|
2010-08-25 15:32:17 +00:00
|
|
|
};
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2021-08-31 19:51:14 +00:00
|
|
|
struct REG_VI
|
|
|
|
{
|
|
|
|
union
|
|
|
|
{
|
2009-02-09 21:15:56 +00:00
|
|
|
float F;
|
2021-08-31 19:51:14 +00:00
|
|
|
s32 SL;
|
|
|
|
u32 UL;
|
|
|
|
s16 SS[2];
|
|
|
|
u16 US[2];
|
|
|
|
s8 SC[4];
|
|
|
|
u8 UC[4];
|
2009-02-09 21:15:56 +00:00
|
|
|
};
|
|
|
|
u32 padding[3]; // needs padding to make them 128bit; VU0 maps VU1's VI regs as 128bits to addr 0x4xx0 in
|
2021-08-31 19:51:14 +00:00
|
|
|
// VU0 mem, with only lower 16 bits valid, and the upper 112bits are hardwired to 0 (cottonvibes)
|
2010-08-25 15:32:17 +00:00
|
|
|
};
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-11-13 04:36:01 +00:00
|
|
|
//#define VUFLAG_BREAKONMFLAG 0x00000001
|
2021-08-31 19:51:14 +00:00
|
|
|
#define VUFLAG_MFLAGSET 0x00000002
|
|
|
|
#define VUFLAG_INTCINTERRUPT 0x00000004
|
|
|
|
struct fdivPipe
|
|
|
|
{
|
2009-02-09 21:15:56 +00:00
|
|
|
int enable;
|
|
|
|
REG_VI reg;
|
|
|
|
u32 sCycle;
|
|
|
|
u32 Cycle;
|
|
|
|
u32 statusflag;
|
|
|
|
};
|
|
|
|
|
2021-08-31 19:51:14 +00:00
|
|
|
struct efuPipe
|
|
|
|
{
|
2009-02-09 21:15:56 +00:00
|
|
|
int enable;
|
|
|
|
REG_VI reg;
|
|
|
|
u32 sCycle;
|
|
|
|
u32 Cycle;
|
|
|
|
};
|
|
|
|
|
2021-08-31 19:51:14 +00:00
|
|
|
struct fmacPipe
|
|
|
|
{
|
2021-09-06 13:13:06 +00:00
|
|
|
u32 regupper;
|
|
|
|
u32 reglower;
|
2021-09-02 23:04:55 +00:00
|
|
|
int flagreg;
|
2021-09-06 13:13:06 +00:00
|
|
|
u32 xyzwupper;
|
|
|
|
u32 xyzwlower;
|
2009-02-09 21:15:56 +00:00
|
|
|
u32 sCycle;
|
|
|
|
u32 Cycle;
|
|
|
|
u32 macflag;
|
|
|
|
u32 statusflag;
|
|
|
|
u32 clipflag;
|
|
|
|
};
|
|
|
|
|
2021-08-31 19:51:14 +00:00
|
|
|
struct ialuPipe
|
|
|
|
{
|
2009-02-19 15:56:07 +00:00
|
|
|
int reg;
|
|
|
|
u32 sCycle;
|
|
|
|
u32 Cycle;
|
|
|
|
};
|
|
|
|
|
2021-09-03 06:23:59 +00:00
|
|
|
struct alignas(16) VURegs
|
2021-08-31 19:51:14 +00:00
|
|
|
{
|
|
|
|
VECTOR VF[32]; // VF and VI need to be first in this struct for proper mapping
|
|
|
|
REG_VI VI[32]; // needs to be 128bit x 32 (cottonvibes)
|
2010-08-27 03:21:16 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
VECTOR ACC;
|
|
|
|
REG_VI q;
|
|
|
|
REG_VI p;
|
|
|
|
|
2021-08-31 19:51:14 +00:00
|
|
|
uint idx; // VU index (0 or 1)
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2010-08-27 03:21:16 +00:00
|
|
|
// flags/cycle are needed by VIF dma code, so they have to be here (for now)
|
|
|
|
// We may replace these by accessors in the future, if merited.
|
2009-02-09 21:15:56 +00:00
|
|
|
u32 cycle;
|
|
|
|
u32 flags;
|
|
|
|
|
2020-05-25 02:08:12 +00:00
|
|
|
// Current opcode being interpreted or recompiled (this var is used by Interps
|
2010-08-27 03:21:16 +00:00
|
|
|
// but not microVU. Would like to have it local to their respective classes... someday)
|
|
|
|
u32 code;
|
2020-12-04 13:03:32 +00:00
|
|
|
u32 start_pc;
|
2010-08-27 03:21:16 +00:00
|
|
|
|
|
|
|
// branch/branchpc are used by interpreter only, but making them local to the interpreter
|
|
|
|
// classes requires considerable code refactoring. Maybe later. >_<
|
|
|
|
u32 branch;
|
|
|
|
u32 branchpc;
|
2012-05-30 21:18:31 +00:00
|
|
|
u32 delaybranchpc;
|
|
|
|
bool takedelaybranch;
|
2021-09-06 13:58:49 +00:00
|
|
|
u32 ebit;
|
2020-08-09 06:30:24 +00:00
|
|
|
u32 pending_q;
|
|
|
|
u32 pending_p;
|
2021-09-07 12:40:01 +00:00
|
|
|
u32 blockhasmbit;
|
2010-08-27 03:21:16 +00:00
|
|
|
|
2021-09-03 06:23:59 +00:00
|
|
|
alignas(16) u32 micro_macflags[4];
|
|
|
|
alignas(16) u32 micro_clipflags[4];
|
|
|
|
alignas(16) u32 micro_statusflags[4];
|
2020-05-25 02:08:12 +00:00
|
|
|
// MAC/Status flags -- these are used by interpreters but are kind of hacky
|
2010-08-27 03:21:16 +00:00
|
|
|
// and shouldn't be relied on for any useful/valid info. Would like to move them out of
|
|
|
|
// this struct eventually.
|
|
|
|
u32 macflag;
|
|
|
|
u32 statusflag;
|
|
|
|
u32 clipflag;
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2021-08-28 05:45:15 +00:00
|
|
|
s32 nextBlockCycles;
|
|
|
|
|
2021-08-31 19:51:14 +00:00
|
|
|
u8* Mem;
|
|
|
|
u8* Micro;
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2021-09-02 23:04:55 +00:00
|
|
|
u32 xgkickaddr;
|
|
|
|
u32 xgkickdiff;
|
|
|
|
u32 xgkicksizeremaining;
|
|
|
|
u32 xgkicklastcycle;
|
2021-09-10 21:03:20 +00:00
|
|
|
u32 xgkickcyclecount;
|
2021-09-14 11:21:01 +00:00
|
|
|
u32 xgkickenable;
|
|
|
|
u32 xgkickendpacket;
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2013-02-24 18:58:52 +00:00
|
|
|
u8 VIBackupCycles;
|
|
|
|
u32 VIOldValue;
|
|
|
|
u32 VIRegNumber;
|
|
|
|
|
2021-09-06 13:13:06 +00:00
|
|
|
fmacPipe fmac[4];
|
|
|
|
u32 fmacreadpos;
|
|
|
|
u32 fmacwritepos;
|
|
|
|
u32 fmaccount;
|
2009-02-09 21:15:56 +00:00
|
|
|
fdivPipe fdiv;
|
|
|
|
efuPipe efu;
|
2021-09-06 13:13:06 +00:00
|
|
|
ialuPipe ialu[4];
|
|
|
|
u32 ialureadpos;
|
|
|
|
u32 ialuwritepos;
|
|
|
|
u32 ialucount;
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2010-08-27 03:21:16 +00:00
|
|
|
VURegs()
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2010-08-27 03:21:16 +00:00
|
|
|
Mem = NULL;
|
|
|
|
Micro = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsVU1() const;
|
|
|
|
bool IsVU0() const;
|
|
|
|
|
|
|
|
VIFregisters& GetVifRegs() const
|
|
|
|
{
|
2010-08-31 05:22:26 +00:00
|
|
|
return IsVU1() ? vif1Regs : vif0Regs;
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
2010-08-25 15:32:17 +00:00
|
|
|
};
|
2010-07-07 05:59:25 +00:00
|
|
|
|
2009-09-27 00:11:09 +00:00
|
|
|
enum VUPipeState
|
|
|
|
{
|
2021-08-31 19:51:14 +00:00
|
|
|
VUPIPE_NONE = 0,
|
|
|
|
VUPIPE_FMAC,
|
|
|
|
VUPIPE_FDIV,
|
|
|
|
VUPIPE_EFU,
|
|
|
|
VUPIPE_IALU,
|
|
|
|
VUPIPE_BRANCH,
|
|
|
|
VUPIPE_XGKICK
|
2009-09-27 00:11:09 +00:00
|
|
|
};
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2021-09-03 06:23:59 +00:00
|
|
|
extern VURegs vuRegs[2];
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2010-08-27 03:21:16 +00:00
|
|
|
// Obsolete(?) -- I think I'd rather use vu0Regs/vu1Regs or actually have these explicit to any
|
|
|
|
// CPP file that needs them only. --air
|
|
|
|
static VURegs& VU0 = vuRegs[0];
|
|
|
|
static VURegs& VU1 = vuRegs[1];
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2010-08-30 20:39:04 +00:00
|
|
|
// Do not use __fi here because it fires 'multiple definition' error in GCC
|
2021-08-31 19:51:14 +00:00
|
|
|
inline bool VURegs::IsVU1() const { return this == &vuRegs[1]; }
|
|
|
|
inline bool VURegs::IsVU0() const { return this == &vuRegs[0]; }
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-09-21 14:19:49 +00:00
|
|
|
extern u32* GET_VU_MEM(VURegs* VU, u32 addr);
|