Fixed a problem with EE's hsync-mode counters. They weren't detecting overflows and targets accurately. This most notably fixes several issues in Tales of the Abyss. Fixed debug mode build, it no longer causes an assertion immediately on starting a game. Removed the final warning from the new C++ build, and cleaned up some code along the way. Deleted the old SSE2EMU functions, which are no longer used since removing SSE1 support from the recompiler a while back.

git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@440 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
Jake.Stine 2008-12-16 08:03:39 +00:00 committed by Gregory Hainaut
parent 533a16116a
commit 77f46f454e
12 changed files with 70 additions and 238 deletions

View File

@ -532,32 +532,30 @@ __forceinline void rcntUpdate()
for (i=0; i<=3; i++) {
// We want to count gated counters (except the hblank which excluded below)
// We want to count gated counters (except the hblank which exclude below, and are
// counted by the hblank timer instead)
//if ( gates & (1<<i) ) continue;
if (!(counters[i].mode & 0x80)) continue;
if((counters[i].mode & 0x3) != 0x3) { // don't count hblank sources
if((counters[i].mode & 0x3) != 0x3) // don't count hblank sources
{
s32 change = cpuRegs.cycle - counters[i].sCycleT;
if( change > 0 ) {
counters[i].count += change / counters[i].rate;
change -= (change / counters[i].rate) * counters[i].rate;
counters[i].sCycleT = cpuRegs.cycle - change;
}
if( change < 0 ) change = 0; // sanity check!
counters[i].count += change / counters[i].rate;
change -= (change / counters[i].rate) * counters[i].rate;
counters[i].sCycleT = cpuRegs.cycle - change;
// Check Counter Targets and Overflows:
_cpuTestTarget( i );
_cpuTestOverflow( i );
}
else counters[i].sCycleT = cpuRegs.cycle;
}
// Check Counter Targets and Overflows:
for (i=0; i<=3; i++)
{
if (!(counters[i].mode & 0x80)) continue; // Stopped
_cpuTestTarget( i );
_cpuTestOverflow( i );
}
cpuRcntSet();
}
@ -634,7 +632,11 @@ void rcntStartGate(unsigned int mode, u32 sCycle) {
for (i=0; i <=3; i++) { //Gates for counters
if ((mode == 0) && ((counters[i].mode & 0x83) == 0x83))
{
counters[i].count += HBLANK_COUNTER_SPEED; //Update counters using the hblank as the clock
_cpuTestTarget( i );
_cpuTestOverflow( i );
}
if (!(gates & (1<<i))) continue;
if ((counters[i].mode & 0x8) != mode) continue;

View File

@ -227,7 +227,7 @@ int IsBIOS(char *filename, char *description);
#define FreezeXMMRegs(save)
#else
extern void FreezeXMMRegs_(int save);
extern u32 g_EEFreezeRegs;
extern bool g_EEFreezeRegs;
#define FreezeXMMRegs(save) if( g_EEFreezeRegs ) { FreezeXMMRegs_(save); }
#ifndef __x86_64__

View File

@ -534,7 +534,10 @@ void cpuBranchTest()
SysPrintf("frozen regs have not been restored!!!\n");
assert( !g_globalXMMSaved X86_32CODE(&& !g_globalMMXSaved) );
#endif
g_EEFreezeRegs = 0;
// Don't need to freeze any regs during a BranchTest.
// Everything has been flushed already.
g_EEFreezeRegs = false;
// Perform counters, ints, and IOP updates:
_cpuBranchTest_Shared();
@ -549,7 +552,7 @@ void cpuBranchTest()
}
assert( !g_globalXMMSaved X86_32CODE(&& !g_globalMMXSaved) );
g_EEFreezeRegs = 1;
g_EEFreezeRegs = true;
}
#endif
@ -685,7 +688,7 @@ void cpuRestartCPU()
void IntcpuBranchTest()
{
#ifndef PCSX2_NORECBUILD
g_EEFreezeRegs = 0;
g_EEFreezeRegs = false;
#endif
// Perform counters, ints, and IOP updates:
@ -699,6 +702,6 @@ void IntcpuBranchTest()
}
#ifndef PCSX2_NORECBUILD
g_EEFreezeRegs = 1;
g_EEFreezeRegs = true;
#endif
}

View File

