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

📄 serialio.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/



#define NULL 0
#include <nwtypes.h>
#include <lanconf.h>
// #include "serialIO.h"
#include <miniproc.h>
#include <string.h>
#include <loader.h>

#define InterruptSignature                              0x50544E49                      /* 'PTNI' */
#define IORegistrationSignature                 0x53524F49                      /* 'SROI' */

/* define Netware 386 OS routines */

/****************************************************************************/
#pragma aux ___GETDS =              \
      0x8C 0xD0    /* mov ax, ss */ \
      0x8E 0xD8    /* mov ds, ax */ \
      0x8E 0xC0    /* mov es, ax */ \
      modify [eax];
/****************************************************************************/
/****************************************************************************/


void Enable(void);
void Disable(void);

#define MaxPorts 2

/* defines for translate tables */
#define MaxBitRateIndex 19
#define MaxParityIndex 5
#define MaxStopBitsIndex 3
#define MaxDataBitsIndex 4


/* define offsets to comm output registers */
#define SER_BAUD_LSB 0
#define SER_BAUD_MSB 1
#define SER_TRANSMIT 0
#define SER_INT_ENABLE 1

/* define offsets for comm input/output registers */
#define SER_LINE_CTL 3
#define SER_MODEM_CTL 4

/* define offsets to comm input registers */
#define SER_RECEIVE 0
#define SER_ID 2
#define SER_LINE_STATUS 5
#define SER_MODEM_STATUS 6

/* define Bits for Interrupt Enable register */
#define SER_DATA_ENABLE 0x01
#define SER_TBRE_ENABLE 0x02
#define SER_LSR_ENABLE  0x04
#define SER_MSR_ENABLE  0x08


/* define Bits for Line Control register */
#define SEND_BREAK 0x40

/* define Bits for Modem Control register */
#define OUT2   0x08
#define RTS    0x02
#define DTR    0x01

/* define Bits for Line Status Register */
#define RECEIVE_READY 0x01
#define OVERRUN_ERROR 0x02
#define PARITY_ERROR  0x04
#define FRAMING_ERROR 0x08
#define BREAK_DETECT   0x10
#define TRANSMIT_READY 0x20


/* define Modem Status Register bits */
#define CTS      0x10
#define DSR      0x20
#define RI       0x40
#define DCD      0x80

#define NO_PENDING_INTR 0x01

#define ERROR_MASK (OVERRUN_ERROR | PARITY_ERROR | FRAMING_ERROR)

/* interrupt controller registers */
#define INT_CTRL_PORT 0x20
#define INT_MASK_PORT 0x21

/* define end of interrupt value */
#define END_OF_INT 0x20

// Return error code from SERIALIO.NLM

#define ERR_BAD_HANDLE          -1  // Bad ComPortStructured handle
#define ERR_NO_INT_AVAIL                  -2  // Com interrupts not available
#define ERR_OUT_MEMORY                    -3  // out of memory
#define ERR_INVALID_PARAMETER     -5  // invalid parameters for com ports
#define ERR_OUT_RTAG                      -4  // can't allocate resource tags
#define ERR_PORT_NOTAVAIL       -6  // requested comm ports already acquired
#define ERR_INVALID_PORT        -7  // requested comm ports not supported/installed

#define HW_XOFF_THRESHOLD       32
#define BUFFER_MIN             128
#define BUFFER_MAX           65535
#define XMT_FIFO_LENGTH            2048
#define RCV_FIFO_LENGTH       2048

// define index into Receive Error Count Array
#define OVERRUN 0
#define PARITY  1
#define FRAMING 2

#define COM1PORT 0
#define COM2PORT 1



#define ComStructSignature  0x4f495352

/* port control structure */
typedef struct ComPortStruct
   {
        struct ComPortStruct   *ComPortLink;
        WORD   ComPort;
        WORD   IrqNumber;
        LONG   ComStructID;
        WORD   IOAddress;
        BYTE   BitRate;
        BYTE   DataBits;
        BYTE   StopBits;
        BYTE   Parity;
        BYTE   FlowControl;
        BYTE   EnableMask;
        WORD   RTS_ON;
   LONG   RcvErrors[4];
        LONG   RcvErrorsSent[4];
        WORD   RTS_OFFthreshold;
        WORD   RcvBufferSize;
        WORD   XmitBufferSize;
        WORD   RcvByteCount;
        char  *ComInputPtr;
        char  *PCInputPtr;
        char  *ComOutputPtr;
        char  *PCOutputPtr;
        char  *InputBuffer;
        char  *OutputBuffer;
   struct ResourceTagStructure     *RS232IORTag;  //calling nlm's RS232 tag
   struct ResourceTagStructure     *InterruptRTag;
   struct ResourceTagStructure     *MemAllocRTag;
        }       T_ComPortStruct;



