1
0
Fork 0

adding support for upper memory

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2262
This commit is contained in:
Sebastian Strohhäcker 2005-08-08 13:33:46 +00:00
parent bc49a1ce91
commit caff0f7a8b
9 changed files with 304 additions and 48 deletions

View file

@ -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);