@ -250,7 +250,7 @@ void intExecuteVU1Block();
void JumpCheckSym(u32 addr, u32 pc);
void JumpCheckSymRet(u32 addr);
extern u32 g_EEFreezeRegs;
extern bool g_EEFreezeRegs;
//exception code
#define EXC_CODE(x) ((x)<<2)

View File

@ -87,18 +87,19 @@ struct DECI2_DBGP_RUN{
_pad, //+08
_pad1, //+0C
argc; //+10
u32 argv[0]; //+14
}; //=14
//u32 argv; //+14
}; //=18
#pragma pack()
void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char *ioppc, char *eecy, char *iopcy){
DECI2_DBGP_HEADER *in=(DECI2_DBGP_HEADER*)inbuffer,
*out=(DECI2_DBGP_HEADER*)outbuffer;
u8 *data=(u8*)in+sizeof(DECI2_DBGP_HEADER);
DECI2_DBGP_EREG *eregs=(DECI2_DBGP_EREG*)((u8*)out+sizeof(DECI2_DBGP_HEADER));
DECI2_DBGP_IREG *iregs=(DECI2_DBGP_IREG*)((u8*)out+sizeof(DECI2_DBGP_HEADER));
DECI2_DBGP_MEM *mem =(DECI2_DBGP_MEM*) ((u8*)out+sizeof(DECI2_DBGP_HEADER));
DECI2_DBGP_RUN *run =(DECI2_DBGP_RUN*) ((u8*)in+sizeof(DECI2_DBGP_HEADER));
const DECI2_DBGP_HEADER *in=(DECI2_DBGP_HEADER*)inbuffer;
DECI2_DBGP_HEADER* out=(DECI2_DBGP_HEADER*)outbuffer;
DECI2_DBGP_EREG *eregs=(DECI2_DBGP_EREG*)&out[1];
DECI2_DBGP_IREG *iregs=(DECI2_DBGP_IREG*)&out[1];
DECI2_DBGP_MEM *mem =(DECI2_DBGP_MEM*) &out[1];
const DECI2_DBGP_RUN*run =(DECI2_DBGP_RUN*) &in[1];
static char line[1024];
int i, s;
@ -110,14 +111,14 @@ void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char
switch(in->type){
case 0x00://ok
sprintf(line, "%s/GETCONF", in->id==0?"CPU":in->id==1?"VU0":"VU1");
data=(u8*)out+sizeof(DECI2_DBGP_HEADER);
if (in->h.destination=='I'){
memcpy(data, &iop, sizeof(DECI2_DBGP_CONF));
memcpy(&out[1], &iop, sizeof(DECI2_DBGP_CONF));
}else
switch(in->id){
case 0:memcpy(data, &cpu, sizeof(DECI2_DBGP_CONF));break;
case 1:memcpy(data, &vu0, sizeof(DECI2_DBGP_CONF));break;
case 2:memcpy(data, &vu1, sizeof(DECI2_DBGP_CONF));break;
case 0:memcpy(&out[1], &cpu, sizeof(DECI2_DBGP_CONF));break;
case 1:memcpy(&out[1], &vu0, sizeof(DECI2_DBGP_CONF));break;
case 2:memcpy(&out[1], &vu1, sizeof(DECI2_DBGP_CONF));break;
}
break;
case 0x02://ok
@ -223,10 +224,12 @@ void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char
}
break;
case 0x08://ok
{
sprintf(line, "%s/RDMEM %08X/%X",
in->id==0?"CPU":in->id==1?"VU0":"VU1", mem->address, mem->length);
data=(u8*)out+ //kids: don't try this at home! :D
u8* data =(u8*)out+ //kids: don't try this at home! :D
((sizeof(DECI2_DBGP_HEADER)+sizeof(DECI2_DBGP_MEM)+(1 << mem->align) - 1) & (0xFFFFFFFF << mem->align));
if ((mem->address & ((1 << mem->align)-1)) ||
(mem->length & ((1 << mem->align)-1))){
out->result=1;
@ -242,6 +245,7 @@ void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char
break;
}
else
{
switch(mem->space){
case 0:
if ((mem->address & 0xF0000000) == 0x70000000)
@ -267,12 +271,16 @@ void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char
memcpy(data, &VU1.Micro[mem->address & 0x3FFF], mem->length);
break;
}
}
out->h.length=mem->length+data-(u8*)out;
break;
}
case 0x0a://ok
{
sprintf(line, "%s/WRMEM %08X/%X",
in->id==0?"CPU":in->id==1?"VU0":"VU1", mem->address, mem->length);
data=(u8*)in+ //kids: don't try this at home! :D
const u8* data=(u8*)in+ //kids: don't try this at home! :D
((sizeof(DECI2_DBGP_HEADER)+sizeof(DECI2_DBGP_MEM)+(1 << mem->align) - 1) & (0xFFFFFFFF << mem->align));
if (mem->length==4 && *(int*)data==0x0000000D)
strcat(line, " BREAKPOINT");
@ -318,14 +326,16 @@ void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char
}
out->h.length=sizeof(DECI2_DBGP_HEADER)+sizeof(DECI2_DBGP_MEM);
break;
}
case 0x10://ok
{
sprintf(line, "%s/GETBRKPT count=%d",
in->id==0?"CPU":in->id==1?"VU0":"VU1", in->count);
data=(u8*)out+sizeof(DECI2_DBGP_HEADER);
if (in->h.destination=='I') memcpy(data, ibrk, out->count=ibrk_count);
else memcpy(data, ebrk, out->count=ebrk_count);
if (in->h.destination=='I') memcpy(&out[1], ibrk, out->count=ibrk_count);
else memcpy(&out[1], ebrk, out->count=ebrk_count);
out->h.length=sizeof(DECI2_DBGP_HEADER)+out->count*sizeof(DECI2_DBGP_BRK);
break;
}
case 0x12://ok [does not break on iop brkpts]
sprintf(line, "%s/PUTBRKPT count=%d",
in->id==0?"CPU":in->id==1?"VU0":"VU1", in->count);
@ -335,8 +345,8 @@ void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char
strcat(line, "TOO MANY");
break;
}
if (in->h.destination=='I') memcpy(ibrk, data, ibrk_count=in->count);
else memcpy(ebrk, data, ebrk_count=in->count);
if (in->h.destination=='I') memcpy(ibrk, &out[1], ibrk_count=in->count);
else memcpy(ebrk, &out[1], ebrk_count=in->count);
out->count=0;
break;
case 0x14://ok, [w/o iop]
@ -368,14 +378,16 @@ void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char
}
break;
case 0x18://ok [without argc/argv stuff]
{
sprintf(line, "%s/RUN code=%d count=%d entry=0x%08X gp=0x%08X argc=%d",
in->id==0?"CPU":in->id==1?"VU0":"VU1", in->code, in->count,
run->entry, run->gp, run->argc);
cpuRegs.CP0.n.EPC=cpuRegs.pc=run->entry;
cpuRegs.GPR.n.gp.UL[0]=run->gp;
// threads_array[0].argc = run->argc;
for (i=0, s=0; i<(int)run->argc; i++) s+=run->argv[i];
memcpy(PSM(0), &run->argv[run->argc], s);
u32* argv = (u32*)&run[1];
for (i=0, s=0; i<(int)run->argc; i++, argv++) s+=argv[i];
memcpy(PSM(0), argv, s);
// threads_array[0].argstring = 0;
InterlockedExchange(&runStatus, STOP);
Sleep(1000);//first get the run thread to Wait state
@ -386,6 +398,7 @@ void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char
#endif
out->h.length=sizeof(DECI2_DBGP_HEADER);
break;
}
default:
sprintf(line, "type=0x%02X code=%d count=%d [unknown]", in->type, in->code, in->count);
}