/* define Local routines */

WORD AcquireSerialPort( WORD PortNumber,
                        struct ResourceTagStructure     *RS232RTag,
                                                           int *ComPortHandle );

WORD InitSerialPort(T_ComPortStruct *ComPortHandle, BYTE UserBitRate,
                    BYTE UserDataBits, BYTE UserStopBits, BYTE UserParity,
                                                  BYTE UserFlowControl);
WORD ReleasePort(T_ComPortStruct *ComPortHandle);
WORD SetReceiveBufferSize(T_ComPortStruct *ComPortHandle, WORD BufferSize);
WORD SetTransmitBufferSize(T_ComPortStruct *ComPortHandle, WORD BufferSize);
WORD WriteData(T_ComPortStruct *ComPortHandle,char *Buffer,WORD Length);
WORD ReadData(T_ComPortStruct *ComPortHandle,char *Buffer,WORD BufferLen);
WORD ExternalStatus(T_ComPortStruct *ComPortHandle);
WORD WriteModemControlRegister(T_ComPortStruct *ComPortHandle, WORD Status);
WORD FlushReadBuffer(T_ComPortStruct *ComPortHandle);
WORD FlushWriteBuffer(T_ComPortStruct *ComPortHandle);
WORD ReadStatus(T_ComPortStruct *ComPortHandle);
LONG ReadErrors(T_ComPortStruct *ComPortHandle, LONG *Count);
WORD WriteStatus(T_ComPortStruct *ComPortHandle);
WORD SendBreak(T_ComPortStruct *ComPortHandle);
WORD ClearBreak(T_ComPortStruct *ComPortHandle);
WORD TestBreak(T_ComPortStruct *ComPortHandle);


static WORD ValidateParameters( struct ComPortStruct *p);
void _IntServiceSer1(void);
void _IntServiceSer2(void);
void TransmitChar(T_ComPortStruct *ComPortHandle);
void SerialIntProcess(T_ComPortStruct *ComPortHandle);
void StartTransmit(T_ComPortStruct *ComPortHandle);
//void interrupt _IntServiceSer1(void);
//void interrupt _IntServiceSer2(void);
WORD Peek(WORD *Pointer);
BYTE inportb(WORD PortAddress);
void outportb(WORD PortAddress, WORD Value);

extern WORD AvailableComPorts;

extern struct ComPortStruct     *ComPortListHead;

// WORD irqNumber[MaxPorts] = { 4, 3 };
void (*irqRoutine[MaxPorts])() = { _IntServiceSer1, _IntServiceSer2 };

LONG badhandle=ERR_BAD_HANDLE;

WORD BitRateTable[MaxBitRateIndex] = {  0x0900,   /*     50 Baud */
                                                                                                         0x0600,   /*     75 Baud */
                                                                                                         0x0417,   /*    110 Baud */
                                                                                                         0x0359,   /*    134.5 Baud */
                                                                                                         0x0300,   /*    150 Baud */
                                                                                                         0x0180,   /*    300 Baud */
                                                                                                         0x00C0,   /*    600 Baud */
                                                                                                         0x0060,   /*   1200 Baud */
                                                                                                         0x0040,   /*   1800 Baud */
                                                                                                         0x003A,   /*   2000 Baud */
                                                                                                         0x0030,   /*   2400 Baud */
                                                                                                         0x0020,   /*   3600 Baud */
                                                                                                         0x0018,   /*   4800 Baud */
                                                                                                         0x0010,   /*   7200 Baud */
                                                                                                         0x000C,   /*   9600 Baud */
                                                                                                         0x0006,   /*  19200 Baud */
                                                                                                         0x0003,   /*  38400 Baud */
                                                                                                         0x0002,   /*  57600 Baud */
                                                                                                         0x0001 }; /* 115200 Baud */

