📄 meminfo.c
字号:
/* Fill from past "conventional RAM" to the ROM BIOS with WOM */
iMemLimit = (int) (END_SEGMENT / 1024);
for (; iRow <= iMemLimit; ++iRow)
{
for (iCol = 0; iCol < (NUM_OF_COLS-1); iCol++)
pMem_Info->abMemoryMap [iRow][iCol] = Wom;
pMem_Info->abMemoryMap [iRow][iCol] = 0;
}
/* Fill the ROM BIOS area with ROM */
for (; iRow < NUM_OF_ROWS; ++iRow)
{
for (iCol = 0; iCol < (NUM_OF_COLS-1); iCol++)
pMem_Info->abMemoryMap [iRow][iCol] = Rom;
pMem_Info->abMemoryMap [iRow][iCol] = 0;
}
/* Set the indexes for the memory map array 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 = (unsigned) (pMem_Info->lConv_Mem / 16L);
uSegment = uSegment & 0xF800;
/* 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)
{
pMem_Info->abMemoryMap [iMapSegment][iMapOffset] = Rom;
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 */
pMem_Info->abMemoryMap [iMapSegment][iMapOffset] = Rom;
iValidRom--;
}
else /* Try to determine what is there */
{
switch (RamRomWomCheck (uSegment, uOffset, OFFSET_INC, fWindowsRunning))
{
case 0:
pMem_Info->abMemoryMap [iMapSegment][iMapOffset] = Ram;
break;
case 1:
pMem_Info->abMemoryMap [iMapSegment][iMapOffset] = NotCertain;
break;
case 2:
pMem_Info->abMemoryMap [iMapSegment][iMapOffset] = Wom;
break;
default:
pMem_Info->abMemoryMap [iMapSegment][iMapOffset] = NotCertain;
}
}
}
/* 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 (0);
}
/*********************************************************************
* VisualMapOverlay - Fills the Visual Memory Map's Overlay map. EMS
* page frames are marked 'E', used UMBs are marked
* 'U', and free UMBs are marked 'F'. Also counts
* up the used and free UMBs.
*
* pMem - Pointer to the memory information structure.
*
* Returns: TRUE if an error occured.
*********************************************************************/
BOOL VisualMapOverlay (MEMORY_STRUCT FAR * pMem)
{
WORD wPageFrameAddress; /* Segment of EMS Page frame */
int iRow, iCol; /* Row and Column of visual map overlay */
int iNumOfChars; /* Number of characters (or 1K blocks) */
/* necessary to fill the page fram area */
TSR_PROGRAMS_STRUCT *pTsr = NULL; /* TSR Program list */
WORD wSize; /* Size required to store TSR list */
WORD i; /* Looping variable */
/* Check to see if an EMS page frame was detected and if we want to */
/* display it. If one was and we do want to show it, fill in the */
/* correct area in the memory map with characters to specify the */
/* page frame */
wPageFrameAddress = pMem->iPageFrameAddress;
if (wPageFrameAddress)
{
iNumOfChars = 64;
iRow = wPageFrameAddress / SEGMENT_INC;
iCol = (wPageFrameAddress - (iRow * SEGMENT_INC)) / (OFFSET_INC >> 4);
FillMemMapOverlay (pMem, iRow, iCol, iNumOfChars, DISPLAY_EMS);
}
/* Now, obtain the Memory Control Block information, to locate the */
/* Upper Memory Blocks. */
if (wDosMajor >= 5 && wDosMajor < 10)
{
/* Obtain the TSR list */
wSize = GetInfoSize (IDI_TSR_PROGRAMS_RECORD, FALSE);
if ((pTsr = malloc (wSize)) == NULL)
{
OutOfMemory();
return (TRUE);
}
/* Zero out the structure */
memset (pTsr, '\0', wSize);
if (GetInfo (IDI_TSR_PROGRAMS_RECORD, pTsr, FALSE, FALSE, FALSE))
return (TRUE);
/* Find the first upper memory block, if it exists */
for (i = 1;
pTsr[i].wAddress != 0 &&
pTsr[i].wAddress + (pTsr[i].dwBlockSize >> 4) < 0xA000;
++i)
;
/* Set the flag for UMBs available */
if (pTsr[i].wAddress + (pTsr[i].dwBlockSize >> 4) >= 0xA000)
pMem->fUmbsAvailable = TRUE;
/* Begin walking the UMBs */
for (; pTsr[i].wAddress != 0; ++i)
{
CHAR chFillChar; /* Character to fill the visual map with */
/* Skip the excluded UMB areas */
if (strcmp (pTsr[i].szTsrName, pszExcludedUmbArea) == 0)
continue;
/* Free areas use 'F', used areas use 'U' */
if (strcmp (pTsr[i].szTsrName, pszFreeMemory) == 0)
{
chFillChar = DISPLAY_FREE_UMB;
/* Add up the UMB area, if it counts */
if (pTsr[i].szTsrName[0] != ' ')
{
pMem->dwTotalUmbs += pTsr[i].dwBlockSize;
pMem->dwFreeUmbs += pTsr[i].dwBlockSize;
if (pTsr[i].dwBlockSize > pMem->dwLargestFreeUmb)
pMem->dwLargestFreeUmb = pTsr[i].dwBlockSize;
}
}
else
{
chFillChar = DISPLAY_USED_UMB;
/* Add up the UMB area, if it counts */
if (pTsr[i].szTsrName[0] != ' ')
pMem->dwTotalUmbs += pTsr[i].dwBlockSize;
}
/* Fill the region with the correct value */
iRow = pTsr[i].wAddress / 0x400;
iCol = (pTsr[i].wAddress % 0x400) / 0x40;
iNumOfChars = (WORD) ((pTsr[i].dwBlockSize + 1023) / 1024);
FillMemMapOverlay (pMem, iRow, iCol, iNumOfChars, chFillChar);
}
/* Free up the TSR structure */
free (pTsr);
}
}
/************************************************************************
*
* Function FillMemMap()
*
* This function fills in a specified portion of the memory map array with
* a specific value.
*
*
* Mem_Info_St Fields Set
* ----------------------
*
* abMemoryMap = The array of unsigned characters which holds the values
* used to display the memory map.
*
*
* Local Variables Used
* --------------------
*
* index : An integer used to keep track of how many fill chars
* have been written to the memory map array.
* iRow, iCol : Integers used to index into the memory map array.
* iNumOfChars : The number of fill characters to write to the map array.
* uchFillChar : The fill character to be written to the map array.
*
************************************************************************/
int FillMemMap (MEMORY_STRUCT FAR * pMem, int iRow, int iCol,
int iNumOfChars, unsigned char uchFillChar)
{
int index = 0;
while (index < iNumOfChars)
{
pMem->abMemoryMap [iRow][iCol] = uchFillChar;
iCol++;
if (iCol == NUM_OF_COLS - 1) /* Use (NUM_OF_COLS - 1) so we don't */
{ /* step on the null char used when */
iCol = 0; /* displaying the map on the screen. */
iRow++;
}
index++;
}
return (0);
}
/************************************************************************
*
* Function FillMemMapOverlay()
*
* This function fills in a specified portion of the memory map overlay
* array witha specific value.
*
*
* Mem_Info_St Fields Set
* ----------------------
*
* abMemMapOverlay = The array of unsigned characters which holds the
* values used to display the memory map.
*
*
* Local Variables Used
* --------------------
*
* index : An integer used to keep track of how many fill chars
* have been written to the memory map array.
* iRow, iCol : Integers used to index into the memory map array.
* iNumOfChars : The number of fill characters to write to the map array.
* uchFillChar : The fill character to be written to the map array.
*
************************************************************************/
int FillMemMapOverlay (MEMORY_STRUCT FAR * pMem, int iRow, int iCol,
int iNumOfChars, unsigned char uchFillChar)
{
int index = 0;
while (index < iNumOfChars)
{
pMem->abMemMapOverlay [iRow][iCol] = uchFillChar;
iCol++;
if (iCol == NUM_OF_COLS - 1) /* Use (NUM_OF_COLS - 1) so we don't */
{ /* step on the null char used when */
iCol = 0; /* displaying the map on the screen. */
iRow++;
}
index++;
}
return (0);
}
/**************************************************************************
* RamRomWomCheck - Checks if the memory pointed to by uSegment:uOffset
* is RAM, ROM, or Available (WOM).
*
* RAM can change.
* WOM is unchangable and has FFH's through the entire
* range.
* ROM is unchangable and is not FFH through the entire
* range.
*
* uSegment - Segment to search
*
* uOffset - Offset to search
*
* uLength - Length of search to perform when checking for ROM/WOM
*
* fWindowsRunning - If windows is running, disable the RAM test.
*
* Returns RAM (0), ROM (1), or WOM (2).
**************************************************************************/
int _fastcall RamRomWomCheck (unsigned uSegment,
unsigned uOffset,
unsigned uLength,
BOOL fWindowsRunning)
{
UCHAR uchHoldByte; /* Used for storing byte during RAM check */
int iReturnValue; /* Value this routine returns */
_asm
{
push es ;Save the ES register
push ax ;Put uSegment into ES
pop es
mov di,dx ;Put uOffset into DI
mov cx,bx ;Put uLength into CX
mov al,es:[di] ;Store byte in holding area
mov [uchHoldByte],al
cmp fWindowsRunning, 0 ;Is it safe to perform the RAM test?
jne SkipRamTest ;Skip out if not.
xor al,0xFF ;Toggle all bits in AL
cli ;Clear interrupts for RAM check
mov es:[di],al ;Put new value back in memory
mov al,[uchHoldByte] ;Put the original value back in AL
; There is logic behind checking the
; original value instead of the changed
; value. Suppose the adapter card at
; this address does not support all 8
; bits. Checking for the changed value
; would return false, even though seven
; bits were changed. (One possibility
; for the missing bit or bits would be
; special purpose RAM).
push cx ;Wait for a moment, to allow memory to
mov cx,0x10 ; stabilize
Wait001:
loop Wait001
pop cx
cmp al,es:[di] ;Check to see if it is the original value
jne ThisMayBeRAM ;If not, this might be RAM
;---- Now check for the difference between ROM and WOM ----
SkipRamTest:
cmp al,0xFF ;Was the byte 0FFH?
jne ThisIsROM ;If not, this is definitely ROM
;---- This could be WOM. Check for a bunch of FFHs ----
repe scasb ;Search for the first non 0FFH
cmp cx,0 ;Did we get to the end without a non-0FFH?
jne ThisIsROM ;If not, this is ROM
;---- WOM was detected, set the return value ----
mov iReturnValue,WOM ;Set the return value
jmp MemCheckComplete ;Exit this routine
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -