mirror of https://github.com/PCSX2/pcsx2.git
Yay! Fixed a memory corruption bug in the SuperVU that caused several "VU-intense" games to crash randomly: Tekken 5, Persona 4, and God of War to name a few.
Changed the Hw FiFo to use what should be a more correct register addressing scheme. The entire contents of each page of the FIFO is mirrored into the lowest register(s). For example, any address between 0x10006010 and 0x10006ff0 should always be treated as address 0x10006000. Code cleanups and minor optimizations to hw.cpp, FiFo.cpp, and gs.cpp. Added some additional utility functions to the Path namespace, for splitting paths into files/folders parts. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@451 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
7e8aeba9c2
commit
63d5ce867b
245
pcsx2/FiFo.cpp
245
pcsx2/FiFo.cpp
|
@ -28,125 +28,194 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////// Quick & dirty FIFO :D ////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ** NOTE: cannot use XMM/MMX regs **
|
||||
|
||||
// Notes on FIFO implementation
|
||||
//
|
||||
// The FIFO consists of four separate pages of HW register memory, each mapped to a
|
||||
// PS2 device. They are listed as follows:
|
||||
//
|
||||
// 0x4000 - 0x5000 : VIF0 (all registers map to 0x4000)
|
||||
// 0x5000 - 0x6000 : VIF1 (all registers map to 0x5000)
|
||||
// 0x6000 - 0x7000 : GS (all registers map to 0x6000)
|
||||
// 0x7000 - 0x8000 : IPU (registers map to 0x7000 and 0x7010, respectively)
|
||||
|
||||
extern int FIFOto_write(u32* pMem, int size);
|
||||
extern void FIFOfrom_readsingle(void *value);
|
||||
|
||||
extern int g_nIPU0Data;
|
||||
extern u8* g_pIPU0Pointer;
|
||||
extern int FOreadpos;
|
||||
// NOTE: cannot use XMM/MMX regs
|
||||
void ReadFIFO(u32 mem, u64 *out) {
|
||||
if ((mem >= 0x10004000) && (mem < 0x10005000)) {
|
||||
VIF_LOG("ReadFIFO VIF0 0x%08X\n", mem);
|
||||
out[0] = psHu64(mem );
|
||||
out[1] = psHu64(mem+8);
|
||||
return;
|
||||
} else
|
||||
if ((mem >= 0x10005000) && (mem < 0x10006000)) {
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
VIF_LOG("ReadFIFO VIF1 0x%08X\n", mem);
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ReadFIFO Pages
|
||||
|
||||
if( vif1Regs->stat & (VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS) ) {
|
||||
SysPrintf("reading from vif1 fifo when stalled\n");
|
||||
}
|
||||
#endif
|
||||
void __fastcall ReadFIFO_page_4(u32 mem, u64 *out)
|
||||
{
|
||||
jASSUME( (mem >= 0x10004000) && (mem < 0x10005000) );
|
||||
|
||||
if (vif1Regs->stat & 0x800000) {
|
||||
if (--psHu32(D1_QWC) == 0) {
|
||||
vif1Regs->stat&= ~0x1f000000;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
out[0] = psHu64(mem );
|
||||
out[1] = psHu64(mem+8);
|
||||
return;
|
||||
} else if( (mem&0xfffff010) == 0x10007000) {
|
||||
VIF_LOG("ReadFIFO/VIF0 0x%08X\n", mem);
|
||||
//out[0] = psHu64(mem );
|
||||
//out[1] = psHu64(mem+8);
|
||||
|
||||
if( g_nIPU0Data > 0 ) {
|
||||
out[0] = psHu64(0x4000);
|
||||
out[1] = psHu64(0x4008);
|
||||
}
|
||||
|
||||
void __fastcall ReadFIFO_page_5(u32 mem, u64 *out)
|
||||
{
|
||||
jASSUME( (mem >= 0x10005000) && (mem < 0x10006000) );
|
||||
|
||||
VIF_LOG("ReadFIFO/VIF1, addr=0x%08X\n", mem);
|
||||
|
||||
if( vif1Regs->stat & (VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS) )
|
||||
DevCon::Notice( "Reading from vif1 fifo when stalled" );
|
||||
|
||||
if (vif1Regs->stat & 0x800000)
|
||||
{
|
||||
if (--psHu32(D1_QWC) == 0)
|
||||
vif1Regs->stat&= ~0x1f000000;
|
||||
}
|
||||
|
||||
//out[0] = psHu64(mem );
|
||||
//out[1] = psHu64(mem+8);
|
||||
|
||||
out[0] = psHu64(0x5000);
|
||||
out[1] = psHu64(0x5008);
|
||||
}
|
||||
|
||||
void __fastcall ReadFIFO_page_6(u32 mem, u64 *out)
|
||||
{
|
||||
jASSUME( (mem >= 0x10006000) && (mem < 0x10007000) );
|
||||
|
||||
DevCon::Notice( "ReadFIFO/GIF, addr=0x%x", params mem );
|
||||
|
||||
//out[0] = psHu64(mem );
|
||||
//out[1] = psHu64(mem+8);
|
||||
|
||||
out[0] = psHu64(0x6000);
|
||||
out[1] = psHu64(0x6008);
|
||||
}
|
||||
|
||||
void __fastcall ReadFIFO_page_7(u32 mem, u64 *out)
|
||||
{
|
||||
jASSUME( (mem >= 0x10007000) && (mem < 0x10008000) );
|
||||
|
||||
// All addresses in this page map to 0x7000 and 0x7010:
|
||||
mem &= 0x10;
|
||||
|
||||
if( mem == 0 )
|
||||
{
|
||||
if( g_nIPU0Data > 0 )
|
||||
{
|
||||
out[0] = *(u64*)(g_pIPU0Pointer);
|
||||
out[1] = *(u64*)(g_pIPU0Pointer+8);
|
||||
FOreadpos = (FOreadpos + 4) & 31;
|
||||
g_nIPU0Data--;
|
||||
g_pIPU0Pointer += 16;
|
||||
}
|
||||
return;
|
||||
}else if ( (mem&0xfffff010) == 0x10007010) {
|
||||
}
|
||||
else
|
||||
FIFOfrom_readsingle((void*)out);
|
||||
return;
|
||||
}
|
||||
SysPrintf("ReadFIFO Unknown %x\n", mem);
|
||||
}
|
||||
|
||||
void ConstReadFIFO(u32 mem)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// WriteFIFO Pages
|
||||
|
||||
void __fastcall WriteFIFO_page_4(u32 mem, const mem128_t *value)
|
||||
{
|
||||
// not done
|
||||
jASSUME( (mem >= 0x10004000) && (mem < 0x10005000) );
|
||||
|
||||
VIF_LOG("WriteFIFO/VIF0, addr=0x%08X\n", mem);
|
||||
|
||||
//psHu64(mem ) = value[0];
|
||||
//psHu64(mem+8) = value[1];
|
||||
|
||||
psHu64(0x4000) = value[0];
|
||||
psHu64(0x4008) = value[1];
|
||||
|
||||
vif0ch->qwc += 1;
|
||||
int ret = VIF0transfer((u32*)value, 4, 0);
|
||||
assert( ret == 0 ); // vif stall code not implemented
|
||||
}
|
||||
|
||||
void WriteFIFO(u32 mem, const u64 *value) {
|
||||
int ret;
|
||||
void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value)
|
||||
{
|
||||
jASSUME( (mem >= 0x10005000) && (mem < 0x10006000) );
|
||||
|
||||
if ((mem >= 0x10004000) && (mem < 0x10005000)) {
|
||||
VIF_LOG("WriteFIFO VIF0 0x%08X\n", mem);
|
||||
VIF_LOG("WriteFIFO/VIF1, addr=0x%08X\n", mem);
|
||||
|
||||
psHu64(mem ) = value[0];
|
||||
psHu64(mem+8) = value[1];
|
||||
vif0ch->qwc += 1;
|
||||
ret = VIF0transfer((u32*)value, 4, 0);
|
||||
assert(ret == 0 ); // vif stall code not implemented
|
||||
//psHu64(mem ) = value[0];
|
||||
//psHu64(mem+8) = value[1];
|
||||
|
||||
psHu64(0x5000) = value[0];
|
||||
psHu64(0x5008) = value[1];
|
||||
|
||||
if(vif1Regs->stat & VIF1_STAT_FDR)
|
||||
DevCon::Notice("writing to fifo when fdr is set!");
|
||||
if( vif1Regs->stat & (VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS) )
|
||||
DevCon::Notice("writing to vif1 fifo when stalled");
|
||||
|
||||
vif1ch->qwc += 1;
|
||||
int ret = VIF1transfer((u32*)value, 4, 0);
|
||||
assert( ret == 0 ); // vif stall code not implemented
|
||||
}
|
||||
|
||||
void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value)
|
||||
{
|
||||
jASSUME( (mem >= 0x10006000) && (mem < 0x10007000) );
|
||||
GIF_LOG("WriteFIFO/GIF, addr=0x%08X\n", mem);
|
||||
|
||||
//psHu64(mem ) = value[0];
|
||||
//psHu64(mem+8) = value[1];
|
||||
|
||||
psHu64(0x6000) = value[0];
|
||||
psHu64(0x6008) = value[1];
|
||||
|
||||
if( mtgsThread != NULL )
|
||||
{
|
||||
const uint count = mtgsThread->PrepDataPacket( GIF_PATH_3, value, 1 );
|
||||
jASSUME( count == 1 );
|
||||
u64* data = (u64*)mtgsThread->GetDataPacketPtr();
|
||||
data[0] = value[0];
|
||||
data[1] = value[1];
|
||||
mtgsThread->SendDataPacket();
|
||||
}
|
||||
else if ((mem >= 0x10005000) && (mem < 0x10006000)) {
|
||||
VIF_LOG("WriteFIFO VIF1 0x%08X\n", mem);
|
||||
|
||||
psHu64(mem ) = value[0];
|
||||
psHu64(mem+8) = value[1];
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if(vif1Regs->stat & VIF1_STAT_FDR)
|
||||
SysPrintf("writing to fifo when fdr is set!\n");
|
||||
if( vif1Regs->stat & (VIF1_STAT_INT|VIF1_STAT_VSS|VIF1_STAT_VIS|VIF1_STAT_VFS) ) {
|
||||
SysPrintf("writing to vif1 fifo when stalled\n");
|
||||
}
|
||||
#endif
|
||||
vif1ch->qwc += 1;
|
||||
ret = VIF1transfer((u32*)value, 4, 0);
|
||||
assert(ret == 0 ); // vif stall code not implemented
|
||||
else
|
||||
{
|
||||
FreezeXMMRegs(1);
|
||||
FreezeMMXRegs(1);
|
||||
GSGIFTRANSFER3((u32*)value, 1);
|
||||
FreezeMMXRegs(0);
|
||||
FreezeXMMRegs(0);
|
||||
}
|
||||
else if ((mem >= 0x10006000) && (mem < 0x10007000)) {
|
||||
GIF_LOG("WriteFIFO GIF 0x%08X\n", mem);
|
||||
}
|
||||
|
||||
psHu64(mem ) = value[0];
|
||||
psHu64(mem+8) = value[1];
|
||||
void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value)
|
||||
{
|
||||
jASSUME( (mem >= 0x10007000) && (mem < 0x10008000) );
|
||||
|
||||
if( mtgsThread != NULL )
|
||||
// All addresses in this page map to 0x7000 and 0x7010:
|
||||
mem &= 0x10;
|
||||
|
||||
IPU_LOG( "WriteFIFO/IPU, addr=0x%x", params mem );
|
||||
|
||||
if( mem == 0 )
|
||||
{
|
||||
// Should this raise a PS2 exception or just ignore silently?
|
||||
Console::Notice( "WriteFIFO/IPUout (ignored)" );
|
||||
}
|
||||
else
|
||||
{
|
||||
IPU_LOG("WriteFIFO IPU_in[%d] <- %8.8X_%8.8X_%8.8X_%8.8X\n",
|
||||
mem/16, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]);
|
||||
|
||||
//committing every 16 bytes
|
||||
while( FIFOto_write((u32*)value, 1) == 0 )
|
||||
{
|
||||
const uint count = mtgsThread->PrepDataPacket( GIF_PATH_3, value, 1 );
|
||||
jASSUME( count == 1 );
|
||||
u64* data = (u64*)mtgsThread->GetDataPacketPtr();
|
||||
data[0] = value[0];
|
||||
data[1] = value[1];
|
||||
mtgsThread->SendDataPacket();
|
||||
}
|
||||
else
|
||||
{
|
||||
FreezeXMMRegs(1);
|
||||
GSGIFTRANSFER3((u32*)value, 1);
|
||||
FreezeXMMRegs(0);
|
||||
}
|
||||
|
||||
} else
|
||||
if ((mem&0xfffff010) == 0x10007010) {
|
||||
IPU_LOG("WriteFIFO IPU_in[%d] <- %8.8X_%8.8X_%8.8X_%8.8X\n", (mem - 0x10007010)/8, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]);
|
||||
|
||||
//commiting every 16 bytes
|
||||
while( FIFOto_write((u32*)value, 1) == 0 ) {
|
||||
Console::WriteLn("IPU sleeping");
|
||||
Threading::Timeslice();
|
||||
}
|
||||
} else {
|
||||
Console::Notice("WriteFIFO Unknown %x", params mem);
|
||||
}
|
||||
}
|
||||
|
||||
void ConstWriteFIFO(u32 mem) {
|
||||
}
|
||||
|
|
175
pcsx2/GS.cpp
175
pcsx2/GS.cpp
|
@ -169,6 +169,7 @@ void gsSetVideoRegionType( u32 isPal )
|
|||
Config.PsxType &= ~1;
|
||||
}
|
||||
|
||||
// If we made it this far it means the refresh rate changed, so update the vsync timers:
|
||||
UpdateVSyncRate();
|
||||
}
|
||||
|
||||
|
@ -339,14 +340,17 @@ void gsCSRwrite(u32 value)
|
|||
}
|
||||
}
|
||||
|
||||
static void IMRwrite(u32 value) {
|
||||
static void IMRwrite(u32 value)
|
||||
{
|
||||
GSIMR = (value & 0x1f00)|0x6000;
|
||||
|
||||
// don't update mtgs mem
|
||||
}
|
||||
|
||||
__forceinline void gsWrite8(u32 mem, u8 value) {
|
||||
switch (mem) {
|
||||
__forceinline void gsWrite8(u32 mem, u8 value)
|
||||
{
|
||||
switch (mem)
|
||||
{
|
||||
case 0x12001000: // GS_CSR
|
||||
gsCSRwrite((CSRw & ~0x000000ff) | value); break;
|
||||
case 0x12001001: // GS_CSR
|
||||
|
@ -364,30 +368,45 @@ __forceinline void gsWrite8(u32 mem, u8 value) {
|
|||
GIF_LOG("GS write 8 at %8.8lx with data %8.8lx\n", mem, value);
|
||||
}
|
||||
|
||||
__forceinline void gsWrite16(u32 mem, u16 value) {
|
||||
__forceinline void _gsSMODEwrite( u32 mem, u32 value )
|
||||
{
|
||||
switch (mem)
|
||||
{
|
||||
case GS_SMODE1:
|
||||
gsSetVideoRegionType( !!(value & 0x6000) );
|
||||
break;
|
||||
|
||||
case GS_SMODE2:
|
||||
if(value & 0x1)
|
||||
Config.PsxType |= 2; // Interlaced
|
||||
else
|
||||
Config.PsxType &= ~2; // Non-Interlaced
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GS Write 16 bit
|
||||
|
||||
__forceinline void gsWrite16(u32 mem, u16 value)
|
||||
{
|
||||
GIF_LOG("GS write 16 at %8.8lx with data %8.8lx\n", mem, value);
|
||||
|
||||
switch (mem) {
|
||||
case 0x12000010: // GS_SMODE1
|
||||
gsSetVideoRegionType( (value & 0x6000) == 0x6000 );
|
||||
break;
|
||||
_gsSMODEwrite( mem, value );
|
||||
|
||||
case 0x12000020: // GS_SMODE2
|
||||
if(value & 0x1) Config.PsxType |= 2; // Interlaced
|
||||
else Config.PsxType &= ~2; // Non-Interlaced
|
||||
break;
|
||||
|
||||
case 0x12001000: // GS_CSR
|
||||
switch (mem)
|
||||
{
|
||||
case GS_CSR:
|
||||
gsCSRwrite( (CSRw&0xffff0000) | value);
|
||||
return; // do not write to MTGS memory
|
||||
case 0x12001002: // GS_CSR
|
||||
return; // do not write to MTGS memory
|
||||
|
||||
case GS_CSR+2:
|
||||
gsCSRwrite( (CSRw&0xffff) | ((u32)value<<16));
|
||||
return; // do not write to MTGS memory
|
||||
case 0x12001010: // GS_IMR
|
||||
//SysPrintf("writing to IMR 16\n");
|
||||
return; // do not write to MTGS memory
|
||||
|
||||
case GS_IMR:
|
||||
IMRwrite(value);
|
||||
return; // do not write to MTGS memory
|
||||
return; // do not write to MTGS memory
|
||||
}
|
||||
|
||||
*(u16*)PS2GS_BASE(mem) = value;
|
||||
|
@ -396,28 +415,25 @@ __forceinline void gsWrite16(u32 mem, u16 value) {
|
|||
mtgsThread->SendSimplePacket(GS_RINGTYPE_MEMWRITE16, mem&0x13ff, value, 0);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GS Write 32 bit
|
||||
|
||||
__forceinline void gsWrite32(u32 mem, u32 value)
|
||||
{
|
||||
assert( !(mem&3));
|
||||
jASSUME( (mem & 3) == 0 );
|
||||
GIF_LOG("GS write 32 at %8.8lx with data %8.8lx\n", mem, value);
|
||||
|
||||
switch (mem) {
|
||||
case 0x12000010: // GS_SMODE1
|
||||
gsSetVideoRegionType( (value & 0x6000) == 0x6000 );
|
||||
break;
|
||||
_gsSMODEwrite( mem, value );
|
||||
|
||||
case 0x12000020: // GS_SMODE2
|
||||
if(value & 0x1) Config.PsxType |= 2; // Interlaced
|
||||
else Config.PsxType &= ~2; // Non-Interlaced
|
||||
break;
|
||||
|
||||
case 0x12001000: // GS_CSR
|
||||
switch (mem)
|
||||
{
|
||||
case GS_CSR:
|
||||
gsCSRwrite(value);
|
||||
return;
|
||||
return;
|
||||
|
||||
case 0x12001010: // GS_IMR
|
||||
case GS_IMR:
|
||||
IMRwrite(value);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
*(u32*)PS2GS_BASE(mem) = value;
|
||||
|
@ -426,14 +442,98 @@ __forceinline void gsWrite32(u32 mem, u32 value)
|
|||
mtgsThread->SendSimplePacket(GS_RINGTYPE_MEMWRITE32, mem&0x13ff, value, 0);
|
||||
}
|
||||
|
||||
__forceinline void gsWrite64(u32 mem, u64 value) {
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GS Write 64 bit
|
||||
|
||||
void __fastcall gsWrite64_page_00( u32 mem, const mem64_t* value )
|
||||
{
|
||||
gsWrite64_generic( mem, value );
|
||||
_gsSMODEwrite( mem, (u32)value[0] );
|
||||
}
|
||||
|
||||
void __fastcall gsWrite64_page_01( u32 mem, const mem64_t* value )
|
||||
{
|
||||
switch( mem )
|
||||
{
|
||||
case GS_CSR:
|
||||
gsCSRwrite((u32)value[0]);
|
||||
return;
|
||||
|
||||
case GS_IMR:
|
||||
IMRwrite((u32)value[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
gsWrite64_generic( mem, value );
|
||||
}
|
||||
|
||||
void __fastcall gsWrite64_generic( u32 mem, const mem64_t* value )
|
||||
{
|
||||
const u32* const srcval32 = (u32*)value;
|
||||
GIF_LOG("GS Write64 at %8.8lx with data %8.8x_%8.8x\n", mem, srcval32[1], srcval32[0]);
|
||||
|
||||
*(u64*)PS2GS_BASE(mem) = *value;
|
||||
|
||||
if( mtgsThread != NULL )
|
||||
mtgsThread->SendSimplePacket(GS_RINGTYPE_MEMWRITE64, mem&0x13ff, srcval32[0], srcval32[1]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GS Write 128 bit
|
||||
|
||||
void __fastcall gsWrite128_page_00( u32 mem, const mem128_t* value )
|
||||
{
|
||||
gsWrite128_generic( mem, value );
|
||||
_gsSMODEwrite( mem, (u32)value[0] );
|
||||
}
|
||||
|
||||
void __fastcall gsWrite128_page_01( u32 mem, const mem128_t* value )
|
||||
{
|
||||
switch( mem )
|
||||
{
|
||||
case GS_CSR:
|
||||
gsCSRwrite((u32)value[0]);
|
||||
return;
|
||||
|
||||
case GS_IMR:
|
||||
IMRwrite((u32)value[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
gsWrite128_generic( mem, value );
|
||||
}
|
||||
|
||||
void __fastcall gsWrite128_generic( u32 mem, const mem128_t* value )
|
||||
{
|
||||
const u32* const srcval32 = (u32*)value;
|
||||
|
||||
GIF_LOG("GS Write64 at %8.8lx with data %8.8x_%8.8x_%8.8x_%8.8x \n", mem,
|
||||
srcval32[3], srcval32[2], srcval32[1], srcval32[0]);
|
||||
|
||||
const uint masked_mem = mem & 0x13ff;
|
||||
u64* writeTo = (u64*)(&g_RealGSMem[masked_mem]);
|
||||
|
||||
writeTo[0] = value[0];
|
||||
writeTo[1] = value[1];
|
||||
|
||||
if( mtgsThread != NULL )
|
||||
{
|
||||
mtgsThread->SendSimplePacket(GS_RINGTYPE_MEMWRITE64, masked_mem, srcval32[0], srcval32[1]);
|
||||
mtgsThread->SendSimplePacket(GS_RINGTYPE_MEMWRITE64, masked_mem+8, srcval32[2], srcval32[3]);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// This function is left in for now for debugging/reference purposes.
|
||||
__forceinline void gsWrite64(u32 mem, u64 value)
|
||||
{
|
||||
GIF_LOG("GS write 64 at %8.8lx with data %8.8lx_%8.8lx\n", mem, ((u32*)&value)[1], (u32)value);
|
||||
|
||||
switch (mem) {
|
||||
switch (mem)
|
||||
{
|
||||
case 0x12000010: // GS_SMODE1
|
||||
gsSetVideoRegionType( (value & 0x6000) == 0x6000 );
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0x12000020: // GS_SMODE2
|
||||
if(value & 0x1) Config.PsxType |= 2; // Interlaced
|
||||
|
@ -454,6 +554,7 @@ __forceinline void gsWrite64(u32 mem, u64 value) {
|
|||
if( mtgsThread != NULL )
|
||||
mtgsThread->SendSimplePacket(GS_RINGTYPE_MEMWRITE64, mem&0x13ff, (u32)value, (u32)(value>>32));
|
||||
}
|
||||
#endif
|
||||
|
||||
__forceinline u8 gsRead8(u32 mem)
|
||||
{
|
||||
|
|
13
pcsx2/GS.h
13
pcsx2/GS.h
|
@ -279,13 +279,24 @@ void gsCSRwrite(u32 value);
|
|||
extern void gsWrite8(u32 mem, u8 value);
|
||||
extern void gsWrite16(u32 mem, u16 value);
|
||||
extern void gsWrite32(u32 mem, u32 value);
|
||||
extern void gsWrite64(u32 mem, u64 value);
|
||||
|
||||
extern void __fastcall gsWrite64_page_00( u32 mem, const mem64_t* value );
|
||||
extern void __fastcall gsWrite64_page_01( u32 mem, const mem64_t* value );
|
||||
extern void __fastcall gsWrite64_generic( u32 mem, const mem64_t* value );
|
||||
|
||||
extern void __fastcall gsWrite128_page_00( u32 mem, const mem128_t* value );
|
||||
extern void __fastcall gsWrite128_page_01( u32 mem, const mem128_t* value );
|
||||
extern void __fastcall gsWrite128_generic( u32 mem, const mem128_t* value );
|
||||
|
||||
extern u8 gsRead8(u32 mem);
|
||||
extern u16 gsRead16(u32 mem);
|
||||
extern u32 gsRead32(u32 mem);
|
||||
extern u64 gsRead64(u32 mem);
|
||||
|
||||
|
||||
//extern void gsWrite64(u32 mem, u64 value);
|
||||
|
||||
|
||||
void gsConstWrite8(u32 mem, int mmreg);
|
||||
void gsConstWrite16(u32 mem, int mmreg);
|
||||
void gsConstWrite32(u32 mem, int mmreg);
|
||||
|
|
510
pcsx2/Hw.cpp
510
pcsx2/Hw.cpp
|
@ -71,7 +71,10 @@ void hwReset()
|
|||
ipuReset();
|
||||
}
|
||||
|
||||
__forceinline u8 hwRead8(u32 mem)
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Hardware READ 8 bit
|
||||
|
||||
__forceinline u8 hwRead8(u32 mem)
|
||||
{
|
||||
u8 ret;
|
||||
|
||||
|
@ -134,6 +137,9 @@ __forceinline u8 hwRead8(u32 mem)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Hardware READ 16 bit
|
||||
|
||||
__forceinline u16 hwRead16(u32 mem)
|
||||
{
|
||||
u16 ret;
|
||||
|
@ -177,6 +183,9 @@ __forceinline u16 hwRead16(u32 mem)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Hardware READ 32 bit
|
||||
|
||||
// Reads hardware registers for page 0 (counters 0 and 1)
|
||||
mem32_t __fastcall hwRead32_page_00(u32 mem)
|
||||
{
|
||||
|
@ -221,20 +230,8 @@ mem32_t __fastcall hwRead32_page_0F(u32 mem)
|
|||
// *Performance Warning* This function is called -A-LOT. Be weary when making changes. It
|
||||
// could impact FPS significantly.
|
||||
|
||||
// Optimization Note:
|
||||
// Shortcut for the INTC_STAT register, which is checked *very* frequently as part of the EE's
|
||||
// vsynch timers. INTC_STAT has the disadvantage of being in the 0x1000f000 case, which has
|
||||
// a lot of additional registers in it, and combined with it's call frequency is a bad thing.
|
||||
|
||||
mem &= 0xffff;
|
||||
|
||||
/*if(mem == (INTC_STAT & 0xffff) )
|
||||
{
|
||||
// This one is checked alot, so leave it commented out unless you love 600 meg logfiles.
|
||||
//HW_LOG("DMAC_STAT Read 32bit %x\n", psHu32(0xe010));
|
||||
return psHu32(INTC_STAT);
|
||||
}*/
|
||||
|
||||
switch( mem )
|
||||
{
|
||||
case 0xf000:
|
||||
|
@ -293,7 +290,7 @@ mem32_t __fastcall hwRead32_page_02(u32 mem)
|
|||
}
|
||||
|
||||
// Used for all pages not explicitly specified above.
|
||||
mem32_t __fastcall hwRead32_page_other(u32 mem)
|
||||
mem32_t __fastcall hwRead32_generic(u32 mem)
|
||||
{
|
||||
const u16 masked_mem = mem & 0xffff;
|
||||
|
||||
|
@ -347,39 +344,62 @@ mem32_t __fastcall hwRead32_page_other(u32 mem)
|
|||
return *((u32*)&PS2MEM_HW[masked_mem]);
|
||||
}
|
||||
|
||||
__forceinline u64 hwRead64(u32 mem) {
|
||||
u64 ret;
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Hardware READ 64 bit
|
||||
|
||||
if ((mem>=0x10002000) && (mem<0x10003000)) {
|
||||
return ipuRead64(mem);
|
||||
}
|
||||
|
||||
// switch (mem) {
|
||||
// default:
|
||||
if (mem < 0x10010000) {
|
||||
ret = psHu64(mem);
|
||||
}
|
||||
else ret = 0;
|
||||
HW_LOG("Unknown Hardware Read 64 at %x\n",mem);
|
||||
// break;
|
||||
// }
|
||||
|
||||
return ret;
|
||||
void __fastcall hwRead64_page_00(u32 mem, mem64_t* result )
|
||||
{
|
||||
*result = hwRead32_page_00( mem );
|
||||
}
|
||||
|
||||
__forceinline void hwRead128(u32 mem, u64 *out) {
|
||||
if (mem >= 0x10004000 && mem < 0x10008000) {
|
||||
ReadFIFO(mem, out); return;
|
||||
}
|
||||
void __fastcall hwRead64_page_01(u32 mem, mem64_t* result )
|
||||
{
|
||||
*result = hwRead32_page_01( mem );
|
||||
}
|
||||
|
||||
if (mem < 0x10010000) {
|
||||
out[0] = psHu64(mem);
|
||||
out[1] = psHu64(mem+8);
|
||||
}
|
||||
void __fastcall hwRead64_page_02(u32 mem, mem64_t* result )
|
||||
{
|
||||
*result = ipuRead64(mem);
|
||||
}
|
||||
|
||||
void __fastcall hwRead64_generic(u32 mem, mem64_t* result )
|
||||
{
|
||||
*result = psHu64(mem);
|
||||
HW_LOG("Unknown Hardware Read 64 at %x\n",mem);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Hardware READ 128 bit
|
||||
|
||||
void __fastcall hwRead128_page_00(u32 mem, mem128_t* result )
|
||||
{
|
||||
result[0] = hwRead32_page_00( mem );
|
||||
result[1] = 0;
|
||||
}
|
||||
|
||||
void __fastcall hwRead128_page_01(u32 mem, mem128_t* result )
|
||||
{
|
||||
result[0] = hwRead32_page_01( mem );
|
||||
result[1] = 0;
|
||||
}
|
||||
|
||||
void __fastcall hwRead128_page_02(u32 mem, mem128_t* result )
|
||||
{
|
||||
// IPU is currently unhandled in 128 bit mode.
|
||||
HW_LOG("Unknown Hardware Read 128 at %x (IPU)\n",mem);
|
||||
}
|
||||
|
||||
void __fastcall hwRead128_generic(u32 mem, mem128_t* out)
|
||||
{
|
||||
out[0] = psHu64(mem);
|
||||
out[1] = psHu64(mem+8);
|
||||
|
||||
HW_LOG("Unknown Hardware Read 128 at %x\n",mem);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// DMA Execution Interfaces
|
||||
|
||||
// dark cloud2 uses 8 bit DMAs register writes
|
||||
static __forceinline void DmaExec8( void (*func)(), u32 mem, u8 value )
|
||||
{
|
||||
|
@ -407,12 +427,15 @@ static void DmaExec( void (*func)(), u32 mem, u32 value )
|
|||
if( (value & 0xc) == 0x4 && (value & 0xffff0000) == 0)
|
||||
psHu32(mem) = (psHu32(mem) & 0xFFFF0000) | (u16)value;
|
||||
else /* Else (including Normal mode etc) write whatever the hardware sends*/
|
||||
psHu32(mem) = (u32)value;
|
||||
psHu32(mem) = (u32)value;
|
||||
|
||||
if ((psHu32(mem) & 0x100) && (psHu32(DMAC_CTRL) & 0x1))
|
||||
func();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Hardware WRITE 8 bit
|
||||
|
||||
char sio_buffer[1024];
|
||||
int sio_count;
|
||||
|
||||
|
@ -456,7 +479,6 @@ void hwWrite8(u32 mem, u8 value) {
|
|||
sio_buffer[sio_count++] = value;
|
||||
}
|
||||
}
|
||||
// SysPrintf("%c", value);
|
||||
break;
|
||||
|
||||
case 0x10003c02: //Tony Hawks Project 8 uses this
|
||||
|
@ -545,10 +567,8 @@ void hwWrite8(u32 mem, u8 value) {
|
|||
|
||||
__forceinline void hwWrite16(u32 mem, u16 value)
|
||||
{
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if( mem >= 0x10002000 && mem < 0x10008000 )
|
||||
SysPrintf("hwWrite16 to %x\n", mem);
|
||||
#endif
|
||||
Console::Notice( "hwWrite16 to %x", params mem );
|
||||
|
||||
switch(mem)
|
||||
{
|
||||
|
@ -767,7 +787,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
|
|||
}
|
||||
}
|
||||
|
||||
// Page 0 of HW mwmory houses registers for Counters 0 and 1
|
||||
// Page 0 of HW memory houses registers for Counters 0 and 1
|
||||
void __fastcall hwWrite32_page_00( u32 mem, u32 value )
|
||||
{
|
||||
mem &= 0xffff;
|
||||
|
@ -787,7 +807,7 @@ void __fastcall hwWrite32_page_00( u32 mem, u32 value )
|
|||
*((u32*)&PS2MEM_HW[mem]) = value;
|
||||
}
|
||||
|
||||
// Page 1 of HW mwmory houses registers for Counters 2 and 3
|
||||
// Page 1 of HW memory houses registers for Counters 2 and 3
|
||||
void __fastcall hwWrite32_page_01( u32 mem, u32 value )
|
||||
{
|
||||
mem &= 0xffff;
|
||||
|
@ -826,24 +846,29 @@ void __fastcall hwWrite32_page_03( u32 mem, u32 value )
|
|||
switch (mem)
|
||||
{
|
||||
case GIF_CTRL:
|
||||
//SysPrintf("GIF_CTRL write %x\n", value);
|
||||
psHu32(mem) = value & 0x8;
|
||||
if (value & 0x1) gsGIFReset();
|
||||
else if( value & 8 ) psHu32(GIF_STAT) |= 8;
|
||||
else psHu32(GIF_STAT) &= ~8;
|
||||
if (value & 0x1)
|
||||
gsGIFReset();
|
||||
else if( value & 8 )
|
||||
psHu32(GIF_STAT) |= 8;
|
||||
else
|
||||
psHu32(GIF_STAT) &= ~8;
|
||||
break;
|
||||
|
||||
case GIF_MODE:
|
||||
{
|
||||
// need to set GIF_MODE (hamster ball)
|
||||
psHu32(GIF_MODE) = value;
|
||||
if (value & 0x1) psHu32(GIF_STAT)|= 0x1;
|
||||
else psHu32(GIF_STAT)&= ~0x1;
|
||||
if (value & 0x4) psHu32(GIF_STAT)|= 0x4;
|
||||
else psHu32(GIF_STAT)&= ~0x4;
|
||||
|
||||
// set/clear bits 0 and 2 as per the GIF_MODE value.
|
||||
const u32 bitmask = 0x1 | 0x4;
|
||||
psHu32(GIF_STAT) &= ~bitmask;
|
||||
psHu32(GIF_STAT) |= (u32)value & bitmask;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIF_STAT: // stat is readonly
|
||||
DevCon::Notice("*PCSX2* Gifstat write value = 0x%x\n", params value);
|
||||
DevCon::Notice("*PCSX2* GIFSTAT write value = 0x%x (readonly, ignored)", params value);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -894,7 +919,11 @@ void __fastcall hwWrite32_page_0E( u32 mem, u32 value )
|
|||
else if( mem == DMAC_STAT )
|
||||
{
|
||||
HW_LOG("DMAC_STAT Write 32bit %x\n", value);
|
||||
psHu16(0xe010)&= ~(value & 0xffff); // clear on 1
|
||||
|
||||
// lower 16 bits: clear on 1
|
||||
// upper 16 bits: reverse on 1
|
||||
|
||||
psHu16(0xe010) &= ~(value & 0xffff);
|
||||
psHu16(0xe012) ^= (u16)(value >> 16);
|
||||
|
||||
cpuTestDMACInts();
|
||||
|
@ -932,16 +961,6 @@ void __fastcall hwWrite32_page_0F( u32 mem, u32 value )
|
|||
psHu32(mem) = value & ~0x80000000; //kill the busy bit
|
||||
break;
|
||||
|
||||
case HELPSWITCH(0x1000f440)://MCH_DRD:
|
||||
psHu32(mem) = value;
|
||||
break;
|
||||
//------------------------------------------------------------------
|
||||
case HELPSWITCH(0x1000f590): // DMAC_ENABLEW
|
||||
HW_LOG("DMAC_ENABLEW Write 32bit %lx\n", value);
|
||||
psHu32(0xf590) = value;
|
||||
psHu32(0xf520) = value;
|
||||
break;
|
||||
//------------------------------------------------------------------
|
||||
case HELPSWITCH(0x1000f200):
|
||||
psHu32(mem) = value;
|
||||
break;
|
||||
|
@ -960,18 +979,29 @@ void __fastcall hwWrite32_page_0F( u32 mem, u32 value )
|
|||
case HELPSWITCH(0x1000f260):
|
||||
psHu32(mem) = 0;
|
||||
break;
|
||||
|
||||
case HELPSWITCH(0x1000f440)://MCH_DRD:
|
||||
psHu32(mem) = value;
|
||||
break;
|
||||
|
||||
case HELPSWITCH(0x1000f590): // DMAC_ENABLEW
|
||||
HW_LOG("DMAC_ENABLEW Write 32bit %lx\n", value);
|
||||
psHu32(0xf590) = value;
|
||||
psHu32(0xf520) = value;
|
||||
break;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
case HELPSWITCH(0x1000f130):
|
||||
case HELPSWITCH(0x1000f410):
|
||||
HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)\n", mem, value, cpuRegs.CP0.n.Status.val);
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
psHu32(mem) = value;
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall hwWrite32_page_other( u32 mem, u32 value )
|
||||
void __fastcall hwWrite32_generic( u32 mem, u32 value )
|
||||
{
|
||||
// Used for developer logging -- optimized away in Public Release.
|
||||
const char* regName = "Unknown";
|
||||
|
@ -1044,141 +1074,175 @@ void __fastcall hwWrite32_page_other( u32 mem, u32 value )
|
|||
psHu32(mem) = value;
|
||||
}
|
||||
|
||||
__forceinline void hwWrite64(u32 mem, u64 value) {
|
||||
u32 val32;
|
||||
int i;
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// HW Write 64 bit
|
||||
|
||||
if ((mem>=0x10002000) && (mem<=0x10002030)) {
|
||||
ipuWrite64(mem, value);
|
||||
void __fastcall hwWrite64_page_02( u32 mem, const mem64_t* srcval )
|
||||
{
|
||||
//hwWrite64( mem, *srcval ); return;
|
||||
ipuWrite64( mem, *srcval );
|
||||
}
|
||||
|
||||
void __fastcall hwWrite64_page_03( u32 mem, const mem64_t* srcval )
|
||||
{
|
||||
//hwWrite64( mem, *srcval ); return;
|
||||
const u64 value = *srcval;
|
||||
|
||||
if(mem>=0x10003800)
|
||||
{
|
||||
if(mem<0x10003c00)
|
||||
vif0Write32(mem, value);
|
||||
else
|
||||
vif1Write32(mem, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((mem>=0x10003800) && (mem<0x10003c00)) {
|
||||
vif0Write32(mem, value); return;
|
||||
}
|
||||
if ((mem>=0x10003c00) && (mem<0x10004000)) {
|
||||
vif1Write32(mem, value); return;
|
||||
}
|
||||
|
||||
switch (mem) {
|
||||
switch (mem)
|
||||
{
|
||||
case GIF_CTRL:
|
||||
DevCon::Status("GIF_CTRL write 64", params value);
|
||||
psHu32(mem) = value & 0x8;
|
||||
if(value & 0x1) {
|
||||
if(value & 0x1)
|
||||
gsGIFReset();
|
||||
//gsReset();
|
||||
}
|
||||
else {
|
||||
if( value & 8 ) psHu32(GIF_STAT) |= 8;
|
||||
else psHu32(GIF_STAT) &= ~8;
|
||||
else
|
||||
{
|
||||
if( value & 8 )
|
||||
psHu32(GIF_STAT) |= 8;
|
||||
else
|
||||
psHu32(GIF_STAT) &= ~8;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case GIF_MODE:
|
||||
{
|
||||
#ifdef GSPATH3FIX
|
||||
Console::Status("GIFMODE64 %x\n", params value);
|
||||
#endif
|
||||
psHu64(GIF_MODE) = value;
|
||||
if (value & 0x1) psHu32(GIF_STAT)|= 0x1;
|
||||
else psHu32(GIF_STAT)&= ~0x1;
|
||||
if (value & 0x4) psHu32(GIF_STAT)|= 0x4;
|
||||
else psHu32(GIF_STAT)&= ~0x4;
|
||||
break;
|
||||
|
||||
// set/clear bits 0 and 2 as per the GIF_MODE value.
|
||||
const u32 bitmask = 0x1 | 0x4;
|
||||
psHu32(GIF_STAT) &= ~bitmask;
|
||||
psHu32(GIF_STAT) |= (u32)value & bitmask;
|
||||
}
|
||||
|
||||
case GIF_STAT: // stat is readonly
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall hwWrite64_page_0E( u32 mem, const mem64_t* srcval )
|
||||
{
|
||||
//hwWrite64( mem, *srcval ); return;
|
||||
|
||||
const u64 value = *srcval;
|
||||
|
||||
if( mem == DMAC_CTRL )
|
||||
{
|
||||
HW_LOG("DMAC_CTRL Write 64bit %x\n", value);
|
||||
}
|
||||
else if( mem == DMAC_STAT )
|
||||
{
|
||||
HW_LOG("DMAC_STAT Write 64bit %x\n", value);
|
||||
|
||||
// lower 16 bits: clear on 1
|
||||
// upper 16 bits: reverse on 1
|
||||
|
||||
psHu16(0xe010) &= ~(value & 0xffff);
|
||||
psHu16(0xe012) ^= (u16)(value >> 16);
|
||||
|
||||
cpuTestDMACInts();
|
||||
return;
|
||||
}
|
||||
|
||||
psHu64(mem) = value;
|
||||
}
|
||||
|
||||
void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval )
|
||||
{
|
||||
//hwWrite64( mem, *srcval ); return;
|
||||
|
||||
const u64 value = *srcval;
|
||||
|
||||
switch (mem)
|
||||
{
|
||||
case 0x1000a000: // dma2 - gif
|
||||
DMA_LOG("0x%8.8x hwWrite64: GSdma %lx\n", cpuRegs.cycle, value);
|
||||
DMA_LOG("0x%8.8x hwWrite64: GSdma %x\n", cpuRegs.cycle, value);
|
||||
DmaExec(dmaGIF, mem, value);
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0x1000e000: // DMAC_CTRL
|
||||
HW_LOG("DMAC_CTRL Write 64bit %x\n", value);
|
||||
psHu64(mem) = value;
|
||||
break;
|
||||
case INTC_STAT:
|
||||
HW_LOG("INTC_STAT Write 64bit %x\n", (u32)value);
|
||||
psHu32(INTC_STAT) &= ~value;
|
||||
//cpuTestINTCInts();
|
||||
break;
|
||||
|
||||
case 0x1000e010: // DMAC_STAT
|
||||
HW_LOG("DMAC_STAT Write 64bit %x\n", value);
|
||||
val32 = (u32)value;
|
||||
psHu16(0xe010)&= ~(val32 & 0xffff); // clear on 1
|
||||
val32 = val32 >> 16;
|
||||
for (i=0; i<16; i++) { // reverse on 1
|
||||
if (val32 & (1<<i)) {
|
||||
if (psHu16(0xe012) & (1<<i))
|
||||
psHu16(0xe012)&= ~(1<<i);
|
||||
else
|
||||
psHu16(0xe012)|= 1<<i;
|
||||
}
|
||||
}
|
||||
cpuTestDMACInts();
|
||||
case INTC_MASK:
|
||||
HW_LOG("INTC_MASK Write 64bit %x\n", (u32)value);
|
||||
psHu32(INTC_MASK) ^= (u16)value;
|
||||
cpuTestINTCInts();
|
||||
break;
|
||||
|
||||
case 0x1000f130:
|
||||
case 0x1000f410:
|
||||
case 0x1000f430:
|
||||
break;
|
||||
|
||||
case 0x1000f590: // DMAC_ENABLEW
|
||||
psHu32(0xf590) = value;
|
||||
psHu32(0xf520) = value;
|
||||
break;
|
||||
|
||||
case 0x1000f000: // INTC_STAT
|
||||
HW_LOG("INTC_STAT Write 64bit %x\n", value);
|
||||
psHu32(INTC_STAT)&=~value;
|
||||
cpuTestINTCInts();
|
||||
break;
|
||||
|
||||
case 0x1000f010: // INTC_MASK
|
||||
HW_LOG("INTC_MASK Write 32bit %x\n", value);
|
||||
for (i=0; i<16; i++) { // reverse on 1
|
||||
const int s = (1<<i);
|
||||
if (value & s) {
|
||||
if (psHu32(INTC_MASK) & s)
|
||||
psHu32(INTC_MASK)&= ~s;
|
||||
else
|
||||
psHu32(INTC_MASK)|= s;
|
||||
}
|
||||
}
|
||||
cpuTestINTCInts();
|
||||
break;
|
||||
|
||||
case 0x1000f130:
|
||||
case 0x1000f410:
|
||||
case 0x1000f430:
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
psHu64(mem) = value;
|
||||
|
||||
HW_LOG("Unknown Hardware write 64 at %x with value %x (status=%x)\n",mem,value, cpuRegs.CP0.n.Status.val);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline void hwWrite128(u32 mem, const u64 *value) {
|
||||
if (mem >= 0x10004000 && mem < 0x10008000) {
|
||||
WriteFIFO(mem, value); return;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// HW Write 128 bit
|
||||
|
||||
void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval)
|
||||
{
|
||||
//hwWrite128( mem, srcval ); return;
|
||||
|
||||
switch (mem)
|
||||
{
|
||||
case INTC_STAT:
|
||||
HW_LOG("INTC_STAT Write 64bit %x\n", (u32)srcval[0]);
|
||||
psHu32(INTC_STAT) &= ~srcval[0];
|
||||
//cpuTestINTCInts();
|
||||
break;
|
||||
|
||||
case INTC_MASK:
|
||||
HW_LOG("INTC_MASK Write 64bit %x\n", (u32)srcval[0]);
|
||||
psHu32(INTC_MASK) ^= (u16)srcval[0];
|
||||
cpuTestINTCInts();
|
||||
break;
|
||||
|
||||
switch (mem) {
|
||||
case 0x1000f590: // DMAC_ENABLEW
|
||||
psHu32(0xf590) = *(u32*)value;
|
||||
psHu32(0xf520) = *(u32*)value;
|
||||
break;
|
||||
psHu32(0xf590) = srcval[0];
|
||||
psHu32(0xf520) = srcval[0];
|
||||
break;
|
||||
|
||||
case 0x1000f130:
|
||||
case 0x1000f410:
|
||||
case 0x1000f430:
|
||||
break;
|
||||
|
||||
default:
|
||||
psHu64(mem ) = srcval[0];
|
||||
psHu64(mem+8) = srcval[1];
|
||||
|
||||
psHu64(mem ) = value[0];
|
||||
psHu64(mem+8) = value[1];
|
||||
|
||||
HW_LOG("Unknown Hardware write 128 at %x with value %x_%x (status=%x)\n", mem, value[1], value[0], cpuRegs.CP0.n.Status.val);
|
||||
break;
|
||||
HW_LOG("Unknown Hardware write 128 at %x with value %x_%x (status=%x)\n", mem, srcval[1], srcval[0], cpuRegs.CP0.n.Status.val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline void intcInterrupt() {
|
||||
__forceinline void intcInterrupt()
|
||||
{
|
||||
if ((cpuRegs.CP0.n.Status.val & 0x400) != 0x400) return;
|
||||
|
||||
if ((psHu32(INTC_STAT)) == 0) {
|
||||
|
@ -1814,5 +1878,143 @@ __forceinline void __fastcall hwWrite32(u32 mem, u32 value)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
__forceinline void hwWrite64(u32 mem, u64 value)
|
||||
{
|
||||
u32 val32;
|
||||
int i;
|
||||
|
||||
if ((mem>=0x10002000) && (mem<=0x10002030)) {
|
||||
ipuWrite64(mem, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((mem>=0x10003800) && (mem<0x10003c00)) {
|
||||
vif0Write32(mem, value); return;
|
||||
}
|
||||
if ((mem>=0x10003c00) && (mem<0x10004000)) {
|
||||
vif1Write32(mem, value); return;
|
||||
}
|
||||
|
||||
switch (mem) {
|
||||
case GIF_CTRL:
|
||||
DevCon::Status("GIF_CTRL write 64", params value);
|
||||
psHu32(mem) = value & 0x8;
|
||||
if(value & 0x1) {
|
||||
gsGIFReset();
|
||||
//gsReset();
|
||||
}
|
||||
else {
|
||||
if( value & 8 ) psHu32(GIF_STAT) |= 8;
|
||||
else psHu32(GIF_STAT) &= ~8;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case GIF_MODE:
|
||||
#ifdef GSPATH3FIX
|
||||
Console::Status("GIFMODE64 %x\n", params value);
|
||||
#endif
|
||||
psHu64(GIF_MODE) = value;
|
||||
if (value & 0x1) psHu32(GIF_STAT)|= 0x1;
|
||||
else psHu32(GIF_STAT)&= ~0x1;
|
||||
if (value & 0x4) psHu32(GIF_STAT)|= 0x4;
|
||||
else psHu32(GIF_STAT)&= ~0x4;
|
||||
break;
|
||||
|
||||
case GIF_STAT: // stat is readonly
|
||||
return;
|
||||
|
||||
case 0x1000a000: // dma2 - gif
|
||||
DMA_LOG("0x%8.8x hwWrite64: GSdma %lx\n", cpuRegs.cycle, value);
|
||||
DmaExec(dmaGIF, mem, value);
|
||||
break;
|
||||
|
||||
case 0x1000e000: // DMAC_CTRL
|
||||
HW_LOG("DMAC_CTRL Write 64bit %x\n", value);
|
||||
psHu64(mem) = value;
|
||||
break;
|
||||
|
||||
case 0x1000e010: // DMAC_STAT
|
||||
HW_LOG("DMAC_STAT Write 64bit %x\n", value);
|
||||
val32 = (u32)value;
|
||||
psHu16(0xe010)&= ~(val32 & 0xffff); // clear on 1
|
||||
val32 = val32 >> 16;
|
||||
for (i=0; i<16; i++) { // reverse on 1
|
||||
if (val32 & (1<<i)) {
|
||||
if (psHu16(0xe012) & (1<<i))
|
||||
psHu16(0xe012)&= ~(1<<i);
|
||||
else
|
||||
psHu16(0xe012)|= 1<<i;
|
||||
}
|
||||
}
|
||||
cpuTestDMACInts();
|
||||
break;
|
||||
|
||||
case 0x1000f590: // DMAC_ENABLEW
|
||||
psHu32(0xf590) = value;
|
||||
psHu32(0xf520) = value;
|
||||
break;
|
||||
|
||||
case 0x1000f000: // INTC_STAT
|
||||
HW_LOG("INTC_STAT Write 64bit %x\n", value);
|
||||
psHu32(INTC_STAT)&=~value;
|
||||
cpuTestINTCInts();
|
||||
break;
|
||||
|
||||
case 0x1000f010: // INTC_MASK
|
||||
HW_LOG("INTC_MASK Write 32bit %x\n", value);
|
||||
for (i=0; i<16; i++) { // reverse on 1
|
||||
const int s = (1<<i);
|
||||
if (value & s) {
|
||||
if (psHu32(INTC_MASK) & s)
|
||||
psHu32(INTC_MASK)&= ~s;
|
||||
else
|
||||
psHu32(INTC_MASK)|= s;
|
||||
}
|
||||
}
|
||||
cpuTestINTCInts();
|
||||
break;
|
||||
|
||||
case 0x1000f130:
|
||||
case 0x1000f410:
|
||||
case 0x1000f430:
|
||||
break;
|
||||
|
||||
default:
|
||||
psHu64(mem) = value;
|
||||
|
||||
HW_LOG("Unknown Hardware write 64 at %x with value %x (status=%x)\n",mem,value, cpuRegs.CP0.n.Status.val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline void hwWrite128(u32 mem, const u64 *value)
|
||||
{
|
||||
if (mem >= 0x10004000 && mem < 0x10008000) {
|
||||
WriteFIFO(mem, value); return;
|
||||
}
|
||||
|
||||
switch (mem) {
|
||||
case 0x1000f590: // DMAC_ENABLEW
|
||||
psHu32(0xf590) = *(u32*)value;
|
||||
psHu32(0xf520) = *(u32*)value;
|
||||
break;
|
||||
case 0x1000f130:
|
||||
case 0x1000f410:
|
||||
case 0x1000f430:
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
psHu64(mem ) = value[0];
|
||||
psHu64(mem+8) = value[1];
|
||||
|
||||
HW_LOG("Unknown Hardware write 128 at %x with value %x_%x (status=%x)\n", mem, value[1], value[0], cpuRegs.CP0.n.Status.val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
47
pcsx2/Hw.h
47
pcsx2/Hw.h
|
@ -32,17 +32,24 @@ extern u8 *psH; // hw mem
|
|||
|
||||
extern void CPU_INT( u32 n, s32 ecycle );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Hardware FIFOs (128 bit access only!)
|
||||
//
|
||||
// VIF0 -- 0x10004000 -- psH[0x4000]
|
||||
// VIF1 -- 0x10005000 -- psH[0x5000]
|
||||
// GIF -- 0x10006000 -- psH[0x6000]
|
||||
// IPUout -- 0x10007000 -- psH[0x7000]
|
||||
// IPUin -- 0x10007010 -- psH[0x7010]
|
||||
|
||||
void ReadFIFO(u32 mem, u64 *out);
|
||||
void ConstReadFIFO(u32 mem);
|
||||
void __fastcall ReadFIFO_page_4(u32 mem, mem128_t *out);
|
||||
void __fastcall ReadFIFO_page_5(u32 mem, mem128_t *out);
|
||||
void __fastcall ReadFIFO_page_6(u32 mem, mem128_t *out);
|
||||
void __fastcall ReadFIFO_page_7(u32 mem, mem128_t *out);
|
||||
|
||||
void WriteFIFO(u32 mem, const u64 *value);
|
||||
void ConstWriteFIFO(u32 mem);
|
||||
void __fastcall WriteFIFO_page_4(u32 mem, const mem128_t *value);
|
||||
void __fastcall WriteFIFO_page_5(u32 mem, const mem128_t *value);
|
||||
void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value);
|
||||
void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value);
|
||||
|
||||
|
||||
//
|
||||
|
@ -364,22 +371,26 @@ void hwShutdown();
|
|||
// hw read functions
|
||||
extern u8 hwRead8 (u32 mem);
|
||||
extern u16 hwRead16(u32 mem);
|
||||
extern u64 hwRead64(u32 mem);
|
||||
extern void hwRead128(u32 mem, u64 *out);
|
||||
|
||||
extern mem32_t __fastcall hwRead32_page_00(u32 mem);
|
||||
extern mem32_t __fastcall hwRead32_page_01(u32 mem);
|
||||
extern mem32_t __fastcall hwRead32_page_02(u32 mem);
|
||||
extern mem32_t __fastcall hwRead32_page_0F(u32 mem);
|
||||
extern mem32_t __fastcall hwRead32_page_other(u32 mem);
|
||||
extern mem32_t __fastcall hwRead32_generic(u32 mem);
|
||||
|
||||
extern mem32_t __fastcall hwRead32(u32 mem);
|
||||
extern void __fastcall hwRead64_page_00(u32 mem, mem64_t* result );
|
||||
extern void __fastcall hwRead64_page_01(u32 mem, mem64_t* result );
|
||||
extern void __fastcall hwRead64_page_02(u32 mem, mem64_t* result );
|
||||
extern void __fastcall hwRead64_generic(u32 mem, mem64_t* result );
|
||||
|
||||
extern void __fastcall hwRead128_page_00(u32 mem, mem128_t* result );
|
||||
extern void __fastcall hwRead128_page_01(u32 mem, mem128_t* result );
|
||||
extern void __fastcall hwRead128_page_02(u32 mem, mem128_t* result );
|
||||
extern void __fastcall hwRead128_generic(u32 mem, mem128_t *out);
|
||||
|
||||
// hw write functions
|
||||
extern void hwWrite8 (u32 mem, u8 value);
|
||||
extern void hwWrite16(u32 mem, u16 value);
|
||||
extern void hwWrite64(u32 mem, u64 value);
|
||||
extern void hwWrite128(u32 mem, const u64 *value);
|
||||
|
||||
extern void __fastcall hwWrite32_page_00( u32 mem, u32 value );
|
||||
extern void __fastcall hwWrite32_page_01( u32 mem, u32 value );
|
||||
|
@ -388,9 +399,21 @@ extern void __fastcall hwWrite32_page_03( u32 mem, u32 value );
|
|||
extern void __fastcall hwWrite32_page_0B( u32 mem, u32 value );
|
||||
extern void __fastcall hwWrite32_page_0E( u32 mem, u32 value );
|
||||
extern void __fastcall hwWrite32_page_0F( u32 mem, u32 value );
|
||||
extern void __fastcall hwWrite32_page_other( u32 mem, u32 value );
|
||||
extern void __fastcall hwWrite32_generic( u32 mem, u32 value );
|
||||
|
||||
extern void __fastcall hwWrite32(u32 mem, u32 value);
|
||||
extern void __fastcall hwWrite64_page_02( u32 mem, const mem64_t* srcval );
|
||||
extern void __fastcall hwWrite64_page_03( u32 mem, const mem64_t* srcval );
|
||||
extern void __fastcall hwWrite64_page_0E( u32 mem, const mem64_t* srcval );
|
||||
extern void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval );
|
||||
|
||||
extern void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval);
|
||||
|
||||
// legacy - used for debugging sometimes
|
||||
//extern mem32_t __fastcall hwRead32(u32 mem);
|
||||
//extern void __fastcall hwWrite32(u32 mem, u32 value);
|
||||
|
||||
//extern void hwWrite64(u32 mem, u64 value);
|
||||
//extern void hwWrite128(u32 mem, const u64 *value);
|
||||
|
||||
void hwIntcIrq(int n);
|
||||
void hwDmacIrq(int n);
|
||||
|
|
134
pcsx2/Memory.cpp
134
pcsx2/Memory.cpp
|
@ -165,6 +165,9 @@ vtlbHandler vu0_micro_mem[2]; // 0 - dynarec, 1 - interpreter
|
|||
vtlbHandler vu1_micro_mem[2]; // 0 - dynarec, 1 - interpreter
|
||||
|
||||
vtlbHandler hw_by_page[0x10];
|
||||
vtlbHandler gs_page_0;
|
||||
vtlbHandler gs_page_1;
|
||||
|
||||
|
||||
// Used to remap the VUmicro memory according to the VU0/VU1 dynarec setting.
|
||||
// (the VU memory operations are different for recs vs. interpreters)
|
||||
|
@ -196,23 +199,36 @@ void memMapPhy()
|
|||
|
||||
//These fallback to mem* stuff ...
|
||||
vtlb_MapHandler(tlb_fallback_1,0x10000000,0x10000);
|
||||
vtlb_MapHandler(tlb_fallback_6,0x12000000,0x10000);
|
||||
vtlb_MapHandler(tlb_fallback_7,0x14000000,0x10000);
|
||||
vtlb_MapHandler(tlb_fallback_4,0x18000000,0x10000);
|
||||
vtlb_MapHandler(tlb_fallback_5,0x1a000000,0x10000);
|
||||
vtlb_MapHandler(tlb_fallback_6,0x12000000,0x10000);
|
||||
vtlb_MapHandler(tlb_fallback_8,0x1f000000,0x10000);
|
||||
vtlb_MapHandler(tlb_fallback_3,0x1f400000,0x10000);
|
||||
vtlb_MapHandler(tlb_fallback_2,0x1f800000,0x10000);
|
||||
vtlb_MapHandler(tlb_fallback_8,0x1f900000,0x10000);
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
// Bind fallback handlers used for logging purposes only.
|
||||
// In release mode the Vtlb will map these addresses directly instead of using
|
||||
// the read/write handlers (which just issue logs and do normal memOps)
|
||||
#endif
|
||||
|
||||
// map specific optimized page handlers for HW accesses
|
||||
vtlb_MapHandler(hw_by_page[0x0], 0x10000000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x1], 0x10001000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x2], 0x10002000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x3], 0x10003000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x4], 0x10004000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x5], 0x10005000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x6], 0x10006000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0x7], 0x10007000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0xb], 0x1000b000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0xe], 0x1000e000, 0x01000);
|
||||
vtlb_MapHandler(hw_by_page[0xf], 0x1000f000, 0x01000);
|
||||
|
||||
vtlb_MapHandler(gs_page_0, 0x12000000, 0x01000);
|
||||
vtlb_MapHandler(gs_page_1, 0x12001000, 0x01000);
|
||||
}
|
||||
|
||||
//Why is this required ?
|
||||
|
@ -298,8 +314,6 @@ mem32_t __fastcall _ext_memRead32(u32 mem)
|
|||
{
|
||||
switch (p)
|
||||
{
|
||||
case 1: // hwm
|
||||
return hwRead32_page_other(mem);
|
||||
case 2: // psh
|
||||
return psxHwRead32(mem);
|
||||
case 6: // gsm
|
||||
|
@ -322,8 +336,6 @@ void __fastcall _ext_memRead64(u32 mem, mem64_t *out)
|
|||
{
|
||||
switch (p)
|
||||
{
|
||||
case 1: // hwm
|
||||
*out = hwRead64(mem); return;
|
||||
case 6: // gsm
|
||||
*out = gsRead64(mem); return;
|
||||
}
|
||||
|
@ -337,8 +349,8 @@ void __fastcall _ext_memRead128(u32 mem, mem128_t *out)
|
|||
{
|
||||
switch (p)
|
||||
{
|
||||
case 1: // hwm
|
||||
hwRead128(mem & ~0xa0000000, out); return;
|
||||
//case 1: // hwm
|
||||
// hwRead128(mem & ~0xa0000000, out); return;
|
||||
case 6: // gsm
|
||||
out[0] = gsRead64(mem );
|
||||
out[1] = gsRead64(mem+8); return;
|
||||
|
@ -398,8 +410,6 @@ template<int p>
|
|||
void __fastcall _ext_memWrite32(u32 mem, u32 value)
|
||||
{
|
||||
switch (p) {
|
||||
case 1: // hwm
|
||||
hwWrite32_page_other(mem, value); return;
|
||||
case 2: // psh
|
||||
psxHwWrite32(mem, value); return;
|
||||
case 6: // gsm
|
||||
|
@ -416,13 +426,13 @@ template<int p>
|
|||
void __fastcall _ext_memWrite64(u32 mem, const u64* value)
|
||||
{
|
||||
|
||||
switch (p) {
|
||||
case 1: // hwm
|
||||
hwWrite64(mem & ~0xa0000000, *value);
|
||||
return;
|
||||
case 6: // gsm
|
||||
gsWrite64(mem & ~0xa0000000, *value); return;
|
||||
}
|
||||
/*switch (p) {
|
||||
//case 1: // hwm
|
||||
// hwWrite64(mem & ~0xa0000000, *value);
|
||||
// return;
|
||||
//case 6: // gsm
|
||||
// gsWrite64(mem & ~0xa0000000, *value); return;
|
||||
}*/
|
||||
|
||||
MEM_LOG("Unknown Memory write64 to address %x with data %8.8x_%8.8x\n", mem, (u32)(*value>>32), (u32)*value);
|
||||
cpuTlbMissW(mem, cpuRegs.branch);
|
||||
|
@ -430,15 +440,15 @@ void __fastcall _ext_memWrite64(u32 mem, const u64* value)
|
|||
template<int p>
|
||||
void __fastcall _ext_memWrite128(u32 mem, const u64 *value)
|
||||
{
|
||||
switch (p) {
|
||||
case 1: // hwm
|
||||
hwWrite128(mem & ~0xa0000000, value);
|
||||
return;
|
||||
case 6: // gsm
|
||||
mem &= ~0xa0000000;
|
||||
gsWrite64(mem, value[0]);
|
||||
gsWrite64(mem+8, value[1]); return;
|
||||
}
|
||||
/*switch (p) {
|
||||
//case 1: // hwm
|
||||
// hwWrite128(mem & ~0xa0000000, value);
|
||||
// return;
|
||||
//case 6: // gsm
|
||||
// mem &= ~0xa0000000;
|
||||
// gsWrite64(mem, value[0]);
|
||||
// gsWrite64(mem+8, value[1]); return;
|
||||
}*/
|
||||
|
||||
MEM_LOG("Unknown Memory write128 to address %x with data %8.8x_%8.8x_%8.8x_%8.8x\n", mem, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]);
|
||||
cpuTlbMissW(mem, cpuRegs.branch);
|
||||
|
@ -671,7 +681,7 @@ void memReset()
|
|||
tlb_fallback_3=vtlb_RegisterHandlerTempl1(_ext_mem,3);
|
||||
tlb_fallback_4=vtlb_RegisterHandlerTempl1(_ext_mem,4);
|
||||
tlb_fallback_5=vtlb_RegisterHandlerTempl1(_ext_mem,5);
|
||||
tlb_fallback_6=vtlb_RegisterHandlerTempl1(_ext_mem,6);
|
||||
//tlb_fallback_6=vtlb_RegisterHandlerTempl1(_ext_mem,6);
|
||||
tlb_fallback_7=vtlb_RegisterHandlerTempl1(_ext_mem,7);
|
||||
tlb_fallback_8=vtlb_RegisterHandlerTempl1(_ext_mem,8);
|
||||
|
||||
|
@ -683,50 +693,88 @@ void memReset()
|
|||
vu0_micro_mem[1] = vtlb_RegisterHandlerTempl2(vuMicro,0,false);
|
||||
vu1_micro_mem[1] = vtlb_RegisterHandlerTempl2(vuMicro,1,false);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// psHw Optimized Mappings
|
||||
// The HW Registers have been split into pages to improve optimization.
|
||||
// Anything not explicitly mapped into one of the hw_by_page handlers will be handled
|
||||
// by the default/generic tlb_fallback_1 handler.
|
||||
|
||||
tlb_fallback_1 = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_other, _ext_memRead64<1>, _ext_memRead128<1>,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_other, _ext_memWrite64<1>, _ext_memWrite128<1>
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, hwRead128_generic,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0x0] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_00, _ext_memRead64<1>, _ext_memRead128<1>,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_00, _ext_memWrite64<1>, _ext_memWrite128<1>
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_00, hwRead64_page_00, hwRead128_page_00,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_00, hwWrite64_generic, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0x1] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_01, _ext_memRead64<1>, _ext_memRead128<1>,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_01, _ext_memWrite64<1>, _ext_memWrite128<1>
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_01, hwRead64_page_01, hwRead128_page_01,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_01, hwWrite64_generic, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0x2] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_02, _ext_memRead64<1>, _ext_memRead128<1>,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_02, _ext_memWrite64<1>, _ext_memWrite128<1>
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_02, hwRead64_page_02, hwRead128_page_02,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_02, hwWrite64_page_02, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0x3] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_other, _ext_memRead64<1>, _ext_memRead128<1>,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_03, _ext_memWrite64<1>, _ext_memWrite128<1>
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, hwRead128_generic,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_03, hwWrite64_page_03, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0x4] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, ReadFIFO_page_4,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, WriteFIFO_page_4
|
||||
);
|
||||
|
||||
hw_by_page[0x5] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, ReadFIFO_page_5,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, WriteFIFO_page_5
|
||||
);
|
||||
|
||||
hw_by_page[0x6] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, ReadFIFO_page_6,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, WriteFIFO_page_6
|
||||
);
|
||||
|
||||
hw_by_page[0x7] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, ReadFIFO_page_7,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_generic, hwWrite64_generic, WriteFIFO_page_7
|
||||
);
|
||||
|
||||
hw_by_page[0xb] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_other, _ext_memRead64<1>, _ext_memRead128<1>,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0B, _ext_memWrite64<1>, _ext_memWrite128<1>
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, hwRead128_generic,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0B, hwWrite64_generic, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0xe] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_other, _ext_memRead64<1>, _ext_memRead128<1>,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0E, _ext_memWrite64<1>, _ext_memWrite128<1>
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_generic, hwRead64_generic, hwRead128_generic,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0E, hwWrite64_page_0E, hwWrite128_generic
|
||||
);
|
||||
|
||||
hw_by_page[0xf] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_0F, _ext_memRead64<1>, _ext_memRead128<1>,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0F, _ext_memWrite64<1>, _ext_memWrite128<1>
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_0F, hwRead64_generic, hwRead128_generic,
|
||||
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0F, hwWrite64_generic, hwWrite128_generic
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// GS Optimized Mappings
|
||||
|
||||
tlb_fallback_6 = vtlb_RegisterHandler(
|
||||
_ext_memRead8<6>, _ext_memRead16<6>, _ext_memRead32<6>, _ext_memRead64<6>, _ext_memRead128<6>,
|
||||
_ext_memWrite8<6>, _ext_memWrite16<6>, _ext_memWrite32<6>, gsWrite64_generic, gsWrite128_generic
|
||||
);
|
||||
|
||||
gs_page_0 = vtlb_RegisterHandler(
|
||||
_ext_memRead8<6>, _ext_memRead16<6>, _ext_memRead32<6>, _ext_memRead64<6>, _ext_memRead128<6>,
|
||||
_ext_memWrite8<6>, _ext_memWrite16<6>, _ext_memWrite32<6>, gsWrite64_page_00, gsWrite128_page_00
|
||||
);
|
||||
|
||||
gs_page_1 = vtlb_RegisterHandler(
|
||||
_ext_memRead8<6>, _ext_memRead16<6>, _ext_memRead32<6>, _ext_memRead64<6>, _ext_memRead128<6>,
|
||||
_ext_memWrite8<6>, _ext_memWrite16<6>, _ext_memWrite32<6>, gsWrite64_page_01, gsWrite128_page_01
|
||||
);
|
||||
|
||||
//vtlb_Reset();
|
||||
|
|
|
@ -33,9 +33,13 @@ namespace Path
|
|||
{
|
||||
|
||||
#ifdef WIN32
|
||||
static const char Separator = '\\';
|
||||
// Path Separator used when creating new paths.
|
||||
static const char Separator( '\\' );
|
||||
// Path separators used when breaking existing paths into parts and pieces.
|
||||
static const string Delimiters( "\\/" );
|
||||
#else
|
||||
static const char Separator = '/';
|
||||
static const char Delimiters( '/' );
|
||||
#endif
|
||||
|
||||
bool Exists( const string& path )
|
||||
|
@ -130,7 +134,7 @@ void Combine( string& dest, const string& srcPath, const string& srcFile )
|
|||
void ReplaceExtension( string& dest, const string& src, const string& ext )
|
||||
{
|
||||
int pos = src.find_last_of( '.' );
|
||||
if( pos == 0 )
|
||||
if( pos == string::npos || pos == 0 )
|
||||
dest = src;
|
||||
else
|
||||
dest.assign( src.begin(), src.begin()+pos );
|
||||
|
@ -142,4 +146,89 @@ void ReplaceExtension( string& dest, const string& src, const string& ext )
|
|||
}
|
||||
}
|
||||
|
||||
// finds the starting character position of a filename for the given source path.
|
||||
static int _findFilenamePosition( const string& src)
|
||||
{
|
||||
// note: the source path could have multiple trailing slashes. We want to ignore those.
|
||||
|
||||
int startpos = src.find_last_not_of( Delimiters );
|
||||
|
||||
if(startpos == string::npos )
|
||||
return 0;
|
||||
|
||||
int pos;
|
||||
|
||||
if( startpos < src.length() )
|
||||
{
|
||||
string trimmed( src.begin(), src.begin()+startpos );
|
||||
pos = trimmed.find_last_of( Delimiters );
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = src.find_last_of( Delimiters );
|
||||
}
|
||||
|
||||
if( pos == string::npos )
|
||||
return 0;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void ReplaceFilename( string& dest, const string& src, const string& newfilename )
|
||||
{
|
||||
int pos = _findFilenamePosition( src );
|
||||
|
||||
if( pos == 0 )
|
||||
dest = src;
|
||||
else
|
||||
dest.assign( src.begin(), src.begin()+pos );
|
||||
|
||||
if( !newfilename.empty() )
|
||||
{
|
||||
dest += '.';
|
||||
dest += newfilename;
|
||||
}
|
||||
}
|
||||
|
||||
void GetFilename( const string& src, string& dest )
|
||||
{
|
||||
int pos = _findFilenamePosition( src );
|
||||
dest.assign( src.begin()+pos, src.end() );
|
||||
}
|
||||
|
||||
void GetDirectory( const string& src, string& dest )
|
||||
{
|
||||
int pos = _findFilenamePosition( src );
|
||||
if( pos == 0 )
|
||||
dest.clear();
|
||||
else
|
||||
dest.assign( src.begin(), src.begin()+pos );
|
||||
}
|
||||
|
||||
void Split( const string& src, string& destpath, string& destfile )
|
||||
{
|
||||
int pos = _findFilenamePosition( src );
|
||||
|
||||
if( pos == 0 )
|
||||
{
|
||||
destpath.clear();
|
||||
destfile = src;
|
||||
}
|
||||
else
|
||||
{
|
||||
destpath.assign( src.begin(), src.begin()+pos );
|
||||
destfile.assign( src.begin()+pos, src.end() );
|
||||
}
|
||||
}
|
||||
|
||||
// Assigns the base/root directory of the given path into dest.
|
||||
// Example /this/that/something.txt -> dest == "/"
|
||||
void GetRootDirectory( const string& src, string& dest )
|
||||
{
|
||||
int pos = src.find_first_of( Delimiters );
|
||||
if( pos == string::npos )
|
||||
dest.clear();
|
||||
else
|
||||
dest.assign( src.begin(), src.begin()+pos );
|
||||
}
|
||||
}
|
|
@ -20,14 +20,20 @@
|
|||
|
||||
namespace Path
|
||||
{
|
||||
void Combine( string& dest, const string& srcPath, const string& srcFile );
|
||||
bool isRooted( const string& path );
|
||||
bool isDirectory( const string& path );
|
||||
bool isFile( const string& path );
|
||||
bool Exists( const string& path );
|
||||
int getFileSize( const string& path );
|
||||
void Combine( std::string& dest, const std::string& srcPath, const std::string& srcFile );
|
||||
bool isRooted( const std::string& path );
|
||||
bool isDirectory( const std::string& path );
|
||||
bool isFile( const std::string& path );
|
||||
bool Exists( const std::string& path );
|
||||
int getFileSize( const std::string& path );
|
||||
|
||||
void ReplaceExtension( std::string& dest, const std::string& src, const std::string& ext );
|
||||
void ReplaceFilename( std::string& dest, const std::string& src, const std::string& newfilename );
|
||||
void GetFilename( const std::string& src, std::string& dest );
|
||||
void GetDirectory( const std::string& src, std::string& dest );
|
||||
void GetRootDirectory( const std::string& src, std::string& dest );
|
||||
void Split( const std::string& src, std::string& destpath, std::string& destfile );
|
||||
|
||||
void ReplaceExtension( string& dest, const string& src, const string& ext );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -374,7 +374,9 @@ void hwConstRead64(u32 mem, int mmreg) {
|
|||
|
||||
PCSX2_ALIGNED16(u32 s_TempFIFO[4]);
|
||||
void hwConstRead128(u32 mem, int xmmreg) {
|
||||
if (mem >= 0x10004000 && mem < 0x10008000) {
|
||||
|
||||
// fixme : This needs to be updated to use the new paged FIFO accessors.
|
||||
/*if (mem >= 0x10004000 && mem < 0x10008000) {
|
||||
iFlushCall(0);
|
||||
PUSH32I((uptr)&s_TempFIFO[0]);
|
||||
PUSH32I(mem);
|
||||
|
@ -382,7 +384,7 @@ void hwConstRead128(u32 mem, int xmmreg) {
|
|||
ADD32ItoR(ESP, 8);
|
||||
_eeReadConstMem128( xmmreg, (uptr)&s_TempFIFO[0]);
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
_eeReadConstMem128( xmmreg, (uptr)PSM(mem));
|
||||
}
|
||||
|
@ -1125,7 +1127,9 @@ void hwConstWrite64(u32 mem, int mmreg)
|
|||
|
||||
void hwConstWrite128(u32 mem, int mmreg)
|
||||
{
|
||||
if (mem >= 0x10004000 && mem < 0x10008000) {
|
||||
// fixme : This needs to be updated to use the new paged FIFO accessors.
|
||||
|
||||
/*if (mem >= 0x10004000 && mem < 0x10008000) {
|
||||
_eeWriteConstMem128((uptr)&s_TempFIFO[0], mmreg);
|
||||
iFlushCall(0);
|
||||
PUSH32I((uptr)&s_TempFIFO[0]);
|
||||
|
@ -1133,7 +1137,7 @@ void hwConstWrite128(u32 mem, int mmreg)
|
|||
CALLFunc((uptr)WriteFIFO);
|
||||
ADD32ItoR(ESP, 8);
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
switch (mem) {
|
||||
case 0x1000f590: // DMAC_ENABLEW
|
||||
|
|
|
@ -40,7 +40,7 @@ void recDoBranchImm( u32* jmpSkip, bool isLikely )
|
|||
pc -= 4; // instruction rewinder for delay slot, if non-likely.
|
||||
recompileNextInstruction(1);
|
||||
}
|
||||
SetBranchImm(pc);
|
||||
SetBranchImm(pc); // start a new recompiled block.
|
||||
}
|
||||
|
||||
void recDoBranchImm_Likely( u32* jmpSkip )
|
||||
|
|
|
@ -680,6 +680,11 @@ int recVUTransformAddr(int x86reg, VURegs* VU, int vireg, int imm)
|
|||
SHL32ItoR(EAX, 4);
|
||||
}
|
||||
else {
|
||||
|
||||
// VU0 has a somewhat interesting memory mapping:
|
||||
// if addr >= 0x4000, reads VU1's VF regs and VI regs
|
||||
// if addr < 0x4000, wrap around at 0x1000
|
||||
|
||||
CMP32ItoR(EAX, 0x400);
|
||||
pjmp[0] = JL8(0); // if addr >= 0x4000, reads VU1's VF regs and VI regs
|
||||
AND32ItoR(EAX, 0x43f);
|
||||
|
|
|
@ -283,9 +283,9 @@ VuBaseBlock::VuBaseBlock()
|
|||
#define SUPERVU_STACKSIZE 0x1000
|
||||
|
||||
static list<VuFunctionHeader*> s_listVUHeaders[2];
|
||||
static list<VuFunctionHeader*>* s_plistCachedHeaders[2];
|
||||
static VuFunctionHeader** recVUHeaders[2] = {NULL};
|
||||
static VuBlockHeader* recVUBlocks[2] = {NULL};
|
||||
static list<VuFunctionHeader*>* s_plistCachedHeaders[2] = {NULL, NULL};
|
||||
static VuFunctionHeader** recVUHeaders[2] = {NULL,NULL};
|
||||
static VuBlockHeader* recVUBlocks[2] = {NULL,NULL};
|
||||
static u8* recVUStack = NULL, *recVUStackPtr = NULL;
|
||||
static vector<_x86regs> s_vecRegArray(128);
|
||||
|
||||
|
@ -403,7 +403,11 @@ void SuperVUReset(int vuindex)
|
|||
if( vuindex < 0 )
|
||||
{
|
||||
DbgCon::Status( "SuperVU reset > Resetting recompiler memory and structures." );
|
||||
memset_8<0xcd, VU_EXESIZE>(s_recVUMem);
|
||||
|
||||
// Does this cause problems on VU recompiler resets? It could, if the VU works like
|
||||
// the EE used to, and actually tries to re-enter the recBlock after issuing a clear. (air)
|
||||
|
||||
//memset_8<0xcd, VU_EXESIZE>(s_recVUMem);
|
||||
memzero_ptr<SUPERVU_STACKSIZE>(recVUStack);
|
||||
|
||||
s_recVUPtr = s_recVUMem;
|
||||
|
@ -795,9 +799,9 @@ static VuFunctionHeader* SuperVURecompileProgram(u32 startpc, int vuindex)
|
|||
// if recPtr reached the mem limit reset whole mem
|
||||
if ( ( (uptr)s_recVUPtr - (uptr)s_recVUMem ) >= VU_EXESIZE-0x40000 ) {
|
||||
//SysPrintf("SuperVU reset mem\n");
|
||||
SuperVUReset(-1);
|
||||
SuperVUReset(0);
|
||||
SuperVUReset(1);
|
||||
SuperVUReset(-1);
|
||||
if( s_TotalVUCycles > 0 ) {
|
||||
// already executing, so return NULL
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in New Issue