⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 meminfo.c

📁 Dos6.0
💻 C
📖 第 1 页 / 共 5 页
字号:

  /* 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 + -