mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-10-14 02:17:36 +08:00
Merge pull request #2705 from cimarronm/dos_execute-umb-fix
Fix with how DOS_Execute allocates memory to comply with the memory a…
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,30 @@ 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)
|
||||
{
|
||||
if (memAllocStrategy & 0xc0)
|
||||
{
|
||||
auto 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