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

📄 meminfo.c

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