mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-10-14 02:17:36 +08:00
Fix with how DOS_Execute allocates memory to comply with the memory allocation strategy for UMB...now, it will allocate and execute in UMB if there is enough memory for the minimum allocation of the executable
This commit is contained in:
@@ -233,6 +233,7 @@ void DOS_Terminate(uint16_t pspseg,bool tsr,uint8_t exitcode);
|
||||
|
||||
/* Memory Handling Routines */
|
||||
void DOS_SetupMemory(void);
|
||||
uint16_t DOS_GetMaximumFreeSize(uint16_t minBlocks);
|
||||
bool DOS_AllocateMemory(uint16_t * segment,uint16_t * blocks);
|
||||
bool DOS_ResizeMemory(uint16_t segment,uint16_t * blocks);
|
||||
bool DOS_FreeMemory(uint16_t segment);
|
||||
@@ -670,6 +671,11 @@ public:
|
||||
uint8_t GetType(void) { return (uint8_t)sGet(sMCB,type);}
|
||||
uint16_t GetSize(void) { return (uint16_t)sGet(sMCB,size);}
|
||||
uint16_t GetPSPSeg(void) { return (uint16_t)sGet(sMCB,psp_segment);}
|
||||
enum class MCBType : uint8_t
|
||||
{
|
||||
ValidBlock = 'M',
|
||||
LastBlock = 'Z'
|
||||
};
|
||||
private:
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack (1)
|
||||
|
@@ -366,6 +366,10 @@ bool DOS_Execute(const char* name, PhysPt block_pt, uint8_t flags) {
|
||||
DOS_AllocateMemory(&pspseg,&maxfree);
|
||||
if (iscom) {
|
||||
minsize=0x1000;maxsize=0xffff;
|
||||
pos=0;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET);
|
||||
uint16_t dataread=0xf800;
|
||||
DOS_ReadFile(fhandle,loadbuf,&dataread);
|
||||
if (dataread<0xf800) minsize=((dataread+0x10)>>4)+0x20;
|
||||
if (machine==MCH_PCJR) {
|
||||
/* try to load file into memory below 96k */
|
||||
pos=0;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET);
|
||||
@@ -386,24 +390,15 @@ bool DOS_Execute(const char* name, PhysPt block_pt, uint8_t flags) {
|
||||
* This allows it to run without the SS:IP out of range error below. */
|
||||
if (maxsize < minsize) maxsize = minsize;
|
||||
}
|
||||
maxfree = DOS_GetMaximumFreeSize(minsize);
|
||||
if (maxfree<minsize) {
|
||||
if (iscom) {
|
||||
/* Reduce minimum of needed memory size to filesize */
|
||||
pos=0;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET);
|
||||
uint16_t dataread=0xf800;
|
||||
DOS_ReadFile(fhandle,loadbuf,&dataread);
|
||||
if (dataread<0xf800) minsize=((dataread+0x10)>>4)+0x20;
|
||||
}
|
||||
if (maxfree<minsize) {
|
||||
DOS_CloseFile(fhandle);
|
||||
delete[] loadbuf;
|
||||
DOS_SetError(DOSERR_INSUFFICIENT_MEMORY);
|
||||
DOS_FreeMemory(envseg);
|
||||
return false;
|
||||
}
|
||||
DOS_CloseFile(fhandle);
|
||||
delete[] loadbuf;
|
||||
DOS_SetError(DOSERR_INSUFFICIENT_MEMORY);
|
||||
DOS_FreeMemory(envseg);
|
||||
return false;
|
||||
}
|
||||
if (maxfree<maxsize) memsize=maxfree;
|
||||
else memsize=maxsize;
|
||||
memsize = (maxfree<maxsize) ? maxfree : maxsize;
|
||||
if (!DOS_AllocateMemory(&pspseg,&memsize)) E_Exit("DOS:Exec error in memory");
|
||||
if (iscom && (machine==MCH_PCJR) && (pspseg<0x2000)) {
|
||||
maxsize=0xffff;
|
||||
|
@@ -16,8 +16,9 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "dosbox.h"
|
||||
#include "logging.h"
|
||||
#include "mem.h"
|
||||
#include "bios.h"
|
||||
@@ -153,6 +154,31 @@ void DOS_zeromem(uint16_t seg,uint16_t para) {
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t GetMaximumMCBFreeSize(uint16_t mcb_segment)
|
||||
{
|
||||
uint16_t largestSize = 0;
|
||||
DOS_MCB mcb(mcb_segment);
|
||||
for (bool endOfChain = false; !endOfChain; mcb.SetPt(mcb_segment))
|
||||
{
|
||||
auto size = mcb.GetSize();
|
||||
if (mcb.GetPSPSeg()==MCB_FREE) largestSize = std::max(largestSize, size);
|
||||
endOfChain = DOS_MCB::MCBType(mcb.GetType())==DOS_MCB::MCBType::LastBlock;
|
||||
mcb_segment += size+1;
|
||||
}
|
||||
return largestSize;
|
||||
}
|
||||
|
||||
uint16_t DOS_GetMaximumFreeSize(uint16_t minBlocks)
|
||||
{
|
||||
uint16_t umbFreeSize = 0;
|
||||
if (memAllocStrategy & 0xc0)
|
||||
{
|
||||
umbFreeSize = GetMaximumMCBFreeSize(dos_infoblock.GetStartOfUMBChain());
|
||||
if (memAllocStrategy & 0x40 || umbFreeSize >= minBlocks) return umbFreeSize;
|
||||
}
|
||||
return GetMaximumMCBFreeSize(dos.firstMCB);
|
||||
}
|
||||
|
||||
bool DOS_AllocateMemory(uint16_t * segment,uint16_t * blocks) {
|
||||
DOS_CompressMemory();
|
||||
uint16_t bigsize=0;
|
||||
|
Reference in New Issue
Block a user