📄 memex.c
字号:
;/*
; * Microsoft Confidential
; * Copyright (C) Microsoft Corporation 1988 - 1991
; * All Rights Reserved.
; */
/*
* MEMEX.C - expanded and extended memory handling functions for MEM.C.
*
*/
#include "bios.h"
#include "ctype.h"
#include "conio.h" /* need for kbhit prototype */
#include "stdio.h"
#include "dos.h"
#include "string.h"
#include "stdlib.h"
#include "msgdef.h"
#include "version.h" /* MSKK02 07/18/89 */
#include "mem.h"
#include "xmm.h"
#include "versionc.h"
int IsWindowsRunning (void);
void
GetExtraMemory()
{
GetEMS();
GetXMS();
}
void
GetXMS()
{
int far *ptr;
long a, b;
mem_table.hma = -2; /* Does not exist by default */
if (IsPre286())
{
mem_table.xms_ttl = 0L;
mem_table.xms_free = 0L;
return;
}
InRegs.x.ax = 0x4300;
int86x (0x2F, &InRegs, &OutRegs, &SegRegs);
if (OutRegs.h.al == 0x80)
{
InRegs.x.ax = 0x4310;
int86x (0x2F, &InRegs, &OutRegs, &SegRegs);
FP_SEG(ptr) = SegRegs.es;
FP_OFF(ptr) = OutRegs.x.bx;
a = XMSVersion (ptr);
b = XMSDriver (ptr);
mem_table.xmsMvers = (int)(a / (long)0x100); // Get version number
mem_table.xmsmvers = (int)(a % (long)0x100);
mem_table.xmsMdrvr = (int)(b / (long)0x100); // Get driver version
mem_table.xmsmdrvr = (int)(b % (long)0x100);
}
/*
* BUGBUG t-richj 11/23/92: Function 0x52 doesn't return valid XMS # if > 16MB
* Previously, MEM was using int 0x21, function 0x52 to obtain the amount
* of XMS on the system--this fails on machines with more than 16MB, as does
* the semi-documented int 0x15, function 0x88 call. The only reliable
* method to determine the total amount of XMS is to sum each used block
* with the amount free (the call for which works properly). We use the
* DOS call here to determine the amount of XMS tenatively; if an XMM
* is installed, we will correct the total size of XMS by working with it.
*
*/
InRegs.h.ah = (unsigned char) 0x52;
intdosx(&InRegs,&OutRegs,&SegRegs);
FP_SEG(SysVarsPtr) = SegRegs.es;
FP_OFF(SysVarsPtr) = OutRegs.x.bx;
if (SysVarsPtr->ExtendedMemory != 0)
{
mem_table.xms_ttl = (long)SysVarsPtr->ExtendedMemory * 1024L;
OutRegs.x.cflag = 0;
InRegs.x.ax = GetExtended;
int86(CASSETTE, &InRegs, &OutRegs);
mem_table.int_15h = (long)OutRegs.x.ax * 1024L;
/*
* subtract out VDisk usage from int15h memory. Note assumption that
* VDisk usage doesn't exceed 64Mb. Don't bother if there is no extended
* memory.
*
*/
if (mem_table.int_15h != 0L)
mem_table.int_15h -= (long)CheckVDisk() * 1024L;
// BUGBUG jimmat 1-14-93
// This has already been done above. Doing it again voids the
// vdisk check just before this.
InRegs.x.ax = 0x8800;
int86 (0x15, &InRegs, &OutRegs);
mem_table.int_15h = (long)OutRegs.x.ax *1024L;
/*
* if an XMS driver is present, INT 15 may return 0 as the amount
* of extended memory available. In that case, call the XMS
* driver to find out the amount of XMS free. Don't call XMS
* unconditionally, because that will cause it to claim memory
* if it has not already done so.
*
* However, it is possible, with the newer versions of Himem,
* for XMS memory and INT 15 memory to coexist. There is no
* completely reliable way to detect this situation, but we
* do know that if Himem is installed, DOS is high, and INT 15
* memory exists, then we are configured that way. In that case,
* we can make calls to Himem without disrupting the memory environment.
* Otherwise we can't.
*
*/
if (XMM_Installed())
{
mem_table.xms_free = XMM_QueryTotalFree() * 1024L;
if (!IsWindowsRunning())
Correct_Total_XMS ();
mem_table.xms_ttl -= mem_table.umb_ttl;
InRegs.x.ax = 0x3306; /* get DOS version info */
intdos(&InRegs, &OutRegs); /* call DOS */
mem_table.hma = (OutRegs.h.dh == DOSHMA) + 2*(OutRegs.h.dh == DOSROM);
if (! mem_table.hma)
{
mem_table.hma = XMM_RequestHMA(0xffff) ? -1 : 0;
if (! mem_table.hma)
{
XMM_ReleaseHMA();
}
}
}
}
}
void
GetEMS ()
{
if (! EMSInstalled()) return;
InRegs.x.ax = EMSGetFreePgs;
int86x (EMS, &InRegs, &OutRegs, &SegRegs);
mem_table.ems_ttl = (16L*1024L) * OutRegs.x.dx;
mem_table.ems_free = (16L*1024L) * OutRegs.x.bx;
InRegs.x.ax = EMSGetVer;
int86x(EMS, &InRegs, &OutRegs, &SegRegs);
mem_table.emsMvers = (OutRegs.h.al & 0xF0) >> 4;
mem_table.emsmvers = (OutRegs.h.al & 0x0F);
}
char EMSInstalled()
{
unsigned int EMSStatus;
unsigned int EMSVersion;
char EmsName[8];
void far *EmsNameP;
InRegs.h.ah = GET_VECT;
InRegs.h.al = EMS;
intdosx(&InRegs,&OutRegs,&SegRegs);
if ((SegRegs.es != 0) && (OutRegs.x.bx != 0))
{
EmsNameP = EmsName;
movedata(SegRegs.es, 0x000a, FP_SEG(EmsNameP), FP_OFF(EmsNameP), 8);
if (strncmp(EmsName, "EMMXXXX0", 8))
return FALSE;
InRegs.x.ax = EMSGetStat; /* get EMS status */
int86x(EMS, &InRegs, &OutRegs, &SegRegs);
EMSStatus = OutRegs.h.ah; /* EMS status in AH */
InRegs.x.ax = EMSGetVer; /* get EMS version */
int86x(EMS, &InRegs, &OutRegs, &SegRegs);
EMSVersion = OutRegs.h.al; /* EMS version in AL */
if ((EMSStatus == 0) && (EMSVersion >= DOSEMSVER))
return TRUE;
}
return FALSE;
}
/*
* The code below is snitched from xmsinfo.c (thanks, jimmat)
*
*/
void Correct_Total_XMS()
{
struct _handle far *lpHandle, far *lpHandleTable;
unsigned int HandleCount, HandleSize;
/*
* If we can talk to the XMS driver, we can obtain an accurate amount of
* total XMS by adding the amount free to the amount used--the amount used
* being obtained by checking each handle, and summing the size of those
* marked 'used' (0x02 == hType).
*
*/
if (lpHandleTable = HimemHandleTable (&HandleCount,&HandleSize))
{
mem_table.xms_ttl = mem_table.xms_free;
mem_table.xms_ttl += 0x40 * 1024L; /* Account for HMA */
for (lpHandle = lpHandleTable; HandleCount; HandleCount--, lpHandle++)
{
if (lpHandle->hType == 0x02) /* Is this handle used? */
{
mem_table.xms_ttl += (long)lpHandle->hLen * 1024L;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -