1
0
Fork 0

Add writemap. Fixes stonekeep in dynamic core.

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2818
This commit is contained in:
Peter Veenstra 2007-02-22 08:45:14 +00:00
parent c392dcfc90
commit 34ccfaec46
2 changed files with 61 additions and 3 deletions

View file

@ -15,6 +15,9 @@ public:
Bit8u * start; //Where in the cache are we
Bitu size;
CacheBlock * next;
Bit8u * wmapmask;
Bit16u maskstart;
Bit16u masklen;
} cache;
struct {
Bitu index;
@ -222,8 +225,22 @@ public:
//Will crash if a block isn't found, which should never happen.
}
*where=block->hash.next;
for (Bitu i=block->page.start;i<=block->page.end;i++) {
if (write_map[i]) write_map[i]--;
if (GCC_UNLIKELY(block->cache.wmapmask!=NULL)) {
for (Bitu i=block->page.start;i<block->cache.maskstart;i++) {
if (write_map[i]) write_map[i]--;
}
Bitu maskct=0;
for (Bitu i=block->cache.maskstart;i<=block->page.end;i++,maskct++) {
if (write_map[i]) {
if ((maskct>=block->cache.masklen) || (!block->cache.wmapmask[maskct])) write_map[i]--;
}
}
free(block->cache.wmapmask);
block->cache.wmapmask=NULL;
} else {
for (Bitu i=block->page.start;i<=block->page.end;i++) {
if (write_map[i]) write_map[i]--;
}
}
}
void Release(void) {
@ -324,6 +341,10 @@ void CacheBlock::Clear(void) {
page.handler->DelCacheBlock(this);
page.handler=0;
}
if (cache.wmapmask){
free(cache.wmapmask);
cache.wmapmask=NULL;
}
}

View file

@ -140,11 +140,43 @@ static Bit32u decode_fetchd(void) {
return mem_readd(decode.code-4);
}
#define START_WMMEM 64
static void INLINE decode_increase_wmapmask(Bitu size) {
Bitu mapidx;
CacheBlock* activecb=decode.active_block;
if (GCC_UNLIKELY(!activecb->cache.wmapmask)) {
activecb->cache.wmapmask=(Bit8u*)malloc(START_WMMEM);
memset(activecb->cache.wmapmask,0,START_WMMEM);
activecb->cache.maskstart=decode.page.index;
activecb->cache.masklen=START_WMMEM;
mapidx=0;
} else {
mapidx=decode.page.index-activecb->cache.maskstart;
if (GCC_UNLIKELY(mapidx+size>=activecb->cache.masklen)) {
Bitu newmasklen=activecb->cache.masklen*4;
if (newmasklen<mapidx+size) newmasklen=((mapidx+size)&~3)*2;
Bit8u* tempmem=(Bit8u*)malloc(newmasklen);
memset(tempmem,0,newmasklen);
memcpy(tempmem,activecb->cache.wmapmask,activecb->cache.masklen);
free(activecb->cache.wmapmask);
activecb->cache.wmapmask=tempmem;
activecb->cache.masklen=newmasklen;
}
}
switch (size) {
case 1 : activecb->cache.wmapmask[mapidx]+=0x01; break;
case 2 : (*(Bit16u*)&activecb->cache.wmapmask[mapidx])+=0x0101; break;
case 4 : (*(Bit32u*)&activecb->cache.wmapmask[mapidx])+=0x01010101; break;
}
}
static bool decode_fetchb_imm(Bitu & val) {
if (decode.page.index<4096) {
Bitu index=(decode.code>>12);
if (paging.tlb.read[index]) {
val=(Bitu)(paging.tlb.read[index]+decode.code);
decode_increase_wmapmask(1);
decode.code++;
decode.page.index++;
return true;
@ -158,6 +190,7 @@ static bool decode_fetchw_imm(Bitu & val) {
Bitu index=(decode.code>>12);
if (paging.tlb.read[index]) {
val=(Bitu)(paging.tlb.read[index]+decode.code);
decode_increase_wmapmask(2);
decode.code+=2;
decode.page.index+=2;
return true;
@ -171,6 +204,7 @@ static bool decode_fetchd_imm(Bitu & val) {
Bitu index=(decode.code>>12);
if (paging.tlb.read[index]) {
val=(Bitu)(paging.tlb.read[index]+decode.code);
decode_increase_wmapmask(4);
decode.code+=4;
decode.page.index+=4;
return true;
@ -1919,7 +1953,10 @@ restart_prefix:
if (!decode.page.invmap) opcode=decode_fetchb();
else {
if (decode.page.index<4096) {
if (GCC_UNLIKELY(decode.page.invmap[decode.page.index]>=4)) goto illegalopcode;
if (GCC_UNLIKELY(decode.page.invmap[decode.page.index]>=4)) {
decode.page.index++;
goto illegalopcode;
}
opcode=decode_fetchb();
} else {
opcode=decode_fetchb();