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

📄 meminfo.c

📁 Dos6.0
💻 C
📖 第 1 页 / 共 5 页
字号:
    {
      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 + -