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

📄 serialio.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:

                }
        return i;
}
/****************************************************************************/
WORD ExternalStatus(T_ComPortStruct *ComPortHandle)
{
        WORD Status;

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        Status = inportb(ComPortHandle->IOAddress+SER_MODEM_STATUS);
        return Status & 0x7fff;
}
/****************************************************************************/
WORD WriteModemControlRegister(T_ComPortStruct *ComPortHandle, WORD Status)
   {

// Only writes to DTR and RTS lines

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        Status = ( Status & (RTS | DTR) ) |
                 ( inportb(ComPortHandle->IOAddress+SER_MODEM_CTL) & ~(DTR | RTS) ) ;

        outportb(ComPortHandle->IOAddress + SER_MODEM_CTL, Status );

        return Status;  // return the actual modem control word output

   }
/****************************************************************************/
WORD FlushReadBuffer(T_ComPortStruct *ComPortHandle)
{

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        Disable();
                /* reset FIFO pointers */
        ComPortHandle-> ComInputPtr = ComPortHandle-> InputBuffer;
        ComPortHandle-> PCInputPtr = ComPortHandle-> InputBuffer;

                /* clear out the COM port */
        inportb(ComPortHandle-> IOAddress + SER_RECEIVE);
        Enable();

        return 0;
}
/****************************************************************************/
WORD FlushWriteBuffer(T_ComPortStruct *ComPortHandle)
{

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        Disable();
        /* reset FIFO pointers */
        ComPortHandle-> ComOutputPtr = ComPortHandle-> OutputBuffer;
        ComPortHandle-> PCOutputPtr = ComPortHandle-> OutputBuffer;
        Enable();

        return 0;
}
/****************************************************************************/
WORD ReadStatus(T_ComPortStruct *ComPortHandle)
   {

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        return ComPortHandle->RcvByteCount;
        }
/****************************************************************************/
LONG ReadErrors(T_ComPortStruct *ComPortHandle, LONG *Count)
// return a pointer to a LONG array with 3 elements :
//   *ptr   = # of OverRun errors accumulated
//   *ptr+1 = # of Parity errors accumulated
//   *ptr+2 = # of Framing errors accumulated
//   *ptr+3 = # of bytes for missed characters
//      all the error counts will be reset to zeroes after the read
   {
        LONG total=0;
        WORD i;

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        CMovD( (LONG *)&(ComPortHandle->RcvErrors[0]),
               (LONG *)&(ComPortHandle->RcvErrorsSent[0]),
                         4 );
/*      ComPortHandle-> RcvErrorsSent[0] = ComPortHandle-> RcvErrors[0];
        ComPortHandle-> RcvErrorsSent[1] = ComPortHandle-> RcvErrors[1];
        ComPortHandle-> RcvErrorsSent[2] = ComPortHandle-> RcvErrors[2];
        ComPortHandle-> RcvErrorsSent[3] = ComPortHandle-> RcvErrors[3];
*/
        for (i=0; i<4; i++)
            total += ComPortHandle->RcvErrors[i];

   ComPortHandle-> RcvErrors[0] = 0;
        ComPortHandle-> RcvErrors[1] = 0;
        ComPortHandle-> RcvErrors[2] = 0;
        ComPortHandle-> RcvErrors[3] = 0;

        Count = (LONG *)&(ComPortHandle->RcvErrorsSent[0]);
        return total;
   }

/****************************************************************************/
WORD WriteStatus(T_ComPortStruct *ComPortHandle)
{
        WORD WriteComplete;

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        WriteComplete = FALSE;
        if (ComPortHandle-> PCOutputPtr == ComPortHandle-> ComOutputPtr)
                WriteComplete = TRUE;
        return(WriteComplete);
}

/****************************************************************************/
WORD SendBreak(T_ComPortStruct *ComPortHandle)
{

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        /* Dont try to send data during Break */
        FlushWriteBuffer(ComPortHandle);
        Disable();
        outportb(ComPortHandle->IOAddress + SER_LINE_CTL,
                         (inportb(ComPortHandle->IOAddress + SER_LINE_CTL) | SEND_BREAK));
        Enable();

        return 0;
}