View File

@ -38,4 +38,4 @@ void sendTTYP(u16 protocol, u8 source, char *data){
else
memcpy(&tmp[sizeof(DECI2_TTYP_HEADER)], data, strlen(data));
//writeData(tmp);
}
}

View File

@ -35,7 +35,7 @@
// chance of saves getting corrupted (untested). But it lacks the purist touch,
// so it's not enabled by default.
//#define SIO_INLINE_IRQS
#define SIO_INLINE_IRQS
struct _sio {

View File

@ -82,7 +82,7 @@ extern u8 g_globalMMXSaved;
void checkregs()
{
assert( g_globalMMXSaved );
if( g_EEFreezeRegs ) assert( g_globalMMXSaved );
}
#endif

View File

@ -291,9 +291,6 @@ protected:
template< int low, int hi >
void rpropSetLOHI( int write1, int read1, int read2, int mask );
template< int mask >
void rpropSetFPURead( int reg );
template< int live >
void rpropSetFPUWrite0( int reg, int mask );

View File

@ -76,7 +76,7 @@ static u8* recPtr = NULL, *recStackPtr = NULL;
static EEINST* s_pInstCache = NULL;
static u32 s_nInstCacheSize = 0;
u32 g_EEFreezeRegs = 0; // if set, should freeze the regs
bool g_EEFreezeRegs = false; // if set, should freeze the regs
static BASEBLOCK* s_pCurBlock = NULL;
static BASEBLOCKEX* s_pCurBlockEx = NULL;
@ -1673,7 +1673,7 @@ static void execute( void )
}
assert( pblock->pFnptr != 0 );
g_EEFreezeRegs = 1;
g_EEFreezeRegs = true;
// skip the POPs
@ -1717,7 +1717,7 @@ static void execute( void )
#endif
g_EEFreezeRegs = 0;
g_EEFreezeRegs = false;
}
void recStep( void ) {

View File

@ -1756,26 +1756,6 @@ extern void PFMAXRtoR( x86IntRegType to, x86IntRegType from );
extern void PFMINMtoR( x86IntRegType to, uptr from );
extern void PFMINRtoR( x86IntRegType to, x86IntRegType from );
extern void SSE2EMU_MOVSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from);
extern void SSE2EMU_MOVQ_M64_to_XMM( x86SSERegType to, uptr from);
extern void SSE2EMU_MOVQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from);
extern void SSE2EMU_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset );
extern void SSE2EMU_MOVD_XMM_to_RmOffset(x86IntRegType to, x86SSERegType from, int offset );
#ifndef __x86_64__
extern void SSE2EMU_MOVDQ2Q_XMM_to_MM( x86MMXRegType to, x86SSERegType from);
extern void SSE2EMU_MOVQ2DQ_MM_to_XMM( x86SSERegType to, x86MMXRegType from);
#endif
/* SSE2 emulated functions for SSE CPU's by kekko*/
extern void SSE2EMU_PSHUFD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 );
extern void SSE2EMU_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from );
extern void SSE2EMU_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
extern void SSE2EMU_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from );
extern void SSE2EMU_MOVD_XMM_to_M32( u32 to, x86SSERegType from );
extern void SSE2EMU_MOVD_R_to_XMM( x86SSERegType to, x86IntRegType from );
////////////////////////////////////////////////////
#ifdef _DEBUG
#define WRITECHECK() CheckX86Ptr()

