📄 meminfo.c
字号:
{
frac_portion = (outregs.h.al & 0x0F);
int_portion = ((outregs.h.al >> 4) & 0x0F);
pMem_Info->iEmm_VersionMajor = int_portion;
pMem_Info->iEmm_VersionMinor = frac_portion;
}
else
pMem_Info->iEmm_Ver_Err = outregs.h.ah;
/* Get the total number of EM pages and the number free using a
LIM 3.X call */
inregs.h.ah = 0x42;
int86(0x67, &inregs, &outregs);
if (outregs.h.ah)
pMem_Info->iEmm_Size_Err = outregs.h.ah;
else
{
pMem_Info->iTotal_Emm_Pages = outregs.x.dx;
pMem_Info->iFree_Emm_Pages = outregs.x.bx;
}
/* If LIM 4.0 was detected use a LIM 4.0 specific call to get the
total number of raw EM pages and the number of raw EM pages
available */
if (pMem_Info->iEmm_VersionMajor == 4 && pMem_Info->iEmm_VersionMinor == 0)
{
/* Get the size of a raw EM page from the EM hardware configuration */
if (( pPtrToConfigBuffer = (unsigned int *) malloc (10)) == NULL )
pMem_Info->iEmm_Size_Err = outregs.h.ah; /* The malloc failed */
else
{
/* Get the EM hardware configuration */
inregs.x.ax = 0x5900;
segread (&segments);
segments.es = (unsigned int) FP_SEG (pPtrToConfigBuffer);
inregs.x.di = (unsigned int) FP_OFF (pPtrToConfigBuffer);
int86x (0x67, &inregs, &outregs, &segments);
if (outregs.h.ah) /* There was an error getting the EM config */
pMem_Info->iEmm_Size_Err = outregs.h.ah;
else
{
/* At this point pPtrToConfigBuffer is pointing to an integer
value which is the raw EM page size, in paragraphs. Next,
get the total number of raw pages and the number available */
inregs.x.ax = 0x5901;
int86 (0x67, &inregs, &outregs);
if (outregs.h.ah) /* There was an error returned */
pMem_Info->iEmm_Size_Err = outregs.h.ah;
else
{
pMem_Info->iTotal_Emm_Pages = outregs.x.dx;
pMem_Info->iFree_Emm_Pages = outregs.x.bx;
}
}
}
}
/* Free up the EMS pointer */
free (pPtrToConfigBuffer);
/* Get the EMS page frame address */
inregs.h.ah = 0x41;
int86(0x67, &inregs, &outregs);
uiPageFrameAddress = outregs.x.bx;
if (!outregs.h.ah) /* A page frame address was returned */
pMem_Info->iPageFrameAddress = uiPageFrameAddress;
return (0);
}
/************************************************************************
*
* Function GetVCPIInfo ()
*
* This function detects whether or not a VCPI control program is present.
* If one is, information about the amount of VCPI memory available is
* gathered.
*
************************************************************************/
int GetVCPIInfo (MEMORY_STRUCT FAR * pMem_Info)
{
union REGS inregs, outregs;
struct SREGS segments;
inregs.x.ax = 0xDE00;
int86x (0x67, &inregs, &outregs, &segments);
if( outregs.h.ah == 0x00 )
{
pMem_Info->iVCPIPresent = 1;
pMem_Info->iVCPIMajorVersion = outregs.h.bh;
pMem_Info->iVCPIMinorVersion = outregs.h.bl;
/* Query the amount of available VCPI memory */
inregs.x.ax = 0xDE03;
int86x (0x67, &inregs, &outregs, &segments);
if (outregs.h.ah == 0x00 )
pMem_Info->iVCPIAvailMemory = outregs.x.dx * 4;
}
return (0);
}
/************************************************************************
*
* Function GetDPMIInfo ()
*
* This function detects whether or not a DPMI control program is present.
* If one is, information about the amount of DPMI memory available is
* gathered by calling the function QueryDPMIMemInfo ().
*
************************************************************************/
int GetDPMIInfo (MEMORY_STRUCT FAR * pMem_Info)
{
union REGS inregs, outregs;
struct SREGS segments;
inregs.x.ax = 0x1687;
int86x (0x2F, &inregs, &outregs, &segments);
if (outregs.x.ax == 0x00)
{
pMem_Info->iDPMIPresent = 1;
pMem_Info->iDPMIMajorVersion = outregs.h.dh;
pMem_Info->iDPMIMinorVersion = outregs.h.dl;
/* Query the DPMI control program */
/*
QueryDPMIMemInfo (pMem_Info);
*/
}
return (0);
}
/************************************************************************
*
* Function QueryDPMIMemInfo ()
*
* This function queries the DPMI control program for amounts of DPMI
* memory.
*
************************************************************************/
int QueryDPMIMemInfo (MEMORY_STRUCT FAR * pMem_Info)
{
long DPMIControl;
unsigned short wRMMemAvail;
DPMI_STRUCT FAR * pDPMIMemInfo = NULL;
pDPMIMemInfo = (DPMI_STRUCT FAR *) &(pMem_Info->DPMIMemInfo);
_asm
{
; Get the entry point of the DPMI control program
; and save it
mov ax, 1687h
int 2Fh
test ax, ax
jnz Failure
mov word ptr [DPMIControl],di
mov word ptr [DPMIControl+2],es
; if si != 0 then we need to allocate some memory
; for the dos extenders private data
test si, si
jz SiZero
mov bx, si
mov ah, 48h
int 21h
jc Failure
mov es, ax
SiZero:
xor ax,ax
call [DPMIControl]
jc Failure
les di, pDPMIMemInfo
mov ax, 0500h
int 31h
jc Failure
mov bx, 0ffffh
mov ax, 0100h
int 31h
mov wRMMemAvail, bx
}
pMem_Info->ulRealModeDPMIMemAvail = wRMMemAvail * 16;
Failure:
return (0);
}
/************************************************************************
*
* Function Get_Xmm_Info()
*
* This function first tests for the existence of an XMS driver. If an
* XMS driver is present, it returns the version of the XMS driver, the
* version of the XMS specification being used, whether or not the high
* memory area (HMA) is present, and whether or not the HMA is available.
* It also returns the size of the largest free extended memory block in
* bytes, and the total amount of free extended memory in bytes.
*
*
* Mem_Info_St Fields Set
* ----------------------
*
* iXmm_Is_There = 1 if an XMS driver is present, 0 if not
* iXmm_Spec_VersionMajor = The major version of the XMS specification
* iXmm_Spec_VersionMinor = The minor version of the XMS specification
* iXmm_Driver_VersionMajor = The internal major version of the XMM driver
* iXmm_Driver_VersionMinor = The internal minor version of the XMM driver
* lLargest_Free_Xm = The size in bytes of the largest free block of
* extended memory. Includes the 64K HMA if it is
* available.
* lTotal_Free_XM = The size in bytes of the total amount of free
* extended memory. Includes the 64K HMA if it is
* available.
*
* Local Variables Used
* --------------------
*
* XMSControl : The address of the XMS driver control function
* XMSIsThere : Used to flag whether or not an XMS driver is
* present
* XMSSpecVersion : The BCD version of the XMS spec being used
* XMSDriverVersion : The BCD version of the XMS driver being used
* LargestFreeBlock : Used to calculate the largest free block
* TotalFreeBlocks : Used to calculate the total amount free
* HMAStatus : Used to check the availability of the HMA
* XMSError : Used to hold error codes returned from the XMS
* calls
* A20Status : Used to hold the status of the A20 address line
* True, False : Used to set value of iXmm_Is_There
*
************************************************************************/
int Get_Xmm_Info(MEMORY_STRUCT FAR * pMem_Info, WORD wProcessorType)
{
long XMSControl;
unsigned char XMSIsThere;
unsigned char XMSSpecVersionMajor, XMSSpecVersionMinor;
unsigned char XMSDriverVersionMajor, XMSDriverVersionMinor;
unsigned int LargestFreeBlock, TotalFreeBlocks;
unsigned int HMAStatus;
unsigned char XMSError;
unsigned int A20Status;
int True = 1;
int False = 0;
int Available = 1;
int NotAvailable = 0;
DWORD SxmsLargestFree; /* Largest free SXMS block */
DWORD SxmsTotalFree; /* Total free SXMS */
/* Determine if an XMS driver is there */
_asm
{
/* After setting AX=43h, AL=00h and calling INT 2Fh, if an
XMS driver is present, AL will be set to 80h */
mov ax,4300h
int 2Fh
mov XMSIsThere,al
}
if ( XMSIsThere == 0x80 ) /* There is an XMS driver present */
{
pMem_Info->iXmm_Is_There = True;
_asm
{
/* Get the address of the XMS driver's control function.
Once we have that we can make calls to it to get the
other info we want */
mov ax,4310h
int 2Fh
mov word ptr [XMSControl],bx
mov word ptr [XMSControl+2],es
/* Get the XMS spec and driver version numbers, in BCD */
mov ah,00h
call [XMSControl]
mov XMSSpecVersionMajor,ah
mov XMSSpecVersionMinor,al
mov XMSDriverVersionMajor,bh
mov XMSDriverVersionMinor,bl
}
/* Get the XMS specification version */
pMem_Info->uchXmm_Spec_VersionMajor = XMSSpecVersionMajor;
pMem_Info->uchXmm_Spec_VersionMinor = XMSSpecVersionMinor;
/* Get the XMS driver version */
pMem_Info->uchXmm_Driver_VersionMajor = XMSDriverVersionMajor;
pMem_Info->uchXmm_Driver_VersionMinor = XMSDriverVersionMinor;
/* Query the amount of free extended memory */
_asm
{
mov ah,08h
call [XMSControl]
mov LargestFreeBlock,ax
mov TotalFreeBlocks,dx
mov XMSError,bl
}
/* Store the largest free block and the total free blocks */
pMem_Info->iLargest_Free_Xm = LargestFreeBlock;
pMem_Info->iTotal_Free_Xm = TotalFreeBlocks;
/* Check to see if the HMA is available by issuing a request for it */
_asm
{
/* Return the status of the request in HMAStatus. 0x0001 means
the request succeeded, 0x0000 means it failed */
mov ah,01h
call [XMSControl]
mov HMAStatus,ax
mov XMSError,bl
}
if (HMAStatus) /* The HMA request succeeded */
{
pMem_Info->iHMAStatus = Available;
/* Release the HMA */
_asm
{
/* Return the status of the release in HMAStatus. 0x0001 means
the HMA was released successfully, 0x0000 means otherwise */
mov ah,02h
call [XMSControl]
mov HMAStatus,ax
mov XMSError,bl
}
if (!HMAStatus) /* The HMA was not successfully released */
pMem_Info->iXMSError = 6; /* There was an error releasing the HMA */
}
else /* the HMA request failed */
{
pMem_Info->iHMAStatus = NotAvailable;
switch (XMSError) /* Get the reason why the HMA request failed */
{
case 0x80: pMem_Info->iXMSError = 1; /* Feature not implemented */
break;
case 0x81: pMem_Info->iXMSError = 2; /* VDISK was detected */
break;
case 0x90: pMem_Info->iXMSError = 3; /* HMA does not exist */
break;
case 0x91: pMem_Info->iXMSError = 4; /* HMA is already in use */
break;
default: pMem_Info->iXMSError = 5; /* Unknown reason */
}
}
/* Query the status of the A20 address line */
_asm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -