Coalesce free memory blocks after resizing a block rather than before. Fixes some MicroProse games on the Tandy machine type. Also add error exits in case of a corrupt MCB chain instead of hanging in an infinite loop.
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3882
This commit is contained in:
parent
58a149deec
commit
5fef7164a5
1 changed files with 8 additions and 3 deletions
|
@ -33,7 +33,8 @@ static void DOS_CompressMemory(void) {
|
|||
|
||||
while (mcb.GetType()!=0x5a) {
|
||||
mcb_next.SetPt((Bit16u)(mcb_segment+mcb.GetSize()+1));
|
||||
if ((mcb.GetPSPSeg()==0) && (mcb_next.GetPSPSeg()==0)) {
|
||||
if (GCC_UNLIKELY((mcb_next.GetType()!=0x4d) && (mcb_next.GetType()!=0x5a))) E_Exit("Corrupt MCB chain");
|
||||
if ((mcb.GetPSPSeg()==MCB_FREE) && (mcb_next.GetPSPSeg()==MCB_FREE)) {
|
||||
mcb.SetSize(mcb.GetSize()+mcb_next.GetSize()+1);
|
||||
mcb.SetType(mcb_next.GetType());
|
||||
} else {
|
||||
|
@ -58,6 +59,7 @@ void DOS_FreeProcessMemory(Bit16u pspseg) {
|
|||
mcb.SetType(0x4d);
|
||||
} else break;
|
||||
}
|
||||
if (GCC_UNLIKELY(mcb.GetType()!=0x4d)) E_Exit("Corrupt MCB chain");
|
||||
mcb_segment+=mcb.GetSize()+1;
|
||||
mcb.SetPt(mcb_segment);
|
||||
}
|
||||
|
@ -111,7 +113,7 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) {
|
|||
Bit16u found_seg=0,found_seg_size=0;
|
||||
for (;;) {
|
||||
mcb.SetPt(mcb_segment);
|
||||
if (mcb.GetPSPSeg()==0) {
|
||||
if (mcb.GetPSPSeg()==MCB_FREE) {
|
||||
/* Check for enough free memory in current block */
|
||||
Bit16u block_size=mcb.GetSize();
|
||||
if (block_size<(*blocks)) {
|
||||
|
@ -225,12 +227,12 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) {
|
|||
return false;
|
||||
}
|
||||
|
||||
DOS_CompressMemory();
|
||||
Bit16u total=mcb.GetSize();
|
||||
DOS_MCB mcb_next(segment+total);
|
||||
if (*blocks<=total) {
|
||||
if (GCC_UNLIKELY(*blocks==total)) {
|
||||
/* Nothing to do */
|
||||
DOS_CompressMemory();
|
||||
return true;
|
||||
}
|
||||
/* Shrinking MCB */
|
||||
|
@ -245,6 +247,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) {
|
|||
mcb_new_next.SetSize(total-*blocks-1);
|
||||
mcb_new_next.SetPSPSeg(MCB_FREE);
|
||||
mcb.SetPSPSeg(dos.psp());
|
||||
DOS_CompressMemory();
|
||||
return true;
|
||||
}
|
||||
/* MCB will grow, try to join with following MCB */
|
||||
|
@ -265,6 +268,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) {
|
|||
mcb_next.SetPSPSeg(MCB_FREE);
|
||||
mcb.SetType(0x4d);
|
||||
mcb.SetPSPSeg(dos.psp());
|
||||
DOS_CompressMemory();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -277,6 +281,7 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) {
|
|||
}
|
||||
mcb.SetSize(total);
|
||||
mcb.SetPSPSeg(dos.psp());
|
||||
DOS_CompressMemory();
|
||||
if (*blocks==total) return true; /* block fit exactly */
|
||||
|
||||
*blocks=total; /* return maximum */
|
||||
|
|
Loading…
Add table
Reference in a new issue