adding support for upper memory
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2262
This commit is contained in:
parent
bc49a1ce91
commit
caff0f7a8b
9 changed files with 304 additions and 48 deletions
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: callback.h,v 1.13 2005-07-30 09:49:28 qbix79 Exp $ */
|
||||
/* $Id: callback.h,v 1.14 2005-08-08 13:33:43 c2woody Exp $ */
|
||||
|
||||
#ifndef DOSBOX_CALLBACK_H
|
||||
#define DOSBOX_CALLBACK_H
|
||||
|
@ -30,7 +30,7 @@ extern CallBack_Handler CallBack_Handlers[];
|
|||
|
||||
enum { CB_RETF,CB_IRET,CB_IRET_STI };
|
||||
|
||||
#define CB_MAX 1024
|
||||
#define CB_MAX 144
|
||||
#define CB_SEG 0xC800
|
||||
#define CB_BASE (CB_SEG << 4)
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: dos_inc.h,v 1.54 2005-08-01 09:30:44 c2woody Exp $ */
|
||||
/* $Id: dos_inc.h,v 1.55 2005-08-08 13:33:43 c2woody Exp $ */
|
||||
|
||||
#ifndef DOSBOX_DOS_INC_H
|
||||
#define DOSBOX_DOS_INC_H
|
||||
|
@ -76,13 +76,13 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3};
|
|||
#define DOS_DRIVES 26
|
||||
#define DOS_DEVICES 10
|
||||
|
||||
#define DOS_INFOBLOCK_SEG 0x50
|
||||
#define DOS_SDA_SEG 0x5a
|
||||
|
||||
#define DOS_INFOBLOCK_SEG 0x80
|
||||
#define DOS_CDS_SEG 0x90
|
||||
#define DOS_CONSTRING_SEG 0xa0
|
||||
#define DOS_CONDRV_SEG 0xa4
|
||||
#define DOS_SDA_SEG 0xb0
|
||||
#define DOS_SDA_OFS 0
|
||||
#define DOS_CONSTRING_SEG 0x5d
|
||||
#define DOS_CONDRV_SEG 0x60
|
||||
#define DOS_SFT_SEG 0x62
|
||||
#define DOS_CDS_SEG 0x64
|
||||
#define DOS_MEM_START 0x102 //First Segment that DOS can use
|
||||
|
||||
/* internal Dos Tables */
|
||||
|
@ -158,6 +158,8 @@ void DOS_FreeProcessMemory(Bit16u pspseg);
|
|||
Bit16u DOS_GetMemory(Bit16u pages);
|
||||
void DOS_SetMemAllocStrategy(Bit16u strat);
|
||||
Bit16u DOS_GetMemAllocStrategy(void);
|
||||
void DOS_BuildUMBChain(const char* use_umbs,bool ems_active);
|
||||
bool DOS_LinkUMBsToMemChain(Bit16u linkstate);
|
||||
|
||||
/* FCB stuff */
|
||||
bool DOS_FCBOpen(Bit16u seg,Bit16u offset);
|
||||
|
@ -354,18 +356,24 @@ public:
|
|||
DOS_InfoBlock () {};
|
||||
void SetLocation(Bit16u seg);
|
||||
void SetFirstMCB(Bit16u _first_mcb);
|
||||
void SetfirstFileTable(RealPt _first_table);
|
||||
void SetBuffers(Bit16u x,Bit16u y);
|
||||
void SetCurDirStruct(Bit32u _curdirstruct);
|
||||
void SetFCBTable(Bit32u _fcbtable);
|
||||
void SetDeviceChainStart(Bit32u _devchain);
|
||||
void SetDiskBufferHeadPt(Bit32u _dbheadpt);
|
||||
RealPt GetPointer (void);
|
||||
void SetStartOfUMBChain(Bit16u _umbstartseg);
|
||||
void SetUMBChainState(Bit8u _umbchaining);
|
||||
Bit16u GetStartOfUMBChain(void);
|
||||
Bit8u GetUMBChainState(void);
|
||||
RealPt GetPointer(void);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
struct sDIB {
|
||||
Bit8u unknown1[4];
|
||||
Bit16u magicWord; // -0x22 needs to be 1
|
||||
Bit8u unknown2[8];
|
||||
Bit16u regCXfrom5e; // -0x18 CX from last int21/ah=5e
|
||||
Bit16u countLRUcache; // -0x16 LRU counter for FCB caching
|
||||
Bit16u countLRUopens; // -0x14 LRU counter for FCB openings
|
||||
|
@ -406,7 +414,7 @@ public:
|
|||
Bit16u lookaheadBufNumber; // 0x51 number of lookahead buffers
|
||||
Bit8u bufferLocation; // 0x53 workspace buffer location
|
||||
Bit32u workspaceBuffer; // 0x54 pointer to workspace buffer
|
||||
Bit8u unknown2[11]; // 0x58
|
||||
Bit8u unknown3[11]; // 0x58
|
||||
Bit8u chainingUMB; // 0x63 bit0: UMB chain linked to MCB chain
|
||||
Bit16u minMemForExec; // 0x64 minimum paragraphs needed for current program
|
||||
Bit16u startOfUMBChain; // 0x66 segment of first UMB-MCB
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: dos.cpp,v 1.84 2005-04-29 13:32:31 qbix79 Exp $ */
|
||||
/* $Id: dos.cpp,v 1.85 2005-08-08 13:33:44 c2woody Exp $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -716,12 +716,15 @@ static Bitu DOS_21Handler(void) {
|
|||
DOS_SetMemAllocStrategy(reg_bx);
|
||||
break;
|
||||
case 2: /* Get UMB Link Status */
|
||||
reg_ax=1; // no UMB support
|
||||
CALLBACK_SCF(true);
|
||||
reg_al=dos_infoblock.GetUMBChainState()&1;
|
||||
CALLBACK_SCF(false);
|
||||
break;
|
||||
case 3: /* Set UMB Link Status */
|
||||
reg_ax=1; // failure, no support
|
||||
CALLBACK_SCF(true);
|
||||
if (DOS_LinkUMBsToMemChain(reg_bx)) CALLBACK_SCF(false);
|
||||
else {
|
||||
reg_ax=1;
|
||||
CALLBACK_SCF(true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_DOSMISC,LOG_ERROR)("DOS:58:Not Supported Set//Get memory allocation call %X",reg_al);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: dos_classes.cpp,v 1.44 2005-08-01 09:30:45 c2woody Exp $ */
|
||||
/* $Id: dos_classes.cpp,v 1.45 2005-08-08 13:33:45 c2woody Exp $ */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -63,6 +63,7 @@ void DOS_InfoBlock::SetLocation(Bit16u segment) {
|
|||
pt=PhysMake(seg,0);
|
||||
/* Clear the initial Block */
|
||||
for(Bitu i=0;i<sizeof(sDIB);i++) mem_writeb(pt+i,0xff);
|
||||
for(Bitu i=0;i<14;i++) mem_writeb(pt+i,0);
|
||||
|
||||
sSave(sDIB,regCXfrom5e,(Bit16u)0);
|
||||
sSave(sDIB,countLRUcache,(Bit16u)0);
|
||||
|
@ -73,7 +74,7 @@ void DOS_InfoBlock::SetLocation(Bit16u segment) {
|
|||
sSave(sDIB,joindedDrives,(Bit8u)0);
|
||||
sSave(sDIB,lastdrive,(Bit8u)0x01);//increase this if you add drives to cds-chain
|
||||
|
||||
sSave(sDIB,diskInfoBuffer,RealMake(segment,0x5f));
|
||||
sSave(sDIB,diskInfoBuffer,RealMake(segment,offsetof(sDIB,diskBufferHeadPt)));
|
||||
sSave(sDIB,setverPtr,(Bit32u)0);
|
||||
|
||||
sSave(sDIB,a20FixOfs,(Bit16u)0);
|
||||
|
@ -83,9 +84,12 @@ void DOS_InfoBlock::SetLocation(Bit16u segment) {
|
|||
sSave(sDIB,bootDrive,(Bit8u)0);
|
||||
sSave(sDIB,useDwordMov,(Bit8u)1);
|
||||
sSave(sDIB,extendedSize,(Bit16u)0x4000); // >16mb
|
||||
sSave(sDIB,magicWord,(Bit16u)0x0001); // dos5+
|
||||
|
||||
sSave(sDIB,sharingCount,(Bit16u)0);
|
||||
sSave(sDIB,sharingDelay,(Bit16u)0);
|
||||
sSave(sDIB,ptrCONinput,(Bit16u)0); // no unread input available
|
||||
sSave(sDIB,maxSectorLength,(Bit16u)0x200);
|
||||
|
||||
sSave(sDIB,dirtyDiskBuffers,(Bit16u)0);
|
||||
sSave(sDIB,lookaheadBufPt,(Bit32u)0);
|
||||
|
@ -109,16 +113,20 @@ void DOS_InfoBlock::SetLocation(Bit16u segment) {
|
|||
sSave(sDIB,nulString[5],(Bit8u)0x20);
|
||||
sSave(sDIB,nulString[6],(Bit8u)0x20);
|
||||
sSave(sDIB,nulString[7],(Bit8u)0x20);
|
||||
|
||||
/* Create a fake SFT, so programs think there are 100 file handles */
|
||||
Bit16u sftOffset=offsetof(sDIB,firstFileTable)+0xa2;
|
||||
sSave(sDIB,firstFileTable,RealMake(segment,sftOffset));
|
||||
real_writed(segment,sftOffset+0x00,RealMake(segment+0x11,0)); //Next File Table
|
||||
real_writew(segment,sftOffset+0x04,100); //File Table supports 100 files
|
||||
real_writed(segment+0x11,0x00,0xffffffff); //Last File Table
|
||||
real_writew(segment+0x11,0x04,100); //File Table supports 100 files
|
||||
}
|
||||
|
||||
void DOS_InfoBlock::SetFirstMCB(Bit16u _firstmcb) {
|
||||
sSave(sDIB,firstMCB,_firstmcb); //c2woody
|
||||
}
|
||||
|
||||
void DOS_InfoBlock::SetfirstFileTable(RealPt _first_table) {
|
||||
sSave(sDIB,firstFileTable,_first_table);
|
||||
}
|
||||
|
||||
void DOS_InfoBlock::SetBuffers(Bit16u x,Bit16u y) {
|
||||
sSave(sDIB,buffers_x,x);
|
||||
sSave(sDIB,buffers_y,y);
|
||||
|
@ -140,6 +148,22 @@ void DOS_InfoBlock::SetDiskBufferHeadPt(Bit32u _dbheadpt) {
|
|||
sSave(sDIB,diskBufferHeadPt,_dbheadpt);
|
||||
}
|
||||
|
||||
Bit16u DOS_InfoBlock::GetStartOfUMBChain(void) {
|
||||
return sGet(sDIB,startOfUMBChain);
|
||||
}
|
||||
|
||||
void DOS_InfoBlock::SetStartOfUMBChain(Bit16u _umbstartseg) {
|
||||
sSave(sDIB,startOfUMBChain,_umbstartseg);
|
||||
}
|
||||
|
||||
Bit8u DOS_InfoBlock::GetUMBChainState(void) {
|
||||
return sGet(sDIB,chainingUMB);
|
||||
}
|
||||
|
||||
void DOS_InfoBlock::SetUMBChainState(Bit8u _umbchaining) {
|
||||
sSave(sDIB,chainingUMB,_umbchaining);
|
||||
}
|
||||
|
||||
RealPt DOS_InfoBlock::GetPointer(void) {
|
||||
return RealMake(seg,offsetof(sDIB,firstDPB));
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "mem.h"
|
||||
#include "dos_inc.h"
|
||||
|
||||
#define UMB_START_SEG 0x9fff
|
||||
|
||||
static Bit16u memAllocStrategy = 0x00;
|
||||
|
||||
static void DOS_CompressMemory(void) {
|
||||
|
@ -50,6 +52,20 @@ void DOS_FreeProcessMemory(Bit16u pspseg) {
|
|||
mcb_segment+=mcb.GetSize()+1;
|
||||
mcb.SetPt(mcb_segment);
|
||||
}
|
||||
|
||||
Bit16u umb_start=dos_infoblock.GetStartOfUMBChain();
|
||||
if (umb_start==UMB_START_SEG) {
|
||||
DOS_MCB umb_mcb(umb_start);
|
||||
while (true) {
|
||||
if (umb_mcb.GetPSPSeg()==pspseg) {
|
||||
umb_mcb.SetPSPSeg(MCB_FREE);
|
||||
}
|
||||
if (umb_mcb.GetType()!=0x4d) break;
|
||||
umb_start+=umb_mcb.GetSize()+1;
|
||||
umb_mcb.SetPt(umb_start);
|
||||
}
|
||||
} else if (umb_start!=0xffff) LOG(LOG_DOSMISC,LOG_ERROR)("Corrupt UMB chain: %x",umb_start);
|
||||
|
||||
DOS_CompressMemory();
|
||||
};
|
||||
|
||||
|
@ -65,7 +81,15 @@ void DOS_SetMemAllocStrategy(Bit16u strat)
|
|||
|
||||
bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) {
|
||||
DOS_CompressMemory();
|
||||
Bit16u bigsize=0;Bit16u mcb_segment=dos.firstMCB;
|
||||
Bit16u bigsize=0;
|
||||
Bit16u mem_strat=memAllocStrategy;
|
||||
Bit16u mcb_segment=dos.firstMCB;
|
||||
|
||||
Bit16u umb_start=dos_infoblock.GetStartOfUMBChain();
|
||||
if (umb_start==UMB_START_SEG) {
|
||||
if (mem_strat&0xc0) mcb_segment=umb_start;
|
||||
} else if (umb_start!=0xffff) LOG(LOG_DOSMISC,LOG_ERROR)("Corrupt UMB chain: %x",umb_start);
|
||||
|
||||
DOS_MCB mcb(0);
|
||||
DOS_MCB mcb_next(0);
|
||||
DOS_MCB psp_mcb(dos.psp()-1);
|
||||
|
@ -88,7 +112,7 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) {
|
|||
} else {
|
||||
// TODO: Strategy "1": Best matching block
|
||||
/* If so allocate it */
|
||||
if ((memAllocStrategy & 0x03)==0) {
|
||||
if ((mem_strat & 0x03)==0) {
|
||||
mcb_next.SetPt((Bit16u)(mcb_segment+*blocks+1));
|
||||
mcb_next.SetPSPSeg(MCB_FREE);
|
||||
mcb_next.SetType(mcb.GetType());
|
||||
|
@ -119,11 +143,15 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) {
|
|||
}
|
||||
/* Onward to the next MCB if there is one */
|
||||
if (mcb.GetType()==0x5a) {
|
||||
*blocks=bigsize;
|
||||
DOS_SetError(DOSERR_INSUFFICIENT_MEMORY);
|
||||
return false;
|
||||
}
|
||||
mcb_segment+=mcb.GetSize()+1;
|
||||
if ((mem_strat&0x80) && (umb_start==UMB_START_SEG)) {
|
||||
mcb_segment=dos.firstMCB;
|
||||
mem_strat&=(~0xc0);
|
||||
} else {
|
||||
*blocks=bigsize;
|
||||
DOS_SetError(DOSERR_INSUFFICIENT_MEMORY);
|
||||
return false;
|
||||
}
|
||||
} else mcb_segment+=mcb.GetSize()+1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -210,6 +238,109 @@ bool DOS_FreeMemory(Bit16u segment) {
|
|||
}
|
||||
|
||||
|
||||
void DOS_BuildUMBChain(const char* use_umbs,bool ems_active) {
|
||||
if (strcmp(use_umbs,"false")!=0) {
|
||||
Bit16u first_umb_seg=0xca00;
|
||||
Bit16u first_umb_size=0x600;
|
||||
|
||||
if (strcmp(use_umbs,"max")==0) {
|
||||
first_umb_seg-=0x100;
|
||||
first_umb_size+=0x100;
|
||||
}
|
||||
|
||||
dos_infoblock.SetStartOfUMBChain(UMB_START_SEG);
|
||||
dos_infoblock.SetUMBChainState(0); // UMBs not linked yet
|
||||
|
||||
DOS_MCB umb_mcb(first_umb_seg);
|
||||
umb_mcb.SetPSPSeg(0); // currently free
|
||||
umb_mcb.SetSize(first_umb_size-1);
|
||||
umb_mcb.SetType(0x5a);
|
||||
|
||||
/* Scan MCB-chain for last block */
|
||||
Bit16u mcb_segment=dos.firstMCB;
|
||||
DOS_MCB mcb(mcb_segment);
|
||||
while (mcb.GetType()!=0x5a) {
|
||||
mcb_segment+=mcb.GetSize()+1;
|
||||
mcb.SetPt(mcb_segment);
|
||||
}
|
||||
|
||||
/* A system MCB has to cover the space between the
|
||||
regular MCB-chain and the UMBs */
|
||||
Bit16u cover_mcb=(Bit16u)(mcb_segment+mcb.GetSize()+1);
|
||||
mcb.SetPt(cover_mcb);
|
||||
mcb.SetType(0x4d);
|
||||
mcb.SetPSPSeg(0x0008);
|
||||
mcb.SetSize(first_umb_seg-cover_mcb-1);
|
||||
mcb.SetFileName("SC ");
|
||||
|
||||
if (!ems_active && (strcmp(use_umbs,"max")==0)) {
|
||||
Bit16u ems_umb_seg=0xe000;
|
||||
Bit16u ems_umb_size=0x1000;
|
||||
|
||||
/* Continue UMB-chain */
|
||||
umb_mcb.SetSize(first_umb_size-2);
|
||||
umb_mcb.SetType(0x4d);
|
||||
|
||||
DOS_MCB umb2_mcb(ems_umb_seg);
|
||||
umb2_mcb.SetPSPSeg(0); // currently free
|
||||
umb2_mcb.SetSize(ems_umb_size-1);
|
||||
umb2_mcb.SetType(0x5a);
|
||||
|
||||
/* A system MCB has to take out the space between the previous and this UMB */
|
||||
cover_mcb=(Bit16u)(first_umb_seg+umb_mcb.GetSize()+1);
|
||||
mcb.SetPt(cover_mcb);
|
||||
mcb.SetType(0x4d);
|
||||
mcb.SetPSPSeg(0x0008);
|
||||
mcb.SetSize(ems_umb_seg-cover_mcb-1);
|
||||
mcb.SetFileName("SC ");
|
||||
}
|
||||
} else {
|
||||
dos_infoblock.SetStartOfUMBChain(0xffff);
|
||||
dos_infoblock.SetUMBChainState(0);
|
||||
}
|
||||
}
|
||||
|
||||
bool DOS_LinkUMBsToMemChain(Bit16u linkstate) {
|
||||
/* Get start of UMB-chain */
|
||||
Bit16u umb_start=dos_infoblock.GetStartOfUMBChain();
|
||||
if (umb_start!=UMB_START_SEG) {
|
||||
if (umb_start!=0xffff) LOG(LOG_DOSMISC,LOG_ERROR)("Corrupt UMB chain: %x",umb_start);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((linkstate&1)==(dos_infoblock.GetUMBChainState()&1)) return true;
|
||||
|
||||
/* Scan MCB-chain for last block before UMB-chain */
|
||||
Bit16u mcb_segment=dos.firstMCB;
|
||||
Bit16u prev_mcb_segment;
|
||||
DOS_MCB mcb(mcb_segment);
|
||||
while ((mcb_segment!=umb_start) && (mcb.GetType()!=0x5a)) {
|
||||
prev_mcb_segment=mcb_segment;
|
||||
mcb_segment+=mcb.GetSize()+1;
|
||||
mcb.SetPt(mcb_segment);
|
||||
}
|
||||
DOS_MCB prev_mcb(prev_mcb_segment);
|
||||
|
||||
switch (linkstate) {
|
||||
case 0x0000: // unlink
|
||||
if ((prev_mcb.GetType()==0x4d) && (mcb_segment==umb_start)) {
|
||||
prev_mcb.SetType(0x5a);
|
||||
}
|
||||
dos_infoblock.SetUMBChainState(0);
|
||||
break;
|
||||
case 0x0001: // link
|
||||
if (mcb.GetType()==0x5a) {
|
||||
mcb.SetType(0x4d);
|
||||
dos_infoblock.SetUMBChainState(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_MSG("Invalid link state %x when reconfiguring MCB chain",linkstate);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void DOS_SetupMemory(void) {
|
||||
|
@ -218,6 +349,7 @@ void DOS_SetupMemory(void) {
|
|||
mcb_devicedummy.SetPSPSeg(0x0008); // Devices
|
||||
mcb_devicedummy.SetSize(1);
|
||||
mcb_devicedummy.SetType(0x4d); // More blocks will follow
|
||||
// mcb_devicedummy.SetFileName("SD ");
|
||||
|
||||
// BioMenace (segment of int2<0x8000)
|
||||
mem_writeb((DOS_MEM_START+1)<<4,0xcf);// iret
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: dos_programs.cpp,v 1.38 2005-07-20 11:35:53 qbix79 Exp $ */
|
||||
/* $Id: dos_programs.cpp,v 1.39 2005-08-08 13:33:45 c2woody Exp $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -207,9 +207,40 @@ public:
|
|||
void Run(void) {
|
||||
/* Show conventional Memory */
|
||||
WriteOut("\n");
|
||||
|
||||
Bit16u umb_start=dos_infoblock.GetStartOfUMBChain();
|
||||
Bit8u umb_flag=dos_infoblock.GetUMBChainState();
|
||||
Bit8u old_memstrat=DOS_GetMemAllocStrategy()&0xff;
|
||||
if (umb_start!=0xffff) {
|
||||
if ((umb_flag&1)==1) DOS_LinkUMBsToMemChain(0);
|
||||
DOS_SetMemAllocStrategy(0);
|
||||
}
|
||||
|
||||
Bit16u seg,blocks;blocks=0xffff;
|
||||
DOS_AllocateMemory(&seg,&blocks);
|
||||
WriteOut(MSG_Get("PROGRAM_MEM_CONVEN"),blocks*16/1024);
|
||||
|
||||
if (umb_start!=0xffff) {
|
||||
DOS_LinkUMBsToMemChain(1);
|
||||
DOS_SetMemAllocStrategy(0x40); // search in UMBs only
|
||||
|
||||
Bit16u largest_block=0,total_blocks=0,block_count=0;
|
||||
for (;; block_count++) {
|
||||
blocks=0xffff;
|
||||
DOS_AllocateMemory(&seg,&blocks);
|
||||
if (blocks==0) break;
|
||||
total_blocks+=blocks;
|
||||
if (blocks>largest_block) largest_block=blocks;
|
||||
DOS_AllocateMemory(&seg,&blocks);
|
||||
}
|
||||
|
||||
Bit8u current_umb_flag=dos_infoblock.GetUMBChainState();
|
||||
if ((current_umb_flag&1)!=(umb_flag&1)) DOS_LinkUMBsToMemChain(umb_flag);
|
||||
DOS_SetMemAllocStrategy(old_memstrat); // restore strategy
|
||||
|
||||
if (block_count>0) WriteOut(MSG_Get("PROGRAM_MEM_UPPER"),total_blocks*16/1024,block_count,largest_block*16/1024);
|
||||
}
|
||||
|
||||
/* Test for and show free XMS */
|
||||
reg_ax=0x4300;CALLBACK_RunRealInt(0x2f);
|
||||
if (reg_al==0x80) {
|
||||
|
@ -695,6 +726,7 @@ void DOS_SetupPrograms(void) {
|
|||
MSG_Add("PROGRAM_MEM_CONVEN","%10d Kb free conventional memory\n");
|
||||
MSG_Add("PROGRAM_MEM_EXTEND","%10d Kb free extended memory\n");
|
||||
MSG_Add("PROGRAM_MEM_EXPAND","%10d Kb free expanded memory\n");
|
||||
MSG_Add("PROGRAM_MEM_UPPER","%10d Kb free upper memory in %d blocks (largest UMB %d Kb)\n");
|
||||
|
||||
MSG_Add("PROGRAM_LOADFIX_ALLOC","%d kb allocated.\n");
|
||||
MSG_Add("PROGRAM_LOADFIX_DEALLOC","%d kb freed.\n");
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: dos_tables.cpp,v 1.19 2005-08-01 09:30:45 c2woody Exp $ */
|
||||
/* $Id: dos_tables.cpp,v 1.20 2005-08-08 13:33:46 c2woody Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "mem.h"
|
||||
|
@ -100,15 +100,6 @@ void DOS_SetupTables(void) {
|
|||
real_writed(seg,0x0e,0x20202020); // driver name
|
||||
dos_infoblock.SetDeviceChainStart(RealMake(seg,0));
|
||||
|
||||
/* Create a fake SFT, so programs think there are 100 file handles */
|
||||
seg=DOS_SFT_SEG;
|
||||
seg2=DOS_SFT_SEG+1;
|
||||
real_writed(seg,0,seg2<<16); //Next File Table
|
||||
real_writew(seg,4,100); //File Table supports 100 files
|
||||
real_writed(seg2,0,0xffffffff); //Last File Table
|
||||
real_writew(seg2,4,100); //File Table supports 100 files
|
||||
dos_infoblock.SetfirstFileTable(RealMake(seg,0));
|
||||
|
||||
/* Create a fake Current Directory Structure */
|
||||
seg=DOS_CDS_SEG;
|
||||
real_writed(seg,0x00,0x005c3a43);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: dosbox.cpp,v 1.86 2005-07-30 14:41:31 qbix79 Exp $ */
|
||||
/* $Id: dosbox.cpp,v 1.87 2005-08-08 13:33:46 c2woody Exp $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -379,9 +379,11 @@ void DOSBOX_Init(void) {
|
|||
secprop->Add_bool("xms",true);
|
||||
secprop->AddInitFunction(&EMS_Init,true);//done
|
||||
secprop->Add_bool("ems",true);
|
||||
secprop->Add_string("umb","true");
|
||||
MSG_Add("DOS_CONFIGFILE_HELP",
|
||||
"xms -- Enable XMS support.\n"
|
||||
"ems -- Enable EMS support.\n"
|
||||
"umb -- Enable UMB support (false,true,max).\n"
|
||||
);
|
||||
// Mscdex
|
||||
secprop->AddInitFunction(&MSCDEX_Init);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: xms.cpp,v 1.35 2005-03-25 11:59:24 qbix79 Exp $ */
|
||||
/* $Id: xms.cpp,v 1.36 2005-08-08 13:33:46 c2woody Exp $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -55,6 +55,7 @@
|
|||
#define XMS_QUERY_ANY_FREE_MEMORY 0x88
|
||||
#define XMS_ALLOCATE_ANY_MEMORY 0x89
|
||||
|
||||
#define XMS_FUNCTION_NOT_IMPLEMENTED 0x80
|
||||
#define HIGH_MEMORY_NOT_EXIST 0x90
|
||||
#define HIGH_MEMORY_IN_USE 0x91
|
||||
#define HIGH_MEMORY_NOT_ALLOCATED 0x93
|
||||
|
@ -63,6 +64,8 @@
|
|||
#define XMS_INVALID_HANDLE 0xa2
|
||||
#define XMS_BLOCK_NOT_LOCKED 0xaa
|
||||
#define XMS_BLOCK_LOCKED 0xab
|
||||
#define UMB_ONLY_SMALLER_BLOCK 0xb0
|
||||
#define UMB_NO_BLOCKS_AVAILABLE 0xb1
|
||||
|
||||
struct XMS_Block {
|
||||
Bitu size;
|
||||
|
@ -102,6 +105,7 @@ Bitu XMS_GetEnabledA20(void)
|
|||
};
|
||||
|
||||
static RealPt xms_callback;
|
||||
static bool umb_available;
|
||||
|
||||
static XMS_Block xms_handles[XMS_HANDLES];
|
||||
|
||||
|
@ -322,13 +326,57 @@ Bitu XMS_Handler(void) {
|
|||
reg_bl = XMS_ResizeMemory(reg_dx, reg_bx);
|
||||
reg_ax = (reg_bl==0);
|
||||
break;
|
||||
case XMS_ALLOCATE_UMB: /* 10 */
|
||||
reg_ax=0;
|
||||
reg_bl=0xb1; //No UMB Available
|
||||
reg_dx=0;
|
||||
case XMS_ALLOCATE_UMB: { /* 10 */
|
||||
if (!umb_available) {
|
||||
reg_ax=0;
|
||||
reg_bl=XMS_FUNCTION_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
Bit16u umb_start=dos_infoblock.GetStartOfUMBChain();
|
||||
if (umb_start==0xffff) {
|
||||
reg_ax=0;
|
||||
reg_bl=UMB_NO_BLOCKS_AVAILABLE;
|
||||
reg_dx=0; // no upper memory available
|
||||
break;
|
||||
}
|
||||
/* Save status and linkage of upper UMB chain and link upper
|
||||
memory to the regular MCB chain */
|
||||
Bit8u umb_flag=dos_infoblock.GetUMBChainState();
|
||||
if ((umb_flag&1)==0) DOS_LinkUMBsToMemChain(1);
|
||||
Bit8u old_memstrat=DOS_GetMemAllocStrategy()&0xff;
|
||||
DOS_SetMemAllocStrategy(0x40); // search in UMBs only
|
||||
|
||||
Bit16u size=reg_dx;Bit16u seg;
|
||||
if (DOS_AllocateMemory(&seg,&size)) {
|
||||
reg_ax=1;
|
||||
reg_bx=seg;
|
||||
} else {
|
||||
reg_ax=0;
|
||||
if (size==0) reg_bl=UMB_NO_BLOCKS_AVAILABLE;
|
||||
else reg_bl=UMB_ONLY_SMALLER_BLOCK;
|
||||
reg_dx=size; // size of largest available UMB
|
||||
}
|
||||
|
||||
/* Restore status and linkage of upper UMB chain */
|
||||
Bit8u current_umb_flag=dos_infoblock.GetUMBChainState();
|
||||
if ((current_umb_flag&1)!=(umb_flag&1)) DOS_LinkUMBsToMemChain(umb_flag);
|
||||
DOS_SetMemAllocStrategy(old_memstrat);
|
||||
}
|
||||
break;
|
||||
case XMS_DEALLOCATE_UMB: /* 11 */
|
||||
LOG(LOG_MISC,LOG_ERROR)("XMS:Unhandled call %2X",reg_ah);
|
||||
if (!umb_available) {
|
||||
reg_ax=0;
|
||||
reg_bl=XMS_FUNCTION_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
if (dos_infoblock.GetStartOfUMBChain()!=0xffff) {
|
||||
if (DOS_FreeMemory(reg_dx)) {
|
||||
reg_ax=0x0001;
|
||||
break;
|
||||
}
|
||||
}
|
||||
reg_ax=0x0000;
|
||||
reg_bl=UMB_NO_BLOCKS_AVAILABLE;
|
||||
break;
|
||||
case XMS_QUERY_ANY_FREE_MEMORY: /* 88 */
|
||||
reg_bl = XMS_QueryFreeMemory(reg_ax,reg_dx);
|
||||
|
@ -336,6 +384,10 @@ Bitu XMS_Handler(void) {
|
|||
reg_edx &= 0xffff;
|
||||
reg_ecx = (MEM_TotalPages()*MEM_PAGESIZE)-1; // highest known physical memory address
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_MISC,LOG_ERROR)("XMS: unknown function %02X",reg_ah);
|
||||
reg_ax=0;
|
||||
reg_bl=XMS_FUNCTION_NOT_IMPLEMENTED;
|
||||
}
|
||||
// LOG(LOG_MISC,LOG_ERROR)("XMS: CALL Result: %02X",reg_bl);
|
||||
return CBRET_NONE;
|
||||
|
@ -346,6 +398,7 @@ private:
|
|||
public:
|
||||
XMS(Section* configuration):Module_base(configuration){
|
||||
Section_prop * section=static_cast<Section_prop *>(configuration);
|
||||
umb_available=false;
|
||||
if (!section->Get_bool("xms")) return;
|
||||
Bitu i;
|
||||
BIOS_ZeroExtendedSize(true);
|
||||
|
@ -373,10 +426,21 @@ public:
|
|||
}
|
||||
/* Disable the 0 handle */
|
||||
xms_handles[0].free = false;
|
||||
|
||||
/* Set up UMB chain */
|
||||
umb_available=strcmp(section->Get_string("umb"),"false")!=0;
|
||||
DOS_BuildUMBChain(section->Get_string("umb"),section->Get_bool("ems"));
|
||||
}
|
||||
|
||||
~XMS(){
|
||||
Section_prop * section = static_cast<Section_prop *>(m_configuration);
|
||||
/* Remove upper memory information */
|
||||
dos_infoblock.SetStartOfUMBChain(0xffff);
|
||||
if (umb_available) {
|
||||
dos_infoblock.SetUMBChainState(0);
|
||||
umb_available=false;
|
||||
}
|
||||
|
||||
if (!section->Get_bool("xms")) return;
|
||||
/* Undo biosclearing */
|
||||
BIOS_ZeroExtendedSize(false);
|
||||
|
|
Loading…
Add table
Reference in a new issue