📄 meminfo.c
字号:
{
mov ah,07h
call [XMSControl]
mov A20Status,ax
mov XMSError,bl
}
/* Store the A20 line status */
pMem_Info->iA20Status = A20Status;
/* Detect the XMS UMB free areas */
#define XMS_UMB_ERROR 2
#define MAX_XMS_UMB_SEGS 100
{
BYTE bErrorCode; /* Error code from XMS UMB call */
WORD wSegmentAddr; /* Segment address of free XMS UMB */
WORD wSegmentSize; /* Size of XMS UMB */
WORD wTotalFree = 0; /* Total amount of free XMS UMB space */
WORD wLargestFree = 0; /* Largest free area */
/* Segment addresses of XMS UMBs */
WORD wSegments[MAX_XMS_UMB_SEGS + 1];
WORD i; /* Looping variable */
BOOL fDoneFlag = FALSE; /* TRUE when all XMS UMBs accounted for */
int iRow, iCol; /* Row and Column of visual map overlay */
int iNumOfChars; /* Number of characters (or 1K blocks) */
for (i = 0; i < MAX_XMS_UMB_SEGS && fDoneFlag == FALSE; ++i)
{
_asm
{
mov ah, 0x10 ; Request XMS UMB
mov dx, 0xFFFF ; Requested size in paragraphs
call [XMSControl] ; Make the call
or ax,ax ; AX == 0x0000 if it failed
jz FirstErrResults ; Jump around if it failed
mov fDoneFlag, XMS_UMB_ERROR ; There is no way this could
; have succeeded. If it did,
; bomb out immediately.
jmp FirstXmsUmbDone
FirstErrResults:
mov bErrorCode, bl ; Store the error code
mov wSegmentSize, dx ; Store size of largest free block
FirstXmsUmbDone:
}
/* Bomb out if 0xFFFF succeeded */
if (fDoneFlag == XMS_UMB_ERROR)
break;
/* Are there no more segments free */
if (bErrorCode == 0xB1)
fDoneFlag == TRUE;
/* If the function was not implemented, bomb out */
if (bErrorCode == 0x80)
{
pMem_Info->fXmsUmbAvailable = FALSE;
fDoneFlag = XMS_UMB_ERROR;
break;
}
/* If an unexpected error occured, bomb out */
if (bErrorCode != 0xB0)
{
fDoneFlag = XMS_UMB_ERROR;
break;
}
/* The XMS UMB calls are available */
pMem_Info->fXmsUmbAvailable = TRUE;
/* One segment of wSegmentSize size is free -- allocate it */
_asm
{
mov ah, 0x10 ; Request XMS UMB
mov dx, wSegmentSize ; Requested size in paragraphs
call [XMSControl] ; Make the call
or ax,ax ; AX == 0x0000 if it failed
jz SecondErrResults ; Jump around if it failed
mov wSegmentAddr, bx ; Store XMS UMB segment address
mov wSegmentSize, dx ; Store size of block
jmp SecondXmsUmbDone
SecondErrResults:
mov fDoneFlag, XMS_UMB_ERROR ; This should not have failed.
; If it did, bomb out
; immediately.
SecondXmsUmbDone:
}
/* Bomb out if 0xFFFF succeeded */
if (fDoneFlag == XMS_UMB_ERROR)
break;
/* Accumulate the results */
wSegments[i] = wSegmentAddr;
if (wSegmentSize > wLargestFree)
wLargestFree = wSegmentSize;
wTotalFree += wSegmentSize;
/* Fill the memory map with "X"es */
iRow = wSegmentAddr / 0x400;
iCol = (wSegmentAddr % 0x400) / 0x40;
iNumOfChars = (WORD) ((((DWORD) wSegmentSize << 4) + 1023) / 1024);
FillMemMapOverlay (pMem_Info, iRow, iCol, iNumOfChars,
REPORT_FREE_XMS_UMB);
}
wSegments[i] = 0x0000;
/* Store the results in the XMS UMB area of pMem_Info */
pMem_Info->dwXmsUmbFree = (DWORD) wTotalFree << 4;
pMem_Info->dwXmsUmbLargestFree = (DWORD) wLargestFree << 4;
/* The amounts have been determined -- free the blocks */
for (i = 0; i < MAX_XMS_UMB_SEGS && wSegments[i] != 0x0000; ++i)
{
wSegmentAddr = wSegments[i];
_asm
{
mov ah, 0x11 ; Release XMS UMB
mov dx, wSegmentAddr ; paragraph to release
call [XMSControl] ; Make the call
or ax,ax ; AX == 0x0000 if it failed
jnz ThirdXmsUmbDone ; Jump around if it failed
mov fDoneFlag, XMS_UMB_ERROR ; This should not have failed.
; If it did, bomb out
; immediately.
ThirdXmsUmbDone:
}
if (fDoneFlag == XMS_UMB_ERROR)
break;
}
}
/* Get the Super Extended Memory values */
{
if (wProcessorType > _80286 &&
GetSuperXmsInfo (XMSControl, &SxmsLargestFree, &SxmsTotalFree) == 0)
{
/* Super XMS exists */
pMem_Info->fSxmsAvailable = TRUE;
pMem_Info->dwSxmsLargestFree = SxmsLargestFree;
pMem_Info->dwSxmsTotalFree = SxmsTotalFree;
}
else
{
/* There is no Super XMS */
pMem_Info->fSxmsAvailable = FALSE;
}
}
}
else /* There is no XMS driver present */
pMem_Info->iXmm_Is_There = False;
return (0);
}
/************************************************************************
* Function GetRomMap - Fills a ROM_MAP structure with the information
* about ROM BIOSes and Option ROMs in the system.
*
* pRomMap - Pointer to the structure for storing the ROM map.
***********************************************************************/
VOID GetRomMap (ROM_MAP *pRomMap, WORD wBusType)
{
int iMapSegment, iMapOffset;
WORD wOptIndex = 0; /* Option ROM index */
unsigned uSegment;
unsigned uOffset;
int iValidRom;
int iFalse = 0;
int iTrue = 1;
unsigned END_SEGMENT = 0xEC00;
/* Check if we are on a ps/2 or not. If this is a ps/2, the
range E000-EFFF is system ROM so we only need to check up
through the DC00 page. If this is not a ps/2, the range
F000-EFFF is ROM so we only need to check up through page EC00 */
if (wBusType == 3) /* Is this a PS/2? (MCA) */
{
END_SEGMENT = 0xDC00;
pRomMap->wRomBiosLoc[0] = 0xE000;
pRomMap->dwRomBiosSize[0] = 0x10000;
pRomMap->wRomBiosLoc[1] = 0xF000;
pRomMap->dwRomBiosSize[1] = 0x10000;
}
else
{
pRomMap->wRomBiosLoc[0] = 0xF000;
pRomMap->dwRomBiosSize[0] = 0x10000;
pRomMap->wRomBiosLoc[1] = 0;
pRomMap->dwRomBiosSize[1] = 0;
}
/* Set the indexes for the memory search to point to just past
the conventional memory limit, first column */
/* Begin stepping through memory, forcing uSegment to start on
a true "visual memory map" line number */
uSegment = 0xA000;
/* Make iMapSegment start on the appropriate line */
iMapSegment = uSegment / 1024;
iMapOffset = 0;
iValidRom = iFalse;
for (; uSegment <= END_SEGMENT; uSegment += SEGMENT_INC)
{
for (uOffset = START_OFFSET; uOffset < ENDING_OFFSET;
uOffset += OFFSET_INC)
{
/* Check the value of iValidRom. If it is non-zero, we are in */
/* an Option ROM and iValidRom is the number of 1K blocks */
/* that we still have to mark as being ROM. Mark the current */
/* 1K block as being ROM and then decrement iValidRom by 1. */
/* If iValidRom is zero, we are not currently inside an */
/* Option ROM area. */
if (iValidRom)
{
iValidRom--;
}
else /* Not currently in an Option ROM */
{
/* Attempt to determine what is at address uSegment:uOffset.
First check for an Option ROM with a valid signature */
iValidRom = OptionRomCheck (uSegment, uOffset);
if (iValidRom)
{
/* An Option ROM with a signature was detected with a
length of iValidRom */
if (wOptIndex < 10)
{
pRomMap->wOptRomLoc[wOptIndex] = uSegment +
(uOffset >> 4);
pRomMap->dwOptRomSize[wOptIndex] = (DWORD) iValidRom *
1024L;
++wOptIndex;
}
iValidRom--;
}
}
/* Set the index for the memory map array to point to the
next column, same row */
iMapOffset++;
}
/* Set the indexes for the memory map array to point to the
next row, first column of the array */
iMapSegment++;
iMapOffset = 0;
}
return;
}
/************************************************************************
*
* Function Get_VisualMemMap()
*
* This function generates a visual memory map of the address range
* 0000 to EFFF. It attempts to detect RAM, ROM and WOM (nothing).
*
* Mem_Info_St Fields Set
* ----------------------
*
* auchMemoryMap = The array holding the characters used to display the
* map.
*
*
* Local Variables Used
* --------------------
*
* iMapSegment, iMapOffset : Used to keep track of the location in the
* : array holding the memory map.
* iRow, iCol : Used to point to a specific location in the
* : array holding the memory map.
* iMemLimit : RAM and WOM extends up to the limit set
* : by this variable
* uSegment, uOffset : The current segment:offset being looked at.
* uiPageFrameAddress : The address of EMS page frame.
* Ram, Rom, Wom
* NotCertain : Used when building the memory map.
* iFalse, iTrue : Used for Boolean checking.
* iValidRom : Used to figure out if we are currently in a
* : ROM area which had a valid signature byte.
* END_SEGMENT : The final segment to check through.
*
************************************************************************/
int Get_VisualMemMap (MEMORY_STRUCT FAR * pMem_Info, WORD wBusType)
{
int iMapSegment, iMapOffset;
int iRow, iCol;
int iMemLimit;
unsigned uSegment;
unsigned uOffset;
unsigned char Ram, Rom, Wom, NotCertain;
int iValidRom;
int iFalse = 0;
int iTrue = 1;
unsigned END_SEGMENT = 0xEC00;
/* Check if we are on a ps/2 or not. If this is a ps/2, the
range E000-EFFF is system ROM so we only need to check up
through the DC00 page. If this is not a ps/2, the range
F000-EFFF is ROM so we only need to check up through page EC00 */
if (wBusType == 3) /* Is this a PS/2? (MCA) */
END_SEGMENT = 0xDC00;
/* Define the characters to be used to display the map. Check
fpOutfile to determine if this map is going to the screen
or to a printer */
/* Going to the screen, use extended chars */
if (fReportFlag == FALSE)
{
Ram = DISPLAY_RAM;
Rom = DISPLAY_ROM;
Wom = DISPLAY_WOM;
NotCertain = DISPLAY_NOT_CERTAIN;
}
else /* Going to a report. Use standard ASCII */
{
Ram = REPORT_RAM;
Rom = REPORT_ROM;
Wom = REPORT_WOM;
NotCertain = REPORT_NOT_CERTAIN;
}
/* Special case for black and white screen display */
if (fBlackWhite == TRUE && fReportFlag == FALSE)
{
Rom = REPORT_ROM;
}
/* Initialize the map to RAM values in conventional RAM area */
/* to RAM, the area up to the ROM BIOS as empty, and the ROM */
/* BIOS as ROM. Also, tack an ending null char in the last */
/* column of each row so that winWrtStrnAttrib can be used */
/* when moving the segment selection bar in the memory browse */
/* stuff. */
/* Fill up the "conventional RAM" in the visual memory map. */
/* RAM is assumed to be installed in 16k incriments. */
/* Set the maximum line number (ie, limit) to fill with RAM */
iMemLimit = (int) (pMem_Info->lConv_Mem / (16384L));
for (iRow = 0; iRow < iMemLimit; iRow++)
{
for (iCol = 0; iCol < (NUM_OF_COLS-1); iCol++)
pMem_Info->abMemoryMap [iRow][iCol] = Ram;
pMem_Info->abMemoryMap [iRow][iCol] = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -