Index: pcsx2/x86/BaseblockEx.h =================================================================== --- pcsx2/x86/BaseblockEx.h (revision 681) +++ pcsx2/x86/BaseblockEx.h (working copy) @@ -60,7 +60,10 @@ // This is an asinine macro that bases indexing on sizeof(BASEBLOCK) for no reason. (air) #define GET_BLOCKTYPE(b) ((b)->Type) -#define PC_GETBLOCK_(x, reclut) ((BASEBLOCK*)(reclut[((u32)(x)) >> 16] + (sizeof(BASEBLOCK)/4)*((x) & 0xffff))) +// x * (sizeof(BASEBLOCK) / 4) sacrifices safety for speed compared to +// x / 4 * sizeof(BASEBLOCK) or a higher level approach. +#define PC_GETBLOCK_(x, reclut) ((BASEBLOCK*)(reclut[((u32)(x)) >> 16] + (x)*(sizeof(BASEBLOCK)/4))) +#define RECLUT_SETPAGE(reclut, page, p) do { reclut[page] = (uptr)(p) - ((page) << 14) * sizeof(BASEBLOCK); } while (0) // This is needed because of the retarded GETBLOCK macro above. C_ASSERT( sizeof(BASEBLOCK) == 8 ); Index: pcsx2/x86/iR3000A.cpp =================================================================== --- pcsx2/x86/iR3000A.cpp (revision 681) +++ pcsx2/x86/iR3000A.cpp (working copy) @@ -101,7 +101,7 @@ #define PSX_GETBLOCK(x) PC_GETBLOCK_(x, psxRecLUT) #define PSXREC_CLEARM(mem) { \ - if ((mem) < g_psxMaxRecMem && psxRecLUT[(mem) >> 16]) { \ + if ((mem) < g_psxMaxRecMem && (psxRecLUT[(mem) >> 16] + mem)) { \ BASEBLOCK* p = PSX_GETBLOCK(mem); \ if( *(u32*)p ) psxRecClearMem(p); \ } \ @@ -594,23 +594,23 @@ // 0x80 comes from : (Ps2MemSize::IopRam / 0x10000) * 4 for (int i=0; i<0x80; i++) { - psxRecLUT[i + 0x0000] = (uptr)&recRAM[(i & 0x1f) << 14]; - psxRecLUT[i + 0x8000] = (uptr)&recRAM[(i & 0x1f) << 14]; - psxRecLUT[i + 0xa000] = (uptr)&recRAM[(i & 0x1f) << 14]; + RECLUT_SETPAGE(psxRecLUT, i + 0x0000, &recRAM[(i & 0x1f) << 14]); + RECLUT_SETPAGE(psxRecLUT, i + 0x8000, &recRAM[(i & 0x1f) << 14]); + RECLUT_SETPAGE(psxRecLUT, i + 0xa000, &recRAM[(i & 0x1f) << 14]); } for (int i=0; i<(Ps2MemSize::Rom / 0x10000); i++) { - psxRecLUT[i + 0x1fc0] = (uptr)&recROM[i << 14]; - psxRecLUT[i + 0x9fc0] = (uptr)&recROM[i << 14]; - psxRecLUT[i + 0xbfc0] = (uptr)&recROM[i << 14]; + RECLUT_SETPAGE(psxRecLUT, i + 0x1fc0, &recROM[i << 14]); + RECLUT_SETPAGE(psxRecLUT, i + 0x9fc0, &recROM[i << 14]); + RECLUT_SETPAGE(psxRecLUT, i + 0xbfc0, &recROM[i << 14]); } for (int i=0; i<(Ps2MemSize::Rom1 / 0x10000); i++) { - psxRecLUT[i + 0x1e00] = (uptr)&recROM1[i << 14]; - psxRecLUT[i + 0x9e00] = (uptr)&recROM1[i << 14]; - psxRecLUT[i + 0xbe00] = (uptr)&recROM1[i << 14]; + RECLUT_SETPAGE(psxRecLUT, i + 0x1e00, &recROM1[i << 14]); + RECLUT_SETPAGE(psxRecLUT, i + 0x9e00, &recROM1[i << 14]); + RECLUT_SETPAGE(psxRecLUT, i + 0xbe00, &recROM1[i << 14]); } if( s_pInstCache ) @@ -869,7 +869,7 @@ void rpsxMemConstClear(u32 mem) { // NOTE! This assumes recLUT never changes its mapping - if( !psxRecLUT[mem>>16] ) + if( !(psxRecLUT[mem>>16] + mem) ) return; CMP32ItoM((uptr)PSX_GETBLOCK(mem), 0); Index: pcsx2/x86/ix86-32/iR5900-32.cpp =================================================================== --- pcsx2/x86/ix86-32/iR5900-32.cpp (revision 681) +++ pcsx2/x86/ix86-32/iR5900-32.cpp (working copy) @@ -556,28 +556,30 @@ for ( int i = 0x0000; i < 0x0200; i++ ) { - recLUT[ i + 0x0000 ] = (uptr)&recRAM[ i << 14 ]; - recLUT[ i + 0x2000 ] = (uptr)&recRAM[ i << 14 ]; - recLUT[ i + 0x3000 ] = (uptr)&recRAM[ i << 14 ]; + RECLUT_SETPAGE(recLUT, i + 0x0000, &recRAM[ i << 14 ]); + RECLUT_SETPAGE(recLUT, i + 0x2000, &recRAM[ i << 14 ]); + RECLUT_SETPAGE(recLUT, i + 0x3000, &recRAM[ i << 14 ]); + RECLUT_SETPAGE(recLUT, i + 0x8000, &recRAM[ i << 14 ]); + RECLUT_SETPAGE(recLUT, i + 0xa000, &recRAM[ i << 14 ]); + RECLUT_SETPAGE(recLUT, i + 0xb000, &recRAM[ i << 14 ]); + RECLUT_SETPAGE(recLUT, i + 0xc000, &recRAM[ i << 14 ]); + RECLUT_SETPAGE(recLUT, i + 0xd000, &recRAM[ i << 14 ]); } for ( int i = 0x0000; i < 0x0040; i++ ) { - recLUT[ i + 0x1fc0 ] = (uptr)&recROM[ i << 14 ]; - recLUT[ i + 0x9fc0 ] = (uptr)&recROM[ i << 14 ]; - recLUT[ i + 0xbfc0 ] = (uptr)&recROM[ i << 14 ]; + RECLUT_SETPAGE(recLUT, i + 0x1fc0, &recROM[ i << 14 ]); + RECLUT_SETPAGE(recLUT, i + 0x9fc0, &recROM[ i << 14 ]); + RECLUT_SETPAGE(recLUT, i + 0xbfc0, &recROM[ i << 14 ]); } for ( int i = 0x0000; i < 0x0004; i++ ) { - recLUT[ i + 0x1e00 ] = (uptr)&recROM1[ i << 14 ]; - recLUT[ i + 0x9e00 ] = (uptr)&recROM1[ i << 14 ]; - recLUT[ i + 0xbe00 ] = (uptr)&recROM1[ i << 14 ]; + RECLUT_SETPAGE(recLUT, i + 0x1e00, &recROM1[ i << 14 ]); + RECLUT_SETPAGE(recLUT, i + 0x9e00, &recROM1[ i << 14 ]); + RECLUT_SETPAGE(recLUT, i + 0xbe00, &recROM1[ i << 14 ]); } - memcpy_fast( recLUT + 0x8000, recLUT, 0x2000 * sizeof(uptr) ); - memcpy_fast( recLUT + 0xa000, recLUT, 0x2000 * sizeof(uptr) ); - // drk||Raziel says this is useful but I'm not sure why. Something to do with forward jumps. // Anyways, it causes random crashing for some reasom, possibly because of memory // corrupition elsewhere in the recs. I can't reproduce the problem here though, @@ -728,24 +730,33 @@ } // called when jumping to variable pc address -static __naked void DispatcherReg() +static void __naked DispatcherReg() { - s_pDispatchBlock = PC_GETBLOCK(cpuRegs.pc); + __asm { + mov eax, dword ptr [cpuRegs.pc] + shr eax, 16 + mov ecx, dword ptr [recLUT] + mov edx, dword ptr [ecx+eax*4] + mov eax, dword ptr [cpuRegs.pc] + lea ecx, [edx+eax*2] + mov dword ptr [s_pDispatchBlock], ecx + cmp eax, dword ptr [ecx+4] + je compiled - if( s_pDispatchBlock->startpc != cpuRegs.pc ) - recRecompile(cpuRegs.pc); + push ecx + push eax + call recRecompile + add esp, 4 + pop ecx - __asm - { - mov eax, s_pDispatchBlock - mov eax, dword ptr [eax] + align 16 +compiled: + mov eax, dword ptr [ecx] } - #ifdef _DEBUG - __asm mov g_EEDispatchTemp, eax + __asm mov g_EEDispatchTemp, eax; assert( g_EEDispatchTemp ); #endif - __asm { shl eax, 4 jmp eax @@ -969,7 +980,7 @@ void REC_CLEARM( u32 mem ) { - if ((mem) < maxrecmem && recLUT[(mem) >> 16]) { + if ((mem) < maxrecmem && (recLUT[(mem) >> 16] + mem)) { BASEBLOCK* p = PC_GETBLOCK(mem); if( *(u32*)p ) recClearMem(p); }