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

📄 cominfo.c

📁 Dos6.0
💻 C
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************
 * Microsoft Diagnostics Version 2.0
 *
 * A diagnostic utility to detect as much useful information about a
 *   customer's computer system as is possible.
 *
 * Microsoft Diagnostics:  We detect the World.
 *
 * COMINFO.C - Source file for serial port detection code.
 ********************************************************************/


/* Include Files */

#include "msd.h"


/*********************************************************************
 * GetComInfo - Gets the COM port information.
 *
 * Returns:  TRUE if an error occured.
 *********************************************************************/

BOOL GetComInfo (COM_STRUCT *pCom, BOOL fMinimumInfo)
{
  WORD  i, wWait;           /* Looping variables                    */
  WORD  wIndex;             /* Index for strings                    */
  WORD  wPort;              /* COM port address                     */
  WORD  wLCR;               /* Line Control Register value          */
  WORD  wMSR;               /* Modem Status Register value          */
  WORD  wNewIID;            /* Used to store changed IID value      */
  DWORD dwBaudRateDivisor;  /* Used to calculate the baud rate      */
  BOOL  fArcnetCard;        /* True if the 02E0-02EF range should   */
                            /*   be avoided                         */

  /* 40:0 is the port address of the first valid COM port */
  WORD FAR * fwPortAddress = (WORD FAR *) 0x00400000;


  /* Determine if an Arcnet card is present at 02E0 */
  fArcnetCard = ArcnetCardPresent();

  /* Set the values in the structure for each port */

  /* Zero out the count of COM ports */
  pCom->wNmbrComPorts = 0;

  for (i = 0; i < MAX_COM_PORTS; ++i)
    {
      {
        /* Load the port address from the DOS Device table, if it exists */
        pCom->ComxInfo[i].wPortAddress = *(fwPortAddress++);
        wPort = pCom->ComxInfo[i].wPortAddress;

        /* Determine if the port exists in the right range */

        if (wPort >= 0x220  &&  wPort <= 0x3FF)
          {
            ++(pCom->wNmbrComPorts);
            pCom->ComxInfo[i].fComPortDetected = TRUE;
          }
        else
          pCom->ComxInfo[i].fComPortDetected = FALSE;

        /* If the Arcnet card is present, disable COM4 testing */
        if (fArcnetCard && wPort >= 0x2E0 && wPort <= 0x2FF)
          pCom->ComxInfo[i].fComPortDetected = FALSE;

        if (fMinimumInfo || !(pCom->ComxInfo[i].fComPortDetected))
          continue;
      }

      {
        /* Read the Line Control Register Port */

        wLCR = inp (wPort + 3);

        /* If the DLAB bit (bit 7) is 1, we can obtain the Baud Rate    */
        /*   Divisor from *fwPortAddress (LSB) and *fwPortAddress + 1   */
        /*   (MSB)                                                      */

        /* If the DLAB bit is not set, set it, then read the Baud Rate  */
        /*   Divisor                                                    */

        if (!(0x80 & wLCR))
          outp (wPort + 3, 0x80 | wLCR);

        /* Pause briefly for the port to respond */
        for (wWait = 0; wWait < 25; ++wWait)
          ;

        dwBaudRateDivisor = (WORD) (inp (wPort)) +
                            (WORD) (inp (wPort + 1) << 8);

        /* Pause briefly for the port to respond */
        for (wWait = 0; wWait < 25; ++wWait)
          ;

        /* If the DLAB bit was not set originally, put it back to it's  */
        /*   original state.                                            */

        if (!(0x80 & wLCR))
          outp (wPort + 3, wLCR);
      }

      {
        /* Calculate the BAUD rate */

        if (dwBaudRateDivisor == 0)
          pCom->ComxInfo[i].dwBaudRate = 0;
        else
          pCom->ComxInfo[i].dwBaudRate = 115200L / dwBaudRateDivisor;
      }

      {
        /* Parity - If bit 3 of the LCR register is off, parity is none. */
        /*          none.  If bit 3 is on, bits 4 and 5 come into play   */
        /*          like this:                                           */
        /*                                                               */
        /*              Bits: 5 4                                        */
        /*                    0 0 - Odd parity                           */
        /*                    0 1 - Even parity                          */
        /*                    1 0 - Mark parity                          */
        /*                    1 1 - Space parity                         */

        if ((wLCR & 0x08) == 0)
          pCom->ComxInfo[i].wParity = 0;
        else
          pCom->ComxInfo[i].wParity = ((wLCR & 0x30) >> 4) + 1;

        memset (pCom->ComxInfo[i].szParity, '\0', MAX_PARITY);

        wIndex = pCom->ComxInfo[i].wParity;
        strcpy (pCom->ComxInfo[i].szParity, paszParityDesc[wIndex]);
      }

      {
        /* Data Bits - Stored in the LCR in bits 0 and 1: */
        /*                                                */
        /*              Bits: 1 0                         */
        /*                    0 0 - 5 data bits           */
        /*                    0 1 - 6 data bits           */
        /*                    1 0 - 7 data bits           */
        /*                    1 1 - 8 data bits           */

        pCom->ComxInfo[i].wDataBits = (wLCR & 0x03) + 5;
      }

      {
        /* Stop Bits - Stored in the LCR in bit 2.  Off is 1 stop bit, */
        /*             On is two stop bits.                            */
        /*             Note:  If data bits is 5 and LCR bit 2 is on,   */
        /*                    stop bits = 1.5.                         */

        pCom->ComxInfo[i].wStopBits = (wLCR & 0x04) ? 2 : 1;

        if (pCom->ComxInfo[i].wDataBits == 5 &&
            pCom->ComxInfo[i].wStopBits == 2)
          pCom->ComxInfo[i].wStopBits = 3;
      }

      {
        /* Read the Modem Status Register values */

        wMSR = inp (wPort + 6);
      }

      {
        /* Carrier Detect is bit 7 of the MSR */

        pCom->ComxInfo[i].fCarrierDetect = (wMSR & 0x80) ? TRUE : FALSE;
      }

      {
        /* Ring Indicator is bit 6 of the MSR */

        pCom->ComxInfo[i].fRingIndicator = (wMSR & 0x40) ? TRUE : FALSE;
      }

      {
        /* Data Set Ready (DSR) is bit 5 of the MSR */

        pCom->ComxInfo[i].fDataSetReady = (wMSR & 0x20) ? TRUE : FALSE;
      }

      {
        /* Clear to Send is bit 4 of the MSR */

        pCom->ComxInfo[i].fClearToSend = (wMSR & 0x10) ? TRUE : FALSE;
      }

      {
        /* Determine the UART chip type.  This is accomplished by       */
        /*   outputing 11000001 to the FIFO Control Register (FCR).     */
        /*   Then, bits 6 and 7 are checked to see if they are on.  The */
        /*   list below shows how the chip type is determined:          */
        /*                                                              */
        /* Bits: 7 6                                                    */
        /*       0 0 - INS8250 UART                                     */
        /*       0 1 - Unknown                                          */
        /*       1 0 - NS16550 UART                                     */
        /*       1 1 - NS16550AN UART                                   */
        /*                                                              */
        /* This may cause problems with TSR communications programs and */
        /*   COM programs running in OS/2 or Windows while MSD runs,    */
        /*   because in order to determine the chip type, I must modify */
        /*   the behavior of the UART chip.                             */

        /* Turn on bits 6 and 7 */
        outp (wPort + 2, 0xC1);

        /* Pause for a moment to allow the port to take the change. */

        for (wWait = 0; wWait < 25; ++wWait)
          ;

        /* Read the changed value */
        wNewIID = inp (wPort + 2);

        /* Set the chip type, based on bits 6 and 7 */
        wIndex = pCom->ComxInfo[i].wUartChip = wNewIID >> 6;

        memset (pCom->ComxInfo[i].szUartChip, '\0', MAX_UART_CHIP);
        strcpy (pCom->ComxInfo[i].szUartChip, paszUartChips[wIndex]);
      }
    }

⌨️ 快捷键说明

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