/****************************************************************************/
WORD ClearBreak(T_ComPortStruct *ComPortHandle)
{

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        /* Dont try to send data during Break */
        Disable();
        outportb( ComPortHandle->IOAddress + SER_LINE_CTL,
                            (inportb(ComPortHandle->IOAddress + SER_LINE_CTL) & ~SEND_BREAK));
   Enable();
        return 0;
}
/****************************************************************************/
WORD TestBreak(T_ComPortStruct *ComPortHandle)
{
        WORD BreakState;

        if ( ComPortListHead == NULL ||
             ComPortHandle->ComStructID != ComStructSignature )
      return ERR_BAD_HANDLE;

        BreakState = 0;
        /* Dont try to send data during Break */
        Disable();
        if (inportb(ComPortHandle->IOAddress + SER_LINE_STATUS) & BREAK_DETECT)
                BreakState++;
        Enable();

        return BreakState;
}

/****************************************************************************/
//void interrupt _IntServiceSer1(void)
void _IntServiceSer1(void)   // interrupt for COM1 port
{
        T_ComPortStruct *ComPortHandle;


        if ( ComPortListHead != NULL )
           {
           ComPortHandle = ComPortListHead;
           for (; ComPortHandle != NULL; ComPortHandle = ComPortHandle->ComPortLink )
                   if ( ComPortHandle->ComPort == COM1PORT )  break;
           if ( ComPortHandle != NULL )
                   SerialIntProcess(ComPortHandle);
           }
        outportb(INT_CTRL_PORT, END_OF_INT);
}
/****************************************************************************/
//void interrupt _IntServiceSer2(void)
void _IntServiceSer2(void)   // interrupt for COM2 port
{
        T_ComPortStruct *ComPortHandle;


        if ( ComPortListHead != NULL )
           {
           ComPortHandle = ComPortListHead;
           for (; ComPortHandle != NULL; ComPortHandle = ComPortHandle->ComPortLink )
                   if ( ComPortHandle->ComPort == COM2PORT )  break;
           if ( ComPortHandle != NULL )
                   SerialIntProcess(ComPortHandle);
           }
        outportb(INT_CTRL_PORT, END_OF_INT);
}

/****************************************************************************/
void SerialIntProcess(T_ComPortStruct *ComPortHandle)
{
        BYTE inByte, bytenotread;
        char *NewInputPtr;
        WORD error_mask;

        error_mask = inportb(ComPortHandle-> IOAddress + SER_LINE_STATUS);


        if ( error_mask & OVERRUN_ERROR )
           ComPortHandle-> RcvErrors[0]++;
        if ( error_mask & PARITY_ERROR )
           ComPortHandle-> RcvErrors[1]++;
        if ( error_mask & FRAMING_ERROR )
           ComPortHandle-> RcvErrors[2]++;

//   if ((inportb(ComPortHandle-> IOAddress + SER_LINE_STATUS)) & RECEIVE_READY)
   if ( error_mask & RECEIVE_READY)
                {
                inByte = inportb(ComPortHandle-> IOAddress + SER_RECEIVE);
                inByte &= CharacterMaskTable[ComPortHandle-> DataBits];
                bytenotread = 1;

                /* check if room in the FIFO */
                if ( ComPortHandle->FlowControl &&
                   ( ComPortHandle->RcvBufferSize - ComPortHandle->RcvByteCount <=
                        ComPortHandle->RTS_OFFthreshold ) ) // there is no room with HW
                                                              // handshaking
                        {

                        if ( ComPortHandle->RTS_ON == TRUE )                    // should send xoff and RTS is on
                           {
                           WriteModemControlRegister ( ComPortHandle,
                              inportb(ComPortHandle->IOAddress+SER_MODEM_CTL) & ~RTS );
                              // Turn RTS off
                           ComPortHandle->RTS_ON = FALSE;
                           }
                           // RTS already off
                        }

                // No flowcontrol or there is room
           /* update FIFO pointer */
      NewInputPtr = ComPortHandle-> ComInputPtr + 1;
           if (NewInputPtr == ComPortHandle-> InputBuffer + ComPortHandle->RcvBufferSize )
           NewInputPtr = ComPortHandle-> InputBuffer;
           if (NewInputPtr != ComPortHandle->PCInputPtr)
                   {
                   ComPortHandle-> ComInputPtr[0] = inByte;
                   ComPortHandle-> ComInputPtr = NewInputPtr;
                   bytenotread = 0;
                   ComPortHandle-> RcvByteCount++;
                   }
           ComPortHandle->RcvErrors[3] += bytenotread;
                }

        /* try to transmit character if its ready */
        TransmitChar(ComPortHandle);
        return;
}

