IOP Fixes/Optimizations:

* Fixed the IOP's recExecute so that it correctly preserves X86 registers (EDI and EBX were not preserved!)
 * Optimized the recExecute procedure, seems like a nice speedup in FMVs and some games that are IOP intensive.
 * Renamed psxMemRead to iopMemRead, added new Virt/Phys functions, and fixed several instances of DMAs using translated addresses (DMAs are always physical maps).  Our IOP doesn't really emulate the tlb so it won't fix anything, but it's more correct in cas stuff is better supported in the future.
 * Removed unneeded FreezeMMXRegs, since the IOPrec doesn't use any mmx/xmm regs anyway.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@628 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-02-27 18:12:59 +00:00
parent e205999744
commit 377830b3a9
18 changed files with 308 additions and 531 deletions

View File

@ -531,12 +531,10 @@ void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) {
// Now's a good time to reload the ELF info...
if( ElfCRC == 0 )
{
FreezeMMXRegs(1);
ElfCRC = loadElfCRC( str );
ElfApplyPatches();
LoadGameSpecificSettings();
GSsetGameCRC( ElfCRC, 0 );
FreezeMMXRegs(0);
}
}
@ -840,7 +838,7 @@ void cdvdNewDiskCB()
}
}
void mechaDecryptBytes(unsigned char* buffer, int size)
void mechaDecryptBytes( u32 madr, int size )
{
int i;
@ -848,10 +846,11 @@ void mechaDecryptBytes(unsigned char* buffer, int size)
int doXor = (cdvd.decSet) & 1;
int doShift = (cdvd.decSet) & 2;
for (i=0; i<size; i++)
u8* curval = iopPhysMem( madr );
for( i=0; i<size; ++i, ++curval )
{
if (doXor) buffer[i] ^= cdvd.Key[4];
if (doShift) buffer[i] = (buffer[i]>>shiftAmount) | (buffer[i]<<(8-shiftAmount));
if( doXor ) *curval ^= cdvd.Key[4];
if( doShift ) *curval = (*curval >> shiftAmount) | (*curval << (8-shiftAmount) );
}
}
@ -870,10 +869,12 @@ int cdvdReadSector() {
return -1;
}
const u32 madr = HW_DMA3_MADR;
// DMAs use physical addresses (air)
u8* mdest = iopPhysMem( HW_DMA3_MADR );
// if raw dvd sector 'fill in the blanks'
if (cdvd.BlockSize == 2064) {
if (cdvd.BlockSize == 2064)
{
// get info on dvd type and layer1 start
u32 layer1Start;
s32 dualType;
@ -882,57 +883,62 @@ int cdvdReadSector() {
cdvdReadDvdDualInfo(&dualType, &layer1Start);
if((dualType == 1) && (lsn >= layer1Start)) {
if((dualType == 1) && (lsn >= layer1Start))
{
// dual layer ptp disc
layerNum = 1;
lsn = lsn-layer1Start + 0x30000;
} else if((dualType == 2) && (lsn >= layer1Start)) {
} else if((dualType == 2) && (lsn >= layer1Start))
{
// dual layer otp disc
layerNum = 1;
lsn = ~(layer1Start+0x30000 - 1);
} else {
} else
{
// single layer disc
// or on first layer of dual layer disc
layerNum = 0;
lsn += 0x30000;
} // ENDLONGIF- Assumed the other dualType is 0.
mdest[0] = 0x20 | layerNum;
mdest[1] = (u8)(lsn >> 16);
mdest[2] = (u8)(lsn >> 8);
mdest[3] = (u8)(lsn );
PSXMu8(madr+0) = 0x20 | layerNum;
PSXMu8(madr+1) = (u8)(lsn >> 16);
PSXMu8(madr+2) = (u8)(lsn >> 8);
PSXMu8(madr+3) = (u8)(lsn );
// sector IED (not calculated at present)
PSXMu8(madr+4) = 0;
PSXMu8(madr+5) = 0;
mdest[4] = 0;
mdest[5] = 0;
// sector CPR_MAI (not calculated at present)
PSXMu8(madr+ 6) = 0;
PSXMu8(madr+ 7) = 0;
PSXMu8(madr+ 8) = 0;
PSXMu8(madr+ 9) = 0;
PSXMu8(madr+10) = 0;
PSXMu8(madr+11) = 0;
mdest[6] = 0;
mdest[7] = 0;
mdest[8] = 0;
mdest[9] = 0;
mdest[10] = 0;
mdest[11] = 0;
// normal 2048 bytes of sector data
memcpy_fast(PSXM(madr+12), cdr.pTransfer, 2048);
memcpy_fast( &mdest[12], cdr.pTransfer, 2048);
// 4 bytes of edc (not calculated at present)
PSXMu8(madr+2060) = 0;
PSXMu8(madr+2061) = 0;
PSXMu8(madr+2062) = 0;
PSXMu8(madr+2063) = 0;
} else {
// normal read
memcpy_fast((u8*)PSXM(madr), cdr.pTransfer, cdvd.BlockSize);
mdest[2060] = 0;
mdest[2061] = 0;
mdest[2062] = 0;
mdest[2063] = 0;
}
else
{
memcpy_fast( mdest, cdr.pTransfer, cdvd.BlockSize);
}
// decrypt sector's bytes
if(cdvd.decSet)
mechaDecryptBytes((u8*)PSXM(madr), cdvd.BlockSize);
if( cdvd.decSet )
mechaDecryptBytes( HW_DMA3_MADR, cdvd.BlockSize );
// Added a clear after memory write .. never seemed to be necessary before but *should*
// be more correct. (air)
psxCpu->Clear( madr, cdvd.BlockSize/4);
psxCpu->Clear( HW_DMA3_MADR, cdvd.BlockSize/4 );
// SysPrintf("sector %x;%x;%x\n", PSXMu8(madr+0), PSXMu8(madr+1), PSXMu8(madr+2));
@ -1329,7 +1335,7 @@ static uint cdvdStartSeek( uint newsector )
}
else
{
CDR_LOG( "CdSeek Begin > Contigious block without seek - delta=%d sectors\n", delta );
CDR_LOG( "CdSeek Begin > Contiguous block without seek - delta=%d sectors\n", delta );
// seektime is the time it takes to read to the destination block:
seektime = delta * cdvd.ReadTime;
@ -1419,7 +1425,7 @@ void cdvdWrite04(u8 rt) { // NCOMMAND
cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode );
// Set the reading block flag. If a seek is pending then Readed will
// take priority in the handler anyway. If the read is contigeous then
// take priority in the handler anyway. If the read is contiguous then
// this'll skip the seek delay.
cdvd.Reading = 1;
break;
@ -1460,7 +1466,7 @@ void cdvdWrite04(u8 rt) { // NCOMMAND
cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode );
// Set the reading block flag. If a seek is pending then Readed will
// take priority in the handler anyway. If the read is contigeous then
// take priority in the handler anyway. If the read is contiguous then
// this'll skip the seek delay.
cdvd.Reading = 1;
break;
@ -1491,7 +1497,7 @@ void cdvdWrite04(u8 rt) { // NCOMMAND
cdvd.RErr = CDVDreadTrack( cdvd.SeekToSector, cdvd.ReadMode );
// Set the reading block flag. If a seek is pending then Readed will
// take priority in the handler anyway. If the read is contigeous then
// take priority in the handler anyway. If the read is contiguous then
// this'll skip the seek delay.
cdvd.Reading = 1;
break;
@ -1503,7 +1509,7 @@ void cdvdWrite04(u8 rt) { // NCOMMAND
//{
DevCon::WriteLn("CDGetToc Param[0]=%d, Param[1]=%d", params cdvd.Param[0],cdvd.Param[1]);
//}
cdvdGetToc( PSXM( HW_DMA3_MADR ) );
cdvdGetToc( iopPhysMem( HW_DMA3_MADR ) );
cdvdSetIrq( (1<<Irq_CommandComplete) ); //| (1<<Irq_DataReady) );
HW_DMA3_CHCR &= ~0x01000000;
psxDmaInterrupt(3);

View File

@ -921,7 +921,7 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
}
cdsize = (bcr & 0xffff) * 4;
memcpy_fast((u8*)PSXM(madr), cdr.pTransfer, cdsize);
memcpy_fast(iopPhysMem(madr), cdr.pTransfer, cdsize);
psxCpu->Clear(madr, cdsize/4);
cdr.pTransfer+=cdsize;

View File

@ -164,18 +164,18 @@ const char *biosC0n[256] = {
#define ra (psxRegs.GPR.n.ra)
#define pc0 (psxRegs.pc)
#define Ra0 ((char*)PSXM(a0))
#define Ra1 ((char*)PSXM(a1))
#define Ra2 ((char*)PSXM(a2))
#define Ra3 ((char*)PSXM(a3))
#define Rv0 ((char*)PSXM(v0))
#define Rsp ((char*)PSXM(sp))
#define Ra0 (iopVirtMemR<char>(a0))
#define Ra1 (iopVirtMemR<char>(a1))
#define Ra2 (iopVirtMemR<char>(a2))
#define Ra3 (iopVirtMemR<char>(a3))
#define Rv0 (iopVirtMemR<char>(v0))
#define Rsp (iopVirtMemR<char>(sp))
void bios_write() { // 0x35/0x03
if (a0 == 1) { // stdout
char *ptr = Ra1;
const char *ptr = Ra1;
while (a2 > 0) {
SysPrintf("%c", *ptr++); a2--;
@ -195,11 +195,19 @@ void bios_printf() { // 3f
char *ptmp = tmp;
int n=1, i=0, j;
memcpy(save, (char*)PSXM(sp), 4*4);
psxMu32(sp) = a0;
psxMu32(sp + 4) = a1;
psxMu32(sp + 8) = a2;
psxMu32(sp + 12) = a3;
memcpy(save, iopVirtMemR<void>(sp), 4*4);
iopMemWrite32(sp, a0);
iopMemWrite32(sp + 4, a1);
iopMemWrite32(sp + 8, a2);
iopMemWrite32(sp + 12, a3);
// old code used phys... is tlb more correct?
//psxMu32(sp) = a0;
//psxMu32(sp + 4) = a1;
//psxMu32(sp + 8) = a2;
//psxMu32(sp + 12) = a3;
while (Ra0[i]) {
switch (Ra0[i]) {
@ -223,21 +231,21 @@ _start:
switch (Ra0[i]) {
case 'f': case 'F':
ptmp+= sprintf(ptmp, tmp2, (float)psxMu32(sp + n * 4)); n++; break;
ptmp+= sprintf(ptmp, tmp2, (float)iopMemRead32(sp + n * 4)); n++; break;
case 'a': case 'A':
case 'e': case 'E':
case 'g': case 'G':
ptmp+= sprintf(ptmp, tmp2, (double)psxMu32(sp + n * 4)); n++; break;
ptmp+= sprintf(ptmp, tmp2, (double)iopMemRead32(sp + n * 4)); n++; break;
case 'p':
case 'i':
case 'd': case 'D':
case 'o': case 'O':
case 'x': case 'X':
ptmp+= sprintf(ptmp, tmp2, (unsigned int)psxMu32(sp + n * 4)); n++; break;
ptmp+= sprintf(ptmp, tmp2, (unsigned int)iopMemRead32(sp + n * 4)); n++; break;
case 'c':
ptmp+= sprintf(ptmp, tmp2, (unsigned char)psxMu32(sp + n * 4)); n++; break;
ptmp+= sprintf(ptmp, tmp2, (unsigned char)iopMemRead32(sp + n * 4)); n++; break;
case 's':
ptmp+= sprintf(ptmp, tmp2, (char*)PSXM(psxMu32(sp + n * 4))); n++; break;
ptmp+= sprintf(ptmp, tmp2, iopVirtMemR<char>(iopMemRead32(sp + n * 4))); n++; break;
case '%':
*ptmp++ = Ra0[i]; break;
}
@ -249,7 +257,9 @@ _start:
}
*ptmp = 0;
memcpy((char*)PSXM(sp), save, 4*4);
// Note: Use Read to obtain a write pointer here, since we're just writing back the
// temp buffer we saved earlier.
memcpy( (void*)iopVirtMemR<void>(sp), save, 4*4);
Console::Write( Color_Cyan, "%s", params tmp);

View File

@ -43,9 +43,7 @@ static void __fastcall psxDmaGeneric(u32 madr, u32 bcr, u32 chcr, u32 spuCore, _
if(SPU2async)
{
FreezeMMXRegs( 1 );
SPU2async(psxRegs.cycle - psxCounters[6].sCycleT);
FreezeMMXRegs( 0 );
//Console::Status("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT);
psxCounters[6].sCycleT = psxRegs.cycle;
@ -61,12 +59,12 @@ static void __fastcall psxDmaGeneric(u32 madr, u32 bcr, u32 chcr, u32 spuCore, _
{
case 0x01000201: //cpu to spu2 transfer
PSXDMA_LOG("*** DMA %c - mem2spu *** %x addr = %x size = %x\n", dmaNum, chcr, madr, bcr);
spu2WriteFunc((u16 *)PSXM(madr), size*2);
spu2WriteFunc((u16 *)iopPhysMem(madr), size*2);
break;
case 0x01000200: //spu2 to cpu transfer
PSXDMA_LOG("*** DMA %c - spu2mem *** %x addr = %x size = %x\n", dmaNum, chcr, madr, bcr);
spu2ReadFunc((u16 *)PSXM(madr), size*2);
spu2ReadFunc((u16 *)iopPhysMem(madr), size*2);
psxCpu->Clear(spuCore ? HW_DMA7_MADR : HW_DMA4_MADR, size);
break;
@ -97,7 +95,7 @@ void psxDma2(u32 madr, u32 bcr, u32 chcr) // GPU
void psxDma6(u32 madr, u32 bcr, u32 chcr)
{
u32 *mem = (u32 *)PSXM(madr);
u32 *mem = (u32 *)iopPhysMem(madr);
PSXDMA_LOG("*** DMA 6 - OT *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
@ -166,12 +164,12 @@ void psxDma8(u32 madr, u32 bcr, u32 chcr) {
switch (chcr & 0x01000201) {
case 0x01000201: //cpu to dev9 transfer
PSXDMA_LOG("*** DMA 8 - DEV9 mem2dev9 *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
DEV9writeDMA8Mem((u32*)PSXM(madr), size);
DEV9writeDMA8Mem((u32*)iopPhysMem(madr), size);
break;
case 0x01000200: //dev9 to cpu transfer
PSXDMA_LOG("*** DMA 8 - DEV9 dev9mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr);
DEV9readDMA8Mem((u32*)PSXM(madr), size);
DEV9readDMA8Mem((u32*)iopPhysMem(madr), size);
break;
default:

View File

@ -42,7 +42,7 @@ void psxMemShutdown()
{
}
u8 psxMemRead8(u32 mem)
u8 iopMemRead8(u32 mem)
{
u32 t = (mem >> 16) & 0x1fff;
@ -71,7 +71,7 @@ u8 psxMemRead8(u32 mem)
}
}
u16 psxMemRead16(u32 mem)
u16 iopMemRead16(u32 mem)
{
u32 t = (mem >> 16) & 0x1fff;
@ -105,7 +105,7 @@ u16 psxMemRead16(u32 mem)
}
}
u32 psxMemRead32(u32 mem)
u32 iopMemRead32(u32 mem)
{
u32 t = (mem >> 16) & 0x1fff;
@ -144,7 +144,7 @@ u32 psxMemRead32(u32 mem)
}
}
void psxMemWrite8(u32 mem, u8 value)
void iopMemWrite8(u32 mem, u8 value)
{
u32 t = (mem >> 16) & 0x1fff;
@ -179,7 +179,7 @@ void psxMemWrite8(u32 mem, u8 value)
}
}
void psxMemWrite16(u32 mem, u16 value)
void iopMemWrite16(u32 mem, u16 value)
{
u32 t = (mem >> 16) & 0x1fff;
switch(t) {
@ -235,7 +235,7 @@ void psxMemWrite16(u32 mem, u16 value)
}
}
void psxMemWrite32(u32 mem, u32 value)
void iopMemWrite32(u32 mem, u32 value)
{
u32 t = (mem >> 16) & 0x1fff;
switch(t) {
@ -326,22 +326,6 @@ void psxMemWrite32(u32 mem, u32 value)
#else
// TLB functions
#ifdef TLB_DEBUG_MEM
// fixme - there are a few places in the code where this is called that really shouldn't receive null.
// cdvdReadSector in CDVD.cpp, psxDma3 in CdRom.cpp, to name two.
void* PSXM(u32 mem)
{
return (psxMemRLUT[(mem) >> 16] == 0 ? NULL : (void*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff)));
}
void* _PSXM(u32 mem)
{
return ((void*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff)));
}
#endif
u8 *psxM = NULL;
u8 *psxP = NULL;
u8 *psxH = NULL;
@ -442,7 +426,6 @@ void psxMemShutdown()
{
vtlb_free( m_psxAllMem, m_psxMemSize );
m_psxAllMem = NULL;
//safe_aligned_free( m_psxAllMem );
psxM = psxP = psxH = psxS = NULL;
@ -450,7 +433,7 @@ void psxMemShutdown()
psxMemRLUT = NULL;
}
u8 psxMemRead8(u32 mem) {
u8 iopMemRead8(u32 mem) {
const u8* p;
u32 t;
@ -477,7 +460,7 @@ u8 psxMemRead8(u32 mem) {
}
}
u16 psxMemRead16(u32 mem) {
u16 iopMemRead16(u32 mem) {
const u8* p;
u32 t;
@ -525,7 +508,7 @@ u16 psxMemRead16(u32 mem) {
}
}
u32 psxMemRead32(u32 mem) {
u32 iopMemRead32(u32 mem) {
const u8* p;
u32 t;
t = (mem >> 16) & 0x1fff;
@ -573,9 +556,7 @@ u32 psxMemRead32(u32 mem) {
if (t == 0x1000) return DEV9read32(mem & 0x1FFFFFFF);
if (mem != 0xfffe0130) {
#ifdef PSXMEM_LOG
if (g_psxWriteOk) PSXMEM_LOG("err lw %8.8lx\n", mem);
#endif
} else {
return writectrl;
}
@ -584,7 +565,7 @@ u32 psxMemRead32(u32 mem) {
}
}
void psxMemWrite8(u32 mem, u8 value) {
void iopMemWrite8(u32 mem, u8 value) {
char *p;
u32 t;
@ -617,7 +598,7 @@ void psxMemWrite8(u32 mem, u8 value) {
}
}
void psxMemWrite16(u32 mem, u16 value) {
void iopMemWrite16(u32 mem, u16 value) {
char *p;
u32 t;
@ -674,7 +655,7 @@ void psxMemWrite16(u32 mem, u16 value) {
}
}
void psxMemWrite32(u32 mem, u32 value) {
void iopMemWrite32(u32 mem, u32 value) {
char *p;
u32 t;

View File

@ -26,13 +26,31 @@ extern u8 *psxS;
extern uptr *psxMemWLUT;
extern const uptr *psxMemRLUT;
#ifdef TLB_DEBUG_MEM
void* PSXM(u32 mem);
void* _PSXM(u32 mem);
#else
#define PSXM(mem) (psxMemRLUT[(mem) >> 16] == 0 ? NULL : (void*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff)))
#define _PSXM(mem) ((const void*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff)))
#endif
// Obtains a write-safe pointer into the IOP's memory, with TLB address translation.
// Hacky! This should really never be used, since anything reading or writing through the
// TLB should be using iopMemRead/Write instead.
template<typename T>
static __forceinline T* iopVirtMemW( u32 mem )
{
return (psxMemWLUT[(mem) >> 16] == 0) ? NULL : (T*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff));
}
// Obtains a read-safe pointer into the IOP's memory, with TLB address translation.
// Hacky! This should really never be used, since anything reading or writing through the
// TLB should be using iopMemRead/Write instead.
template<typename T>
static __forceinline const T* iopVirtMemR( u32 mem )
{
return (psxMemRLUT[(mem) >> 16] == 0) ? NULL : (const T*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff));
//return ((const T*)(psxMemRLUT[(mem) >> 16] + ((mem) & 0xffff)));
}
// Obtains a pointer to the IOP's physical mapping (bypasses the TLB)
static __forceinline u8* iopPhysMem( u32 addr )
{
return &psxM[addr & 0x1fffff];
}
#define psxSs8(mem) psxS[(mem) & 0xffff]
#define psxSs16(mem) (*(s16*)&psxS[(mem) & 0xffff])
@ -41,14 +59,6 @@ void* _PSXM(u32 mem);
#define psxSu16(mem) (*(u16*)&psxS[(mem) & 0xffff])
#define psxSu32(mem) (*(u32*)&psxS[(mem) & 0xffff])
#define psxMs8(mem) psxM[(mem) & 0x1fffff]
#define psxMs16(mem) (*(s16*)&psxM[(mem) & 0x1fffff])
#define psxMs32(mem) (*(s32*)&psxM[(mem) & 0x1fffff])
#define psxMu8(mem) (*(u8*) &psxM[(mem) & 0x1fffff])
#define psxMu16(mem) (*(u16*)&psxM[(mem) & 0x1fffff])
#define psxMu32(mem) (*(u32*)&psxM[(mem) & 0x1fffff])
#define psxMu64(mem) (*(u64*)&psxM[(mem) & 0x1fffff])
#define psxPs8(mem) psxP[(mem) & 0xffff]
#define psxPs16(mem) (*(s16*)&psxP[(mem) & 0xffff])
#define psxPs32(mem) (*(s32*)&psxP[(mem) & 0xffff])
@ -63,23 +73,23 @@ void* _PSXM(u32 mem);
#define psxHu16(mem) (*(u16*)&psxH[(mem) & 0xffff])
#define psxHu32(mem) (*(u32*)&psxH[(mem) & 0xffff])
#define PSXMs8(mem) (*(s8 *)_PSXM(mem))
#define PSXMs16(mem) (*(s16*)_PSXM(mem))
#define PSXMs32(mem) (*(s32*)_PSXM(mem))
#define PSXMu8(mem) (*(u8 *)_PSXM(mem))
#define PSXMu16(mem) (*(u16*)_PSXM(mem))
#define PSXMu32(mem) (*(u32*)_PSXM(mem))
//#define PSXMs8(mem) (*(s8 *)_PSXM(mem))
//#define PSXMs16(mem) (*(s16*)_PSXM(mem))
//#define PSXMs32(mem) (*(s32*)_PSXM(mem))
//#define PSXMu8(mem) (*(u8 *)_PSXM(mem))
//#define PSXMu16(mem) (*(u16*)_PSXM(mem))
//#define PSXMu32(mem) (*(u32*)_PSXM(mem))
void psxMemAlloc();
void psxMemReset();
void psxMemShutdown();
u8 psxMemRead8 (u32 mem);
u16 psxMemRead16(u32 mem);
u32 psxMemRead32(u32 mem);
void psxMemWrite8 (u32 mem, u8 value);
void psxMemWrite16(u32 mem, u16 value);
void psxMemWrite32(u32 mem, u32 value);
u8 iopMemRead8 (u32 mem);
u16 iopMemRead16(u32 mem);
u32 iopMemRead32(u32 mem);
void iopMemWrite8 (u32 mem, u8 value);
void iopMemWrite16(u32 mem, u16 value);
void iopMemWrite32(u32 mem, u32 value);
// x86reg and mmreg are always x86 regs
void psxRecMemRead8();

View File

@ -222,7 +222,7 @@ void psxDma11(u32 madr, u32 bcr, u32 chcr) {
sio.count = 1;
for(j = 0; j < ((bcr & 0xFFFF) * 4); j++)
{
sio2_fifoIn(PSXMu8(madr));
sio2_fifoIn(iopMemRead8(madr));
madr++;
if(sio2.packet.sendSize == BUFSIZE)
goto finished;
@ -250,7 +250,7 @@ void psxDma12(u32 madr, u32 bcr, u32 chcr) {
bcr = size;
while (bcr > 0) {
PSXMu8(madr) = sio2_fifoOut();
iopMemWrite8( madr, sio2_fifoOut() );
bcr--; madr++;
if(sio2.recvIndex == sio2.packet.sendSize) break;
}

View File

@ -381,13 +381,13 @@ void _applypatch(int place, IniPatch *p)
switch (p->type)
{
case BYTE_T:
psxMemWrite8(p->addr, (u8)p->data);
iopMemWrite8(p->addr, (u8)p->data);
break;
case SHORT_T:
psxMemWrite16(p->addr, (u16)p->data);
iopMemWrite16(p->addr, (u16)p->data);
break;
case WORD_T:
psxMemWrite32(p->addr, (u32)p->data);
iopMemWrite32(p->addr, (u32)p->data);
break;
default:
break;

View File

@ -174,10 +174,10 @@ irxlib irxlibs[32] = {
26 }
};
#define Ra0 ((char*)PSXM(psxRegs.GPR.n.a0))
#define Ra1 ((char*)PSXM(psxRegs.GPR.n.a1))
#define Ra2 ((char*)PSXM(psxRegs.GPR.n.a2))
#define Ra3 ((char*)PSXM(psxRegs.GPR.n.a3))
#define Ra0 (iopVirtMemR<char>(psxRegs.GPR.n.a0))
#define Ra1 (iopVirtMemR<char>(psxRegs.GPR.n.a1))
#define Ra2 (iopVirtMemR<char>(psxRegs.GPR.n.a2))
#define Ra3 (iopVirtMemR<char>(psxRegs.GPR.n.a3))
const char* intrname[]={
"INT_VBLANK", "INT_GM", "INT_CDROM", "INT_DMA", //00
@ -204,17 +204,17 @@ void zeroEx()
#ifdef PCSX2_DEVBUILD
u32 pc;
u32 code;
char *lib;
const char *lib;
char *fname = NULL;
int i;
if (!Config.PsxOut) return;
pc = psxRegs.pc;
while (PSXMu32(pc) != 0x41e00000) pc-=4;
while (iopMemRead32(pc) != 0x41e00000) pc-=4;
lib = (char*)PSXM(pc+12);
code = PSXMu32(psxRegs.pc - 4) & 0xffff;
lib = iopVirtMemR<char>(pc+12);
code = iopMemRead32(psxRegs.pc - 4) & 0xffff;
for (i=0; i<IRXLIBS; i++) {
if (!strncmp(lib, irxlibs[i].name, 8)) {
@ -263,7 +263,7 @@ void zeroEx()
}
if (!strncmp(lib, "loadcore", 8) && code == 6) {
DevCon::WriteLn("loadcore RegisterLibraryEntries (%x): %8.8s", params psxRegs.pc, PSXM(psxRegs.GPR.n.a0+12));
DevCon::WriteLn("loadcore RegisterLibraryEntries (%x): %8.8s", params psxRegs.pc, iopVirtMemR<char>(psxRegs.GPR.n.a0+12));
}
if (!strncmp(lib, "intrman", 7) && code == 4) {
@ -377,8 +377,9 @@ void psxJALR() { if (_Rd_) { _SetLink(_Rd_); } doBranch(_u32(_rRs_)); }
///////////////////////////////////////////
// These macros are used to assemble the repassembler functions
static __forceinline void execI() {
psxRegs.code = PSXMu32(psxRegs.pc);
static __forceinline void execI()
{
psxRegs.code = iopMemRead32(psxRegs.pc);
PSXCPU_LOG("%s\n", disR3000AF(psxRegs.code, psxRegs.pc));

View File

@ -175,47 +175,47 @@ void psxRFE() {
void psxLB() {
if (_Rt_) {
_rRt_ = (s8 )psxMemRead8(_oB_);
_rRt_ = (s8 )iopMemRead8(_oB_);
} else {
psxMemRead8(_oB_);
iopMemRead8(_oB_);
}
}
void psxLBU() {
if (_Rt_) {
_rRt_ = psxMemRead8(_oB_);
_rRt_ = iopMemRead8(_oB_);
} else {
psxMemRead8(_oB_);
iopMemRead8(_oB_);
}
}
void psxLH() {
if (_Rt_) {
_rRt_ = (s16)psxMemRead16(_oB_);
_rRt_ = (s16)iopMemRead16(_oB_);
} else {
psxMemRead16(_oB_);
iopMemRead16(_oB_);
}
}
void psxLHU() {
if (_Rt_) {
_rRt_ = psxMemRead16(_oB_);
_rRt_ = iopMemRead16(_oB_);
} else {
psxMemRead16(_oB_);
iopMemRead16(_oB_);
}
}
void psxLW() {
if (_Rt_) {
_rRt_ = psxMemRead32(_oB_);
_rRt_ = iopMemRead32(_oB_);
} else {
psxMemRead32(_oB_);
iopMemRead32(_oB_);
}
}
void psxLWL() {
u32 shift = (_oB_ & 3) << 3;
u32 mem = psxMemRead32(_oB_ & 0xfffffffc);
u32 mem = iopMemRead32(_oB_ & 0xfffffffc);
if (!_Rt_) return;
_rRt_ = ( _u32(_rRt_) & (0x00ffffff >> shift) ) |
@ -234,11 +234,11 @@ void psxLWL() {
void psxLWR() {
u32 shift = (_oB_ & 3) << 3;
u32 mem = psxMemRead32(_oB_ & 0xfffffffc);
u32 mem = iopMemRead32(_oB_ & 0xfffffffc);
if (!_Rt_) return;
_rRt_ = ( _u32(_rRt_) & (0xffffff00 << (24 - shift)) ) |
( mem >> shift );
( mem >> shift );
/*
Mem = 1234. Reg = abcd
@ -251,15 +251,15 @@ void psxLWR() {
*/
}
void psxSB() { psxMemWrite8 (_oB_, _u8 (_rRt_)); }
void psxSH() { psxMemWrite16(_oB_, _u16(_rRt_)); }
void psxSW() { psxMemWrite32(_oB_, _u32(_rRt_)); }
void psxSB() { iopMemWrite8 (_oB_, _u8 (_rRt_)); }
void psxSH() { iopMemWrite16(_oB_, _u16(_rRt_)); }
void psxSW() { iopMemWrite32(_oB_, _u32(_rRt_)); }
void psxSWL() {
u32 shift = (_oB_ & 3) << 3;
u32 mem = psxMemRead32(_oB_ & 0xfffffffc);
u32 mem = iopMemRead32(_oB_ & 0xfffffffc);
psxMemWrite32((_oB_ & 0xfffffffc), ( ( _u32(_rRt_) >> (24 - shift) ) ) |
iopMemWrite32((_oB_ & 0xfffffffc), ( ( _u32(_rRt_) >> (24 - shift) ) ) |
( mem & (0xffffff00 << shift) ));
/*
Mem = 1234. Reg = abcd
@ -274,9 +274,9 @@ void psxSWL() {
void psxSWR() {
u32 shift = (_oB_ & 3) << 3;
u32 mem = psxMemRead32(_oB_ & 0xfffffffc);
u32 mem = iopMemRead32(_oB_ & 0xfffffffc);
psxMemWrite32((_oB_ & 0xfffffffc), ( ( _u32(_rRt_) << shift ) |
iopMemWrite32((_oB_ & 0xfffffffc), ( ( _u32(_rRt_) << shift ) |
(mem & (0x00ffffff >> (24 - shift)) ) ) );
/*
Mem = 1234. Reg = abcd

View File

@ -244,8 +244,8 @@ void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char
break;
}
if (in->h.destination=='I')
if (PSXM(mem->address & 0x1FFFFFFF))
memcpy(data, PSXM(mem->address & 0x1FFFFFFF), mem->length);
if (iopVirtMemR<void>(mem->address & 0x1FFFFFFF))
memcpy(data, iopVirtMemR<void>(mem->address & 0x1FFFFFFF), mem->length);
else{
out->result=0x11;
strcat(line, " ADDRESS ERROR");
@ -298,8 +298,8 @@ void D2_DBGP(const u8 *inbuffer, u8 *outbuffer, char *message, char *eepc, char
break;
}
if (in->h.destination=='I')
if (PSXM(mem->address & 0x1FFFFFFF))
memcpy(PSXM(mem->address & 0x1FFFFFFF), data, mem->length);
if (iopVirtMemR<void>(mem->address & 0x1FFFFFFF))
memcpy( (void*)iopVirtMemR<void>(mem->address & 0x1FFFFFFF), data, mem->length);
else{
out->result=0x11;
strcat(line, " ADDRESS ERROR");

View File

@ -58,7 +58,7 @@ void D2_ILOADP(const u8 *inbuffer, u8 *outbuffer, char *message){
DECI2_ILOADP_HEADER *in=(DECI2_ILOADP_HEADER*)inbuffer,
*out=(DECI2_ILOADP_HEADER*)outbuffer;
u8 *data=(u8*)in+sizeof(DECI2_ILOADP_HEADER);
irxImageInfo *iii;
const irxImageInfo *iii;
static char line[1024];
memcpy(outbuffer, inbuffer, 128*1024);//BUFFERSIZE
@ -76,7 +76,7 @@ void D2_ILOADP(const u8 *inbuffer, u8 *outbuffer, char *message){
case 4:
sprintf(line, "code=LIST action=%d stamp=%d moduleId=0x%X", in->action, in->stamp, in->moduleId);
data=(u8*)out+sizeof(DECI2_ILOADP_HEADER);
for (iii=(irxImageInfo*)PSXM(0x800); iii; iii=iii->next?(irxImageInfo*)PSXM(iii->next):0, data+=4)
for (iii=iopVirtMemR<irxImageInfo>(0x800); iii; iii=iii->next?iopVirtMemR<irxImageInfo>(iii->next):0, data+=4)
*(u32*)data=iii->index;
out->h.length=data-(u8*)out;
@ -84,13 +84,13 @@ void D2_ILOADP(const u8 *inbuffer, u8 *outbuffer, char *message){
case 6:
sprintf(line, "code=INFO action=%d stamp=%d moduleId=0x%X", in->action, in->stamp, in->moduleId);
data=(u8*)out+sizeof(DECI2_ILOADP_HEADER);
for(iii=(irxImageInfo*)PSXM(0x800); iii; iii=iii->next?(irxImageInfo*)PSXM(iii->next):0)
for(iii=iopVirtMemR<irxImageInfo>(0x800); iii; iii=iii->next?iopVirtMemR<irxImageInfo>(iii->next):0)
if (iii->index==in->moduleId){
writeInfo((DECI2_ILOADP_INFO*)data,
iii->version, iii->flags, iii->vaddr, iii->text_size, iii->data_size, iii->bss_size);
data+=sizeof(DECI2_ILOADP_INFO);
strcpy((char*)data, (char*)PSXM(iii->name));
data+=strlen((char*)PSXM(iii->name))+4;
strcpy((char*)data, iopVirtMemR<char>(iii->name));
data+=strlen(iopVirtMemR<char>(iii->name))+4;
data=(u8*)((int)data & 0xFFFFFFFC);
break;

View File

@ -204,11 +204,11 @@ __forceinline void SIF0Dma()
else // Chain mode
{
// Process DMA tag at HW_DMA9_TADR
sif0.sifData = *(struct sifData *)PSXM(HW_DMA9_TADR);
sif0.sifData = *(sifData *)iopPhysMem( HW_DMA9_TADR );
sif0.sifData.words = (sif0.sifData.words + 3) & 0xfffffffc; // Round up to nearest 4.
SIF0write((u32*)PSXM(HW_DMA9_TADR+8), 4);
SIF0write((u32*)iopPhysMem(HW_DMA9_TADR+8), 4);
//psxCycles += 2;
@ -231,7 +231,7 @@ __forceinline void SIF0Dma()
SIF_LOG("+++++++++++ %lX of %lX\n", wTransfer, sif0.counter /*(HW_DMA9_BCR >> 16)*/ );
SIF0write((u32*)PSXM(HW_DMA9_MADR), wTransfer);
SIF0write((u32*)iopPhysMem(HW_DMA9_MADR), wTransfer);
HW_DMA9_MADR += wTransfer << 2;
//HW_DMA9_BCR = (HW_DMA9_BCR & 0xFFFF) | (((HW_DMA9_BCR >> 16) - wTransfer)<<16);
psxCycles += (wTransfer / 4) * BIAS; // fixme : should be / 16
@ -453,7 +453,7 @@ __forceinline void SIF1Dma()
SIF_LOG(" IOP SIF doing transfer %04X to %08X\n", readSize, HW_DMA10_MADR);
SIF1read((u32*)PSXM(HW_DMA10_MADR), readSize);
SIF1read((u32*)iopPhysMem(HW_DMA10_MADR), readSize);
psxCpu->Clear(HW_DMA10_MADR, readSize);
psxCycles += readSize / 4; // fixme: should be / 16
sif1.counter = size-readSize;

View File

@ -57,7 +57,7 @@ void MakeDebugOpcode(void)
void MakeIOPDebugOpcode(void)
{
psxRegs.code = PSXMu32( opcode_addr);
psxRegs.code = iopMemRead32( opcode_addr );
}
BOOL HasBreakpoint()
@ -671,7 +671,7 @@ void RefreshIOPDebugger(void)
for (t = DebuggerIOPPC, cnt = 0; t < (DebuggerIOPPC + 0x00000029); t += 0x00000004, cnt++)
{
// Make the opcode.
u32 mem = PSXMu32(t);
u32 mem = iopMemRead32( t );
char *str = R3000A::disR3000Fasm(mem, t);
SendMessage(hWnd_IOP_debugdisasm, LB_ADDSTRING, 0, (LPARAM)str);
}

View File

@ -8,221 +8,14 @@
.extern b440
.extern b440table
#define PS2MEM_BASE_ 0x18000000 // has to match Memory.h
#define BLOCKTYPE_STARTPC 4 // startpc offset
#define BLOCKTYPE_DELAYSLOT 1 // if bit set, delay slot
#define BASEBLOCK_SIZE 2 // in dwords
#define PCOFFSET 0x208
#define PSX_MEMMASK 0x5fffffff
#ifdef __x86_64__
#define REG_PC %edi
#define REG_BLOCK %r12
#define REG_BLOCKd %r12d
.globl R3000AExecute
R3000AExecute:
push %rbx
push %rbp
push %r12
push %r13
push %r14
push %r15
// calc PSX_GETBLOCK
// ((BASEBLOCK*)(recLUT[((u32)(x)) >> 16] + (sizeof(BASEBLOCK)/4)*((x) & 0xffff)))
mov %eax, dword ptr [psxRegs + PCOFFSET]
mov REG_PC, %eax
mov REG_BLOCKd, %eax
shl %rax, 32
shr %rax, 48
and REG_BLOCK, 0xfffc
shl %rax, 3
add %rax, [psxRecLUT]
shl REG_BLOCK, 1
add REG_BLOCK, [%rax]
mov %r8d, [REG_BLOCK+4]
mov %r9d, REG_PC
and %r8d, 0x5fffffff
and %r9d, 0x5fffffff
cmp %r8d, %r9d
jne Execute_Recompile
mov %edx, [REG_BLOCK]
and %rdx, 0xfffffff // pFnptr
jnz Execute_Function
Execute_Recompile:
call psxRecRecompile
mov %edx, [REG_BLOCK]
and %rdx, 0xfffffff // pFnptr
Execute_Function:
call %rdx
pop %r15
pop %r14
pop %r13
pop %r12
pop %rbp
pop %rbx
ret
// jumped to when invalid psxpc address
.globl psxDispatcher
psxDispatcher:
// EDX contains the current psxpc to jump to, stack contains the jump addr to modify
push %rdx
// calc PSX_GETBLOCK
// ((BASEBLOCK*)(recLUT[((u32)(x)) >> 16] + (sizeof(BASEBLOCK)/4)*((x) & 0xffff)))
mov %eax, dword ptr [psxRegs + PCOFFSET]
mov REG_PC, %eax
mov REG_BLOCKd, %eax
shl %rax, 32
shr %rax, 48
and REG_BLOCK, 0xfffc
shl %rax, 3
add %rax, [psxRecLUT]
shl REG_BLOCK, 1
add REG_BLOCK, [%rax]
// check if startpc&PSX_MEMMASK == psxRegs.pc&PSX_MEMMASK
mov %eax, REG_PC
mov %edx, [REG_BLOCK+BLOCKTYPE_STARTPC]
and %eax, PSX_MEMMASK // remove higher bits
and %edx, PSX_MEMMASK
cmp %eax, %edx
je psxDispatcher_CheckPtr
// recompile
call psxRecRecompile
psxDispatcher_CheckPtr:
mov REG_BLOCKd, dword ptr [REG_BLOCK]
#ifdef _DEBUG
test REG_BLOCKd, REG_BLOCKd
jnz psxDispatcher_CallFn
// throw an exception
int 10
psxDispatcher_CallFn:
#endif
//and REG_BLOCK, 0x0fffffff
shl REG_BLOCK, 4
mov %rdx, REG_BLOCK
pop %rcx // x86Ptr to mod
sub %rdx, %rcx
sub %rdx, 4
mov [%rcx], %edx
jmp REG_BLOCK
.globl psxDispatcherClear
psxDispatcherClear:
// %EDX contains the current psxpc
mov dword ptr [psxRegs + PCOFFSET], %edx
mov %eax, %edx
// calc PSX_GETBLOCK
// ((BASEBLOCK*)(recLUT[((u32)(x)) >> 16] + (sizeof(BASEBLOCK)/4)*((x) & 0xffff)))
mov REG_BLOCKd, %edx
shl %rax, 32
shr %rax, 48
and REG_BLOCK, 0xfffc
shl %rax, 3
add %rax, [psxRecLUT]
shl REG_BLOCK, 1
add REG_BLOCK, [%rax]
// check if startpc&PSX_MEMMASK == psxRegs.pc&PSX_MEMMASK
mov REG_PC, %edx
mov %eax, REG_PC
mov %edx, [REG_BLOCK+BLOCKTYPE_STARTPC]
and %eax, PSX_MEMMASK // remove higher bits
and %edx, PSX_MEMMASK
cmp %eax, %edx
jne psxDispatcherClear_Recompile
mov %eax, dword ptr [REG_BLOCK]
#ifdef _DEBUG
test %eax, %eax
jnz psxDispatcherClear_CallFn
// throw an exception
int 10
psxDispatcherClear_CallFn:
#endif
//and %rax, 0x0fffffff
shl %rax, 4
jmp %rax
psxDispatcherClear_Recompile:
call psxRecRecompile
mov %eax, dword ptr [REG_BLOCK]
// r15 holds the prev x86 pointer
//and %rax, 0x0fffffff
shl %rax, 4
mov byte ptr [%r15], 0xe9 // jmp32
mov %rdx, %rax
sub %rdx, %r15
sub %rdx, 5
mov [%r15+1], %edx
jmp %rax
// called when jumping to variable psxpc address
.globl psxDispatcherReg
psxDispatcherReg:
//s_pDispatchBlock = PSX_GETBLOCK(psxRegs.pc);
mov %eax, dword ptr [psxRegs + PCOFFSET]
mov REG_PC, %eax
mov REG_BLOCKd, %eax
shl %rax, 32
shr %rax, 48
and REG_BLOCK, 0xfffc
shl %rax, 3
add %rax, [psxRecLUT]
shl REG_BLOCK, 1
add REG_BLOCK, [%rax]
// check if startpc == psxRegs.pc
cmp REG_PC, dword ptr [REG_BLOCK+BLOCKTYPE_STARTPC]
jne psxDispatcherReg_recomp
mov REG_BLOCKd, dword ptr [REG_BLOCK]
#ifdef _DEBUG
test %eax, %eax
jnz psxDispatcherReg_CallFn2
// throw an exception
int 10
psxDispatcherReg_CallFn2:
#endif
and REG_BLOCK, 0x0fffffff
jmp REG_BLOCK // fnptr
psxDispatcherReg_recomp:
call psxRecRecompile
mov %eax, dword ptr [REG_BLOCK]
//and %rax, 0x0fffffff
shl, REG_BLOCK, 4
jmp %rax // fnprt
#else // not x86-64
#define REG_PC %ecx
#define REG_BLOCK %esi
@ -247,8 +40,8 @@ psxDispatcher:
// check if startpc&PSX_MEMMASK == psxRegs.pc&PSX_MEMMASK
mov %eax, REG_PC
mov %edx, [REG_BLOCK+BLOCKTYPE_STARTPC]
and %eax, PSX_MEMMASK // remove higher bits
and %edx, PSX_MEMMASK
//and %eax, PSX_MEMMASK // remove higher bits
//and %edx, PSX_MEMMASK
cmp %eax, %edx
je psxDispatcher_CheckPtr
@ -300,8 +93,8 @@ psxDispatcherClear:
mov %eax, %edx
mov REG_PC, %edx
mov %edx, [REG_BLOCK+BLOCKTYPE_STARTPC]
and %eax, PSX_MEMMASK // remove higher bits
and %edx, PSX_MEMMASK
//and %eax, PSX_MEMMASK // remove higher bits
//and %edx, PSX_MEMMASK
cmp %eax, %edx
jne psxDispatcherClear_Recompile
@ -379,16 +172,14 @@ psxDispatcherReg_CallFn2:
jmp %eax // fnptr
psxDispatcherReg_recomp:
sub %esp, 8
mov dword ptr [%esp+4], %edx
mov dword ptr [%esp], %ecx
// changed this to use push/pop instead (faster on cores) - air
push edx
push ecx
call psxRecRecompile
mov %edx, dword ptr [%esp+4]
add %esp, 8
pop ecx
pop edx
mov %eax, dword ptr [%edx]
//and %eax, 0x0fffffff
shl %eax, 4
jmp %eax // fnptr
#endif

View File

@ -100,7 +100,6 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch);
void psxRecompileNextInstruction(int delayslot);
extern void (*rpsxBSC[64])();
extern void (*rpsxBSC_co[64])();
void rpsxpropBSC(EEINST* prev, EEINST* pinst);
#ifdef _DEBUG
@ -157,7 +156,7 @@ static void iIopDumpBlock( int startpc, u8 * ptr )
f = fopen( filename, "w" );
assert( f != NULL );
for ( i = startpc; i < s_nEndBlock; i += 4 ) {
fprintf( f, "%s\n", disR3000Fasm( *(u32*)PSXM( i ), i ) );
fprintf( f, "%s\n", disR3000Fasm( iopMemRead32( i ), i ) );
}
// write the instruction info
@ -655,17 +654,9 @@ static void recShutdown()
#pragma warning(disable:4731) // frame pointer register 'ebp' modified by inline assembly code
static u32 s_uSaveESP = 0;
/*
static __forceinline void R3000AExecute()
{
#ifdef _DEBUG
u8* fnptr;
u32 oldesi;
/*#else
R3000AFNPTR pfn;*/
#endif
BASEBLOCK* pblock;
pblock = PSX_GETBLOCK(psxRegs.pc);
@ -709,40 +700,29 @@ static __forceinline void R3000AExecute()
#else
((R3000AFNPTR)pblock->GetFnptr())();
#endif
}
}*/
u32 g_psxlastpc = 0;
#if defined(_MSC_VER)
#ifdef _MSC_VER
static u32 g_temp;
// jumped to when invalid psxpc address
__declspec(naked,noreturn) void psxDispatcher()
__declspec(naked) void psxDispatcher()
{
// EDX contains the current psxpc to jump to, stack contains the jump addr to modify
__asm push edx
// calc PSX_GETBLOCK
s_pDispatchBlock = PSX_GETBLOCK(psxRegs.pc);
__asm {
mov eax, s_pDispatchBlock
//jASSUME( psxRegs.pc <= PSX_MEMMASK );
s_pDispatchBlock = PSX_GETBLOCK( psxRegs.pc );
// check if startpc&PSX_MEMMASK == psxRegs.pc&PSX_MEMMASK
mov ecx, psxRegs.pc
mov edx, [eax+BLOCKTYPE_STARTPC];
and ecx, PSX_MEMMASK // remove higher bits
and edx, PSX_MEMMASK
cmp ecx, edx
je CheckPtr
if( s_pDispatchBlock->startpc != psxRegs.pc )
psxRecRecompile(psxRegs.pc);
// recompile
push psxRegs.pc // psxpc
call psxRecRecompile
add esp, 4 // pop old param
__asm
{
mov eax, s_pDispatchBlock
CheckPtr:
mov eax, dword ptr [eax]
}
@ -751,11 +731,12 @@ CheckPtr:
assert( g_temp );
#endif
__asm {
//and eax, 0x0fffffff
// Modify the prev block's jump address, and jump to the new block:
__asm
{
shl eax,4
mov edx, eax
pop ecx // x86Ptr to mod
mov edx, eax
sub edx, ecx
sub edx, 4
mov dword ptr [ecx], edx
@ -764,20 +745,23 @@ CheckPtr:
}
}
__declspec(naked,noreturn) void psxDispatcherClear()
__declspec(naked) void psxDispatcherClear()
{
// EDX contains the current psxpc
__asm mov psxRegs.pc, edx
__asm push edx
//jASSUME( psxRegs.pc <= PSX_MEMMASK );
// calc PSX_GETBLOCK
s_pDispatchBlock = PSX_GETBLOCK(psxRegs.pc);
if( (s_pDispatchBlock->startpc&PSX_MEMMASK) == (psxRegs.pc&PSX_MEMMASK) ) {
if( s_pDispatchBlock->startpc == psxRegs.pc ) {
assert( s_pDispatchBlock->GetFnptr() != 0 );
// already modded the code, jump to the new place
__asm {
__asm
{
pop edx
add esp, 4 // ignore stack
mov eax, s_pDispatchBlock
@ -788,7 +772,8 @@ __declspec(naked,noreturn) void psxDispatcherClear()
}
}
__asm {
__asm
{
call psxRecRecompile
add esp, 4 // pop old param
mov eax, s_pDispatchBlock
@ -809,32 +794,18 @@ __declspec(naked,noreturn) void psxDispatcherClear()
}
// called when jumping to variable psxpc address
__declspec(naked,noreturn) void psxDispatcherReg()
__declspec(naked) void psxDispatcherReg()
{
__asm {
//s_pDispatchBlock = PSX_GETBLOCK(psxRegs.pc);
mov edx, psxRegs.pc
mov ecx, edx
}
//jASSUME( psxRegs.pc <= PSX_MEMMASK );
s_pDispatchBlock = PSX_GETBLOCK( psxRegs.pc );
__asm {
shr edx, 14
and edx, 0xfffffffc
add edx, psxRecLUT
mov edx, dword ptr [edx]
if( s_pDispatchBlock->startpc != psxRegs.pc )
psxRecRecompile(psxRegs.pc);
mov eax, ecx
and eax, 0xfffc
// edx += 2*eax
shl eax, 1
add edx, eax
// check if startpc == psxRegs.pc
mov eax, ecx
cmp eax, dword ptr [edx+BLOCKTYPE_STARTPC]
jne recomp
mov eax, dword ptr [edx]
__asm
{
mov eax, s_pDispatchBlock
mov eax, dword ptr [eax]
}
#ifdef _DEBUG
@ -842,23 +813,10 @@ __declspec(naked,noreturn) void psxDispatcherReg()
assert( g_temp );
#endif
__asm {
//and eax, 0x0fffffff
shl eax,4
jmp eax // fnptr
recomp:
sub esp, 8
mov dword ptr [esp+4], edx
mov dword ptr [esp], ecx
call psxRecRecompile
mov edx, dword ptr [esp+4]
add esp, 8
mov eax, dword ptr [edx]
//and eax, 0x0fffffff
shl eax,4
jmp eax // fnptr
__asm
{
shl eax, 4
jmp eax
}
}
@ -876,6 +834,58 @@ void psxDispatcherReg();
#endif // _MSC_VER
static void recExecute()
{
// note: this function is currently never used.
//for (;;) R3000AExecute();
}
static s32 recExecuteBlock( s32 eeCycles )
{
psxBreak = 0;
psxCycleEE = eeCycles;
// Register freezing note:
// The IOP does not use mmx/xmm registers, so we don't modify the status
// of the g_EEFreezeRegs here.
#ifdef _MSC_VER
__asm
{
push ebx
push esi
push edi
push ebp
call psxDispatcherReg
pop ebp
pop edi
pop esi
pop ebx
}
#else
__asm__
(
".intel_syntax\n"
"push %ebx\n"
"push %esi\n"
"push %edi\n"
"push %ebp\n"
"call psxDispatcherReg\n"
"pop %ebp\n"
"pop %edi\n"
"pop %esi\n"
"pop %ebx\n"
".att_syntax\n"
);
#endif
return psxBreak + psxCycleEE;
}
static void recClear(u32 Addr, u32 Size)
{
u32 i;
@ -1034,7 +1044,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
x86SetJ8( j8Ptr[0] );
}
static int *s_pCode;
static const int *s_pCode;
#if !defined(_MSC_VER)
static void checkcodefn()
@ -1148,7 +1158,7 @@ void psxRecompileNextInstruction(int delayslot)
MOV32ItoR(EAX, psxpc);
#endif
s_pCode = (int *)PSXM( psxpc );
s_pCode = iopVirtMemR<int>( psxpc );
assert(s_pCode);
psxRegs.code = *(int *)s_pCode;
@ -1185,18 +1195,6 @@ void psxRecompileNextInstruction(int delayslot)
_clearNeededX86regs();
}
static void recExecute() {
for (;;) R3000AExecute();
}
static s32 recExecuteBlock( s32 eeCycles )
{
psxBreak = 0;
psxCycleEE = eeCycles;
R3000AExecute();
return psxBreak + psxCycleEE;
}
#include "IopHw.h"
void iDumpPsxRegisters(u32 startpc, u32 temp)
@ -1354,7 +1352,7 @@ void psxRecRecompile(u32 startpc)
}
}
psxRegs.code = *(int *)PSXM(i);
psxRegs.code = iopMemRead32(i);
switch(psxRegs.code >> 26) {
case 0: // special
@ -1414,7 +1412,7 @@ StartRecomp:
pcur->info = 0;
for(i = s_nEndBlock; i > startpc; i -= 4 ) {
psxRegs.code = *(int *)PSXM(i-4);
psxRegs.code = iopMemRead32(i-4);
pcur[-1] = pcur[0];
rpsxpropBSC(pcur-1, pcur);
pcur--;

View File

@ -895,7 +895,7 @@ REC_FUNC(SWR);
#else
// TLB loadstore functions (slower
// TLB loadstore functions
REC_FUNC(LWL);
REC_FUNC(LWR);
REC_FUNC(SWL);
@ -909,7 +909,7 @@ static void rpsxLB()
MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]);
if (_Imm_) ADD32ItoR(X86ARG1, _Imm_);
_callFunctionArg1((uptr)psxMemRead8, X86ARG1|MEM_X86TAG, 0);
_callFunctionArg1((uptr)iopMemRead8, X86ARG1|MEM_X86TAG, 0);
if (_Rt_) {
MOVSX32R8toR(EAX, EAX);
MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
@ -925,7 +925,7 @@ static void rpsxLBU()
MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]);
if (_Imm_) ADD32ItoR(X86ARG1, _Imm_);
_callFunctionArg1((uptr)psxMemRead8, X86ARG1|MEM_X86TAG, 0);
_callFunctionArg1((uptr)iopMemRead8, X86ARG1|MEM_X86TAG, 0);
if (_Rt_) {
MOVZX32R8toR(EAX, EAX);
MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
@ -941,7 +941,7 @@ static void rpsxLH()
MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]);
if (_Imm_) ADD32ItoR(X86ARG1, _Imm_);
_callFunctionArg1((uptr)psxMemRead16, X86ARG1|MEM_X86TAG, 0);
_callFunctionArg1((uptr)iopMemRead16, X86ARG1|MEM_X86TAG, 0);
if (_Rt_) {
MOVSX32R16toR(EAX, EAX);
MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
@ -957,7 +957,7 @@ static void rpsxLHU()
MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]);
if (_Imm_) ADD32ItoR(X86ARG1, _Imm_);
_callFunctionArg1((uptr)psxMemRead16, X86ARG1|MEM_X86TAG, 0);
_callFunctionArg1((uptr)iopMemRead16, X86ARG1|MEM_X86TAG, 0);
if (_Rt_) {
MOVZX32R16toR(EAX, EAX);
MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
@ -975,16 +975,13 @@ static void rpsxLW()
MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]);
if (_Imm_) ADD32ItoR(X86ARG1, _Imm_);
#ifndef TLB_DEBUG_MEM
TEST32ItoR(X86ARG1, 0x10000000);
j8Ptr[0] = JZ8(0);
#endif
_callFunctionArg1((uptr)psxMemRead32, X86ARG1|MEM_X86TAG, 0);
_callFunctionArg1((uptr)iopMemRead32, X86ARG1|MEM_X86TAG, 0);
if (_Rt_) {
MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
}
#ifndef TLB_DEBUG_MEM
j8Ptr[1] = JMP8(0);
x86SetJ8(j8Ptr[0]);
@ -996,7 +993,6 @@ static void rpsxLW()
MOV32RtoM( (uptr)&psxRegs.GPR.r[_Rt_], X86ARG1);
x86SetJ8(j8Ptr[1]);
#endif
PSX_DEL_CONST(_Rt_);
}
@ -1007,7 +1003,7 @@ static void rpsxSB()
MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]);
if (_Imm_) ADD32ItoR(X86ARG1, _Imm_);
_callFunctionArg2((uptr)psxMemWrite8, X86ARG1|MEM_X86TAG, MEM_MEMORYTAG, 0, (uptr)&psxRegs.GPR.r[_Rt_]);
_callFunctionArg2((uptr)iopMemWrite8, X86ARG1|MEM_X86TAG, MEM_MEMORYTAG, 0, (uptr)&psxRegs.GPR.r[_Rt_]);
}
static void rpsxSH()
@ -1017,7 +1013,7 @@ static void rpsxSH()
MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]);
if (_Imm_) ADD32ItoR(X86ARG1, _Imm_);
_callFunctionArg2((uptr)psxMemWrite16, X86ARG1|MEM_X86TAG, MEM_MEMORYTAG, 0, (uptr)&psxRegs.GPR.r[_Rt_]);
_callFunctionArg2((uptr)iopMemWrite16, X86ARG1|MEM_X86TAG, MEM_MEMORYTAG, 0, (uptr)&psxRegs.GPR.r[_Rt_]);
}
static void rpsxSW()
@ -1027,7 +1023,7 @@ static void rpsxSW()
MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rs_]);
if (_Imm_) ADD32ItoR(X86ARG1, _Imm_);
_callFunctionArg2((uptr)psxMemWrite32, X86ARG1|MEM_X86TAG, MEM_MEMORYTAG, 0, (uptr)&psxRegs.GPR.r[_Rt_]);
_callFunctionArg2((uptr)iopMemWrite32, X86ARG1|MEM_X86TAG, MEM_MEMORYTAG, 0, (uptr)&psxRegs.GPR.r[_Rt_]);
}
#endif // end load store
@ -1326,7 +1322,7 @@ void rpsxBEQ_process(int info, int process)
x86Ptr = prevx86;
s_do32 = 1;
psxpc -= 4;
psxRegs.code = *(u32*)PSXM( psxpc - 4 );
psxRegs.code = iopMemRead32( psxpc - 4 );
psxLoadBranchState();
rpsxSetBranchEQ(info, process);
psxRecompileNextInstruction(1);
@ -1389,7 +1385,7 @@ void rpsxBNE_process(int info, int process)
x86Ptr = prevx86;
s_do32 = 1;
psxpc -= 4;
psxRegs.code = *(u32*)PSXM( psxpc - 4 );
psxRegs.code = iopMemRead32( psxpc - 4 );
psxLoadBranchState();
rpsxSetBranchEQ(info, process);
psxRecompileNextInstruction(1);
@ -1442,7 +1438,7 @@ void rpsxBLTZ()
else {
x86Ptr = prevx86;
psxpc -= 4;
psxRegs.code = *(u32*)PSXM( psxpc - 4 );
psxRegs.code = iopMemRead32( psxpc - 4 );
psxLoadBranchState();
u32* pjmp32 = JL32(0);
psxRecompileNextInstruction(1);
@ -1489,7 +1485,7 @@ void rpsxBGEZ()
else {
x86Ptr = prevx86;
psxpc -= 4;
psxRegs.code = *(u32*)PSXM( psxpc - 4 );
psxRegs.code = iopMemRead32( psxpc - 4 );
psxLoadBranchState();
u32* pjmp32 = JGE32(0);
psxRecompileNextInstruction(1);
@ -1545,7 +1541,7 @@ void rpsxBLTZAL()
else {
x86Ptr = prevx86;
psxpc -= 4;
psxRegs.code = *(u32*)PSXM( psxpc - 4 );
psxRegs.code = iopMemRead32( psxpc - 4 );
psxLoadBranchState();
u32* pjmp32 = JL32(0);
MOV32ItoM((uptr)&psxRegs.GPR.r[31], psxpc+4);
@ -1598,7 +1594,7 @@ void rpsxBGEZAL()
else {
x86Ptr = prevx86;
psxpc -= 4;
psxRegs.code = *(u32*)PSXM( psxpc - 4 );
psxRegs.code = iopMemRead32( psxpc - 4 );
psxLoadBranchState();
u32* pjmp32 = JGE32(0);
MOV32ItoM((uptr)&psxRegs.GPR.r[31], psxpc+4);
@ -1649,7 +1645,7 @@ void rpsxBLEZ()
else {
x86Ptr = prevx86;
psxpc -= 4;
psxRegs.code = *(u32*)PSXM( psxpc - 4 );
psxRegs.code = iopMemRead32( psxpc - 4 );
psxLoadBranchState();
u32* pjmp32 = JLE32(0);
psxRecompileNextInstruction(1);
@ -1697,7 +1693,7 @@ void rpsxBGTZ()
else {
x86Ptr = prevx86;
psxpc -= 4;
psxRegs.code = *(u32*)PSXM( psxpc - 4 );
psxRegs.code = iopMemRead32( psxpc - 4 );
psxLoadBranchState();
u32* pjmp32 = JG32(0);
psxRecompileNextInstruction(1);
@ -1819,18 +1815,6 @@ void (*rpsxCP0[32])() = {
rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL
};
// coissued insts
void (*rpsxBSC_co[64] )() = {
rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL,
rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL,
rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL,
rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL,
rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL,
rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL,
rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL,
rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL, rpsxNULL,
};
////////////////////////////////////////////////
// Back-Prob Function Tables - Gathering Info //
////////////////////////////////////////////////

View File

@ -684,8 +684,8 @@ static __naked void Dispatcher()
assert( g_EEDispatchTemp );
#endif
// Modify the prev block's jump address, and jump to the new block:
__asm {
//and eax, 0x0fffffff
shl eax, 4
pop ecx // x86Ptr to mod
mov edx, eax
@ -718,7 +718,6 @@ static __naked void DispatcherClear()
mov eax, s_pDispatchBlock
add esp, 4 // ignore stack
mov eax, dword ptr [eax]
//and eax, 0x0fffffff
shl eax, 4
jmp eax
}
@ -732,7 +731,6 @@ static __naked void DispatcherClear()
pop ecx // old fnptr
//and eax, 0x0fffffff
shl eax, 4
mov byte ptr [ecx], 0xe9 // jmp32
mov edx, eax
@ -764,7 +762,6 @@ static __naked void DispatcherReg()
#endif
__asm {
//and eax, 0x0fffffff
shl eax, 4
jmp eax
}
@ -774,7 +771,8 @@ __forceinline void recExecute()
{
// Optimization note : Compared pushad against manually pushing the regs one-by-one.
// Manually pushing is faster, especially on Core2's and such. :)
do {
do
{
g_EEFreezeRegs = true;
__asm
{