meminfo.c

来自「Dos6.0」· C语言 代码 · 共 2,069 行 · 第 1/5 页

C
2,069
字号

    ;---- RAM may have been detected ----

    ThisMayBeRAM:

      mov   bl,es:[di]          ;Now check to see if it is the changed value.
      xor   bl,0xFF             ;  The value may be bus noise or some other
                                ;  unusual case (WYSE 286 w/ 640k).  If it
                                ;  doesn't match the changed value, it is
                                ;  not RAM.

      cmp   al,bl               ;Does it match the changed value
      jne   ThisIsNotRAM        ;If not, this is something else

    ;---- RAM really was detected ----

      mov   al,uchHoldByte      ;Restore the original byte
      mov   es:[di],al

      mov   iReturnValue,RAM    ;Set the return value
      jmp   MemCheckComplete    ;Exit this routine

    ;---- ROM was detected, set the return value ----

    ThisIsROM:

      mov   iReturnValue,ROM    ;Set the return value
      jmp   MemCheckComplete    ;Exit this routine

    ;---- It's not RAM, it's not ROM, it's not WOM, it's something else ----

    ThisIsNotRAM:

      mov   iReturnValue,ROM    ;We'll call it available for now
      jmp   MemCheckComplete    ;Exit this routine

    ;---- Test is completed, return to calling routine ----

    MemCheckComplete:

      sti                       ;Restore interrupts
      pop   es                  ;Restore the original ES register
    }

  return (iReturnValue);
}

/**************************************************************************
 * OptionRomCheck - Checks for the presence of installed Option ROM cards
 *                  (ie, EGA/VGA, Net cards with ROMs, etc).
 *
 *                  Option ROM cards are installed in the range of C000
 *                    (A000?) - EFFF for non-PS/2 computers.  PS/2s use
 *                    E000-FFFF, so option cards can only be installed
 *                    between C000 - DFFF.
 *
 *                  According to the limited documentation we've found,
 *                    (Specifically a Windows 3.00 assembly language
 *                    include file), all Option ROMs in the valid range
 *                    start with the bytes AAH, 55H, followed by a byte
 *                    that tells the length of the ROM card / 512:
 *
 *                    +----------------------+
 *                    |         AAH          |
 *                    +----------------------+
 *                    |         55H          |
 *                    +----------------------+
 *                    | Byte: ROM Size / 512 |
 *                    +----------------------+
 *                    |/ / / / / / / / / / / |
 *                    | /-Option ROM code-/  |
 *                    |/ / / / / / / / / / / |
 *                    +----------------------+
 *                    (Sum of all bytes MOD 100H is 00H).
 *
 *                  I add up all the bytes starting from th AAH into BL,
 *                    allowing BL to overflow (an 8 bit checksum sort
 *                    of arrangement).  If the value is 00H, this was
 *                    a valid option card.  If not, I stumbled across
 *                    a spurious 55 AA in memory.
 *
 * uSegment - Segment to search.
 *
 * uOffset  - Offset to search.
 *
 * Returns: Number of 1K pages for the Option ROM starting at the
 *          specified location, or 0 if no Option ROM was found.
 **************************************************************************/

int _fastcall OptionRomCheck (unsigned uSegment, unsigned uOffset)
{
  int   iReturnValue;           /* Value this routine returns */

  _asm
    {
                                ;uSegment is in AX
                                ;uOffset  is in DX

      push  es                  ;Save the ES register

    ;---- Adjust Segment so Offset can be :0000 ----

      mov   cl,4                ;Shift uOffset 4 bits
      shr   dx,cl
      add   ax,dx               ;Add to uSegment

      push  ax                  ;Put uSegment into ES
      pop   es
      xor   di,di               ;Put zero into DI

    ;---- Check for ROM signature ----

      cmp   es:[di],0xAA55      ;Is the ROM signature present?
      jne   NotOptionRom        ;If not, jump out.

    ;---- ROM signature detected, Set return value in case it's valid ----

      xor   cx,cx               ;Zero out CX register
      mov   cl,es:[di + 2]      ;Load the number of bytes / 512
      test  cl,0x01             ;Is it an odd value?
      jz    SetReturnValue      ;If not, set return value
      inc   cx                  ;If odd, increase CX to even 1K boundry

    SetReturnValue:
      shr   cx,1                ;Divide by 2 to obtain Option ROM size in K
      mov   iReturnValue,cx     ;Set the return value, in case this is
                                ;  a value Option ROM.

    ;---- Prepare for checksum on Option ROM ----

      xor   cx,cx               ;Zero out CX register

;     inc   di                  ;Bump DI three bytes to move around the
;     inc   di                  ;  ROM signature
;                               ;Load the number of bytes in the Option ROM
;                               ;  into CX

      mov   ch,es:[di + 2]      ;CL = byte count / 512 (CX = byte count / 2)
      shl   cx,1                ;CX now = number of bytes

      xor   al,al               ;Zero out the checksum register

    ;---- Perform checksum ----

    CkSumLoop:

      add   al,es:[di]          ;Add byte to AL (overflow is expected)
      inc   di                  ;Bump DI to point to next byte
      loop  CkSumLoop           ;Loop until all bytes have been read

    ;---- Checksum is complete, AL = 0 means this is a valid Option ROM ----

      cmp   al,0                ;Is the checksum zero?
      je    OptionCheckComplete ;If so, the return value has already been
                                ;  set, so we jump out of the routine

                                ;If not, fall through...

    ;---- ROM Signature not Detected ----

    NotOptionRom:

      mov   iReturnValue,0      ;Set the return value to zero.
      jmp   OptionCheckComplete ;Exit this routine

    ;---- Test is completed, return to calling routine ----

    OptionCheckComplete:

      pop   es                  ;Restore the original ES register
    }

  return (iReturnValue);
}