/****************************************************************************/
void StartTransmit(T_ComPortStruct *ComPortHandle)
{

        Disable();
        /* if transmitter is not running start it */
   if ((ComPortHandle-> EnableMask & (SER_TBRE_ENABLE | SER_MSR_ENABLE)) == 0)
//   if ((ComPortHandle-> EnableMask & SER_TBRE_ENABLE ) == 0)
      {
    /* enable transmit buffer empty interrupts */
      ComPortHandle-> EnableMask |= SER_TBRE_ENABLE;
      outportb(ComPortHandle->IOAddress + SER_INT_ENABLE,
                         ComPortHandle-> EnableMask);
      }

   Enable();
        return;
}
/****************************************************************************/
extern struct ScreenStruct *sID;

void TransmitChar(T_ComPortStruct *ComPortHandle)
{
        char *NewOutput;
        BYTE CurrentMask;
        WORD msr;

        CurrentMask = ComPortHandle-> EnableMask;
   msr = inportb ( ComPortHandle-> IOAddress+SER_MODEM_STATUS ) & (CTS|DSR);

        if ( ( ComPortHandle-> FlowControl == 0 ) || msr == (CTS|DSR) )
                {

           /* If data is buffered lets try to send it */
           if (ComPortHandle-> ComOutputPtr != ComPortHandle-> PCOutputPtr)
                   {
                        /* make sure hardware can take character */
                        if (inportb(ComPortHandle->IOAddress + SER_LINE_STATUS) &
                                                                             TRANSMIT_READY)
                                {
                                outportb(ComPortHandle-> IOAddress + SER_TRANSMIT,
                                         ComPortHandle-> ComOutputPtr[0]);
                                NewOutput = ComPortHandle-> ComOutputPtr + 1;
                           if (NewOutput == ComPortHandle-> OutputBuffer +
                                                    ComPortHandle->XmitBufferSize )
                                        NewOutput = ComPortHandle-> OutputBuffer;
                                ComPortHandle-> ComOutputPtr = NewOutput;
                                }

                        /* Send next character when Transmit buffer is empty */
                        ComPortHandle-> EnableMask &= ~SER_MSR_ENABLE;
                        ComPortHandle-> EnableMask |= SER_TBRE_ENABLE;
                        }
        else
                {
                   /* no more characters in FIFO, so turn off all interrupts */
                ComPortHandle-> EnableMask &= ~(SER_TBRE_ENABLE | SER_MSR_ENABLE);
                   ComPortHandle-> EnableMask &= ~SER_TBRE_ENABLE;
                   }
        }
        else
                {
                /* cannot send due to hardware flow control so wait for status change*/
                ComPortHandle-> EnableMask |= SER_MSR_ENABLE;
                ComPortHandle-> EnableMask &= ~SER_TBRE_ENABLE;
                }

        /* if mask changed output mask to hardware */
        if (CurrentMask != ComPortHandle-> EnableMask)
                outportb(ComPortHandle->IOAddress + SER_INT_ENABLE,
                         ComPortHandle-> EnableMask);

        return;
}

/****************************************************************************/
WORD Peek(pointer)
WORD *pointer;
{
return(((WORD *)MapAbsoluteAddressToDataOffset((LONG) pointer))[0]);
}

/****************************************************************************/
#pragma aux inportb =                             \
         0xEC                   /* in  al, dx */    \
         parm  [dx]                                                       \
         value [al];

/****************************************************************************/
#pragma aux outportb =                            \
        0xEE               /* out dx, al */       \
         parm  [dx]  [al];

⌨️ 快捷键说明

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