diff --git a/include/paging.h b/include/paging.h index 7126e26b..4fc68214 100644 --- a/include/paging.h +++ b/include/paging.h @@ -48,9 +48,11 @@ class PageDirectory; #define PFLAG_READABLE 0x1 #define PFLAG_WRITEABLE 0x2 #define PFLAG_HASROM 0x4 -#define PFLAG_HASCODE 0x8 //Page contains dynamic code +#define PFLAG_HASCODE32 0x8 //Page contains 32-bit dynamic code #define PFLAG_NOCODE 0x10 //No dynamic code can be generated here #define PFLAG_INIT 0x20 //No dynamic code can be generated here +#define PFLAG_HASCODE16 0x40 //Page contains 16-bit dynamic code +#define PFLAG_HASCODE (PFLAG_HASCODE32|PFLAG_HASCODE16) #define LINK_START ((1024+64)/4) //Start right after the HMA diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 0d354291..17e84221 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -362,7 +362,7 @@ run_block: { Bitu temp_ip=SegPhys(cs)+reg_eip; CodePageHandler * temp_handler=(CodePageHandler *)get_tlb_readhandler(temp_ip); - if (temp_handler->flags & PFLAG_HASCODE) { + if (temp_handler->flags & (cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16)) { block=temp_handler->FindCacheBlock(temp_ip & 4095); if (!block) goto restart_core; cache.block.running->LinkTo(ret==BR_Link2,block); diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 8a42d0d5..08a3526b 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -73,7 +73,7 @@ public: void SetupAt(Bitu _phys_page,PageHandler * _old_pagehandler) { phys_page=_phys_page; old_pagehandler=_old_pagehandler; - flags=old_pagehandler->flags|PFLAG_HASCODE; + flags=old_pagehandler->flags|(cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16); flags&=~PFLAG_WRITEABLE; active_blocks=0; active_count=16; diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 7b0f6411..33186f6a 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -53,19 +53,26 @@ static struct DynDecode { static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) { Bit8u rdval; + const Bitu cflag = cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16; //Ensure page contains memory: if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; PageHandler * handler=get_tlb_readhandler(lin_addr); if (handler->flags & PFLAG_HASCODE) { cph=( CodePageHandler *)handler; - return false; + if (handler->flags & cflag) return false; + cph->ClearRelease(); + cph=0; + handler=get_tlb_readhandler(lin_addr); } if (handler->flags & PFLAG_NOCODE) { if (PAGING_ForcePageInit(lin_addr)) { handler=get_tlb_readhandler(lin_addr); if (handler->flags & PFLAG_HASCODE) { cph=( CodePageHandler *)handler; - return false; + if (handler->flags & cflag) return false; + cph->ClearRelease(); + cph=0; + handler=get_tlb_readhandler(lin_addr); } } if (handler->flags & PFLAG_NOCODE) { diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 2c80bb7e..9e232916 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -159,16 +159,14 @@ CacheBlockDynRec * LinkBlocks(BlockReturn ret) { // the last instruction was a control flow modifying instruction Bitu temp_ip=SegPhys(cs)+reg_eip; CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)get_tlb_readhandler(temp_ip); - if (temp_handler->flags & PFLAG_HASCODE) { + if (temp_handler->flags & (cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16)) { // see if the target is an already translated block block=temp_handler->FindCacheBlock(temp_ip & 4095); - if (!block) return NULL; - - // found it, link the current block to - cache.block.running->LinkTo(ret==BR_Link2,block); - return block; + if (block) { // found it, link the current block to + cache.block.running->LinkTo(ret==BR_Link2,block); + } } - return NULL; + return block; } /* diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index 61ac83b4..9ae81eb3 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -96,7 +96,7 @@ public: old_pagehandler=_old_pagehandler; // adjust flags - flags=old_pagehandler->flags|PFLAG_HASCODE; + flags=old_pagehandler->flags|(cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16); flags&=~PFLAG_WRITEABLE; active_blocks=0; diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index b91c2665..e466e96b 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -130,21 +130,30 @@ static struct DynDecode { static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) { Bit8u rdval; + const Bitu cflag = cpu.code.big ? PFLAG_HASCODE32:PFLAG_HASCODE16; //Ensure page contains memory: if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; PageHandler * handler=get_tlb_readhandler(lin_addr); if (handler->flags & PFLAG_HASCODE) { - // this is a codepage handler, and the one that we're looking for + // this is a codepage handler, make sure it matches current code size cph=(CodePageHandlerDynRec *)handler; - return false; + if (handler->flags & cflag) return false; + // wrong code size/stale dynamic code, drop it + cph->ClearRelease(); + cph=0; + // handler was changed, refresh + handler=get_tlb_readhandler(lin_addr); } if (handler->flags & PFLAG_NOCODE) { if (PAGING_ForcePageInit(lin_addr)) { handler=get_tlb_readhandler(lin_addr); if (handler->flags & PFLAG_HASCODE) { cph=(CodePageHandlerDynRec *)handler; - return false; + if (handler->flags & cflag) return false; + cph->ClearRelease(); + cph=0; + handler=get_tlb_readhandler(lin_addr); } } if (handler->flags & PFLAG_NOCODE) {