View File

@ -1326,167 +1326,4 @@ _inline void SSEX_MOVHLPS_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
}
}
// SSE2 emulation
_inline void SSE2EMU_MOVSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from)
{
SSE_SHUFPS_XMM_to_XMM(to, from, 0x4e);
SSE_SHUFPS_XMM_to_XMM(to, to, 0x4e);
}
_inline void SSE2EMU_MOVQ_M64_to_XMM( x86SSERegType to, uptr from)
{
SSE_XORPS_XMM_to_XMM(to, to);
SSE_MOVLPS_M64_to_XMM(to, from);
}
_inline void SSE2EMU_MOVQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from)
{
SSE_XORPS_XMM_to_XMM(to, to);
SSE2EMU_MOVSD_XMM_to_XMM(to, from);
}
_inline void SSE2EMU_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
{
MOV32RmtoROffset(EAX, from, offset);
MOV32ItoM((uptr)p+4, 0);
MOV32ItoM((uptr)p+8, 0);
MOV32RtoM((uptr)p, EAX);
MOV32ItoM((uptr)p+12, 0);
SSE_MOVAPS_M128_to_XMM(to, (uptr)p);
}
_inline void SSE2EMU_MOVD_XMM_to_RmOffset(x86IntRegType to, x86SSERegType from, int offset )
{
SSE_MOVSS_XMM_to_M32((uptr)p, from);
MOV32MtoR(EAX, (uptr)p);
MOV32RtoRmOffset(to, EAX, offset);
}
#ifndef __x86_64__
extern void SetMMXstate();
_inline void SSE2EMU_MOVDQ2Q_XMM_to_MM( x86MMXRegType to, x86SSERegType from)
{
SSE_MOVLPS_XMM_to_M64((u32)p, from);
MOVQMtoR(to, (uptr)p);
SetMMXstate();
}
_inline void SSE2EMU_MOVQ2DQ_MM_to_XMM( x86SSERegType to, x86MMXRegType from)
{
MOVQRtoM((uptr)p, from);
SSE_MOVLPS_M64_to_XMM(to, (uptr)p);
SetMMXstate();
}
#endif
/****************************************************************************/
/* SSE2 Emulated functions for SSE CPU's by kekko */
/****************************************************************************/
_inline void SSE2EMU_PSHUFD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) {
MOV32ItoR(EAX, (u32)&p);
MOV32ItoR(EBX, (u32)&p2);
SSE_MOVUPSRtoRm(EAX, from);
MOV32ItoR(ECX, (u32)imm8);
AND32ItoR(ECX, 3);
SHL32ItoR(ECX, 2);
ADD32RtoR(ECX, EAX);
MOV32RmtoR(ECX, ECX);
MOV32RtoRm(EBX, ECX);
ADD32ItoR(EBX, 4);
MOV32ItoR(ECX, (u32)imm8);
SHR32ItoR(ECX, 2);
AND32ItoR(ECX, 3);
SHL32ItoR(ECX, 2);
ADD32RtoR(ECX, EAX);
MOV32RmtoR(ECX, ECX);
MOV32RtoRm(EBX, ECX);
ADD32ItoR(EBX, 4);
MOV32ItoR(ECX, (u32)imm8);
SHR32ItoR(ECX, 4);
AND32ItoR(ECX, 3);
SHL32ItoR(ECX, 2);
ADD32RtoR(ECX, EAX);
MOV32RmtoR(ECX, ECX);
MOV32RtoRm(EBX, ECX);
ADD32ItoR(EBX, 4);
MOV32ItoR(ECX, (u32)imm8);
SHR32ItoR(ECX, 6);
AND32ItoR(ECX, 3);
SHL32ItoR(ECX, 2);
ADD32RtoR(ECX, EAX);
MOV32RmtoR(ECX, ECX);
MOV32RtoRm(EBX, ECX);
SUB32ItoR(EBX, 12);
SSE_MOVUPSRmtoR(to, EBX);
}
_inline void SSE2EMU_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from ) {
MOV32ItoR(to, (uptr)&p);
SSE_MOVUPSRtoRm(to, from);
MOV32RmtoR(to, to);
}
#ifndef __x86_64__
extern void SetFPUstate();
extern void _freeMMXreg(int mmxreg);
#endif
_inline void SSE2EMU_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) {
#ifndef __x86_64__
SetFPUstate();
_freeMMXreg(7);
#endif
SSE_MOVAPS_XMM_to_M128((uptr)f, from);
FLD32((u32)&f[0]);
FISTP32((u32)&p2[0]);
FLD32((u32)&f[1]);
FISTP32((u32)&p2[1]);
FLD32((u32)&f[2]);
FISTP32((u32)&p2[2]);
FLD32((u32)&f[3]);
FISTP32((u32)&p2[3]);
SSE_MOVAPS_M128_to_XMM(to, (uptr)p2);
}
_inline void SSE2EMU_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from ) {
#ifndef __x86_64__
SetFPUstate();
_freeMMXreg(7);
#endif
FILD32((u32)from);
FSTP32((u32)&f[0]);
FILD32((u32)from+4);
FSTP32((u32)&f[1]);
FILD32((u32)from+8);
FSTP32((u32)&f[2]);
FILD32((u32)from+12);
FSTP32((u32)&f[3]);
SSE_MOVAPS_M128_to_XMM(to, (uptr)f);
}
_inline void SSE2EMU_MOVD_XMM_to_M32( u32 to, x86SSERegType from ) {
MOV32ItoR(EAX, (u32)&p);
SSE_MOVUPSRtoRm(EAX, from);
MOV32RmtoR(EAX, EAX);
MOV32RtoM(to, EAX);
}
_inline void SSE2EMU_MOVD_R_to_XMM( x86SSERegType to, x86IntRegType from ) {
MOV32ItoM((uptr)p+4, 0);
MOV32ItoM((uptr)p+8, 0);
MOV32RtoM((uptr)p, from);
MOV32ItoM((uptr)p+12, 0);
SSE_MOVAPS_M128_to_XMM(to, (uptr)p);
}
#endif