/*********************************************************************
 * SprintMemInfo - Put Memory information into a set of strings to be
 *                 printed or displayed.
 *
 * fMemoryType  - Type(s) of memory to put into strings (MEM_ALL to
 *                show all types of memory).
 * pMem         - Pointer to the structure describing the memory
 *                types.
 * szSumStrings - Summary information string holder.
 *
 * Returns:  NULL if an error occured, or if summary information is
 *           requested.
 *********************************************************************/

QSZ * SprintMemInfo (BOOL fMemoryType,
                     MEMORY_STRUCT *pMem,
                     CHAR szSumStrings[][MAX_SUMM_INFO + 5],
                     BOOL fOverlayFlag)
{
  WORD wNmbrStrings;        /* Number of strings                     */
  WORD wNmbrChars;          /* Number of characters in the strings   */
  WORD i;                   /* Index variable                        */
  CHAR chBuffer[120];       /* Local string                          */
  QSZ  *pqszStrings;        /* Location for storing string pointers  */
  WORD wAlignColumn;        /* Column to align titles                */


  /* Summary strings */
  if (szSumStrings != NULL)
    {
      i = 0;

      /* Conventional */
      sprintf (chBuffer, "%ldK", pMem->lConv_Mem / 1024L);
      strncpy (szSumStrings[i], chBuffer, MAX_SUMM_INFO + 3);

      /* Extended */
      if (pMem->iCMOSExtended)
        {
          strncat (szSumStrings[i], pszCommaSpace,
                   MAX_SUMM_INFO + 3 - strlen (szSumStrings[i]));

	  sprintf (chBuffer, "%uK ", (unsigned int)pMem->iCMOSExtended);
          strcat (chBuffer, "Ext");

          if (strlen (chBuffer) + strlen (szSumStrings[i]) > MAX_SUMM_INFO + 3)
            {
              i = 1;
              szSumStrings[i][0] = '\0';
            }

          strncat (szSumStrings[i], chBuffer,
                   MAX_SUMM_INFO + 3 - strlen (szSumStrings[i]));
        }

      /* EMS */
      if (pMem->iTotal_Emm_Pages)
        {
          strncat (szSumStrings[i], pszCommaSpace,
                   MAX_SUMM_INFO + 3 - strlen (szSumStrings[i]));

	  sprintf (chBuffer, "%uK ", (unsigned int)pMem->iTotal_Emm_Pages * 16);
          strcat (chBuffer, "EMS");

          if (strlen (chBuffer) + strlen (szSumStrings[i]) > MAX_SUMM_INFO + 3)
            {
              i = 1;
              szSumStrings[i][0] = '\0';
            }

          strncat (szSumStrings[i], chBuffer,
                   MAX_SUMM_INFO + 3 - strlen (szSumStrings[i]));
        }

      /* XMS */
      if (pMem->iXmm_Free_Err == 0 && pMem->iTotal_Free_Xm != 0)
        {
          strncat (szSumStrings[i], pszCommaSpace,
                   MAX_SUMM_INFO + 3 - strlen (szSumStrings[i]));

	  sprintf (chBuffer, "%uK ", (unsigned int)pMem->iTotal_Free_Xm);
          strcat (chBuffer, "XMS");

          if (strlen (chBuffer) + strlen (szSumStrings[i]) > MAX_SUMM_INFO + 3)
            {
              i = 1;
              szSumStrings[i][0] = '\0';
            }

          strncat (szSumStrings[i], chBuffer,
                   MAX_SUMM_INFO + 3 - strlen (szSumStrings[i]));
        }

      return (NULL);
    }


  /* Overestimate the amount of space required for the strings */

  switch (fMemoryType)
    {
      case MEM_ALL:
        wAlignColumn = MEM_MAX_ALIGN;
        wNmbrStrings = MEM_CONV_STRINGS + MEM_EXT_STRINGS  +
                       MEM_EMS_STRINGS  + MEM_XMS_STRINGS  +
                       MEM_VCPI_STRINGS + MEM_DPMI_STRINGS +
                       MEM_LEGEND_STRINGS;
        if (wNmbrStrings < MEM_640K_LIMIT)
          wNmbrStrings = MEM_640K_LIMIT;
        wNmbrChars   = 2450;  /* Beyond the maximum chars required */
        break;

      case MEM_SUMMARY:
        wAlignColumn =  0;
        wNmbrStrings =  1;
        wNmbrChars   = REPORT_WIDTH + 1;
        break;

      case MEM_CONVENTIONAL:
        wAlignColumn = MEM_CONV_ALIGN;
        wNmbrStrings = MEM_CONV_STRINGS;
        wNmbrChars   = MEM_CONV_STRINGS * REPORT_WIDTH + 1;
        break;

      case MEM_EXTENDED:
        wAlignColumn = MEM_EXT_ALIGN;
        wNmbrStrings = MEM_EXT_STRINGS;
        wNmbrChars   = MEM_EXT_STRINGS * REPORT_WIDTH + 1;
        break;

      case MEM_EMS:
        wAlignColumn = MEM_EMS_ALIGN;
        wNmbrStrings = MEM_EMS_STRINGS;
        wNmbrChars   = MEM_EMS_STRINGS * REPORT_WIDTH + 1;
        break;

      case MEM_XMS:
        wAlignColumn = MEM_XMS_ALIGN;
        wNmbrStrings = MEM_XMS_STRINGS;
        wNmbrChars   = MEM_XMS_STRINGS * REPORT_WIDTH + 1;
        break;

      case MEM_VCPI:
        wAlignColumn = MEM_VCPI_ALIGN;
        wNmbrStrings = MEM_VCPI_STRINGS;
        wNmbrChars   = MEM_VCPI_STRINGS * REPORT_WIDTH + 1;
        break;

      case MEM_DPMI:
        wAlignColumn = MEM_DPMI_ALIGN;
        wNmbrStrings = MEM_DPMI_STRINGS;
        wNmbrChars   = MEM_DPMI_STRINGS * REPORT_WIDTH + 1;
        break;

      case MEM_VISUAL_MAP:
        wAlignColumn = 12;
        wNmbrStrings = 65;
        wNmbrChars   = wNmbrStrings * 40;
        break;


      default:
        wAlignColumn =  0;
        wNmbrStrings =  1;
        wNmbrChars   = REPORT_WIDTH + 1;
    }


  /* Allocate space for the pointer area and string area */
  pqszStrings = AllocStringSpace (wNmbrStrings, wNmbrChars);
  if (pqszStrings == NULL)
    return (NULL);


  /* Put the information in place */

  i = 0;

  /* Summary Information */

  if (fMemoryType == MEM_SUMMARY)
    {
      return (NULL);
    }


  /* Include the memory legend */

  if (fReportFlag)
    {
      sprintf (chBuffer, "Legend:  Available \"%c%c\"  RAM \"%c%c\"  ROM \"%c%c\"  Possibly Available \"%c%c\"",
               REPORT_WOM, REPORT_WOM,
               REPORT_RAM, REPORT_RAM,
               REPORT_ROM, REPORT_ROM,
               REPORT_NOT_CERTAIN, REPORT_NOT_CERTAIN);
      Qstrcpy (pqszStrings[i], chBuffer);
      PrepNextString (pqszStrings, i++);

      sprintf (chBuffer, "  EMS Page Frame \"%c%c\"",
               REPORT_EMS, REPORT_EMS);
      Qstrcpy (pqszStrings[i], chBuffer);

      if (wDosMajor >= 5 && wDosMajor < 10)
        {
          sprintf (chBuffer, "  Used UMBs \"%c%c\"  Free UMBs \"%c%c\"",
                   REPORT_USED_UMB, REPORT_USED_UMB,
                   REPORT_FREE_UMB, REPORT_FREE_UMB);
          Qstrcat (pqszStrings[i], chBuffer);
        }

      if (pMem->fXmsUmbAvailable)
        {
          sprintf (chBuffer, "  Free XMS UMBs \"%c%c\"",
                   REPORT_FREE_XMS_UMB, REPORT_FREE_XMS_UMB);
          Qstrcat (pqszStrings[i], chBuffer);
        }

      PrepNextString (pqszStrings, i++);
    }
  else
    {
      sprintf (chBuffer, "Legend:  Available \"&1%c%c&0\"  RAM \"&1%c%c&0\"  ROM \"&1%c%c&0\"  Possibly Available \"&1%c%c&0\"",
               DISPLAY_WOM, DISPLAY_WOM,
               DISPLAY_RAM, DISPLAY_RAM,
               (fBlackWhite) ? REPORT_ROM : DISPLAY_ROM,
               (fBlackWhite) ? REPORT_ROM : DISPLAY_ROM,
               DISPLAY_NOT_CERTAIN, DISPLAY_NOT_CERTAIN);
      Qstrcpy (pqszStrings[i], chBuffer);
      PrepNextString (pqszStrings, i++);

      sprintf (chBuffer, "  EMS Page Frame \"&1%c%c&0\"",
               DISPLAY_EMS, DISPLAY_EMS);
      Qstrcpy (pqszStrings[i], chBuffer);

      if (wDosMajor >= 5 && wDosMajor < 10)
        {
          sprintf (chBuffer, "  Used UMBs \"&1%c%c&0\"  Free UMBs \"&1%

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?