BYTE ParityTable[MaxParityIndex] = {    0x00,     /* no parity */
                                                                                                         0x08,     /* odd parity */
                                                                                                         0x18,     /* even parity */
                                                                                                         0x28,     /* mark parity */
                                                                                                         0x38 };   /* space parity */

BYTE StopBitTable[MaxStopBitsIndex] = { 0x00,     /* 1 stop bit */
                                                                                                         0x04,    /* 1.5 stop bits for 5 data bits */
                                                                                                         0x04 };          /* 2 stop bits */

BYTE CharacterLengthTable[MaxDataBitsIndex] = {
                                                                                                         0x00,    /* 5 bits */
                                                                                                         0x01,    /* 6 bits */
                                                                                                         0x02,    /* 7 bits */
                                                                                                         0x03};   /* 8 bits */

BYTE CharacterMaskTable[MaxDataBitsIndex] = {
                                                                                                         0x1F,    /* 5 bits */
                                                                                                         0x3F,    /* 6 bits */
                                                                                                         0x7F,    /* 7 bits */
                                                                                                         0xFF};    /* 8 bits */


/****************************************************************************/

/*
Note:
(a) The ResourceTag for the hardware interrupt vector is currently owned by the
    serdrv.nlm. This may be changed to be an input parameter passed in by the
    application later on.

(b) If this library is to be a released product, the symbols 'ReturnResourceTag'
    and 'CFindLoadModuleHandle' need to be exported by the OS.


(c) Apparently, there needs to be a delay of about 50 ms between WriteStatus
    and ReadStatus for low baudrate

*/



/****************************************************************************/


#define MAX_COM_PORTS 2

extern struct LoadDefinitionStructure *SerdrvNLMHandle;
extern struct IOConfigurationStructure ioConfig;


/*
static WORD CheckBIOS( WORD PortNumber )
   {

   if ((PortNumber < MAX_COM_PORTS) &&
                 (((Peek((WORD *)0x411) >> 1) & 0x07) > PortNumber) &&
                 ( Peek((WORD *) (0x400 + PortNumber * 2))) != 0  )
       return TRUE;
   else
            return FALSE;
   }
*/

WORD AcquireSerialPort( WORD PortNumber,
                       struct ResourceTagStructure     *RS232RTag,
                                                          int *ComPortHandle )

   {
   struct ResourceTagStructure    *InterruptRTag;
   struct ResourceTagStructure    *NLMAllocRTag;
   struct ComPortStruct *p;
        LONG rc;
        LONG eoi;
        size_t size;

        *ComPortHandle = NULL;

   if ( AvailableComPorts < PortNumber ) return ERR_INVALID_PORT;

        if ( ioConfig.CIOPortsAndRanges[PortNumber*2] == 0 )
                return ERR_PORT_NOTAVAIL;

        if ( ComPortListHead != NULL )
           {
                p = ComPortListHead;
                for (; p != NULL; p = p->ComPortLink )
                        if ( p->ComPort == PortNumber )  return ERR_PORT_NOTAVAIL;
                }

        NLMAllocRTag = AllocateResourceTag( RS232RTag->RTModule,
                                                "RS232IO Data Memory",
                                       AllocSignature );

        if ( NLMAllocRTag == NULL ) return ERR_OUT_RTAG;

        NLMAllocRTag->RTLink = RS232RTag->RTLink;
        RS232RTag->RTLink = RS232RTag->RTModule->LDResourceList;
   RS232RTag->RTModule->LDResourceList = RS232RTag;


        size = sizeof(struct ComPortStruct);
   p = (T_ComPortStruct *)Alloc( size, NLMAllocRTag );

        if ( p == NULL ) return ERR_OUT_MEMORY;

        p-> IOAddress = ioConfig.CIOPortsAndRanges[PortNumber*2];
                        /* Peek( (WORD *)(0x400 + PortNumber * 2) ); */
   p-> ComPort = PortNumber;
   p-> IrqNumber = ioConfig.CIntLine[PortNumber];

                /* take over hardware interrupt Vector */
   InterruptRTag = AllocateResourceTag( RS232RTag->RTModule,
                                       "RS232IO Interrupt Handler",
                                                InterruptSignature );

   if ( InterruptRTag == NULL ) return ERR_OUT_RTAG;

⌨️ 快捷键说明

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