diff --git a/pcsx2/SPR.cpp b/pcsx2/SPR.cpp index 8166ba3ba4..5c5291fad0 100644 --- a/pcsx2/SPR.cpp +++ b/pcsx2/SPR.cpp @@ -76,9 +76,6 @@ int _SPR0chain() { memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); - // Clear dependent EE recompiler blocks, if necessary [needed for BTS protection system] - Cpu->Clear( spr0->madr, spr0->qwc << 2 ); - // clear VU mem also! TestClearVUs(spr0->madr, spr0->qwc << 2); // Wtf is going on here? AFAIK, only VIF should affect VU micromem (cottonvibes) @@ -124,7 +121,6 @@ void _SPR0interleave() { // clear VU mem also! TestClearVUs(spr0->madr, spr0->qwc << 2); - Cpu->Clear( spr0->madr, spr0->qwc << 2 ); memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); } spr0->sadr += spr0->qwc * 16; diff --git a/pcsx2/vtlb.cpp b/pcsx2/vtlb.cpp index 058f1dcbed..2a016c61bf 100644 --- a/pcsx2/vtlb.cpp +++ b/pcsx2/vtlb.cpp @@ -90,18 +90,6 @@ callfunction: // Interpreter Implementations of VTLB Memory Operations. // See recVTLB.cpp for the dynarec versions. -// ------------------------------------------------------------------------ -// Helper for the BTS manual protection system. Sets a bit based on the given address, -// marking that piece of PS2 memory as 'dirty.' -// -static void memwritebits(u8* ptr) -{ - u32 offs=ptr-vtlbdata.alloc_base; - offs/=16; - vtlbdata.alloc_bits[offs/8] |= 1 << (offs%8); -} - -// ------------------------------------------------------------------------ // Interpreted VTLB lookup for 8, 16, and 32 bit accesses template __forceinline DataType __fastcall MemOp_r0(u32 addr) @@ -168,7 +156,6 @@ __forceinline void __fastcall MemOp_w0(u32 addr, DataType data) s32 ppf=addr+vmv; if (!(ppf<0)) { - memwritebits((u8*)ppf); *reinterpret_cast(ppf)=data; } else @@ -198,7 +185,6 @@ __forceinline void __fastcall MemOp_w1(u32 addr,const DataType* data) s32 ppf=addr+vmv; if (!(ppf<0)) { - memwritebits((u8*)ppf); *reinterpret_cast(ppf)=*data; if (DataSize==128) *reinterpret_cast(ppf+8)=data[1]; diff --git a/pcsx2/vtlb.h b/pcsx2/vtlb.h index 0eaaf5d90e..b1674fc79d 100644 --- a/pcsx2/vtlb.h +++ b/pcsx2/vtlb.h @@ -81,8 +81,6 @@ namespace vtlb_private struct MapData { - u8 alloc_bits[VTLB_ALLOC_SIZE/16/8]; - u8* alloc_base; //base of the memory array int alloc_current; //current base diff --git a/pcsx2/x86/BaseblockEx.h b/pcsx2/x86/BaseblockEx.h index 6ef0261451..fa38d61891 100644 --- a/pcsx2/x86/BaseblockEx.h +++ b/pcsx2/x86/BaseblockEx.h @@ -70,7 +70,7 @@ public: int LastIndex (u32 startpc) const; BASEBLOCKEX* GetByX86(uptr ip); - inline int Index (u32 startpc) const + __forceinline int Index (u32 startpc) const { int idx = LastIndex(startpc); // fixme: I changed the parenthesis to be unambiguous, but this needs to be checked to see if ((x or y or z) and w) @@ -83,31 +83,43 @@ public: return idx; } - inline BASEBLOCKEX* operator[](int idx) + __forceinline BASEBLOCKEX* operator[](int idx) { if (idx < 0 || idx >= (int)blocks.size()) return 0; return &blocks[idx]; } - inline BASEBLOCKEX* Get(u32 startpc) + __forceinline BASEBLOCKEX* Get(u32 startpc) { return (*this)[Index(startpc)]; } - inline void Remove(int idx) + __forceinline void Remove(int idx) { //u32 startpc = blocks[idx].startpc; std::pair range = links.equal_range(blocks[idx].startpc); for (linkiter_t i = range.first; i != range.second; ++i) *(u32*)i->second = recompiler - (i->second + 4); + + if( IsDevBuild ) + { + // Clear the first instruction to 0xcc (breakpoint), as a way to assert if some + // static jumps get left behind to this block. Note: Do not clear more than the + // first byte, since this code is called during exception handlers and event handlers + // both of which expect to be able to return to the recompiled code. + + BASEBLOCKEX effu( blocks[idx] ); + memset( (void*)effu.fnptr, 0xcc, 1 ); + } + // TODO: remove links from this block? blocks.erase(blocks.begin() + idx); } void Link(u32 pc, uptr jumpptr); - inline void Reset() + __forceinline void Reset() { blocks.clear(); links.clear(); diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index ae3ce24403..d6b67e39c0 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -751,13 +751,6 @@ void recClear(u32 addr, u32 size) return; addr = HWADDR(addr); - addr -= addr % 16; // round down. - size += 3; // round up! - size -= size % 4; - - for (u32 a = addr / 16; a < addr / 16 + size / 4; a++) - vtlb_private::vtlbdata.alloc_bits[a / 8] &= ~(1 << (a & 7)); - int blockidx = recBlocks.LastIndex(addr + size * 4 - 4); if (blockidx == -1) @@ -1274,7 +1267,7 @@ void __fastcall dyna_block_discard(u32 start,u32 sz) void __fastcall dyna_page_reset(u32 start,u32 sz) { - DevCon::WriteLn("dyna_page_reset .. start=%08X count=%d", params start,sz); + DevCon::WriteLn("dyna_page_reset .. start=%08X size=%d", params start,sz*4); Cpu->Clear(start & ~0xfffUL, 0x400); manual_counter[start >> 12]++; mmap_MarkCountedRamPage(PSM(start), start & ~0xfffUL); @@ -1532,10 +1525,10 @@ StartRecomp: iDumpBlock(startpc, recPtr); #endif - u32 sz=(s_nEndBlock-startpc)>>2; + u32 sz = (s_nEndBlock-startpc)>>2; - u32 inpage_ptr=HWADDR(startpc); - u32 inpage_sz=sz*4; + u32 inpage_ptr = HWADDR(startpc); + u32 inpage_sz = sz*4; while(inpage_sz) { @@ -1551,38 +1544,41 @@ StartRecomp: } else { - using namespace vtlb_private; - - MOV32ItoR(ECX, inpage_ptr); - MOV32ItoR(EDX, pgsz / 4); - - u32 index = (psM - vtlbdata.alloc_base + inpage_ptr) / 16 / 32; // 16 bytes per bit, 32 bits per dword. - u32 mask = 0; - - u32 start = inpage_ptr & ~15; - u32 end = inpage_ptr + pgsz; - for (u32 pos = start, bit = (start / 16) % 32; pos < end; pos += 16, bit++) { - if( bit == 32 ) - { - xTEST(ptr32[&vtlbdata.alloc_bits[index]], mask); - xJNZ(dyna_block_discard); - bit = 0; - mask = 0; - index++; - } - mask |= 1 << bit; - } - xTEST(ptr32[&vtlbdata.alloc_bits[index]], mask); - xJNZ(dyna_block_discard); - - if (manual_counter[inpage_ptr >> 12] <= 4) + xMOV( ecx, inpage_ptr ); + xMOV( edx, pgsz / 4 ); + //xMOV( eax, startpc ); // uncomment this to access startpc (as eax) in dyna_block_discard + + u32 lpc = inpage_ptr; + u32 stg = pgsz; + while(stg>0) { + xCMP( ptr32[PSM(lpc)], *(u32*)PSM(lpc) ); + xJNE( dyna_block_discard ); + + stg -= 4; + lpc += 4; + } + + if (startpc != 0x81fc0 && manual_counter[inpage_ptr >> 12] <= 4) { xADD(ptr16[&manual_page[inpage_ptr >> 12]], 1); xJC( dyna_page_reset ); + + // KH2 manual_counter failure -- during the intro vid a block which overlaps + // two pages causes constant recompilation. The block is very large and has two entry + // points, one around 0x01f1de1c and one around 0x01f1dfac (varies on locale). The + // former is the one that's not being cleared correctly [or at least behaves as though + // it's not being cleared correctly]. + + // note: clearcnt is measured per-page, not per-block! + DbgCon::WriteLn( "Manual block @ %08X : size=%3d page/offs=%05X/%03X inpgsz=%d clearcnt=%d", + params startpc, sz, inpage_ptr>>12, inpage_offs, inpage_sz, manual_counter[inpage_ptr >> 12] ); + } + else + { + DbgCon::WriteLn( "Uncounted Manual block @ %08X : size=%3d page/offs=%05X/%03X inpgsz=%d", + params startpc, sz, inpage_ptr>>12, inpage_offs, pgsz, inpage_sz ); } - DbgCon::WriteLn("Manual block @ %08X : %08X %d %d %d %d", params - startpc,inpage_ptr,pgsz,0x1000-inpage_offs,inpage_sz,sz*4); } } inpage_ptr += pgsz; diff --git a/pcsx2/x86/ix86-32/recVTLB.cpp b/pcsx2/x86/ix86-32/recVTLB.cpp index 240ee78ab1..b4ff537b44 100644 --- a/pcsx2/x86/ix86-32/recVTLB.cpp +++ b/pcsx2/x86/ix86-32/recVTLB.cpp @@ -423,14 +423,6 @@ static void _vtlb_DynGen_DirectWrite( u32 bits ) iMOV128_SSE(ptr[ecx],ptr[edx]); break; } - - xSHR( ecx, 4 ); - - uptr alloc_base = (uptr)vtlbdata.alloc_base; - u8* bits_base = vtlbdata.alloc_bits; - bits_base -= (alloc_base>>4)/8; //in bytes - - xBTS( ptr32[bits_base], ecx ); } // ------------------------------------------------------------------------